@alephium/web3 0.4.0 → 0.5.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +5 -3
- package/dist/src/api/api-alephium.js +1 -1
- package/dist/src/api/types.d.ts +1 -0
- package/dist/src/api/types.js +9 -1
- package/dist/src/constants.d.ts +1 -0
- package/dist/src/constants.js +2 -1
- package/dist/src/contract/contract.d.ts +90 -49
- package/dist/src/contract/contract.js +297 -77
- package/dist/src/contract/ralph.js +12 -3
- package/dist/src/signer/tx-builder.js +2 -2
- package/dist/src/signer/types.d.ts +2 -4
- package/dist/src/utils/utils.d.ts +1 -0
- package/dist/src/utils/utils.js +3 -1
- package/package.json +3 -3
- package/src/api/api-alephium.ts +5 -3
- package/src/api/types.ts +8 -0
- package/src/constants.ts +1 -0
- package/src/contract/contract.ts +472 -143
- package/src/contract/ralph.ts +13 -3
- package/src/signer/tx-builder.ts +2 -2
- package/src/signer/types.ts +14 -6
- package/src/utils/utils.ts +4 -1
|
@@ -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.Script = exports.Contract = exports.Artifact = exports.Project = exports.DEFAULT_COMPILER_OPTIONS = exports.DEFAULT_NODE_COMPILER_OPTIONS = void 0;
|
|
46
|
+
exports.callMethod = exports.subscribeAllEvents = exports.subscribeContractEvent = exports.decodeEvent = exports.subscribeContractDestroyedEvent = exports.subscribeContractCreatedEvent = exports.fetchContractState = exports.ContractInstance = exports.testMethod = exports.subscribeEventsFromContract = exports.decodeContractDestroyedEvent = exports.decodeContractCreatedEvent = exports.ContractFactory = exports.randomTxId = exports.toApiVals = exports.Script = exports.Contract = exports.Artifact = exports.Project = exports.DEFAULT_COMPILER_OPTIONS = exports.DEFAULT_NODE_COMPILER_OPTIONS = void 0;
|
|
47
47
|
const buffer_1 = require("buffer/");
|
|
48
48
|
const crypto_1 = require("crypto");
|
|
49
49
|
const fs_1 = __importDefault(require("fs"));
|
|
@@ -52,8 +52,9 @@ const api_1 = require("../api");
|
|
|
52
52
|
const ralph = __importStar(require("./ralph"));
|
|
53
53
|
const utils_1 = require("../utils");
|
|
54
54
|
const global_1 = require("../global");
|
|
55
|
-
const __1 = require("..");
|
|
56
55
|
const path = __importStar(require("path"));
|
|
56
|
+
const events_1 = require("./events");
|
|
57
|
+
const constants_1 = require("../constants");
|
|
57
58
|
var SourceKind;
|
|
58
59
|
(function (SourceKind) {
|
|
59
60
|
SourceKind[SourceKind["Contract"] = 0] = "Contract";
|
|
@@ -249,7 +250,7 @@ class Project {
|
|
|
249
250
|
}
|
|
250
251
|
return script.artifact;
|
|
251
252
|
}
|
|
252
|
-
async saveArtifactsToFile() {
|
|
253
|
+
async saveArtifactsToFile(projectRootDir) {
|
|
253
254
|
const artifactsRootDir = this.artifactsRootDir;
|
|
254
255
|
const saveToFile = async function (compiled) {
|
|
255
256
|
const artifactPath = compiled.sourceInfo.getArtifactPath(artifactsRootDir);
|
|
@@ -261,7 +262,7 @@ class Project {
|
|
|
261
262
|
};
|
|
262
263
|
this.contracts.forEach((contract) => saveToFile(contract));
|
|
263
264
|
this.scripts.forEach((script) => saveToFile(script));
|
|
264
|
-
await this.projectArtifact.saveToFile(
|
|
265
|
+
await this.projectArtifact.saveToFile(projectRootDir);
|
|
265
266
|
}
|
|
266
267
|
contractByCodeHash(codeHash) {
|
|
267
268
|
const contract = [...this.contracts.values()].find((c) => c.artifact.codeHash === codeHash || c.artifact.codeHashDebug == codeHash);
|
|
@@ -270,7 +271,7 @@ class Project {
|
|
|
270
271
|
}
|
|
271
272
|
return contract.artifact;
|
|
272
273
|
}
|
|
273
|
-
static async compile(provider, sourceInfos, contractsRootDir, artifactsRootDir, errorOnWarnings, compilerOptions) {
|
|
274
|
+
static async compile(provider, sourceInfos, projectRootDir, contractsRootDir, artifactsRootDir, errorOnWarnings, compilerOptions) {
|
|
274
275
|
const sourceStr = sourceInfos.map((f) => f.sourceCode).join('\n');
|
|
275
276
|
const result = await provider.contracts.postContractsCompileProject({
|
|
276
277
|
code: sourceStr,
|
|
@@ -290,10 +291,10 @@ class Project {
|
|
|
290
291
|
});
|
|
291
292
|
const projectArtifact = Project.buildProjectArtifact(sourceInfos, contracts, scripts, compilerOptions);
|
|
292
293
|
const project = new Project(contractsRootDir, artifactsRootDir, sourceInfos, contracts, scripts, errorOnWarnings, projectArtifact);
|
|
293
|
-
await project.saveArtifactsToFile();
|
|
294
|
+
await project.saveArtifactsToFile(projectRootDir);
|
|
294
295
|
return project;
|
|
295
296
|
}
|
|
296
|
-
static async loadArtifacts(provider, sourceInfos, projectArtifact, contractsRootDir, artifactsRootDir, errorOnWarnings, compilerOptions) {
|
|
297
|
+
static async loadArtifacts(provider, sourceInfos, projectArtifact, projectRootDir, contractsRootDir, artifactsRootDir, errorOnWarnings, compilerOptions) {
|
|
297
298
|
try {
|
|
298
299
|
const contracts = new Map();
|
|
299
300
|
const scripts = new Map();
|
|
@@ -317,7 +318,7 @@ class Project {
|
|
|
317
318
|
}
|
|
318
319
|
catch (error) {
|
|
319
320
|
console.log(`Failed to load artifacts, error: ${error}, try to re-compile contracts...`);
|
|
320
|
-
return Project.compile(provider, sourceInfos, contractsRootDir, artifactsRootDir, errorOnWarnings, compilerOptions);
|
|
321
|
+
return Project.compile(provider, sourceInfos, projectRootDir, contractsRootDir, artifactsRootDir, errorOnWarnings, compilerOptions);
|
|
321
322
|
}
|
|
322
323
|
}
|
|
323
324
|
static getImportSourcePath(projectRootDir, importPath) {
|
|
@@ -406,14 +407,14 @@ class Project {
|
|
|
406
407
|
const provider = (0, global_1.getCurrentNodeProvider)();
|
|
407
408
|
const sourceFiles = await Project.loadSourceFiles(projectRootDir, contractsRootDir);
|
|
408
409
|
const { errorOnWarnings, ...nodeCompilerOptions } = { ...exports.DEFAULT_COMPILER_OPTIONS, ...compilerOptionsPartial };
|
|
409
|
-
const projectArtifact = await ProjectArtifact.from(
|
|
410
|
+
const projectArtifact = await ProjectArtifact.from(projectRootDir);
|
|
410
411
|
if (typeof projectArtifact === 'undefined' || projectArtifact.needToReCompile(nodeCompilerOptions, sourceFiles)) {
|
|
411
412
|
console.log(`Compiling contracts in folder "${contractsRootDir}"`);
|
|
412
|
-
Project.currentProject = await Project.compile(provider, sourceFiles, contractsRootDir, artifactsRootDir, errorOnWarnings, nodeCompilerOptions);
|
|
413
|
+
Project.currentProject = await Project.compile(provider, sourceFiles, projectRootDir, contractsRootDir, artifactsRootDir, errorOnWarnings, nodeCompilerOptions);
|
|
413
414
|
}
|
|
414
415
|
else {
|
|
415
416
|
console.log(`Contracts are compiled already. Loading them from folder "${artifactsRootDir}"`);
|
|
416
|
-
Project.currentProject = await Project.loadArtifacts(provider, sourceFiles, projectArtifact, contractsRootDir, artifactsRootDir, errorOnWarnings, nodeCompilerOptions);
|
|
417
|
+
Project.currentProject = await Project.loadArtifacts(provider, sourceFiles, projectArtifact, projectRootDir, contractsRootDir, artifactsRootDir, errorOnWarnings, nodeCompilerOptions);
|
|
417
418
|
}
|
|
418
419
|
}
|
|
419
420
|
}
|
|
@@ -482,12 +483,6 @@ class Contract extends Artifact {
|
|
|
482
483
|
const artifact = JSON.parse(content.toString());
|
|
483
484
|
return Contract.fromJson(artifact, bytecodeDebugPatch, codeHashDebug);
|
|
484
485
|
}
|
|
485
|
-
async fetchState(address, group) {
|
|
486
|
-
const state = await __1.web3.getCurrentNodeProvider().contracts.getContractsAddressState(address, {
|
|
487
|
-
group: group
|
|
488
|
-
});
|
|
489
|
-
return this.fromApiContractState(state);
|
|
490
|
-
}
|
|
491
486
|
toString() {
|
|
492
487
|
const object = {
|
|
493
488
|
version: this.version,
|
|
@@ -519,34 +514,12 @@ class Contract extends Artifact {
|
|
|
519
514
|
bytes[0] = 3;
|
|
520
515
|
return utils_1.bs58.encode(bytes);
|
|
521
516
|
}
|
|
522
|
-
|
|
517
|
+
printDebugMessages(funcName, messages) {
|
|
523
518
|
if (messages.length != 0) {
|
|
524
519
|
console.log(`Testing ${this.name}.${funcName}:`);
|
|
525
520
|
messages.forEach((m) => console.log(`Debug - ${m.contractAddress} - ${m.message}`));
|
|
526
521
|
}
|
|
527
522
|
}
|
|
528
|
-
async _test(funcName, params, expectPublic, accessType, printDebugMessages) {
|
|
529
|
-
const apiParams = this.toTestContract(funcName, params);
|
|
530
|
-
const apiResult = await __1.web3.getCurrentNodeProvider().contracts.postContractsTestContract(apiParams);
|
|
531
|
-
const methodIndex = typeof params.testMethodIndex !== 'undefined' ? params.testMethodIndex : this.getMethodIndex(funcName);
|
|
532
|
-
const isPublic = this.functions[`${methodIndex}`].isPublic;
|
|
533
|
-
if (printDebugMessages) {
|
|
534
|
-
this._printDebugMessages(funcName, apiResult.debugMessages);
|
|
535
|
-
}
|
|
536
|
-
if (isPublic === expectPublic) {
|
|
537
|
-
const result = await this.fromTestContractResult(methodIndex, apiResult);
|
|
538
|
-
return result;
|
|
539
|
-
}
|
|
540
|
-
else {
|
|
541
|
-
throw new Error(`The test method ${funcName} is not ${accessType}`);
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
async testPublicMethod(funcName, params, printDebugMessages = true) {
|
|
545
|
-
return this._test(funcName, params, true, 'public', printDebugMessages);
|
|
546
|
-
}
|
|
547
|
-
async testPrivateMethod(funcName, params, printDebugMessages = true) {
|
|
548
|
-
return this._test(funcName, params, false, 'private', printDebugMessages);
|
|
549
|
-
}
|
|
550
523
|
toApiFields(fields) {
|
|
551
524
|
if (typeof fields === 'undefined') {
|
|
552
525
|
return [];
|
|
@@ -573,12 +546,15 @@ class Contract extends Artifact {
|
|
|
573
546
|
toApiContractStates(states) {
|
|
574
547
|
return typeof states != 'undefined' ? states.map((state) => toApiContractState(state)) : undefined;
|
|
575
548
|
}
|
|
576
|
-
|
|
549
|
+
toApiTestContractParams(funcName, params) {
|
|
550
|
+
const immFields = params.initialFields === undefined ? [] : extractFields(params.initialFields, this.fieldsSig, false);
|
|
551
|
+
const mutFields = params.initialFields === undefined ? [] : extractFields(params.initialFields, this.fieldsSig, true);
|
|
577
552
|
return {
|
|
578
553
|
group: params.group,
|
|
579
554
|
address: params.address,
|
|
580
555
|
bytecode: this.bytecodeDebug,
|
|
581
|
-
|
|
556
|
+
initialImmFields: immFields,
|
|
557
|
+
initialMutFields: mutFields,
|
|
582
558
|
initialAsset: typeof params.initialAsset !== 'undefined' ? toApiAsset(params.initialAsset) : undefined,
|
|
583
559
|
methodIndex: this.getMethodIndex(funcName),
|
|
584
560
|
args: this.toApiArgs(funcName, params.testArgs),
|
|
@@ -593,7 +569,7 @@ class Contract extends Artifact {
|
|
|
593
569
|
bytecode: state.bytecode,
|
|
594
570
|
initialStateHash: state.initialStateHash,
|
|
595
571
|
codeHash: state.codeHash,
|
|
596
|
-
fields: fromApiFields(state.
|
|
572
|
+
fields: fromApiFields(state.immFields, state.mutFields, this.fieldsSig),
|
|
597
573
|
fieldsSig: this.fieldsSig,
|
|
598
574
|
asset: fromApiAsset(state.asset)
|
|
599
575
|
};
|
|
@@ -602,12 +578,12 @@ class Contract extends Artifact {
|
|
|
602
578
|
const contract = Project.currentProject.contractByCodeHash(state.codeHash);
|
|
603
579
|
return contract.fromApiContractState(state);
|
|
604
580
|
}
|
|
605
|
-
static fromApiEvent(event, codeHash) {
|
|
581
|
+
static fromApiEvent(event, codeHash, txId) {
|
|
606
582
|
let eventSig;
|
|
607
|
-
if (event.eventIndex ==
|
|
583
|
+
if (event.eventIndex == Contract.ContractCreatedEventIndex) {
|
|
608
584
|
eventSig = this.ContractCreatedEvent;
|
|
609
585
|
}
|
|
610
|
-
else if (event.eventIndex ==
|
|
586
|
+
else if (event.eventIndex == Contract.ContractDestroyedEventIndex) {
|
|
611
587
|
eventSig = this.ContractDestroyedEvent;
|
|
612
588
|
}
|
|
613
589
|
else {
|
|
@@ -615,63 +591,96 @@ class Contract extends Artifact {
|
|
|
615
591
|
eventSig = contract.eventsSig[event.eventIndex];
|
|
616
592
|
}
|
|
617
593
|
return {
|
|
594
|
+
txId: txId,
|
|
618
595
|
blockHash: event.blockHash,
|
|
619
596
|
contractAddress: event.contractAddress,
|
|
620
597
|
name: eventSig.name,
|
|
598
|
+
eventIndex: event.eventIndex,
|
|
621
599
|
fields: fromApiEventFields(event.fields, eventSig)
|
|
622
600
|
};
|
|
623
601
|
}
|
|
624
|
-
|
|
602
|
+
fromApiTestContractResult(methodName, result, txId) {
|
|
603
|
+
const methodIndex = this.functions.findIndex((sig) => sig.name === methodName);
|
|
604
|
+
const returnTypes = this.functions[`${methodIndex}`].returnTypes;
|
|
605
|
+
const rawReturn = (0, api_1.fromApiArray)(result.returns, returnTypes);
|
|
606
|
+
const returns = rawReturn.length === 0 ? null : rawReturn.length === 1 ? rawReturn[0] : rawReturn;
|
|
625
607
|
const addressToCodeHash = new Map();
|
|
626
608
|
addressToCodeHash.set(result.address, result.codeHash);
|
|
627
609
|
result.contracts.forEach((contract) => addressToCodeHash.set(contract.address, contract.codeHash));
|
|
628
610
|
return {
|
|
629
611
|
contractId: (0, utils_1.binToHex)((0, utils_1.contractIdFromAddress)(result.address)),
|
|
630
612
|
contractAddress: result.address,
|
|
631
|
-
returns:
|
|
613
|
+
returns: returns,
|
|
632
614
|
gasUsed: result.gasUsed,
|
|
633
615
|
contracts: result.contracts.map((contract) => Contract.fromApiContractState(contract)),
|
|
634
616
|
txOutputs: result.txOutputs.map(fromApiOutput),
|
|
635
|
-
events: result.events
|
|
636
|
-
const contractAddress = event.contractAddress;
|
|
637
|
-
const codeHash = addressToCodeHash.get(contractAddress);
|
|
638
|
-
if (typeof codeHash !== 'undefined' || event.eventIndex < 0) {
|
|
639
|
-
return Contract.fromApiEvent(event, codeHash);
|
|
640
|
-
}
|
|
641
|
-
else {
|
|
642
|
-
throw Error(`Cannot find codeHash for the contract address: ${contractAddress}`);
|
|
643
|
-
}
|
|
644
|
-
}),
|
|
617
|
+
events: Contract.fromApiEvents(result.events, addressToCodeHash, txId),
|
|
645
618
|
debugMessages: result.debugMessages
|
|
646
619
|
};
|
|
647
620
|
}
|
|
648
621
|
async txParamsForDeployment(signer, params) {
|
|
649
|
-
const bytecode = this.buildByteCodeToDeploy(params.initialFields
|
|
622
|
+
const bytecode = this.buildByteCodeToDeploy(params.initialFields ?? {});
|
|
650
623
|
const signerParams = {
|
|
651
624
|
signerAddress: await signer.getSelectedAddress(),
|
|
652
625
|
bytecode: bytecode,
|
|
653
|
-
initialAttoAlphAmount: params
|
|
654
|
-
issueTokenAmount: params
|
|
655
|
-
initialTokenAmounts: params
|
|
656
|
-
gasAmount: params
|
|
657
|
-
gasPrice: params
|
|
626
|
+
initialAttoAlphAmount: params?.initialAttoAlphAmount,
|
|
627
|
+
issueTokenAmount: params?.issueTokenAmount,
|
|
628
|
+
initialTokenAmounts: params?.initialTokenAmounts,
|
|
629
|
+
gasAmount: params?.gasAmount,
|
|
630
|
+
gasPrice: params?.gasPrice
|
|
658
631
|
};
|
|
659
632
|
return signerParams;
|
|
660
633
|
}
|
|
661
|
-
async deploy(signer, params) {
|
|
662
|
-
const signerParams = await this.txParamsForDeployment(signer, params);
|
|
663
|
-
return signer.signAndSubmitDeployContractTx(signerParams);
|
|
664
|
-
}
|
|
665
634
|
buildByteCodeToDeploy(initialFields) {
|
|
666
635
|
return ralph.buildContractByteCode(this.bytecode, initialFields, this.fieldsSig);
|
|
667
636
|
}
|
|
637
|
+
static fromApiEvents(events, addressToCodeHash, txId) {
|
|
638
|
+
return events.map((event) => {
|
|
639
|
+
const contractAddress = event.contractAddress;
|
|
640
|
+
const codeHash = addressToCodeHash.get(contractAddress);
|
|
641
|
+
if (typeof codeHash !== 'undefined' || event.eventIndex < 0) {
|
|
642
|
+
return Contract.fromApiEvent(event, codeHash, txId);
|
|
643
|
+
}
|
|
644
|
+
else {
|
|
645
|
+
throw Error(`Cannot find codeHash for the contract address: ${contractAddress}`);
|
|
646
|
+
}
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
toApiCallContract(params, groupIndex, contractAddress, methodIndex) {
|
|
650
|
+
const functionSig = this.functions[`${methodIndex}`];
|
|
651
|
+
const args = toApiVals(params.args ?? {}, functionSig.paramNames, functionSig.paramTypes);
|
|
652
|
+
return {
|
|
653
|
+
...params,
|
|
654
|
+
group: groupIndex,
|
|
655
|
+
address: contractAddress,
|
|
656
|
+
methodIndex: methodIndex,
|
|
657
|
+
args: args
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
fromApiCallContractResult(result, txId, methodIndex) {
|
|
661
|
+
const returnTypes = this.functions[`${methodIndex}`].returnTypes;
|
|
662
|
+
const rawReturn = (0, api_1.fromApiArray)(result.returns, returnTypes);
|
|
663
|
+
const returns = rawReturn.length === 0 ? null : rawReturn.length === 1 ? rawReturn[0] : rawReturn;
|
|
664
|
+
const addressToCodeHash = new Map();
|
|
665
|
+
result.contracts.forEach((contract) => addressToCodeHash.set(contract.address, contract.codeHash));
|
|
666
|
+
return {
|
|
667
|
+
returns: returns,
|
|
668
|
+
gasUsed: result.gasUsed,
|
|
669
|
+
contracts: result.contracts.map((state) => Contract.fromApiContractState(state)),
|
|
670
|
+
txInputs: result.txInputs,
|
|
671
|
+
txOutputs: result.txOutputs.map((output) => fromApiOutput(output)),
|
|
672
|
+
events: Contract.fromApiEvents(result.events, addressToCodeHash, txId)
|
|
673
|
+
};
|
|
674
|
+
}
|
|
668
675
|
}
|
|
669
676
|
exports.Contract = Contract;
|
|
677
|
+
Contract.ContractCreatedEventIndex = -1;
|
|
670
678
|
Contract.ContractCreatedEvent = {
|
|
671
679
|
name: 'ContractCreated',
|
|
672
680
|
fieldNames: ['address'],
|
|
673
681
|
fieldTypes: ['Address']
|
|
674
682
|
};
|
|
683
|
+
Contract.ContractDestroyedEventIndex = -2;
|
|
675
684
|
Contract.ContractDestroyedEvent = {
|
|
676
685
|
name: 'ContractDestroyed',
|
|
677
686
|
fieldNames: ['address'],
|
|
@@ -716,7 +725,7 @@ class Script extends Artifact {
|
|
|
716
725
|
async txParamsForExecution(signer, params) {
|
|
717
726
|
const signerParams = {
|
|
718
727
|
signerAddress: await signer.getSelectedAddress(),
|
|
719
|
-
bytecode: this.buildByteCodeToDeploy(params.initialFields
|
|
728
|
+
bytecode: this.buildByteCodeToDeploy(params.initialFields ?? {}),
|
|
720
729
|
attoAlphAmount: params.attoAlphAmount,
|
|
721
730
|
tokens: params.tokens,
|
|
722
731
|
gasAmount: params.gasAmount,
|
|
@@ -724,16 +733,26 @@ class Script extends Artifact {
|
|
|
724
733
|
};
|
|
725
734
|
return signerParams;
|
|
726
735
|
}
|
|
727
|
-
async execute(signer, params) {
|
|
728
|
-
const signerParams = await this.txParamsForExecution(signer, params);
|
|
729
|
-
return await signer.signAndSubmitExecuteScriptTx(signerParams);
|
|
730
|
-
}
|
|
731
736
|
buildByteCodeToDeploy(initialFields) {
|
|
732
737
|
return ralph.buildScriptByteCode(this.bytecodeTemplate, initialFields, this.fieldsSig);
|
|
733
738
|
}
|
|
734
739
|
}
|
|
735
740
|
exports.Script = Script;
|
|
736
|
-
function fromApiFields(
|
|
741
|
+
function fromApiFields(immFields, mutFields, fieldsSig) {
|
|
742
|
+
const vals = [];
|
|
743
|
+
let immIndex = 0;
|
|
744
|
+
let mutIndex = 0;
|
|
745
|
+
const isMutable = fieldsSig.types.flatMap((tpe, index) => Array((0, api_1.typeLength)(tpe)).fill(fieldsSig.isMutable[`${index}`]));
|
|
746
|
+
isMutable.forEach((mutable) => {
|
|
747
|
+
if (mutable) {
|
|
748
|
+
vals.push(mutFields[`${mutIndex}`]);
|
|
749
|
+
mutIndex += 1;
|
|
750
|
+
}
|
|
751
|
+
else {
|
|
752
|
+
vals.push(immFields[`${immIndex}`]);
|
|
753
|
+
immIndex += 1;
|
|
754
|
+
}
|
|
755
|
+
});
|
|
737
756
|
return (0, api_1.fromApiVals)(vals, fieldsSig.names, fieldsSig.types);
|
|
738
757
|
}
|
|
739
758
|
function fromApiEventFields(vals, eventSig) {
|
|
@@ -759,13 +778,23 @@ function getVal(vals, name) {
|
|
|
759
778
|
throw Error(`No Val exists for ${name}`);
|
|
760
779
|
}
|
|
761
780
|
}
|
|
781
|
+
function extractFields(fields, fieldsSig, mutable) {
|
|
782
|
+
const fieldIndexes = fieldsSig.names
|
|
783
|
+
.map((_, index) => index)
|
|
784
|
+
.filter((index) => fieldsSig.isMutable[`${index}`] === mutable);
|
|
785
|
+
const fieldNames = fieldIndexes.map((index) => fieldsSig.names[`${index}`]);
|
|
786
|
+
const fieldTypes = fieldIndexes.map((index) => fieldsSig.types[`${index}`]);
|
|
787
|
+
return toApiVals(fields, fieldNames, fieldTypes);
|
|
788
|
+
}
|
|
762
789
|
function toApiContractState(state) {
|
|
790
|
+
const stateFields = state.fields ?? {};
|
|
763
791
|
return {
|
|
764
792
|
address: state.address,
|
|
765
793
|
bytecode: state.bytecode,
|
|
766
794
|
codeHash: state.codeHash,
|
|
767
795
|
initialStateHash: state.initialStateHash,
|
|
768
|
-
|
|
796
|
+
immFields: extractFields(stateFields, state.fieldsSig, false),
|
|
797
|
+
mutFields: extractFields(stateFields, state.fieldsSig, true),
|
|
769
798
|
asset: toApiAsset(state.asset)
|
|
770
799
|
};
|
|
771
800
|
}
|
|
@@ -782,6 +811,7 @@ function toApiVals(fields, names, types) {
|
|
|
782
811
|
return (0, api_1.toApiVal)(val, tpe);
|
|
783
812
|
});
|
|
784
813
|
}
|
|
814
|
+
exports.toApiVals = toApiVals;
|
|
785
815
|
function toApiInputAsset(inputAsset) {
|
|
786
816
|
return { address: inputAsset.address, asset: toApiAsset(inputAsset.asset) };
|
|
787
817
|
}
|
|
@@ -813,5 +843,195 @@ function fromApiOutput(output) {
|
|
|
813
843
|
throw new Error(`Unknown output type: ${output}`);
|
|
814
844
|
}
|
|
815
845
|
}
|
|
816
|
-
|
|
817
|
-
|
|
846
|
+
function randomTxId() {
|
|
847
|
+
const bytes = new Uint8Array(32);
|
|
848
|
+
crypto_1.webcrypto.getRandomValues(bytes);
|
|
849
|
+
return (0, utils_1.binToHex)(bytes);
|
|
850
|
+
}
|
|
851
|
+
exports.randomTxId = randomTxId;
|
|
852
|
+
utils_1.assertType;
|
|
853
|
+
class ContractFactory {
|
|
854
|
+
constructor(contract) {
|
|
855
|
+
this.contract = contract;
|
|
856
|
+
}
|
|
857
|
+
async deploy(signer, deployParams) {
|
|
858
|
+
const signerParams = await this.contract.txParamsForDeployment(signer, deployParams);
|
|
859
|
+
const result = await signer.signAndSubmitDeployContractTx(signerParams);
|
|
860
|
+
return {
|
|
861
|
+
...result,
|
|
862
|
+
instance: this.at(result.contractAddress)
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
// This is used for testing contract functions
|
|
866
|
+
stateForTest(initFields, asset, address) {
|
|
867
|
+
const newAsset = {
|
|
868
|
+
alphAmount: asset?.alphAmount ?? constants_1.ONE_ALPH,
|
|
869
|
+
tokens: asset?.tokens
|
|
870
|
+
};
|
|
871
|
+
return this.contract.toState(initFields, newAsset, address);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
exports.ContractFactory = ContractFactory;
|
|
875
|
+
function decodeFields(event, eventSig, eventIndex) {
|
|
876
|
+
if (event.eventIndex !== eventIndex) {
|
|
877
|
+
throw new Error(`Invalid event index: ${event.eventIndex}, expected: ${eventIndex}`);
|
|
878
|
+
}
|
|
879
|
+
return (0, api_1.fromApiVals)(event.fields, eventSig.fieldNames, eventSig.fieldTypes);
|
|
880
|
+
}
|
|
881
|
+
function decodeContractCreatedEvent(event) {
|
|
882
|
+
const fields = decodeFields(event, Contract.ContractCreatedEvent, Contract.ContractCreatedEventIndex);
|
|
883
|
+
return {
|
|
884
|
+
blockHash: event.blockHash,
|
|
885
|
+
txId: event.txId,
|
|
886
|
+
eventIndex: event.eventIndex,
|
|
887
|
+
name: Contract.ContractCreatedEvent.name,
|
|
888
|
+
fields: { address: fields['address'] }
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
exports.decodeContractCreatedEvent = decodeContractCreatedEvent;
|
|
892
|
+
function decodeContractDestroyedEvent(event) {
|
|
893
|
+
const fields = decodeFields(event, Contract.ContractDestroyedEvent, Contract.ContractDestroyedEventIndex);
|
|
894
|
+
return {
|
|
895
|
+
blockHash: event.blockHash,
|
|
896
|
+
txId: event.txId,
|
|
897
|
+
eventIndex: event.eventIndex,
|
|
898
|
+
name: Contract.ContractDestroyedEvent.name,
|
|
899
|
+
fields: { address: fields['address'] }
|
|
900
|
+
};
|
|
901
|
+
}
|
|
902
|
+
exports.decodeContractDestroyedEvent = decodeContractDestroyedEvent;
|
|
903
|
+
function subscribeEventsFromContract(options, address, eventIndex, decodeFunc, fromCount) {
|
|
904
|
+
const messageCallback = (event) => {
|
|
905
|
+
if (event.eventIndex !== eventIndex) {
|
|
906
|
+
return Promise.resolve();
|
|
907
|
+
}
|
|
908
|
+
return options.messageCallback(decodeFunc(event));
|
|
909
|
+
};
|
|
910
|
+
const errorCallback = (err, subscription) => {
|
|
911
|
+
return options.errorCallback(err, subscription);
|
|
912
|
+
};
|
|
913
|
+
const opt = {
|
|
914
|
+
pollingInterval: options.pollingInterval,
|
|
915
|
+
messageCallback: messageCallback,
|
|
916
|
+
errorCallback: errorCallback
|
|
917
|
+
};
|
|
918
|
+
return (0, events_1.subscribeToEvents)(opt, address, fromCount);
|
|
919
|
+
}
|
|
920
|
+
exports.subscribeEventsFromContract = subscribeEventsFromContract;
|
|
921
|
+
async function testMethod(contract, methodName, params) {
|
|
922
|
+
const txId = params?.txId ?? randomTxId();
|
|
923
|
+
const apiParams = contract.contract.toApiTestContractParams(methodName, {
|
|
924
|
+
...params,
|
|
925
|
+
txId: txId,
|
|
926
|
+
initialFields: params.initialFields === undefined ? {} : params.initialFields,
|
|
927
|
+
testArgs: params.testArgs === undefined ? {} : params.testArgs
|
|
928
|
+
});
|
|
929
|
+
const apiResult = await (0, global_1.getCurrentNodeProvider)().contracts.postContractsTestContract(apiParams);
|
|
930
|
+
const testResult = contract.contract.fromApiTestContractResult(methodName, apiResult, txId);
|
|
931
|
+
contract.contract.printDebugMessages(methodName, testResult.debugMessages);
|
|
932
|
+
return testResult;
|
|
933
|
+
}
|
|
934
|
+
exports.testMethod = testMethod;
|
|
935
|
+
class ContractInstance {
|
|
936
|
+
constructor(address) {
|
|
937
|
+
this.address = address;
|
|
938
|
+
this.contractId = (0, utils_1.binToHex)((0, utils_1.contractIdFromAddress)(address));
|
|
939
|
+
this.groupIndex = (0, utils_1.groupOfAddress)(address);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
exports.ContractInstance = ContractInstance;
|
|
943
|
+
async function fetchContractState(contract, instance) {
|
|
944
|
+
const contractState = await (0, global_1.getCurrentNodeProvider)().contracts.getContractsAddressState(instance.address, {
|
|
945
|
+
group: instance.groupIndex
|
|
946
|
+
});
|
|
947
|
+
const state = contract.contract.fromApiContractState(contractState);
|
|
948
|
+
return {
|
|
949
|
+
...state,
|
|
950
|
+
fields: state.fields
|
|
951
|
+
};
|
|
952
|
+
}
|
|
953
|
+
exports.fetchContractState = fetchContractState;
|
|
954
|
+
function subscribeContractCreatedEvent(instance, options, fromCount) {
|
|
955
|
+
return subscribeEventsFromContract(options, instance.address, Contract.ContractCreatedEventIndex, (event) => {
|
|
956
|
+
return {
|
|
957
|
+
...decodeContractCreatedEvent(event),
|
|
958
|
+
contractAddress: instance.address
|
|
959
|
+
};
|
|
960
|
+
}, fromCount);
|
|
961
|
+
}
|
|
962
|
+
exports.subscribeContractCreatedEvent = subscribeContractCreatedEvent;
|
|
963
|
+
function subscribeContractDestroyedEvent(instance, options, fromCount) {
|
|
964
|
+
return subscribeEventsFromContract(options, instance.address, Contract.ContractDestroyedEventIndex, (event) => {
|
|
965
|
+
return {
|
|
966
|
+
...decodeContractDestroyedEvent(event),
|
|
967
|
+
contractAddress: instance.address
|
|
968
|
+
};
|
|
969
|
+
}, fromCount);
|
|
970
|
+
}
|
|
971
|
+
exports.subscribeContractDestroyedEvent = subscribeContractDestroyedEvent;
|
|
972
|
+
function decodeEvent(contract, instance, event, targetEventIndex) {
|
|
973
|
+
if (event.eventIndex !== targetEventIndex &&
|
|
974
|
+
!(targetEventIndex >= 0 && targetEventIndex < contract.eventsSig.length)) {
|
|
975
|
+
throw new Error('Invalid event index: ' + event.eventIndex + ', expected: ' + targetEventIndex);
|
|
976
|
+
}
|
|
977
|
+
const eventSig = contract.eventsSig[`${targetEventIndex}`];
|
|
978
|
+
const fieldNames = eventSig.fieldNames;
|
|
979
|
+
const fieldTypes = eventSig.fieldTypes;
|
|
980
|
+
const fields = (0, api_1.fromApiVals)(event.fields, fieldNames, fieldTypes);
|
|
981
|
+
return {
|
|
982
|
+
contractAddress: instance.address,
|
|
983
|
+
blockHash: event.blockHash,
|
|
984
|
+
txId: event.txId,
|
|
985
|
+
eventIndex: event.eventIndex,
|
|
986
|
+
name: eventSig.name,
|
|
987
|
+
fields: fields
|
|
988
|
+
};
|
|
989
|
+
}
|
|
990
|
+
exports.decodeEvent = decodeEvent;
|
|
991
|
+
function subscribeContractEvent(contract, instance, options, eventName, fromCount) {
|
|
992
|
+
const eventIndex = contract.eventsSig.findIndex((sig) => sig.name === eventName);
|
|
993
|
+
return subscribeEventsFromContract(options, instance.address, eventIndex, (event) => decodeEvent(contract, instance, event, eventIndex), fromCount);
|
|
994
|
+
}
|
|
995
|
+
exports.subscribeContractEvent = subscribeContractEvent;
|
|
996
|
+
function subscribeAllEvents(contract, instance, options, fromCount) {
|
|
997
|
+
const messageCallback = (event) => {
|
|
998
|
+
switch (event.eventIndex) {
|
|
999
|
+
case Contract.ContractCreatedEventIndex: {
|
|
1000
|
+
return options.messageCallback({
|
|
1001
|
+
...decodeContractCreatedEvent(event),
|
|
1002
|
+
contractAddress: instance.address
|
|
1003
|
+
});
|
|
1004
|
+
}
|
|
1005
|
+
case Contract.ContractDestroyedEventIndex: {
|
|
1006
|
+
return options.messageCallback({
|
|
1007
|
+
...decodeContractDestroyedEvent(event),
|
|
1008
|
+
contractAddress: instance.address
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
1011
|
+
default:
|
|
1012
|
+
return options.messageCallback({
|
|
1013
|
+
...decodeEvent(contract, instance, event, event.eventIndex),
|
|
1014
|
+
contractAddress: instance.address
|
|
1015
|
+
});
|
|
1016
|
+
}
|
|
1017
|
+
};
|
|
1018
|
+
const errorCallback = (err, subscription) => {
|
|
1019
|
+
return options.errorCallback(err, subscription);
|
|
1020
|
+
};
|
|
1021
|
+
const opt = {
|
|
1022
|
+
pollingInterval: options.pollingInterval,
|
|
1023
|
+
messageCallback: messageCallback,
|
|
1024
|
+
errorCallback: errorCallback
|
|
1025
|
+
};
|
|
1026
|
+
return (0, events_1.subscribeToEvents)(opt, instance.address, fromCount);
|
|
1027
|
+
}
|
|
1028
|
+
exports.subscribeAllEvents = subscribeAllEvents;
|
|
1029
|
+
async function callMethod(contract, instance, methodName, params) {
|
|
1030
|
+
const methodIndex = contract.contract.getMethodIndex(methodName);
|
|
1031
|
+
const txId = params?.txId ?? randomTxId();
|
|
1032
|
+
const callParams = contract.contract.toApiCallContract({ ...params, txId: txId, args: params.args === undefined ? {} : params.args }, instance.groupIndex, instance.address, methodIndex);
|
|
1033
|
+
const result = await (0, global_1.getCurrentNodeProvider)().contracts.postContractsCallContract(callParams);
|
|
1034
|
+
const callResult = contract.contract.fromApiCallContractResult(result, txId, methodIndex);
|
|
1035
|
+
return callResult;
|
|
1036
|
+
}
|
|
1037
|
+
exports.callMethod = callMethod;
|
|
@@ -253,8 +253,12 @@ function buildScriptByteCode(bytecodeTemplate, fields, fieldsSig) {
|
|
|
253
253
|
});
|
|
254
254
|
}
|
|
255
255
|
exports.buildScriptByteCode = buildScriptByteCode;
|
|
256
|
-
function
|
|
257
|
-
const
|
|
256
|
+
function encodeFields(fields, fieldsSig, mutable) {
|
|
257
|
+
const fieldIndexes = fieldsSig.isMutable
|
|
258
|
+
.map((_, index) => index)
|
|
259
|
+
.filter((index) => fieldsSig.isMutable[`${index}`] === mutable);
|
|
260
|
+
const fieldsEncoded = fieldIndexes.flatMap((fieldIndex) => {
|
|
261
|
+
const fieldName = fieldsSig.names[`${fieldIndex}`];
|
|
258
262
|
const fieldType = fieldsSig.types[`${fieldIndex}`];
|
|
259
263
|
if (fieldName in fields) {
|
|
260
264
|
const fieldValue = fields[`${fieldName}`];
|
|
@@ -265,7 +269,12 @@ function buildContractByteCode(bytecode, fields, fieldsSig) {
|
|
|
265
269
|
}
|
|
266
270
|
});
|
|
267
271
|
const fieldsLength = buffer_1.Buffer.from(encodeI256(BigInt(fieldsEncoded.length))).toString('hex');
|
|
268
|
-
return
|
|
272
|
+
return fieldsLength + fieldsEncoded.map((f) => buffer_1.Buffer.from(f).toString('hex')).join('');
|
|
273
|
+
}
|
|
274
|
+
function buildContractByteCode(bytecode, fields, fieldsSig) {
|
|
275
|
+
const encodedImmFields = encodeFields(fields, fieldsSig, false);
|
|
276
|
+
const encodedMutFields = encodeFields(fields, fieldsSig, true);
|
|
277
|
+
return bytecode + encodedImmFields + encodedMutFields;
|
|
269
278
|
}
|
|
270
279
|
exports.buildContractByteCode = buildContractByteCode;
|
|
271
280
|
var ApiValType;
|
|
@@ -62,7 +62,7 @@ class TransactionBuilder {
|
|
|
62
62
|
};
|
|
63
63
|
const response = await this.nodeProvider.contracts.postContractsUnsignedTxDeployContract(data);
|
|
64
64
|
const contractId = __1.utils.binToHex(__1.utils.contractIdFromAddress(response.contractAddress));
|
|
65
|
-
return { ...response, contractId, gasPrice: (0, api_1.fromApiNumber256)(response.gasPrice) };
|
|
65
|
+
return { ...response, groupIndex: response.fromGroup, contractId, gasPrice: (0, api_1.fromApiNumber256)(response.gasPrice) };
|
|
66
66
|
}
|
|
67
67
|
async buildExecuteScriptTx(params, publicKey) {
|
|
68
68
|
TransactionBuilder.validatePublicKey(params, publicKey);
|
|
@@ -75,7 +75,7 @@ class TransactionBuilder {
|
|
|
75
75
|
...rest
|
|
76
76
|
};
|
|
77
77
|
const response = await this.nodeProvider.contracts.postContractsUnsignedTxExecuteScript(data);
|
|
78
|
-
return { ...response, gasPrice: (0, api_1.fromApiNumber256)(response.gasPrice) };
|
|
78
|
+
return { ...response, groupIndex: response.fromGroup, gasPrice: (0, api_1.fromApiNumber256)(response.gasPrice) };
|
|
79
79
|
}
|
|
80
80
|
async buildUnsignedTx(params) {
|
|
81
81
|
const data = { unsignedTx: params.unsignedTx };
|
|
@@ -43,8 +43,7 @@ export interface SignDeployContractTxParams {
|
|
|
43
43
|
gasPrice?: Number256;
|
|
44
44
|
}
|
|
45
45
|
export interface SignDeployContractTxResult {
|
|
46
|
-
|
|
47
|
-
toGroup: number;
|
|
46
|
+
groupIndex: number;
|
|
48
47
|
unsignedTx: string;
|
|
49
48
|
txId: string;
|
|
50
49
|
signature: string;
|
|
@@ -62,8 +61,7 @@ export interface SignExecuteScriptTxParams {
|
|
|
62
61
|
gasPrice?: Number256;
|
|
63
62
|
}
|
|
64
63
|
export interface SignExecuteScriptTxResult {
|
|
65
|
-
|
|
66
|
-
toGroup: number;
|
|
64
|
+
groupIndex: number;
|
|
67
65
|
unsignedTx: string;
|
|
68
66
|
txId: string;
|
|
69
67
|
signature: string;
|
package/dist/src/utils/utils.js
CHANGED
|
@@ -94,7 +94,9 @@ function groupOfAddress(address) {
|
|
|
94
94
|
return groupOfP2shAddress(addressBody);
|
|
95
95
|
}
|
|
96
96
|
else {
|
|
97
|
-
|
|
97
|
+
// Contract Address
|
|
98
|
+
const id = contractIdFromAddress(address);
|
|
99
|
+
return id[`${id.length - 1}`];
|
|
98
100
|
}
|
|
99
101
|
}
|
|
100
102
|
exports.groupOfAddress = groupOfAddress;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alephium/web3",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0-rc.1",
|
|
4
4
|
"description": "A JS/TS library to interact with the Alephium platform",
|
|
5
5
|
"license": "GPL",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
},
|
|
28
28
|
"author": "Alephium dev <dev@alephium.org>",
|
|
29
29
|
"config": {
|
|
30
|
-
"alephium_version": "1.
|
|
31
|
-
"explorer_backend_version": "1.12.0
|
|
30
|
+
"alephium_version": "1.7.0",
|
|
31
|
+
"explorer_backend_version": "1.12.0"
|
|
32
32
|
},
|
|
33
33
|
"scripts": {
|
|
34
34
|
"build": "rm -rf dist/* && npx tsc --build . && webpack",
|