@alephium/web3 0.9.0-rc.0 → 0.9.0-rc.1

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