@alephium/web3 0.2.0-rc.0 → 0.2.0-rc.11

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 (98) hide show
  1. package/.eslintignore +2 -2
  2. package/README.md +2 -135
  3. package/contracts/greeter/greeter.ral +3 -3
  4. package/contracts/greeter/greeter_interface.ral +1 -0
  5. package/contracts/greeter_main.ral +3 -5
  6. package/dist/alephium-web3.min.js +1 -1
  7. package/dist/alephium-web3.min.js.LICENSE.txt +0 -17
  8. package/dist/alephium-web3.min.js.map +1 -1
  9. package/dist/scripts/create-project.js +3 -2
  10. package/dist/src/api/api-alephium.d.ts +46 -13
  11. package/dist/src/api/api-alephium.js +19 -3
  12. package/dist/src/api/api-explorer.d.ts +32 -16
  13. package/dist/src/api/api-explorer.js +26 -0
  14. package/dist/src/api/index.d.ts +3 -2
  15. package/dist/src/api/index.js +22 -3
  16. package/dist/src/api/types.d.ts +23 -0
  17. package/dist/src/api/types.js +240 -0
  18. package/dist/src/contract/contract.d.ts +104 -64
  19. package/dist/src/contract/contract.js +370 -426
  20. package/dist/src/contract/events.d.ts +4 -4
  21. package/dist/src/contract/index.js +5 -1
  22. package/dist/src/contract/ralph.d.ts +4 -4
  23. package/dist/src/global.d.ts +4 -0
  24. package/dist/src/global.js +38 -0
  25. package/dist/src/index.d.ts +2 -0
  26. package/dist/src/index.js +20 -1
  27. package/dist/src/signer/index.d.ts +0 -1
  28. package/dist/src/signer/index.js +5 -2
  29. package/dist/src/signer/signer.d.ts +21 -11
  30. package/dist/src/signer/signer.js +46 -9
  31. package/dist/src/transaction/index.d.ts +0 -1
  32. package/dist/src/transaction/index.js +5 -2
  33. package/dist/src/transaction/status.d.ts +2 -1
  34. package/dist/src/utils/index.d.ts +0 -1
  35. package/dist/src/utils/index.js +5 -2
  36. package/dist/src/utils/subscription.d.ts +0 -1
  37. package/dist/src/utils/subscription.js +2 -1
  38. package/dist/src/utils/utils.d.ts +5 -4
  39. package/dist/src/utils/utils.js +18 -17
  40. package/jest-config.json +11 -0
  41. package/package.json +7 -35
  42. package/scripts/create-project.ts +3 -2
  43. package/src/api/api-alephium.ts +56 -8
  44. package/src/api/api-explorer.ts +30 -0
  45. package/src/api/index.ts +14 -3
  46. package/src/api/types.ts +233 -0
  47. package/src/contract/contract.ts +537 -526
  48. package/src/contract/events.ts +6 -6
  49. package/src/contract/ralph.ts +4 -4
  50. package/src/{transaction/sign-verify.ts → global.ts} +14 -15
  51. package/src/index.ts +3 -0
  52. package/src/signer/index.ts +0 -1
  53. package/src/signer/signer.ts +70 -19
  54. package/src/transaction/index.ts +0 -1
  55. package/src/transaction/status.ts +4 -2
  56. package/src/utils/index.ts +0 -1
  57. package/src/utils/subscription.ts +3 -3
  58. package/src/utils/utils.ts +11 -11
  59. package/templates/base/package.json +2 -2
  60. package/templates/base/src/greeter.ts +10 -9
  61. package/templates/react/package.json +2 -2
  62. package/templates/react/src/App.tsx +2 -2
  63. package/.eslintrc.json +0 -21
  64. package/LICENSE +0 -165
  65. package/contracts/add/add.ral +0 -16
  66. package/contracts/main.ral +0 -6
  67. package/contracts/sub/sub.ral +0 -9
  68. package/dist/src/signer/node-wallet.d.ts +0 -13
  69. package/dist/src/signer/node-wallet.js +0 -60
  70. package/dist/src/test/index.d.ts +0 -7
  71. package/dist/src/test/index.js +0 -41
  72. package/dist/src/test/privatekey-wallet.d.ts +0 -12
  73. package/dist/src/test/privatekey-wallet.js +0 -68
  74. package/dist/src/transaction/sign-verify.d.ts +0 -2
  75. package/dist/src/transaction/sign-verify.js +0 -58
  76. package/dist/src/utils/password-crypto.d.ts +0 -2
  77. package/dist/src/utils/password-crypto.js +0 -69
  78. package/gitignore +0 -10
  79. package/src/contract/ralph.test.ts +0 -178
  80. package/src/fixtures/address.json +0 -36
  81. package/src/fixtures/balance.json +0 -9
  82. package/src/fixtures/self-clique.json +0 -19
  83. package/src/fixtures/transaction.json +0 -13
  84. package/src/fixtures/transactions.json +0 -179
  85. package/src/signer/fixtures/genesis.json +0 -26
  86. package/src/signer/fixtures/wallets.json +0 -26
  87. package/src/signer/node-wallet.ts +0 -74
  88. package/src/test/index.ts +0 -32
  89. package/src/test/privatekey-wallet.ts +0 -58
  90. package/src/transaction/sign-verify.test.ts +0 -50
  91. package/src/utils/address.test.ts +0 -47
  92. package/src/utils/djb2.test.ts +0 -35
  93. package/src/utils/password-crypto.test.ts +0 -27
  94. package/src/utils/password-crypto.ts +0 -77
  95. package/src/utils/utils.test.ts +0 -161
  96. package/test/contract.test.ts +0 -178
  97. package/test/events.test.ts +0 -138
  98. package/test/transaction.test.ts +0 -72
@@ -18,7 +18,11 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
18
18
  */
19
19
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
20
20
  if (k2 === undefined) k2 = k;
21
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[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);
22
26
  }) : (function(o, m, k, k2) {
23
27
  if (k2 === undefined) k2 = k;
24
28
  o[k2] = m[k];
@@ -39,178 +43,356 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
39
43
  return (mod && mod.__esModule) ? mod : { "default": mod };
40
44
  };
41
45
  Object.defineProperty(exports, "__esModule", { value: true });
42
- exports.toApiVal = exports.extractArray = exports.Script = exports.Contract = exports.Common = void 0;
46
+ exports.Script = exports.Contract = exports.Artifact = exports.Project = exports.DEFAULT_COMPILER_OPTIONS = exports.DEFAULT_NODE_COMPILER_OPTIONS = void 0;
43
47
  const buffer_1 = require("buffer/");
44
- const cryptojs = __importStar(require("crypto-js"));
45
- const crypto = __importStar(require("crypto"));
48
+ const crypto_1 = require("crypto");
46
49
  const fs_1 = __importDefault(require("fs"));
47
50
  const fs_2 = require("fs");
51
+ const api_1 = require("../api");
48
52
  const ralph = __importStar(require("./ralph"));
49
53
  const utils_1 = require("../utils");
54
+ const global_1 = require("../global");
55
+ var SourceType;
56
+ (function (SourceType) {
57
+ SourceType[SourceType["Contract"] = 0] = "Contract";
58
+ SourceType[SourceType["Script"] = 1] = "Script";
59
+ SourceType[SourceType["AbstractContract"] = 2] = "AbstractContract";
60
+ SourceType[SourceType["Interface"] = 3] = "Interface";
61
+ })(SourceType || (SourceType = {}));
62
+ exports.DEFAULT_NODE_COMPILER_OPTIONS = {
63
+ ignoreUnusedConstantsWarnings: false,
64
+ ignoreUnusedVariablesWarnings: false,
65
+ ignoreUnusedFieldsWarnings: false,
66
+ ignoreUnusedPrivateFunctionsWarnings: false,
67
+ ignoreReadonlyCheckWarnings: false,
68
+ ignoreExternalCallCheckWarnings: false
69
+ };
70
+ exports.DEFAULT_COMPILER_OPTIONS = { errorOnWarnings: true, ...exports.DEFAULT_NODE_COMPILER_OPTIONS };
71
+ class TypedMatcher {
72
+ constructor(pattern, type) {
73
+ this.matcher = new RegExp(pattern, 'mg');
74
+ this.type = type;
75
+ }
76
+ match(str) {
77
+ const results = str.match(this.matcher);
78
+ return results === null ? 0 : results.length;
79
+ }
80
+ }
50
81
  class SourceFile {
51
- constructor(dirs, fileName) {
52
- this.dirs = dirs;
53
- this.dirPath = dirs.length === 0 ? '' : dirs.join('/') + '/';
54
- if (fileName.endsWith('.json')) {
55
- this.contractPath = './contracts/' + this.dirPath + fileName.slice(0, -5);
56
- this.artifactPath = './artifacts/' + this.dirPath + fileName;
57
- }
58
- else {
59
- this.contractPath = './contracts/' + this.dirPath + fileName;
60
- this.artifactPath = './artifacts/' + this.dirPath + fileName + '.json';
61
- }
82
+ constructor(type, sourceCode, sourceCodeHash, contractPath) {
83
+ this.type = type;
84
+ this.sourceCode = sourceCode;
85
+ this.sourceCodeHash = sourceCodeHash;
86
+ this.contractPath = contractPath;
87
+ }
88
+ getArtifactPath(artifactsRootPath) {
89
+ return artifactsRootPath + this.contractPath.slice(this.contractPath.indexOf('/')) + '.json';
90
+ }
91
+ static async from(type, sourceCode, contractPath) {
92
+ const sourceCodeHash = await crypto_1.webcrypto.subtle.digest('SHA-256', buffer_1.Buffer.from(sourceCode));
93
+ return new SourceFile(type, sourceCode, buffer_1.Buffer.from(sourceCodeHash).toString('hex'), contractPath);
62
94
  }
63
95
  }
64
- class Common {
65
- constructor(sourceCodeSha256, functions) {
66
- this.sourceCodeSha256 = sourceCodeSha256;
67
- this.functions = functions;
96
+ class Compiled {
97
+ constructor(sourceFile, artifact, warnings) {
98
+ this.sourceFile = sourceFile;
99
+ this.artifact = artifact;
100
+ this.warnings = warnings;
68
101
  }
69
- static _getArtifactFromCache(codeHash) {
70
- return this._artifactCache.get(codeHash);
102
+ }
103
+ class ProjectArtifact {
104
+ constructor(compilerOptionsUsed, infos) {
105
+ ProjectArtifact.checkCompilerOptionsParameter(compilerOptionsUsed);
106
+ this.compilerOptionsUsed = compilerOptionsUsed;
107
+ this.infos = infos;
71
108
  }
72
- static _putArtifactToCache(contract) {
73
- if (!this._artifactCache.has(contract.codeHash)) {
74
- if (this._artifactCache.size >= this.artifactCacheCapacity) {
75
- const keyToDelete = this._artifactCache.keys().next().value;
76
- this._artifactCache.delete(keyToDelete);
77
- }
78
- this._artifactCache.set(contract.codeHash, contract);
109
+ static checkCompilerOptionsParameter(compilerOptions) {
110
+ if (Object.keys(compilerOptions).length != Object.keys(exports.DEFAULT_NODE_COMPILER_OPTIONS).length) {
111
+ throw Error(`Not all compiler options are set: ${compilerOptions}`);
112
+ }
113
+ const combined = { ...compilerOptions, ...exports.DEFAULT_NODE_COMPILER_OPTIONS };
114
+ if (Object.keys(combined).length !== Object.keys(exports.DEFAULT_NODE_COMPILER_OPTIONS).length) {
115
+ throw Error(`There are unknown compiler options: ${compilerOptions}`);
79
116
  }
80
117
  }
81
- static _artifactsFolder() {
82
- return './artifacts/';
118
+ async saveToFile(rootPath) {
119
+ const filepath = rootPath + '/' + ProjectArtifact.artifactFileName;
120
+ const artifact = { compilerOptionsUsed: this.compilerOptionsUsed, infos: Object.fromEntries(this.infos) };
121
+ const content = JSON.stringify(artifact, null, 2);
122
+ return fs_2.promises.writeFile(filepath, content);
83
123
  }
84
- static getSourceFile(path, _dirs) {
85
- const parts = path.split('/');
86
- const dirs = Array.from(_dirs);
87
- if (parts.length === 1) {
88
- return new SourceFile(dirs, path);
124
+ needToReCompile(compilerOptions, files) {
125
+ ProjectArtifact.checkCompilerOptionsParameter(compilerOptions);
126
+ const optionsMatched = Object.entries(compilerOptions).every(([key, inputOption]) => {
127
+ const usedOption = this.compilerOptionsUsed[`${key}`];
128
+ return usedOption === inputOption;
129
+ });
130
+ if (!optionsMatched) {
131
+ return true;
89
132
  }
90
- parts.slice(0, parts.length - 1).forEach((part) => {
91
- switch (part) {
92
- case '.': {
93
- break;
94
- }
95
- case '..': {
96
- if (dirs.length === 0) {
97
- throw new Error('Invalid file path: ' + path);
98
- }
99
- dirs.pop();
100
- break;
101
- }
102
- default: {
103
- dirs.push(part);
104
- }
133
+ if (files.length !== this.infos.size) {
134
+ return true;
135
+ }
136
+ for (const file of files) {
137
+ const info = this.infos.get(file.contractPath);
138
+ if (typeof info === 'undefined' || info.sourceCodeHash !== file.sourceCodeHash) {
139
+ return true;
105
140
  }
141
+ }
142
+ return false;
143
+ }
144
+ static async from(rootPath) {
145
+ const filepath = rootPath + '/' + ProjectArtifact.artifactFileName;
146
+ if (!fs_1.default.existsSync(filepath)) {
147
+ return undefined;
148
+ }
149
+ const content = await fs_2.promises.readFile(filepath);
150
+ const json = JSON.parse(content.toString());
151
+ const compilerOptionsUsed = json.compilerOptionsUsed;
152
+ const files = new Map(Object.entries(json.infos));
153
+ return new ProjectArtifact(compilerOptionsUsed, files);
154
+ }
155
+ }
156
+ ProjectArtifact.artifactFileName = '.project.json';
157
+ class Project {
158
+ constructor(provider, contractsRootPath, artifactsRootPath, sourceFiles, contracts, scripts, errorOnWarnings, projectArtifact) {
159
+ this.nodeProvider = provider;
160
+ this.contractsRootPath = contractsRootPath;
161
+ this.artifactsRootPath = artifactsRootPath;
162
+ this.sourceFiles = sourceFiles;
163
+ this.contracts = contracts;
164
+ this.scripts = scripts;
165
+ this.projectArtifact = projectArtifact;
166
+ if (errorOnWarnings) {
167
+ Project.checkCompilerWarnings([...contracts.map((c) => c.warnings).flat(), ...scripts.map((s) => s.warnings).flat()], errorOnWarnings);
168
+ }
169
+ }
170
+ static buildProjectArtifact(sourceFiles, contracts, scripts, compilerOptions) {
171
+ const files = new Map();
172
+ contracts.forEach((c) => {
173
+ files.set(c.sourceFile.contractPath, {
174
+ sourceCodeHash: c.sourceFile.sourceCodeHash,
175
+ warnings: c.warnings
176
+ });
106
177
  });
107
- return new SourceFile(dirs, parts[parts.length - 1]);
108
- }
109
- static async _handleImports(pathes, contractStr, importsCache) {
110
- const localImportsCache = [];
111
- let result = contractStr.replace(Common.importRegex, (match) => {
112
- localImportsCache.push(match);
113
- return '';
178
+ scripts.forEach((s) => {
179
+ files.set(s.sourceFile.contractPath, {
180
+ sourceCodeHash: s.sourceFile.sourceCodeHash,
181
+ warnings: s.warnings
182
+ });
114
183
  });
115
- for (const myImport of localImportsCache) {
116
- const relativePath = myImport.slice(8, -1);
117
- const importSourceFile = this.getSourceFile(relativePath, pathes);
118
- if (!importsCache.includes(importSourceFile.contractPath)) {
119
- importsCache.push(importSourceFile.contractPath);
120
- const importContractStr = await Common._loadContractStr(importSourceFile, importsCache, (code) => Contract.checkCodeType(importSourceFile.contractPath, code));
121
- result = result.concat('\n', importContractStr);
184
+ const compiledSize = contracts.length + scripts.length;
185
+ sourceFiles.slice(compiledSize).forEach((c) => {
186
+ files.set(c.contractPath, {
187
+ sourceCodeHash: c.sourceCodeHash,
188
+ warnings: []
189
+ });
190
+ });
191
+ return new ProjectArtifact(compilerOptions, files);
192
+ }
193
+ getContractPath(path) {
194
+ return path.startsWith(`./${this.contractsRootPath}`)
195
+ ? path.slice(2)
196
+ : path.startsWith(this.contractsRootPath)
197
+ ? path
198
+ : this.contractsRootPath + '/' + path;
199
+ }
200
+ static checkCompilerWarnings(warnings, errorOnWarnings) {
201
+ if (warnings.length !== 0) {
202
+ const prefixPerWarning = ' - ';
203
+ const warningString = prefixPerWarning + warnings.join('\n' + prefixPerWarning);
204
+ const output = `Compilation warnings:\n` + warningString + '\n';
205
+ if (errorOnWarnings) {
206
+ throw new Error(output);
207
+ }
208
+ else {
209
+ console.log(output);
122
210
  }
123
211
  }
124
- return result;
125
212
  }
126
- static async _loadContractStr(sourceFile, importsCache, validate) {
127
- const contractPath = sourceFile.contractPath;
128
- const contractBuffer = await fs_2.promises.readFile(contractPath);
129
- const contractStr = contractBuffer.toString();
130
- validate(contractStr);
131
- return Common._handleImports(sourceFile.dirs, contractStr, importsCache);
213
+ static contract(name) {
214
+ const contract = Project.currentProject.contracts.find((c) => c.artifact.name === name);
215
+ if (typeof contract === 'undefined') {
216
+ throw new Error(`Contract "${name}" does not exist`);
217
+ }
218
+ return contract.artifact;
132
219
  }
133
- static checkFileNameExtension(fileName) {
134
- if (!fileName.endsWith('.ral')) {
135
- throw new Error('Smart contract file name should end with ".ral"');
220
+ static script(name) {
221
+ const script = Project.currentProject.scripts.find((c) => c.artifact.name === name);
222
+ if (typeof script === 'undefined') {
223
+ throw new Error(`Script "${name}" does not exist`);
136
224
  }
225
+ return script.artifact;
137
226
  }
138
- static async _from(provider, sourceFile, loadContractStr, compile) {
139
- Common.checkFileNameExtension(sourceFile.contractPath);
140
- const contractStr = await loadContractStr(sourceFile, []);
141
- const contractHash = cryptojs.SHA256(contractStr).toString();
142
- const existingContract = this._getArtifactFromCache(contractHash);
143
- if (typeof existingContract !== 'undefined') {
144
- return existingContract;
227
+ async saveArtifactsToFile() {
228
+ const artifactsRootPath = this.artifactsRootPath;
229
+ const saveToFile = async function (compiled) {
230
+ const artifactPath = compiled.sourceFile.getArtifactPath(artifactsRootPath);
231
+ const folder = artifactPath.slice(0, artifactPath.lastIndexOf('/'));
232
+ if (!fs_1.default.existsSync(folder)) {
233
+ fs_1.default.mkdirSync(folder, { recursive: true });
234
+ }
235
+ return fs_2.promises.writeFile(artifactPath, compiled.artifact.toString());
236
+ };
237
+ for (const contract of this.contracts) {
238
+ await saveToFile(contract);
145
239
  }
146
- else {
147
- return compile(provider, sourceFile, contractStr, contractHash);
240
+ for (const script of this.scripts) {
241
+ await saveToFile(script);
148
242
  }
243
+ await this.projectArtifact.saveToFile(this.artifactsRootPath);
149
244
  }
150
- _saveToFile(sourceFile) {
151
- const folder = Common._artifactsFolder() + sourceFile.dirPath;
152
- if (!fs_1.default.existsSync(folder)) {
153
- fs_1.default.mkdirSync(folder, { recursive: true });
245
+ contractByCodeHash(codeHash) {
246
+ const contract = this.contracts.find((c) => c.artifact.codeHash === codeHash);
247
+ if (typeof contract === 'undefined') {
248
+ throw new Error(`Unknown code with code hash: ${codeHash}`);
154
249
  }
155
- return fs_2.promises.writeFile(sourceFile.artifactPath, this.toString());
250
+ return contract.artifact;
156
251
  }
157
- }
158
- exports.Common = Common;
159
- Common.importRegex = new RegExp('^import "([^"/]+/(([^"]+)/)?)?[a-z][a-z_0-9]*.ral"', 'mg');
160
- Common.contractRegex = new RegExp('^TxContract [A-Z][a-zA-Z0-9]*', 'mg');
161
- Common.interfaceRegex = new RegExp('^Interface [A-Z][a-zA-Z0-9]* \\{', 'mg');
162
- Common.scriptRegex = new RegExp('^TxScript [A-Z][a-zA-Z0-9]*', 'mg');
163
- Common._artifactCache = new Map();
164
- Common.artifactCacheCapacity = 20;
165
- class Contract extends Common {
166
- constructor(sourceCodeSha256, bytecode, codeHash, fieldsSig, eventsSig, functions) {
167
- super(sourceCodeSha256, functions);
168
- this.bytecode = bytecode;
169
- this.codeHash = codeHash;
170
- this.fieldsSig = fieldsSig;
171
- this.eventsSig = eventsSig;
252
+ static async compile(provider, files, contractsRootPath, artifactsRootPath, errorOnWarnings, compilerOptions) {
253
+ const sourceStr = files.map((f) => f.sourceCode).join('\n');
254
+ const result = await provider.contracts.postContractsCompileProject({
255
+ code: sourceStr,
256
+ compilerOptions: compilerOptions
257
+ });
258
+ const contracts = [];
259
+ const scripts = [];
260
+ result.contracts.forEach((contractResult, index) => {
261
+ const sourceFile = files[`${index}`];
262
+ const contract = Contract.fromCompileResult(contractResult);
263
+ contracts.push(new Compiled(sourceFile, contract, contractResult.warnings));
264
+ });
265
+ result.scripts.forEach((scriptResult, index) => {
266
+ const sourceFile = files[index + contracts.length];
267
+ const script = Script.fromCompileResult(scriptResult);
268
+ scripts.push(new Compiled(sourceFile, script, scriptResult.warnings));
269
+ });
270
+ const projectArtifact = Project.buildProjectArtifact(files, contracts, scripts, compilerOptions);
271
+ const project = new Project(provider, contractsRootPath, artifactsRootPath, files, contracts, scripts, errorOnWarnings, projectArtifact);
272
+ await project.saveArtifactsToFile();
273
+ return project;
172
274
  }
173
- static checkCodeType(fileName, contractStr) {
174
- const interfaceMatches = contractStr.match(Contract.interfaceRegex);
175
- const contractMatches = contractStr.match(Contract.contractRegex);
176
- if (interfaceMatches === null && contractMatches === null) {
177
- throw new Error(`No contract found in: ${fileName}`);
178
- }
179
- if (interfaceMatches && contractMatches) {
180
- throw new Error(`Multiple contracts and interfaces in: ${fileName}`);
181
- }
182
- if (interfaceMatches === null) {
183
- if (contractMatches !== null && contractMatches.length > 1) {
184
- throw new Error(`Multiple contracts in: ${fileName}`);
275
+ static async loadArtifacts(provider, files, projectArtifact, contractsRootPath, artifactsRootPath, errorOnWarnings, compilerOptions) {
276
+ try {
277
+ const contracts = [];
278
+ const scripts = [];
279
+ for (const file of files) {
280
+ const info = projectArtifact.infos.get(file.contractPath);
281
+ if (typeof info === 'undefined') {
282
+ throw Error(`Unable to find project info for ${file.contractPath}, please rebuild the project`);
283
+ }
284
+ const warnings = info.warnings;
285
+ const artifactPath = file.getArtifactPath(artifactsRootPath);
286
+ if (file.type === SourceType.Contract) {
287
+ const artifact = await Contract.fromArtifactFile(artifactPath);
288
+ contracts.push(new Compiled(file, artifact, warnings));
289
+ }
290
+ else if (file.type === SourceType.Script) {
291
+ const artifact = await Script.fromArtifactFile(artifactPath);
292
+ scripts.push(new Compiled(file, artifact, warnings));
293
+ }
185
294
  }
295
+ return new Project(provider, contractsRootPath, artifactsRootPath, files, contracts, scripts, errorOnWarnings, projectArtifact);
186
296
  }
187
- if (contractMatches === null) {
188
- if (interfaceMatches !== null && interfaceMatches.length > 1) {
189
- throw new Error(`Multiple interfaces in: ${fileName}`);
297
+ catch (error) {
298
+ console.log(`Failed to load artifacts, error: ${error}, try to re-compile contracts...`);
299
+ return Project.compile(provider, files, contractsRootPath, artifactsRootPath, errorOnWarnings, compilerOptions);
300
+ }
301
+ }
302
+ static async loadSourceFile(dirPath, filename) {
303
+ const contractPath = dirPath + '/' + filename;
304
+ if (!filename.endsWith('.ral')) {
305
+ throw new Error(`Invalid filename: ${contractPath}, smart contract file name should end with ".ral"`);
306
+ }
307
+ const sourceBuffer = await fs_2.promises.readFile(contractPath);
308
+ const sourceStr = sourceBuffer.toString();
309
+ const results = this.matchers.map((m) => m.match(sourceStr));
310
+ const matchNumber = results.reduce((a, b) => a + b, 0);
311
+ if (matchNumber === 0) {
312
+ throw new Error(`No contract defined in file: ${contractPath}`);
313
+ }
314
+ if (matchNumber > 1) {
315
+ throw new Error(`Multiple definitions in file: ${contractPath}`);
316
+ }
317
+ const matcherIndex = results.indexOf(1);
318
+ const type = this.matchers[`${matcherIndex}`].type;
319
+ return SourceFile.from(type, sourceStr, contractPath);
320
+ }
321
+ static async loadSourceFiles(contractsRootPath) {
322
+ const loadDir = async function (dirPath, results) {
323
+ const dirents = await fs_2.promises.readdir(dirPath, { withFileTypes: true });
324
+ for (const dirent of dirents) {
325
+ if (dirent.isFile()) {
326
+ const file = await Project.loadSourceFile(dirPath, dirent.name);
327
+ results.push(file);
328
+ }
329
+ else {
330
+ const newPath = dirPath + '/' + dirent.name;
331
+ await loadDir(newPath, results);
332
+ }
190
333
  }
334
+ };
335
+ const sourceFiles = [];
336
+ await loadDir(contractsRootPath, sourceFiles);
337
+ const contractAndScriptSize = sourceFiles.filter((f) => f.type === SourceType.Contract || f.type === SourceType.Script).length;
338
+ if (sourceFiles.length === 0 || contractAndScriptSize === 0) {
339
+ throw new Error('Project have no source files');
340
+ }
341
+ return sourceFiles.sort((a, b) => a.type - b.type);
342
+ }
343
+ static async build(compilerOptionsPartial = {}, contractsRootPath = 'contracts', artifactsRootPath = 'artifacts') {
344
+ const provider = (0, global_1.getCurrentNodeProvider)();
345
+ const sourceFiles = await Project.loadSourceFiles(contractsRootPath);
346
+ const { errorOnWarnings, ...nodeCompilerOptions } = { ...exports.DEFAULT_COMPILER_OPTIONS, ...compilerOptionsPartial };
347
+ const projectArtifact = await ProjectArtifact.from(artifactsRootPath);
348
+ if (typeof projectArtifact === 'undefined' || projectArtifact.needToReCompile(nodeCompilerOptions, sourceFiles)) {
349
+ console.log(`Compile contracts in folder "${contractsRootPath}"`);
350
+ Project.currentProject = await Project.compile(provider, sourceFiles, contractsRootPath, artifactsRootPath, errorOnWarnings, nodeCompilerOptions);
191
351
  }
352
+ else {
353
+ console.log(`Load compiled contracts from folder "${artifactsRootPath}"`);
354
+ Project.currentProject = await Project.loadArtifacts(provider, sourceFiles, projectArtifact, contractsRootPath, artifactsRootPath, errorOnWarnings, nodeCompilerOptions);
355
+ }
356
+ }
357
+ }
358
+ exports.Project = Project;
359
+ Project.abstractContractMatcher = new TypedMatcher('^Abstract Contract [A-Z][a-zA-Z0-9]*', SourceType.AbstractContract);
360
+ Project.contractMatcher = new TypedMatcher('^Contract [A-Z][a-zA-Z0-9]*', SourceType.Contract);
361
+ Project.interfaceMatcher = new TypedMatcher('^Interface [A-Z][a-zA-Z0-9]* \\{', SourceType.Interface);
362
+ Project.scriptMatcher = new TypedMatcher('^TxScript [A-Z][a-zA-Z0-9]*', SourceType.Script);
363
+ Project.matchers = [
364
+ Project.abstractContractMatcher,
365
+ Project.contractMatcher,
366
+ Project.interfaceMatcher,
367
+ Project.scriptMatcher
368
+ ];
369
+ class Artifact {
370
+ constructor(name, functions) {
371
+ this.name = name;
372
+ this.functions = functions;
192
373
  }
193
- static async loadContractStr(sourceFile) {
194
- return Common._loadContractStr(sourceFile, [], (code) => Contract.checkCodeType(sourceFile.contractPath, code));
374
+ publicFunctions() {
375
+ return this.functions.filter((func) => func.isPublic).map((func) => func.name);
195
376
  }
196
- static async fromSource(provider, path) {
197
- if (!fs_1.default.existsSync(Common._artifactsFolder())) {
198
- fs_1.default.mkdirSync(Common._artifactsFolder(), { recursive: true });
199
- }
200
- const sourceFile = this.getSourceFile(path, []);
201
- const contract = await Common._from(provider, sourceFile, (sourceFile) => Contract.loadContractStr(sourceFile), Contract.compile);
202
- this._putArtifactToCache(contract);
203
- return contract;
377
+ usingPreapprovedAssetsFunctions() {
378
+ return this.functions.filter((func) => func.usePreapprovedAssets).map((func) => func.name);
204
379
  }
205
- static async compile(provider, sourceFile, contractStr, contractHash) {
206
- const compiled = await provider.contracts.postContractsCompileContract({ code: contractStr });
207
- const artifact = new Contract(contractHash, compiled.bytecode, compiled.codeHash, compiled.fields, compiled.events, compiled.functions);
208
- await artifact._saveToFile(sourceFile);
209
- return artifact;
380
+ usingAssetsInContractFunctions() {
381
+ return this.functions.filter((func) => func.useAssetsInContract).map((func) => func.name);
382
+ }
383
+ }
384
+ exports.Artifact = Artifact;
385
+ class Contract extends Artifact {
386
+ constructor(name, bytecode, codeHash, fieldsSig, eventsSig, functions) {
387
+ super(name, functions);
388
+ this.bytecode = bytecode;
389
+ this.codeHash = codeHash;
390
+ this.fieldsSig = fieldsSig;
391
+ this.eventsSig = eventsSig;
210
392
  }
211
393
  // TODO: safely parse json
212
394
  static fromJson(artifact) {
213
- if (artifact.sourceCodeSha256 == null ||
395
+ if (artifact.name == null ||
214
396
  artifact.bytecode == null ||
215
397
  artifact.codeHash == null ||
216
398
  artifact.fieldsSig == null ||
@@ -218,31 +400,34 @@ class Contract extends Common {
218
400
  artifact.functions == null) {
219
401
  throw Error('The artifact JSON for contract is incomplete');
220
402
  }
221
- const contract = new Contract(artifact.sourceCodeSha256, artifact.bytecode, artifact.codeHash, artifact.fieldsSig, artifact.eventsSig, artifact.functions);
222
- this._putArtifactToCache(contract);
403
+ const contract = new Contract(artifact.name, artifact.bytecode, artifact.codeHash, artifact.fieldsSig, artifact.eventsSig, artifact.functions);
223
404
  return contract;
224
405
  }
406
+ static fromCompileResult(result) {
407
+ return new Contract(result.name, result.bytecode, result.codeHash, result.fields, result.events, result.functions);
408
+ }
225
409
  // support both 'code.ral' and 'code.ral.json'
226
410
  static async fromArtifactFile(path) {
227
- const sourceFile = this.getSourceFile(path, []);
228
- const artifactPath = sourceFile.artifactPath;
229
- const content = await fs_2.promises.readFile(artifactPath);
411
+ const content = await fs_2.promises.readFile(path);
230
412
  const artifact = JSON.parse(content.toString());
231
413
  return Contract.fromJson(artifact);
232
414
  }
233
- async fetchState(provider, address, group) {
234
- const state = await provider.contracts.getContractsAddressState(address, { group: group });
415
+ async fetchState(address, group) {
416
+ const state = await Project.currentProject.nodeProvider.contracts.getContractsAddressState(address, {
417
+ group: group
418
+ });
235
419
  return this.fromApiContractState(state);
236
420
  }
237
421
  toString() {
238
- return JSON.stringify({
239
- sourceCodeSha256: this.sourceCodeSha256,
422
+ const object = {
423
+ name: this.name,
240
424
  bytecode: this.bytecode,
241
425
  codeHash: this.codeHash,
242
426
  fieldsSig: this.fieldsSig,
243
427
  eventsSig: this.eventsSig,
244
428
  functions: this.functions
245
- }, null, 2);
429
+ };
430
+ return JSON.stringify(object, null, 2);
246
431
  }
247
432
  toState(fields, asset, address) {
248
433
  const addressDef = typeof address !== 'undefined' ? address : Contract.randomAddress();
@@ -256,16 +441,18 @@ class Contract extends Common {
256
441
  asset: asset
257
442
  };
258
443
  }
444
+ // no need to be cryptographically strong random
259
445
  static randomAddress() {
260
- const bytes = crypto.randomBytes(33);
446
+ const bytes = new Uint8Array(33);
447
+ crypto_1.webcrypto.getRandomValues(bytes);
261
448
  bytes[0] = 3;
262
449
  return utils_1.bs58.encode(bytes);
263
450
  }
264
- async _test(provider, funcName, params, expectPublic, accessType) {
451
+ async _test(funcName, params, expectPublic, accessType) {
265
452
  const apiParams = this.toTestContract(funcName, params);
266
- const apiResult = await provider.contracts.postContractsTestContract(apiParams);
453
+ const apiResult = await Project.currentProject.nodeProvider.contracts.postContractsTestContract(apiParams);
267
454
  const methodIndex = typeof params.testMethodIndex !== 'undefined' ? params.testMethodIndex : this.getMethodIndex(funcName);
268
- const isPublic = this.functions[`${methodIndex}`].signature.indexOf('pub ') !== -1;
455
+ const isPublic = this.functions[`${methodIndex}`].isPublic;
269
456
  if (isPublic === expectPublic) {
270
457
  const result = await this.fromTestContractResult(methodIndex, apiResult);
271
458
  return result;
@@ -274,11 +461,11 @@ class Contract extends Common {
274
461
  throw new Error(`The test method ${funcName} is not ${accessType}`);
275
462
  }
276
463
  }
277
- async testPublicMethod(provider, funcName, params) {
278
- return this._test(provider, funcName, params, true, 'public');
464
+ async testPublicMethod(funcName, params) {
465
+ return this._test(funcName, params, true, 'public');
279
466
  }
280
- async testPrivateMethod(provider, funcName, params) {
281
- return this._test(provider, funcName, params, false, 'private');
467
+ async testPrivateMethod(funcName, params) {
468
+ return this._test(funcName, params, false, 'private');
282
469
  }
283
470
  toApiFields(fields) {
284
471
  if (typeof fields === 'undefined') {
@@ -319,30 +506,8 @@ class Contract extends Common {
319
506
  inputAssets: toApiInputAssets(params.inputAssets)
320
507
  };
321
508
  }
322
- static async fromCodeHash(codeHash) {
323
- const cached = this._getArtifactFromCache(codeHash);
324
- if (typeof cached !== 'undefined') {
325
- return cached;
326
- }
327
- const files = await fs_2.promises.readdir(Common._artifactsFolder());
328
- for (const file of files) {
329
- if (file.endsWith('.ral.json')) {
330
- try {
331
- const contract = await Contract.fromArtifactFile(file);
332
- if (contract.codeHash === codeHash) {
333
- return contract;
334
- }
335
- }
336
- catch (_) { }
337
- }
338
- }
339
- throw new Error(`Unknown code with code hash: ${codeHash}`);
340
- }
341
- static async getFieldsSig(state) {
342
- return Contract.fromCodeHash(state.codeHash).then((contract) => contract.fieldsSig);
343
- }
344
509
  async fromApiContractState(state) {
345
- const contract = await Contract.fromCodeHash(state.codeHash);
510
+ const contract = Project.currentProject.contractByCodeHash(state.codeHash);
346
511
  return {
347
512
  address: state.address,
348
513
  contractId: (0, utils_1.binToHex)((0, utils_1.contractIdFromAddress)(state.address)),
@@ -350,7 +515,7 @@ class Contract extends Common {
350
515
  initialStateHash: state.initialStateHash,
351
516
  codeHash: state.codeHash,
352
517
  fields: fromApiFields(state.fields, contract.fieldsSig),
353
- fieldsSig: await Contract.getFieldsSig(state),
518
+ fieldsSig: contract.fieldsSig,
354
519
  asset: fromApiAsset(state.asset)
355
520
  };
356
521
  }
@@ -363,7 +528,7 @@ class Contract extends Common {
363
528
  eventSig = this.ContractDestroyedEvent;
364
529
  }
365
530
  else {
366
- const contract = await Contract.fromCodeHash(codeHash);
531
+ const contract = Project.currentProject.contractByCodeHash(codeHash);
367
532
  eventSig = contract.eventsSig[event.eventIndex];
368
533
  }
369
534
  return {
@@ -380,7 +545,7 @@ class Contract extends Common {
380
545
  return {
381
546
  address: result.address,
382
547
  contractId: (0, utils_1.binToHex)((0, utils_1.contractIdFromAddress)(result.address)),
383
- returns: fromApiArray(result.returns, this.functions[`${methodIndex}`].returnTypes),
548
+ returns: (0, api_1.fromApiArray)(result.returns, this.functions[`${methodIndex}`].returnTypes),
384
549
  gasUsed: result.gasUsed,
385
550
  contracts: await Promise.all(result.contracts.map((contract) => this.fromApiContractState(contract))),
386
551
  txOutputs: result.txOutputs.map(fromApiOutput),
@@ -403,7 +568,7 @@ class Contract extends Common {
403
568
  bytecode: bytecode,
404
569
  initialAttoAlphAmount: extractOptionalNumber256(params.initialAttoAlphAmount),
405
570
  issueTokenAmount: extractOptionalNumber256(params.issueTokenAmount),
406
- initialTokenAmounts: params.initialTokenAmounts?.map(toApiToken),
571
+ initialTokenAmounts: (0, api_1.toApiTokens)(params.initialTokenAmounts),
407
572
  gasAmount: params.gasAmount,
408
573
  gasPrice: extractOptionalNumber256(params.gasPrice)
409
574
  };
@@ -424,78 +589,53 @@ class Contract extends Common {
424
589
  exports.Contract = Contract;
425
590
  Contract.ContractCreatedEvent = {
426
591
  name: 'ContractCreated',
427
- signature: 'event ContractCreated(address:Address)',
428
592
  fieldNames: ['address'],
429
593
  fieldTypes: ['Address']
430
594
  };
431
595
  Contract.ContractDestroyedEvent = {
432
596
  name: 'ContractDestroyed',
433
- signature: 'event ContractDestroyed(address:Address)',
434
597
  fieldNames: ['address'],
435
598
  fieldTypes: ['Address']
436
599
  };
437
- class Script extends Common {
438
- constructor(sourceCodeSha256, bytecodeTemplate, fieldsSig, functions) {
439
- super(sourceCodeSha256, functions);
600
+ class Script extends Artifact {
601
+ constructor(name, bytecodeTemplate, fieldsSig, functions) {
602
+ super(name, functions);
440
603
  this.bytecodeTemplate = bytecodeTemplate;
441
604
  this.fieldsSig = fieldsSig;
442
605
  }
443
- static checkCodeType(fileName, contractStr) {
444
- const scriptMatches = contractStr.match(this.scriptRegex);
445
- if (scriptMatches === null) {
446
- throw new Error(`No script found in: ${fileName}`);
447
- }
448
- else if (scriptMatches.length > 1) {
449
- throw new Error(`Multiple scripts in: ${fileName}`);
450
- }
451
- else {
452
- return;
453
- }
454
- }
455
- static async loadContractStr(sourceFile) {
456
- return Common._loadContractStr(sourceFile, [], (code) => Script.checkCodeType(sourceFile.contractPath, code));
457
- }
458
- static async fromSource(provider, path) {
459
- const sourceFile = this.getSourceFile(path, []);
460
- return Common._from(provider, sourceFile, (sourceFile) => Script.loadContractStr(sourceFile), Script.compile);
461
- }
462
- static async compile(provider, sourceFile, scriptStr, contractHash) {
463
- const compiled = await provider.contracts.postContractsCompileScript({ code: scriptStr });
464
- const artifact = new Script(contractHash, compiled.bytecodeTemplate, compiled.fields, compiled.functions);
465
- await artifact._saveToFile(sourceFile);
466
- return artifact;
606
+ static fromCompileResult(result) {
607
+ return new Script(result.name, result.bytecodeTemplate, result.fields, result.functions);
467
608
  }
468
609
  // TODO: safely parse json
469
610
  static fromJson(artifact) {
470
- if (artifact.sourceCodeSha256 == null ||
611
+ if (artifact.name == null ||
471
612
  artifact.bytecodeTemplate == null ||
472
613
  artifact.fieldsSig == null ||
473
614
  artifact.functions == null) {
474
615
  throw Error('The artifact JSON for script is incomplete');
475
616
  }
476
- return new Script(artifact.sourceCodeSha256, artifact.bytecodeTemplate, artifact.fieldsSig, artifact.functions);
617
+ return new Script(artifact.name, artifact.bytecodeTemplate, artifact.fieldsSig, artifact.functions);
477
618
  }
478
619
  static async fromArtifactFile(path) {
479
- const sourceFile = this.getSourceFile(path, []);
480
- const artifactPath = sourceFile.artifactPath;
481
- const content = await fs_2.promises.readFile(artifactPath);
620
+ const content = await fs_2.promises.readFile(path);
482
621
  const artifact = JSON.parse(content.toString());
483
622
  return this.fromJson(artifact);
484
623
  }
485
624
  toString() {
486
- return JSON.stringify({
487
- sourceCodeSha256: this.sourceCodeSha256,
625
+ const object = {
626
+ name: this.name,
488
627
  bytecodeTemplate: this.bytecodeTemplate,
489
628
  fieldsSig: this.fieldsSig,
490
629
  functions: this.functions
491
- }, null, 2);
630
+ };
631
+ return JSON.stringify(object, null, 2);
492
632
  }
493
633
  async paramsForDeployment(params) {
494
634
  const signerParams = {
495
635
  signerAddress: params.signerAddress,
496
636
  bytecode: this.buildByteCodeToDeploy(params.initialFields ? params.initialFields : {}),
497
637
  attoAlphAmount: extractOptionalNumber256(params.attoAlphAmount),
498
- tokens: typeof params.tokens !== 'undefined' ? params.tokens.map(toApiToken) : undefined,
638
+ tokens: (0, api_1.toApiTokens)(params.tokens),
499
639
  gasAmount: params.gasAmount,
500
640
  gasPrice: extractOptionalNumber256(params.gasPrice)
501
641
  };
@@ -513,221 +653,25 @@ class Script extends Common {
513
653
  }
514
654
  }
515
655
  exports.Script = Script;
516
- function extractBoolean(v) {
517
- if (typeof v === 'boolean') {
518
- return v;
519
- }
520
- else {
521
- throw new Error(`Invalid boolean value: ${v}`);
522
- }
523
- }
524
- // TODO: check integer bounds
525
- function extractNumber256(v) {
526
- if ((typeof v === 'number' && Number.isInteger(v)) || typeof v === 'bigint') {
527
- return v.toString();
528
- }
529
- else if (typeof v === 'string') {
530
- return v;
531
- }
532
- else {
533
- throw new Error(`Invalid 256 bit number: ${v}`);
534
- }
535
- }
536
656
  function extractOptionalNumber256(v) {
537
- return typeof v !== 'undefined' ? extractNumber256(v) : undefined;
538
- }
539
- // TODO: check hex string
540
- function extractByteVec(v) {
541
- if (typeof v === 'string') {
542
- // try to convert from address to contract id
543
- try {
544
- const address = utils_1.bs58.decode(v);
545
- if (address.length == 33 && address[0] == 3) {
546
- return buffer_1.Buffer.from(address.slice(1)).toString('hex');
547
- }
548
- }
549
- catch (_) {
550
- return v;
551
- }
552
- return v;
553
- }
554
- else {
555
- throw new Error(`Invalid string: ${v}`);
556
- }
557
- }
558
- function extractBs58(v) {
559
- if (typeof v === 'string') {
560
- try {
561
- utils_1.bs58.decode(v);
562
- return v;
563
- }
564
- catch (error) {
565
- throw new Error(`Invalid base58 string: ${v}`);
566
- }
567
- }
568
- else {
569
- throw new Error(`Invalid string: ${v}`);
570
- }
571
- }
572
- function decodeNumber256(n) {
573
- if (Number.isSafeInteger(Number.parseInt(n))) {
574
- return Number(n);
575
- }
576
- else {
577
- return BigInt(n);
578
- }
579
- }
580
- function extractArray(tpe, v) {
581
- if (!Array.isArray(v)) {
582
- throw new Error(`Expected array, got ${v}`);
583
- }
584
- const semiColonIndex = tpe.lastIndexOf(';');
585
- if (semiColonIndex == -1) {
586
- throw new Error(`Invalid Val type: ${tpe}`);
587
- }
588
- const subType = tpe.slice(1, semiColonIndex);
589
- const dim = parseInt(tpe.slice(semiColonIndex + 1, -1));
590
- if (v.length != dim) {
591
- throw new Error(`Invalid val dimension: ${v}`);
592
- }
593
- else {
594
- return { value: v.map((v) => toApiVal(v, subType)), type: 'Array' };
595
- }
596
- }
597
- exports.extractArray = extractArray;
598
- function toApiVal(v, tpe) {
599
- if (tpe === 'Bool') {
600
- return { value: extractBoolean(v), type: tpe };
601
- }
602
- else if (tpe === 'U256' || tpe === 'I256') {
603
- return { value: extractNumber256(v), type: tpe };
604
- }
605
- else if (tpe === 'ByteVec') {
606
- return { value: extractByteVec(v), type: tpe };
607
- }
608
- else if (tpe === 'Address') {
609
- return { value: extractBs58(v), type: tpe };
610
- }
611
- else {
612
- return extractArray(tpe, v);
613
- }
614
- }
615
- exports.toApiVal = toApiVal;
616
- function decodeArrayType(tpe) {
617
- const semiColonIndex = tpe.lastIndexOf(';');
618
- if (semiColonIndex === -1) {
619
- throw new Error(`Invalid Val type: ${tpe}`);
620
- }
621
- const subType = tpe.slice(1, semiColonIndex);
622
- const dim = parseInt(tpe.slice(semiColonIndex + 1, -1));
623
- if (subType[0] == '[') {
624
- const [baseType, subDim] = decodeArrayType(subType);
625
- return [baseType, (subDim.unshift(dim), subDim)];
626
- }
627
- else {
628
- return [subType, [dim]];
629
- }
630
- }
631
- function foldVals(vals, dims) {
632
- if (dims.length == 1) {
633
- return vals;
634
- }
635
- else {
636
- const result = [];
637
- const chunkSize = vals.length / dims[0];
638
- const chunkDims = dims.slice(1);
639
- for (let i = 0; i < vals.length; i += chunkSize) {
640
- const chunk = vals.slice(i, i + chunkSize);
641
- result.push(foldVals(chunk, chunkDims));
642
- }
643
- return result;
644
- }
645
- }
646
- function _fromApiVal(vals, valIndex, tpe) {
647
- if (vals.length === 0) {
648
- throw new Error('Not enough Vals');
649
- }
650
- const firstVal = vals[`${valIndex}`];
651
- if (tpe === 'Bool' && firstVal.type === tpe) {
652
- return [firstVal.value, valIndex + 1];
653
- }
654
- else if ((tpe === 'U256' || tpe === 'I256') && firstVal.type === tpe) {
655
- return [decodeNumber256(firstVal.value), valIndex + 1];
656
- }
657
- else if ((tpe === 'ByteVec' || tpe === 'Address') && firstVal.type === tpe) {
658
- return [firstVal.value, valIndex + 1];
659
- }
660
- else {
661
- const [baseType, dims] = decodeArrayType(tpe);
662
- const arraySize = dims.reduce((a, b) => a * b);
663
- const nextIndex = valIndex + arraySize;
664
- const valsToUse = vals.slice(valIndex, nextIndex);
665
- if (valsToUse.length == arraySize && valsToUse.every((val) => val.type === baseType)) {
666
- const localVals = valsToUse.map((val) => fromApiVal(val, baseType));
667
- return [foldVals(localVals, dims), nextIndex];
668
- }
669
- else {
670
- throw new Error(`Invalid array Val type: ${valsToUse}, ${tpe}`);
671
- }
672
- }
657
+ return typeof v !== 'undefined' ? (0, api_1.toApiNumber256)(v) : undefined;
673
658
  }
674
659
  function fromApiFields(vals, fieldsSig) {
675
- return fromApiVals(vals, fieldsSig.names, fieldsSig.types);
660
+ return (0, api_1.fromApiVals)(vals, fieldsSig.names, fieldsSig.types);
676
661
  }
677
662
  function fromApiEventFields(vals, eventSig) {
678
- return fromApiVals(vals, eventSig.fieldNames, eventSig.fieldTypes);
679
- }
680
- function fromApiVals(vals, names, types) {
681
- let valIndex = 0;
682
- const result = {};
683
- types.forEach((currentType, index) => {
684
- const currentName = names[`${index}`];
685
- const [val, nextIndex] = _fromApiVal(vals, valIndex, currentType);
686
- valIndex = nextIndex;
687
- result[`${currentName}`] = val;
688
- });
689
- return result;
690
- }
691
- function fromApiArray(vals, types) {
692
- let valIndex = 0;
693
- const result = [];
694
- for (const currentType of types) {
695
- const [val, nextIndex] = _fromApiVal(vals, valIndex, currentType);
696
- result.push(val);
697
- valIndex = nextIndex;
698
- }
699
- return result;
700
- }
701
- function fromApiVal(v, tpe) {
702
- if (v.type === 'Bool' && v.type === tpe) {
703
- return v.value;
704
- }
705
- else if ((v.type === 'U256' || v.type === 'I256') && v.type === tpe) {
706
- return decodeNumber256(v.value);
707
- }
708
- else if ((v.type === 'ByteVec' || v.type === 'Address') && v.type === tpe) {
709
- return v.value;
710
- }
711
- else {
712
- throw new Error(`Invalid node.Val type: ${v}`);
713
- }
714
- }
715
- function toApiToken(token) {
716
- return { id: token.id, amount: extractNumber256(token.amount) };
717
- }
718
- function fromApiToken(token) {
719
- return { id: token.id, amount: decodeNumber256(token.amount) };
663
+ return (0, api_1.fromApiVals)(vals, eventSig.fieldNames, eventSig.fieldTypes);
720
664
  }
721
665
  function toApiAsset(asset) {
722
666
  return {
723
- attoAlphAmount: extractNumber256(asset.alphAmount),
724
- tokens: typeof asset.tokens !== 'undefined' ? asset.tokens.map(toApiToken) : []
667
+ attoAlphAmount: (0, api_1.toApiNumber256)(asset.alphAmount),
668
+ tokens: typeof asset.tokens !== 'undefined' ? asset.tokens.map(api_1.toApiToken) : []
725
669
  };
726
670
  }
727
671
  function fromApiAsset(asset) {
728
672
  return {
729
- alphAmount: decodeNumber256(asset.attoAlphAmount),
730
- tokens: typeof asset.tokens !== 'undefined' ? asset.tokens.map(fromApiToken) : undefined
673
+ alphAmount: (0, api_1.fromApiNumber256)(asset.attoAlphAmount),
674
+ tokens: (0, api_1.fromApiTokens)(asset.tokens)
731
675
  };
732
676
  }
733
677
  function getVal(vals, name) {
@@ -752,13 +696,13 @@ function toApiFields(fields, fieldsSig) {
752
696
  return toApiVals(fields, fieldsSig.names, fieldsSig.types);
753
697
  }
754
698
  function toApiArgs(args, funcSig) {
755
- return toApiVals(args, funcSig.argNames, funcSig.argTypes);
699
+ return toApiVals(args, funcSig.paramNames, funcSig.paramTypes);
756
700
  }
757
701
  function toApiVals(fields, names, types) {
758
702
  return names.map((name, index) => {
759
703
  const val = getVal(fields, name);
760
704
  const tpe = types[`${index}`];
761
- return toApiVal(val, tpe);
705
+ return (0, api_1.toApiVal)(val, tpe);
762
706
  });
763
707
  }
764
708
  function toApiInputAsset(inputAsset) {
@@ -773,8 +717,8 @@ function fromApiOutput(output) {
773
717
  return {
774
718
  type: 'AssetOutput',
775
719
  address: asset.address,
776
- alphAmount: decodeNumber256(asset.attoAlphAmount),
777
- tokens: asset.tokens.map(fromApiToken),
720
+ alphAmount: (0, api_1.fromApiNumber256)(asset.attoAlphAmount),
721
+ tokens: (0, api_1.fromApiTokens)(asset.tokens),
778
722
  lockTime: asset.lockTime,
779
723
  message: asset.message
780
724
  };
@@ -784,8 +728,8 @@ function fromApiOutput(output) {
784
728
  return {
785
729
  type: 'ContractOutput',
786
730
  address: asset.address,
787
- alphAmount: decodeNumber256(asset.attoAlphAmount),
788
- tokens: asset.tokens.map(fromApiToken)
731
+ alphAmount: (0, api_1.fromApiNumber256)(asset.attoAlphAmount),
732
+ tokens: (0, api_1.fromApiTokens)(asset.tokens)
789
733
  };
790
734
  }
791
735
  else {