@alephium/web3 0.2.0-test.1 → 0.2.0

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.
Files changed (128) hide show
  1. package/.eslintignore +2 -2
  2. package/README.md +2 -135
  3. package/dist/alephium-web3.min.js +1 -1
  4. package/dist/alephium-web3.min.js.LICENSE.txt +0 -17
  5. package/dist/alephium-web3.min.js.map +1 -1
  6. package/dist/src/api/api-alephium.d.ts +115 -17
  7. package/dist/src/api/api-alephium.js +145 -80
  8. package/dist/src/api/api-explorer.d.ts +178 -51
  9. package/dist/src/api/api-explorer.js +172 -37
  10. package/dist/src/api/index.d.ts +40 -5
  11. package/dist/src/api/index.js +115 -7
  12. package/dist/src/api/types.d.ts +23 -0
  13. package/dist/src/api/types.js +235 -0
  14. package/dist/src/api/utils.d.ts +6 -0
  15. package/dist/{scripts/rename-gitignore.js → src/api/utils.js} +11 -6
  16. package/dist/src/contract/contract.d.ts +68 -55
  17. package/dist/src/contract/contract.js +235 -384
  18. package/dist/src/contract/events.d.ts +4 -4
  19. package/dist/src/contract/events.js +2 -1
  20. package/dist/src/contract/index.js +5 -1
  21. package/dist/src/contract/ralph.d.ts +5 -4
  22. package/dist/src/contract/ralph.js +27 -1
  23. package/dist/src/global.d.ts +6 -2
  24. package/dist/src/global.js +19 -3
  25. package/dist/src/index.d.ts +2 -1
  26. package/dist/src/index.js +23 -2
  27. package/dist/src/signer/index.d.ts +0 -1
  28. package/dist/src/signer/index.js +5 -2
  29. package/dist/src/signer/signer.d.ts +59 -60
  30. package/dist/src/signer/signer.js +99 -70
  31. package/dist/src/transaction/index.d.ts +0 -1
  32. package/dist/src/transaction/index.js +5 -2
  33. package/dist/src/transaction/status.d.ts +2 -1
  34. package/dist/src/transaction/status.js +2 -1
  35. package/dist/src/utils/bs58.d.ts +1 -0
  36. package/dist/src/utils/bs58.js +13 -1
  37. package/dist/src/utils/index.d.ts +0 -1
  38. package/dist/src/utils/index.js +5 -2
  39. package/dist/src/utils/subscription.d.ts +0 -2
  40. package/dist/src/utils/subscription.js +0 -2
  41. package/dist/src/utils/utils.d.ts +4 -9
  42. package/dist/src/utils/utils.js +20 -24
  43. package/jest-config.json +11 -0
  44. package/package.json +11 -45
  45. package/src/api/api-alephium.ts +162 -25
  46. package/src/api/api-explorer.ts +247 -54
  47. package/src/api/index.ts +140 -6
  48. package/src/api/types.ts +229 -0
  49. package/{scripts/rename-gitignore.js → src/api/utils.ts} +7 -6
  50. package/src/contract/contract.ts +398 -429
  51. package/src/contract/events.ts +6 -5
  52. package/src/contract/ralph.ts +29 -4
  53. package/src/global.ts +23 -3
  54. package/src/index.ts +7 -1
  55. package/src/signer/index.ts +0 -1
  56. package/src/signer/signer.ts +165 -135
  57. package/src/transaction/index.ts +0 -1
  58. package/src/transaction/status.ts +5 -2
  59. package/src/utils/bs58.ts +11 -0
  60. package/src/utils/index.ts +0 -1
  61. package/src/utils/subscription.ts +0 -4
  62. package/src/utils/utils.ts +11 -19
  63. package/webpack.config.js +3 -0
  64. package/.eslintrc.json +0 -21
  65. package/LICENSE +0 -165
  66. package/contracts/add/add.ral +0 -13
  67. package/contracts/greeter/greeter.ral +0 -7
  68. package/contracts/greeter/greeter_interface.ral +0 -4
  69. package/contracts/greeter_main.ral +0 -7
  70. package/contracts/main.ral +0 -4
  71. package/contracts/sub/sub.ral +0 -10
  72. package/contracts/test/metadata.ral +0 -18
  73. package/contracts/test/warnings.ral +0 -8
  74. package/dev/user.conf +0 -29
  75. package/dist/scripts/create-project.d.ts +0 -2
  76. package/dist/scripts/create-project.js +0 -125
  77. package/dist/scripts/rename-gitignore.d.ts +0 -1
  78. package/dist/scripts/start-devnet.d.ts +0 -1
  79. package/dist/scripts/start-devnet.js +0 -131
  80. package/dist/scripts/stop-devnet.d.ts +0 -1
  81. package/dist/scripts/stop-devnet.js +0 -32
  82. package/dist/src/signer/node-wallet.d.ts +0 -11
  83. package/dist/src/signer/node-wallet.js +0 -57
  84. package/dist/src/test/index.d.ts +0 -6
  85. package/dist/src/test/index.js +0 -41
  86. package/dist/src/test/privatekey-wallet.d.ts +0 -11
  87. package/dist/src/test/privatekey-wallet.js +0 -68
  88. package/dist/src/transaction/sign-verify.d.ts +0 -2
  89. package/dist/src/transaction/sign-verify.js +0 -58
  90. package/dist/src/utils/password-crypto.d.ts +0 -2
  91. package/dist/src/utils/password-crypto.js +0 -69
  92. package/gitignore +0 -9
  93. package/scripts/create-project.ts +0 -137
  94. package/scripts/start-devnet.js +0 -141
  95. package/scripts/stop-devnet.js +0 -32
  96. package/src/contract/ralph.test.ts +0 -178
  97. package/src/fixtures/address.json +0 -36
  98. package/src/fixtures/balance.json +0 -9
  99. package/src/fixtures/self-clique.json +0 -19
  100. package/src/fixtures/transaction.json +0 -13
  101. package/src/fixtures/transactions.json +0 -179
  102. package/src/signer/fixtures/genesis.json +0 -26
  103. package/src/signer/fixtures/wallets.json +0 -26
  104. package/src/signer/node-wallet.ts +0 -65
  105. package/src/test/index.ts +0 -31
  106. package/src/test/privatekey-wallet.ts +0 -57
  107. package/src/transaction/sign-verify.test.ts +0 -50
  108. package/src/transaction/sign-verify.ts +0 -39
  109. package/src/utils/address.test.ts +0 -47
  110. package/src/utils/djb2.test.ts +0 -35
  111. package/src/utils/password-crypto.test.ts +0 -27
  112. package/src/utils/password-crypto.ts +0 -77
  113. package/src/utils/utils.test.ts +0 -161
  114. package/templates/base/README.md +0 -34
  115. package/templates/base/package.json +0 -35
  116. package/templates/base/src/greeter.ts +0 -42
  117. package/templates/base/tsconfig.json +0 -19
  118. package/templates/react/README.md +0 -34
  119. package/templates/react/config-overrides.js +0 -18
  120. package/templates/react/package.json +0 -66
  121. package/templates/react/src/App.tsx +0 -42
  122. package/templates/react/src/artifacts/greeter.ral.json +0 -26
  123. package/templates/react/src/artifacts/greeter_main.ral.json +0 -22
  124. package/templates/shared/.eslintrc.json +0 -12
  125. package/templates/shared/scripts/header.js +0 -0
  126. package/test/contract.test.ts +0 -213
  127. package/test/events.test.ts +0 -141
  128. package/test/transaction.test.ts +0 -73
@@ -16,14 +16,15 @@ You should have received a copy of the GNU Lesser General Public License
16
16
  along with the library. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
 
19
- import { ContractEvent } from '../api/api-alephium'
19
+ import { web3 } from '..'
20
+ import { node } from '../api'
20
21
  import { Subscription, SubscribeOptions } from '../utils'
21
22
 
22
- export class EventSubscription extends Subscription<ContractEvent> {
23
+ export class EventSubscription extends Subscription<node.ContractEvent> {
23
24
  readonly contractAddress: string
24
25
  private fromCount: number
25
26
 
26
- constructor(options: SubscribeOptions<ContractEvent>, contractAddress: string, fromCount?: number) {
27
+ constructor(options: SubscribeOptions<node.ContractEvent>, contractAddress: string, fromCount?: number) {
27
28
  super(options)
28
29
  this.contractAddress = contractAddress
29
30
  this.fromCount = typeof fromCount === 'undefined' ? 0 : fromCount
@@ -44,7 +45,7 @@ export class EventSubscription extends Subscription<ContractEvent> {
44
45
 
45
46
  override async polling(): Promise<void> {
46
47
  try {
47
- const events = await this.provider.events.getEventsContractContractaddress(this.contractAddress, {
48
+ const events = await web3.getCurrentNodeProvider().events.getEventsContractContractaddress(this.contractAddress, {
48
49
  start: this.fromCount
49
50
  })
50
51
  if (this.cancelled) {
@@ -67,7 +68,7 @@ export class EventSubscription extends Subscription<ContractEvent> {
67
68
  }
68
69
 
69
70
  export function subscribeToEvents(
70
- options: SubscribeOptions<ContractEvent>,
71
+ options: SubscribeOptions<node.ContractEvent>,
71
72
  contractAddress: string,
72
73
  fromCount?: number
73
74
  ): EventSubscription {
@@ -17,9 +17,9 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
 
19
19
  import { Buffer } from 'buffer/'
20
+ import { Val } from '../api'
20
21
  import { bs58, isHexString } from '../utils'
21
- import { node } from '../api'
22
- import { Fields, Val } from './contract'
22
+ import { Fields, FieldsSig } from './contract'
23
23
 
24
24
  const bigIntZero = BigInt(0)
25
25
 
@@ -236,7 +236,7 @@ export function encodeScriptField(tpe: string, value: Val): Uint8Array {
236
236
 
237
237
  const scriptFieldRegex = /\{([0-9]*)\}/g
238
238
 
239
- export function buildScriptByteCode(bytecodeTemplate: string, fields: Fields, fieldsSig: node.FieldsSig): string {
239
+ export function buildScriptByteCode(bytecodeTemplate: string, fields: Fields, fieldsSig: FieldsSig): string {
240
240
  return bytecodeTemplate.replace(scriptFieldRegex, (_, fieldIndex: string) => {
241
241
  const fieldName = fieldsSig.names[`${fieldIndex}`]
242
242
  const fieldType = fieldsSig.types[`${fieldIndex}`]
@@ -249,7 +249,7 @@ export function buildScriptByteCode(bytecodeTemplate: string, fields: Fields, fi
249
249
  })
250
250
  }
251
251
 
252
- export function buildContractByteCode(bytecode: string, fields: Fields, fieldsSig: node.FieldsSig): string {
252
+ export function buildContractByteCode(bytecode: string, fields: Fields, fieldsSig: FieldsSig): string {
253
253
  const fieldsEncoded = fieldsSig.names.flatMap((fieldName, fieldIndex) => {
254
254
  const fieldType = fieldsSig.types[`${fieldIndex}`]
255
255
  if (fieldName in fields) {
@@ -343,6 +343,31 @@ function invalidVal(tpe: string, value: Val): Error {
343
343
  return Error(`Invalid API value ${value} for type ${tpe}`)
344
344
  }
345
345
 
346
+ export function buildDebugBytecode(bytecode: string, bytecodePatch: string): string {
347
+ if (bytecodePatch === '') {
348
+ return bytecode
349
+ }
350
+
351
+ const pattern = /[=+-][0-9a-f]*/g
352
+ let result = ''
353
+ let index = 0
354
+ for (const parts of bytecodePatch.matchAll(pattern)) {
355
+ const part = parts[0]
356
+ const diffType = part[0]
357
+ if (diffType === '=') {
358
+ const length = parseInt(part.substring(1))
359
+ result = result + bytecode.slice(index, index + length)
360
+ index = index + length
361
+ } else if (diffType === '+') {
362
+ result = result + part.substring(1)
363
+ } else {
364
+ const length = parseInt(part.substring(1))
365
+ index = index + length
366
+ }
367
+ }
368
+ return result
369
+ }
370
+
346
371
  // export function buildContractByteCode(
347
372
  // compiled: node.TemplateContractByteCode,
348
373
  // templateVariables: TemplateVariables
package/src/global.ts CHANGED
@@ -16,13 +16,15 @@ You should have received a copy of the GNU Lesser General Public License
16
16
  along with the library. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
 
19
- import { NodeProvider } from './api'
19
+ import { ExplorerProvider, NodeProvider } from './api'
20
20
 
21
21
  let _currentNodeProvider: NodeProvider | undefined = undefined
22
22
 
23
- export function setCurrentNodeProvider(provider: NodeProvider | string): void {
23
+ export function setCurrentNodeProvider(provider: NodeProvider): void
24
+ export function setCurrentNodeProvider(baseUrl: string, apiKey?: string): void
25
+ export function setCurrentNodeProvider(provider: NodeProvider | string, apiKey?: string): void {
24
26
  if (typeof provider == 'string') {
25
- _currentNodeProvider = new NodeProvider(provider)
27
+ _currentNodeProvider = new NodeProvider(provider, apiKey)
26
28
  } else {
27
29
  _currentNodeProvider = provider
28
30
  }
@@ -34,3 +36,21 @@ export function getCurrentNodeProvider(): NodeProvider {
34
36
  }
35
37
  return _currentNodeProvider
36
38
  }
39
+
40
+ let _currentExplorerProvider: ExplorerProvider | undefined = undefined
41
+
42
+ export function setCurrentExplorerProvider(provider: ExplorerProvider): void
43
+ export function setCurrentExplorerProvider(baseUrl: string, apiKey?: string): void
44
+ export function setCurrentExplorerProvider(provider: ExplorerProvider | string, apiKey?: string): void {
45
+ if (typeof provider == 'string') {
46
+ _currentExplorerProvider = new ExplorerProvider(provider, apiKey)
47
+ } else {
48
+ _currentExplorerProvider = provider
49
+ }
50
+ }
51
+
52
+ // Different from `NodeProvider`, this may return `undefined`
53
+ // as ExplorerProvider is not necessary for all applications
54
+ export function getCurrentExplorerProvider(): ExplorerProvider | undefined {
55
+ return _currentExplorerProvider
56
+ }
package/src/index.ts CHANGED
@@ -16,6 +16,10 @@ You should have received a copy of the GNU Lesser General Public License
16
16
  along with the library. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
 
19
+ BigInt.prototype['toJSON'] = function () {
20
+ return this.toString()
21
+ }
22
+
19
23
  export * from './api'
20
24
  export * from './contract'
21
25
  export * from './signer'
@@ -23,4 +27,6 @@ export * from './utils'
23
27
  export * from './transaction'
24
28
 
25
29
  export * from './constants'
26
- export * from './global'
30
+ export * as web3 from './global'
31
+
32
+ export * as utils from './utils'
@@ -17,4 +17,3 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
 
19
19
  export * from './signer'
20
- export * from './node-wallet'
@@ -17,23 +17,25 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
 
19
19
  import { ec as EC } from 'elliptic'
20
- import { NodeProvider } from '../api'
20
+ import {
21
+ ExplorerProvider,
22
+ fromApiNumber256,
23
+ fromApiTokens,
24
+ NodeProvider,
25
+ Number256,
26
+ toApiNumber256,
27
+ toApiNumber256Optional,
28
+ toApiTokens,
29
+ Token
30
+ } from '../api'
21
31
  import { node } from '../api'
22
32
  import * as utils from '../utils'
23
33
  import { Eq, assertType } from '../utils'
24
34
  import blake from 'blakejs'
25
- import { Token } from '../api/api-alephium'
26
- import { getCurrentNodeProvider } from '../global'
27
35
 
28
- const ec = new EC('secp256k1')
36
+ export type OutputRef = node.OutputRef
29
37
 
30
- export interface SignResult {
31
- fromGroup: number
32
- toGroup: number
33
- unsignedTx: string
34
- txId: string
35
- signature: string
36
- }
38
+ const ec = new EC('secp256k1')
37
39
 
38
40
  export interface Account {
39
41
  address: string
@@ -41,42 +43,39 @@ export interface Account {
41
43
  publicKey: string
42
44
  }
43
45
 
44
- export type SubmitTx = { submitTx?: boolean }
45
46
  export type SignerAddress = { signerAddress: string }
46
- type TxBuildParams<T> = Omit<T, 'fromPublicKey' | 'targetBlockHash'> & SignerAddress & SubmitTx
47
-
48
- export type GetAccountsParams = undefined
49
- export type GetAccountsResult = Account[]
47
+ type TxBuildParams<T> = Omit<T, 'fromPublicKey' | 'targetBlockHash'> & SignerAddress
48
+ type SignResult<T> = Omit<T, 'gasPrice'> & { signature: string; gasPrice: Number256 }
50
49
 
51
50
  export interface SignTransferTxParams {
52
51
  signerAddress: string
53
- destinations: node.Destination[]
54
- utxos?: node.OutputRef[]
52
+ destinations: Destination[]
53
+ utxos?: OutputRef[]
55
54
  gasAmount?: number
56
- gasPrice?: string
57
- submitTx?: boolean
55
+ gasPrice?: Number256
58
56
  }
59
- assertType<Eq<SignTransferTxParams, TxBuildParams<node.BuildTransaction>>>()
57
+ assertType<Eq<keyof SignTransferTxParams, keyof TxBuildParams<node.BuildTransaction>>>()
60
58
  export interface SignTransferTxResult {
61
59
  fromGroup: number
62
60
  toGroup: number
63
61
  unsignedTx: string
64
62
  txId: string
65
63
  signature: string
64
+ gasAmount: number
65
+ gasPrice: Number256
66
66
  }
67
- assertType<Eq<SignTransferTxResult, SignResult>>()
67
+ assertType<Eq<SignTransferTxResult, SignResult<node.BuildTransactionResult>>>()
68
68
 
69
69
  export interface SignDeployContractTxParams {
70
70
  signerAddress: string
71
71
  bytecode: string
72
- initialAttoAlphAmount?: string
72
+ initialAttoAlphAmount?: Number256
73
73
  initialTokenAmounts?: Token[]
74
- issueTokenAmount?: string
74
+ issueTokenAmount?: Number256
75
75
  gasAmount?: number
76
- gasPrice?: string
77
- submitTx?: boolean
76
+ gasPrice?: Number256
78
77
  }
79
- assertType<Eq<SignDeployContractTxParams, TxBuildParams<node.BuildDeployContractTx>>>()
78
+ assertType<Eq<keyof SignDeployContractTxParams, keyof TxBuildParams<node.BuildDeployContractTx>>>()
80
79
  export interface SignDeployContractTxResult {
81
80
  fromGroup: number
82
81
  toGroup: number
@@ -85,52 +84,46 @@ export interface SignDeployContractTxResult {
85
84
  signature: string
86
85
  contractId: string
87
86
  contractAddress: string
87
+ gasAmount: number
88
+ gasPrice: Number256
88
89
  }
89
- assertType<Eq<SignDeployContractTxResult, SignResult & { contractId: string; contractAddress: string }>>()
90
+ assertType<Eq<SignDeployContractTxResult, SignResult<node.BuildDeployContractTxResult> & { contractId: string }>>()
90
91
 
91
92
  export interface SignExecuteScriptTxParams {
92
93
  signerAddress: string
93
94
  bytecode: string
94
- attoAlphAmount?: string
95
- tokens?: node.Token[]
95
+ attoAlphAmount?: Number256
96
+ tokens?: Token[]
96
97
  gasAmount?: number
97
- gasPrice?: string
98
- submitTx?: boolean
98
+ gasPrice?: Number256
99
99
  }
100
- assertType<Eq<SignExecuteScriptTxParams, TxBuildParams<node.BuildExecuteScriptTx>>>()
100
+ assertType<Eq<keyof SignExecuteScriptTxParams, keyof TxBuildParams<node.BuildExecuteScriptTx>>>()
101
101
  export interface SignExecuteScriptTxResult {
102
102
  fromGroup: number
103
103
  toGroup: number
104
104
  unsignedTx: string
105
105
  txId: string
106
106
  signature: string
107
+ gasAmount: number
108
+ gasPrice: Number256
107
109
  }
108
- assertType<Eq<SignExecuteScriptTxResult, SignResult>>()
110
+ assertType<Eq<SignExecuteScriptTxResult, SignResult<node.BuildExecuteScriptTxResult>>>()
109
111
 
110
112
  export interface SignUnsignedTxParams {
111
113
  signerAddress: string
112
114
  unsignedTx: string
113
- submitTx?: boolean
114
115
  }
115
- assertType<Eq<SignUnsignedTxParams, { unsignedTx: string } & SubmitTx & SignerAddress>>()
116
+ assertType<Eq<SignUnsignedTxParams, { unsignedTx: string } & SignerAddress>>()
116
117
  export interface SignUnsignedTxResult {
117
118
  fromGroup: number
118
119
  toGroup: number
119
120
  unsignedTx: string
120
121
  txId: string
121
122
  signature: string
123
+ gasAmount: number
124
+ gasPrice: Number256
122
125
  }
123
- assertType<Eq<SignUnsignedTxResult, SignResult>>()
124
-
125
- export interface SignHexStringParams {
126
- signerAddress: string
127
- hexString: string
128
- }
129
- assertType<Eq<SignHexStringParams, { hexString: string } & SignerAddress>>()
130
- export interface SignHexStringResult {
131
- signature: string
132
- }
133
- assertType<Eq<SignHexStringResult, Pick<SignResult, 'signature'>>>()
126
+ assertType<Eq<SignUnsignedTxResult, SignTransferTxResult>>
134
127
 
135
128
  export interface SignMessageParams {
136
129
  signerAddress: string
@@ -140,144 +133,150 @@ assertType<Eq<SignMessageParams, { message: string } & SignerAddress>>()
140
133
  export interface SignMessageResult {
141
134
  signature: string
142
135
  }
143
- assertType<Eq<SignMessageResult, Pick<SignResult, 'signature'>>>()
136
+
137
+ export interface SubmitTransactionParams {
138
+ unsignedTx: string
139
+ signature: string
140
+ }
141
+ export interface SubmissionResult {
142
+ txId: string
143
+ fromGroup: number
144
+ toGroup: number
145
+ }
144
146
 
145
147
  export interface SignerProvider {
146
- getAccounts(): Promise<Account[]>
147
- signTransferTx(params: SignTransferTxParams): Promise<SignTransferTxResult>
148
- signDeployContractTx(params: SignDeployContractTxParams): Promise<SignDeployContractTxResult>
149
- signExecuteScriptTx(params: SignExecuteScriptTxParams): Promise<SignExecuteScriptTxResult>
148
+ get nodeProvider(): NodeProvider | undefined
149
+ get explorerProvider(): ExplorerProvider | undefined
150
+
151
+ getSelectedAccount(): Promise<Account>
152
+
153
+ signAndSubmitTransferTx(params: SignTransferTxParams): Promise<SignTransferTxResult>
154
+ signAndSubmitDeployContractTx(params: SignDeployContractTxParams): Promise<SignDeployContractTxResult>
155
+ signAndSubmitExecuteScriptTx(params: SignExecuteScriptTxParams): Promise<SignExecuteScriptTxResult>
156
+ signAndSubmitUnsignedTx(params: SignUnsignedTxParams): Promise<SignUnsignedTxResult>
157
+
150
158
  signUnsignedTx(params: SignUnsignedTxParams): Promise<SignUnsignedTxResult>
151
- signHexString(params: SignHexStringParams): Promise<SignHexStringResult>
159
+ // The message will be prefixed with 'Alephium Signed Message: ' before signing
160
+ // so that the resulted signature cannot be reused for building transactions.
152
161
  signMessage(params: SignMessageParams): Promise<SignMessageResult>
153
162
  }
154
163
 
155
- export abstract class SignerWithNodeProvider implements SignerProvider {
156
- readonly provider: NodeProvider
157
- alwaysSubmitTx: boolean
158
-
159
- abstract getAccounts(): Promise<Account[]>
164
+ export abstract class SignerProviderSimple implements SignerProvider {
165
+ abstract get nodeProvider(): NodeProvider | undefined
166
+ abstract get explorerProvider(): ExplorerProvider | undefined
167
+ abstract getSelectedAccount(): Promise<Account>
160
168
 
161
- async getAccount(signerAddress: string): Promise<Account> {
162
- const accounts = await this.getAccounts()
163
- const account = accounts.find((a) => a.address === signerAddress)
164
- if (typeof account === 'undefined') {
165
- throw new Error('Unmatched signerAddress')
166
- } else {
167
- return account
169
+ private getNodeProvider(): NodeProvider {
170
+ if (this.nodeProvider === undefined) {
171
+ throw Error('The signer does not contain a node provider')
168
172
  }
173
+ return this.nodeProvider
169
174
  }
170
175
 
171
- constructor(alwaysSubmitTx: boolean) {
172
- this.provider = getCurrentNodeProvider()
173
- this.alwaysSubmitTx = alwaysSubmitTx
176
+ async submitTransaction(params: SubmitTransactionParams): Promise<SubmissionResult> {
177
+ const data: node.SubmitTransaction = { unsignedTx: params.unsignedTx, signature: params.signature }
178
+ return this.getNodeProvider().transactions.postTransactionsSubmit(data)
174
179
  }
175
180
 
176
- private async defaultSignerAddress(): Promise<string> {
177
- return (await this.getAccounts())[0].address
181
+ async signAndSubmitTransferTx(params: SignTransferTxParams): Promise<SignTransferTxResult> {
182
+ const signResult = await this.signTransferTx(params)
183
+ await this.submitTransaction(signResult)
184
+ return signResult
178
185
  }
179
-
180
- async submitTransaction(unsignedTx: string, txHash: string, signerAddress?: string): Promise<SubmissionResult> {
181
- const address = typeof signerAddress !== 'undefined' ? signerAddress : await this.defaultSignerAddress()
182
- const signature = await this.signRaw(address, txHash)
183
- const params: node.SubmitTransaction = { unsignedTx: unsignedTx, signature: signature }
184
- return this.provider.transactions.postTransactionsSubmit(params)
186
+ async signAndSubmitDeployContractTx(params: SignDeployContractTxParams): Promise<SignDeployContractTxResult> {
187
+ const signResult = await this.signDeployContractTx(params)
188
+ await this.submitTransaction(signResult)
189
+ return signResult
185
190
  }
186
-
187
- private shouldSubmitTx(params: SubmitTx): boolean {
188
- return this.alwaysSubmitTx || (params.submitTx ? params.submitTx : true)
191
+ async signAndSubmitExecuteScriptTx(params: SignExecuteScriptTxParams): Promise<SignExecuteScriptTxResult> {
192
+ const signResult = await this.signExecuteScriptTx(params)
193
+ await this.submitTransaction(signResult)
194
+ return signResult
195
+ }
196
+ async signAndSubmitUnsignedTx(params: SignUnsignedTxParams): Promise<SignUnsignedTxResult> {
197
+ const signResult = await this.signUnsignedTx(params)
198
+ await this.submitTransaction(signResult)
199
+ return signResult
189
200
  }
190
201
 
191
202
  private async usePublicKey<T extends SignerAddress>(
192
203
  params: T
193
204
  ): Promise<Omit<T, 'signerAddress'> & { fromPublicKey: string }> {
194
205
  const { signerAddress, ...restParams } = params
195
- const allAccounts = await this.getAccounts()
196
- const signerAccount = allAccounts.find((account) => account.address === signerAddress)
197
- if (typeof signerAccount === 'undefined') {
198
- throw new Error('Unknown signer address')
206
+ const selectedAccount = await this.getSelectedAccount()
207
+ if (signerAddress !== selectedAccount.address) {
208
+ throw new Error('The signer address is not the selected address')
199
209
  } else {
200
- return { fromPublicKey: signerAccount.publicKey, ...restParams }
210
+ return { fromPublicKey: selectedAccount.publicKey, ...restParams }
201
211
  }
202
212
  }
203
213
 
204
214
  async signTransferTx(params: SignTransferTxParams): Promise<SignTransferTxResult> {
205
215
  const response = await this.buildTransferTx(params)
206
- return this.handleSign({ signerAddress: params.signerAddress, ...response }, this.shouldSubmitTx(params))
216
+ const signature = await this.signRaw(params.signerAddress, response.txId)
217
+ return { ...response, signature, gasPrice: fromApiNumber256(response.gasPrice) }
207
218
  }
208
219
 
209
220
  async buildTransferTx(params: SignTransferTxParams): Promise<node.BuildTransactionResult> {
210
- return this.provider.transactions.postTransactionsBuild(await this.usePublicKey(params))
221
+ const data: node.BuildTransaction = {
222
+ ...(await this.usePublicKey(params)),
223
+ destinations: toApiDestinations(params.destinations),
224
+ gasPrice: toApiNumber256Optional(params.gasPrice)
225
+ }
226
+ return this.getNodeProvider().transactions.postTransactionsBuild(data)
211
227
  }
212
228
 
213
229
  async signDeployContractTx(params: SignDeployContractTxParams): Promise<SignDeployContractTxResult> {
214
230
  const response = await this.buildContractCreationTx(params)
215
- const result = await this.handleSign(
216
- { signerAddress: params.signerAddress, ...response },
217
- this.shouldSubmitTx(params)
218
- )
231
+ const signature = await this.signRaw(params.signerAddress, response.txId)
219
232
  const contractId = utils.binToHex(utils.contractIdFromAddress(response.contractAddress))
220
- return { ...result, contractId: contractId, contractAddress: response.contractAddress }
233
+ return { ...response, contractId, signature, gasPrice: fromApiNumber256(response.gasPrice) }
221
234
  }
222
235
 
223
236
  async buildContractCreationTx(params: SignDeployContractTxParams): Promise<node.BuildDeployContractTxResult> {
224
- return this.provider.contracts.postContractsUnsignedTxDeployContract(await this.usePublicKey(params))
237
+ const data: node.BuildDeployContractTx = {
238
+ ...(await this.usePublicKey(params)),
239
+ initialAttoAlphAmount: toApiNumber256Optional(params.initialAttoAlphAmount),
240
+ initialTokenAmounts: toApiTokens(params.initialTokenAmounts),
241
+ issueTokenAmount: toApiNumber256Optional(params.issueTokenAmount),
242
+ gasPrice: toApiNumber256Optional(params.gasPrice)
243
+ }
244
+ return this.getNodeProvider().contracts.postContractsUnsignedTxDeployContract(data)
225
245
  }
226
246
 
227
247
  async signExecuteScriptTx(params: SignExecuteScriptTxParams): Promise<SignExecuteScriptTxResult> {
228
248
  const response = await this.buildScriptTx(params)
229
- return this.handleSign({ signerAddress: params.signerAddress, ...response }, this.shouldSubmitTx(params))
249
+ const signature = await this.signRaw(params.signerAddress, response.txId)
250
+ return { ...response, signature, gasPrice: fromApiNumber256(response.gasPrice) }
230
251
  }
231
252
 
232
253
  async buildScriptTx(params: SignExecuteScriptTxParams): Promise<node.BuildExecuteScriptTxResult> {
233
- return this.provider.contracts.postContractsUnsignedTxExecuteScript(await this.usePublicKey(params))
254
+ const data: node.BuildExecuteScriptTx = {
255
+ ...(await this.usePublicKey(params)),
256
+ attoAlphAmount: toApiNumber256Optional(params.attoAlphAmount),
257
+ tokens: toApiTokens(params.tokens),
258
+ gasPrice: toApiNumber256Optional(params.gasPrice)
259
+ }
260
+ return this.getNodeProvider().contracts.postContractsUnsignedTxExecuteScript(data)
234
261
  }
235
262
 
236
263
  // in general, wallet should show the decoded information to user for confirmation
237
264
  // please overwrite this function for real wallet
238
265
  async signUnsignedTx(params: SignUnsignedTxParams): Promise<SignUnsignedTxResult> {
239
266
  const data = { unsignedTx: params.unsignedTx }
240
- const decoded = await this.provider.transactions.postTransactionsDecodeUnsignedTx(data)
241
- return this.handleSign(
242
- {
243
- fromGroup: decoded.fromGroup,
244
- toGroup: decoded.toGroup,
245
- signerAddress: params.signerAddress,
246
- unsignedTx: params.unsignedTx,
247
- txId: decoded.unsignedTx.txId
248
- },
249
- params.submitTx ? params.submitTx : true // we don't consider `alwaysSubmitTx` as the tx might needs multiple signatures
250
- )
251
- }
252
-
253
- protected async handleSign(
254
- response: { fromGroup: number; toGroup: number; signerAddress: string; unsignedTx: string; txId: string },
255
- submitTx: boolean
256
- ): Promise<SignResult> {
257
- // sign the tx
258
- const signature = await this.signRaw(response.signerAddress, response.txId)
259
- // submit the tx if required
260
- if (submitTx) {
261
- await this.provider.transactions.postTransactionsSubmit({
262
- unsignedTx: response.unsignedTx,
263
- signature: signature
264
- })
265
- }
266
- // return the signature back to the provider
267
+ const decoded = await this.getNodeProvider().transactions.postTransactionsDecodeUnsignedTx(data)
268
+ const signature = await this.signRaw(params.signerAddress, decoded.unsignedTx.txId)
267
269
  return {
268
- fromGroup: response.fromGroup,
269
- toGroup: response.toGroup,
270
- unsignedTx: response.unsignedTx,
271
- txId: response.txId,
272
- signature: signature
270
+ fromGroup: decoded.fromGroup,
271
+ toGroup: decoded.toGroup,
272
+ unsignedTx: params.unsignedTx,
273
+ txId: decoded.unsignedTx.txId,
274
+ signature,
275
+ gasAmount: decoded.unsignedTx.gasAmount,
276
+ gasPrice: fromApiNumber256(decoded.unsignedTx.gasPrice)
273
277
  }
274
278
  }
275
279
 
276
- async signHexString(params: SignHexStringParams): Promise<SignHexStringResult> {
277
- const signature = await this.signRaw(params.signerAddress, params.hexString)
278
- return { signature: signature }
279
- }
280
-
281
280
  async signMessage(params: SignMessageParams): Promise<SignMessageResult> {
282
281
  const extendedMessage = extendMessage(params.message)
283
282
  const messageHash = blake.blake2b(extendedMessage, undefined, 32)
@@ -288,10 +287,20 @@ export abstract class SignerWithNodeProvider implements SignerProvider {
288
287
  abstract signRaw(signerAddress: string, hexString: string): Promise<string>
289
288
  }
290
289
 
291
- export interface SubmissionResult {
292
- txId: string
293
- fromGroup: number
294
- toGroup: number
290
+ export abstract class SignerProviderWithMultipleAccounts extends SignerProviderSimple {
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>
295
304
  }
296
305
 
297
306
  export function verifyHexString(hexString: string, publicKey: string, signature: string): boolean {
@@ -312,3 +321,24 @@ export function verifySignedMessage(message: string, publicKey: string, signatur
312
321
  const messageHash = blake.blake2b(extendedMessage, undefined, 32)
313
322
  return verifyHexString(utils.binToHex(messageHash), publicKey, signature)
314
323
  }
324
+
325
+ export interface Destination {
326
+ address: string
327
+ attoAlphAmount: Number256
328
+ tokens?: Token[]
329
+ lockTime?: number
330
+ message?: string
331
+ }
332
+ assertType<Eq<keyof Destination, keyof node.Destination>>
333
+
334
+ export function toApiDestination(data: Destination): node.Destination {
335
+ return { ...data, attoAlphAmount: toApiNumber256(data.attoAlphAmount), tokens: toApiTokens(data.tokens) }
336
+ }
337
+
338
+ export function toApiDestinations(data: Destination[]): node.Destination[] {
339
+ return data.map(toApiDestination)
340
+ }
341
+
342
+ export function fromApiDestination(data: node.Destination): Destination {
343
+ return { ...data, attoAlphAmount: fromApiNumber256(data.attoAlphAmount), tokens: fromApiTokens(data.tokens) }
344
+ }
@@ -16,5 +16,4 @@ You should have received a copy of the GNU Lesser General Public License
16
16
  along with the library. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
 
19
- export * from './sign-verify'
20
19
  export * from './status'
@@ -16,9 +16,12 @@ You should have received a copy of the GNU Lesser General Public License
16
16
  along with the library. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
 
19
- import { TxStatus } from '../api/api-alephium'
19
+ import { web3 } from '..'
20
+ import { node } from '../api'
20
21
  import { Subscription, SubscribeOptions } from '../utils'
21
22
 
23
+ export type TxStatus = node.TxStatus
24
+
22
25
  export class TxStatusSubscription extends Subscription<TxStatus> {
23
26
  readonly txId: string
24
27
  readonly fromGroup?: number
@@ -35,7 +38,7 @@ export class TxStatusSubscription extends Subscription<TxStatus> {
35
38
 
36
39
  override async polling(): Promise<void> {
37
40
  try {
38
- const txStatus = await this.provider.transactions.getTransactionsStatus({
41
+ const txStatus = await web3.getCurrentNodeProvider().transactions.getTransactionsStatus({
39
42
  txId: this.txId,
40
43
  fromGroup: this.fromGroup,
41
44
  toGroup: this.toGroup
package/src/utils/bs58.ts CHANGED
@@ -23,4 +23,15 @@ const ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
23
23
 
24
24
  export const bs58 = basex(ALPHABET)
25
25
 
26
+ export function isBase58(s: string): boolean {
27
+ if (s === '' || s.trim() === '') {
28
+ return false
29
+ }
30
+ try {
31
+ return bs58.encode(bs58.decode(s)) === s
32
+ } catch (err) {
33
+ return false
34
+ }
35
+ }
36
+
26
37
  export default bs58
@@ -19,6 +19,5 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
19
19
  export * from './address'
20
20
  export * from './bs58'
21
21
  export * from './djb2'
22
- export * from './password-crypto'
23
22
  export * from './utils'
24
23
  export * from './subscription'