starknet 4.16.0 → 4.17.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/index.mjs CHANGED
@@ -5,8 +5,7 @@ var __export = (target, all) => {
5
5
  };
6
6
 
7
7
  // src/contract/default.ts
8
- import BN3 from "bn.js";
9
- import assert4 from "minimalistic-assert";
8
+ import assert5 from "minimalistic-assert";
10
9
 
11
10
  // src/utils/fetchPonyfill.ts
12
11
  import isomorphicFetch from "isomorphic-fetch";
@@ -3467,6 +3466,187 @@ var ProviderInterface = class {
3467
3466
  // src/provider/index.ts
3468
3467
  var defaultProvider = new Provider();
3469
3468
 
3469
+ // src/utils/calldata.ts
3470
+ import BN3 from "bn.js";
3471
+ import assert4 from "minimalistic-assert";
3472
+ var CheckCallData = class {
3473
+ constructor(abi) {
3474
+ this.abi = abi;
3475
+ this.structs = abi.filter((abiEntry) => abiEntry.type === "struct").reduce(
3476
+ (acc, abiEntry) => ({
3477
+ ...acc,
3478
+ [abiEntry.name]: abiEntry
3479
+ }),
3480
+ {}
3481
+ );
3482
+ }
3483
+ compileCalldata(args, inputs) {
3484
+ const argsIterator = args[Symbol.iterator]();
3485
+ return inputs.reduce((acc, input) => {
3486
+ if (/_len$/.test(input.name)) {
3487
+ return acc;
3488
+ }
3489
+ const parsedData = this.parseCalldataField(argsIterator, input);
3490
+ if (Array.isArray(parsedData)) {
3491
+ acc.push(...parsedData);
3492
+ } else {
3493
+ acc.push(parsedData);
3494
+ }
3495
+ return acc;
3496
+ }, []);
3497
+ }
3498
+ validateMethodAndArgs(type, method, args = []) {
3499
+ if (type !== "DEPLOY") {
3500
+ const invocableFunctionNames = this.abi.filter((abi) => {
3501
+ if (abi.type !== "function")
3502
+ return false;
3503
+ const isView = abi.stateMutability === "view";
3504
+ return type === "INVOKE" ? !isView : isView;
3505
+ }).map((abi) => abi.name);
3506
+ assert4(
3507
+ invocableFunctionNames.includes(method),
3508
+ `${type === "INVOKE" ? "invocable" : "viewable"} method not found in abi`
3509
+ );
3510
+ }
3511
+ const methodAbi = this.abi.find(
3512
+ (abi) => type === "DEPLOY" ? abi.name === method && abi.type === method : abi.name === method && abi.type === "function"
3513
+ );
3514
+ let argPosition = 0;
3515
+ methodAbi.inputs.forEach((input) => {
3516
+ if (/_len$/.test(input.name)) {
3517
+ return;
3518
+ }
3519
+ if (input.type === "felt") {
3520
+ assert4(
3521
+ typeof args[argPosition] === "string" || typeof args[argPosition] === "number" || args[argPosition] instanceof BN3,
3522
+ `arg ${input.name} should be a felt (string, number, BigNumber)`
3523
+ );
3524
+ argPosition += 1;
3525
+ } else if (input.type in this.structs && typeof args[argPosition] === "object") {
3526
+ if (Array.isArray(args[argPosition])) {
3527
+ const structMembersLength = this.calculateStructMembers(input.type);
3528
+ assert4(
3529
+ args[argPosition].length === structMembersLength,
3530
+ `arg should be of length ${structMembersLength}`
3531
+ );
3532
+ } else {
3533
+ this.structs[input.type].members.forEach(({ name }) => {
3534
+ assert4(
3535
+ Object.keys(args[argPosition]).includes(name),
3536
+ `arg should have a property ${name}`
3537
+ );
3538
+ });
3539
+ }
3540
+ argPosition += 1;
3541
+ } else {
3542
+ assert4(Array.isArray(args[argPosition]), `arg ${input.name} should be an Array`);
3543
+ if (input.type === "felt*") {
3544
+ args[argPosition].forEach((felt) => {
3545
+ assert4(
3546
+ typeof felt === "string" || typeof felt === "number" || felt instanceof BN3,
3547
+ `arg ${input.name} should be an array of string, number or BigNumber`
3548
+ );
3549
+ });
3550
+ argPosition += 1;
3551
+ } else if (/\(felt/.test(input.type)) {
3552
+ const tupleLength = input.type.split(",").length;
3553
+ assert4(
3554
+ args[argPosition].length === tupleLength,
3555
+ `arg ${input.name} should have ${tupleLength} elements in tuple`
3556
+ );
3557
+ args[argPosition].forEach((felt) => {
3558
+ assert4(
3559
+ typeof felt === "string" || typeof felt === "number" || felt instanceof BN3,
3560
+ `arg ${input.name} should be an array of string, number or BigNumber`
3561
+ );
3562
+ });
3563
+ argPosition += 1;
3564
+ } else {
3565
+ const arrayType = input.type.replace("*", "");
3566
+ args[argPosition].forEach((struct) => {
3567
+ this.structs[arrayType].members.forEach(({ name }) => {
3568
+ if (Array.isArray(struct)) {
3569
+ const structMembersLength = this.calculateStructMembers(arrayType);
3570
+ assert4(
3571
+ struct.length === structMembersLength,
3572
+ `arg should be of length ${structMembersLength}`
3573
+ );
3574
+ } else {
3575
+ assert4(
3576
+ Object.keys(struct).includes(name),
3577
+ `arg ${input.name} should be an array of ${arrayType}`
3578
+ );
3579
+ }
3580
+ });
3581
+ });
3582
+ argPosition += 1;
3583
+ }
3584
+ }
3585
+ });
3586
+ }
3587
+ parseCalldataField(argsIterator, input) {
3588
+ const { name, type } = input;
3589
+ const { value } = argsIterator.next();
3590
+ const parsedCalldata = [];
3591
+ switch (true) {
3592
+ case /\*/.test(type):
3593
+ if (Array.isArray(value)) {
3594
+ parsedCalldata.push(toFelt(value.length));
3595
+ return value.reduce((acc, el) => {
3596
+ if (/felt/.test(type)) {
3597
+ acc.push(toFelt(el));
3598
+ } else {
3599
+ acc.push(...this.parseCalldataValue(el, type.replace("*", "")));
3600
+ }
3601
+ return acc;
3602
+ }, parsedCalldata);
3603
+ }
3604
+ throw Error(`Expected ${name} to be array`);
3605
+ case type in this.structs:
3606
+ return this.parseCalldataValue(value, type);
3607
+ case /\(felt/.test(type):
3608
+ if (Array.isArray(value)) {
3609
+ return value.map((el) => toFelt(el));
3610
+ }
3611
+ throw Error(`Expected ${name} to be array`);
3612
+ default:
3613
+ return toFelt(value);
3614
+ }
3615
+ }
3616
+ parseCalldataValue(element, type) {
3617
+ if (element === void 0) {
3618
+ throw Error("Missing element in calldata");
3619
+ }
3620
+ if (Array.isArray(element)) {
3621
+ const structMemberNum = this.calculateStructMembers(type);
3622
+ if (element.length !== structMemberNum) {
3623
+ throw Error("Missing element in calldata");
3624
+ }
3625
+ return element.map((el) => toFelt(el));
3626
+ }
3627
+ if (this.structs[type] && this.structs[type].members.length) {
3628
+ return this.structs[type].members.reduce((acc, member) => {
3629
+ const parsedData = this.parseCalldataValue(element[member.name], member.type);
3630
+ if (typeof parsedData === "string") {
3631
+ acc.push(parsedData);
3632
+ } else {
3633
+ acc.push(...parsedData);
3634
+ }
3635
+ return acc;
3636
+ }, []);
3637
+ }
3638
+ return toFelt(element);
3639
+ }
3640
+ calculateStructMembers(struct) {
3641
+ return this.structs[struct].members.reduce((acc, member) => {
3642
+ if (member.type === "felt") {
3643
+ return acc + 1;
3644
+ }
3645
+ return acc + this.calculateStructMembers(member.type);
3646
+ }, 0);
3647
+ }
3648
+ };
3649
+
3470
3650
  // src/contract/default.ts
3471
3651
  function parseFelt(candidate) {
3472
3652
  try {
@@ -3530,6 +3710,7 @@ var Contract = class {
3530
3710
  }),
3531
3711
  {}
3532
3712
  );
3713
+ this.checkCalldata = new CheckCallData(abi);
3533
3714
  Object.defineProperty(this, "functions", {
3534
3715
  enumerable: true,
3535
3716
  value: {},
@@ -3607,10 +3788,10 @@ var Contract = class {
3607
3788
  }
3608
3789
  async call(method, args = [], options = {}) {
3609
3790
  const blockIdentifier = (options == null ? void 0 : options.blockIdentifier) || void 0;
3610
- assert4(this.address !== null, "contract is not connected to an address");
3611
- this.validateMethodAndArgs("CALL", method, args);
3791
+ assert5(this.address !== null, "contract is not connected to an address");
3792
+ this.checkCalldata.validateMethodAndArgs("CALL", method, args);
3612
3793
  const { inputs } = this.abi.find((abi) => abi.name === method);
3613
- const calldata = this.compileCalldata(args, inputs);
3794
+ const calldata = this.checkCalldata.compileCalldata(args, inputs);
3614
3795
  return this.providerOrAccount.callContract(
3615
3796
  {
3616
3797
  contractAddress: this.address,
@@ -3621,8 +3802,8 @@ var Contract = class {
3621
3802
  ).then((x) => this.parseResponse(method, x.result));
3622
3803
  }
3623
3804
  invoke(method, args = [], options = {}) {
3624
- assert4(this.address !== null, "contract is not connected to an address");
3625
- this.validateMethodAndArgs("INVOKE", method, args);
3805
+ assert5(this.address !== null, "contract is not connected to an address");
3806
+ this.checkCalldata.validateMethodAndArgs("INVOKE", method, args);
3626
3807
  const { inputs } = this.abi.find((abi) => abi.name === method);
3627
3808
  const inputsLength = inputs.reduce((acc, input) => {
3628
3809
  if (!/_len$/.test(input.name)) {
@@ -3635,7 +3816,7 @@ var Contract = class {
3635
3816
  `Invalid number of arguments, expected ${inputsLength} arguments, but got ${args.length}`
3636
3817
  );
3637
3818
  }
3638
- const calldata = this.compileCalldata(args, inputs);
3819
+ const calldata = this.checkCalldata.compileCalldata(args, inputs);
3639
3820
  const invocation = {
3640
3821
  contractAddress: this.address,
3641
3822
  calldata,
@@ -3662,8 +3843,8 @@ var Contract = class {
3662
3843
  );
3663
3844
  }
3664
3845
  async estimate(method, args = []) {
3665
- assert4(this.address !== null, "contract is not connected to an address");
3666
- this.validateMethodAndArgs("INVOKE", method, args);
3846
+ assert5(this.address !== null, "contract is not connected to an address");
3847
+ this.checkCalldata.validateMethodAndArgs("INVOKE", method, args);
3667
3848
  const invocation = this.populateTransaction[method](...args);
3668
3849
  if ("estimateInvokeFee" in this.providerOrAccount) {
3669
3850
  return this.providerOrAccount.estimateInvokeFee(invocation);
@@ -3675,128 +3856,9 @@ var Contract = class {
3675
3856
  return {
3676
3857
  contractAddress: this.address,
3677
3858
  entrypoint: method,
3678
- calldata: this.compileCalldata(args, inputs)
3859
+ calldata: this.checkCalldata.compileCalldata(args, inputs)
3679
3860
  };
3680
3861
  }
3681
- calculateStructMembers(struct) {
3682
- return this.structs[struct].members.reduce((acc, member) => {
3683
- if (member.type === "felt") {
3684
- return acc + 1;
3685
- }
3686
- return acc + this.calculateStructMembers(member.type);
3687
- }, 0);
3688
- }
3689
- validateMethodAndArgs(type, method, args = []) {
3690
- const invocableFunctionNames = this.abi.filter((abi) => {
3691
- if (abi.type !== "function")
3692
- return false;
3693
- const isView = abi.stateMutability === "view";
3694
- return type === "INVOKE" ? !isView : isView;
3695
- }).map((abi) => abi.name);
3696
- assert4(
3697
- invocableFunctionNames.includes(method),
3698
- `${type === "INVOKE" ? "invocable" : "viewable"} method not found in abi`
3699
- );
3700
- const methodAbi = this.abi.find(
3701
- (abi) => abi.name === method && abi.type === "function"
3702
- );
3703
- let argPosition = 0;
3704
- methodAbi.inputs.forEach((input) => {
3705
- if (/_len$/.test(input.name)) {
3706
- return;
3707
- }
3708
- if (input.type === "felt") {
3709
- assert4(
3710
- typeof args[argPosition] === "string" || typeof args[argPosition] === "number" || args[argPosition] instanceof BN3,
3711
- `arg ${input.name} should be a felt (string, number, BigNumber)`
3712
- );
3713
- argPosition += 1;
3714
- } else if (input.type in this.structs && typeof args[argPosition] === "object") {
3715
- if (Array.isArray(args[argPosition])) {
3716
- const structMembersLength = this.calculateStructMembers(input.type);
3717
- assert4(
3718
- args[argPosition].length === structMembersLength,
3719
- `arg should be of length ${structMembersLength}`
3720
- );
3721
- } else {
3722
- this.structs[input.type].members.forEach(({ name }) => {
3723
- assert4(
3724
- Object.keys(args[argPosition]).includes(name),
3725
- `arg should have a property ${name}`
3726
- );
3727
- });
3728
- }
3729
- argPosition += 1;
3730
- } else {
3731
- assert4(Array.isArray(args[argPosition]), `arg ${input.name} should be an Array`);
3732
- if (input.type === "felt*") {
3733
- args[argPosition].forEach((felt) => {
3734
- assert4(
3735
- typeof felt === "string" || typeof felt === "number" || felt instanceof BN3,
3736
- `arg ${input.name} should be an array of string, number or BigNumber`
3737
- );
3738
- });
3739
- argPosition += 1;
3740
- } else if (/\(felt/.test(input.type)) {
3741
- const tupleLength = input.type.split(",").length;
3742
- assert4(
3743
- args[argPosition].length === tupleLength,
3744
- `arg ${input.name} should have ${tupleLength} elements in tuple`
3745
- );
3746
- args[argPosition].forEach((felt) => {
3747
- assert4(
3748
- typeof felt === "string" || typeof felt === "number" || felt instanceof BN3,
3749
- `arg ${input.name} should be an array of string, number or BigNumber`
3750
- );
3751
- });
3752
- argPosition += 1;
3753
- } else {
3754
- const arrayType = input.type.replace("*", "");
3755
- args[argPosition].forEach((struct) => {
3756
- this.structs[arrayType].members.forEach(({ name }) => {
3757
- if (Array.isArray(struct)) {
3758
- const structMembersLength = this.calculateStructMembers(arrayType);
3759
- assert4(
3760
- struct.length === structMembersLength,
3761
- `arg should be of length ${structMembersLength}`
3762
- );
3763
- } else {
3764
- assert4(
3765
- Object.keys(struct).includes(name),
3766
- `arg ${input.name} should be an array of ${arrayType}`
3767
- );
3768
- }
3769
- });
3770
- });
3771
- argPosition += 1;
3772
- }
3773
- }
3774
- });
3775
- }
3776
- parseCalldataValue(element, type) {
3777
- if (element === void 0) {
3778
- throw Error("Missing element in calldata");
3779
- }
3780
- if (Array.isArray(element)) {
3781
- const structMemberNum = this.calculateStructMembers(type);
3782
- if (element.length !== structMemberNum) {
3783
- throw Error("Missing element in calldata");
3784
- }
3785
- return element.map((el) => toFelt(el));
3786
- }
3787
- if (this.structs[type] && this.structs[type].members.length) {
3788
- return this.structs[type].members.reduce((acc, member) => {
3789
- const parsedData = this.parseCalldataValue(element[member.name], member.type);
3790
- if (typeof parsedData === "string") {
3791
- acc.push(parsedData);
3792
- } else {
3793
- acc.push(...parsedData);
3794
- }
3795
- return acc;
3796
- }, []);
3797
- }
3798
- return toFelt(element);
3799
- }
3800
3862
  parseResponseStruct(responseIterator, type) {
3801
3863
  if (type in this.structs && this.structs[type]) {
3802
3864
  return this.structs[type].members.reduce((acc, el) => {
@@ -3806,50 +3868,6 @@ var Contract = class {
3806
3868
  }
3807
3869
  return parseFelt(responseIterator.next().value);
3808
3870
  }
3809
- parseCalldataField(argsIterator, input) {
3810
- const { name, type } = input;
3811
- const { value } = argsIterator.next();
3812
- const parsedCalldata = [];
3813
- switch (true) {
3814
- case /\*/.test(type):
3815
- if (Array.isArray(value)) {
3816
- parsedCalldata.push(toFelt(value.length));
3817
- return value.reduce((acc, el) => {
3818
- if (/felt/.test(type)) {
3819
- acc.push(toFelt(el));
3820
- } else {
3821
- acc.push(...this.parseCalldataValue(el, type.replace("*", "")));
3822
- }
3823
- return acc;
3824
- }, parsedCalldata);
3825
- }
3826
- throw Error(`Expected ${name} to be array`);
3827
- case type in this.structs:
3828
- return this.parseCalldataValue(value, type);
3829
- case /\(felt/.test(type):
3830
- if (Array.isArray(value)) {
3831
- return value.map((el) => toFelt(el));
3832
- }
3833
- throw Error(`Expected ${name} to be array`);
3834
- default:
3835
- return toFelt(value);
3836
- }
3837
- }
3838
- compileCalldata(args, inputs) {
3839
- const argsIterator = args[Symbol.iterator]();
3840
- return inputs.reduce((acc, input) => {
3841
- if (/_len$/.test(input.name)) {
3842
- return acc;
3843
- }
3844
- const parsedData = this.parseCalldataField(argsIterator, input);
3845
- if (Array.isArray(parsedData)) {
3846
- acc.push(...parsedData);
3847
- } else {
3848
- acc.push(parsedData);
3849
- }
3850
- return acc;
3851
- }, []);
3852
- }
3853
3871
  parseResponseField(responseIterator, output, parsedResult) {
3854
3872
  const { name, type } = output;
3855
3873
  const parsedDataArr = [];
@@ -3900,15 +3918,19 @@ var ContractInterface = class {
3900
3918
  };
3901
3919
 
3902
3920
  // src/contract/contractFactory.ts
3903
- import assert5 from "minimalistic-assert";
3921
+ import assert6 from "minimalistic-assert";
3904
3922
  var ContractFactory = class {
3905
3923
  constructor(compiledContract, classHash, account, abi = compiledContract.abi) {
3906
3924
  this.abi = abi;
3907
3925
  this.compiledContract = compiledContract;
3908
3926
  this.account = account;
3909
3927
  this.classHash = classHash;
3928
+ this.checkCalldata = new CheckCallData(abi);
3910
3929
  }
3911
- async deploy(constructorCalldata, addressSalt) {
3930
+ async deploy(args = [], addressSalt) {
3931
+ this.checkCalldata.validateMethodAndArgs("DEPLOY", "constructor", args);
3932
+ const { inputs } = this.abi.find((abi) => abi.type === "constructor");
3933
+ const constructorCalldata = this.checkCalldata.compileCalldata(args, inputs);
3912
3934
  const {
3913
3935
  deploy: { contract_address, transaction_hash }
3914
3936
  } = await this.account.declareDeploy({
@@ -3917,7 +3939,7 @@ var ContractFactory = class {
3917
3939
  constructorCalldata,
3918
3940
  salt: addressSalt
3919
3941
  });
3920
- assert5(Boolean(contract_address), "Deployment of the contract failed");
3942
+ assert6(Boolean(contract_address), "Deployment of the contract failed");
3921
3943
  const contractInstance = new Contract(
3922
3944
  this.compiledContract.abi,
3923
3945
  contract_address,