@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.
- 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 +115 -17
- package/dist/src/api/api-alephium.js +145 -80
- package/dist/src/api/api-explorer.d.ts +178 -51
- package/dist/src/api/api-explorer.js +172 -37
- 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 +68 -55
- package/dist/src/contract/contract.js +235 -384
- 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 +6 -2
- package/dist/src/global.js +19 -3
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.js +23 -2
- 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 -70
- 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 -2
- package/dist/src/utils/subscription.js +0 -2
- package/dist/src/utils/utils.d.ts +4 -9
- package/dist/src/utils/utils.js +20 -24
- package/jest-config.json +11 -0
- package/package.json +11 -45
- package/src/api/api-alephium.ts +162 -25
- package/src/api/api-explorer.ts +247 -54
- 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 +398 -429
- package/src/contract/events.ts +6 -5
- package/src/contract/ralph.ts +29 -4
- package/src/global.ts +23 -3
- package/src/index.ts +7 -1
- package/src/signer/index.ts +0 -1
- package/src/signer/signer.ts +165 -135
- package/src/transaction/index.ts +0 -1
- package/src/transaction/status.ts +5 -2
- package/src/utils/bs58.ts +11 -0
- package/src/utils/index.ts +0 -1
- package/src/utils/subscription.ts +0 -4
- package/src/utils/utils.ts +11 -19
- package/webpack.config.js +3 -0
- package/.eslintrc.json +0 -21
- package/LICENSE +0 -165
- package/contracts/add/add.ral +0 -13
- package/contracts/greeter/greeter.ral +0 -7
- package/contracts/greeter/greeter_interface.ral +0 -4
- package/contracts/greeter_main.ral +0 -7
- package/contracts/main.ral +0 -4
- package/contracts/sub/sub.ral +0 -10
- package/contracts/test/metadata.ral +0 -18
- package/contracts/test/warnings.ral +0 -8
- package/dev/user.conf +0 -29
- package/dist/scripts/create-project.d.ts +0 -2
- package/dist/scripts/create-project.js +0 -125
- 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 -11
- package/dist/src/signer/node-wallet.js +0 -57
- package/dist/src/test/index.d.ts +0 -6
- package/dist/src/test/index.js +0 -41
- package/dist/src/test/privatekey-wallet.d.ts +0 -11
- 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 -9
- package/scripts/create-project.ts +0 -137
- 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 -65
- package/src/test/index.ts +0 -31
- package/src/test/privatekey-wallet.ts +0 -57
- 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 -42
- 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 -213
- package/test/events.test.ts +0 -141
- package/test/transaction.test.ts +0 -73
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
|
|
@@ -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
|
|
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
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
|
|
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'
|
package/src/signer/index.ts
CHANGED
package/src/signer/signer.ts
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
36
|
+
export type OutputRef = node.OutputRef
|
|
29
37
|
|
|
30
|
-
|
|
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
|
|
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:
|
|
54
|
-
utxos?:
|
|
52
|
+
destinations: Destination[]
|
|
53
|
+
utxos?: OutputRef[]
|
|
55
54
|
gasAmount?: number
|
|
56
|
-
gasPrice?:
|
|
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?:
|
|
72
|
+
initialAttoAlphAmount?: Number256
|
|
73
73
|
initialTokenAmounts?: Token[]
|
|
74
|
-
issueTokenAmount?:
|
|
74
|
+
issueTokenAmount?: Number256
|
|
75
75
|
gasAmount?: number
|
|
76
|
-
gasPrice?:
|
|
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
|
|
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?:
|
|
95
|
-
tokens?:
|
|
95
|
+
attoAlphAmount?: Number256
|
|
96
|
+
tokens?: Token[]
|
|
96
97
|
gasAmount?: number
|
|
97
|
-
gasPrice?:
|
|
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 } &
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
-
|
|
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
|
|
156
|
-
|
|
157
|
-
|
|
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
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
172
|
-
|
|
173
|
-
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)
|
|
174
179
|
}
|
|
175
180
|
|
|
176
|
-
|
|
177
|
-
|
|
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
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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
|
-
|
|
188
|
-
|
|
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
|
|
196
|
-
|
|
197
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 { ...
|
|
233
|
+
return { ...response, contractId, signature, gasPrice: fromApiNumber256(response.gasPrice) }
|
|
221
234
|
}
|
|
222
235
|
|
|
223
236
|
async buildContractCreationTx(params: SignDeployContractTxParams): Promise<node.BuildDeployContractTxResult> {
|
|
224
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
241
|
-
|
|
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:
|
|
269
|
-
toGroup:
|
|
270
|
-
unsignedTx:
|
|
271
|
-
txId:
|
|
272
|
-
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
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
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
|
+
}
|
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
|
|
@@ -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
|
|
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
|
package/src/utils/index.ts
CHANGED