@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
@@ -39,35 +39,21 @@ var __importStar = (this && this.__importStar) || function (mod) {
39
39
  __setModuleDefault(result, mod);
40
40
  return result;
41
41
  };
42
- var __importDefault = (this && this.__importDefault) || function (mod) {
43
- return (mod && mod.__esModule) ? mod : { "default": mod };
44
- };
45
42
  Object.defineProperty(exports, "__esModule", { value: true });
46
- exports.tryGetCallResult = exports.getTokenIdFromUnsignedTx = exports.getContractIdFromUnsignedTx = exports.getContractEventsCurrentCount = exports.multicallMethods = exports.callMethod = exports.subscribeContractEvents = exports.subscribeContractEvent = exports.decodeEvent = exports.subscribeContractDestroyedEvent = exports.subscribeContractCreatedEvent = exports.fetchContractState = exports.ContractInstance = exports.getMapItem = exports.RalphMap = exports.testMethod = exports.addStdIdToFields = exports.subscribeEventsFromContract = exports.decodeContractDestroyedEvent = exports.decodeContractCreatedEvent = exports.DestroyContractEventAddresses = exports.CreateContractEventAddresses = exports.ExecutableScript = exports.ContractFactory = exports.randomTxId = exports.fromApiEventFields = exports.fromApiArray = exports.getDefaultValue = exports.fromApiFields = exports.Script = exports.Contract = exports.Artifact = exports.Project = exports.Struct = exports.ProjectArtifact = exports.DEFAULT_COMPILER_OPTIONS = exports.DEFAULT_NODE_COMPILER_OPTIONS = exports.StdIdFieldName = void 0;
43
+ exports.getTokenIdFromUnsignedTx = exports.getContractIdFromUnsignedTx = exports.getContractEventsCurrentCount = exports.multicallMethods = exports.callMethod = exports.subscribeContractEvents = exports.subscribeContractEvent = exports.decodeEvent = exports.subscribeContractDestroyedEvent = exports.subscribeContractCreatedEvent = exports.fetchContractState = exports.ContractInstance = exports.getMapItem = exports.RalphMap = exports.testMethod = exports.addStdIdToFields = exports.subscribeEventsFromContract = exports.decodeContractDestroyedEvent = exports.decodeContractCreatedEvent = exports.DestroyContractEventAddresses = exports.CreateContractEventAddresses = exports.ExecutableScript = exports.ContractFactory = exports.randomTxId = exports.fromApiEventFields = exports.fromApiArray = exports.getDefaultValue = exports.fromApiFields = exports.Script = exports.Contract = exports.Artifact = exports.Struct = exports.DEFAULT_COMPILER_OPTIONS = exports.DEFAULT_NODE_COMPILER_OPTIONS = exports.StdIdFieldName = void 0;
47
44
  const buffer_1 = require("buffer/");
48
- const fs_1 = __importDefault(require("fs"));
49
- const fs_2 = require("fs");
45
+ const fs_1 = require("fs");
50
46
  const api_1 = require("../api");
51
47
  const ralph = __importStar(require("./ralph"));
52
48
  const utils_1 = require("../utils");
53
49
  const global_1 = require("../global");
54
- const path = __importStar(require("path"));
55
50
  const events_1 = require("./events");
56
51
  const constants_1 = require("../constants");
57
52
  const blake = __importStar(require("blakejs"));
58
- const error_1 = require("../utils/error");
59
53
  const debug_1 = require("../debug");
60
54
  const codec_1 = require("../codec");
61
55
  const crypto = new utils_1.WebCrypto();
62
56
  exports.StdIdFieldName = '__stdInterfaceId';
63
- var SourceKind;
64
- (function (SourceKind) {
65
- SourceKind[SourceKind["Contract"] = 0] = "Contract";
66
- SourceKind[SourceKind["Script"] = 1] = "Script";
67
- SourceKind[SourceKind["AbstractContract"] = 2] = "AbstractContract";
68
- SourceKind[SourceKind["Interface"] = 3] = "Interface";
69
- SourceKind[SourceKind["Struct"] = 4] = "Struct";
70
- })(SourceKind || (SourceKind = {}));
71
57
  exports.DEFAULT_NODE_COMPILER_OPTIONS = {
72
58
  ignoreUnusedConstantsWarnings: false,
73
59
  ignoreUnusedVariablesWarnings: false,
@@ -77,169 +63,6 @@ exports.DEFAULT_NODE_COMPILER_OPTIONS = {
77
63
  ignoreCheckExternalCallerWarnings: false
78
64
  };
79
65
  exports.DEFAULT_COMPILER_OPTIONS = { errorOnWarnings: true, ...exports.DEFAULT_NODE_COMPILER_OPTIONS };
80
- class TypedMatcher {
81
- constructor(pattern, type) {
82
- this.matcher = new RegExp(pattern, 'mg');
83
- this.type = type;
84
- }
85
- }
86
- function removeParentsPrefix(parts) {
87
- let index = 0;
88
- for (let i = 0; i < parts.length; i++) {
89
- if (parts[`${i}`] === '..') {
90
- index += 1;
91
- }
92
- else {
93
- break;
94
- }
95
- }
96
- return path.join(...parts.slice(index));
97
- }
98
- class SourceInfo {
99
- getArtifactPath(artifactsRootDir) {
100
- let fullPath;
101
- if (this.isExternal) {
102
- const relativePath = removeParentsPrefix(this.contractRelativePath.split(path.sep));
103
- const externalPath = path.join('.external', relativePath);
104
- fullPath = path.join(artifactsRootDir, externalPath);
105
- }
106
- else {
107
- fullPath = path.join(artifactsRootDir, this.contractRelativePath);
108
- }
109
- return path.join(path.dirname(fullPath), `${this.name}.ral.json`);
110
- }
111
- constructor(type, name, sourceCode, sourceCodeHash, contractRelativePath, isExternal) {
112
- this.type = type;
113
- this.name = name;
114
- this.sourceCode = sourceCode;
115
- this.sourceCodeHash = sourceCodeHash;
116
- this.contractRelativePath = contractRelativePath;
117
- this.isExternal = isExternal;
118
- }
119
- static async from(type, name, sourceCode, contractRelativePath, isExternal) {
120
- const sourceCodeHash = await crypto.subtle.digest('SHA-256', buffer_1.Buffer.from(sourceCode));
121
- const sourceCodeHashHex = buffer_1.Buffer.from(sourceCodeHash).toString('hex');
122
- return new SourceInfo(type, name, sourceCode, sourceCodeHashHex, contractRelativePath, isExternal);
123
- }
124
- }
125
- class Compiled {
126
- constructor(sourceInfo, artifact, warnings) {
127
- this.sourceInfo = sourceInfo;
128
- this.artifact = artifact;
129
- this.warnings = warnings;
130
- }
131
- }
132
- function findSourceInfoAtLineNumber(sources, line) {
133
- let currentLine = 0;
134
- const sourceInfosWithLine = sources.map((source) => {
135
- const startIndex = currentLine + 1;
136
- currentLine += source.sourceCode.split('\n').length;
137
- const endIndex = currentLine;
138
- return { sourceInfo: source, startIndex: startIndex, endIndex: endIndex };
139
- });
140
- const sourceInfo = sourceInfosWithLine.find((sourceInfoWithLine) => {
141
- return line >= sourceInfoWithLine.startIndex && line <= sourceInfoWithLine.endIndex;
142
- });
143
- return sourceInfo;
144
- }
145
- class ProjectArtifact {
146
- static checkCompilerOptionsParameter(compilerOptions) {
147
- if (Object.keys(compilerOptions).length != Object.keys(exports.DEFAULT_NODE_COMPILER_OPTIONS).length) {
148
- throw Error(`Not all compiler options are set: ${compilerOptions}`);
149
- }
150
- const combined = { ...compilerOptions, ...exports.DEFAULT_NODE_COMPILER_OPTIONS };
151
- if (Object.keys(combined).length !== Object.keys(exports.DEFAULT_NODE_COMPILER_OPTIONS).length) {
152
- throw Error(`There are unknown compiler options: ${compilerOptions}`);
153
- }
154
- }
155
- constructor(fullNodeVersion, compilerOptionsUsed, infos) {
156
- ProjectArtifact.checkCompilerOptionsParameter(compilerOptionsUsed);
157
- this.fullNodeVersion = fullNodeVersion;
158
- this.compilerOptionsUsed = compilerOptionsUsed;
159
- this.infos = infos;
160
- }
161
- static isCodeChanged(current, previous) {
162
- if (current.infos.size !== previous.infos.size) {
163
- return true;
164
- }
165
- for (const [name, codeInfo] of current.infos) {
166
- const prevCodeInfo = previous.infos.get(name);
167
- if (prevCodeInfo?.codeHashDebug !== codeInfo.codeHashDebug) {
168
- return true;
169
- }
170
- }
171
- return false;
172
- }
173
- async saveToFile(rootPath) {
174
- const filepath = path.join(rootPath, ProjectArtifact.artifactFileName);
175
- const artifact = {
176
- fullNodeVersion: this.fullNodeVersion,
177
- compilerOptionsUsed: this.compilerOptionsUsed,
178
- infos: Object.fromEntries(new Map([...this.infos].sort()))
179
- };
180
- const content = JSON.stringify(artifact, null, 2);
181
- return fs_2.promises.writeFile(filepath, content);
182
- }
183
- needToReCompile(compilerOptions, sourceInfos, fullNodeVersion) {
184
- ProjectArtifact.checkCompilerOptionsParameter(compilerOptions);
185
- if (this.fullNodeVersion !== fullNodeVersion) {
186
- return true;
187
- }
188
- const optionsMatched = Object.entries(compilerOptions).every(([key, inputOption]) => {
189
- const usedOption = this.compilerOptionsUsed[`${key}`];
190
- return usedOption === inputOption;
191
- });
192
- if (!optionsMatched) {
193
- return true;
194
- }
195
- if (sourceInfos.length !== this.infos.size) {
196
- return true;
197
- }
198
- for (const sourceInfo of sourceInfos) {
199
- const info = this.infos.get(sourceInfo.name);
200
- if (typeof info === 'undefined' || info.sourceCodeHash !== sourceInfo.sourceCodeHash) {
201
- return true;
202
- }
203
- }
204
- return false;
205
- }
206
- static async from(rootPath) {
207
- const filepath = path.join(rootPath, ProjectArtifact.artifactFileName);
208
- if (!fs_1.default.existsSync(filepath)) {
209
- return undefined;
210
- }
211
- try {
212
- const content = await fs_2.promises.readFile(filepath);
213
- const json = JSON.parse(content.toString());
214
- const fullNodeVersion = json.fullNodeVersion;
215
- const compilerOptionsUsed = json.compilerOptionsUsed;
216
- const files = new Map(Object.entries(json.infos));
217
- return new ProjectArtifact(fullNodeVersion, compilerOptionsUsed, files);
218
- }
219
- catch (error) {
220
- console.error(`Failed to load project artifact, error: ${error}`);
221
- return undefined;
222
- }
223
- }
224
- }
225
- exports.ProjectArtifact = ProjectArtifact;
226
- ProjectArtifact.artifactFileName = '.project.json';
227
- function removeOldArtifacts(dir) {
228
- const files = fs_1.default.readdirSync(dir);
229
- files.forEach((file) => {
230
- const filePath = path.join(dir, file);
231
- const stat = fs_1.default.statSync(filePath);
232
- if (stat.isDirectory()) {
233
- removeOldArtifacts(filePath);
234
- }
235
- else if (filePath.endsWith('.ral.json') || filePath.endsWith('.ral')) {
236
- fs_1.default.unlinkSync(filePath);
237
- }
238
- });
239
- if (fs_1.default.readdirSync(dir).length === 0) {
240
- fs_1.default.rmdirSync(dir);
241
- }
242
- }
243
66
  class Struct {
244
67
  constructor(name, fieldNames, fieldTypes, isMutable) {
245
68
  this.name = name;
@@ -266,341 +89,12 @@ class Struct {
266
89
  }
267
90
  }
268
91
  exports.Struct = Struct;
269
- class Project {
270
- static buildProjectArtifact(fullNodeVersion, sourceInfos, contracts, scripts, compilerOptions) {
271
- const files = new Map();
272
- contracts.forEach((c) => {
273
- files.set(c.artifact.name, {
274
- sourceFile: c.sourceInfo.contractRelativePath,
275
- sourceCodeHash: c.sourceInfo.sourceCodeHash,
276
- bytecodeDebugPatch: c.artifact.bytecodeDebugPatch,
277
- codeHashDebug: c.artifact.codeHashDebug,
278
- warnings: c.warnings
279
- });
280
- });
281
- scripts.forEach((s) => {
282
- files.set(s.artifact.name, {
283
- sourceFile: s.sourceInfo.contractRelativePath,
284
- sourceCodeHash: s.sourceInfo.sourceCodeHash,
285
- bytecodeDebugPatch: s.artifact.bytecodeDebugPatch,
286
- codeHashDebug: '',
287
- warnings: s.warnings
288
- });
289
- });
290
- const compiledSize = contracts.size + scripts.size;
291
- sourceInfos.slice(compiledSize).forEach((c) => {
292
- files.set(c.name, {
293
- sourceFile: c.contractRelativePath,
294
- sourceCodeHash: c.sourceCodeHash,
295
- bytecodeDebugPatch: '',
296
- codeHashDebug: '',
297
- warnings: []
298
- });
299
- });
300
- return new ProjectArtifact(fullNodeVersion, compilerOptions, files);
301
- }
302
- constructor(contractsRootDir, artifactsRootDir, sourceInfos, contracts, scripts, structs, errorOnWarnings, projectArtifact) {
303
- this.contractsRootDir = contractsRootDir;
304
- this.artifactsRootDir = artifactsRootDir;
305
- this.sourceInfos = sourceInfos;
306
- this.contracts = contracts;
307
- this.scripts = scripts;
308
- this.structs = structs;
309
- this.projectArtifact = projectArtifact;
310
- if (errorOnWarnings) {
311
- Project.checkCompilerWarnings([
312
- ...[...contracts.entries()].map((c) => c[1].warnings).flat(),
313
- ...[...scripts.entries()].map((s) => s[1].warnings).flat()
314
- ], errorOnWarnings);
315
- }
316
- }
317
- static checkCompilerWarnings(warnings, errorOnWarnings) {
318
- if (warnings.length !== 0) {
319
- const prefixPerWarning = ' - ';
320
- const warningString = prefixPerWarning + warnings.join('\n' + prefixPerWarning);
321
- const output = `Compilation warnings:\n` + warningString + '\n';
322
- if (errorOnWarnings) {
323
- throw new Error(output);
324
- }
325
- else {
326
- console.log(output);
327
- }
328
- }
329
- }
330
- static contract(name) {
331
- const contract = Project.currentProject.contracts.get(name);
332
- if (typeof contract === 'undefined') {
333
- throw new Error(`Contract "${name}" does not exist`);
334
- }
335
- return contract.artifact;
336
- }
337
- static script(name) {
338
- const script = Project.currentProject.scripts.get(name);
339
- if (typeof script === 'undefined') {
340
- throw new Error(`Script "${name}" does not exist`);
341
- }
342
- return script.artifact;
343
- }
344
- static async loadStructs(artifactsRootDir) {
345
- const filePath = path.join(artifactsRootDir, 'structs.ral.json');
346
- if (!fs_1.default.existsSync(filePath))
347
- return [];
348
- const content = await fs_2.promises.readFile(filePath);
349
- const json = JSON.parse(content.toString());
350
- if (!Array.isArray(json)) {
351
- throw Error(`Invalid structs JSON: ${content}`);
352
- }
353
- return Array.from(json).map((item) => Struct.fromJson(item));
354
- }
355
- async saveStructsToFile() {
356
- if (this.structs.length === 0)
357
- return;
358
- const structs = this.structs.map((s) => s.toJson());
359
- const filePath = path.join(this.artifactsRootDir, 'structs.ral.json');
360
- return fs_2.promises.writeFile(filePath, JSON.stringify(structs, null, 2));
361
- }
362
- async saveArtifactsToFile(projectRootDir) {
363
- const artifactsRootDir = this.artifactsRootDir;
364
- const saveToFile = async function (compiled) {
365
- const artifactPath = compiled.sourceInfo.getArtifactPath(artifactsRootDir);
366
- const dirname = path.dirname(artifactPath);
367
- if (!fs_1.default.existsSync(dirname)) {
368
- fs_1.default.mkdirSync(dirname, { recursive: true });
369
- }
370
- return fs_2.promises.writeFile(artifactPath, compiled.artifact.toString());
371
- };
372
- this.contracts.forEach((contract) => saveToFile(contract));
373
- this.scripts.forEach((script) => saveToFile(script));
374
- this.saveStructsToFile();
375
- await this.projectArtifact.saveToFile(projectRootDir);
376
- }
377
- contractByCodeHash(codeHash) {
378
- const contract = [...this.contracts.values()].find((c) => c.artifact.codeHash === codeHash || c.artifact.codeHashDebug == codeHash);
379
- if (typeof contract === 'undefined') {
380
- throw new Error(`Unknown code with code hash: ${codeHash}`);
381
- }
382
- return contract.artifact;
383
- }
384
- static async getCompileResult(provider, compilerOptions, sources) {
385
- try {
386
- const sourceStr = sources.map((f) => f.sourceCode).join('\n');
387
- return await provider.contracts.postContractsCompileProject({
388
- code: sourceStr,
389
- compilerOptions: compilerOptions
390
- });
391
- }
392
- catch (error) {
393
- if (!(error instanceof Error)) {
394
- throw error;
395
- }
396
- const parsed = (0, error_1.parseError)(error.message);
397
- if (!parsed) {
398
- throw error;
399
- }
400
- const sourceInfo = findSourceInfoAtLineNumber(sources, parsed.lineStart);
401
- if (!sourceInfo) {
402
- throw error;
403
- }
404
- const shiftIndex = parsed.lineStart - sourceInfo.startIndex + 1;
405
- const newError = parsed.reformat(shiftIndex, sourceInfo.sourceInfo.contractRelativePath);
406
- throw new Error(newError);
407
- }
408
- }
409
- static async compile(fullNodeVersion, provider, sourceInfos, projectRootDir, contractsRootDir, artifactsRootDir, errorOnWarnings, compilerOptions) {
410
- const removeDuplicates = sourceInfos.reduce((acc, sourceInfo) => {
411
- if (acc.find((info) => info.sourceCodeHash === sourceInfo.sourceCodeHash) === undefined) {
412
- acc.push(sourceInfo);
413
- }
414
- return acc;
415
- }, []);
416
- const result = await Project.getCompileResult(provider, compilerOptions, removeDuplicates);
417
- const contracts = new Map();
418
- const scripts = new Map();
419
- const structs = result.structs === undefined ? [] : result.structs.map((item) => Struct.fromStructSig(item));
420
- result.contracts.forEach((contractResult) => {
421
- const sourceInfo = sourceInfos.find((sourceInfo) => sourceInfo.type === SourceKind.Contract && sourceInfo.name === contractResult.name);
422
- if (sourceInfo === undefined) {
423
- // this should never happen
424
- throw new Error(`SourceInfo does not exist for contract ${contractResult.name}`);
425
- }
426
- const contract = Contract.fromCompileResult(contractResult, structs);
427
- contracts.set(contract.name, new Compiled(sourceInfo, contract, contractResult.warnings));
428
- });
429
- result.scripts.forEach((scriptResult) => {
430
- const sourceInfo = sourceInfos.find((sourceInfo) => sourceInfo.type === SourceKind.Script && sourceInfo.name === scriptResult.name);
431
- if (sourceInfo === undefined) {
432
- // this should never happen
433
- throw new Error(`SourceInfo does not exist for script ${scriptResult.name}`);
434
- }
435
- const script = Script.fromCompileResult(scriptResult, structs);
436
- scripts.set(script.name, new Compiled(sourceInfo, script, scriptResult.warnings));
437
- });
438
- const projectArtifact = Project.buildProjectArtifact(fullNodeVersion, sourceInfos, contracts, scripts, compilerOptions);
439
- const project = new Project(contractsRootDir, artifactsRootDir, sourceInfos, contracts, scripts, structs, errorOnWarnings, projectArtifact);
440
- await project.saveArtifactsToFile(projectRootDir);
441
- return project;
442
- }
443
- static async loadArtifacts(provider, sourceInfos, projectArtifact, projectRootDir, contractsRootDir, artifactsRootDir, errorOnWarnings, compilerOptions) {
444
- try {
445
- const contracts = new Map();
446
- const scripts = new Map();
447
- const structs = await Project.loadStructs(artifactsRootDir);
448
- for (const sourceInfo of sourceInfos) {
449
- const info = projectArtifact.infos.get(sourceInfo.name);
450
- if (typeof info === 'undefined') {
451
- throw Error(`Unable to find project info for ${sourceInfo.name}, please rebuild the project`);
452
- }
453
- const warnings = info.warnings;
454
- const artifactDir = sourceInfo.getArtifactPath(artifactsRootDir);
455
- if (sourceInfo.type === SourceKind.Contract) {
456
- const artifact = await Contract.fromArtifactFile(artifactDir, info.bytecodeDebugPatch, info.codeHashDebug, structs);
457
- contracts.set(artifact.name, new Compiled(sourceInfo, artifact, warnings));
458
- }
459
- else if (sourceInfo.type === SourceKind.Script) {
460
- const artifact = await Script.fromArtifactFile(artifactDir, info.bytecodeDebugPatch, structs);
461
- scripts.set(artifact.name, new Compiled(sourceInfo, artifact, warnings));
462
- }
463
- }
464
- return new Project(contractsRootDir, artifactsRootDir, sourceInfos, contracts, scripts, structs, errorOnWarnings, projectArtifact);
465
- }
466
- catch (error) {
467
- console.log(`Failed to load artifacts, error: ${error}, try to re-compile contracts...`);
468
- return Project.compile(projectArtifact.fullNodeVersion, provider, sourceInfos, projectRootDir, contractsRootDir, artifactsRootDir, errorOnWarnings, compilerOptions);
469
- }
470
- }
471
- static getImportSourcePath(projectRootDir, importPath) {
472
- const parts = importPath.split('/');
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_1.default.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
- static async handleImports(projectRootDir, contractRootDir, sourceStr, importsCache) {
491
- const localImportsCache = [];
492
- const result = sourceStr.replace(Project.importRegex, (match) => {
493
- localImportsCache.push(match);
494
- return '';
495
- });
496
- const externalSourceInfos = [];
497
- for (const myImport of localImportsCache) {
498
- const originImportPath = myImport.slice(8, -1);
499
- const importPath = originImportPath.endsWith('.ral') ? originImportPath : originImportPath + '.ral';
500
- if (!importsCache.includes(importPath)) {
501
- importsCache.push(importPath);
502
- const sourcePath = Project.getImportSourcePath(projectRootDir, importPath);
503
- const sourceInfos = await Project.loadSourceFile(projectRootDir, contractRootDir, sourcePath, importsCache, true);
504
- externalSourceInfos.push(...sourceInfos);
505
- }
506
- }
507
- return [result, externalSourceInfos];
508
- }
509
- static async loadSourceFile(projectRootDir, contractsRootDir, sourcePath, importsCache, isExternal) {
510
- const contractRelativePath = path.relative(contractsRootDir, sourcePath);
511
- if (!sourcePath.endsWith('.ral')) {
512
- throw new Error(`Invalid filename: ${sourcePath}, smart contract file name should end with ".ral"`);
513
- }
514
- const sourceBuffer = await fs_2.promises.readFile(sourcePath);
515
- const [sourceStr, externalSourceInfos] = await Project.handleImports(projectRootDir, contractsRootDir, sourceBuffer.toString(), importsCache);
516
- if (sourceStr.match(new RegExp('^import "', 'mg')) !== null) {
517
- throw new Error(`Invalid import statements, source: ${sourcePath}`);
518
- }
519
- const sourceInfos = externalSourceInfos;
520
- for (const matcher of this.matchers) {
521
- const results = sourceStr.matchAll(matcher.matcher);
522
- for (const result of results) {
523
- const sourceInfo = await SourceInfo.from(matcher.type, result[1], sourceStr, contractRelativePath, isExternal);
524
- sourceInfos.push(sourceInfo);
525
- }
526
- }
527
- return sourceInfos;
528
- }
529
- static async loadSourceFiles(projectRootDir, contractsRootDir) {
530
- const importsCache = [];
531
- const sourceInfos = [];
532
- const loadDir = async function (dirPath) {
533
- const dirents = await fs_2.promises.readdir(dirPath, { withFileTypes: true });
534
- for (const dirent of dirents) {
535
- if (dirent.isFile()) {
536
- const sourcePath = path.join(dirPath, dirent.name);
537
- const infos = await Project.loadSourceFile(projectRootDir, contractsRootDir, sourcePath, importsCache, false);
538
- sourceInfos.push(...infos);
539
- }
540
- else {
541
- const newPath = path.join(dirPath, dirent.name);
542
- await loadDir(newPath);
543
- }
544
- }
545
- };
546
- await loadDir(contractsRootDir);
547
- const contractAndScriptSize = sourceInfos.filter((f) => f.type === SourceKind.Contract || f.type === SourceKind.Script).length;
548
- if (sourceInfos.length === 0 || contractAndScriptSize === 0) {
549
- throw new Error('Project have no source files');
550
- }
551
- return sourceInfos.sort((a, b) => a.type - b.type);
552
- }
553
- static async build(compilerOptionsPartial = {}, projectRootDir = '.', contractsRootDir = Project.DEFAULT_CONTRACTS_DIR, artifactsRootDir = Project.DEFAULT_ARTIFACTS_DIR, defaultFullNodeVersion = undefined) {
554
- const provider = (0, global_1.getCurrentNodeProvider)();
555
- const fullNodeVersion = defaultFullNodeVersion ?? (await provider.infos.getInfosVersion()).version;
556
- const sourceFiles = await Project.loadSourceFiles(projectRootDir, contractsRootDir);
557
- const { errorOnWarnings, ...nodeCompilerOptions } = { ...exports.DEFAULT_COMPILER_OPTIONS, ...compilerOptionsPartial };
558
- const projectArtifact = await ProjectArtifact.from(projectRootDir);
559
- if (projectArtifact === undefined ||
560
- projectArtifact.needToReCompile(nodeCompilerOptions, sourceFiles, fullNodeVersion)) {
561
- if (fs_1.default.existsSync(artifactsRootDir)) {
562
- removeOldArtifacts(artifactsRootDir);
563
- }
564
- console.log(`Compiling contracts in folder "${contractsRootDir}"`);
565
- Project.currentProject = await Project.compile(fullNodeVersion, provider, sourceFiles, projectRootDir, contractsRootDir, artifactsRootDir, errorOnWarnings, nodeCompilerOptions);
566
- }
567
- else {
568
- console.log(`Contracts are compiled already. Loading them from folder "${artifactsRootDir}"`);
569
- Project.currentProject = await Project.loadArtifacts(provider, sourceFiles, projectArtifact, projectRootDir, contractsRootDir, artifactsRootDir, errorOnWarnings, nodeCompilerOptions);
570
- }
571
- }
572
- }
573
- exports.Project = Project;
574
- Project.importRegex = new RegExp('^import "[^"./]+/[^"]*[a-z][a-z_0-9]*(.ral)?"', 'mg');
575
- Project.abstractContractMatcher = new TypedMatcher('^Abstract Contract ([A-Z][a-zA-Z0-9]*)', SourceKind.AbstractContract);
576
- Project.contractMatcher = new TypedMatcher('^Contract ([A-Z][a-zA-Z0-9]*)', SourceKind.Contract);
577
- Project.interfaceMatcher = new TypedMatcher('^Interface ([A-Z][a-zA-Z0-9]*)', SourceKind.Interface);
578
- Project.scriptMatcher = new TypedMatcher('^TxScript ([A-Z][a-zA-Z0-9]*)', SourceKind.Script);
579
- Project.structMatcher = new TypedMatcher('struct ([A-Z][a-zA-Z0-9]*)', SourceKind.Struct);
580
- Project.matchers = [
581
- Project.abstractContractMatcher,
582
- Project.contractMatcher,
583
- Project.interfaceMatcher,
584
- Project.scriptMatcher,
585
- Project.structMatcher
586
- ];
587
- Project.DEFAULT_CONTRACTS_DIR = 'contracts';
588
- Project.DEFAULT_ARTIFACTS_DIR = 'artifacts';
589
92
  class Artifact {
590
93
  constructor(version, name, functions) {
591
94
  this.version = version;
592
95
  this.name = name;
593
96
  this.functions = functions;
594
97
  }
595
- publicFunctions() {
596
- return this.functions.filter((func) => func.isPublic).map((func) => func.name);
597
- }
598
- usingPreapprovedAssetsFunctions() {
599
- return this.functions.filter((func) => func.usePreapprovedAssets).map((func) => func.name);
600
- }
601
- usingAssetsInContractFunctions() {
602
- return this.functions.filter((func) => func.useAssetsInContract).map((func) => func.name);
603
- }
604
98
  async isDevnet(signer) {
605
99
  if (!signer.nodeProvider) {
606
100
  return false;
@@ -610,6 +104,15 @@ class Artifact {
610
104
  }
611
105
  }
612
106
  exports.Artifact = Artifact;
107
+ function fromFunctionSig(sig) {
108
+ return {
109
+ name: sig.name,
110
+ paramNames: sig.paramNames,
111
+ paramTypes: sig.paramTypes,
112
+ paramIsMutable: sig.paramIsMutable,
113
+ returnTypes: sig.returnTypes
114
+ };
115
+ }
613
116
  class Contract extends Artifact {
614
117
  constructor(version, name, bytecode, bytecodeDebugPatch, codeHash, codeHashDebug, fieldsSig, eventsSig, functions, constants, enums, structs, mapsSig, stdInterfaceId) {
615
118
  super(version, name, functions);
@@ -625,6 +128,16 @@ class Contract extends Artifact {
625
128
  this.stdInterfaceId = stdInterfaceId;
626
129
  this.bytecodeDebug = ralph.buildDebugBytecode(this.bytecode, this.bytecodeDebugPatch);
627
130
  this.codeHashDebug = codeHashDebug;
131
+ this.decodedMethods = codec_1.contract.contractCodec.decodeContract(buffer_1.Buffer.from(bytecode, 'hex')).methods;
132
+ }
133
+ publicFunctions() {
134
+ return this.functions.filter((_, index) => this.decodedMethods[`${index}`].isPublic);
135
+ }
136
+ usingPreapprovedAssetsFunctions() {
137
+ return this.functions.filter((_, index) => this.decodedMethods[`${index}`].usePreapprovedAssets);
138
+ }
139
+ usingAssetsInContractFunctions() {
140
+ return this.functions.filter((_, index) => this.decodedMethods[`${index}`].useContractAssets);
628
141
  }
629
142
  // TODO: safely parse json
630
143
  static fromJson(artifact, bytecodeDebugPatch = '', codeHashDebug = '', structs = []) {
@@ -643,11 +156,11 @@ class Contract extends Artifact {
643
156
  return contract;
644
157
  }
645
158
  static fromCompileResult(result, structs = []) {
646
- return new Contract(result.version, result.name, result.bytecode, result.bytecodeDebugPatch, result.codeHash, result.codeHashDebug, result.fields, result.events, result.functions, result.constants, result.enums, structs, result.maps, result.stdInterfaceId);
159
+ return new Contract(result.version, result.name, result.bytecode, result.bytecodeDebugPatch, result.codeHash, result.codeHashDebug, result.fields, result.events, result.functions.map(fromFunctionSig), result.constants, result.enums, structs, result.maps, result.stdInterfaceId);
647
160
  }
648
161
  // support both 'code.ral' and 'code.ral.json'
649
162
  static async fromArtifactFile(path, bytecodeDebugPatch, codeHashDebug, structs = []) {
650
- const content = await fs_2.promises.readFile(path);
163
+ const content = await fs_1.promises.readFile(path);
651
164
  const artifact = JSON.parse(content.toString());
652
165
  return Contract.fromJson(artifact, bytecodeDebugPatch, codeHashDebug, structs);
653
166
  }
@@ -768,9 +281,7 @@ class Contract extends Artifact {
768
281
  };
769
282
  }
770
283
  static fromApiContractState(state, getContractByCodeHash) {
771
- const contract = getContractByCodeHash
772
- ? getContractByCodeHash(state.codeHash)
773
- : Project.currentProject.contractByCodeHash(state.codeHash);
284
+ const contract = getContractByCodeHash(state.codeHash);
774
285
  return contract.fromApiContractState(state);
775
286
  }
776
287
  static fromApiEvent(event, codeHash, txId, getContractByCodeHash) {
@@ -785,9 +296,7 @@ class Contract extends Artifact {
785
296
  name = Contract.ContractDestroyedEvent.name;
786
297
  }
787
298
  else {
788
- const contract = getContractByCodeHash
789
- ? getContractByCodeHash(codeHash)
790
- : Project.currentProject.contractByCodeHash(codeHash);
299
+ const contract = getContractByCodeHash(codeHash);
791
300
  const eventSig = contract.eventsSig[event.eventIndex];
792
301
  fields = fromApiEventFields(event.fields, eventSig);
793
302
  name = eventSig.name;
@@ -801,7 +310,7 @@ class Contract extends Artifact {
801
310
  fields: fields
802
311
  };
803
312
  }
804
- fromApiTestContractResult(methodName, result, txId) {
313
+ fromApiTestContractResult(methodName, result, txId, getContractByCodeHash) {
805
314
  const methodIndex = this.functions.findIndex((sig) => sig.name === methodName);
806
315
  const returnTypes = this.functions[`${methodIndex}`].returnTypes;
807
316
  const rawReturn = fromApiArray(result.returns, returnTypes, this.structs);
@@ -814,9 +323,9 @@ class Contract extends Artifact {
814
323
  contractAddress: result.address,
815
324
  returns: returns,
816
325
  gasUsed: result.gasUsed,
817
- contracts: result.contracts.map((contract) => Contract.fromApiContractState(contract)),
326
+ contracts: result.contracts.map((contract) => Contract.fromApiContractState(contract, getContractByCodeHash)),
818
327
  txOutputs: result.txOutputs.map(fromApiOutput),
819
- events: Contract.fromApiEvents(result.events, addressToCodeHash, txId),
328
+ events: Contract.fromApiEvents(result.events, addressToCodeHash, txId, getContractByCodeHash),
820
329
  debugMessages: result.debugMessages
821
330
  };
822
331
  }
@@ -871,7 +380,7 @@ class Contract extends Artifact {
871
380
  }
872
381
  fromApiCallContractResult(result, txId, methodIndex, getContractByCodeHash) {
873
382
  const returnTypes = this.functions[`${methodIndex}`].returnTypes;
874
- const callResult = tryGetCallResult(result);
383
+ const callResult = (0, api_1.tryGetCallResult)(result);
875
384
  const rawReturn = fromApiArray(callResult.returns, returnTypes, this.structs);
876
385
  const returns = rawReturn.length === 0 ? null : rawReturn.length === 1 ? rawReturn[0] : rawReturn;
877
386
  const addressToCodeHash = new Map();
@@ -909,7 +418,7 @@ class Script extends Artifact {
909
418
  this.structs = structs;
910
419
  }
911
420
  static fromCompileResult(result, structs = []) {
912
- return new Script(result.version, result.name, result.bytecodeTemplate, result.bytecodeDebugPatch, result.fields, result.functions, structs);
421
+ return new Script(result.version, result.name, result.bytecodeTemplate, result.bytecodeDebugPatch, result.fields, result.functions.map(fromFunctionSig), structs);
913
422
  }
914
423
  // TODO: safely parse json
915
424
  static fromJson(artifact, bytecodeDebugPatch = '', structs = []) {
@@ -923,7 +432,7 @@ class Script extends Artifact {
923
432
  return new Script(artifact.version, artifact.name, artifact.bytecodeTemplate, bytecodeDebugPatch, artifact.fieldsSig, artifact.functions, structs);
924
433
  }
925
434
  static async fromArtifactFile(path, bytecodeDebugPatch, structs = []) {
926
- const content = await fs_2.promises.readFile(path);
435
+ const content = await fs_1.promises.readFile(path);
927
436
  const artifact = JSON.parse(content.toString());
928
437
  return this.fromJson(artifact, bytecodeDebugPatch, structs);
929
438
  }
@@ -1215,7 +724,9 @@ function genCodeForType(type, structs) {
1215
724
  const { immFields, mutFields } = ralph.calcFieldSize(type, true, structs);
1216
725
  const loadImmFieldByIndex = {
1217
726
  isPublic: true,
1218
- assetModifier: 0,
727
+ usePreapprovedAssets: false,
728
+ useContractAssets: false,
729
+ usePayToContractOnly: false,
1219
730
  argsLength: 1,
1220
731
  localsLength: 1,
1221
732
  returnLength: 1,
@@ -1243,7 +754,9 @@ function genCodeForType(type, structs) {
1243
754
  };
1244
755
  const destroy = {
1245
756
  isPublic: true,
1246
- assetModifier: 2,
757
+ usePreapprovedAssets: false,
758
+ useContractAssets: true,
759
+ usePayToContractOnly: false,
1247
760
  argsLength: 1,
1248
761
  localsLength: 1,
1249
762
  returnLength: 0,
@@ -1295,7 +808,7 @@ function mapsToExistingContracts(contract, parentContractId, group, initialMaps)
1295
808
  });
1296
809
  return contractStates;
1297
810
  }
1298
- async function testMethod(factory, methodName, params) {
811
+ async function testMethod(factory, methodName, params, getContractByCodeHash) {
1299
812
  const txId = params?.txId ?? randomTxId();
1300
813
  const contract = factory.contract;
1301
814
  const address = params.address ?? (0, utils_1.addressFromContractId)((0, utils_1.binToHex)(crypto.getRandomValues(new Uint8Array(32))));
@@ -1313,7 +826,7 @@ async function testMethod(factory, methodName, params) {
1313
826
  });
1314
827
  const apiResult = await (0, global_1.getCurrentNodeProvider)().contracts.postContractsTestContract(apiParams);
1315
828
  const maps = existingContractsToMaps(contract, address, group, apiResult, initialMaps);
1316
- const testResult = contract.fromApiTestContractResult(methodName, apiResult, txId);
829
+ const testResult = contract.fromApiTestContractResult(methodName, apiResult, txId, getContractByCodeHash);
1317
830
  contract.printDebugMessages(methodName, testResult.debugMessages);
1318
831
  return {
1319
832
  ...testResult,
@@ -1322,27 +835,35 @@ async function testMethod(factory, methodName, params) {
1322
835
  }
1323
836
  exports.testMethod = testMethod;
1324
837
  class RalphMap {
1325
- constructor(parentContract, parentInstance, mapName) {
838
+ constructor(parentContract, parentContractId, mapName) {
1326
839
  this.parentContract = parentContract;
1327
- this.parentInstance = parentInstance;
840
+ this.parentContractId = parentContractId;
1328
841
  this.mapName = mapName;
842
+ this.groupIndex = (0, utils_1.groupOfAddress)((0, utils_1.addressFromContractId)(parentContractId));
1329
843
  }
1330
844
  async get(key) {
1331
- return getMapItem(this.parentContract, this.parentInstance, this.mapName, key);
845
+ return getMapItem(this.parentContract, this.parentContractId, this.groupIndex, this.mapName, key);
1332
846
  }
1333
847
  async contains(key) {
1334
848
  return this.get(key).then((v) => v !== undefined);
1335
849
  }
850
+ toJSON() {
851
+ return {
852
+ parentContractId: this.parentContractId,
853
+ mapName: this.mapName,
854
+ groupIndex: this.groupIndex
855
+ };
856
+ }
1336
857
  }
1337
858
  exports.RalphMap = RalphMap;
1338
- async function getMapItem(parentContract, parentInstance, mapName, key) {
859
+ async function getMapItem(parentContract, parentContractId, groupIndex, mapName, key) {
1339
860
  const index = parentContract.mapsSig?.names.findIndex((name) => name === mapName);
1340
861
  const mapType = index === undefined ? undefined : parentContract.mapsSig?.types[`${index}`];
1341
862
  if (mapType === undefined) {
1342
863
  throw new Error(`Map ${mapName} does not exist in contract ${parentContract.name}`);
1343
864
  }
1344
865
  const [keyType, valueType] = ralph.parseMapType(mapType);
1345
- const mapItemContractId = calcWrapperContractId(parentInstance.contractId, index, key, keyType, parentInstance.groupIndex);
866
+ const mapItemContractId = calcWrapperContractId(parentContractId, index, key, keyType, groupIndex);
1346
867
  const mapItemAddress = (0, utils_1.addressFromContractId)(mapItemContractId);
1347
868
  try {
1348
869
  const state = await (0, global_1.getCurrentNodeProvider)().contracts.getContractsAddressState(mapItemAddress);
@@ -1562,10 +1083,3 @@ const getContractIdFromUnsignedTx = async (nodeProvider, unsignedTx) => {
1562
1083
  exports.getContractIdFromUnsignedTx = getContractIdFromUnsignedTx;
1563
1084
  // This function only works in the simple case where a single non-subcontract is created in the tx
1564
1085
  exports.getTokenIdFromUnsignedTx = exports.getContractIdFromUnsignedTx;
1565
- function tryGetCallResult(result) {
1566
- if (result.type === 'CallContractFailed') {
1567
- throw new Error(`Failed to call contract, error: ${result.error}`);
1568
- }
1569
- return result;
1570
- }
1571
- exports.tryGetCallResult = tryGetCallResult;