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