@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.
@@ -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(this.artifactsRootDir);
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(artifactsRootDir);
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
- _printDebugMessages(funcName, messages) {
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
- toTestContract(funcName, params) {
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
- initialFields: this.toApiFields(params.initialFields),
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.fields, this.fieldsSig),
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 == -1) {
583
+ if (event.eventIndex == Contract.ContractCreatedEventIndex) {
608
584
  eventSig = this.ContractCreatedEvent;
609
585
  }
610
- else if (event.eventIndex == -2) {
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
- fromTestContractResult(methodIndex, result) {
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: (0, api_1.fromApiArray)(result.returns, this.functions[`${methodIndex}`].returnTypes),
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.map((event) => {
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 ? 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.initialAttoAlphAmount,
654
- issueTokenAmount: params.issueTokenAmount,
655
- initialTokenAmounts: params.initialTokenAmounts,
656
- gasAmount: params.gasAmount,
657
- gasPrice: params.gasPrice
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 ? 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(vals, fieldsSig) {
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
- fields: toApiFields(state.fields, state.fieldsSig),
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
- (0, utils_1.assertType)();
817
- (0, utils_1.assertType)();
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 buildContractByteCode(bytecode, fields, fieldsSig) {
257
- const fieldsEncoded = fieldsSig.names.flatMap((fieldName, fieldIndex) => {
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 bytecode + fieldsLength + fieldsEncoded.map((f) => buffer_1.Buffer.from(f).toString('hex')).join('');
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
- fromGroup: number;
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
- fromGroup: number;
66
- toGroup: number;
64
+ groupIndex: number;
67
65
  unsignedTx: string;
68
66
  txId: string;
69
67
  signature: string;
@@ -29,4 +29,5 @@ export declare type Eq<X, Y> = _Eq<{
29
29
  [P in keyof Y]: Y[P];
30
30
  }>;
31
31
  export declare function assertType<T extends true>(): void;
32
+ export declare type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
32
33
  export {};
@@ -94,7 +94,9 @@ function groupOfAddress(address) {
94
94
  return groupOfP2shAddress(addressBody);
95
95
  }
96
96
  else {
97
- throw new Error(`Invalid asset address type: ${addressType}`);
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.4.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.6.4",
31
- "explorer_backend_version": "1.12.0-rc2"
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",