@alephium/web3 0.2.0-test.0 → 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.
- package/.eslintignore +2 -2
- package/README.md +2 -135
- package/dist/alephium-web3.min.js +1 -1
- package/dist/alephium-web3.min.js.LICENSE.txt +0 -17
- package/dist/alephium-web3.min.js.map +1 -1
- package/dist/src/api/api-alephium.d.ts +152 -24
- package/dist/src/api/api-alephium.js +163 -82
- package/dist/src/api/api-explorer.d.ts +192 -49
- package/dist/src/api/api-explorer.js +195 -34
- package/dist/src/api/index.d.ts +40 -5
- package/dist/src/api/index.js +115 -7
- package/dist/src/api/types.d.ts +23 -0
- package/dist/src/api/types.js +235 -0
- package/dist/src/api/utils.d.ts +6 -0
- package/dist/{scripts/rename-gitignore.js → src/api/utils.js} +11 -6
- package/dist/src/contract/contract.d.ts +127 -80
- package/dist/src/contract/contract.js +425 -467
- package/dist/src/contract/events.d.ts +4 -4
- package/dist/src/contract/events.js +2 -1
- package/dist/src/contract/index.js +5 -1
- package/dist/src/contract/ralph.d.ts +5 -4
- package/dist/src/contract/ralph.js +27 -1
- package/dist/src/global.d.ts +7 -0
- package/dist/src/global.js +54 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +23 -1
- package/dist/src/signer/index.d.ts +0 -1
- package/dist/src/signer/index.js +5 -2
- package/dist/src/signer/signer.d.ts +59 -60
- package/dist/src/signer/signer.js +99 -69
- package/dist/src/transaction/index.d.ts +0 -1
- package/dist/src/transaction/index.js +5 -2
- package/dist/src/transaction/status.d.ts +2 -1
- package/dist/src/transaction/status.js +2 -1
- package/dist/src/utils/bs58.d.ts +1 -0
- package/dist/src/utils/bs58.js +13 -1
- package/dist/src/utils/index.d.ts +0 -1
- package/dist/src/utils/index.js +5 -2
- package/dist/src/utils/subscription.d.ts +0 -3
- package/dist/src/utils/subscription.js +0 -1
- package/dist/src/utils/utils.d.ts +6 -11
- package/dist/src/utils/utils.js +22 -26
- package/jest-config.json +11 -0
- package/package.json +11 -47
- package/src/api/api-alephium.ts +219 -33
- package/src/api/api-explorer.ts +275 -52
- package/src/api/index.ts +140 -6
- package/src/api/types.ts +229 -0
- package/{scripts/rename-gitignore.js → src/api/utils.ts} +7 -6
- package/src/contract/contract.ts +663 -581
- package/src/contract/events.ts +8 -7
- package/src/contract/ralph.ts +29 -4
- package/src/global.ts +56 -0
- package/src/index.ts +7 -0
- package/src/signer/index.ts +0 -1
- package/src/signer/signer.ts +165 -134
- package/src/transaction/index.ts +0 -1
- package/src/transaction/status.ts +6 -3
- package/src/utils/bs58.ts +11 -0
- package/src/utils/index.ts +0 -1
- package/src/utils/subscription.ts +1 -5
- package/src/utils/utils.ts +15 -23
- package/webpack.config.js +3 -0
- package/.eslintrc.json +0 -21
- package/LICENSE +0 -165
- package/contracts/add/add.ral +0 -16
- package/contracts/greeter/greeter.ral +0 -7
- package/contracts/greeter/greeter_interface.ral +0 -3
- package/contracts/greeter_main.ral +0 -9
- package/contracts/main.ral +0 -6
- package/contracts/sub/sub.ral +0 -9
- package/dev/user.conf +0 -29
- package/dist/scripts/create-project.d.ts +0 -2
- package/dist/scripts/create-project.js +0 -124
- package/dist/scripts/rename-gitignore.d.ts +0 -1
- package/dist/scripts/start-devnet.d.ts +0 -1
- package/dist/scripts/start-devnet.js +0 -131
- package/dist/scripts/stop-devnet.d.ts +0 -1
- package/dist/scripts/stop-devnet.js +0 -32
- package/dist/src/signer/node-wallet.d.ts +0 -13
- package/dist/src/signer/node-wallet.js +0 -60
- package/dist/src/test/index.d.ts +0 -7
- package/dist/src/test/index.js +0 -41
- package/dist/src/test/privatekey-wallet.d.ts +0 -12
- package/dist/src/test/privatekey-wallet.js +0 -68
- package/dist/src/transaction/sign-verify.d.ts +0 -2
- package/dist/src/transaction/sign-verify.js +0 -58
- package/dist/src/utils/password-crypto.d.ts +0 -2
- package/dist/src/utils/password-crypto.js +0 -69
- package/gitignore +0 -10
- package/scripts/create-project.ts +0 -136
- package/scripts/start-devnet.js +0 -141
- package/scripts/stop-devnet.js +0 -32
- package/src/contract/ralph.test.ts +0 -178
- package/src/fixtures/address.json +0 -36
- package/src/fixtures/balance.json +0 -9
- package/src/fixtures/self-clique.json +0 -19
- package/src/fixtures/transaction.json +0 -13
- package/src/fixtures/transactions.json +0 -179
- package/src/signer/fixtures/genesis.json +0 -26
- package/src/signer/fixtures/wallets.json +0 -26
- package/src/signer/node-wallet.ts +0 -74
- package/src/test/index.ts +0 -32
- package/src/test/privatekey-wallet.ts +0 -58
- package/src/transaction/sign-verify.test.ts +0 -50
- package/src/transaction/sign-verify.ts +0 -39
- package/src/utils/address.test.ts +0 -47
- package/src/utils/djb2.test.ts +0 -35
- package/src/utils/password-crypto.test.ts +0 -27
- package/src/utils/password-crypto.ts +0 -77
- package/src/utils/utils.test.ts +0 -161
- package/templates/base/README.md +0 -34
- package/templates/base/package.json +0 -35
- package/templates/base/src/greeter.ts +0 -41
- package/templates/base/tsconfig.json +0 -19
- package/templates/react/README.md +0 -34
- package/templates/react/config-overrides.js +0 -18
- package/templates/react/package.json +0 -66
- package/templates/react/src/App.tsx +0 -42
- package/templates/react/src/artifacts/greeter.ral.json +0 -26
- package/templates/react/src/artifacts/greeter_main.ral.json +0 -22
- package/templates/shared/.eslintrc.json +0 -12
- package/templates/shared/scripts/header.js +0 -0
- package/test/contract.test.ts +0 -178
- package/test/events.test.ts +0 -138
- package/test/transaction.test.ts +0 -72
package/src/contract/events.ts
CHANGED
|
@@ -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 {
|
|
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
|
|
@@ -31,7 +32,7 @@ export class EventSubscription extends Subscription<ContractEvent> {
|
|
|
31
32
|
this.startPolling()
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
override startPolling() {
|
|
35
|
+
override startPolling(): void {
|
|
35
36
|
this.eventEmitter.on('tick', async () => {
|
|
36
37
|
await this.polling()
|
|
37
38
|
})
|
|
@@ -42,9 +43,9 @@ export class EventSubscription extends Subscription<ContractEvent> {
|
|
|
42
43
|
return this.fromCount
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
override async polling() {
|
|
46
|
+
override async polling(): Promise<void> {
|
|
46
47
|
try {
|
|
47
|
-
const events = await
|
|
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 {
|
package/src/contract/ralph.ts
CHANGED
|
@@ -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 {
|
|
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:
|
|
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:
|
|
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
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2018 - 2022 The Alephium Authors
|
|
3
|
+
This file is part of the alephium project.
|
|
4
|
+
|
|
5
|
+
The library is free software: you can redistribute it and/or modify
|
|
6
|
+
it under the terms of the GNU Lesser General Public License as published by
|
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
(at your option) any later version.
|
|
9
|
+
|
|
10
|
+
The library is distributed in the hope that it will be useful,
|
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
GNU Lesser General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU Lesser General Public License
|
|
16
|
+
along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { ExplorerProvider, NodeProvider } from './api'
|
|
20
|
+
|
|
21
|
+
let _currentNodeProvider: NodeProvider | undefined = undefined
|
|
22
|
+
|
|
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 {
|
|
26
|
+
if (typeof provider == 'string') {
|
|
27
|
+
_currentNodeProvider = new NodeProvider(provider, apiKey)
|
|
28
|
+
} else {
|
|
29
|
+
_currentNodeProvider = provider
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function getCurrentNodeProvider(): NodeProvider {
|
|
34
|
+
if (typeof _currentNodeProvider === 'undefined') {
|
|
35
|
+
throw Error('No node provider is set.')
|
|
36
|
+
}
|
|
37
|
+
return _currentNodeProvider
|
|
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,3 +27,6 @@ export * from './utils'
|
|
|
23
27
|
export * from './transaction'
|
|
24
28
|
|
|
25
29
|
export * from './constants'
|
|
30
|
+
export * as web3 from './global'
|
|
31
|
+
|
|
32
|
+
export * as utils from './utils'
|
package/src/signer/index.ts
CHANGED
package/src/signer/signer.ts
CHANGED
|
@@ -17,22 +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 {
|
|
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
35
|
|
|
27
|
-
|
|
36
|
+
export type OutputRef = node.OutputRef
|
|
28
37
|
|
|
29
|
-
|
|
30
|
-
fromGroup: number
|
|
31
|
-
toGroup: number
|
|
32
|
-
unsignedTx: string
|
|
33
|
-
txId: string
|
|
34
|
-
signature: string
|
|
35
|
-
}
|
|
38
|
+
const ec = new EC('secp256k1')
|
|
36
39
|
|
|
37
40
|
export interface Account {
|
|
38
41
|
address: string
|
|
@@ -40,42 +43,39 @@ export interface Account {
|
|
|
40
43
|
publicKey: string
|
|
41
44
|
}
|
|
42
45
|
|
|
43
|
-
export type SubmitTx = { submitTx?: boolean }
|
|
44
46
|
export type SignerAddress = { signerAddress: string }
|
|
45
|
-
type TxBuildParams<T> = Omit<T, 'fromPublicKey'> & SignerAddress
|
|
46
|
-
|
|
47
|
-
export type GetAccountsParams = undefined
|
|
48
|
-
export type GetAccountsResult = Account[]
|
|
47
|
+
type TxBuildParams<T> = Omit<T, 'fromPublicKey' | 'targetBlockHash'> & SignerAddress
|
|
48
|
+
type SignResult<T> = Omit<T, 'gasPrice'> & { signature: string; gasPrice: Number256 }
|
|
49
49
|
|
|
50
50
|
export interface SignTransferTxParams {
|
|
51
51
|
signerAddress: string
|
|
52
|
-
destinations:
|
|
53
|
-
utxos?:
|
|
52
|
+
destinations: Destination[]
|
|
53
|
+
utxos?: OutputRef[]
|
|
54
54
|
gasAmount?: number
|
|
55
|
-
gasPrice?:
|
|
56
|
-
submitTx?: boolean
|
|
55
|
+
gasPrice?: Number256
|
|
57
56
|
}
|
|
58
|
-
assertType<Eq<SignTransferTxParams, TxBuildParams<node.BuildTransaction>>>()
|
|
57
|
+
assertType<Eq<keyof SignTransferTxParams, keyof TxBuildParams<node.BuildTransaction>>>()
|
|
59
58
|
export interface SignTransferTxResult {
|
|
60
59
|
fromGroup: number
|
|
61
60
|
toGroup: number
|
|
62
61
|
unsignedTx: string
|
|
63
62
|
txId: string
|
|
64
63
|
signature: string
|
|
64
|
+
gasAmount: number
|
|
65
|
+
gasPrice: Number256
|
|
65
66
|
}
|
|
66
|
-
assertType<Eq<SignTransferTxResult, SignResult
|
|
67
|
+
assertType<Eq<SignTransferTxResult, SignResult<node.BuildTransactionResult>>>()
|
|
67
68
|
|
|
68
69
|
export interface SignDeployContractTxParams {
|
|
69
70
|
signerAddress: string
|
|
70
71
|
bytecode: string
|
|
71
|
-
initialAttoAlphAmount?:
|
|
72
|
+
initialAttoAlphAmount?: Number256
|
|
72
73
|
initialTokenAmounts?: Token[]
|
|
73
|
-
issueTokenAmount?:
|
|
74
|
+
issueTokenAmount?: Number256
|
|
74
75
|
gasAmount?: number
|
|
75
|
-
gasPrice?:
|
|
76
|
-
submitTx?: boolean
|
|
76
|
+
gasPrice?: Number256
|
|
77
77
|
}
|
|
78
|
-
assertType<Eq<SignDeployContractTxParams, TxBuildParams<node.BuildDeployContractTx>>>()
|
|
78
|
+
assertType<Eq<keyof SignDeployContractTxParams, keyof TxBuildParams<node.BuildDeployContractTx>>>()
|
|
79
79
|
export interface SignDeployContractTxResult {
|
|
80
80
|
fromGroup: number
|
|
81
81
|
toGroup: number
|
|
@@ -84,52 +84,46 @@ export interface SignDeployContractTxResult {
|
|
|
84
84
|
signature: string
|
|
85
85
|
contractId: string
|
|
86
86
|
contractAddress: string
|
|
87
|
+
gasAmount: number
|
|
88
|
+
gasPrice: Number256
|
|
87
89
|
}
|
|
88
|
-
assertType<Eq<SignDeployContractTxResult, SignResult & { contractId: string
|
|
90
|
+
assertType<Eq<SignDeployContractTxResult, SignResult<node.BuildDeployContractTxResult> & { contractId: string }>>()
|
|
89
91
|
|
|
90
92
|
export interface SignExecuteScriptTxParams {
|
|
91
93
|
signerAddress: string
|
|
92
94
|
bytecode: string
|
|
93
|
-
attoAlphAmount?:
|
|
94
|
-
tokens?:
|
|
95
|
+
attoAlphAmount?: Number256
|
|
96
|
+
tokens?: Token[]
|
|
95
97
|
gasAmount?: number
|
|
96
|
-
gasPrice?:
|
|
97
|
-
submitTx?: boolean
|
|
98
|
+
gasPrice?: Number256
|
|
98
99
|
}
|
|
99
|
-
assertType<Eq<SignExecuteScriptTxParams, TxBuildParams<node.BuildExecuteScriptTx>>>()
|
|
100
|
+
assertType<Eq<keyof SignExecuteScriptTxParams, keyof TxBuildParams<node.BuildExecuteScriptTx>>>()
|
|
100
101
|
export interface SignExecuteScriptTxResult {
|
|
101
102
|
fromGroup: number
|
|
102
103
|
toGroup: number
|
|
103
104
|
unsignedTx: string
|
|
104
105
|
txId: string
|
|
105
106
|
signature: string
|
|
107
|
+
gasAmount: number
|
|
108
|
+
gasPrice: Number256
|
|
106
109
|
}
|
|
107
|
-
assertType<Eq<SignExecuteScriptTxResult, SignResult
|
|
110
|
+
assertType<Eq<SignExecuteScriptTxResult, SignResult<node.BuildExecuteScriptTxResult>>>()
|
|
108
111
|
|
|
109
112
|
export interface SignUnsignedTxParams {
|
|
110
113
|
signerAddress: string
|
|
111
114
|
unsignedTx: string
|
|
112
|
-
submitTx?: boolean
|
|
113
115
|
}
|
|
114
|
-
assertType<Eq<SignUnsignedTxParams, { unsignedTx: string } &
|
|
116
|
+
assertType<Eq<SignUnsignedTxParams, { unsignedTx: string } & SignerAddress>>()
|
|
115
117
|
export interface SignUnsignedTxResult {
|
|
116
118
|
fromGroup: number
|
|
117
119
|
toGroup: number
|
|
118
120
|
unsignedTx: string
|
|
119
121
|
txId: string
|
|
120
122
|
signature: string
|
|
123
|
+
gasAmount: number
|
|
124
|
+
gasPrice: Number256
|
|
121
125
|
}
|
|
122
|
-
assertType<Eq<SignUnsignedTxResult,
|
|
123
|
-
|
|
124
|
-
export interface SignHexStringParams {
|
|
125
|
-
signerAddress: string
|
|
126
|
-
hexString: string
|
|
127
|
-
}
|
|
128
|
-
assertType<Eq<SignHexStringParams, { hexString: string } & SignerAddress>>()
|
|
129
|
-
export interface SignHexStringResult {
|
|
130
|
-
signature: string
|
|
131
|
-
}
|
|
132
|
-
assertType<Eq<SignHexStringResult, Pick<SignResult, 'signature'>>>()
|
|
126
|
+
assertType<Eq<SignUnsignedTxResult, SignTransferTxResult>>
|
|
133
127
|
|
|
134
128
|
export interface SignMessageParams {
|
|
135
129
|
signerAddress: string
|
|
@@ -139,144 +133,150 @@ assertType<Eq<SignMessageParams, { message: string } & SignerAddress>>()
|
|
|
139
133
|
export interface SignMessageResult {
|
|
140
134
|
signature: string
|
|
141
135
|
}
|
|
142
|
-
|
|
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
|
+
}
|
|
143
146
|
|
|
144
147
|
export interface SignerProvider {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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
|
+
|
|
149
158
|
signUnsignedTx(params: SignUnsignedTxParams): Promise<SignUnsignedTxResult>
|
|
150
|
-
|
|
159
|
+
// The message will be prefixed with 'Alephium Signed Message: ' before signing
|
|
160
|
+
// so that the resulted signature cannot be reused for building transactions.
|
|
151
161
|
signMessage(params: SignMessageParams): Promise<SignMessageResult>
|
|
152
162
|
}
|
|
153
163
|
|
|
154
|
-
export abstract class
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
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>
|
|
159
168
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
if (typeof account === 'undefined') {
|
|
164
|
-
throw new Error('Unmatched signerAddress')
|
|
165
|
-
} else {
|
|
166
|
-
return account
|
|
169
|
+
private getNodeProvider(): NodeProvider {
|
|
170
|
+
if (this.nodeProvider === undefined) {
|
|
171
|
+
throw Error('The signer does not contain a node provider')
|
|
167
172
|
}
|
|
173
|
+
return this.nodeProvider
|
|
168
174
|
}
|
|
169
175
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
this.
|
|
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)
|
|
173
179
|
}
|
|
174
180
|
|
|
175
|
-
|
|
176
|
-
|
|
181
|
+
async signAndSubmitTransferTx(params: SignTransferTxParams): Promise<SignTransferTxResult> {
|
|
182
|
+
const signResult = await this.signTransferTx(params)
|
|
183
|
+
await this.submitTransaction(signResult)
|
|
184
|
+
return signResult
|
|
177
185
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
const params: node.SubmitTransaction = { unsignedTx: unsignedTx, signature: signature }
|
|
183
|
-
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
|
|
184
190
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
|
188
200
|
}
|
|
189
201
|
|
|
190
202
|
private async usePublicKey<T extends SignerAddress>(
|
|
191
203
|
params: T
|
|
192
204
|
): Promise<Omit<T, 'signerAddress'> & { fromPublicKey: string }> {
|
|
193
205
|
const { signerAddress, ...restParams } = params
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
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')
|
|
198
209
|
} else {
|
|
199
|
-
return { fromPublicKey:
|
|
210
|
+
return { fromPublicKey: selectedAccount.publicKey, ...restParams }
|
|
200
211
|
}
|
|
201
212
|
}
|
|
202
213
|
|
|
203
214
|
async signTransferTx(params: SignTransferTxParams): Promise<SignTransferTxResult> {
|
|
204
215
|
const response = await this.buildTransferTx(params)
|
|
205
|
-
|
|
216
|
+
const signature = await this.signRaw(params.signerAddress, response.txId)
|
|
217
|
+
return { ...response, signature, gasPrice: fromApiNumber256(response.gasPrice) }
|
|
206
218
|
}
|
|
207
219
|
|
|
208
220
|
async buildTransferTx(params: SignTransferTxParams): Promise<node.BuildTransactionResult> {
|
|
209
|
-
|
|
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)
|
|
210
227
|
}
|
|
211
228
|
|
|
212
229
|
async signDeployContractTx(params: SignDeployContractTxParams): Promise<SignDeployContractTxResult> {
|
|
213
230
|
const response = await this.buildContractCreationTx(params)
|
|
214
|
-
const
|
|
215
|
-
{ signerAddress: params.signerAddress, ...response },
|
|
216
|
-
this.shouldSubmitTx(params)
|
|
217
|
-
)
|
|
231
|
+
const signature = await this.signRaw(params.signerAddress, response.txId)
|
|
218
232
|
const contractId = utils.binToHex(utils.contractIdFromAddress(response.contractAddress))
|
|
219
|
-
return { ...
|
|
233
|
+
return { ...response, contractId, signature, gasPrice: fromApiNumber256(response.gasPrice) }
|
|
220
234
|
}
|
|
221
235
|
|
|
222
236
|
async buildContractCreationTx(params: SignDeployContractTxParams): Promise<node.BuildDeployContractTxResult> {
|
|
223
|
-
|
|
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)
|
|
224
245
|
}
|
|
225
246
|
|
|
226
247
|
async signExecuteScriptTx(params: SignExecuteScriptTxParams): Promise<SignExecuteScriptTxResult> {
|
|
227
248
|
const response = await this.buildScriptTx(params)
|
|
228
|
-
|
|
249
|
+
const signature = await this.signRaw(params.signerAddress, response.txId)
|
|
250
|
+
return { ...response, signature, gasPrice: fromApiNumber256(response.gasPrice) }
|
|
229
251
|
}
|
|
230
252
|
|
|
231
253
|
async buildScriptTx(params: SignExecuteScriptTxParams): Promise<node.BuildExecuteScriptTxResult> {
|
|
232
|
-
|
|
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)
|
|
233
261
|
}
|
|
234
262
|
|
|
235
263
|
// in general, wallet should show the decoded information to user for confirmation
|
|
236
264
|
// please overwrite this function for real wallet
|
|
237
265
|
async signUnsignedTx(params: SignUnsignedTxParams): Promise<SignUnsignedTxResult> {
|
|
238
266
|
const data = { unsignedTx: params.unsignedTx }
|
|
239
|
-
const decoded = await this.
|
|
240
|
-
|
|
241
|
-
{
|
|
242
|
-
fromGroup: decoded.fromGroup,
|
|
243
|
-
toGroup: decoded.toGroup,
|
|
244
|
-
signerAddress: params.signerAddress,
|
|
245
|
-
unsignedTx: params.unsignedTx,
|
|
246
|
-
txId: decoded.unsignedTx.txId
|
|
247
|
-
},
|
|
248
|
-
params.submitTx ? params.submitTx : true // we don't consider `alwaysSubmitTx` as the tx might needs multiple signatures
|
|
249
|
-
)
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
protected async handleSign(
|
|
253
|
-
response: { fromGroup: number; toGroup: number; signerAddress: string; unsignedTx: string; txId: string },
|
|
254
|
-
submitTx: boolean
|
|
255
|
-
): Promise<SignResult> {
|
|
256
|
-
// sign the tx
|
|
257
|
-
const signature = await this.signRaw(response.signerAddress, response.txId)
|
|
258
|
-
// submit the tx if required
|
|
259
|
-
if (submitTx) {
|
|
260
|
-
await this.provider.transactions.postTransactionsSubmit({
|
|
261
|
-
unsignedTx: response.unsignedTx,
|
|
262
|
-
signature: signature
|
|
263
|
-
})
|
|
264
|
-
}
|
|
265
|
-
// 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)
|
|
266
269
|
return {
|
|
267
|
-
fromGroup:
|
|
268
|
-
toGroup:
|
|
269
|
-
unsignedTx:
|
|
270
|
-
txId:
|
|
271
|
-
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)
|
|
272
277
|
}
|
|
273
278
|
}
|
|
274
279
|
|
|
275
|
-
async signHexString(params: SignHexStringParams): Promise<SignHexStringResult> {
|
|
276
|
-
const signature = await this.signRaw(params.signerAddress, params.hexString)
|
|
277
|
-
return { signature: signature }
|
|
278
|
-
}
|
|
279
|
-
|
|
280
280
|
async signMessage(params: SignMessageParams): Promise<SignMessageResult> {
|
|
281
281
|
const extendedMessage = extendMessage(params.message)
|
|
282
282
|
const messageHash = blake.blake2b(extendedMessage, undefined, 32)
|
|
@@ -287,10 +287,20 @@ export abstract class SignerWithNodeProvider implements SignerProvider {
|
|
|
287
287
|
abstract signRaw(signerAddress: string, hexString: string): Promise<string>
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
-
export
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
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>
|
|
294
304
|
}
|
|
295
305
|
|
|
296
306
|
export function verifyHexString(hexString: string, publicKey: string, signature: string): boolean {
|
|
@@ -311,3 +321,24 @@ export function verifySignedMessage(message: string, publicKey: string, signatur
|
|
|
311
321
|
const messageHash = blake.blake2b(extendedMessage, undefined, 32)
|
|
312
322
|
return verifyHexString(utils.binToHex(messageHash), publicKey, signature)
|
|
313
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
|
+
}
|
package/src/transaction/index.ts
CHANGED
|
@@ -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 {
|
|
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
|
|
@@ -33,9 +36,9 @@ export class TxStatusSubscription extends Subscription<TxStatus> {
|
|
|
33
36
|
this.startPolling()
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
override async polling() {
|
|
39
|
+
override async polling(): Promise<void> {
|
|
37
40
|
try {
|
|
38
|
-
const txStatus = await
|
|
41
|
+
const txStatus = await web3.getCurrentNodeProvider().transactions.getTransactionsStatus({
|
|
39
42
|
txId: this.txId,
|
|
40
43
|
fromGroup: this.fromGroup,
|
|
41
44
|
toGroup: this.toGroup
|