starknet 4.13.2 → 4.14.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.
Files changed (46) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/CODE_OF_CONDUCT.md +128 -0
  3. package/README.md +2 -2
  4. package/__tests__/account.test.ts +38 -14
  5. package/__tests__/contract.test.ts +70 -57
  6. package/__tests__/defaultProvider.test.ts +14 -13
  7. package/__tests__/fixtures.ts +26 -27
  8. package/__tests__/rpcProvider.test.ts +19 -16
  9. package/__tests__/sequencerProvider.test.ts +47 -55
  10. package/__tests__/utils/utils.test.ts +10 -0
  11. package/dist/index.d.ts +112 -28
  12. package/dist/index.global.js +511 -453
  13. package/dist/index.global.js.map +1 -1
  14. package/dist/index.js +107 -49
  15. package/dist/index.js.map +1 -1
  16. package/dist/index.mjs +107 -49
  17. package/dist/index.mjs.map +1 -1
  18. package/index.d.ts +112 -28
  19. package/index.global.js +511 -453
  20. package/index.global.js.map +1 -1
  21. package/index.js +107 -49
  22. package/index.js.map +1 -1
  23. package/index.mjs +107 -49
  24. package/index.mjs.map +1 -1
  25. package/package.json +2 -2
  26. package/src/account/default.ts +29 -7
  27. package/src/account/interface.ts +71 -5
  28. package/src/contract/contractFactory.ts +20 -13
  29. package/src/contract/default.ts +10 -1
  30. package/src/provider/default.ts +26 -11
  31. package/src/provider/interface.ts +9 -3
  32. package/src/provider/rpc.ts +15 -11
  33. package/src/provider/sequencer.ts +11 -6
  34. package/src/provider/utils.ts +19 -11
  35. package/src/types/account.ts +21 -1
  36. package/src/types/lib.ts +5 -2
  37. package/src/types/provider.ts +0 -5
  38. package/src/utils/events.ts +32 -0
  39. package/src/utils/number.ts +6 -0
  40. package/www/docs/API/account.md +156 -2
  41. package/www/docs/API/contractFactory.md +7 -11
  42. package/www/docs/API/provider.md +5 -9
  43. package/www/docs/API/utils.md +8 -0
  44. package/www/guides/account.md +89 -38
  45. package/www/guides/erc20.md +115 -59
  46. package/www/guides/intro.md +11 -4
package/index.mjs CHANGED
@@ -5,7 +5,7 @@ var __export = (target, all) => {
5
5
  };
6
6
 
7
7
  // src/contract/default.ts
8
- import BN2 from "bn.js";
8
+ import BN3 from "bn.js";
9
9
  import assert4 from "minimalistic-assert";
10
10
 
11
11
  // src/utils/fetchPonyfill.ts
@@ -62,6 +62,7 @@ __export(number_exports, {
62
62
  assertInRange: () => assertInRange,
63
63
  bigNumberishArrayToDecimalStringArray: () => bigNumberishArrayToDecimalStringArray,
64
64
  bigNumberishArrayToHexadecimalStringArray: () => bigNumberishArrayToHexadecimalStringArray,
65
+ cleanHex: () => cleanHex,
65
66
  getDecimalString: () => getDecimalString,
66
67
  getHexString: () => getHexString,
67
68
  getHexStringArray: () => getHexStringArray,
@@ -164,6 +165,7 @@ function toFelt(num) {
164
165
  }
165
166
  return toBN(num).toString();
166
167
  }
168
+ var cleanHex = (hex) => hex.toLowerCase().replace(/^(0x)0+/, "$1");
167
169
  function assertInRange(input, lowerBound, upperBound, inputName = "") {
168
170
  const messageSuffix = inputName === "" ? "invalid length" : `invalid ${inputName} length`;
169
171
  const inputBn = toBN(input);
@@ -2595,6 +2597,8 @@ var RPCResponseParser = class {
2595
2597
  };
2596
2598
 
2597
2599
  // src/provider/utils.ts
2600
+ import { BN as BN2 } from "bn.js";
2601
+ var validBlockTags = ["latest", "pending"];
2598
2602
  var Block = class {
2599
2603
  constructor(_identifier) {
2600
2604
  this.hash = null;
@@ -2602,17 +2606,21 @@ var Block = class {
2602
2606
  this.tag = null;
2603
2607
  this.valueOf = () => this.number;
2604
2608
  this.toString = () => this.hash;
2605
- this.setIdentifier = function(__identifier) {
2606
- if (typeof __identifier === "string" && isHex(__identifier)) {
2607
- this.hash = __identifier;
2608
- } else if (typeof __identifier === "number") {
2609
- this.number = __identifier;
2610
- } else {
2611
- this.tag = __identifier;
2612
- }
2613
- };
2614
2609
  this.setIdentifier(_identifier);
2615
2610
  }
2611
+ setIdentifier(__identifier) {
2612
+ if (typeof __identifier === "string" && isHex(__identifier)) {
2613
+ this.hash = __identifier;
2614
+ } else if (BN2.isBN(__identifier)) {
2615
+ this.hash = toHex(__identifier);
2616
+ } else if (typeof __identifier === "number") {
2617
+ this.number = __identifier;
2618
+ } else if (typeof __identifier === "string" && validBlockTags.includes(__identifier)) {
2619
+ this.tag = __identifier;
2620
+ } else {
2621
+ this.tag = "pending";
2622
+ }
2623
+ }
2616
2624
  get queryIdentifier() {
2617
2625
  if (this.number !== null) {
2618
2626
  return `blockNumber=${this.number}`;
@@ -2699,7 +2707,7 @@ var RpcProvider = class {
2699
2707
  contract_address: contractAddress
2700
2708
  });
2701
2709
  }
2702
- async getNonce(contractAddress, blockIdentifier = "pending") {
2710
+ async getNonceForAddress(contractAddress, blockIdentifier = "pending") {
2703
2711
  const block_id = new Block(blockIdentifier).identifier;
2704
2712
  return this.fetchEndpoint("starknet_getNonce", {
2705
2713
  contract_address: contractAddress,
@@ -2884,25 +2892,25 @@ var RpcProvider = class {
2884
2892
  async traceBlockTransactions(blockHash) {
2885
2893
  return this.fetchEndpoint("starknet_traceBlockTransactions", { block_hash: blockHash });
2886
2894
  }
2887
- async waitForTransaction(txHash, retryInterval = 8e3) {
2895
+ async waitForTransaction(txHash, successStates = ["ACCEPTED_ON_L1", "ACCEPTED_ON_L2", "PENDING"], retryInterval = 8e3) {
2896
+ const errorStates = ["REJECTED", "NOT_RECEIVED"];
2888
2897
  let { retries } = this;
2889
2898
  let onchain = false;
2899
+ let txReceipt = {};
2890
2900
  while (!onchain) {
2891
- const successStates = ["ACCEPTED_ON_L1", "ACCEPTED_ON_L2", "PENDING"];
2892
- const errorStates = ["REJECTED", "NOT_RECEIVED"];
2893
2901
  await wait(retryInterval);
2894
2902
  try {
2895
- const res = await this.getTransactionReceipt(txHash);
2896
- if (!("status" in res)) {
2903
+ txReceipt = await this.getTransactionReceipt(txHash);
2904
+ if (!("status" in txReceipt)) {
2897
2905
  const error = new Error("pending transaction");
2898
2906
  throw error;
2899
2907
  }
2900
- if (res.status && successStates.includes(res.status)) {
2908
+ if (txReceipt.status && successStates.includes(txReceipt.status)) {
2901
2909
  onchain = true;
2902
- } else if (res.status && errorStates.includes(res.status)) {
2903
- const message = res.status;
2910
+ } else if (txReceipt.status && errorStates.includes(txReceipt.status)) {
2911
+ const message = txReceipt.status;
2904
2912
  const error = new Error(message);
2905
- error.response = res;
2913
+ error.response = txReceipt;
2906
2914
  throw error;
2907
2915
  }
2908
2916
  } catch (error) {
@@ -2916,6 +2924,7 @@ var RpcProvider = class {
2916
2924
  retries -= 1;
2917
2925
  }
2918
2926
  await wait(retryInterval);
2927
+ return txReceipt;
2919
2928
  }
2920
2929
  async getTransactionCount(blockIdentifier = "pending") {
2921
2930
  const block_id = new Block(blockIdentifier).identifier;
@@ -3214,7 +3223,7 @@ var SequencerProvider = class {
3214
3223
  this.responseParser.parseGetBlockResponse
3215
3224
  );
3216
3225
  }
3217
- async getNonce(contractAddress, blockIdentifier = "pending") {
3226
+ async getNonceForAddress(contractAddress, blockIdentifier = "pending") {
3218
3227
  return this.fetchEndpoint("get_nonce", { contractAddress, blockIdentifier });
3219
3228
  }
3220
3229
  async getStorageAt(contractAddress, key, blockIdentifier = "pending") {
@@ -3344,13 +3353,13 @@ var SequencerProvider = class {
3344
3353
  async getCode(contractAddress, blockIdentifier = "pending") {
3345
3354
  return this.fetchEndpoint("get_code", { contractAddress, blockIdentifier });
3346
3355
  }
3347
- async waitForTransaction(txHash, retryInterval = 8e3) {
3356
+ async waitForTransaction(txHash, successStates = ["ACCEPTED_ON_L1", "ACCEPTED_ON_L2", "PENDING"], retryInterval = 8e3) {
3357
+ const errorStates = ["REJECTED", "NOT_RECEIVED"];
3348
3358
  let onchain = false;
3359
+ let res;
3349
3360
  while (!onchain) {
3350
3361
  await wait(retryInterval);
3351
- const res = await this.getTransactionStatus(txHash);
3352
- const successStates = ["ACCEPTED_ON_L1", "ACCEPTED_ON_L2", "PENDING"];
3353
- const errorStates = ["REJECTED", "NOT_RECEIVED"];
3362
+ res = await this.getTransactionStatus(txHash);
3354
3363
  if (successStates.includes(res.tx_status)) {
3355
3364
  onchain = true;
3356
3365
  } else if (errorStates.includes(res.tx_status)) {
@@ -3361,6 +3370,8 @@ ${res.tx_failure_reason.error_message}` : res.tx_status;
3361
3370
  throw error;
3362
3371
  }
3363
3372
  }
3373
+ const txReceipt = await this.getTransactionReceipt(txHash);
3374
+ return txReceipt;
3364
3375
  }
3365
3376
  async getTransactionStatus(txHash) {
3366
3377
  const txHashHex = toHex(toBN(txHash));
@@ -3387,11 +3398,13 @@ ${res.tx_failure_reason.error_message}` : res.tx_status;
3387
3398
  // src/provider/default.ts
3388
3399
  var Provider = class {
3389
3400
  constructor(providerOrOptions) {
3390
- if (providerOrOptions && "chainId" in providerOrOptions) {
3401
+ if (providerOrOptions instanceof Provider) {
3402
+ this.provider = providerOrOptions.provider;
3403
+ } else if (providerOrOptions instanceof RpcProvider || providerOrOptions instanceof SequencerProvider) {
3391
3404
  this.provider = providerOrOptions;
3392
- } else if (providerOrOptions == null ? void 0 : providerOrOptions.rpc) {
3405
+ } else if (providerOrOptions && "rpc" in providerOrOptions) {
3393
3406
  this.provider = new RpcProvider(providerOrOptions.rpc);
3394
- } else if (providerOrOptions == null ? void 0 : providerOrOptions.sequencer) {
3407
+ } else if (providerOrOptions && "sequencer" in providerOrOptions) {
3395
3408
  this.provider = new SequencerProvider(providerOrOptions.sequencer);
3396
3409
  } else {
3397
3410
  this.provider = new SequencerProvider();
@@ -3425,8 +3438,8 @@ var Provider = class {
3425
3438
  blockIdentifier
3426
3439
  );
3427
3440
  }
3428
- async getNonce(contractAddress, blockIdentifier) {
3429
- return this.provider.getNonce(contractAddress, blockIdentifier);
3441
+ async getNonceForAddress(contractAddress, blockIdentifier) {
3442
+ return this.provider.getNonceForAddress(contractAddress, blockIdentifier);
3430
3443
  }
3431
3444
  async getStorageAt(contractAddress, key, blockIdentifier = "pending") {
3432
3445
  return this.provider.getStorageAt(contractAddress, key, blockIdentifier);
@@ -3461,8 +3474,8 @@ var Provider = class {
3461
3474
  async getCode(contractAddress, blockIdentifier) {
3462
3475
  return this.provider.getCode(contractAddress, blockIdentifier);
3463
3476
  }
3464
- async waitForTransaction(txHash, retryInterval) {
3465
- return this.provider.waitForTransaction(txHash, retryInterval);
3477
+ async waitForTransaction(txHash, successStates, retryInterval) {
3478
+ return this.provider.waitForTransaction(txHash, successStates, retryInterval);
3466
3479
  }
3467
3480
  };
3468
3481
 
@@ -3483,7 +3496,13 @@ function parseFelt(candidate) {
3483
3496
  }
3484
3497
  function buildCall(contract, functionAbi) {
3485
3498
  return async function(...args) {
3486
- return contract.call(functionAbi.name, args);
3499
+ let blockIdentifier = null;
3500
+ args.forEach((arg) => {
3501
+ if (arg.blockIdentifier) {
3502
+ blockIdentifier = arg.blockIdentifier;
3503
+ }
3504
+ });
3505
+ return contract.call(functionAbi.name, args, { blockIdentifier });
3487
3506
  };
3488
3507
  }
3489
3508
  function buildInvoke(contract, functionAbi) {
@@ -3708,7 +3727,7 @@ var Contract = class {
3708
3727
  }
3709
3728
  if (input.type === "felt") {
3710
3729
  assert4(
3711
- typeof args[argPosition] === "string" || typeof args[argPosition] === "number" || args[argPosition] instanceof BN2,
3730
+ typeof args[argPosition] === "string" || typeof args[argPosition] === "number" || args[argPosition] instanceof BN3,
3712
3731
  `arg ${input.name} should be a felt (string, number, BigNumber)`
3713
3732
  );
3714
3733
  argPosition += 1;
@@ -3733,7 +3752,7 @@ var Contract = class {
3733
3752
  if (input.type === "felt*") {
3734
3753
  args[argPosition].forEach((felt) => {
3735
3754
  assert4(
3736
- typeof felt === "string" || typeof felt === "number" || felt instanceof BN2,
3755
+ typeof felt === "string" || typeof felt === "number" || felt instanceof BN3,
3737
3756
  `arg ${input.name} should be an array of string, number or BigNumber`
3738
3757
  );
3739
3758
  });
@@ -3746,7 +3765,7 @@ var Contract = class {
3746
3765
  );
3747
3766
  args[argPosition].forEach((felt) => {
3748
3767
  assert4(
3749
- typeof felt === "string" || typeof felt === "number" || felt instanceof BN2,
3768
+ typeof felt === "string" || typeof felt === "number" || felt instanceof BN3,
3750
3769
  `arg ${input.name} should be an array of string, number or BigNumber`
3751
3770
  );
3752
3771
  });
@@ -3903,32 +3922,36 @@ var ContractInterface = class {
3903
3922
  // src/contract/contractFactory.ts
3904
3923
  import assert5 from "minimalistic-assert";
3905
3924
  var ContractFactory = class {
3906
- constructor(compiledContract, providerOrAccount = defaultProvider, abi = compiledContract.abi) {
3925
+ constructor(compiledContract, classHash, account, abi = compiledContract.abi) {
3907
3926
  this.abi = abi;
3908
3927
  this.compiledContract = compiledContract;
3909
- this.providerOrAccount = providerOrAccount;
3928
+ this.account = account;
3929
+ this.classHash = classHash;
3910
3930
  }
3911
3931
  async deploy(constructorCalldata, addressSalt) {
3912
- const { contract_address, transaction_hash } = await this.providerOrAccount.deployContract({
3932
+ const {
3933
+ deploy: { contract_address, transaction_hash }
3934
+ } = await this.account.declareDeploy({
3913
3935
  contract: this.compiledContract,
3936
+ classHash: this.classHash,
3914
3937
  constructorCalldata,
3915
- addressSalt
3938
+ salt: addressSalt
3916
3939
  });
3917
3940
  assert5(Boolean(contract_address), "Deployment of the contract failed");
3918
3941
  const contractInstance = new Contract(
3919
3942
  this.compiledContract.abi,
3920
3943
  contract_address,
3921
- this.providerOrAccount
3944
+ this.account
3922
3945
  );
3923
3946
  contractInstance.deployTransactionHash = transaction_hash;
3924
3947
  return contractInstance;
3925
3948
  }
3926
- connect(providerOrAccount) {
3927
- this.providerOrAccount = providerOrAccount;
3949
+ connect(account) {
3950
+ this.account = account;
3928
3951
  return this;
3929
3952
  }
3930
3953
  attach(address) {
3931
- return new Contract(this.abi, address, this.providerOrAccount);
3954
+ return new Contract(this.abi, address, this.account);
3932
3955
  }
3933
3956
  };
3934
3957
 
@@ -4272,6 +4295,29 @@ var Signer = class {
4272
4295
  }
4273
4296
  };
4274
4297
 
4298
+ // src/utils/events.ts
4299
+ function parseUDCEvent(txReceipt) {
4300
+ if (!txReceipt.events) {
4301
+ throw new Error("UDC emited event is empty");
4302
+ }
4303
+ const event = txReceipt.events.find(
4304
+ (it) => cleanHex(it.from_address) === cleanHex(UDC.ADDRESS)
4305
+ ) || {
4306
+ data: []
4307
+ };
4308
+ return {
4309
+ transaction_hash: txReceipt.transaction_hash,
4310
+ contract_address: event.data[0],
4311
+ address: event.data[0],
4312
+ deployer: event.data[1],
4313
+ unique: event.data[2],
4314
+ classHash: event.data[3],
4315
+ calldata_len: event.data[4],
4316
+ calldata: event.data.slice(5, 5 + parseInt(event.data[4], 16)),
4317
+ salt: event.data[event.data.length - 1]
4318
+ };
4319
+ }
4320
+
4275
4321
  // src/account/default.ts
4276
4322
  var Account = class extends Provider {
4277
4323
  constructor(providerOrOptions, address, keyPairOrSigner) {
@@ -4280,7 +4326,7 @@ var Account = class extends Provider {
4280
4326
  this.signer = "getPubKey" in keyPairOrSigner ? keyPairOrSigner : new Signer(keyPairOrSigner);
4281
4327
  }
4282
4328
  async getNonce(blockIdentifier) {
4283
- return super.getNonce(this.address, blockIdentifier);
4329
+ return super.getNonceForAddress(this.address, blockIdentifier);
4284
4330
  }
4285
4331
  async estimateFee(calls, estimateFeeDetails) {
4286
4332
  return this.estimateInvokeFee(calls, estimateFeeDetails);
@@ -4367,7 +4413,7 @@ var Account = class extends Provider {
4367
4413
  }
4368
4414
  async estimateDeployFee({
4369
4415
  classHash,
4370
- salt,
4416
+ salt = "0",
4371
4417
  unique = true,
4372
4418
  constructorCalldata = [],
4373
4419
  additionalCalls = []
@@ -4448,9 +4494,10 @@ var Account = class extends Provider {
4448
4494
  unique = true,
4449
4495
  constructorCalldata = [],
4450
4496
  additionalCalls = []
4451
- }, transactionsDetail = {}) {
4497
+ }, invocationsDetails = {}) {
4452
4498
  const compiledConstructorCallData = compileCalldata(constructorCalldata);
4453
4499
  const callsArray = Array.isArray(additionalCalls) ? additionalCalls : [additionalCalls];
4500
+ const deploySalt = salt ?? randomAddress();
4454
4501
  return this.execute(
4455
4502
  [
4456
4503
  {
@@ -4458,7 +4505,7 @@ var Account = class extends Provider {
4458
4505
  entrypoint: UDC.ENTRYPOINT,
4459
4506
  calldata: [
4460
4507
  classHash,
4461
- salt,
4508
+ deploySalt,
4462
4509
  toCairoBool(unique),
4463
4510
  compiledConstructorCallData.length,
4464
4511
  ...compiledConstructorCallData
@@ -4467,9 +4514,20 @@ var Account = class extends Provider {
4467
4514
  ...callsArray
4468
4515
  ],
4469
4516
  void 0,
4470
- transactionsDetail
4517
+ invocationsDetails
4471
4518
  );
4472
4519
  }
4520
+ async deployContract(payload, details = {}) {
4521
+ const deployTx = await this.deploy(payload, details);
4522
+ const txReceipt = await this.waitForTransaction(deployTx.transaction_hash, ["ACCEPTED_ON_L2"]);
4523
+ return parseUDCEvent(txReceipt);
4524
+ }
4525
+ async declareDeploy({ classHash, contract, constructorCalldata }, details) {
4526
+ const { transaction_hash } = await this.declare({ contract, classHash }, details);
4527
+ const declare = await this.waitForTransaction(transaction_hash, ["ACCEPTED_ON_L2"]);
4528
+ const deploy = await this.deployContract({ classHash, constructorCalldata }, details);
4529
+ return { declare: { ...declare, class_hash: classHash }, deploy };
4530
+ }
4473
4531
  async deployAccount({
4474
4532
  classHash,
4475
4533
  constructorCalldata = [],