@alephium/web3 0.40.0 → 0.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/alephium-web3.min.js +1 -1
  2. package/dist/alephium-web3.min.js.map +1 -1
  3. package/dist/src/api/node-provider.d.ts +2 -0
  4. package/dist/src/api/node-provider.js +12 -6
  5. package/dist/src/api/utils.d.ts +1 -1
  6. package/dist/src/block/block.d.ts +28 -0
  7. package/dist/src/block/block.js +131 -0
  8. package/dist/src/block/index.d.ts +1 -0
  9. package/dist/src/block/index.js +22 -0
  10. package/dist/src/codec/contract-output-codec.js +4 -4
  11. package/dist/src/codec/lockup-script-codec.js +2 -2
  12. package/dist/src/codec/method-codec.d.ts +3 -1
  13. package/dist/src/codec/method-codec.js +27 -2
  14. package/dist/src/codec/script-codec.d.ts +11 -6
  15. package/dist/src/codec/script-codec.js +13 -2
  16. package/dist/src/codec/transaction-codec.js +2 -2
  17. package/dist/src/codec/unlock-script-codec.d.ts +2 -2
  18. package/dist/src/codec/unsigned-tx-codec.d.ts +2 -2
  19. package/dist/src/contract/contract.d.ts +23 -101
  20. package/dist/src/contract/contract.js +52 -538
  21. package/dist/src/contract/events.d.ts +1 -2
  22. package/dist/src/contract/events.js +28 -14
  23. package/dist/src/index.d.ts +1 -0
  24. package/dist/src/index.js +1 -0
  25. package/dist/src/signer/tx-builder.js +4 -4
  26. package/dist/src/transaction/index.d.ts +1 -0
  27. package/dist/src/transaction/index.js +1 -0
  28. package/dist/src/transaction/status.js +28 -4
  29. package/dist/src/transaction/utils.d.ts +2 -0
  30. package/dist/src/transaction/utils.js +34 -0
  31. package/dist/src/utils/address.js +29 -16
  32. package/dist/src/utils/exchange.js +25 -15
  33. package/dist/src/utils/number.d.ts +1 -1
  34. package/dist/src/utils/sign.js +6 -6
  35. package/dist/src/utils/subscription.d.ts +4 -4
  36. package/dist/src/utils/subscription.js +1 -1
  37. package/package.json +3 -3
  38. package/src/api/node-provider.ts +8 -1
  39. package/src/api/utils.ts +1 -1
  40. package/src/block/block.ts +139 -0
  41. package/src/block/index.ts +19 -0
  42. package/src/codec/contract-output-codec.ts +1 -1
  43. package/src/codec/lockup-script-codec.ts +3 -3
  44. package/src/codec/method-codec.ts +41 -3
  45. package/src/codec/script-codec.ts +23 -5
  46. package/src/codec/transaction-codec.ts +1 -1
  47. package/src/codec/unlock-script-codec.ts +2 -2
  48. package/src/codec/unsigned-tx-codec.ts +2 -2
  49. package/src/contract/contract.ts +72 -779
  50. package/src/contract/events.ts +6 -18
  51. package/src/index.ts +1 -0
  52. package/src/signer/tx-builder.ts +2 -2
  53. package/src/transaction/index.ts +1 -0
  54. package/src/transaction/status.ts +4 -4
  55. package/src/transaction/utils.ts +38 -0
  56. package/src/utils/address.ts +15 -2
  57. package/src/utils/exchange.ts +32 -10
  58. package/src/utils/number.ts +1 -1
  59. package/src/utils/sign.ts +1 -1
  60. package/src/utils/subscription.ts +4 -4
  61. package/std/fungible_token_interface.ral +1 -0
  62. package/std/nft_collection_interface.ral +1 -0
  63. package/std/nft_collection_with_royalty_interface.ral +1 -0
  64. package/std/nft_interface.ral +1 -0
  65. package/webpack.config.js +0 -1
  66. package/dist/src/utils/error.d.ts +0 -15
  67. package/dist/src/utils/error.js +0 -66
  68. package/src/utils/error.ts +0 -77
@@ -17,7 +17,6 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
 
19
19
  import { Buffer } from 'buffer/'
20
- import fs from 'fs'
21
20
  import { promises as fsPromises } from 'fs'
22
21
  import {
23
22
  fromApiNumber256,
@@ -34,9 +33,9 @@ import {
34
33
  getDefaultPrimitiveValue,
35
34
  PrimitiveTypes,
36
35
  decodeArrayType,
37
- fromApiPrimitiveVal
36
+ fromApiPrimitiveVal,
37
+ tryGetCallResult
38
38
  } from '../api'
39
- import { CompileProjectResult } from '../api/api-alephium'
40
39
  import {
41
40
  SignDeployContractTxParams,
42
41
  SignDeployContractTxResult,
@@ -62,11 +61,9 @@ import {
62
61
  HexString
63
62
  } from '../utils'
64
63
  import { getCurrentNodeProvider } from '../global'
65
- import * as path from 'path'
66
64
  import { EventSubscribeOptions, EventSubscription, subscribeToEvents } from './events'
67
65
  import { ONE_ALPH, TOTAL_NUMBER_OF_GROUPS } from '../constants'
68
66
  import * as blake from 'blakejs'
69
- import { parseError } from '../utils/error'
70
67
  import { isContractDebugMessageEnabled } from '../debug'
71
68
  import {
72
69
  contract,
@@ -87,7 +84,7 @@ const crypto = new WebCrypto()
87
84
  export type FieldsSig = node.FieldsSig
88
85
  export type MapsSig = node.MapsSig
89
86
  export type EventSig = node.EventSig
90
- export type FunctionSig = node.FunctionSig
87
+ export type FunctionSig = Omit<node.FunctionSig, 'isPublic' | 'usePreapprovedAssets' | 'useAssetsInContract'>
91
88
  export type Fields = NamedVals
92
89
  export type Arguments = NamedVals
93
90
  export type Constant = node.Constant
@@ -95,14 +92,6 @@ export type Enum = node.Enum
95
92
 
96
93
  export const StdIdFieldName = '__stdInterfaceId'
97
94
 
98
- enum SourceKind {
99
- Contract = 0,
100
- Script = 1,
101
- AbstractContract = 2,
102
- Interface = 3,
103
- Struct = 4
104
- }
105
-
106
95
  export type CompilerOptions = node.CompilerOptions & {
107
96
  errorOnWarnings: boolean
108
97
  }
@@ -118,231 +107,6 @@ export const DEFAULT_NODE_COMPILER_OPTIONS: node.CompilerOptions = {
118
107
 
119
108
  export const DEFAULT_COMPILER_OPTIONS: CompilerOptions = { errorOnWarnings: true, ...DEFAULT_NODE_COMPILER_OPTIONS }
120
109
 
121
- class TypedMatcher<T extends SourceKind> {
122
- matcher: RegExp
123
- type: T
124
-
125
- constructor(pattern: string, type: T) {
126
- this.matcher = new RegExp(pattern, 'mg')
127
- this.type = type
128
- }
129
- }
130
-
131
- function removeParentsPrefix(parts: string[]): string {
132
- let index = 0
133
- for (let i = 0; i < parts.length; i++) {
134
- if (parts[`${i}`] === '..') {
135
- index += 1
136
- } else {
137
- break
138
- }
139
- }
140
- return path.join(...parts.slice(index))
141
- }
142
-
143
- class SourceInfo {
144
- type: SourceKind
145
- name: string
146
- contractRelativePath: string
147
- sourceCode: string
148
- sourceCodeHash: string
149
- isExternal: boolean
150
-
151
- getArtifactPath(artifactsRootDir: string): string {
152
- let fullPath: string
153
- if (this.isExternal) {
154
- const relativePath = removeParentsPrefix(this.contractRelativePath.split(path.sep))
155
- const externalPath = path.join('.external', relativePath)
156
- fullPath = path.join(artifactsRootDir, externalPath)
157
- } else {
158
- fullPath = path.join(artifactsRootDir, this.contractRelativePath)
159
- }
160
- return path.join(path.dirname(fullPath), `${this.name}.ral.json`)
161
- }
162
-
163
- constructor(
164
- type: SourceKind,
165
- name: string,
166
- sourceCode: string,
167
- sourceCodeHash: string,
168
- contractRelativePath: string,
169
- isExternal: boolean
170
- ) {
171
- this.type = type
172
- this.name = name
173
- this.sourceCode = sourceCode
174
- this.sourceCodeHash = sourceCodeHash
175
- this.contractRelativePath = contractRelativePath
176
- this.isExternal = isExternal
177
- }
178
-
179
- static async from(
180
- type: SourceKind,
181
- name: string,
182
- sourceCode: string,
183
- contractRelativePath: string,
184
- isExternal: boolean
185
- ): Promise<SourceInfo> {
186
- const sourceCodeHash = await crypto.subtle.digest('SHA-256', Buffer.from(sourceCode))
187
- const sourceCodeHashHex = Buffer.from(sourceCodeHash).toString('hex')
188
- return new SourceInfo(type, name, sourceCode, sourceCodeHashHex, contractRelativePath, isExternal)
189
- }
190
- }
191
-
192
- class Compiled<T extends Artifact> {
193
- sourceInfo: SourceInfo
194
- artifact: T
195
- warnings: string[]
196
-
197
- constructor(sourceInfo: SourceInfo, artifact: T, warnings: string[]) {
198
- this.sourceInfo = sourceInfo
199
- this.artifact = artifact
200
- this.warnings = warnings
201
- }
202
- }
203
-
204
- type CodeInfo = {
205
- sourceFile: string
206
- sourceCodeHash: string
207
- bytecodeDebugPatch: string
208
- codeHashDebug: string
209
- warnings: string[]
210
- }
211
-
212
- type SourceInfoIndexes = {
213
- sourceInfo: SourceInfo
214
- startIndex: number
215
- endIndex: number
216
- }
217
-
218
- function findSourceInfoAtLineNumber(sources: SourceInfo[], line: number): SourceInfoIndexes | undefined {
219
- let currentLine = 0
220
- const sourceInfosWithLine: SourceInfoIndexes[] = sources.map((source) => {
221
- const startIndex = currentLine + 1
222
- currentLine += source.sourceCode.split('\n').length
223
- const endIndex = currentLine
224
- return { sourceInfo: source, startIndex: startIndex, endIndex: endIndex }
225
- })
226
-
227
- const sourceInfo = sourceInfosWithLine.find((sourceInfoWithLine) => {
228
- return line >= sourceInfoWithLine.startIndex && line <= sourceInfoWithLine.endIndex
229
- })
230
-
231
- return sourceInfo
232
- }
233
-
234
- export class ProjectArtifact {
235
- static readonly artifactFileName = '.project.json'
236
-
237
- fullNodeVersion: string
238
- compilerOptionsUsed: node.CompilerOptions
239
- infos: Map<string, CodeInfo>
240
-
241
- static checkCompilerOptionsParameter(compilerOptions: node.CompilerOptions): void {
242
- if (Object.keys(compilerOptions).length != Object.keys(DEFAULT_NODE_COMPILER_OPTIONS).length) {
243
- throw Error(`Not all compiler options are set: ${compilerOptions}`)
244
- }
245
-
246
- const combined = { ...compilerOptions, ...DEFAULT_NODE_COMPILER_OPTIONS }
247
- if (Object.keys(combined).length !== Object.keys(DEFAULT_NODE_COMPILER_OPTIONS).length) {
248
- throw Error(`There are unknown compiler options: ${compilerOptions}`)
249
- }
250
- }
251
-
252
- constructor(fullNodeVersion: string, compilerOptionsUsed: node.CompilerOptions, infos: Map<string, CodeInfo>) {
253
- ProjectArtifact.checkCompilerOptionsParameter(compilerOptionsUsed)
254
- this.fullNodeVersion = fullNodeVersion
255
- this.compilerOptionsUsed = compilerOptionsUsed
256
- this.infos = infos
257
- }
258
-
259
- static isCodeChanged(current: ProjectArtifact, previous: ProjectArtifact): boolean {
260
- if (current.infos.size !== previous.infos.size) {
261
- return true
262
- }
263
- for (const [name, codeInfo] of current.infos) {
264
- const prevCodeInfo = previous.infos.get(name)
265
- if (prevCodeInfo?.codeHashDebug !== codeInfo.codeHashDebug) {
266
- return true
267
- }
268
- }
269
- return false
270
- }
271
-
272
- async saveToFile(rootPath: string): Promise<void> {
273
- const filepath = path.join(rootPath, ProjectArtifact.artifactFileName)
274
- const artifact = {
275
- fullNodeVersion: this.fullNodeVersion,
276
- compilerOptionsUsed: this.compilerOptionsUsed,
277
- infos: Object.fromEntries(new Map([...this.infos].sort()))
278
- }
279
- const content = JSON.stringify(artifact, null, 2)
280
- return fsPromises.writeFile(filepath, content)
281
- }
282
-
283
- needToReCompile(compilerOptions: node.CompilerOptions, sourceInfos: SourceInfo[], fullNodeVersion: string): boolean {
284
- ProjectArtifact.checkCompilerOptionsParameter(compilerOptions)
285
- if (this.fullNodeVersion !== fullNodeVersion) {
286
- return true
287
- }
288
-
289
- const optionsMatched = Object.entries(compilerOptions).every(([key, inputOption]) => {
290
- const usedOption = this.compilerOptionsUsed[`${key}`]
291
- return usedOption === inputOption
292
- })
293
- if (!optionsMatched) {
294
- return true
295
- }
296
-
297
- if (sourceInfos.length !== this.infos.size) {
298
- return true
299
- }
300
- for (const sourceInfo of sourceInfos) {
301
- const info = this.infos.get(sourceInfo.name)
302
- if (typeof info === 'undefined' || info.sourceCodeHash !== sourceInfo.sourceCodeHash) {
303
- return true
304
- }
305
- }
306
-
307
- return false
308
- }
309
-
310
- static async from(rootPath: string): Promise<ProjectArtifact | undefined> {
311
- const filepath = path.join(rootPath, ProjectArtifact.artifactFileName)
312
- if (!fs.existsSync(filepath)) {
313
- return undefined
314
- }
315
- try {
316
- const content = await fsPromises.readFile(filepath)
317
- const json = JSON.parse(content.toString())
318
- const fullNodeVersion = json.fullNodeVersion as string
319
- const compilerOptionsUsed = json.compilerOptionsUsed as node.CompilerOptions
320
- const files = new Map(Object.entries<CodeInfo>(json.infos))
321
- return new ProjectArtifact(fullNodeVersion, compilerOptionsUsed, files)
322
- } catch (error) {
323
- console.error(`Failed to load project artifact, error: ${error}`)
324
- return undefined
325
- }
326
- }
327
- }
328
-
329
- function removeOldArtifacts(dir: string) {
330
- const files = fs.readdirSync(dir)
331
- files.forEach((file) => {
332
- const filePath = path.join(dir, file)
333
- const stat = fs.statSync(filePath)
334
- if (stat.isDirectory()) {
335
- removeOldArtifacts(filePath)
336
- } else if (filePath.endsWith('.ral.json') || filePath.endsWith('.ral')) {
337
- fs.unlinkSync(filePath)
338
- }
339
- })
340
-
341
- if (fs.readdirSync(dir).length === 0) {
342
- fs.rmdirSync(dir)
343
- }
344
- }
345
-
346
110
  export class Struct {
347
111
  name: string
348
112
  fieldNames: string[]
@@ -377,491 +141,6 @@ export class Struct {
377
141
  }
378
142
  }
379
143
 
380
- export class Project {
381
- sourceInfos: SourceInfo[]
382
- contracts: Map<string, Compiled<Contract>>
383
- scripts: Map<string, Compiled<Script>>
384
- structs: Struct[]
385
- projectArtifact: ProjectArtifact
386
-
387
- readonly contractsRootDir: string
388
- readonly artifactsRootDir: string
389
-
390
- static currentProject: Project
391
-
392
- static readonly importRegex = new RegExp('^import "[^"./]+/[^"]*[a-z][a-z_0-9]*(.ral)?"', 'mg')
393
- static readonly abstractContractMatcher = new TypedMatcher<SourceKind>(
394
- '^Abstract Contract ([A-Z][a-zA-Z0-9]*)',
395
- SourceKind.AbstractContract
396
- )
397
- static readonly contractMatcher = new TypedMatcher('^Contract ([A-Z][a-zA-Z0-9]*)', SourceKind.Contract)
398
- static readonly interfaceMatcher = new TypedMatcher('^Interface ([A-Z][a-zA-Z0-9]*)', SourceKind.Interface)
399
- static readonly scriptMatcher = new TypedMatcher('^TxScript ([A-Z][a-zA-Z0-9]*)', SourceKind.Script)
400
- static readonly structMatcher = new TypedMatcher('struct ([A-Z][a-zA-Z0-9]*)', SourceKind.Struct)
401
- static readonly matchers = [
402
- Project.abstractContractMatcher,
403
- Project.contractMatcher,
404
- Project.interfaceMatcher,
405
- Project.scriptMatcher,
406
- Project.structMatcher
407
- ]
408
-
409
- static buildProjectArtifact(
410
- fullNodeVersion: string,
411
- sourceInfos: SourceInfo[],
412
- contracts: Map<string, Compiled<Contract>>,
413
- scripts: Map<string, Compiled<Script>>,
414
- compilerOptions: node.CompilerOptions
415
- ): ProjectArtifact {
416
- const files: Map<string, CodeInfo> = new Map()
417
- contracts.forEach((c) => {
418
- files.set(c.artifact.name, {
419
- sourceFile: c.sourceInfo.contractRelativePath,
420
- sourceCodeHash: c.sourceInfo.sourceCodeHash,
421
- bytecodeDebugPatch: c.artifact.bytecodeDebugPatch,
422
- codeHashDebug: c.artifact.codeHashDebug,
423
- warnings: c.warnings
424
- })
425
- })
426
- scripts.forEach((s) => {
427
- files.set(s.artifact.name, {
428
- sourceFile: s.sourceInfo.contractRelativePath,
429
- sourceCodeHash: s.sourceInfo.sourceCodeHash,
430
- bytecodeDebugPatch: s.artifact.bytecodeDebugPatch,
431
- codeHashDebug: '',
432
- warnings: s.warnings
433
- })
434
- })
435
- const compiledSize = contracts.size + scripts.size
436
- sourceInfos.slice(compiledSize).forEach((c) => {
437
- files.set(c.name, {
438
- sourceFile: c.contractRelativePath,
439
- sourceCodeHash: c.sourceCodeHash,
440
- bytecodeDebugPatch: '',
441
- codeHashDebug: '',
442
- warnings: []
443
- })
444
- })
445
- return new ProjectArtifact(fullNodeVersion, compilerOptions, files)
446
- }
447
-
448
- private constructor(
449
- contractsRootDir: string,
450
- artifactsRootDir: string,
451
- sourceInfos: SourceInfo[],
452
- contracts: Map<string, Compiled<Contract>>,
453
- scripts: Map<string, Compiled<Script>>,
454
- structs: Struct[],
455
- errorOnWarnings: boolean,
456
- projectArtifact: ProjectArtifact
457
- ) {
458
- this.contractsRootDir = contractsRootDir
459
- this.artifactsRootDir = artifactsRootDir
460
- this.sourceInfos = sourceInfos
461
- this.contracts = contracts
462
- this.scripts = scripts
463
- this.structs = structs
464
- this.projectArtifact = projectArtifact
465
-
466
- if (errorOnWarnings) {
467
- Project.checkCompilerWarnings(
468
- [
469
- ...[...contracts.entries()].map((c) => c[1].warnings).flat(),
470
- ...[...scripts.entries()].map((s) => s[1].warnings).flat()
471
- ],
472
- errorOnWarnings
473
- )
474
- }
475
- }
476
-
477
- static checkCompilerWarnings(warnings: string[], errorOnWarnings: boolean): void {
478
- if (warnings.length !== 0) {
479
- const prefixPerWarning = ' - '
480
- const warningString = prefixPerWarning + warnings.join('\n' + prefixPerWarning)
481
- const output = `Compilation warnings:\n` + warningString + '\n'
482
- if (errorOnWarnings) {
483
- throw new Error(output)
484
- } else {
485
- console.log(output)
486
- }
487
- }
488
- }
489
-
490
- static contract(name: string): Contract {
491
- const contract = Project.currentProject.contracts.get(name)
492
- if (typeof contract === 'undefined') {
493
- throw new Error(`Contract "${name}" does not exist`)
494
- }
495
- return contract.artifact
496
- }
497
-
498
- static script(name: string): Script {
499
- const script = Project.currentProject.scripts.get(name)
500
- if (typeof script === 'undefined') {
501
- throw new Error(`Script "${name}" does not exist`)
502
- }
503
- return script.artifact
504
- }
505
-
506
- private static async loadStructs(artifactsRootDir: string): Promise<Struct[]> {
507
- const filePath = path.join(artifactsRootDir, 'structs.ral.json')
508
- if (!fs.existsSync(filePath)) return []
509
- const content = await fsPromises.readFile(filePath)
510
- const json = JSON.parse(content.toString())
511
- if (!Array.isArray(json)) {
512
- throw Error(`Invalid structs JSON: ${content}`)
513
- }
514
- return Array.from(json).map((item) => Struct.fromJson(item))
515
- }
516
-
517
- private async saveStructsToFile(): Promise<void> {
518
- if (this.structs.length === 0) return
519
- const structs = this.structs.map((s) => s.toJson())
520
- const filePath = path.join(this.artifactsRootDir, 'structs.ral.json')
521
- return fsPromises.writeFile(filePath, JSON.stringify(structs, null, 2))
522
- }
523
-
524
- private async saveArtifactsToFile(projectRootDir: string): Promise<void> {
525
- const artifactsRootDir = this.artifactsRootDir
526
- const saveToFile = async function (compiled: Compiled<Artifact>): Promise<void> {
527
- const artifactPath = compiled.sourceInfo.getArtifactPath(artifactsRootDir)
528
- const dirname = path.dirname(artifactPath)
529
- if (!fs.existsSync(dirname)) {
530
- fs.mkdirSync(dirname, { recursive: true })
531
- }
532
- return fsPromises.writeFile(artifactPath, compiled.artifact.toString())
533
- }
534
- this.contracts.forEach((contract) => saveToFile(contract))
535
- this.scripts.forEach((script) => saveToFile(script))
536
- this.saveStructsToFile()
537
- await this.projectArtifact.saveToFile(projectRootDir)
538
- }
539
-
540
- contractByCodeHash(codeHash: string): Contract {
541
- const contract = [...this.contracts.values()].find(
542
- (c) => c.artifact.codeHash === codeHash || c.artifact.codeHashDebug == codeHash
543
- )
544
- if (typeof contract === 'undefined') {
545
- throw new Error(`Unknown code with code hash: ${codeHash}`)
546
- }
547
- return contract.artifact
548
- }
549
-
550
- private static async getCompileResult(
551
- provider: NodeProvider,
552
- compilerOptions: node.CompilerOptions,
553
- sources: SourceInfo[]
554
- ): Promise<CompileProjectResult> {
555
- try {
556
- const sourceStr = sources.map((f) => f.sourceCode).join('\n')
557
- return await provider.contracts.postContractsCompileProject({
558
- code: sourceStr,
559
- compilerOptions: compilerOptions
560
- })
561
- } catch (error) {
562
- if (!(error instanceof Error)) {
563
- throw error
564
- }
565
-
566
- const parsed = parseError(error.message)
567
- if (!parsed) {
568
- throw error
569
- }
570
-
571
- const sourceInfo = findSourceInfoAtLineNumber(sources, parsed.lineStart)
572
- if (!sourceInfo) {
573
- throw error
574
- }
575
-
576
- const shiftIndex = parsed.lineStart - sourceInfo.startIndex + 1
577
- const newError = parsed.reformat(shiftIndex, sourceInfo.sourceInfo.contractRelativePath)
578
- throw new Error(newError)
579
- }
580
- }
581
-
582
- private static async compile(
583
- fullNodeVersion: string,
584
- provider: NodeProvider,
585
- sourceInfos: SourceInfo[],
586
- projectRootDir: string,
587
- contractsRootDir: string,
588
- artifactsRootDir: string,
589
- errorOnWarnings: boolean,
590
- compilerOptions: node.CompilerOptions
591
- ): Promise<Project> {
592
- const removeDuplicates = sourceInfos.reduce((acc: SourceInfo[], sourceInfo: SourceInfo) => {
593
- if (acc.find((info) => info.sourceCodeHash === sourceInfo.sourceCodeHash) === undefined) {
594
- acc.push(sourceInfo)
595
- }
596
- return acc
597
- }, [])
598
-
599
- const result = await Project.getCompileResult(provider, compilerOptions, removeDuplicates)
600
- const contracts = new Map<string, Compiled<Contract>>()
601
- const scripts = new Map<string, Compiled<Script>>()
602
- const structs = result.structs === undefined ? [] : result.structs.map((item) => Struct.fromStructSig(item))
603
- result.contracts.forEach((contractResult) => {
604
- const sourceInfo = sourceInfos.find(
605
- (sourceInfo) => sourceInfo.type === SourceKind.Contract && sourceInfo.name === contractResult.name
606
- )
607
- if (sourceInfo === undefined) {
608
- // this should never happen
609
- throw new Error(`SourceInfo does not exist for contract ${contractResult.name}`)
610
- }
611
- const contract = Contract.fromCompileResult(contractResult, structs)
612
- contracts.set(contract.name, new Compiled(sourceInfo, contract, contractResult.warnings))
613
- })
614
- result.scripts.forEach((scriptResult) => {
615
- const sourceInfo = sourceInfos.find(
616
- (sourceInfo) => sourceInfo.type === SourceKind.Script && sourceInfo.name === scriptResult.name
617
- )
618
- if (sourceInfo === undefined) {
619
- // this should never happen
620
- throw new Error(`SourceInfo does not exist for script ${scriptResult.name}`)
621
- }
622
- const script = Script.fromCompileResult(scriptResult, structs)
623
- scripts.set(script.name, new Compiled(sourceInfo, script, scriptResult.warnings))
624
- })
625
- const projectArtifact = Project.buildProjectArtifact(
626
- fullNodeVersion,
627
- sourceInfos,
628
- contracts,
629
- scripts,
630
- compilerOptions
631
- )
632
- const project = new Project(
633
- contractsRootDir,
634
- artifactsRootDir,
635
- sourceInfos,
636
- contracts,
637
- scripts,
638
- structs,
639
- errorOnWarnings,
640
- projectArtifact
641
- )
642
- await project.saveArtifactsToFile(projectRootDir)
643
- return project
644
- }
645
-
646
- private static async loadArtifacts(
647
- provider: NodeProvider,
648
- sourceInfos: SourceInfo[],
649
- projectArtifact: ProjectArtifact,
650
- projectRootDir: string,
651
- contractsRootDir: string,
652
- artifactsRootDir: string,
653
- errorOnWarnings: boolean,
654
- compilerOptions: node.CompilerOptions
655
- ): Promise<Project> {
656
- try {
657
- const contracts = new Map<string, Compiled<Contract>>()
658
- const scripts = new Map<string, Compiled<Script>>()
659
- const structs = await Project.loadStructs(artifactsRootDir)
660
- for (const sourceInfo of sourceInfos) {
661
- const info = projectArtifact.infos.get(sourceInfo.name)
662
- if (typeof info === 'undefined') {
663
- throw Error(`Unable to find project info for ${sourceInfo.name}, please rebuild the project`)
664
- }
665
- const warnings = info.warnings
666
- const artifactDir = sourceInfo.getArtifactPath(artifactsRootDir)
667
- if (sourceInfo.type === SourceKind.Contract) {
668
- const artifact = await Contract.fromArtifactFile(
669
- artifactDir,
670
- info.bytecodeDebugPatch,
671
- info.codeHashDebug,
672
- structs
673
- )
674
- contracts.set(artifact.name, new Compiled(sourceInfo, artifact, warnings))
675
- } else if (sourceInfo.type === SourceKind.Script) {
676
- const artifact = await Script.fromArtifactFile(artifactDir, info.bytecodeDebugPatch, structs)
677
- scripts.set(artifact.name, new Compiled(sourceInfo, artifact, warnings))
678
- }
679
- }
680
-
681
- return new Project(
682
- contractsRootDir,
683
- artifactsRootDir,
684
- sourceInfos,
685
- contracts,
686
- scripts,
687
- structs,
688
- errorOnWarnings,
689
- projectArtifact
690
- )
691
- } catch (error) {
692
- console.log(`Failed to load artifacts, error: ${error}, try to re-compile contracts...`)
693
- return Project.compile(
694
- projectArtifact.fullNodeVersion,
695
- provider,
696
- sourceInfos,
697
- projectRootDir,
698
- contractsRootDir,
699
- artifactsRootDir,
700
- errorOnWarnings,
701
- compilerOptions
702
- )
703
- }
704
- }
705
-
706
- private static getImportSourcePath(projectRootDir: string, importPath: string): string {
707
- const parts = importPath.split('/')
708
- if (parts.length > 1 && parts[0] === 'std') {
709
- const currentDir = path.dirname(__filename)
710
- return path.join(...[currentDir, '..', '..', '..', importPath])
711
- }
712
- let moduleDir = projectRootDir
713
- while (true) {
714
- const expectedPath = path.join(...[moduleDir, 'node_modules', importPath])
715
- if (fs.existsSync(expectedPath)) {
716
- return expectedPath
717
- }
718
- const oldModuleDir = moduleDir
719
- moduleDir = path.join(moduleDir, '..')
720
- if (oldModuleDir === moduleDir) {
721
- throw new Error(`Specified import file does not exist: ${importPath}`)
722
- }
723
- }
724
- }
725
-
726
- private static async handleImports(
727
- projectRootDir: string,
728
- contractRootDir: string,
729
- sourceStr: string,
730
- importsCache: string[]
731
- ): Promise<[string, SourceInfo[]]> {
732
- const localImportsCache: string[] = []
733
- const result = sourceStr.replace(Project.importRegex, (match) => {
734
- localImportsCache.push(match)
735
- return ''
736
- })
737
- const externalSourceInfos: SourceInfo[] = []
738
- for (const myImport of localImportsCache) {
739
- const originImportPath = myImport.slice(8, -1)
740
- const importPath = originImportPath.endsWith('.ral') ? originImportPath : originImportPath + '.ral'
741
- if (!importsCache.includes(importPath)) {
742
- importsCache.push(importPath)
743
- const sourcePath = Project.getImportSourcePath(projectRootDir, importPath)
744
- const sourceInfos = await Project.loadSourceFile(
745
- projectRootDir,
746
- contractRootDir,
747
- sourcePath,
748
- importsCache,
749
- true
750
- )
751
- externalSourceInfos.push(...sourceInfos)
752
- }
753
- }
754
- return [result, externalSourceInfos]
755
- }
756
-
757
- private static async loadSourceFile(
758
- projectRootDir: string,
759
- contractsRootDir: string,
760
- sourcePath: string,
761
- importsCache: string[],
762
- isExternal: boolean
763
- ): Promise<SourceInfo[]> {
764
- const contractRelativePath = path.relative(contractsRootDir, sourcePath)
765
- if (!sourcePath.endsWith('.ral')) {
766
- throw new Error(`Invalid filename: ${sourcePath}, smart contract file name should end with ".ral"`)
767
- }
768
-
769
- const sourceBuffer = await fsPromises.readFile(sourcePath)
770
- const [sourceStr, externalSourceInfos] = await Project.handleImports(
771
- projectRootDir,
772
- contractsRootDir,
773
- sourceBuffer.toString(),
774
- importsCache
775
- )
776
- if (sourceStr.match(new RegExp('^import "', 'mg')) !== null) {
777
- throw new Error(`Invalid import statements, source: ${sourcePath}`)
778
- }
779
- const sourceInfos = externalSourceInfos
780
- for (const matcher of this.matchers) {
781
- const results = sourceStr.matchAll(matcher.matcher)
782
- for (const result of results) {
783
- const sourceInfo = await SourceInfo.from(matcher.type, result[1], sourceStr, contractRelativePath, isExternal)
784
- sourceInfos.push(sourceInfo)
785
- }
786
- }
787
- return sourceInfos
788
- }
789
-
790
- private static async loadSourceFiles(projectRootDir: string, contractsRootDir: string): Promise<SourceInfo[]> {
791
- const importsCache: string[] = []
792
- const sourceInfos: SourceInfo[] = []
793
- const loadDir = async function (dirPath: string): Promise<void> {
794
- const dirents = await fsPromises.readdir(dirPath, { withFileTypes: true })
795
- for (const dirent of dirents) {
796
- if (dirent.isFile()) {
797
- const sourcePath = path.join(dirPath, dirent.name)
798
- const infos = await Project.loadSourceFile(projectRootDir, contractsRootDir, sourcePath, importsCache, false)
799
- sourceInfos.push(...infos)
800
- } else {
801
- const newPath = path.join(dirPath, dirent.name)
802
- await loadDir(newPath)
803
- }
804
- }
805
- }
806
- await loadDir(contractsRootDir)
807
- const contractAndScriptSize = sourceInfos.filter(
808
- (f) => f.type === SourceKind.Contract || f.type === SourceKind.Script
809
- ).length
810
- if (sourceInfos.length === 0 || contractAndScriptSize === 0) {
811
- throw new Error('Project have no source files')
812
- }
813
- return sourceInfos.sort((a, b) => a.type - b.type)
814
- }
815
-
816
- static readonly DEFAULT_CONTRACTS_DIR = 'contracts'
817
- static readonly DEFAULT_ARTIFACTS_DIR = 'artifacts'
818
-
819
- static async build(
820
- compilerOptionsPartial: Partial<CompilerOptions> = {},
821
- projectRootDir = '.',
822
- contractsRootDir = Project.DEFAULT_CONTRACTS_DIR,
823
- artifactsRootDir = Project.DEFAULT_ARTIFACTS_DIR,
824
- defaultFullNodeVersion: string | undefined = undefined
825
- ): Promise<void> {
826
- const provider = getCurrentNodeProvider()
827
- const fullNodeVersion = defaultFullNodeVersion ?? (await provider.infos.getInfosVersion()).version
828
- const sourceFiles = await Project.loadSourceFiles(projectRootDir, contractsRootDir)
829
- const { errorOnWarnings, ...nodeCompilerOptions } = { ...DEFAULT_COMPILER_OPTIONS, ...compilerOptionsPartial }
830
- const projectArtifact = await ProjectArtifact.from(projectRootDir)
831
- if (
832
- projectArtifact === undefined ||
833
- projectArtifact.needToReCompile(nodeCompilerOptions, sourceFiles, fullNodeVersion)
834
- ) {
835
- if (fs.existsSync(artifactsRootDir)) {
836
- removeOldArtifacts(artifactsRootDir)
837
- }
838
- console.log(`Compiling contracts in folder "${contractsRootDir}"`)
839
- Project.currentProject = await Project.compile(
840
- fullNodeVersion,
841
- provider,
842
- sourceFiles,
843
- projectRootDir,
844
- contractsRootDir,
845
- artifactsRootDir,
846
- errorOnWarnings,
847
- nodeCompilerOptions
848
- )
849
- } else {
850
- console.log(`Contracts are compiled already. Loading them from folder "${artifactsRootDir}"`)
851
- Project.currentProject = await Project.loadArtifacts(
852
- provider,
853
- sourceFiles,
854
- projectArtifact,
855
- projectRootDir,
856
- contractsRootDir,
857
- artifactsRootDir,
858
- errorOnWarnings,
859
- nodeCompilerOptions
860
- )
861
- }
862
- }
863
- }
864
-
865
144
  export abstract class Artifact {
866
145
  readonly version: string
867
146
  readonly name: string
@@ -875,18 +154,6 @@ export abstract class Artifact {
875
154
 
876
155
  abstract buildByteCodeToDeploy(initialFields: Fields, isDevnet: boolean): string
877
156
 
878
- publicFunctions(): string[] {
879
- return this.functions.filter((func) => func.isPublic).map((func) => func.name)
880
- }
881
-
882
- usingPreapprovedAssetsFunctions(): string[] {
883
- return this.functions.filter((func) => func.usePreapprovedAssets).map((func) => func.name)
884
- }
885
-
886
- usingAssetsInContractFunctions(): string[] {
887
- return this.functions.filter((func) => func.useAssetsInContract).map((func) => func.name)
888
- }
889
-
890
157
  async isDevnet(signer: SignerProvider): Promise<boolean> {
891
158
  if (!signer.nodeProvider) {
892
159
  return false
@@ -896,6 +163,16 @@ export abstract class Artifact {
896
163
  }
897
164
  }
898
165
 
166
+ function fromFunctionSig(sig: node.FunctionSig): FunctionSig {
167
+ return {
168
+ name: sig.name,
169
+ paramNames: sig.paramNames,
170
+ paramTypes: sig.paramTypes,
171
+ paramIsMutable: sig.paramIsMutable,
172
+ returnTypes: sig.returnTypes
173
+ }
174
+ }
175
+
899
176
  export class Contract extends Artifact {
900
177
  readonly bytecode: string
901
178
  readonly bytecodeDebugPatch: string
@@ -910,6 +187,7 @@ export class Contract extends Artifact {
910
187
 
911
188
  readonly bytecodeDebug: string
912
189
  readonly codeHashDebug: string
190
+ readonly decodedMethods: Method[]
913
191
 
914
192
  constructor(
915
193
  version: string,
@@ -941,6 +219,20 @@ export class Contract extends Artifact {
941
219
 
942
220
  this.bytecodeDebug = ralph.buildDebugBytecode(this.bytecode, this.bytecodeDebugPatch)
943
221
  this.codeHashDebug = codeHashDebug
222
+
223
+ this.decodedMethods = contract.contractCodec.decodeContract(Buffer.from(bytecode, 'hex')).methods
224
+ }
225
+
226
+ publicFunctions(): FunctionSig[] {
227
+ return this.functions.filter((_, index) => this.decodedMethods[`${index}`].isPublic)
228
+ }
229
+
230
+ usingPreapprovedAssetsFunctions(): FunctionSig[] {
231
+ return this.functions.filter((_, index) => this.decodedMethods[`${index}`].usePreapprovedAssets)
232
+ }
233
+
234
+ usingAssetsInContractFunctions(): FunctionSig[] {
235
+ return this.functions.filter((_, index) => this.decodedMethods[`${index}`].useContractAssets)
944
236
  }
945
237
 
946
238
  // TODO: safely parse json
@@ -987,7 +279,7 @@ export class Contract extends Artifact {
987
279
  result.codeHashDebug,
988
280
  result.fields,
989
281
  result.events,
990
- result.functions,
282
+ result.functions.map(fromFunctionSig),
991
283
  result.constants,
992
284
  result.enums,
993
285
  structs,
@@ -1144,11 +436,9 @@ export class Contract extends Artifact {
1144
436
 
1145
437
  static fromApiContractState(
1146
438
  state: node.ContractState,
1147
- getContractByCodeHash?: (codeHash: string) => Contract
439
+ getContractByCodeHash: (codeHash: string) => Contract
1148
440
  ): ContractState {
1149
- const contract = getContractByCodeHash
1150
- ? getContractByCodeHash(state.codeHash)
1151
- : Project.currentProject.contractByCodeHash(state.codeHash)
441
+ const contract = getContractByCodeHash(state.codeHash)
1152
442
  return contract.fromApiContractState(state)
1153
443
  }
1154
444
 
@@ -1170,7 +460,7 @@ export class Contract extends Artifact {
1170
460
  event: node.ContractEventByTxId,
1171
461
  codeHash: string | undefined,
1172
462
  txId: string,
1173
- getContractByCodeHash?: (codeHash: string) => Contract
463
+ getContractByCodeHash: (codeHash: string) => Contract
1174
464
  ): ContractEvent {
1175
465
  let fields: Fields
1176
466
  let name: string
@@ -1182,9 +472,7 @@ export class Contract extends Artifact {
1182
472
  fields = fromApiEventFields(event.fields, Contract.ContractDestroyedEvent, true)
1183
473
  name = Contract.ContractDestroyedEvent.name
1184
474
  } else {
1185
- const contract = getContractByCodeHash
1186
- ? getContractByCodeHash(codeHash!)
1187
- : Project.currentProject.contractByCodeHash(codeHash!)
475
+ const contract = getContractByCodeHash(codeHash!)
1188
476
  const eventSig = contract.eventsSig[event.eventIndex]
1189
477
  fields = fromApiEventFields(event.fields, eventSig)
1190
478
  name = eventSig.name
@@ -1203,7 +491,8 @@ export class Contract extends Artifact {
1203
491
  fromApiTestContractResult(
1204
492
  methodName: string,
1205
493
  result: node.TestContractResult,
1206
- txId: string
494
+ txId: string,
495
+ getContractByCodeHash: (codeHash: string) => Contract
1207
496
  ): TestContractResult<unknown> {
1208
497
  const methodIndex = this.functions.findIndex((sig) => sig.name === methodName)
1209
498
  const returnTypes = this.functions[`${methodIndex}`].returnTypes
@@ -1218,9 +507,9 @@ export class Contract extends Artifact {
1218
507
  contractAddress: result.address,
1219
508
  returns: returns,
1220
509
  gasUsed: result.gasUsed,
1221
- contracts: result.contracts.map((contract) => Contract.fromApiContractState(contract)),
510
+ contracts: result.contracts.map((contract) => Contract.fromApiContractState(contract, getContractByCodeHash)),
1222
511
  txOutputs: result.txOutputs.map(fromApiOutput),
1223
- events: Contract.fromApiEvents(result.events, addressToCodeHash, txId),
512
+ events: Contract.fromApiEvents(result.events, addressToCodeHash, txId, getContractByCodeHash),
1224
513
  debugMessages: result.debugMessages
1225
514
  }
1226
515
  }
@@ -1264,7 +553,7 @@ export class Contract extends Artifact {
1264
553
  events: node.ContractEventByTxId[],
1265
554
  addressToCodeHash: Map<string, string>,
1266
555
  txId: string,
1267
- getContractByCodeHash?: (codeHash: string) => Contract
556
+ getContractByCodeHash: (codeHash: string) => Contract
1268
557
  ): ContractEvent[] {
1269
558
  return events.map((event) => {
1270
559
  const contractAddress = event.contractAddress
@@ -1298,7 +587,7 @@ export class Contract extends Artifact {
1298
587
  result: node.CallContractResult,
1299
588
  txId: string,
1300
589
  methodIndex: number,
1301
- getContractByCodeHash?: (codeHash: string) => Contract
590
+ getContractByCodeHash: (codeHash: string) => Contract
1302
591
  ): CallContractResult<unknown> {
1303
592
  const returnTypes = this.functions[`${methodIndex}`].returnTypes
1304
593
  const callResult = tryGetCallResult(result)
@@ -1348,7 +637,7 @@ export class Script extends Artifact {
1348
637
  result.bytecodeTemplate,
1349
638
  result.bytecodeDebugPatch,
1350
639
  result.fields,
1351
- result.functions,
640
+ result.functions.map(fromFunctionSig),
1352
641
  structs
1353
642
  )
1354
643
  }
@@ -1831,14 +1120,14 @@ export function subscribeEventsFromContract<T extends Fields, M extends Contract
1831
1120
  decodeFunc: (event: node.ContractEvent) => M,
1832
1121
  fromCount?: number
1833
1122
  ): EventSubscription {
1834
- const messageCallback = (event: node.ContractEvent): Promise<void> => {
1123
+ const messageCallback = (event: node.ContractEvent) => {
1835
1124
  if (event.eventIndex !== eventIndex) {
1836
1125
  return Promise.resolve()
1837
1126
  }
1838
1127
  return options.messageCallback(decodeFunc(event))
1839
1128
  }
1840
1129
 
1841
- const errorCallback = (err: any, subscription: Subscription<node.ContractEvent>): Promise<void> => {
1130
+ const errorCallback = (err: any, subscription: Subscription<node.ContractEvent>) => {
1842
1131
  return options.errorCallback(err, subscription as unknown as Subscription<M>)
1843
1132
  }
1844
1133
  const opt: EventSubscribeOptions<node.ContractEvent> = {
@@ -1877,7 +1166,9 @@ function genCodeForType(type: string, structs: Struct[]): { bytecode: string; co
1877
1166
  const { immFields, mutFields } = ralph.calcFieldSize(type, true, structs)
1878
1167
  const loadImmFieldByIndex: Method = {
1879
1168
  isPublic: true,
1880
- assetModifier: 0,
1169
+ usePreapprovedAssets: false,
1170
+ useContractAssets: false,
1171
+ usePayToContractOnly: false,
1881
1172
  argsLength: 1,
1882
1173
  localsLength: 1,
1883
1174
  returnLength: 1,
@@ -1905,7 +1196,9 @@ function genCodeForType(type: string, structs: Struct[]): { bytecode: string; co
1905
1196
  }
1906
1197
  const destroy: Method = {
1907
1198
  isPublic: true,
1908
- assetModifier: 2,
1199
+ usePreapprovedAssets: false,
1200
+ useContractAssets: true,
1201
+ usePayToContractOnly: false,
1909
1202
  argsLength: 1,
1910
1203
  localsLength: 1,
1911
1204
  returnLength: 0,
@@ -1980,7 +1273,8 @@ export async function testMethod<
1980
1273
  >(
1981
1274
  factory: ContractFactory<I, F>,
1982
1275
  methodName: string,
1983
- params: Optional<TestContractParams<F, A, M>, 'testArgs' | 'initialFields'>
1276
+ params: Optional<TestContractParams<F, A, M>, 'testArgs' | 'initialFields'>,
1277
+ getContractByCodeHash: (codeHash: string) => Contract
1984
1278
  ): Promise<TestContractResult<R, M>> {
1985
1279
  const txId = params?.txId ?? randomTxId()
1986
1280
  const contract = factory.contract
@@ -1999,7 +1293,7 @@ export async function testMethod<
1999
1293
  })
2000
1294
  const apiResult = await getCurrentNodeProvider().contracts.postContractsTestContract(apiParams)
2001
1295
  const maps = existingContractsToMaps(contract, address, group, apiResult, initialMaps)
2002
- const testResult = contract.fromApiTestContractResult(methodName, apiResult, txId)
1296
+ const testResult = contract.fromApiTestContractResult(methodName, apiResult, txId, getContractByCodeHash)
2003
1297
  contract.printDebugMessages(methodName, testResult.debugMessages)
2004
1298
  return {
2005
1299
  ...testResult,
@@ -2008,24 +1302,36 @@ export async function testMethod<
2008
1302
  }
2009
1303
 
2010
1304
  export class RalphMap<K extends Val, V extends Val> {
1305
+ private readonly groupIndex: number
2011
1306
  constructor(
2012
1307
  private readonly parentContract: Contract,
2013
- private readonly parentInstance: ContractInstance,
1308
+ private readonly parentContractId: HexString,
2014
1309
  private readonly mapName: string
2015
- ) {}
1310
+ ) {
1311
+ this.groupIndex = groupOfAddress(addressFromContractId(parentContractId))
1312
+ }
2016
1313
 
2017
1314
  async get(key: K): Promise<V | undefined> {
2018
- return getMapItem(this.parentContract, this.parentInstance, this.mapName, key)
1315
+ return getMapItem(this.parentContract, this.parentContractId, this.groupIndex, this.mapName, key)
2019
1316
  }
2020
1317
 
2021
1318
  async contains(key: K): Promise<boolean> {
2022
1319
  return this.get(key).then((v) => v !== undefined)
2023
1320
  }
1321
+
1322
+ toJSON() {
1323
+ return {
1324
+ parentContractId: this.parentContractId,
1325
+ mapName: this.mapName,
1326
+ groupIndex: this.groupIndex
1327
+ }
1328
+ }
2024
1329
  }
2025
1330
 
2026
1331
  export async function getMapItem<R extends Val>(
2027
1332
  parentContract: Contract,
2028
- parentInstance: ContractInstance,
1333
+ parentContractId: HexString,
1334
+ groupIndex: number,
2029
1335
  mapName: string,
2030
1336
  key: Val
2031
1337
  ): Promise<R | undefined> {
@@ -2035,13 +1341,7 @@ export async function getMapItem<R extends Val>(
2035
1341
  throw new Error(`Map ${mapName} does not exist in contract ${parentContract.name}`)
2036
1342
  }
2037
1343
  const [keyType, valueType] = ralph.parseMapType(mapType)
2038
- const mapItemContractId = calcWrapperContractId(
2039
- parentInstance.contractId,
2040
- index!,
2041
- key,
2042
- keyType,
2043
- parentInstance.groupIndex
2044
- )
1344
+ const mapItemContractId = calcWrapperContractId(parentContractId, index!, key, keyType, groupIndex)
2045
1345
  const mapItemAddress = addressFromContractId(mapItemContractId)
2046
1346
  try {
2047
1347
  const state = await getCurrentNodeProvider().contracts.getContractsAddressState(mapItemAddress)
@@ -2271,13 +1571,13 @@ export function subscribeContractEvents(
2271
1571
  options: EventSubscribeOptions<ContractEvent<any>>,
2272
1572
  fromCount?: number
2273
1573
  ): EventSubscription {
2274
- const messageCallback = (event: node.ContractEvent): Promise<void> => {
1574
+ const messageCallback = (event: node.ContractEvent) => {
2275
1575
  return options.messageCallback({
2276
1576
  ...decodeEvent(contract, instance, event, event.eventIndex),
2277
1577
  contractAddress: instance.address
2278
1578
  })
2279
1579
  }
2280
- const errorCallback = (err: any, subscription: Subscription<node.ContractEvent>): Promise<void> => {
1580
+ const errorCallback = (err: any, subscription: Subscription<node.ContractEvent>) => {
2281
1581
  return options.errorCallback(err, subscription as unknown as Subscription<ContractEvent<any>>)
2282
1582
  }
2283
1583
  const opt: EventSubscribeOptions<node.ContractEvent> = {
@@ -2294,7 +1594,7 @@ export async function callMethod<I extends ContractInstance, F extends Fields, A
2294
1594
  instance: ContractInstance,
2295
1595
  methodName: string,
2296
1596
  params: Optional<CallContractParams<A>, 'args'>,
2297
- getContractByCodeHash?: (codeHash: string) => Contract
1597
+ getContractByCodeHash: (codeHash: string) => Contract
2298
1598
  ): Promise<CallContractResult<R>> {
2299
1599
  const methodIndex = contract.contract.getMethodIndex(methodName)
2300
1600
  const txId = params?.txId ?? randomTxId()
@@ -2314,7 +1614,7 @@ export async function multicallMethods<I extends ContractInstance, F extends Fie
2314
1614
  contract: ContractFactory<I, F>,
2315
1615
  instance: ContractInstance,
2316
1616
  calls: Record<string, Optional<CallContractParams<any>, 'args'>>,
2317
- getContractByCodeHash?: (codeHash: string) => Contract
1617
+ getContractByCodeHash: (codeHash: string) => Contract
2318
1618
  ): Promise<Record<string, CallContractResult<any>>> {
2319
1619
  const callEntries = Object.entries(calls)
2320
1620
  const callsParams = callEntries.map((entry) => {
@@ -2369,10 +1669,3 @@ export const getContractIdFromUnsignedTx = async (
2369
1669
 
2370
1670
  // This function only works in the simple case where a single non-subcontract is created in the tx
2371
1671
  export const getTokenIdFromUnsignedTx = getContractIdFromUnsignedTx
2372
-
2373
- export function tryGetCallResult(result: node.CallContractResult): node.CallContractSucceeded {
2374
- if (result.type === 'CallContractFailed') {
2375
- throw new Error(`Failed to call contract, error: ${(result as node.CallContractFailed).error}`)
2376
- }
2377
- return result as node.CallContractSucceeded
2378
- }