@alephium/web3 0.35.1 → 0.36.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/api-alephium.d.ts +8 -1
- package/dist/src/api/api-alephium.js +1 -1
- package/dist/src/api/types.d.ts +7 -6
- package/dist/src/api/types.js +19 -100
- package/dist/src/contract/contract.d.ts +31 -11
- package/dist/src/contract/contract.js +167 -89
- package/dist/src/contract/ralph.d.ts +6 -5
- package/dist/src/contract/ralph.js +68 -80
- package/package.json +2 -2
- package/src/api/api-alephium.ts +9 -1
- package/src/api/types.ts +20 -103
- package/src/contract/contract.ts +218 -92
- package/src/contract/ralph.ts +95 -81
|
@@ -43,7 +43,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
43
43
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
44
44
|
};
|
|
45
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
-
exports.tryGetCallResult = exports.getTokenIdFromUnsignedTx = exports.getContractIdFromUnsignedTx = exports.getContractEventsCurrentCount = exports.multicallMethods = exports.callMethod = exports.subscribeContractEvents = exports.subscribeContractEvent = exports.decodeEvent = exports.subscribeContractDestroyedEvent = exports.subscribeContractCreatedEvent = exports.fetchContractState = exports.ContractInstance = exports.testMethod = exports.addStdIdToFields = exports.subscribeEventsFromContract = exports.decodeContractDestroyedEvent = exports.decodeContractCreatedEvent = exports.DestroyContractEventAddress = exports.CreateContractEventAddress = exports.ExecutableScript = exports.ContractFactory = exports.randomTxId = exports.
|
|
46
|
+
exports.tryGetCallResult = exports.getTokenIdFromUnsignedTx = exports.getContractIdFromUnsignedTx = exports.getContractEventsCurrentCount = exports.multicallMethods = exports.callMethod = exports.subscribeContractEvents = exports.subscribeContractEvent = exports.decodeEvent = exports.subscribeContractDestroyedEvent = exports.subscribeContractCreatedEvent = exports.fetchContractState = exports.ContractInstance = exports.testMethod = exports.addStdIdToFields = exports.subscribeEventsFromContract = exports.decodeContractDestroyedEvent = exports.decodeContractCreatedEvent = exports.DestroyContractEventAddress = exports.CreateContractEventAddress = exports.ExecutableScript = exports.ContractFactory = exports.randomTxId = exports.fromApiEventFields = exports.fromApiArray = exports.getDefaultValue = exports.fromApiFields = exports.Script = exports.Contract = exports.Artifact = exports.Project = exports.Struct = exports.ProjectArtifact = exports.DEFAULT_COMPILER_OPTIONS = exports.DEFAULT_NODE_COMPILER_OPTIONS = exports.StdIdFieldName = void 0;
|
|
47
47
|
const buffer_1 = require("buffer/");
|
|
48
48
|
const fs_1 = __importDefault(require("fs"));
|
|
49
49
|
const fs_2 = require("fs");
|
|
@@ -65,6 +65,7 @@ var SourceKind;
|
|
|
65
65
|
SourceKind[SourceKind["Script"] = 1] = "Script";
|
|
66
66
|
SourceKind[SourceKind["AbstractContract"] = 2] = "AbstractContract";
|
|
67
67
|
SourceKind[SourceKind["Interface"] = 3] = "Interface";
|
|
68
|
+
SourceKind[SourceKind["Struct"] = 4] = "Struct";
|
|
68
69
|
})(SourceKind || (SourceKind = {}));
|
|
69
70
|
exports.DEFAULT_NODE_COMPILER_OPTIONS = {
|
|
70
71
|
ignoreUnusedConstantsWarnings: false,
|
|
@@ -238,6 +239,32 @@ function removeOldArtifacts(dir) {
|
|
|
238
239
|
fs_1.default.rmdirSync(dir);
|
|
239
240
|
}
|
|
240
241
|
}
|
|
242
|
+
class Struct {
|
|
243
|
+
constructor(name, fieldNames, fieldTypes, isMutable) {
|
|
244
|
+
this.name = name;
|
|
245
|
+
this.fieldNames = fieldNames;
|
|
246
|
+
this.fieldTypes = fieldTypes;
|
|
247
|
+
this.isMutable = isMutable;
|
|
248
|
+
}
|
|
249
|
+
static fromJson(json) {
|
|
250
|
+
if (json.name === null || json.fieldNames === null || json.fieldTypes === null || json.isMutable === null) {
|
|
251
|
+
throw Error('The JSON for struct is incomplete');
|
|
252
|
+
}
|
|
253
|
+
return new Struct(json.name, json.fieldNames, json.fieldTypes, json.isMutable);
|
|
254
|
+
}
|
|
255
|
+
static fromStructSig(sig) {
|
|
256
|
+
return new Struct(sig.name, sig.fieldNames, sig.fieldTypes, sig.isMutable);
|
|
257
|
+
}
|
|
258
|
+
toJson() {
|
|
259
|
+
return {
|
|
260
|
+
name: this.name,
|
|
261
|
+
fieldNames: this.fieldNames,
|
|
262
|
+
fieldTypes: this.fieldTypes,
|
|
263
|
+
isMutable: this.isMutable
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
exports.Struct = Struct;
|
|
241
268
|
class Project {
|
|
242
269
|
static buildProjectArtifact(fullNodeVersion, sourceInfos, contracts, scripts, compilerOptions) {
|
|
243
270
|
const files = new Map();
|
|
@@ -271,12 +298,13 @@ class Project {
|
|
|
271
298
|
});
|
|
272
299
|
return new ProjectArtifact(fullNodeVersion, compilerOptions, files);
|
|
273
300
|
}
|
|
274
|
-
constructor(contractsRootDir, artifactsRootDir, sourceInfos, contracts, scripts, errorOnWarnings, projectArtifact) {
|
|
301
|
+
constructor(contractsRootDir, artifactsRootDir, sourceInfos, contracts, scripts, structs, errorOnWarnings, projectArtifact) {
|
|
275
302
|
this.contractsRootDir = contractsRootDir;
|
|
276
303
|
this.artifactsRootDir = artifactsRootDir;
|
|
277
304
|
this.sourceInfos = sourceInfos;
|
|
278
305
|
this.contracts = contracts;
|
|
279
306
|
this.scripts = scripts;
|
|
307
|
+
this.structs = structs;
|
|
280
308
|
this.projectArtifact = projectArtifact;
|
|
281
309
|
if (errorOnWarnings) {
|
|
282
310
|
Project.checkCompilerWarnings([
|
|
@@ -312,6 +340,24 @@ class Project {
|
|
|
312
340
|
}
|
|
313
341
|
return script.artifact;
|
|
314
342
|
}
|
|
343
|
+
static async loadStructs(artifactsRootDir) {
|
|
344
|
+
const filePath = path.join(artifactsRootDir, 'structs.ral.json');
|
|
345
|
+
if (!fs_1.default.existsSync(filePath))
|
|
346
|
+
return [];
|
|
347
|
+
const content = await fs_2.promises.readFile(filePath);
|
|
348
|
+
const json = JSON.parse(content.toString());
|
|
349
|
+
if (!Array.isArray(json)) {
|
|
350
|
+
throw Error(`Invalid structs JSON: ${content}`);
|
|
351
|
+
}
|
|
352
|
+
return Array.from(json).map((item) => Struct.fromJson(item));
|
|
353
|
+
}
|
|
354
|
+
async saveStructsToFile() {
|
|
355
|
+
if (this.structs.length === 0)
|
|
356
|
+
return;
|
|
357
|
+
const structs = this.structs.map((s) => s.toJson());
|
|
358
|
+
const filePath = path.join(this.artifactsRootDir, 'structs.ral.json');
|
|
359
|
+
return fs_2.promises.writeFile(filePath, JSON.stringify(structs, null, 2));
|
|
360
|
+
}
|
|
315
361
|
async saveArtifactsToFile(projectRootDir) {
|
|
316
362
|
const artifactsRootDir = this.artifactsRootDir;
|
|
317
363
|
const saveToFile = async function (compiled) {
|
|
@@ -324,6 +370,7 @@ class Project {
|
|
|
324
370
|
};
|
|
325
371
|
this.contracts.forEach((contract) => saveToFile(contract));
|
|
326
372
|
this.scripts.forEach((script) => saveToFile(script));
|
|
373
|
+
this.saveStructsToFile();
|
|
327
374
|
await this.projectArtifact.saveToFile(projectRootDir);
|
|
328
375
|
}
|
|
329
376
|
contractByCodeHash(codeHash) {
|
|
@@ -368,13 +415,14 @@ class Project {
|
|
|
368
415
|
const result = await Project.getCompileResult(provider, compilerOptions, removeDuplicates);
|
|
369
416
|
const contracts = new Map();
|
|
370
417
|
const scripts = new Map();
|
|
418
|
+
const structs = result.structs === undefined ? [] : result.structs.map((item) => Struct.fromStructSig(item));
|
|
371
419
|
result.contracts.forEach((contractResult) => {
|
|
372
420
|
const sourceInfo = sourceInfos.find((sourceInfo) => sourceInfo.type === SourceKind.Contract && sourceInfo.name === contractResult.name);
|
|
373
421
|
if (sourceInfo === undefined) {
|
|
374
422
|
// this should never happen
|
|
375
423
|
throw new Error(`SourceInfo does not exist for contract ${contractResult.name}`);
|
|
376
424
|
}
|
|
377
|
-
const contract = Contract.fromCompileResult(contractResult);
|
|
425
|
+
const contract = Contract.fromCompileResult(contractResult, structs);
|
|
378
426
|
contracts.set(contract.name, new Compiled(sourceInfo, contract, contractResult.warnings));
|
|
379
427
|
});
|
|
380
428
|
result.scripts.forEach((scriptResult) => {
|
|
@@ -383,11 +431,11 @@ class Project {
|
|
|
383
431
|
// this should never happen
|
|
384
432
|
throw new Error(`SourceInfo does not exist for script ${scriptResult.name}`);
|
|
385
433
|
}
|
|
386
|
-
const script = Script.fromCompileResult(scriptResult);
|
|
434
|
+
const script = Script.fromCompileResult(scriptResult, structs);
|
|
387
435
|
scripts.set(script.name, new Compiled(sourceInfo, script, scriptResult.warnings));
|
|
388
436
|
});
|
|
389
437
|
const projectArtifact = Project.buildProjectArtifact(fullNodeVersion, sourceInfos, contracts, scripts, compilerOptions);
|
|
390
|
-
const project = new Project(contractsRootDir, artifactsRootDir, sourceInfos, contracts, scripts, errorOnWarnings, projectArtifact);
|
|
438
|
+
const project = new Project(contractsRootDir, artifactsRootDir, sourceInfos, contracts, scripts, structs, errorOnWarnings, projectArtifact);
|
|
391
439
|
await project.saveArtifactsToFile(projectRootDir);
|
|
392
440
|
return project;
|
|
393
441
|
}
|
|
@@ -395,6 +443,7 @@ class Project {
|
|
|
395
443
|
try {
|
|
396
444
|
const contracts = new Map();
|
|
397
445
|
const scripts = new Map();
|
|
446
|
+
const structs = await Project.loadStructs(artifactsRootDir);
|
|
398
447
|
for (const sourceInfo of sourceInfos) {
|
|
399
448
|
const info = projectArtifact.infos.get(sourceInfo.name);
|
|
400
449
|
if (typeof info === 'undefined') {
|
|
@@ -403,15 +452,15 @@ class Project {
|
|
|
403
452
|
const warnings = info.warnings;
|
|
404
453
|
const artifactDir = sourceInfo.getArtifactPath(artifactsRootDir);
|
|
405
454
|
if (sourceInfo.type === SourceKind.Contract) {
|
|
406
|
-
const artifact = await Contract.fromArtifactFile(artifactDir, info.bytecodeDebugPatch, info.codeHashDebug);
|
|
455
|
+
const artifact = await Contract.fromArtifactFile(artifactDir, info.bytecodeDebugPatch, info.codeHashDebug, structs);
|
|
407
456
|
contracts.set(artifact.name, new Compiled(sourceInfo, artifact, warnings));
|
|
408
457
|
}
|
|
409
458
|
else if (sourceInfo.type === SourceKind.Script) {
|
|
410
|
-
const artifact = await Script.fromArtifactFile(artifactDir, info.bytecodeDebugPatch);
|
|
459
|
+
const artifact = await Script.fromArtifactFile(artifactDir, info.bytecodeDebugPatch, structs);
|
|
411
460
|
scripts.set(artifact.name, new Compiled(sourceInfo, artifact, warnings));
|
|
412
461
|
}
|
|
413
462
|
}
|
|
414
|
-
return new Project(contractsRootDir, artifactsRootDir, sourceInfos, contracts, scripts, errorOnWarnings, projectArtifact);
|
|
463
|
+
return new Project(contractsRootDir, artifactsRootDir, sourceInfos, contracts, scripts, structs, errorOnWarnings, projectArtifact);
|
|
415
464
|
}
|
|
416
465
|
catch (error) {
|
|
417
466
|
console.log(`Failed to load artifacts, error: ${error}, try to re-compile contracts...`);
|
|
@@ -526,11 +575,13 @@ Project.abstractContractMatcher = new TypedMatcher('^Abstract Contract ([A-Z][a-
|
|
|
526
575
|
Project.contractMatcher = new TypedMatcher('^Contract ([A-Z][a-zA-Z0-9]*)', SourceKind.Contract);
|
|
527
576
|
Project.interfaceMatcher = new TypedMatcher('^Interface ([A-Z][a-zA-Z0-9]*)', SourceKind.Interface);
|
|
528
577
|
Project.scriptMatcher = new TypedMatcher('^TxScript ([A-Z][a-zA-Z0-9]*)', SourceKind.Script);
|
|
578
|
+
Project.structMatcher = new TypedMatcher('struct ([A-Z][a-zA-Z0-9]*)', SourceKind.Struct);
|
|
529
579
|
Project.matchers = [
|
|
530
580
|
Project.abstractContractMatcher,
|
|
531
581
|
Project.contractMatcher,
|
|
532
582
|
Project.interfaceMatcher,
|
|
533
|
-
Project.scriptMatcher
|
|
583
|
+
Project.scriptMatcher,
|
|
584
|
+
Project.structMatcher
|
|
534
585
|
];
|
|
535
586
|
Project.DEFAULT_CONTRACTS_DIR = 'contracts';
|
|
536
587
|
Project.DEFAULT_ARTIFACTS_DIR = 'artifacts';
|
|
@@ -559,7 +610,7 @@ class Artifact {
|
|
|
559
610
|
}
|
|
560
611
|
exports.Artifact = Artifact;
|
|
561
612
|
class Contract extends Artifact {
|
|
562
|
-
constructor(version, name, bytecode, bytecodeDebugPatch, codeHash, codeHashDebug, fieldsSig, eventsSig, functions, constants, enums, stdInterfaceId) {
|
|
613
|
+
constructor(version, name, bytecode, bytecodeDebugPatch, codeHash, codeHashDebug, fieldsSig, eventsSig, functions, constants, enums, structs, stdInterfaceId) {
|
|
563
614
|
super(version, name, functions);
|
|
564
615
|
this.bytecode = bytecode;
|
|
565
616
|
this.bytecodeDebugPatch = bytecodeDebugPatch;
|
|
@@ -568,12 +619,13 @@ class Contract extends Artifact {
|
|
|
568
619
|
this.eventsSig = eventsSig;
|
|
569
620
|
this.constants = constants;
|
|
570
621
|
this.enums = enums;
|
|
622
|
+
this.structs = structs;
|
|
571
623
|
this.stdInterfaceId = stdInterfaceId;
|
|
572
624
|
this.bytecodeDebug = ralph.buildDebugBytecode(this.bytecode, this.bytecodeDebugPatch);
|
|
573
625
|
this.codeHashDebug = codeHashDebug;
|
|
574
626
|
}
|
|
575
627
|
// TODO: safely parse json
|
|
576
|
-
static fromJson(artifact, bytecodeDebugPatch = '', codeHashDebug = '') {
|
|
628
|
+
static fromJson(artifact, bytecodeDebugPatch = '', codeHashDebug = '', structs = []) {
|
|
577
629
|
if (artifact.version == null ||
|
|
578
630
|
artifact.name == null ||
|
|
579
631
|
artifact.bytecode == null ||
|
|
@@ -585,17 +637,17 @@ class Contract extends Artifact {
|
|
|
585
637
|
artifact.functions == null) {
|
|
586
638
|
throw Error('The artifact JSON for contract is incomplete');
|
|
587
639
|
}
|
|
588
|
-
const contract = new Contract(artifact.version, artifact.name, artifact.bytecode, bytecodeDebugPatch, artifact.codeHash, codeHashDebug ? codeHashDebug : artifact.codeHash, artifact.fieldsSig, artifact.eventsSig, artifact.functions, artifact.constants, artifact.enums, artifact.stdInterfaceId === null ? undefined : artifact.stdInterfaceId);
|
|
640
|
+
const contract = new Contract(artifact.version, artifact.name, artifact.bytecode, bytecodeDebugPatch, artifact.codeHash, codeHashDebug ? codeHashDebug : artifact.codeHash, artifact.fieldsSig, artifact.eventsSig, artifact.functions, artifact.constants, artifact.enums, structs, artifact.stdInterfaceId === null ? undefined : artifact.stdInterfaceId);
|
|
589
641
|
return contract;
|
|
590
642
|
}
|
|
591
|
-
static fromCompileResult(result) {
|
|
592
|
-
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, result.stdInterfaceId);
|
|
643
|
+
static fromCompileResult(result, structs = []) {
|
|
644
|
+
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.stdInterfaceId);
|
|
593
645
|
}
|
|
594
646
|
// support both 'code.ral' and 'code.ral.json'
|
|
595
|
-
static async fromArtifactFile(path, bytecodeDebugPatch, codeHashDebug) {
|
|
647
|
+
static async fromArtifactFile(path, bytecodeDebugPatch, codeHashDebug, structs = []) {
|
|
596
648
|
const content = await fs_2.promises.readFile(path);
|
|
597
649
|
const artifact = JSON.parse(content.toString());
|
|
598
|
-
return Contract.fromJson(artifact, bytecodeDebugPatch, codeHashDebug);
|
|
650
|
+
return Contract.fromJson(artifact, bytecodeDebugPatch, codeHashDebug, structs);
|
|
599
651
|
}
|
|
600
652
|
toString() {
|
|
601
653
|
const object = {
|
|
@@ -622,10 +674,7 @@ class Contract extends Artifact {
|
|
|
622
674
|
types: this.fieldsSig.types.slice(0, -1),
|
|
623
675
|
isMutable: this.fieldsSig.isMutable.slice(0, -1)
|
|
624
676
|
};
|
|
625
|
-
return fields
|
|
626
|
-
acc[`${key}`] = (0, api_1.getDefaultValue)(fields.types[`${index}`]);
|
|
627
|
-
return acc;
|
|
628
|
-
}, {});
|
|
677
|
+
return getDefaultValue(fields, this.structs);
|
|
629
678
|
}
|
|
630
679
|
toState(fields, asset, address) {
|
|
631
680
|
const addressDef = typeof address !== 'undefined' ? address : Contract.randomAddress();
|
|
@@ -657,7 +706,7 @@ class Contract extends Artifact {
|
|
|
657
706
|
return [];
|
|
658
707
|
}
|
|
659
708
|
else {
|
|
660
|
-
return toApiFields(fields, this.fieldsSig);
|
|
709
|
+
return toApiFields(fields, this.fieldsSig, this.structs);
|
|
661
710
|
}
|
|
662
711
|
}
|
|
663
712
|
toApiArgs(funcName, args) {
|
|
@@ -666,7 +715,7 @@ class Contract extends Artifact {
|
|
|
666
715
|
if (func == null) {
|
|
667
716
|
throw new Error(`Invalid function name: ${funcName}`);
|
|
668
717
|
}
|
|
669
|
-
return toApiArgs(args, func);
|
|
718
|
+
return toApiArgs(args, func, this.structs);
|
|
670
719
|
}
|
|
671
720
|
else {
|
|
672
721
|
return [];
|
|
@@ -676,11 +725,14 @@ class Contract extends Artifact {
|
|
|
676
725
|
return this.functions.findIndex((func) => func.name === funcName);
|
|
677
726
|
}
|
|
678
727
|
toApiContractStates(states) {
|
|
679
|
-
return typeof states != 'undefined' ? states.map((state) => toApiContractState(state)) : undefined;
|
|
728
|
+
return typeof states != 'undefined' ? states.map((state) => toApiContractState(state, this.structs)) : undefined;
|
|
680
729
|
}
|
|
681
730
|
toApiTestContractParams(funcName, params) {
|
|
682
|
-
const
|
|
683
|
-
|
|
731
|
+
const allFields = params.initialFields === undefined
|
|
732
|
+
? []
|
|
733
|
+
: ralph.flattenFields(params.initialFields, this.fieldsSig.names, this.fieldsSig.types, this.fieldsSig.isMutable, this.structs);
|
|
734
|
+
const immFields = allFields.filter((f) => !f.isMutable).map((f) => (0, api_1.toApiVal)(f.value, f.type));
|
|
735
|
+
const mutFields = allFields.filter((f) => f.isMutable).map((f) => (0, api_1.toApiVal)(f.value, f.type));
|
|
684
736
|
return {
|
|
685
737
|
group: params.group,
|
|
686
738
|
blockHash: params.blockHash,
|
|
@@ -705,7 +757,7 @@ class Contract extends Artifact {
|
|
|
705
757
|
bytecode: state.bytecode,
|
|
706
758
|
initialStateHash: state.initialStateHash,
|
|
707
759
|
codeHash: state.codeHash,
|
|
708
|
-
fields: fromApiFields(state.immFields, state.mutFields, this.fieldsSig),
|
|
760
|
+
fields: fromApiFields(state.immFields, state.mutFields, this.fieldsSig, this.structs),
|
|
709
761
|
fieldsSig: this.fieldsSig,
|
|
710
762
|
asset: fromApiAsset(state.asset)
|
|
711
763
|
};
|
|
@@ -747,7 +799,7 @@ class Contract extends Artifact {
|
|
|
747
799
|
fromApiTestContractResult(methodName, result, txId) {
|
|
748
800
|
const methodIndex = this.functions.findIndex((sig) => sig.name === methodName);
|
|
749
801
|
const returnTypes = this.functions[`${methodIndex}`].returnTypes;
|
|
750
|
-
const rawReturn =
|
|
802
|
+
const rawReturn = fromApiArray(result.returns, returnTypes, this.structs);
|
|
751
803
|
const returns = rawReturn.length === 0 ? null : rawReturn.length === 1 ? rawReturn[0] : rawReturn;
|
|
752
804
|
const addressToCodeHash = new Map();
|
|
753
805
|
addressToCodeHash.set(result.address, result.codeHash);
|
|
@@ -783,7 +835,7 @@ class Contract extends Artifact {
|
|
|
783
835
|
}
|
|
784
836
|
buildByteCodeToDeploy(initialFields, isDevnet) {
|
|
785
837
|
try {
|
|
786
|
-
return ralph.buildContractByteCode(isDevnet ? this.bytecodeDebug : this.bytecode, initialFields, this.fieldsSig);
|
|
838
|
+
return ralph.buildContractByteCode(isDevnet ? this.bytecodeDebug : this.bytecode, initialFields, this.fieldsSig, this.structs);
|
|
787
839
|
}
|
|
788
840
|
catch (error) {
|
|
789
841
|
throw new Error(`Failed to build bytecode for contract ${this.name}, error: ${error}`);
|
|
@@ -803,7 +855,7 @@ class Contract extends Artifact {
|
|
|
803
855
|
}
|
|
804
856
|
toApiCallContract(params, groupIndex, contractAddress, methodIndex) {
|
|
805
857
|
const functionSig = this.functions[`${methodIndex}`];
|
|
806
|
-
const args =
|
|
858
|
+
const args = toApiArgs(params.args ?? {}, functionSig, this.structs);
|
|
807
859
|
return {
|
|
808
860
|
...params,
|
|
809
861
|
group: groupIndex,
|
|
@@ -815,7 +867,7 @@ class Contract extends Artifact {
|
|
|
815
867
|
fromApiCallContractResult(result, txId, methodIndex, getContractByCodeHash) {
|
|
816
868
|
const returnTypes = this.functions[`${methodIndex}`].returnTypes;
|
|
817
869
|
const callResult = tryGetCallResult(result);
|
|
818
|
-
const rawReturn =
|
|
870
|
+
const rawReturn = fromApiArray(callResult.returns, returnTypes, this.structs);
|
|
819
871
|
const returns = rawReturn.length === 0 ? null : rawReturn.length === 1 ? rawReturn[0] : rawReturn;
|
|
820
872
|
const addressToCodeHash = new Map();
|
|
821
873
|
callResult.contracts.forEach((contract) => addressToCodeHash.set(contract.address, contract.codeHash));
|
|
@@ -844,17 +896,18 @@ Contract.ContractDestroyedEvent = {
|
|
|
844
896
|
fieldTypes: ['Address']
|
|
845
897
|
};
|
|
846
898
|
class Script extends Artifact {
|
|
847
|
-
constructor(version, name, bytecodeTemplate, bytecodeDebugPatch, fieldsSig, functions) {
|
|
899
|
+
constructor(version, name, bytecodeTemplate, bytecodeDebugPatch, fieldsSig, functions, structs) {
|
|
848
900
|
super(version, name, functions);
|
|
849
901
|
this.bytecodeTemplate = bytecodeTemplate;
|
|
850
902
|
this.bytecodeDebugPatch = bytecodeDebugPatch;
|
|
851
903
|
this.fieldsSig = fieldsSig;
|
|
904
|
+
this.structs = structs;
|
|
852
905
|
}
|
|
853
|
-
static fromCompileResult(result) {
|
|
854
|
-
return new Script(result.version, result.name, result.bytecodeTemplate, result.bytecodeDebugPatch, result.fields, result.functions);
|
|
906
|
+
static fromCompileResult(result, structs = []) {
|
|
907
|
+
return new Script(result.version, result.name, result.bytecodeTemplate, result.bytecodeDebugPatch, result.fields, result.functions, structs);
|
|
855
908
|
}
|
|
856
909
|
// TODO: safely parse json
|
|
857
|
-
static fromJson(artifact, bytecodeDebugPatch = '') {
|
|
910
|
+
static fromJson(artifact, bytecodeDebugPatch = '', structs = []) {
|
|
858
911
|
if (artifact.version == null ||
|
|
859
912
|
artifact.name == null ||
|
|
860
913
|
artifact.bytecodeTemplate == null ||
|
|
@@ -862,12 +915,12 @@ class Script extends Artifact {
|
|
|
862
915
|
artifact.functions == null) {
|
|
863
916
|
throw Error('The artifact JSON for script is incomplete');
|
|
864
917
|
}
|
|
865
|
-
return new Script(artifact.version, artifact.name, artifact.bytecodeTemplate, bytecodeDebugPatch, artifact.fieldsSig, artifact.functions);
|
|
918
|
+
return new Script(artifact.version, artifact.name, artifact.bytecodeTemplate, bytecodeDebugPatch, artifact.fieldsSig, artifact.functions, structs);
|
|
866
919
|
}
|
|
867
|
-
static async fromArtifactFile(path, bytecodeDebugPatch) {
|
|
920
|
+
static async fromArtifactFile(path, bytecodeDebugPatch, structs = []) {
|
|
868
921
|
const content = await fs_2.promises.readFile(path);
|
|
869
922
|
const artifact = JSON.parse(content.toString());
|
|
870
|
-
return this.fromJson(artifact, bytecodeDebugPatch);
|
|
923
|
+
return this.fromJson(artifact, bytecodeDebugPatch, structs);
|
|
871
924
|
}
|
|
872
925
|
toString() {
|
|
873
926
|
const object = {
|
|
@@ -894,7 +947,7 @@ class Script extends Artifact {
|
|
|
894
947
|
}
|
|
895
948
|
buildByteCodeToDeploy(initialFields) {
|
|
896
949
|
try {
|
|
897
|
-
return ralph.buildScriptByteCode(this.bytecodeTemplate, initialFields, this.fieldsSig);
|
|
950
|
+
return ralph.buildScriptByteCode(this.bytecodeTemplate, initialFields, this.fieldsSig, this.structs);
|
|
898
951
|
}
|
|
899
952
|
catch (error) {
|
|
900
953
|
throw new Error(`Failed to build bytecode for script ${this.name}, error: ${error}`);
|
|
@@ -902,26 +955,69 @@ class Script extends Artifact {
|
|
|
902
955
|
}
|
|
903
956
|
}
|
|
904
957
|
exports.Script = Script;
|
|
905
|
-
function fromApiFields(immFields, mutFields, fieldsSig) {
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
958
|
+
function fromApiFields(immFields, mutFields, fieldsSig, structs) {
|
|
959
|
+
let [immIndex, mutIndex] = [0, 0];
|
|
960
|
+
const func = (type, isMutable) => {
|
|
961
|
+
const nodeVal = isMutable ? mutFields[mutIndex++] : immFields[immIndex++];
|
|
962
|
+
return (0, api_1.fromApiPrimitiveVal)(nodeVal, type);
|
|
963
|
+
};
|
|
964
|
+
return fieldsSig.names.reduce((acc, name, index) => {
|
|
965
|
+
const fieldType = fieldsSig.types[`${index}`];
|
|
966
|
+
const isMutable = fieldsSig.isMutable[`${index}`];
|
|
967
|
+
acc[`${name}`] = buildVal(isMutable, fieldType, structs, func);
|
|
968
|
+
return acc;
|
|
969
|
+
}, {});
|
|
970
|
+
}
|
|
971
|
+
exports.fromApiFields = fromApiFields;
|
|
972
|
+
function buildVal(isMutable, type, structs, func) {
|
|
973
|
+
if (type.startsWith('[')) {
|
|
974
|
+
const [baseType, size] = (0, api_1.decodeArrayType)(type);
|
|
975
|
+
return Array.from(Array(size).keys()).map(() => buildVal(isMutable, baseType, structs, func));
|
|
976
|
+
}
|
|
977
|
+
const struct = structs.find((s) => s.name === type);
|
|
978
|
+
if (struct !== undefined) {
|
|
979
|
+
return struct.fieldNames.reduce((acc, name, index) => {
|
|
980
|
+
const fieldType = struct.fieldTypes[`${index}`];
|
|
981
|
+
const isFieldMutable = isMutable && struct.isMutable[`${index}`];
|
|
982
|
+
acc[`${name}`] = buildVal(isFieldMutable, fieldType, structs, func);
|
|
983
|
+
return acc;
|
|
984
|
+
}, {});
|
|
985
|
+
}
|
|
986
|
+
const primitiveType = api_1.PrimitiveTypes.includes(type) ? type : 'ByteVec'; // contract type
|
|
987
|
+
return func(primitiveType, isMutable);
|
|
988
|
+
}
|
|
989
|
+
function getDefaultValue(fieldsSig, structs) {
|
|
990
|
+
return fieldsSig.names.reduce((acc, name, index) => {
|
|
991
|
+
const type = fieldsSig.types[`${index}`];
|
|
992
|
+
acc[`${name}`] = buildVal(false, type, structs, api_1.getDefaultPrimitiveValue);
|
|
993
|
+
return acc;
|
|
994
|
+
}, {});
|
|
995
|
+
}
|
|
996
|
+
exports.getDefaultValue = getDefaultValue;
|
|
997
|
+
function fromApiVal(iter, type, structs, systemEvent = false) {
|
|
998
|
+
const func = (primitiveType) => {
|
|
999
|
+
const currentValue = iter.next();
|
|
1000
|
+
if (currentValue.done)
|
|
1001
|
+
throw Error('Not enough vals');
|
|
1002
|
+
return (0, api_1.fromApiPrimitiveVal)(currentValue.value, primitiveType, systemEvent);
|
|
1003
|
+
};
|
|
1004
|
+
return buildVal(false, type, structs, func);
|
|
1005
|
+
}
|
|
1006
|
+
function fromApiArray(values, types, structs) {
|
|
1007
|
+
const iter = values.values();
|
|
1008
|
+
return types.map((type) => fromApiVal(iter, type, structs));
|
|
921
1009
|
}
|
|
1010
|
+
exports.fromApiArray = fromApiArray;
|
|
922
1011
|
function fromApiEventFields(vals, eventSig, systemEvent = false) {
|
|
923
|
-
|
|
1012
|
+
const iter = vals.values();
|
|
1013
|
+
return eventSig.fieldNames.reduce((acc, name, index) => {
|
|
1014
|
+
const type = eventSig.fieldTypes[`${index}`];
|
|
1015
|
+
// currently event does not support struct type
|
|
1016
|
+
acc[`${name}`] = fromApiVal(iter, type, [], systemEvent);
|
|
1017
|
+
return acc;
|
|
1018
|
+
}, {});
|
|
924
1019
|
}
|
|
1020
|
+
exports.fromApiEventFields = fromApiEventFields;
|
|
925
1021
|
function toApiAsset(asset) {
|
|
926
1022
|
return {
|
|
927
1023
|
attoAlphAmount: (0, api_1.toApiNumber256)(asset.alphAmount),
|
|
@@ -934,48 +1030,32 @@ function fromApiAsset(asset) {
|
|
|
934
1030
|
tokens: (0, api_1.fromApiTokens)(asset.tokens)
|
|
935
1031
|
};
|
|
936
1032
|
}
|
|
937
|
-
function
|
|
938
|
-
if (name in vals) {
|
|
939
|
-
return vals[`${name}`];
|
|
940
|
-
}
|
|
941
|
-
else {
|
|
942
|
-
throw Error(`No Val exists for ${name}`);
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
function extractFields(fields, fieldsSig, mutable) {
|
|
946
|
-
const fieldIndexes = fieldsSig.names
|
|
947
|
-
.map((_, index) => index)
|
|
948
|
-
.filter((index) => fieldsSig.isMutable[`${index}`] === mutable);
|
|
949
|
-
const fieldNames = fieldIndexes.map((index) => fieldsSig.names[`${index}`]);
|
|
950
|
-
const fieldTypes = fieldIndexes.map((index) => fieldsSig.types[`${index}`]);
|
|
951
|
-
return toApiVals(fields, fieldNames, fieldTypes);
|
|
952
|
-
}
|
|
953
|
-
function toApiContractState(state) {
|
|
1033
|
+
function toApiContractState(state, structs) {
|
|
954
1034
|
const stateFields = state.fields ?? {};
|
|
1035
|
+
const fieldsSig = state.fieldsSig;
|
|
1036
|
+
const allFields = ralph.flattenFields(stateFields, fieldsSig.names, fieldsSig.types, fieldsSig.isMutable, structs);
|
|
1037
|
+
const immFields = allFields.filter((f) => !f.isMutable).map((f) => (0, api_1.toApiVal)(f.value, f.type));
|
|
1038
|
+
const mutFields = allFields.filter((f) => f.isMutable).map((f) => (0, api_1.toApiVal)(f.value, f.type));
|
|
955
1039
|
return {
|
|
956
1040
|
address: state.address,
|
|
957
1041
|
bytecode: state.bytecode,
|
|
958
1042
|
codeHash: state.codeHash,
|
|
959
1043
|
initialStateHash: state.initialStateHash,
|
|
960
|
-
immFields
|
|
961
|
-
mutFields
|
|
1044
|
+
immFields,
|
|
1045
|
+
mutFields,
|
|
962
1046
|
asset: toApiAsset(state.asset)
|
|
963
1047
|
};
|
|
964
1048
|
}
|
|
965
|
-
function toApiFields(fields, fieldsSig) {
|
|
966
|
-
return
|
|
1049
|
+
function toApiFields(fields, fieldsSig, structs) {
|
|
1050
|
+
return ralph
|
|
1051
|
+
.flattenFields(fields, fieldsSig.names, fieldsSig.types, fieldsSig.isMutable, structs)
|
|
1052
|
+
.map((f) => (0, api_1.toApiVal)(f.value, f.type));
|
|
967
1053
|
}
|
|
968
|
-
function toApiArgs(args, funcSig) {
|
|
969
|
-
return
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
return names.map((name, index) => {
|
|
973
|
-
const val = getVal(fields, name);
|
|
974
|
-
const tpe = types[`${index}`];
|
|
975
|
-
return (0, api_1.toApiVal)(val, tpe);
|
|
976
|
-
});
|
|
1054
|
+
function toApiArgs(args, funcSig, structs) {
|
|
1055
|
+
return ralph
|
|
1056
|
+
.flattenFields(args, funcSig.paramNames, funcSig.paramTypes, funcSig.paramIsMutable, structs)
|
|
1057
|
+
.map((f) => (0, api_1.toApiVal)(f.value, f.type));
|
|
977
1058
|
}
|
|
978
|
-
exports.toApiVals = toApiVals;
|
|
979
1059
|
function toApiInputAsset(inputAsset) {
|
|
980
1060
|
return { address: inputAsset.address, asset: toApiAsset(inputAsset.asset) };
|
|
981
1061
|
}
|
|
@@ -1175,9 +1255,7 @@ function decodeEvent(contract, instance, event, targetEventIndex) {
|
|
|
1175
1255
|
throw new Error('Invalid event index: ' + event.eventIndex + ', expected: ' + targetEventIndex);
|
|
1176
1256
|
}
|
|
1177
1257
|
const eventSig = contract.eventsSig[`${targetEventIndex}`];
|
|
1178
|
-
const
|
|
1179
|
-
const fieldTypes = eventSig.fieldTypes;
|
|
1180
|
-
const fields = (0, api_1.fromApiVals)(event.fields, fieldNames, fieldTypes);
|
|
1258
|
+
const fields = fromApiEventFields(event.fields, eventSig);
|
|
1181
1259
|
return {
|
|
1182
1260
|
contractAddress: instance.address,
|
|
1183
1261
|
blockHash: event.blockHash,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Val } from '../api';
|
|
2
|
-
import { Fields, FieldsSig } from './contract';
|
|
2
|
+
import { Fields, FieldsSig, Struct } from './contract';
|
|
3
3
|
export declare function encodeBool(bool: boolean): Uint8Array;
|
|
4
4
|
export declare function encodeI256(i256: bigint): Uint8Array;
|
|
5
5
|
export declare function encodeU256(u256: bigint): Uint8Array;
|
|
@@ -19,12 +19,13 @@ export declare function encodeVmByteVec(bytes: string): Uint8Array;
|
|
|
19
19
|
export declare function encodeVmAddress(address: string): Uint8Array;
|
|
20
20
|
export declare function encodeScriptFieldAsString(tpe: string, value: Val): string;
|
|
21
21
|
export declare function encodeScriptField(tpe: string, value: Val): Uint8Array;
|
|
22
|
-
export declare function
|
|
22
|
+
export declare function flattenFields(fields: Fields, names: string[], types: string[], isMutable: boolean[], structs: Struct[]): {
|
|
23
23
|
name: string;
|
|
24
24
|
type: string;
|
|
25
25
|
value: Val;
|
|
26
|
+
isMutable: boolean;
|
|
26
27
|
}[];
|
|
27
|
-
export declare function buildScriptByteCode(bytecodeTemplate: string, fields: Fields, fieldsSig: FieldsSig): string;
|
|
28
|
-
export declare function buildContractByteCode(bytecode: string, fields: Fields, fieldsSig: FieldsSig): string;
|
|
29
|
-
export declare function encodeContractField(tpe: string, value: Val): Uint8Array
|
|
28
|
+
export declare function buildScriptByteCode(bytecodeTemplate: string, fields: Fields, fieldsSig: FieldsSig, structs: Struct[]): string;
|
|
29
|
+
export declare function buildContractByteCode(bytecode: string, fields: Fields, fieldsSig: FieldsSig, structs: Struct[]): string;
|
|
30
|
+
export declare function encodeContractField(tpe: string, value: Val): Uint8Array;
|
|
30
31
|
export declare function buildDebugBytecode(bytecode: string, bytecodePatch: string): string;
|