@alephium/web3 0.8.2-test.3 → 0.9.0-rc.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 (78) hide show
  1. package/LICENSE +165 -0
  2. package/package.json +37 -36
  3. package/src/api/api-alephium.ts +2 -1
  4. package/src/api/node-provider.ts +41 -25
  5. package/src/api/types.ts +10 -15
  6. package/src/contract/contract.ts +63 -40
  7. package/src/index.ts +1 -0
  8. package/{dist/scripts/header.js → src/token/index.ts} +2 -1
  9. package/{dist/src/utils/djb2.js → src/token/nft.ts} +16 -9
  10. package/std/fungible_token_interface.ral +1 -0
  11. package/std/nft_collection_interface.ral +24 -3
  12. package/std/nft_interface.ral +22 -0
  13. package/dist/alephium-web3.min.js +0 -3
  14. package/dist/alephium-web3.min.js.LICENSE.txt +0 -12
  15. package/dist/alephium-web3.min.js.map +0 -1
  16. package/dist/scripts/check-versions.d.ts +0 -1
  17. package/dist/scripts/check-versions.js +0 -39
  18. package/dist/scripts/header.d.ts +0 -0
  19. package/dist/src/api/api-alephium.d.ts +0 -1716
  20. package/dist/src/api/api-alephium.js +0 -1284
  21. package/dist/src/api/api-explorer.d.ts +0 -923
  22. package/dist/src/api/api-explorer.js +0 -711
  23. package/dist/src/api/explorer-provider.d.ts +0 -20
  24. package/dist/src/api/explorer-provider.js +0 -69
  25. package/dist/src/api/index.d.ts +0 -6
  26. package/dist/src/api/index.js +0 -52
  27. package/dist/src/api/node-provider.d.ts +0 -23
  28. package/dist/src/api/node-provider.js +0 -93
  29. package/dist/src/api/types.d.ts +0 -38
  30. package/dist/src/api/types.js +0 -263
  31. package/dist/src/api/utils.d.ts +0 -12
  32. package/dist/src/api/utils.js +0 -59
  33. package/dist/src/constants.d.ts +0 -6
  34. package/dist/src/constants.js +0 -26
  35. package/dist/src/contract/contract.d.ts +0 -293
  36. package/dist/src/contract/contract.js +0 -1079
  37. package/dist/src/contract/events.d.ts +0 -11
  38. package/dist/src/contract/events.js +0 -65
  39. package/dist/src/contract/index.d.ts +0 -3
  40. package/dist/src/contract/index.js +0 -36
  41. package/dist/src/contract/ralph.d.ts +0 -13
  42. package/dist/src/contract/ralph.js +0 -397
  43. package/dist/src/global.d.ts +0 -7
  44. package/dist/src/global.js +0 -54
  45. package/dist/src/index.d.ts +0 -8
  46. package/dist/src/index.js +0 -57
  47. package/dist/src/signer/index.d.ts +0 -3
  48. package/dist/src/signer/index.js +0 -36
  49. package/dist/src/signer/signer.d.ts +0 -60
  50. package/dist/src/signer/signer.js +0 -236
  51. package/dist/src/signer/tx-builder.d.ts +0 -12
  52. package/dist/src/signer/tx-builder.js +0 -96
  53. package/dist/src/signer/types.d.ts +0 -115
  54. package/dist/src/signer/types.js +0 -30
  55. package/dist/src/transaction/index.d.ts +0 -2
  56. package/dist/src/transaction/index.js +0 -35
  57. package/dist/src/transaction/sign-verify.d.ts +0 -3
  58. package/dist/src/transaction/sign-verify.js +0 -52
  59. package/dist/src/transaction/status.d.ts +0 -11
  60. package/dist/src/transaction/status.js +0 -49
  61. package/dist/src/utils/address.d.ts +0 -1
  62. package/dist/src/utils/address.js +0 -42
  63. package/dist/src/utils/bs58.d.ts +0 -5
  64. package/dist/src/utils/bs58.js +0 -40
  65. package/dist/src/utils/djb2.d.ts +0 -1
  66. package/dist/src/utils/index.d.ts +0 -7
  67. package/dist/src/utils/index.js +0 -40
  68. package/dist/src/utils/number.d.ts +0 -18
  69. package/dist/src/utils/number.fixture.d.ts +0 -12
  70. package/dist/src/utils/number.fixture.js +0 -189
  71. package/dist/src/utils/number.js +0 -149
  72. package/dist/src/utils/sign.d.ts +0 -3
  73. package/dist/src/utils/sign.js +0 -89
  74. package/dist/src/utils/subscription.d.ts +0 -21
  75. package/dist/src/utils/subscription.js +0 -51
  76. package/dist/src/utils/utils.d.ts +0 -40
  77. package/dist/src/utils/utils.js +0 -244
  78. package/jest-config.json +0 -11
@@ -1,1079 +0,0 @@
1
- "use strict";
2
- /*
3
- Copyright 2018 - 2022 The Alephium Authors
4
- This file is part of the alephium project.
5
-
6
- The library is free software: you can redistribute it and/or modify
7
- it under the terms of the GNU Lesser General Public License as published by
8
- the Free Software Foundation, either version 3 of the License, or
9
- (at your option) any later version.
10
-
11
- The library is distributed in the hope that it will be useful,
12
- but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- GNU Lesser General Public License for more details.
15
-
16
- You should have received a copy of the GNU Lesser General Public License
17
- along with the library. If not, see <http://www.gnu.org/licenses/>.
18
- */
19
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
20
- if (k2 === undefined) k2 = k;
21
- var desc = Object.getOwnPropertyDescriptor(m, k);
22
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
23
- desc = { enumerable: true, get: function() { return m[k]; } };
24
- }
25
- Object.defineProperty(o, k2, desc);
26
- }) : (function(o, m, k, k2) {
27
- if (k2 === undefined) k2 = k;
28
- o[k2] = m[k];
29
- }));
30
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
31
- Object.defineProperty(o, "default", { enumerable: true, value: v });
32
- }) : function(o, v) {
33
- o["default"] = v;
34
- });
35
- var __importStar = (this && this.__importStar) || function (mod) {
36
- if (mod && mod.__esModule) return mod;
37
- var result = {};
38
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
39
- __setModuleDefault(result, mod);
40
- return result;
41
- };
42
- var __importDefault = (this && this.__importDefault) || function (mod) {
43
- return (mod && mod.__esModule) ? mod : { "default": mod };
44
- };
45
- Object.defineProperty(exports, "__esModule", { value: true });
46
- exports.getContractEventsCurrentCount = exports.multicallMethods = exports.callMethod = exports.subscribeContractEvents = exports.subscribeContractEvent = exports.decodeEvent = exports.subscribeContractDestroyedEvent = exports.subscribeContractCreatedEvent = exports.fetchContractState = exports.ContractInstance = exports.testMethod = exports.subscribeEventsFromContract = exports.decodeContractDestroyedEvent = exports.decodeContractCreatedEvent = exports.DestroyContractEventAddress = exports.CreateContractEventAddress = exports.ContractFactory = exports.randomTxId = exports.toApiVals = exports.Script = exports.Contract = exports.Artifact = exports.Project = exports.DEFAULT_COMPILER_OPTIONS = exports.DEFAULT_NODE_COMPILER_OPTIONS = void 0;
47
- const buffer_1 = require("buffer/");
48
- const crypto_1 = require("crypto");
49
- const fs_1 = __importDefault(require("fs"));
50
- const fs_2 = require("fs");
51
- const api_1 = require("../api");
52
- const ralph = __importStar(require("./ralph"));
53
- const utils_1 = require("../utils");
54
- const global_1 = require("../global");
55
- const path = __importStar(require("path"));
56
- const events_1 = require("./events");
57
- const constants_1 = require("../constants");
58
- var SourceKind;
59
- (function (SourceKind) {
60
- SourceKind[SourceKind["Contract"] = 0] = "Contract";
61
- SourceKind[SourceKind["Script"] = 1] = "Script";
62
- SourceKind[SourceKind["AbstractContract"] = 2] = "AbstractContract";
63
- SourceKind[SourceKind["Interface"] = 3] = "Interface";
64
- })(SourceKind || (SourceKind = {}));
65
- exports.DEFAULT_NODE_COMPILER_OPTIONS = {
66
- ignoreUnusedConstantsWarnings: false,
67
- ignoreUnusedVariablesWarnings: false,
68
- ignoreUnusedFieldsWarnings: false,
69
- ignoreUnusedPrivateFunctionsWarnings: false,
70
- ignoreUpdateFieldsCheckWarnings: false,
71
- ignoreCheckExternalCallerWarnings: false
72
- };
73
- exports.DEFAULT_COMPILER_OPTIONS = { errorOnWarnings: true, ...exports.DEFAULT_NODE_COMPILER_OPTIONS };
74
- class TypedMatcher {
75
- constructor(pattern, type) {
76
- this.matcher = new RegExp(pattern, 'mg');
77
- this.type = type;
78
- }
79
- }
80
- function removeParentsPrefix(parts) {
81
- let index = 0;
82
- for (let i = 0; i < parts.length; i++) {
83
- if (parts[`${i}`] === '..') {
84
- index += 1;
85
- }
86
- else {
87
- break;
88
- }
89
- }
90
- return path.join(...parts.slice(index));
91
- }
92
- class SourceInfo {
93
- constructor(type, name, sourceCode, sourceCodeHash, contractRelativePath, isExternal) {
94
- this.type = type;
95
- this.name = name;
96
- this.sourceCode = sourceCode;
97
- this.sourceCodeHash = sourceCodeHash;
98
- this.contractRelativePath = contractRelativePath;
99
- this.isExternal = isExternal;
100
- }
101
- getArtifactPath(artifactsRootDir) {
102
- if (this.isExternal) {
103
- const relativePath = removeParentsPrefix(this.contractRelativePath.split(path.sep));
104
- const externalPath = path.join('.external', relativePath);
105
- return path.join(artifactsRootDir, externalPath) + '.json';
106
- }
107
- return path.join(artifactsRootDir, this.contractRelativePath) + '.json';
108
- }
109
- static async from(type, name, sourceCode, contractRelativePath, isExternal) {
110
- const sourceCodeHash = await crypto_1.webcrypto.subtle.digest('SHA-256', buffer_1.Buffer.from(sourceCode));
111
- const sourceCodeHashHex = buffer_1.Buffer.from(sourceCodeHash).toString('hex');
112
- return new SourceInfo(type, name, sourceCode, sourceCodeHashHex, contractRelativePath, isExternal);
113
- }
114
- }
115
- class Compiled {
116
- constructor(sourceInfo, artifact, warnings) {
117
- this.sourceInfo = sourceInfo;
118
- this.artifact = artifact;
119
- this.warnings = warnings;
120
- }
121
- }
122
- class ProjectArtifact {
123
- constructor(compilerOptionsUsed, infos) {
124
- ProjectArtifact.checkCompilerOptionsParameter(compilerOptionsUsed);
125
- this.compilerOptionsUsed = compilerOptionsUsed;
126
- this.infos = infos;
127
- }
128
- static checkCompilerOptionsParameter(compilerOptions) {
129
- if (Object.keys(compilerOptions).length != Object.keys(exports.DEFAULT_NODE_COMPILER_OPTIONS).length) {
130
- throw Error(`Not all compiler options are set: ${compilerOptions}`);
131
- }
132
- const combined = { ...compilerOptions, ...exports.DEFAULT_NODE_COMPILER_OPTIONS };
133
- if (Object.keys(combined).length !== Object.keys(exports.DEFAULT_NODE_COMPILER_OPTIONS).length) {
134
- throw Error(`There are unknown compiler options: ${compilerOptions}`);
135
- }
136
- }
137
- async saveToFile(rootPath) {
138
- const filepath = path.join(rootPath, ProjectArtifact.artifactFileName);
139
- const artifact = {
140
- compilerOptionsUsed: this.compilerOptionsUsed,
141
- infos: Object.fromEntries(new Map([...this.infos].sort()))
142
- };
143
- const content = JSON.stringify(artifact, null, 2);
144
- return fs_2.promises.writeFile(filepath, content);
145
- }
146
- needToReCompile(compilerOptions, sourceInfos) {
147
- ProjectArtifact.checkCompilerOptionsParameter(compilerOptions);
148
- const optionsMatched = Object.entries(compilerOptions).every(([key, inputOption]) => {
149
- const usedOption = this.compilerOptionsUsed[`${key}`];
150
- return usedOption === inputOption;
151
- });
152
- if (!optionsMatched) {
153
- return true;
154
- }
155
- if (sourceInfos.length !== this.infos.size) {
156
- return true;
157
- }
158
- for (const sourceInfo of sourceInfos) {
159
- const info = this.infos.get(sourceInfo.name);
160
- if (typeof info === 'undefined' || info.sourceCodeHash !== sourceInfo.sourceCodeHash) {
161
- return true;
162
- }
163
- }
164
- return false;
165
- }
166
- static async from(rootPath) {
167
- const filepath = path.join(rootPath, ProjectArtifact.artifactFileName);
168
- if (!fs_1.default.existsSync(filepath)) {
169
- return undefined;
170
- }
171
- const content = await fs_2.promises.readFile(filepath);
172
- const json = JSON.parse(content.toString());
173
- const compilerOptionsUsed = json.compilerOptionsUsed;
174
- const files = new Map(Object.entries(json.infos));
175
- return new ProjectArtifact(compilerOptionsUsed, files);
176
- }
177
- }
178
- ProjectArtifact.artifactFileName = '.project.json';
179
- class Project {
180
- constructor(contractsRootDir, artifactsRootDir, sourceInfos, contracts, scripts, errorOnWarnings, projectArtifact) {
181
- this.contractsRootDir = contractsRootDir;
182
- this.artifactsRootDir = artifactsRootDir;
183
- this.sourceInfos = sourceInfos;
184
- this.contracts = contracts;
185
- this.scripts = scripts;
186
- this.projectArtifact = projectArtifact;
187
- if (errorOnWarnings) {
188
- Project.checkCompilerWarnings([
189
- ...[...contracts.entries()].map((c) => c[1].warnings).flat(),
190
- ...[...scripts.entries()].map((s) => s[1].warnings).flat()
191
- ], errorOnWarnings);
192
- }
193
- }
194
- static buildProjectArtifact(sourceInfos, contracts, scripts, compilerOptions) {
195
- const files = new Map();
196
- contracts.forEach((c) => {
197
- files.set(c.artifact.name, {
198
- sourceFile: c.sourceInfo.contractRelativePath,
199
- sourceCodeHash: c.sourceInfo.sourceCodeHash,
200
- bytecodeDebugPatch: c.artifact.bytecodeDebugPatch,
201
- codeHashDebug: c.artifact.codeHashDebug,
202
- warnings: c.warnings
203
- });
204
- });
205
- scripts.forEach((s) => {
206
- files.set(s.artifact.name, {
207
- sourceFile: s.sourceInfo.contractRelativePath,
208
- sourceCodeHash: s.sourceInfo.sourceCodeHash,
209
- bytecodeDebugPatch: s.artifact.bytecodeDebugPatch,
210
- codeHashDebug: '',
211
- warnings: s.warnings
212
- });
213
- });
214
- const compiledSize = contracts.size + scripts.size;
215
- sourceInfos.slice(compiledSize).forEach((c) => {
216
- files.set(c.name, {
217
- sourceFile: c.contractRelativePath,
218
- sourceCodeHash: c.sourceCodeHash,
219
- bytecodeDebugPatch: '',
220
- codeHashDebug: '',
221
- warnings: []
222
- });
223
- });
224
- return new ProjectArtifact(compilerOptions, files);
225
- }
226
- static checkCompilerWarnings(warnings, errorOnWarnings) {
227
- if (warnings.length !== 0) {
228
- const prefixPerWarning = ' - ';
229
- const warningString = prefixPerWarning + warnings.join('\n' + prefixPerWarning);
230
- const output = `Compilation warnings:\n` + warningString + '\n';
231
- if (errorOnWarnings) {
232
- throw new Error(output);
233
- }
234
- else {
235
- console.log(output);
236
- }
237
- }
238
- }
239
- static contract(name) {
240
- const contract = Project.currentProject.contracts.get(name);
241
- if (typeof contract === 'undefined') {
242
- throw new Error(`Contract "${name}" does not exist`);
243
- }
244
- return contract.artifact;
245
- }
246
- static script(name) {
247
- const script = Project.currentProject.scripts.get(name);
248
- if (typeof script === 'undefined') {
249
- throw new Error(`Script "${name}" does not exist`);
250
- }
251
- return script.artifact;
252
- }
253
- async saveArtifactsToFile(projectRootDir) {
254
- const artifactsRootDir = this.artifactsRootDir;
255
- const saveToFile = async function (compiled) {
256
- const artifactPath = compiled.sourceInfo.getArtifactPath(artifactsRootDir);
257
- const dirname = path.dirname(artifactPath);
258
- if (!fs_1.default.existsSync(dirname)) {
259
- fs_1.default.mkdirSync(dirname, { recursive: true });
260
- }
261
- return fs_2.promises.writeFile(artifactPath, compiled.artifact.toString());
262
- };
263
- this.contracts.forEach((contract) => saveToFile(contract));
264
- this.scripts.forEach((script) => saveToFile(script));
265
- await this.projectArtifact.saveToFile(projectRootDir);
266
- }
267
- contractByCodeHash(codeHash) {
268
- const contract = [...this.contracts.values()].find((c) => c.artifact.codeHash === codeHash || c.artifact.codeHashDebug == codeHash);
269
- if (typeof contract === 'undefined') {
270
- throw new Error(`Unknown code with code hash: ${codeHash}`);
271
- }
272
- return contract.artifact;
273
- }
274
- static async compile(provider, sourceInfos, projectRootDir, contractsRootDir, artifactsRootDir, errorOnWarnings, compilerOptions) {
275
- const sourceStr = sourceInfos.map((f) => f.sourceCode).join('\n');
276
- const result = await provider.contracts.postContractsCompileProject({
277
- code: sourceStr,
278
- compilerOptions: compilerOptions
279
- });
280
- const contracts = new Map();
281
- const scripts = new Map();
282
- result.contracts.forEach((contractResult, index) => {
283
- const sourceInfo = sourceInfos[`${index}`];
284
- const contract = Contract.fromCompileResult(contractResult);
285
- contracts.set(contract.name, new Compiled(sourceInfo, contract, contractResult.warnings));
286
- });
287
- result.scripts.forEach((scriptResult, index) => {
288
- const sourceInfo = sourceInfos[index + contracts.size];
289
- const script = Script.fromCompileResult(scriptResult);
290
- scripts.set(script.name, new Compiled(sourceInfo, script, scriptResult.warnings));
291
- });
292
- const projectArtifact = Project.buildProjectArtifact(sourceInfos, contracts, scripts, compilerOptions);
293
- const project = new Project(contractsRootDir, artifactsRootDir, sourceInfos, contracts, scripts, errorOnWarnings, projectArtifact);
294
- await project.saveArtifactsToFile(projectRootDir);
295
- return project;
296
- }
297
- static async loadArtifacts(provider, sourceInfos, projectArtifact, projectRootDir, contractsRootDir, artifactsRootDir, errorOnWarnings, compilerOptions) {
298
- try {
299
- const contracts = new Map();
300
- const scripts = new Map();
301
- for (const sourceInfo of sourceInfos) {
302
- const info = projectArtifact.infos.get(sourceInfo.name);
303
- if (typeof info === 'undefined') {
304
- throw Error(`Unable to find project info for ${sourceInfo.name}, please rebuild the project`);
305
- }
306
- const warnings = info.warnings;
307
- const artifactDir = sourceInfo.getArtifactPath(artifactsRootDir);
308
- if (sourceInfo.type === SourceKind.Contract) {
309
- const artifact = await Contract.fromArtifactFile(artifactDir, info.bytecodeDebugPatch, info.codeHashDebug);
310
- contracts.set(artifact.name, new Compiled(sourceInfo, artifact, warnings));
311
- }
312
- else if (sourceInfo.type === SourceKind.Script) {
313
- const artifact = await Script.fromArtifactFile(artifactDir, info.bytecodeDebugPatch);
314
- scripts.set(artifact.name, new Compiled(sourceInfo, artifact, warnings));
315
- }
316
- }
317
- return new Project(contractsRootDir, artifactsRootDir, sourceInfos, contracts, scripts, errorOnWarnings, projectArtifact);
318
- }
319
- catch (error) {
320
- console.log(`Failed to load artifacts, error: ${error}, try to re-compile contracts...`);
321
- return Project.compile(provider, sourceInfos, projectRootDir, contractsRootDir, artifactsRootDir, errorOnWarnings, compilerOptions);
322
- }
323
- }
324
- static getImportSourcePath(projectRootDir, importPath) {
325
- const parts = importPath.split('/');
326
- if (parts.length > 1 && parts[0] === 'std') {
327
- const currentDir = path.dirname(__filename);
328
- return path.join(...[currentDir, '..', '..', '..', importPath]);
329
- }
330
- let moduleDir = projectRootDir;
331
- while (true) {
332
- const expectedPath = path.join(...[moduleDir, 'node_modules', importPath]);
333
- if (fs_1.default.existsSync(expectedPath)) {
334
- return expectedPath;
335
- }
336
- const oldModuleDir = moduleDir;
337
- moduleDir = path.join(moduleDir, '..');
338
- if (oldModuleDir === moduleDir) {
339
- throw new Error(`Specified import file does not exist: ${importPath}`);
340
- }
341
- }
342
- }
343
- static async handleImports(projectRootDir, contractRootDir, sourceStr, importsCache) {
344
- const localImportsCache = [];
345
- const result = sourceStr.replace(Project.importRegex, (match) => {
346
- localImportsCache.push(match);
347
- return '';
348
- });
349
- const externalSourceInfos = [];
350
- for (const myImport of localImportsCache) {
351
- const originImportPath = myImport.slice(8, -1);
352
- const importPath = originImportPath.endsWith('.ral') ? originImportPath : originImportPath + '.ral';
353
- if (!importsCache.includes(importPath)) {
354
- importsCache.push(importPath);
355
- const sourcePath = Project.getImportSourcePath(projectRootDir, importPath);
356
- const sourceInfos = await Project.loadSourceFile(projectRootDir, contractRootDir, sourcePath, importsCache, true);
357
- externalSourceInfos.push(...sourceInfos);
358
- }
359
- }
360
- return [result, externalSourceInfos];
361
- }
362
- static async loadSourceFile(projectRootDir, contractsRootDir, sourcePath, importsCache, isExternal) {
363
- const contractRelativePath = path.relative(contractsRootDir, sourcePath);
364
- if (!sourcePath.endsWith('.ral')) {
365
- throw new Error(`Invalid filename: ${sourcePath}, smart contract file name should end with ".ral"`);
366
- }
367
- const sourceBuffer = await fs_2.promises.readFile(sourcePath);
368
- const [sourceStr, externalSourceInfos] = await Project.handleImports(projectRootDir, contractsRootDir, sourceBuffer.toString(), importsCache);
369
- if (sourceStr.match(new RegExp('^import "', 'mg')) !== null) {
370
- throw new Error(`Invalid import statements, source: ${sourcePath}`);
371
- }
372
- const sourceInfos = externalSourceInfos;
373
- for (const matcher of this.matchers) {
374
- const results = sourceStr.matchAll(matcher.matcher);
375
- for (const result of results) {
376
- const sourceInfo = await SourceInfo.from(matcher.type, result[1], sourceStr, contractRelativePath, isExternal);
377
- sourceInfos.push(sourceInfo);
378
- }
379
- }
380
- return sourceInfos;
381
- }
382
- static async loadSourceFiles(projectRootDir, contractsRootDir) {
383
- const importsCache = [];
384
- const sourceInfos = [];
385
- const loadDir = async function (dirPath) {
386
- const dirents = await fs_2.promises.readdir(dirPath, { withFileTypes: true });
387
- for (const dirent of dirents) {
388
- if (dirent.isFile()) {
389
- const sourcePath = path.join(dirPath, dirent.name);
390
- const infos = await Project.loadSourceFile(projectRootDir, contractsRootDir, sourcePath, importsCache, false);
391
- sourceInfos.push(...infos);
392
- }
393
- else {
394
- const newPath = path.join(dirPath, dirent.name);
395
- await loadDir(newPath);
396
- }
397
- }
398
- };
399
- await loadDir(contractsRootDir);
400
- const contractAndScriptSize = sourceInfos.filter((f) => f.type === SourceKind.Contract || f.type === SourceKind.Script).length;
401
- if (sourceInfos.length === 0 || contractAndScriptSize === 0) {
402
- throw new Error('Project have no source files');
403
- }
404
- return sourceInfos.sort((a, b) => a.type - b.type);
405
- }
406
- static async build(compilerOptionsPartial = {}, projectRootDir = '.', contractsRootDir = Project.DEFAULT_CONTRACTS_DIR, artifactsRootDir = Project.DEFAULT_ARTIFACTS_DIR) {
407
- const provider = (0, global_1.getCurrentNodeProvider)();
408
- const sourceFiles = await Project.loadSourceFiles(projectRootDir, contractsRootDir);
409
- const { errorOnWarnings, ...nodeCompilerOptions } = { ...exports.DEFAULT_COMPILER_OPTIONS, ...compilerOptionsPartial };
410
- const projectArtifact = await ProjectArtifact.from(projectRootDir);
411
- if (typeof projectArtifact === 'undefined' || projectArtifact.needToReCompile(nodeCompilerOptions, sourceFiles)) {
412
- console.log(`Compiling contracts in folder "${contractsRootDir}"`);
413
- Project.currentProject = await Project.compile(provider, sourceFiles, projectRootDir, contractsRootDir, artifactsRootDir, errorOnWarnings, nodeCompilerOptions);
414
- }
415
- else {
416
- console.log(`Contracts are compiled already. Loading them from folder "${artifactsRootDir}"`);
417
- Project.currentProject = await Project.loadArtifacts(provider, sourceFiles, projectArtifact, projectRootDir, contractsRootDir, artifactsRootDir, errorOnWarnings, nodeCompilerOptions);
418
- }
419
- }
420
- }
421
- exports.Project = Project;
422
- Project.importRegex = new RegExp('^import "[^"./]+/[^"]*[a-z][a-z_0-9]*(.ral)?"', 'mg');
423
- Project.abstractContractMatcher = new TypedMatcher('^Abstract Contract ([A-Z][a-zA-Z0-9]*)', SourceKind.AbstractContract);
424
- Project.contractMatcher = new TypedMatcher('^Contract ([A-Z][a-zA-Z0-9]*)', SourceKind.Contract);
425
- Project.interfaceMatcher = new TypedMatcher('^Interface ([A-Z][a-zA-Z0-9]*)', SourceKind.Interface);
426
- Project.scriptMatcher = new TypedMatcher('^TxScript ([A-Z][a-zA-Z0-9]*)', SourceKind.Script);
427
- Project.matchers = [
428
- Project.abstractContractMatcher,
429
- Project.contractMatcher,
430
- Project.interfaceMatcher,
431
- Project.scriptMatcher
432
- ];
433
- Project.DEFAULT_CONTRACTS_DIR = 'contracts';
434
- Project.DEFAULT_ARTIFACTS_DIR = 'artifacts';
435
- class Artifact {
436
- constructor(version, name, functions) {
437
- this.version = version;
438
- this.name = name;
439
- this.functions = functions;
440
- }
441
- publicFunctions() {
442
- return this.functions.filter((func) => func.isPublic).map((func) => func.name);
443
- }
444
- usingPreapprovedAssetsFunctions() {
445
- return this.functions.filter((func) => func.usePreapprovedAssets).map((func) => func.name);
446
- }
447
- usingAssetsInContractFunctions() {
448
- return this.functions.filter((func) => func.useAssetsInContract).map((func) => func.name);
449
- }
450
- }
451
- exports.Artifact = Artifact;
452
- class Contract extends Artifact {
453
- constructor(version, name, bytecode, bytecodeDebugPatch, codeHash, codeHashDebug, fieldsSig, eventsSig, functions) {
454
- super(version, name, functions);
455
- this.bytecode = bytecode;
456
- this.bytecodeDebugPatch = bytecodeDebugPatch;
457
- this.codeHash = codeHash;
458
- this.fieldsSig = fieldsSig;
459
- this.eventsSig = eventsSig;
460
- this.bytecodeDebug = ralph.buildDebugBytecode(this.bytecode, this.bytecodeDebugPatch);
461
- this.codeHashDebug = codeHashDebug;
462
- }
463
- // TODO: safely parse json
464
- static fromJson(artifact, bytecodeDebugPatch = '', codeHashDebug = '') {
465
- if (artifact.version == null ||
466
- artifact.name == null ||
467
- artifact.bytecode == null ||
468
- artifact.codeHash == null ||
469
- artifact.fieldsSig == null ||
470
- artifact.eventsSig == null ||
471
- artifact.functions == null) {
472
- throw Error('The artifact JSON for contract is incomplete');
473
- }
474
- const contract = new Contract(artifact.version, artifact.name, artifact.bytecode, bytecodeDebugPatch, artifact.codeHash, codeHashDebug ? codeHashDebug : artifact.codeHash, artifact.fieldsSig, artifact.eventsSig, artifact.functions);
475
- return contract;
476
- }
477
- static fromCompileResult(result) {
478
- return new Contract(result.version, result.name, result.bytecode, result.bytecodeDebugPatch, result.codeHash, result.codeHashDebug, result.fields, result.events, result.functions);
479
- }
480
- // support both 'code.ral' and 'code.ral.json'
481
- static async fromArtifactFile(path, bytecodeDebugPatch, codeHashDebug) {
482
- const content = await fs_2.promises.readFile(path);
483
- const artifact = JSON.parse(content.toString());
484
- return Contract.fromJson(artifact, bytecodeDebugPatch, codeHashDebug);
485
- }
486
- toString() {
487
- const object = {
488
- version: this.version,
489
- name: this.name,
490
- bytecode: this.bytecode,
491
- codeHash: this.codeHash,
492
- fieldsSig: this.fieldsSig,
493
- eventsSig: this.eventsSig,
494
- functions: this.functions
495
- };
496
- return JSON.stringify(object, null, 2);
497
- }
498
- toState(fields, asset, address) {
499
- const addressDef = typeof address !== 'undefined' ? address : Contract.randomAddress();
500
- return {
501
- address: addressDef,
502
- contractId: (0, utils_1.binToHex)((0, utils_1.contractIdFromAddress)(addressDef)),
503
- bytecode: this.bytecode,
504
- codeHash: this.codeHash,
505
- fields: fields,
506
- fieldsSig: this.fieldsSig,
507
- asset: asset
508
- };
509
- }
510
- // no need to be cryptographically strong random
511
- static randomAddress() {
512
- const bytes = new Uint8Array(33);
513
- crypto_1.webcrypto.getRandomValues(bytes);
514
- bytes[0] = 3;
515
- return utils_1.bs58.encode(bytes);
516
- }
517
- printDebugMessages(funcName, messages) {
518
- if (messages.length != 0) {
519
- console.log(`Testing ${this.name}.${funcName}:`);
520
- messages.forEach((m) => console.log(`Debug - ${m.contractAddress} - ${m.message}`));
521
- }
522
- }
523
- toApiFields(fields) {
524
- if (typeof fields === 'undefined') {
525
- return [];
526
- }
527
- else {
528
- return toApiFields(fields, this.fieldsSig);
529
- }
530
- }
531
- toApiArgs(funcName, args) {
532
- if (args) {
533
- const func = this.functions.find((func) => func.name == funcName);
534
- if (func == null) {
535
- throw new Error(`Invalid function name: ${funcName}`);
536
- }
537
- return toApiArgs(args, func);
538
- }
539
- else {
540
- return [];
541
- }
542
- }
543
- getMethodIndex(funcName) {
544
- return this.functions.findIndex((func) => func.name === funcName);
545
- }
546
- toApiContractStates(states) {
547
- return typeof states != 'undefined' ? states.map((state) => toApiContractState(state)) : undefined;
548
- }
549
- toApiTestContractParams(funcName, params) {
550
- const immFields = params.initialFields === undefined ? [] : extractFields(params.initialFields, this.fieldsSig, false);
551
- const mutFields = params.initialFields === undefined ? [] : extractFields(params.initialFields, this.fieldsSig, true);
552
- return {
553
- group: params.group,
554
- blockHash: params.blockHash,
555
- blockTimeStamp: params.blockTimeStamp,
556
- txId: params.txId,
557
- address: params.address,
558
- bytecode: this.bytecodeDebug,
559
- initialImmFields: immFields,
560
- initialMutFields: mutFields,
561
- initialAsset: typeof params.initialAsset !== 'undefined' ? toApiAsset(params.initialAsset) : undefined,
562
- methodIndex: this.getMethodIndex(funcName),
563
- args: this.toApiArgs(funcName, params.testArgs),
564
- existingContracts: this.toApiContractStates(params.existingContracts),
565
- inputAssets: toApiInputAssets(params.inputAssets)
566
- };
567
- }
568
- fromApiContractState(state) {
569
- return {
570
- address: state.address,
571
- contractId: (0, utils_1.binToHex)((0, utils_1.contractIdFromAddress)(state.address)),
572
- bytecode: state.bytecode,
573
- initialStateHash: state.initialStateHash,
574
- codeHash: state.codeHash,
575
- fields: fromApiFields(state.immFields, state.mutFields, this.fieldsSig),
576
- fieldsSig: this.fieldsSig,
577
- asset: fromApiAsset(state.asset)
578
- };
579
- }
580
- static fromApiContractState(state) {
581
- const contract = Project.currentProject.contractByCodeHash(state.codeHash);
582
- return contract.fromApiContractState(state);
583
- }
584
- static fromApiEvent(event, codeHash, txId) {
585
- let fields;
586
- let name;
587
- if (event.eventIndex == Contract.ContractCreatedEventIndex) {
588
- fields = fromApiSystemEventFields(event.fields, Contract.ContractCreatedEvent);
589
- name = Contract.ContractCreatedEvent.name;
590
- }
591
- else if (event.eventIndex == Contract.ContractDestroyedEventIndex) {
592
- fields = fromApiSystemEventFields(event.fields, Contract.ContractDestroyedEvent);
593
- name = Contract.ContractDestroyedEvent.name;
594
- }
595
- else {
596
- const contract = Project.currentProject.contractByCodeHash(codeHash);
597
- const eventSig = contract.eventsSig[event.eventIndex];
598
- fields = fromApiEventFields(event.fields, eventSig);
599
- name = eventSig.name;
600
- }
601
- return {
602
- txId: txId,
603
- blockHash: event.blockHash,
604
- contractAddress: event.contractAddress,
605
- name: name,
606
- eventIndex: event.eventIndex,
607
- fields: fields
608
- };
609
- }
610
- fromApiTestContractResult(methodName, result, txId) {
611
- const methodIndex = this.functions.findIndex((sig) => sig.name === methodName);
612
- const returnTypes = this.functions[`${methodIndex}`].returnTypes;
613
- const rawReturn = (0, api_1.fromApiArray)(result.returns, returnTypes);
614
- const returns = rawReturn.length === 0 ? null : rawReturn.length === 1 ? rawReturn[0] : rawReturn;
615
- const addressToCodeHash = new Map();
616
- addressToCodeHash.set(result.address, result.codeHash);
617
- result.contracts.forEach((contract) => addressToCodeHash.set(contract.address, contract.codeHash));
618
- return {
619
- contractId: (0, utils_1.binToHex)((0, utils_1.contractIdFromAddress)(result.address)),
620
- contractAddress: result.address,
621
- returns: returns,
622
- gasUsed: result.gasUsed,
623
- contracts: result.contracts.map((contract) => Contract.fromApiContractState(contract)),
624
- txOutputs: result.txOutputs.map(fromApiOutput),
625
- events: Contract.fromApiEvents(result.events, addressToCodeHash, txId),
626
- debugMessages: result.debugMessages
627
- };
628
- }
629
- async txParamsForDeployment(signer, params) {
630
- const bytecode = this.buildByteCodeToDeploy(params.initialFields ?? {});
631
- const selectedAccount = await signer.getSelectedAccount();
632
- const signerParams = {
633
- signerAddress: selectedAccount.address,
634
- signerKeyType: selectedAccount.keyType,
635
- bytecode: bytecode,
636
- initialAttoAlphAmount: params?.initialAttoAlphAmount,
637
- issueTokenAmount: params?.issueTokenAmount,
638
- initialTokenAmounts: params?.initialTokenAmounts,
639
- gasAmount: params?.gasAmount,
640
- gasPrice: params?.gasPrice
641
- };
642
- return signerParams;
643
- }
644
- buildByteCodeToDeploy(initialFields) {
645
- return ralph.buildContractByteCode(this.bytecode, initialFields, this.fieldsSig);
646
- }
647
- static fromApiEvents(events, addressToCodeHash, txId) {
648
- return events.map((event) => {
649
- const contractAddress = event.contractAddress;
650
- const codeHash = addressToCodeHash.get(contractAddress);
651
- if (typeof codeHash !== 'undefined' || event.eventIndex < 0) {
652
- return Contract.fromApiEvent(event, codeHash, txId);
653
- }
654
- else {
655
- throw Error(`Cannot find codeHash for the contract address: ${contractAddress}`);
656
- }
657
- });
658
- }
659
- toApiCallContract(params, groupIndex, contractAddress, methodIndex) {
660
- const functionSig = this.functions[`${methodIndex}`];
661
- const args = toApiVals(params.args ?? {}, functionSig.paramNames, functionSig.paramTypes);
662
- return {
663
- ...params,
664
- group: groupIndex,
665
- address: contractAddress,
666
- methodIndex: methodIndex,
667
- args: args
668
- };
669
- }
670
- fromApiCallContractResult(result, txId, methodIndex) {
671
- const returnTypes = this.functions[`${methodIndex}`].returnTypes;
672
- const rawReturn = (0, api_1.fromApiArray)(result.returns, returnTypes);
673
- const returns = rawReturn.length === 0 ? null : rawReturn.length === 1 ? rawReturn[0] : rawReturn;
674
- const addressToCodeHash = new Map();
675
- result.contracts.forEach((contract) => addressToCodeHash.set(contract.address, contract.codeHash));
676
- return {
677
- returns: returns,
678
- gasUsed: result.gasUsed,
679
- contracts: result.contracts.map((state) => Contract.fromApiContractState(state)),
680
- txInputs: result.txInputs,
681
- txOutputs: result.txOutputs.map((output) => fromApiOutput(output)),
682
- events: Contract.fromApiEvents(result.events, addressToCodeHash, txId)
683
- };
684
- }
685
- }
686
- exports.Contract = Contract;
687
- Contract.ContractCreatedEventIndex = -1;
688
- Contract.ContractCreatedEvent = {
689
- name: 'ContractCreated',
690
- fieldNames: ['address'],
691
- fieldTypes: ['Address'],
692
- optionalFieldNames: ['parentAddress'],
693
- optionalFieldTypes: ['Address']
694
- };
695
- Contract.ContractDestroyedEventIndex = -2;
696
- Contract.ContractDestroyedEvent = {
697
- name: 'ContractDestroyed',
698
- fieldNames: ['address'],
699
- fieldTypes: ['Address']
700
- };
701
- class Script extends Artifact {
702
- constructor(version, name, bytecodeTemplate, bytecodeDebugPatch, fieldsSig, functions) {
703
- super(version, name, functions);
704
- this.bytecodeTemplate = bytecodeTemplate;
705
- this.bytecodeDebugPatch = bytecodeDebugPatch;
706
- this.fieldsSig = fieldsSig;
707
- }
708
- static fromCompileResult(result) {
709
- return new Script(result.version, result.name, result.bytecodeTemplate, result.bytecodeDebugPatch, result.fields, result.functions);
710
- }
711
- // TODO: safely parse json
712
- static fromJson(artifact, bytecodeDebugPatch = '') {
713
- if (artifact.version == null ||
714
- artifact.name == null ||
715
- artifact.bytecodeTemplate == null ||
716
- artifact.fieldsSig == null ||
717
- artifact.functions == null) {
718
- throw Error('The artifact JSON for script is incomplete');
719
- }
720
- return new Script(artifact.version, artifact.name, artifact.bytecodeTemplate, bytecodeDebugPatch, artifact.fieldsSig, artifact.functions);
721
- }
722
- static async fromArtifactFile(path, bytecodeDebugPatch) {
723
- const content = await fs_2.promises.readFile(path);
724
- const artifact = JSON.parse(content.toString());
725
- return this.fromJson(artifact, bytecodeDebugPatch);
726
- }
727
- toString() {
728
- const object = {
729
- version: this.version,
730
- name: this.name,
731
- bytecodeTemplate: this.bytecodeTemplate,
732
- fieldsSig: this.fieldsSig,
733
- functions: this.functions
734
- };
735
- return JSON.stringify(object, null, 2);
736
- }
737
- async txParamsForExecution(signer, params) {
738
- const selectedAccount = await signer.getSelectedAccount();
739
- const signerParams = {
740
- signerAddress: selectedAccount.address,
741
- signerKeyType: selectedAccount.keyType,
742
- bytecode: this.buildByteCodeToDeploy(params.initialFields ?? {}),
743
- attoAlphAmount: params.attoAlphAmount,
744
- tokens: params.tokens,
745
- gasAmount: params.gasAmount,
746
- gasPrice: params.gasPrice
747
- };
748
- return signerParams;
749
- }
750
- buildByteCodeToDeploy(initialFields) {
751
- return ralph.buildScriptByteCode(this.bytecodeTemplate, initialFields, this.fieldsSig);
752
- }
753
- }
754
- exports.Script = Script;
755
- function fromApiFields(immFields, mutFields, fieldsSig) {
756
- const vals = [];
757
- let immIndex = 0;
758
- let mutIndex = 0;
759
- const isMutable = fieldsSig.types.flatMap((tpe, index) => Array((0, api_1.typeLength)(tpe)).fill(fieldsSig.isMutable[`${index}`]));
760
- isMutable.forEach((mutable) => {
761
- if (mutable) {
762
- vals.push(mutFields[`${mutIndex}`]);
763
- mutIndex += 1;
764
- }
765
- else {
766
- vals.push(immFields[`${immIndex}`]);
767
- immIndex += 1;
768
- }
769
- });
770
- return (0, api_1.fromApiVals)(vals, fieldsSig.names, fieldsSig.types);
771
- }
772
- function fromApiEventFields(vals, eventSig) {
773
- return (0, api_1.fromApiVals)(vals, eventSig.fieldNames, eventSig.fieldTypes);
774
- }
775
- function fromApiSystemEventFields(vals, systemEventSig) {
776
- return (0, api_1.fromApiVals)(vals, systemEventSig.fieldNames, systemEventSig.fieldTypes, systemEventSig.optionalFieldNames ?? [], systemEventSig.optionalFieldTypes ?? []);
777
- }
778
- function toApiAsset(asset) {
779
- return {
780
- attoAlphAmount: (0, api_1.toApiNumber256)(asset.alphAmount),
781
- tokens: typeof asset.tokens !== 'undefined' ? asset.tokens.map(api_1.toApiToken) : []
782
- };
783
- }
784
- function fromApiAsset(asset) {
785
- return {
786
- alphAmount: (0, api_1.fromApiNumber256)(asset.attoAlphAmount),
787
- tokens: (0, api_1.fromApiTokens)(asset.tokens)
788
- };
789
- }
790
- function getVal(vals, name) {
791
- if (name in vals) {
792
- return vals[`${name}`];
793
- }
794
- else {
795
- throw Error(`No Val exists for ${name}`);
796
- }
797
- }
798
- function extractFields(fields, fieldsSig, mutable) {
799
- const fieldIndexes = fieldsSig.names
800
- .map((_, index) => index)
801
- .filter((index) => fieldsSig.isMutable[`${index}`] === mutable);
802
- const fieldNames = fieldIndexes.map((index) => fieldsSig.names[`${index}`]);
803
- const fieldTypes = fieldIndexes.map((index) => fieldsSig.types[`${index}`]);
804
- return toApiVals(fields, fieldNames, fieldTypes);
805
- }
806
- function toApiContractState(state) {
807
- const stateFields = state.fields ?? {};
808
- return {
809
- address: state.address,
810
- bytecode: state.bytecode,
811
- codeHash: state.codeHash,
812
- initialStateHash: state.initialStateHash,
813
- immFields: extractFields(stateFields, state.fieldsSig, false),
814
- mutFields: extractFields(stateFields, state.fieldsSig, true),
815
- asset: toApiAsset(state.asset)
816
- };
817
- }
818
- function toApiFields(fields, fieldsSig) {
819
- return toApiVals(fields, fieldsSig.names, fieldsSig.types);
820
- }
821
- function toApiArgs(args, funcSig) {
822
- return toApiVals(args, funcSig.paramNames, funcSig.paramTypes);
823
- }
824
- function toApiVals(fields, names, types) {
825
- return names.map((name, index) => {
826
- const val = getVal(fields, name);
827
- const tpe = types[`${index}`];
828
- return (0, api_1.toApiVal)(val, tpe);
829
- });
830
- }
831
- exports.toApiVals = toApiVals;
832
- function toApiInputAsset(inputAsset) {
833
- return { address: inputAsset.address, asset: toApiAsset(inputAsset.asset) };
834
- }
835
- function toApiInputAssets(inputAssets) {
836
- return typeof inputAssets !== 'undefined' ? inputAssets.map(toApiInputAsset) : undefined;
837
- }
838
- function fromApiOutput(output) {
839
- if (output.type === 'AssetOutput') {
840
- const asset = output;
841
- return {
842
- type: 'AssetOutput',
843
- address: asset.address,
844
- alphAmount: (0, api_1.fromApiNumber256)(asset.attoAlphAmount),
845
- tokens: (0, api_1.fromApiTokens)(asset.tokens),
846
- lockTime: asset.lockTime,
847
- message: asset.message
848
- };
849
- }
850
- else if (output.type === 'ContractOutput') {
851
- const asset = output;
852
- return {
853
- type: 'ContractOutput',
854
- address: asset.address,
855
- alphAmount: (0, api_1.fromApiNumber256)(asset.attoAlphAmount),
856
- tokens: (0, api_1.fromApiTokens)(asset.tokens)
857
- };
858
- }
859
- else {
860
- throw new Error(`Unknown output type: ${output}`);
861
- }
862
- }
863
- function randomTxId() {
864
- const bytes = new Uint8Array(32);
865
- crypto_1.webcrypto.getRandomValues(bytes);
866
- return (0, utils_1.binToHex)(bytes);
867
- }
868
- exports.randomTxId = randomTxId;
869
- utils_1.assertType;
870
- class ContractFactory {
871
- constructor(contract) {
872
- this.contract = contract;
873
- }
874
- async deploy(signer, deployParams) {
875
- const signerParams = await this.contract.txParamsForDeployment(signer, deployParams);
876
- const result = await signer.signAndSubmitDeployContractTx(signerParams);
877
- return {
878
- ...result,
879
- instance: this.at(result.contractAddress)
880
- };
881
- }
882
- // This is used for testing contract functions
883
- stateForTest(initFields, asset, address) {
884
- const newAsset = {
885
- alphAmount: asset?.alphAmount ?? constants_1.ONE_ALPH,
886
- tokens: asset?.tokens
887
- };
888
- return this.contract.toState(initFields, newAsset, address);
889
- }
890
- }
891
- exports.ContractFactory = ContractFactory;
892
- function specialContractAddress(n) {
893
- const bytes = new Uint8Array(32).fill(0);
894
- bytes[31] = n;
895
- return (0, utils_1.addressFromContractId)((0, utils_1.binToHex)(bytes));
896
- }
897
- exports.CreateContractEventAddress = specialContractAddress(-1);
898
- exports.DestroyContractEventAddress = specialContractAddress(-2);
899
- function decodeSystemEvent(event, systemEventSig, eventIndex) {
900
- if (event.eventIndex !== eventIndex) {
901
- throw new Error(`Invalid event index: ${event.eventIndex}, expected: ${eventIndex}`);
902
- }
903
- return fromApiSystemEventFields(event.fields, systemEventSig);
904
- }
905
- function decodeContractCreatedEvent(event) {
906
- const fields = decodeSystemEvent(event, Contract.ContractCreatedEvent, Contract.ContractCreatedEventIndex);
907
- return {
908
- blockHash: event.blockHash,
909
- txId: event.txId,
910
- eventIndex: event.eventIndex,
911
- name: Contract.ContractCreatedEvent.name,
912
- fields: {
913
- address: fields['address'],
914
- parentAddress: fields['parentAddress'] === undefined ? undefined : fields['parentAddress']
915
- }
916
- };
917
- }
918
- exports.decodeContractCreatedEvent = decodeContractCreatedEvent;
919
- function decodeContractDestroyedEvent(event) {
920
- const fields = decodeSystemEvent(event, Contract.ContractDestroyedEvent, Contract.ContractDestroyedEventIndex);
921
- return {
922
- blockHash: event.blockHash,
923
- txId: event.txId,
924
- eventIndex: event.eventIndex,
925
- name: Contract.ContractDestroyedEvent.name,
926
- fields: { address: fields['address'] }
927
- };
928
- }
929
- exports.decodeContractDestroyedEvent = decodeContractDestroyedEvent;
930
- function subscribeEventsFromContract(options, address, eventIndex, decodeFunc, fromCount) {
931
- const messageCallback = (event) => {
932
- if (event.eventIndex !== eventIndex) {
933
- return Promise.resolve();
934
- }
935
- return options.messageCallback(decodeFunc(event));
936
- };
937
- const errorCallback = (err, subscription) => {
938
- return options.errorCallback(err, subscription);
939
- };
940
- const opt = {
941
- pollingInterval: options.pollingInterval,
942
- messageCallback: messageCallback,
943
- errorCallback: errorCallback
944
- };
945
- return (0, events_1.subscribeToEvents)(opt, address, fromCount);
946
- }
947
- exports.subscribeEventsFromContract = subscribeEventsFromContract;
948
- async function testMethod(contract, methodName, params) {
949
- const txId = params?.txId ?? randomTxId();
950
- const apiParams = contract.contract.toApiTestContractParams(methodName, {
951
- ...params,
952
- txId: txId,
953
- initialFields: params.initialFields === undefined ? {} : params.initialFields,
954
- testArgs: params.testArgs === undefined ? {} : params.testArgs
955
- });
956
- const apiResult = await (0, global_1.getCurrentNodeProvider)().contracts.postContractsTestContract(apiParams);
957
- const testResult = contract.contract.fromApiTestContractResult(methodName, apiResult, txId);
958
- contract.contract.printDebugMessages(methodName, testResult.debugMessages);
959
- return testResult;
960
- }
961
- exports.testMethod = testMethod;
962
- class ContractInstance {
963
- constructor(address) {
964
- this.address = address;
965
- this.contractId = (0, utils_1.binToHex)((0, utils_1.contractIdFromAddress)(address));
966
- this.groupIndex = (0, utils_1.groupOfAddress)(address);
967
- }
968
- }
969
- exports.ContractInstance = ContractInstance;
970
- async function fetchContractState(contract, instance) {
971
- const contractState = await (0, global_1.getCurrentNodeProvider)().contracts.getContractsAddressState(instance.address, {
972
- group: instance.groupIndex
973
- });
974
- const state = contract.contract.fromApiContractState(contractState);
975
- return {
976
- ...state,
977
- fields: state.fields
978
- };
979
- }
980
- exports.fetchContractState = fetchContractState;
981
- function subscribeContractCreatedEvent(options, fromCount) {
982
- return subscribeEventsFromContract(options, exports.CreateContractEventAddress, Contract.ContractCreatedEventIndex, (event) => {
983
- return {
984
- ...decodeContractCreatedEvent(event),
985
- contractAddress: exports.CreateContractEventAddress
986
- };
987
- }, fromCount);
988
- }
989
- exports.subscribeContractCreatedEvent = subscribeContractCreatedEvent;
990
- function subscribeContractDestroyedEvent(options, fromCount) {
991
- return subscribeEventsFromContract(options, exports.DestroyContractEventAddress, Contract.ContractDestroyedEventIndex, (event) => {
992
- return {
993
- ...decodeContractDestroyedEvent(event),
994
- contractAddress: exports.DestroyContractEventAddress
995
- };
996
- }, fromCount);
997
- }
998
- exports.subscribeContractDestroyedEvent = subscribeContractDestroyedEvent;
999
- function decodeEvent(contract, instance, event, targetEventIndex) {
1000
- if (event.eventIndex !== targetEventIndex &&
1001
- !(targetEventIndex >= 0 && targetEventIndex < contract.eventsSig.length)) {
1002
- throw new Error('Invalid event index: ' + event.eventIndex + ', expected: ' + targetEventIndex);
1003
- }
1004
- const eventSig = contract.eventsSig[`${targetEventIndex}`];
1005
- const fieldNames = eventSig.fieldNames;
1006
- const fieldTypes = eventSig.fieldTypes;
1007
- const fields = (0, api_1.fromApiVals)(event.fields, fieldNames, fieldTypes);
1008
- return {
1009
- contractAddress: instance.address,
1010
- blockHash: event.blockHash,
1011
- txId: event.txId,
1012
- eventIndex: event.eventIndex,
1013
- name: eventSig.name,
1014
- fields: fields
1015
- };
1016
- }
1017
- exports.decodeEvent = decodeEvent;
1018
- function subscribeContractEvent(contract, instance, options, eventName, fromCount) {
1019
- const eventIndex = contract.eventsSig.findIndex((sig) => sig.name === eventName);
1020
- return subscribeEventsFromContract(options, instance.address, eventIndex, (event) => decodeEvent(contract, instance, event, eventIndex), fromCount);
1021
- }
1022
- exports.subscribeContractEvent = subscribeContractEvent;
1023
- function subscribeContractEvents(contract, instance, options, fromCount) {
1024
- const messageCallback = (event) => {
1025
- return options.messageCallback({
1026
- ...decodeEvent(contract, instance, event, event.eventIndex),
1027
- contractAddress: instance.address
1028
- });
1029
- };
1030
- const errorCallback = (err, subscription) => {
1031
- return options.errorCallback(err, subscription);
1032
- };
1033
- const opt = {
1034
- pollingInterval: options.pollingInterval,
1035
- messageCallback: messageCallback,
1036
- errorCallback: errorCallback
1037
- };
1038
- return (0, events_1.subscribeToEvents)(opt, instance.address, fromCount);
1039
- }
1040
- exports.subscribeContractEvents = subscribeContractEvents;
1041
- async function callMethod(contract, instance, methodName, params) {
1042
- const methodIndex = contract.contract.getMethodIndex(methodName);
1043
- const txId = params?.txId ?? randomTxId();
1044
- const callParams = contract.contract.toApiCallContract({ ...params, txId: txId, args: params.args === undefined ? {} : params.args }, instance.groupIndex, instance.address, methodIndex);
1045
- const result = await (0, global_1.getCurrentNodeProvider)().contracts.postContractsCallContract(callParams);
1046
- const callResult = contract.contract.fromApiCallContractResult(result, txId, methodIndex);
1047
- return callResult;
1048
- }
1049
- exports.callMethod = callMethod;
1050
- async function multicallMethods(contract, instance, calls) {
1051
- const callEntries = Object.entries(calls);
1052
- const callsParams = callEntries.map((entry) => {
1053
- const [methodName, params] = entry;
1054
- const methodIndex = contract.contract.getMethodIndex(methodName);
1055
- const txId = params?.txId ?? randomTxId();
1056
- return contract.contract.toApiCallContract({ ...params, txId: txId, args: params.args === undefined ? {} : params.args }, instance.groupIndex, instance.address, methodIndex);
1057
- });
1058
- const result = await (0, global_1.getCurrentNodeProvider)().contracts.postContractsMulticallContract({ calls: callsParams });
1059
- const callsResult = {};
1060
- callsParams.forEach((call, index) => {
1061
- const methodIndex = call.methodIndex;
1062
- const callResult = result.results[`${methodIndex}`];
1063
- const methodName = callEntries[`${index}`][`0`];
1064
- callsResult[`${methodName}`] = contract.contract.fromApiCallContractResult(callResult, call.txId, methodIndex);
1065
- });
1066
- return callsResult;
1067
- }
1068
- exports.multicallMethods = multicallMethods;
1069
- async function getContractEventsCurrentCount(contractAddress) {
1070
- return (0, global_1.getCurrentNodeProvider)()
1071
- .events.getEventsContractContractaddressCurrentCount(contractAddress)
1072
- .catch((error) => {
1073
- if (error instanceof Error && error.message.includes(`${contractAddress} not found`)) {
1074
- return 0;
1075
- }
1076
- throw error;
1077
- });
1078
- }
1079
- exports.getContractEventsCurrentCount = getContractEventsCurrentCount;