@alephium/web3 0.35.0 → 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 +168 -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 +219 -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);
|
|
@@ -774,6 +826,7 @@ class Contract extends Artifact {
|
|
|
774
826
|
bytecode: bytecode,
|
|
775
827
|
initialAttoAlphAmount: params?.initialAttoAlphAmount,
|
|
776
828
|
issueTokenAmount: params?.issueTokenAmount,
|
|
829
|
+
issueTokenTo: params?.issueTokenTo,
|
|
777
830
|
initialTokenAmounts: params?.initialTokenAmounts,
|
|
778
831
|
gasAmount: params?.gasAmount,
|
|
779
832
|
gasPrice: params?.gasPrice
|
|
@@ -782,7 +835,7 @@ class Contract extends Artifact {
|
|
|
782
835
|
}
|
|
783
836
|
buildByteCodeToDeploy(initialFields, isDevnet) {
|
|
784
837
|
try {
|
|
785
|
-
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);
|
|
786
839
|
}
|
|
787
840
|
catch (error) {
|
|
788
841
|
throw new Error(`Failed to build bytecode for contract ${this.name}, error: ${error}`);
|
|
@@ -802,7 +855,7 @@ class Contract extends Artifact {
|
|
|
802
855
|
}
|
|
803
856
|
toApiCallContract(params, groupIndex, contractAddress, methodIndex) {
|
|
804
857
|
const functionSig = this.functions[`${methodIndex}`];
|
|
805
|
-
const args =
|
|
858
|
+
const args = toApiArgs(params.args ?? {}, functionSig, this.structs);
|
|
806
859
|
return {
|
|
807
860
|
...params,
|
|
808
861
|
group: groupIndex,
|
|
@@ -814,7 +867,7 @@ class Contract extends Artifact {
|
|
|
814
867
|
fromApiCallContractResult(result, txId, methodIndex, getContractByCodeHash) {
|
|
815
868
|
const returnTypes = this.functions[`${methodIndex}`].returnTypes;
|
|
816
869
|
const callResult = tryGetCallResult(result);
|
|
817
|
-
const rawReturn =
|
|
870
|
+
const rawReturn = fromApiArray(callResult.returns, returnTypes, this.structs);
|
|
818
871
|
const returns = rawReturn.length === 0 ? null : rawReturn.length === 1 ? rawReturn[0] : rawReturn;
|
|
819
872
|
const addressToCodeHash = new Map();
|
|
820
873
|
callResult.contracts.forEach((contract) => addressToCodeHash.set(contract.address, contract.codeHash));
|
|
@@ -843,17 +896,18 @@ Contract.ContractDestroyedEvent = {
|
|
|
843
896
|
fieldTypes: ['Address']
|
|
844
897
|
};
|
|
845
898
|
class Script extends Artifact {
|
|
846
|
-
constructor(version, name, bytecodeTemplate, bytecodeDebugPatch, fieldsSig, functions) {
|
|
899
|
+
constructor(version, name, bytecodeTemplate, bytecodeDebugPatch, fieldsSig, functions, structs) {
|
|
847
900
|
super(version, name, functions);
|
|
848
901
|
this.bytecodeTemplate = bytecodeTemplate;
|
|
849
902
|
this.bytecodeDebugPatch = bytecodeDebugPatch;
|
|
850
903
|
this.fieldsSig = fieldsSig;
|
|
904
|
+
this.structs = structs;
|
|
851
905
|
}
|
|
852
|
-
static fromCompileResult(result) {
|
|
853
|
-
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);
|
|
854
908
|
}
|
|
855
909
|
// TODO: safely parse json
|
|
856
|
-
static fromJson(artifact, bytecodeDebugPatch = '') {
|
|
910
|
+
static fromJson(artifact, bytecodeDebugPatch = '', structs = []) {
|
|
857
911
|
if (artifact.version == null ||
|
|
858
912
|
artifact.name == null ||
|
|
859
913
|
artifact.bytecodeTemplate == null ||
|
|
@@ -861,12 +915,12 @@ class Script extends Artifact {
|
|
|
861
915
|
artifact.functions == null) {
|
|
862
916
|
throw Error('The artifact JSON for script is incomplete');
|
|
863
917
|
}
|
|
864
|
-
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);
|
|
865
919
|
}
|
|
866
|
-
static async fromArtifactFile(path, bytecodeDebugPatch) {
|
|
920
|
+
static async fromArtifactFile(path, bytecodeDebugPatch, structs = []) {
|
|
867
921
|
const content = await fs_2.promises.readFile(path);
|
|
868
922
|
const artifact = JSON.parse(content.toString());
|
|
869
|
-
return this.fromJson(artifact, bytecodeDebugPatch);
|
|
923
|
+
return this.fromJson(artifact, bytecodeDebugPatch, structs);
|
|
870
924
|
}
|
|
871
925
|
toString() {
|
|
872
926
|
const object = {
|
|
@@ -893,7 +947,7 @@ class Script extends Artifact {
|
|
|
893
947
|
}
|
|
894
948
|
buildByteCodeToDeploy(initialFields) {
|
|
895
949
|
try {
|
|
896
|
-
return ralph.buildScriptByteCode(this.bytecodeTemplate, initialFields, this.fieldsSig);
|
|
950
|
+
return ralph.buildScriptByteCode(this.bytecodeTemplate, initialFields, this.fieldsSig, this.structs);
|
|
897
951
|
}
|
|
898
952
|
catch (error) {
|
|
899
953
|
throw new Error(`Failed to build bytecode for script ${this.name}, error: ${error}`);
|
|
@@ -901,26 +955,69 @@ class Script extends Artifact {
|
|
|
901
955
|
}
|
|
902
956
|
}
|
|
903
957
|
exports.Script = Script;
|
|
904
|
-
function fromApiFields(immFields, mutFields, fieldsSig) {
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
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));
|
|
920
1009
|
}
|
|
1010
|
+
exports.fromApiArray = fromApiArray;
|
|
921
1011
|
function fromApiEventFields(vals, eventSig, systemEvent = false) {
|
|
922
|
-
|
|
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
|
+
}, {});
|
|
923
1019
|
}
|
|
1020
|
+
exports.fromApiEventFields = fromApiEventFields;
|
|
924
1021
|
function toApiAsset(asset) {
|
|
925
1022
|
return {
|
|
926
1023
|
attoAlphAmount: (0, api_1.toApiNumber256)(asset.alphAmount),
|
|
@@ -933,48 +1030,32 @@ function fromApiAsset(asset) {
|
|
|
933
1030
|
tokens: (0, api_1.fromApiTokens)(asset.tokens)
|
|
934
1031
|
};
|
|
935
1032
|
}
|
|
936
|
-
function
|
|
937
|
-
if (name in vals) {
|
|
938
|
-
return vals[`${name}`];
|
|
939
|
-
}
|
|
940
|
-
else {
|
|
941
|
-
throw Error(`No Val exists for ${name}`);
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
function extractFields(fields, fieldsSig, mutable) {
|
|
945
|
-
const fieldIndexes = fieldsSig.names
|
|
946
|
-
.map((_, index) => index)
|
|
947
|
-
.filter((index) => fieldsSig.isMutable[`${index}`] === mutable);
|
|
948
|
-
const fieldNames = fieldIndexes.map((index) => fieldsSig.names[`${index}`]);
|
|
949
|
-
const fieldTypes = fieldIndexes.map((index) => fieldsSig.types[`${index}`]);
|
|
950
|
-
return toApiVals(fields, fieldNames, fieldTypes);
|
|
951
|
-
}
|
|
952
|
-
function toApiContractState(state) {
|
|
1033
|
+
function toApiContractState(state, structs) {
|
|
953
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));
|
|
954
1039
|
return {
|
|
955
1040
|
address: state.address,
|
|
956
1041
|
bytecode: state.bytecode,
|
|
957
1042
|
codeHash: state.codeHash,
|
|
958
1043
|
initialStateHash: state.initialStateHash,
|
|
959
|
-
immFields
|
|
960
|
-
mutFields
|
|
1044
|
+
immFields,
|
|
1045
|
+
mutFields,
|
|
961
1046
|
asset: toApiAsset(state.asset)
|
|
962
1047
|
};
|
|
963
1048
|
}
|
|
964
|
-
function toApiFields(fields, fieldsSig) {
|
|
965
|
-
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));
|
|
966
1053
|
}
|
|
967
|
-
function toApiArgs(args, funcSig) {
|
|
968
|
-
return
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
return names.map((name, index) => {
|
|
972
|
-
const val = getVal(fields, name);
|
|
973
|
-
const tpe = types[`${index}`];
|
|
974
|
-
return (0, api_1.toApiVal)(val, tpe);
|
|
975
|
-
});
|
|
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));
|
|
976
1058
|
}
|
|
977
|
-
exports.toApiVals = toApiVals;
|
|
978
1059
|
function toApiInputAsset(inputAsset) {
|
|
979
1060
|
return { address: inputAsset.address, asset: toApiAsset(inputAsset.asset) };
|
|
980
1061
|
}
|
|
@@ -1174,9 +1255,7 @@ function decodeEvent(contract, instance, event, targetEventIndex) {
|
|
|
1174
1255
|
throw new Error('Invalid event index: ' + event.eventIndex + ', expected: ' + targetEventIndex);
|
|
1175
1256
|
}
|
|
1176
1257
|
const eventSig = contract.eventsSig[`${targetEventIndex}`];
|
|
1177
|
-
const
|
|
1178
|
-
const fieldTypes = eventSig.fieldTypes;
|
|
1179
|
-
const fields = (0, api_1.fromApiVals)(event.fields, fieldNames, fieldTypes);
|
|
1258
|
+
const fields = fromApiEventFields(event.fields, eventSig);
|
|
1180
1259
|
return {
|
|
1181
1260
|
contractAddress: instance.address,
|
|
1182
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;
|