@alephium/web3 0.3.0-rc.5 → 0.3.0-rc.8

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.
@@ -86,14 +86,32 @@ class TypedMatcher<T extends SourceKind> {
86
86
  }
87
87
  }
88
88
 
89
+ function removeParentsPrefix(parts: string[]): string {
90
+ let index = 0
91
+ for (let i = 0; i < parts.length; i++) {
92
+ if (parts[`${i}`] === '..') {
93
+ index += 1
94
+ } else {
95
+ break
96
+ }
97
+ }
98
+ return path.join(...parts.slice(index))
99
+ }
100
+
89
101
  class SourceInfo {
90
102
  type: SourceKind
91
103
  name: string
92
104
  contractRelativePath: string
93
105
  sourceCode: string
94
106
  sourceCodeHash: string
107
+ isExternal: boolean
95
108
 
96
109
  getArtifactPath(artifactsRootDir: string): string {
110
+ if (this.isExternal) {
111
+ const relativePath = removeParentsPrefix(this.contractRelativePath.split(path.sep))
112
+ const externalPath = path.join('.external', relativePath)
113
+ return path.join(artifactsRootDir, externalPath) + '.json'
114
+ }
97
115
  return path.join(artifactsRootDir, this.contractRelativePath) + '.json'
98
116
  }
99
117
 
@@ -102,23 +120,27 @@ class SourceInfo {
102
120
  name: string,
103
121
  sourceCode: string,
104
122
  sourceCodeHash: string,
105
- contractRelativePath: string
123
+ contractRelativePath: string,
124
+ isExternal: boolean
106
125
  ) {
107
126
  this.type = type
108
127
  this.name = name
109
128
  this.sourceCode = sourceCode
110
129
  this.sourceCodeHash = sourceCodeHash
111
130
  this.contractRelativePath = contractRelativePath
131
+ this.isExternal = isExternal
112
132
  }
113
133
 
114
134
  static async from(
115
135
  type: SourceKind,
116
136
  name: string,
117
137
  sourceCode: string,
118
- contractRelativePath: string
138
+ contractRelativePath: string,
139
+ isExternal: boolean
119
140
  ): Promise<SourceInfo> {
120
141
  const sourceCodeHash = await crypto.subtle.digest('SHA-256', Buffer.from(sourceCode))
121
- return new SourceInfo(type, name, sourceCode, Buffer.from(sourceCodeHash).toString('hex'), contractRelativePath)
142
+ const sourceCodeHashHex = Buffer.from(sourceCodeHash).toString('hex')
143
+ return new SourceInfo(type, name, sourceCode, sourceCodeHashHex, contractRelativePath, isExternal)
122
144
  }
123
145
  }
124
146
 
@@ -223,12 +245,13 @@ export class Project {
223
245
 
224
246
  static currentProject: Project
225
247
 
248
+ static readonly importRegex = new RegExp('^import "[^"./]+/[^"]*[a-z][a-z_0-9]*(.ral)?"', 'mg')
226
249
  static readonly abstractContractMatcher = new TypedMatcher<SourceKind>(
227
250
  '^Abstract Contract ([A-Z][a-zA-Z0-9]*)',
228
251
  SourceKind.AbstractContract
229
252
  )
230
253
  static readonly contractMatcher = new TypedMatcher('^Contract ([A-Z][a-zA-Z0-9]*)', SourceKind.Contract)
231
- static readonly interfaceMatcher = new TypedMatcher('^Interface ([A-Z][a-zA-Z0-9]*) \\{', SourceKind.Interface)
254
+ static readonly interfaceMatcher = new TypedMatcher('^Interface ([A-Z][a-zA-Z0-9]*)', SourceKind.Interface)
232
255
  static readonly scriptMatcher = new TypedMatcher('^TxScript ([A-Z][a-zA-Z0-9]*)', SourceKind.Script)
233
256
  static readonly matchers = [
234
257
  Project.abstractContractMatcher,
@@ -445,45 +468,107 @@ export class Project {
445
468
  }
446
469
  }
447
470
 
471
+ private static getImportSourcePath(projectRootDir: string, importPath: string): string {
472
+ const parts = importPath.split(path.sep)
473
+ if (parts.length > 1 && parts[0] === 'std') {
474
+ const currentDir = path.dirname(__filename)
475
+ return path.join(...[currentDir, '..', '..', '..', importPath])
476
+ }
477
+ let moduleDir = projectRootDir
478
+ while (true) {
479
+ const expectedPath = path.join(...[moduleDir, 'node_modules', importPath])
480
+ if (fs.existsSync(expectedPath)) {
481
+ return expectedPath
482
+ }
483
+ const oldModuleDir = moduleDir
484
+ moduleDir = path.join(moduleDir, '..')
485
+ if (oldModuleDir === moduleDir) {
486
+ throw new Error(`Specified import file does not exist: ${importPath}`)
487
+ }
488
+ }
489
+ }
490
+
491
+ private static async handleImports(
492
+ projectRootDir: string,
493
+ contractRootDir: string,
494
+ sourceStr: string,
495
+ importsCache: string[]
496
+ ): Promise<[string, SourceInfo[]]> {
497
+ const localImportsCache: string[] = []
498
+ const result = sourceStr.replace(Project.importRegex, (match) => {
499
+ localImportsCache.push(match)
500
+ return ''
501
+ })
502
+ const externalSourceInfos: SourceInfo[] = []
503
+ for (const myImport of localImportsCache) {
504
+ const originImportPath = myImport.slice(8, -1)
505
+ const importPath = originImportPath.endsWith('.ral') ? originImportPath : originImportPath + '.ral'
506
+ if (!importsCache.includes(importPath)) {
507
+ importsCache.push(importPath)
508
+ const sourcePath = Project.getImportSourcePath(projectRootDir, importPath)
509
+ const sourceInfos = await Project.loadSourceFile(
510
+ projectRootDir,
511
+ contractRootDir,
512
+ sourcePath,
513
+ importsCache,
514
+ true
515
+ )
516
+ externalSourceInfos.push(...sourceInfos)
517
+ }
518
+ }
519
+ return [result, externalSourceInfos]
520
+ }
521
+
448
522
  private static async loadSourceFile(
523
+ projectRootDir: string,
449
524
  contractsRootDir: string,
450
- dirPath: string,
451
- filename: string
525
+ sourcePath: string,
526
+ importsCache: string[],
527
+ isExternal: boolean
452
528
  ): Promise<SourceInfo[]> {
453
- const contractPath = path.join(dirPath, filename)
454
- const contractRelativePath = path.relative(contractsRootDir, contractPath)
455
- if (!filename.endsWith('.ral')) {
456
- throw new Error(`Invalid filename: ${contractPath}, smart contract file name should end with ".ral"`)
529
+ const contractRelativePath = path.relative(contractsRootDir, sourcePath)
530
+ if (!sourcePath.endsWith('.ral')) {
531
+ throw new Error(`Invalid filename: ${sourcePath}, smart contract file name should end with ".ral"`)
457
532
  }
458
533
 
459
- const sourceBuffer = await fsPromises.readFile(contractPath)
460
- const sourceStr = sourceBuffer.toString()
461
- const sourceInfos: SourceInfo[] = []
534
+ const sourceBuffer = await fsPromises.readFile(sourcePath)
535
+ const [sourceStr, externalSourceInfos] = await Project.handleImports(
536
+ projectRootDir,
537
+ contractsRootDir,
538
+ sourceBuffer.toString(),
539
+ importsCache
540
+ )
541
+ if (sourceStr.match(new RegExp('^import "', 'mg')) !== null) {
542
+ throw new Error(`Invalid import statements, source: ${sourcePath}`)
543
+ }
544
+ const sourceInfos = externalSourceInfos
462
545
  for (const matcher of this.matchers) {
463
546
  const results = sourceStr.matchAll(matcher.matcher)
464
547
  for (const result of results) {
465
- const sourceInfo = await SourceInfo.from(matcher.type, result[1], sourceStr, contractRelativePath)
548
+ const sourceInfo = await SourceInfo.from(matcher.type, result[1], sourceStr, contractRelativePath, isExternal)
466
549
  sourceInfos.push(sourceInfo)
467
550
  }
468
551
  }
469
552
  return sourceInfos
470
553
  }
471
554
 
472
- private static async loadSourceFiles(contractsRootDir: string): Promise<SourceInfo[]> {
473
- const loadDir = async function (dirPath: string, results: SourceInfo[]): Promise<void> {
555
+ private static async loadSourceFiles(projectRootDir: string, contractsRootDir: string): Promise<SourceInfo[]> {
556
+ const importsCache: string[] = []
557
+ const sourceInfos: SourceInfo[] = []
558
+ const loadDir = async function (dirPath: string): Promise<void> {
474
559
  const dirents = await fsPromises.readdir(dirPath, { withFileTypes: true })
475
560
  for (const dirent of dirents) {
476
561
  if (dirent.isFile()) {
477
- const sourceInfos = await Project.loadSourceFile(contractsRootDir, dirPath, dirent.name)
478
- results.push(...sourceInfos)
562
+ const sourcePath = path.join(dirPath, dirent.name)
563
+ const infos = await Project.loadSourceFile(projectRootDir, contractsRootDir, sourcePath, importsCache, false)
564
+ sourceInfos.push(...infos)
479
565
  } else {
480
566
  const newPath = path.join(dirPath, dirent.name)
481
- await loadDir(newPath, results)
567
+ await loadDir(newPath)
482
568
  }
483
569
  }
484
570
  }
485
- const sourceInfos: SourceInfo[] = []
486
- await loadDir(contractsRootDir, sourceInfos)
571
+ await loadDir(contractsRootDir)
487
572
  const contractAndScriptSize = sourceInfos.filter(
488
573
  (f) => f.type === SourceKind.Contract || f.type === SourceKind.Script
489
574
  ).length
@@ -498,11 +583,12 @@ export class Project {
498
583
 
499
584
  static async build(
500
585
  compilerOptionsPartial: Partial<CompilerOptions> = {},
586
+ projectRootDir = '.',
501
587
  contractsRootDir = Project.DEFAULT_CONTRACTS_DIR,
502
588
  artifactsRootDir = Project.DEFAULT_ARTIFACTS_DIR
503
589
  ): Promise<void> {
504
590
  const provider = getCurrentNodeProvider()
505
- const sourceFiles = await Project.loadSourceFiles(contractsRootDir)
591
+ const sourceFiles = await Project.loadSourceFiles(projectRootDir, contractsRootDir)
506
592
  const { errorOnWarnings, ...nodeCompilerOptions } = { ...DEFAULT_COMPILER_OPTIONS, ...compilerOptionsPartial }
507
593
  const projectArtifact = await ProjectArtifact.from(artifactsRootDir)
508
594
  if (typeof projectArtifact === 'undefined' || projectArtifact.needToReCompile(nodeCompilerOptions, sourceFiles)) {
@@ -18,3 +18,4 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
18
18
 
19
19
  export * from './signer'
20
20
  export * from './types'
21
+ export * from './tx-builder'
@@ -17,15 +17,7 @@ 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 {
21
- ExplorerProvider,
22
- fromApiNumber256,
23
- fromApiTokens,
24
- NodeProvider,
25
- toApiNumber256,
26
- toApiNumber256Optional,
27
- toApiTokens
28
- } from '../api'
20
+ import { ExplorerProvider, fromApiNumber256, fromApiTokens, NodeProvider, toApiNumber256, toApiTokens } from '../api'
29
21
  import { node } from '../api'
30
22
  import * as utils from '../utils'
31
23
  import blake from 'blakejs'
@@ -46,8 +38,14 @@ import {
46
38
  SignUnsignedTxParams,
47
39
  SignUnsignedTxResult,
48
40
  SubmissionResult,
49
- SubmitTransactionParams
41
+ SubmitTransactionParams,
42
+ ExtSignTransferTxParams,
43
+ ExtSignDeployContractTxParams,
44
+ ExtSignExecuteScriptTxParams,
45
+ ExtSignUnsignedTxParams,
46
+ ExtSignMessageParams
50
47
  } from './types'
48
+ import { TransactionBuilder } from './tx-builder'
51
49
 
52
50
  const ec = new EC('secp256k1')
53
51
 
@@ -71,12 +69,19 @@ export interface SignerProvider {
71
69
  // Abstraction for interactive signer (e.g. WalletConnect instance, Extension wallet object)
72
70
  export interface InteractiveSignerProvider<EnableOptions extends EnableOptionsBase = EnableOptionsBase>
73
71
  extends SignerProvider {
74
- enable(opt?: EnableOptions): Promise<void>
72
+ enable(opt?: EnableOptions): Promise<Address>
75
73
  disconnect(): Promise<void>
74
+
75
+ // Methods inherited from SignerProvider, but require networkId in the params
76
+ signAndSubmitTransferTx(params: ExtSignTransferTxParams): Promise<SignTransferTxResult>
77
+ signAndSubmitDeployContractTx(params: ExtSignDeployContractTxParams): Promise<SignDeployContractTxResult>
78
+ signAndSubmitExecuteScriptTx(params: ExtSignExecuteScriptTxParams): Promise<SignExecuteScriptTxResult>
79
+ signAndSubmitUnsignedTx(params: ExtSignUnsignedTxParams): Promise<SignUnsignedTxResult>
80
+ signUnsignedTx(params: ExtSignUnsignedTxParams): Promise<SignUnsignedTxResult>
81
+ signMessage(params: ExtSignMessageParams): Promise<SignMessageResult>
76
82
  }
77
83
 
78
- export abstract class SignerProviderSimple implements SignerProvider {
79
- abstract get nodeProvider(): NodeProvider | undefined
84
+ export abstract class SignerProviderSimple extends TransactionBuilder implements SignerProvider {
80
85
  abstract get explorerProvider(): ExplorerProvider | undefined
81
86
 
82
87
  abstract getSelectedAccount(): Promise<Account>
@@ -86,16 +91,9 @@ export abstract class SignerProviderSimple implements SignerProvider {
86
91
  return account.address
87
92
  }
88
93
 
89
- private getNodeProvider(): NodeProvider {
90
- if (this.nodeProvider === undefined) {
91
- throw Error('The signer does not contain a node provider')
92
- }
93
- return this.nodeProvider
94
- }
95
-
96
94
  async submitTransaction(params: SubmitTransactionParams): Promise<SubmissionResult> {
97
95
  const data: node.SubmitTransaction = { unsignedTx: params.unsignedTx, signature: params.signature }
98
- return this.getNodeProvider().transactions.postTransactionsSubmit(data)
96
+ return this.nodeProvider.transactions.postTransactionsSubmit(data)
99
97
  }
100
98
 
101
99
  async signAndSubmitTransferTx(params: SignTransferTxParams): Promise<SignTransferTxResult> {
@@ -132,67 +130,43 @@ export abstract class SignerProviderSimple implements SignerProvider {
132
130
  async signTransferTx(params: SignTransferTxParams): Promise<SignTransferTxResult> {
133
131
  const response = await this.buildTransferTx(params)
134
132
  const signature = await this.signRaw(params.signerAddress, response.txId)
135
- return { ...response, signature, gasPrice: fromApiNumber256(response.gasPrice) }
133
+ return { signature, ...response }
136
134
  }
137
135
 
138
- async buildTransferTx(params: SignTransferTxParams): Promise<node.BuildTransactionResult> {
139
- const data: node.BuildTransaction = {
140
- ...(await this.usePublicKey(params)),
141
- destinations: toApiDestinations(params.destinations),
142
- gasPrice: toApiNumber256Optional(params.gasPrice)
143
- }
144
- return this.getNodeProvider().transactions.postTransactionsBuild(data)
136
+ override async buildTransferTx(params: SignTransferTxParams): Promise<Omit<SignTransferTxResult, 'signature'>> {
137
+ return super.buildTransferTx(params, await this.getPublicKey(params.signerAddress))
145
138
  }
146
139
 
147
140
  async signDeployContractTx(params: SignDeployContractTxParams): Promise<SignDeployContractTxResult> {
148
- const response = await this.buildContractCreationTx(params)
141
+ const response = await this.buildDeployContractTx(params)
149
142
  const signature = await this.signRaw(params.signerAddress, response.txId)
150
- const contractId = utils.binToHex(utils.contractIdFromAddress(response.contractAddress))
151
- return { ...response, contractId, signature, gasPrice: fromApiNumber256(response.gasPrice) }
143
+ return { signature, ...response }
152
144
  }
153
145
 
154
- async buildContractCreationTx(params: SignDeployContractTxParams): Promise<node.BuildDeployContractTxResult> {
155
- const data: node.BuildDeployContractTx = {
156
- ...(await this.usePublicKey(params)),
157
- initialAttoAlphAmount: toApiNumber256Optional(params.initialAttoAlphAmount),
158
- initialTokenAmounts: toApiTokens(params.initialTokenAmounts),
159
- issueTokenAmount: toApiNumber256Optional(params.issueTokenAmount),
160
- gasPrice: toApiNumber256Optional(params.gasPrice)
161
- }
162
- return this.getNodeProvider().contracts.postContractsUnsignedTxDeployContract(data)
146
+ override async buildDeployContractTx(
147
+ params: SignDeployContractTxParams
148
+ ): Promise<Omit<SignDeployContractTxResult, 'signature'>> {
149
+ return super.buildDeployContractTx(params, await this.getPublicKey(params.signerAddress))
163
150
  }
164
151
 
165
152
  async signExecuteScriptTx(params: SignExecuteScriptTxParams): Promise<SignExecuteScriptTxResult> {
166
- const response = await this.buildScriptTx(params)
153
+ const response = await this.buildExecuteScriptTx(params)
167
154
  const signature = await this.signRaw(params.signerAddress, response.txId)
168
- return { ...response, signature, gasPrice: fromApiNumber256(response.gasPrice) }
155
+ return { signature, ...response }
169
156
  }
170
157
 
171
- async buildScriptTx(params: SignExecuteScriptTxParams): Promise<node.BuildExecuteScriptTxResult> {
172
- const data: node.BuildExecuteScriptTx = {
173
- ...(await this.usePublicKey(params)),
174
- attoAlphAmount: toApiNumber256Optional(params.attoAlphAmount),
175
- tokens: toApiTokens(params.tokens),
176
- gasPrice: toApiNumber256Optional(params.gasPrice)
177
- }
178
- return this.getNodeProvider().contracts.postContractsUnsignedTxExecuteScript(data)
158
+ override async buildExecuteScriptTx(
159
+ params: SignExecuteScriptTxParams
160
+ ): Promise<Omit<SignExecuteScriptTxResult, 'signature'>> {
161
+ return super.buildExecuteScriptTx(params, await this.getPublicKey(params.signerAddress))
179
162
  }
180
163
 
181
164
  // in general, wallet should show the decoded information to user for confirmation
182
165
  // please overwrite this function for real wallet
183
166
  async signUnsignedTx(params: SignUnsignedTxParams): Promise<SignUnsignedTxResult> {
184
- const data = { unsignedTx: params.unsignedTx }
185
- const decoded = await this.getNodeProvider().transactions.postTransactionsDecodeUnsignedTx(data)
186
- const signature = await this.signRaw(params.signerAddress, decoded.unsignedTx.txId)
187
- return {
188
- fromGroup: decoded.fromGroup,
189
- toGroup: decoded.toGroup,
190
- unsignedTx: params.unsignedTx,
191
- txId: decoded.unsignedTx.txId,
192
- signature,
193
- gasAmount: decoded.unsignedTx.gasAmount,
194
- gasPrice: fromApiNumber256(decoded.unsignedTx.gasPrice)
195
- }
167
+ const response = await this.buildUnsignedTx(params)
168
+ const signature = await this.signRaw(params.signerAddress, response.txId)
169
+ return { signature, ...response }
196
170
  }
197
171
 
198
172
  async signMessage(params: SignMessageParams): Promise<SignMessageResult> {
@@ -0,0 +1,121 @@
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 { utils } from '..'
20
+ import { fromApiNumber256, node, NodeProvider, toApiNumber256Optional, toApiTokens } from '../api'
21
+ import { addressFromPublicKey } from '../utils'
22
+ import { toApiDestinations } from './signer'
23
+ import {
24
+ SignDeployContractTxParams,
25
+ SignDeployContractTxResult,
26
+ SignerAddress,
27
+ SignExecuteScriptTxParams,
28
+ SignExecuteScriptTxResult,
29
+ SignTransferTxParams,
30
+ SignTransferTxResult,
31
+ SignUnsignedTxParams,
32
+ SignUnsignedTxResult
33
+ } from './types'
34
+
35
+ export abstract class TransactionBuilder {
36
+ abstract get nodeProvider(): NodeProvider
37
+
38
+ static create(baseUrl: string, apiKey?: string) {
39
+ const nodeProvider = new NodeProvider(baseUrl, apiKey)
40
+ return new (class extends TransactionBuilder {
41
+ get nodeProvider(): NodeProvider {
42
+ return nodeProvider
43
+ }
44
+ })()
45
+ }
46
+
47
+ private static validatePublicKey(params: SignerAddress, publicKey: string) {
48
+ const address = addressFromPublicKey(publicKey)
49
+ if (address !== params.signerAddress) {
50
+ throw new Error('Unmatched public key')
51
+ }
52
+ }
53
+
54
+ async buildTransferTx(
55
+ params: SignTransferTxParams,
56
+ publicKey: string
57
+ ): Promise<Omit<SignTransferTxResult, 'signature'>> {
58
+ TransactionBuilder.validatePublicKey(params, publicKey)
59
+
60
+ const { destinations, gasPrice, ...rest } = params
61
+ const data: node.BuildTransaction = {
62
+ fromPublicKey: publicKey,
63
+ destinations: toApiDestinations(destinations),
64
+ gasPrice: toApiNumber256Optional(gasPrice),
65
+ ...rest
66
+ }
67
+ const response = await this.nodeProvider.transactions.postTransactionsBuild(data)
68
+ return { ...response, gasPrice: fromApiNumber256(response.gasPrice) }
69
+ }
70
+
71
+ async buildDeployContractTx(
72
+ params: SignDeployContractTxParams,
73
+ publicKey: string
74
+ ): Promise<Omit<SignDeployContractTxResult, 'signature'>> {
75
+ TransactionBuilder.validatePublicKey(params, publicKey)
76
+
77
+ const { initialAttoAlphAmount, initialTokenAmounts, issueTokenAmount, gasPrice, ...rest } = params
78
+ const data: node.BuildDeployContractTx = {
79
+ fromPublicKey: publicKey,
80
+ initialAttoAlphAmount: toApiNumber256Optional(initialAttoAlphAmount),
81
+ initialTokenAmounts: toApiTokens(initialTokenAmounts),
82
+ issueTokenAmount: toApiNumber256Optional(issueTokenAmount),
83
+ gasPrice: toApiNumber256Optional(gasPrice),
84
+ ...rest
85
+ }
86
+ const response = await this.nodeProvider.contracts.postContractsUnsignedTxDeployContract(data)
87
+ const contractId = utils.binToHex(utils.contractIdFromAddress(response.contractAddress))
88
+ return { ...response, contractId, gasPrice: fromApiNumber256(response.gasPrice) }
89
+ }
90
+
91
+ async buildExecuteScriptTx(
92
+ params: SignExecuteScriptTxParams,
93
+ publicKey: string
94
+ ): Promise<Omit<SignExecuteScriptTxResult, 'signature'>> {
95
+ TransactionBuilder.validatePublicKey(params, publicKey)
96
+
97
+ const { attoAlphAmount, tokens, gasPrice, ...rest } = params
98
+ const data: node.BuildExecuteScriptTx = {
99
+ fromPublicKey: publicKey,
100
+ attoAlphAmount: toApiNumber256Optional(attoAlphAmount),
101
+ tokens: toApiTokens(tokens),
102
+ gasPrice: toApiNumber256Optional(gasPrice),
103
+ ...rest
104
+ }
105
+ const response = await this.nodeProvider.contracts.postContractsUnsignedTxExecuteScript(data)
106
+ return { ...response, gasPrice: fromApiNumber256(response.gasPrice) }
107
+ }
108
+
109
+ async buildUnsignedTx(params: SignUnsignedTxParams): Promise<Omit<SignUnsignedTxResult, 'signature'>> {
110
+ const data = { unsignedTx: params.unsignedTx }
111
+ const decoded = await this.nodeProvider.transactions.postTransactionsDecodeUnsignedTx(data)
112
+ return {
113
+ fromGroup: decoded.fromGroup,
114
+ toGroup: decoded.toGroup,
115
+ unsignedTx: params.unsignedTx,
116
+ txId: decoded.unsignedTx.txId,
117
+ gasAmount: decoded.unsignedTx.gasAmount,
118
+ gasPrice: fromApiNumber256(decoded.unsignedTx.gasPrice)
119
+ }
120
+ }
121
+ }
@@ -143,6 +143,13 @@ export interface SubmissionResult {
143
143
  export interface EnableOptionsBase {
144
144
  // chainGroup - specify whether to use addresses from a specific group
145
145
  chainGroup?: number
146
+ networkId: string
146
147
  onDisconnected: () => Promise<void>
147
- onNetworkChanged: (network: { networkName: string; networkId: number }) => Promise<void>
148
148
  }
149
+
150
+ // Transaction Params for InteractiveSignerProvider
151
+ export type ExtSignTransferTxParams = SignTransferTxParams & { networkId: string }
152
+ export type ExtSignDeployContractTxParams = SignDeployContractTxParams & { networkId: string }
153
+ export type ExtSignExecuteScriptTxParams = SignExecuteScriptTxParams & { networkId: string }
154
+ export type ExtSignUnsignedTxParams = SignUnsignedTxParams & { networkId: string }
155
+ export type ExtSignMessageParams = SignMessageParams & { networkId: string }
@@ -0,0 +1,9 @@
1
+ Interface IToken {
2
+ pub fn getSymbol() -> ByteVec
3
+
4
+ pub fn getName() -> ByteVec
5
+
6
+ pub fn getDecimals() -> U256
7
+
8
+ pub fn getTotalSupply() -> U256
9
+ }