@alephium/web3 0.2.0-rc.30 → 0.2.0-rc.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,6 +20,7 @@ import { ec as EC } from 'elliptic'
20
20
  import {
21
21
  fromApiNumber256,
22
22
  fromApiTokens,
23
+ NodeProvider,
23
24
  Number256,
24
25
  toApiNumber256,
25
26
  toApiNumber256Optional,
@@ -30,7 +31,6 @@ import { node } from '../api'
30
31
  import * as utils from '../utils'
31
32
  import { Eq, assertType } from '../utils'
32
33
  import blake from 'blakejs'
33
- import { web3 } from '..'
34
34
 
35
35
  export type OutputRef = node.OutputRef
36
36
 
@@ -50,9 +50,8 @@ export interface Account {
50
50
  publicKey: string
51
51
  }
52
52
 
53
- export type SubmitTx = { submitTx?: boolean }
54
53
  export type SignerAddress = { signerAddress: string }
55
- type TxBuildParams<T> = Omit<T, 'fromPublicKey' | 'targetBlockHash'> & SignerAddress & SubmitTx
54
+ type TxBuildParams<T> = Omit<T, 'fromPublicKey' | 'targetBlockHash'> & SignerAddress
56
55
 
57
56
  export type GetAccountsParams = undefined
58
57
  export type GetAccountsResult = Account[]
@@ -63,7 +62,6 @@ export interface SignTransferTxParams {
63
62
  utxos?: OutputRef[]
64
63
  gasAmount?: number
65
64
  gasPrice?: Number256
66
- submitTx?: boolean
67
65
  }
68
66
  assertType<Eq<keyof SignTransferTxParams, keyof TxBuildParams<node.BuildTransaction>>>()
69
67
  export interface SignTransferTxResult {
@@ -83,7 +81,6 @@ export interface SignDeployContractTxParams {
83
81
  issueTokenAmount?: Number256
84
82
  gasAmount?: number
85
83
  gasPrice?: Number256
86
- submitTx?: boolean
87
84
  }
88
85
  assertType<Eq<keyof SignDeployContractTxParams, keyof TxBuildParams<node.BuildDeployContractTx>>>()
89
86
  export interface SignDeployContractTxResult {
@@ -104,7 +101,6 @@ export interface SignExecuteScriptTxParams {
104
101
  tokens?: Token[]
105
102
  gasAmount?: number
106
103
  gasPrice?: string
107
- submitTx?: boolean
108
104
  }
109
105
  assertType<Eq<keyof SignExecuteScriptTxParams, keyof TxBuildParams<node.BuildExecuteScriptTx>>>()
110
106
  export interface SignExecuteScriptTxResult {
@@ -119,9 +115,8 @@ assertType<Eq<SignExecuteScriptTxResult, SignResult>>()
119
115
  export interface SignUnsignedTxParams {
120
116
  signerAddress: string
121
117
  unsignedTx: string
122
- submitTx?: boolean
123
118
  }
124
- assertType<Eq<SignUnsignedTxParams, { unsignedTx: string } & SubmitTx & SignerAddress>>()
119
+ assertType<Eq<SignUnsignedTxParams, { unsignedTx: string } & SignerAddress>>()
125
120
  export interface SignUnsignedTxResult {
126
121
  fromGroup: number
127
122
  toGroup: number
@@ -151,8 +146,8 @@ export interface SignMessageResult {
151
146
  }
152
147
  assertType<Eq<SignMessageResult, Pick<SignResult, 'signature'>>>()
153
148
 
154
- export interface SignerProvider {
155
- getAccounts(): Promise<Account[]>
149
+ export interface SignerProviderWithoutNodeProvider {
150
+ getSelectedAccount(): Promise<Account>
156
151
  signTransferTx(params: SignTransferTxParams): Promise<SignTransferTxResult>
157
152
  signDeployContractTx(params: SignDeployContractTxParams): Promise<SignDeployContractTxResult>
158
153
  signExecuteScriptTx(params: SignExecuteScriptTxParams): Promise<SignExecuteScriptTxResult>
@@ -161,63 +156,47 @@ export interface SignerProvider {
161
156
  signMessage(params: SignMessageParams): Promise<SignMessageResult>
162
157
  }
163
158
 
164
- export abstract class SignerWithNodeProvider implements SignerProvider {
165
- alwaysSubmitTx: boolean
159
+ export abstract class SignerProvider implements SignerProviderWithoutNodeProvider {
160
+ abstract get nodeProvider(): NodeProvider
161
+ abstract getSelectedAccount(): Promise<Account>
166
162
 
167
- abstract getAccounts(): Promise<Account[]>
168
-
169
- async getAccount(signerAddress: string): Promise<Account> {
170
- const accounts = await this.getAccounts()
171
- const account = accounts.find((a) => a.address === signerAddress)
172
- if (typeof account === 'undefined') {
173
- throw new Error('Unmatched signerAddress')
174
- } else {
175
- return account
176
- }
163
+ async submitTransaction(unsignedTx: string, signature: string): Promise<SubmissionResult> {
164
+ const params: node.SubmitTransaction = { unsignedTx: unsignedTx, signature: signature }
165
+ return this.nodeProvider.transactions.postTransactionsSubmit(params)
177
166
  }
178
167
 
179
- abstract setActiveAccount(addressIndex: number): Promise<void>
180
- abstract setActiveAccount(address: string): Promise<void>
181
- abstract setActiveAccount(input: unknown): Promise<void>
182
-
183
- abstract getActiveAccount(): Promise<Account>
184
-
185
- constructor(alwaysSubmitTx: boolean) {
186
- this.alwaysSubmitTx = alwaysSubmitTx
168
+ async signAndSubmitTransferTx(params: SignTransferTxParams): Promise<SubmissionResult> {
169
+ const signResult = await this.signTransferTx(params)
170
+ return this.submitTransaction(signResult.unsignedTx, signResult.signature)
187
171
  }
188
-
189
- async submitTransaction(unsignedTx: string, signerAddress?: string): Promise<SubmissionResult> {
190
- const decoded = await web3
191
- .getCurrentNodeProvider()
192
- .transactions.postTransactionsDecodeUnsignedTx({ unsignedTx: unsignedTx })
193
- const txId = decoded.unsignedTx.txId
194
-
195
- const address = typeof signerAddress !== 'undefined' ? signerAddress : (await this.getActiveAccount()).address
196
- const signature = await this.signRaw(address, txId)
197
- const params: node.SubmitTransaction = { unsignedTx: unsignedTx, signature: signature }
198
- return web3.getCurrentNodeProvider().transactions.postTransactionsSubmit(params)
172
+ async signAndSubmitDeployContractTx(params: SignDeployContractTxParams): Promise<SubmissionResult> {
173
+ const signResult = await this.signDeployContractTx(params)
174
+ return this.submitTransaction(signResult.unsignedTx, signResult.signature)
199
175
  }
200
-
201
- private shouldSubmitTx(params: SubmitTx): boolean {
202
- return this.alwaysSubmitTx || (params.submitTx ? params.submitTx : true)
176
+ async signAndSubmitExecuteScriptTx(params: SignExecuteScriptTxParams): Promise<SubmissionResult> {
177
+ const signResult = await this.signExecuteScriptTx(params)
178
+ return this.submitTransaction(signResult.unsignedTx, signResult.signature)
179
+ }
180
+ async signAndSubmitUnsignedTx(params: SignUnsignedTxParams): Promise<SubmissionResult> {
181
+ const signResult = await this.signUnsignedTx(params)
182
+ return this.submitTransaction(signResult.unsignedTx, signResult.signature)
203
183
  }
204
184
 
205
185
  private async usePublicKey<T extends SignerAddress>(
206
186
  params: T
207
187
  ): Promise<Omit<T, 'signerAddress'> & { fromPublicKey: string }> {
208
188
  const { signerAddress, ...restParams } = params
209
- const allAccounts = await this.getAccounts()
210
- const signerAccount = allAccounts.find((account) => account.address === signerAddress)
211
- if (typeof signerAccount === 'undefined') {
212
- throw new Error('Unknown signer address')
189
+ const selectedAccount = await this.getSelectedAccount()
190
+ if (signerAddress !== selectedAccount.address) {
191
+ throw new Error('The signer address is not the selected address')
213
192
  } else {
214
- return { fromPublicKey: signerAccount.publicKey, ...restParams }
193
+ return { fromPublicKey: selectedAccount.publicKey, ...restParams }
215
194
  }
216
195
  }
217
196
 
218
197
  async signTransferTx(params: SignTransferTxParams): Promise<SignTransferTxResult> {
219
198
  const response = await this.buildTransferTx(params)
220
- return this.handleSign({ signerAddress: params.signerAddress, ...response }, this.shouldSubmitTx(params))
199
+ return this.handleSign({ signerAddress: params.signerAddress, ...response })
221
200
  }
222
201
 
223
202
  async buildTransferTx(params: SignTransferTxParams): Promise<node.BuildTransactionResult> {
@@ -226,15 +205,12 @@ export abstract class SignerWithNodeProvider implements SignerProvider {
226
205
  destinations: toApiDestinations(params.destinations),
227
206
  gasPrice: toApiNumber256Optional(params.gasPrice)
228
207
  }
229
- return web3.getCurrentNodeProvider().transactions.postTransactionsBuild(data)
208
+ return this.nodeProvider.transactions.postTransactionsBuild(data)
230
209
  }
231
210
 
232
211
  async signDeployContractTx(params: SignDeployContractTxParams): Promise<SignDeployContractTxResult> {
233
212
  const response = await this.buildContractCreationTx(params)
234
- const result = await this.handleSign(
235
- { signerAddress: params.signerAddress, ...response },
236
- this.shouldSubmitTx(params)
237
- )
213
+ const result = await this.handleSign({ signerAddress: params.signerAddress, ...response })
238
214
  const contractId = utils.binToHex(utils.contractIdFromAddress(response.contractAddress))
239
215
  return { ...result, contractId: contractId, contractAddress: response.contractAddress }
240
216
  }
@@ -247,12 +223,12 @@ export abstract class SignerWithNodeProvider implements SignerProvider {
247
223
  issueTokenAmount: toApiNumber256Optional(params.issueTokenAmount),
248
224
  gasPrice: toApiNumber256Optional(params.gasPrice)
249
225
  }
250
- return web3.getCurrentNodeProvider().contracts.postContractsUnsignedTxDeployContract(data)
226
+ return this.nodeProvider.contracts.postContractsUnsignedTxDeployContract(data)
251
227
  }
252
228
 
253
229
  async signExecuteScriptTx(params: SignExecuteScriptTxParams): Promise<SignExecuteScriptTxResult> {
254
230
  const response = await this.buildScriptTx(params)
255
- return this.handleSign({ signerAddress: params.signerAddress, ...response }, this.shouldSubmitTx(params))
231
+ return this.handleSign({ signerAddress: params.signerAddress, ...response })
256
232
  }
257
233
 
258
234
  async buildScriptTx(params: SignExecuteScriptTxParams): Promise<node.BuildExecuteScriptTxResult> {
@@ -260,39 +236,32 @@ export abstract class SignerWithNodeProvider implements SignerProvider {
260
236
  ...(await this.usePublicKey(params)),
261
237
  tokens: toApiTokens(params.tokens)
262
238
  }
263
- return web3.getCurrentNodeProvider().contracts.postContractsUnsignedTxExecuteScript(data)
239
+ return this.nodeProvider.contracts.postContractsUnsignedTxExecuteScript(data)
264
240
  }
265
241
 
266
242
  // in general, wallet should show the decoded information to user for confirmation
267
243
  // please overwrite this function for real wallet
268
244
  async signUnsignedTx(params: SignUnsignedTxParams): Promise<SignUnsignedTxResult> {
269
245
  const data = { unsignedTx: params.unsignedTx }
270
- const decoded = await web3.getCurrentNodeProvider().transactions.postTransactionsDecodeUnsignedTx(data)
271
- return this.handleSign(
272
- {
273
- fromGroup: decoded.fromGroup,
274
- toGroup: decoded.toGroup,
275
- signerAddress: params.signerAddress,
276
- unsignedTx: params.unsignedTx,
277
- txId: decoded.unsignedTx.txId
278
- },
279
- params.submitTx ? params.submitTx : true // we don't consider `alwaysSubmitTx` as the tx might needs multiple signatures
280
- )
246
+ const decoded = await this.nodeProvider.transactions.postTransactionsDecodeUnsignedTx(data)
247
+ return this.handleSign({
248
+ fromGroup: decoded.fromGroup,
249
+ toGroup: decoded.toGroup,
250
+ signerAddress: params.signerAddress,
251
+ unsignedTx: params.unsignedTx,
252
+ txId: decoded.unsignedTx.txId
253
+ })
281
254
  }
282
255
 
283
- protected async handleSign(
284
- response: { fromGroup: number; toGroup: number; signerAddress: string; unsignedTx: string; txId: string },
285
- submitTx: boolean
286
- ): Promise<SignResult> {
256
+ protected async handleSign(response: {
257
+ fromGroup: number
258
+ toGroup: number
259
+ signerAddress: string
260
+ unsignedTx: string
261
+ txId: string
262
+ }): Promise<SignResult> {
287
263
  // sign the tx
288
264
  const signature = await this.signRaw(response.signerAddress, response.txId)
289
- // submit the tx if required
290
- if (submitTx) {
291
- await web3.getCurrentNodeProvider().transactions.postTransactionsSubmit({
292
- unsignedTx: response.unsignedTx,
293
- signature: signature
294
- })
295
- }
296
265
  // return the signature back to the provider
297
266
  return {
298
267
  fromGroup: response.fromGroup,
@@ -318,6 +287,22 @@ export abstract class SignerWithNodeProvider implements SignerProvider {
318
287
  abstract signRaw(signerAddress: string, hexString: string): Promise<string>
319
288
  }
320
289
 
290
+ export abstract class SignerProviderWithMultipleAccounts extends SignerProvider {
291
+ abstract getAccounts(): Promise<Account[]>
292
+
293
+ async getAccount(signerAddress: string): Promise<Account> {
294
+ const accounts = await this.getAccounts()
295
+ const account = accounts.find((a) => a.address === signerAddress)
296
+ if (typeof account === 'undefined') {
297
+ throw new Error('Unmatched signerAddress')
298
+ } else {
299
+ return account
300
+ }
301
+ }
302
+
303
+ abstract setSelectedAccount(address: string): Promise<void>
304
+ }
305
+
321
306
  export interface SubmissionResult {
322
307
  txId: string
323
308
  fromGroup: number
@@ -17,8 +17,6 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
 
19
19
  import EventEmitter from 'eventemitter3'
20
- import { getCurrentNodeProvider } from '../global'
21
- import { NodeProvider } from '../api'
22
20
 
23
21
  type MessageCallback<Message> = (message: Message) => Promise<void>
24
22
  type ErrorCallback<Message> = (error: any, subscription: Subscription<Message>) => Promise<void>