quais 1.0.0-alpha.21 → 1.0.0-alpha.22

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 (86) hide show
  1. package/dist/quais.js +156 -75
  2. package/dist/quais.js.map +1 -1
  3. package/dist/quais.min.js +1 -1
  4. package/dist/quais.umd.js +156 -75
  5. package/dist/quais.umd.js.map +1 -1
  6. package/dist/quais.umd.min.js +1 -1
  7. package/examples/signing/pubkey-to-address.js +37 -0
  8. package/examples/wallets/qi-wallet-alice-bob-send-receive.js +90 -0
  9. package/examples/wallets/qi-wallet-convert-to-quai.js +73 -0
  10. package/examples/wallets/qi-wallet-send-qi-to-bob.js +87 -0
  11. package/examples/wallets/utils.js +132 -0
  12. package/lib/commonjs/providers/abstract-provider.d.ts +13 -4
  13. package/lib/commonjs/providers/abstract-provider.d.ts.map +1 -1
  14. package/lib/commonjs/providers/abstract-provider.js +18 -5
  15. package/lib/commonjs/providers/abstract-provider.js.map +1 -1
  16. package/lib/commonjs/providers/provider-jsonrpc.d.ts.map +1 -1
  17. package/lib/commonjs/providers/provider-jsonrpc.js +6 -0
  18. package/lib/commonjs/providers/provider-jsonrpc.js.map +1 -1
  19. package/lib/commonjs/providers/provider-websocket.d.ts +1 -1
  20. package/lib/commonjs/providers/provider-websocket.d.ts.map +1 -1
  21. package/lib/commonjs/providers/provider-websocket.js +22 -17
  22. package/lib/commonjs/providers/provider-websocket.js.map +1 -1
  23. package/lib/commonjs/providers/provider.d.ts +8 -0
  24. package/lib/commonjs/providers/provider.d.ts.map +1 -1
  25. package/lib/commonjs/providers/provider.js +7 -4
  26. package/lib/commonjs/providers/provider.js.map +1 -1
  27. package/lib/commonjs/providers/subscriber-polling.js +1 -1
  28. package/lib/commonjs/quais.d.ts +2 -2
  29. package/lib/commonjs/quais.d.ts.map +1 -1
  30. package/lib/commonjs/quais.js.map +1 -1
  31. package/lib/commonjs/transaction/utxo.d.ts +14 -0
  32. package/lib/commonjs/transaction/utxo.d.ts.map +1 -1
  33. package/lib/commonjs/transaction/utxo.js.map +1 -1
  34. package/lib/commonjs/wallet/index.d.ts +2 -2
  35. package/lib/commonjs/wallet/index.d.ts.map +1 -1
  36. package/lib/commonjs/wallet/index.js.map +1 -1
  37. package/lib/commonjs/wallet/payment-codes.d.ts.map +1 -1
  38. package/lib/commonjs/wallet/payment-codes.js +3 -4
  39. package/lib/commonjs/wallet/payment-codes.js.map +1 -1
  40. package/lib/commonjs/wallet/qi-hdwallet.d.ts +3 -2
  41. package/lib/commonjs/wallet/qi-hdwallet.d.ts.map +1 -1
  42. package/lib/commonjs/wallet/qi-hdwallet.js +98 -44
  43. package/lib/commonjs/wallet/qi-hdwallet.js.map +1 -1
  44. package/lib/esm/providers/abstract-provider.d.ts +13 -4
  45. package/lib/esm/providers/abstract-provider.d.ts.map +1 -1
  46. package/lib/esm/providers/abstract-provider.js +18 -5
  47. package/lib/esm/providers/abstract-provider.js.map +1 -1
  48. package/lib/esm/providers/provider-jsonrpc.d.ts.map +1 -1
  49. package/lib/esm/providers/provider-jsonrpc.js +6 -0
  50. package/lib/esm/providers/provider-jsonrpc.js.map +1 -1
  51. package/lib/esm/providers/provider-websocket.d.ts +1 -1
  52. package/lib/esm/providers/provider-websocket.d.ts.map +1 -1
  53. package/lib/esm/providers/provider-websocket.js +23 -18
  54. package/lib/esm/providers/provider-websocket.js.map +1 -1
  55. package/lib/esm/providers/provider.d.ts +8 -0
  56. package/lib/esm/providers/provider.d.ts.map +1 -1
  57. package/lib/esm/providers/provider.js +7 -4
  58. package/lib/esm/providers/provider.js.map +1 -1
  59. package/lib/esm/providers/subscriber-polling.js +1 -1
  60. package/lib/esm/quais.d.ts +2 -2
  61. package/lib/esm/quais.d.ts.map +1 -1
  62. package/lib/esm/quais.js.map +1 -1
  63. package/lib/esm/transaction/utxo.d.ts +14 -0
  64. package/lib/esm/transaction/utxo.d.ts.map +1 -1
  65. package/lib/esm/transaction/utxo.js.map +1 -1
  66. package/lib/esm/wallet/index.d.ts +2 -2
  67. package/lib/esm/wallet/index.d.ts.map +1 -1
  68. package/lib/esm/wallet/index.js.map +1 -1
  69. package/lib/esm/wallet/payment-codes.d.ts.map +1 -1
  70. package/lib/esm/wallet/payment-codes.js +4 -5
  71. package/lib/esm/wallet/payment-codes.js.map +1 -1
  72. package/lib/esm/wallet/qi-hdwallet.d.ts +3 -2
  73. package/lib/esm/wallet/qi-hdwallet.d.ts.map +1 -1
  74. package/lib/esm/wallet/qi-hdwallet.js +99 -45
  75. package/lib/esm/wallet/qi-hdwallet.js.map +1 -1
  76. package/package.json +1 -1
  77. package/src/providers/abstract-provider.ts +36 -9
  78. package/src/providers/provider-jsonrpc.ts +7 -0
  79. package/src/providers/provider-websocket.ts +22 -18
  80. package/src/providers/provider.ts +17 -7
  81. package/src/providers/subscriber-polling.ts +1 -1
  82. package/src/quais.ts +5 -0
  83. package/src/transaction/utxo.ts +16 -0
  84. package/src/wallet/index.ts +2 -2
  85. package/src/wallet/payment-codes.ts +4 -6
  86. package/src/wallet/qi-hdwallet.ts +119 -53
package/dist/quais.js CHANGED
@@ -20867,7 +20867,12 @@ function addressFromTransactionRequest(tx) {
20867
20867
  return tx.from;
20868
20868
  }
20869
20869
  if ('txInputs' in tx && !!tx.txInputs) {
20870
- return computeAddress(tx.txInputs[0].pubkey);
20870
+ const inputs = tx.txInputs;
20871
+ return computeAddress(inputs[0].pubkey);
20872
+ }
20873
+ if ('txIn' in tx && !!tx.txIn) {
20874
+ const inputs = tx.txIn;
20875
+ return computeAddress(inputs[0].pubkey);
20871
20876
  }
20872
20877
  if ('to' in tx && !!tx.to) {
20873
20878
  return tx.to;
@@ -21623,9 +21628,7 @@ class TransactionReceipt {
21623
21628
  * @ignore
21624
21629
  */
21625
21630
  constructor(tx, provider) {
21626
- this.#logs = Object.freeze(tx.logs.map((log) => {
21627
- return new Log(log, provider);
21628
- }));
21631
+ this.#logs = Object.freeze(Array.isArray(tx.logs) ? tx.logs.map((log) => new Log(log, provider)) : []);
21629
21632
  let gasPrice = BN_0$1;
21630
21633
  if (tx.effectiveGasPrice != null) {
21631
21634
  gasPrice = tx.effectiveGasPrice;
@@ -27662,7 +27665,7 @@ class PaymentCodePublic {
27662
27665
  * @protected
27663
27666
  */
27664
27667
  getAddressFromPubkey(pubKey) {
27665
- return getAddress(keccak256('0x' + hexlify(pubKey).substring(4)).substring(26));
27668
+ return computeAddress(hexlify(pubKey));
27666
27669
  }
27667
27670
  /**
27668
27671
  * Retrieves a payment address based on the provided parameters.
@@ -27673,8 +27676,8 @@ class PaymentCodePublic {
27673
27676
  * @throws {Error} - If unable to derive public key or if an unknown address type is specified.
27674
27677
  */
27675
27678
  getPaymentAddress(paymentCode, idx) {
27676
- const pubkey = hexlify(this.derivePaymentPublicKey(paymentCode, idx));
27677
- return getAddress(keccak256('0x' + pubkey.substring(4)).substring(26));
27679
+ const pubkey = this.derivePaymentPublicKey(paymentCode, idx);
27680
+ return this.getAddressFromPubkey(pubkey);
27678
27681
  }
27679
27682
  }
27680
27683
  class PaymentCodePrivate extends PaymentCodePublic {
@@ -28440,14 +28443,14 @@ class QiHDWallet extends AbstractHDWallet {
28440
28443
  this._addressUseChecker = checker;
28441
28444
  }
28442
28445
  /**
28443
- * Finds the last used index in an array of QiAddressInfo objects.
28446
+ * Finds the last used index in an array of QiAddressInfo objects. If no index is found, returns -1.
28444
28447
  *
28445
28448
  * @param {QiAddressInfo[]} addresses - The array of QiAddressInfo objects.
28446
28449
  * @returns {number} The last used index.
28447
28450
  */
28448
28451
  _findLastUsedIndex(addresses, account, zone) {
28449
28452
  const filteredAddresses = addresses?.filter((addressInfo) => addressInfo.account === account && addressInfo.zone === zone);
28450
- return filteredAddresses?.reduce((maxIndex, addressInfo) => Math.max(maxIndex, addressInfo.index), -1) || 0;
28453
+ return filteredAddresses?.reduce((maxIndex, addressInfo) => Math.max(maxIndex, addressInfo.index), -1) || -1;
28451
28454
  }
28452
28455
  /**
28453
28456
  * Derives the next Qi BIP 44 address for the specified account and zone.
@@ -28685,66 +28688,93 @@ class QiHDWallet extends AbstractHDWallet {
28685
28688
  let selection = fewestCoinSelector.performSelection(spendTarget);
28686
28689
  // 3. Generate as many unused addresses as required to populate the spend outputs
28687
28690
  const sendAddresses = await getDestinationAddresses(selection.spendOutputs.length);
28688
- const getChangeAddresses = async (count) => {
28689
- const changeAddresses = this._addressesMap.get('BIP44:change') || [];
28690
- const addresses = [];
28691
- for (let i = 0; i < changeAddresses.length; i++) {
28692
- if (changeAddresses[i].status === AddressStatus.UNUSED) {
28693
- addresses.push(changeAddresses[i]);
28694
- }
28695
- if (addresses.length === count)
28691
+ const getChangeAddressesForOutputs = async (count) => {
28692
+ const currentChangeAddresses = this._addressesMap.get('BIP44:change') || [];
28693
+ const outpusChangeAddresses = [];
28694
+ for (let i = 0; i < currentChangeAddresses.length; i++) {
28695
+ if (currentChangeAddresses[i].status === AddressStatus.UNUSED) {
28696
+ outpusChangeAddresses.push(currentChangeAddresses[i]);
28697
+ }
28698
+ if (outpusChangeAddresses.length === count)
28696
28699
  break;
28697
28700
  }
28698
28701
  // Generate the remaining number of change addresses if needed
28699
- const remainingAddressesNeeded = count - addresses.length;
28702
+ const remainingAddressesNeeded = count - outpusChangeAddresses.length;
28700
28703
  if (remainingAddressesNeeded > 0) {
28701
- addresses.push(...Array(remainingAddressesNeeded)
28704
+ outpusChangeAddresses.push(...Array(remainingAddressesNeeded)
28702
28705
  .fill(0)
28703
28706
  .map(() => this.getNextChangeAddressSync(0, originZone)));
28704
28707
  }
28705
28708
  // Combine the existing change addresses with the newly generated addresses and ensure they are unique and sorted by index
28706
28709
  const mergedChangeAddresses = [
28707
- ...addresses.map((address) => ({ ...address, status: AddressStatus.ATTEMPTED_USE })),
28708
- ...changeAddresses,
28710
+ ...outpusChangeAddresses.map((address) => ({ ...address, status: AddressStatus.ATTEMPTED_USE })),
28711
+ ...currentChangeAddresses,
28709
28712
  ];
28710
28713
  const sortedAndFilteredChangeAddresses = mergedChangeAddresses
28711
28714
  .filter((address, index, self) => self.findIndex((t) => t.address === address.address) === index)
28712
28715
  .sort((a, b) => a.index - b.index);
28713
28716
  // Update the _addressesMap with the modified change addresses and statuses
28714
28717
  this._addressesMap.set('BIP44:change', sortedAndFilteredChangeAddresses);
28715
- return addresses.map((address) => address.address);
28718
+ return outpusChangeAddresses.map((address) => address.address);
28716
28719
  };
28717
28720
  // 4. Get change addresses
28718
- const changeAddresses = await getChangeAddresses(selection.changeOutputs.length);
28721
+ const changeAddresses = await getChangeAddressesForOutputs(selection.changeOutputs.length);
28719
28722
  // 5. Create the transaction and sign it using the signTransaction method
28720
28723
  let inputPubKeys = selection.inputs.map((input) => this.locateAddressInfo(input.address)?.pubKey);
28721
28724
  if (inputPubKeys.some((pubkey) => !pubkey)) {
28722
28725
  throw new Error('Missing public key for input address');
28723
28726
  }
28727
+ let attempts = 0;
28728
+ let finalFee = 0n;
28729
+ let satisfiedFeeEstimation = false;
28730
+ const MAX_FEE_ESTIMATION_ATTEMPTS = 5;
28731
+ while (attempts < MAX_FEE_ESTIMATION_ATTEMPTS) {
28732
+ const feeEstimationTx = this.prepareFeeEstimationTransaction(selection, inputPubKeys.map((pubkey) => pubkey), sendAddresses, changeAddresses);
28733
+ finalFee = await this.provider.estimateFeeForQi(feeEstimationTx);
28734
+ // Get new selection with updated fee
28735
+ selection = fewestCoinSelector.performSelection(spendTarget, finalFee);
28736
+ // Determine if new addresses are needed for the change outputs
28737
+ const changeAddressesNeeded = selection.changeOutputs.length - changeAddresses.length;
28738
+ if (changeAddressesNeeded > 0) {
28739
+ // Need more change addresses
28740
+ const newChangeAddresses = await getChangeAddressesForOutputs(changeAddressesNeeded);
28741
+ changeAddresses.push(...newChangeAddresses);
28742
+ }
28743
+ else if (changeAddressesNeeded < 0) {
28744
+ // Have extra change addresses, remove the addresses starting from the end
28745
+ // TODO: Set the status of the addresses to UNUSED in _addressesMap. This fine for now as it will be fixed during next sync
28746
+ changeAddresses.splice(changeAddressesNeeded);
28747
+ }
28748
+ // Determine if new addresses are needed for the spend outputs
28749
+ const spendAddressesNeeded = selection.spendOutputs.length - sendAddresses.length;
28750
+ if (spendAddressesNeeded > 0) {
28751
+ // Need more send addresses
28752
+ const newSendAddresses = await getDestinationAddresses(spendAddressesNeeded);
28753
+ sendAddresses.push(...newSendAddresses);
28754
+ }
28755
+ else if (spendAddressesNeeded < 0) {
28756
+ // Have extra send addresses, remove the excess
28757
+ // TODO: Set the status of the addresses to UNUSED in _addressesMap. This fine for now as it will be fixed during next sync
28758
+ sendAddresses.splice(spendAddressesNeeded);
28759
+ }
28760
+ inputPubKeys = selection.inputs.map((input) => this.locateAddressInfo(input.address)?.pubKey);
28761
+ // Calculate total new outputs needed (absolute value)
28762
+ const totalNewOutputsNeeded = Math.abs(changeAddressesNeeded) + Math.abs(spendAddressesNeeded);
28763
+ // If we need 5 or fewer new outputs, we can break the loop
28764
+ if ((changeAddressesNeeded <= 0 && spendAddressesNeeded <= 0) || totalNewOutputsNeeded <= 5) {
28765
+ finalFee *= 3n; // Increase the fee 3x to ensure it's accepted
28766
+ satisfiedFeeEstimation = true;
28767
+ break;
28768
+ }
28769
+ attempts++;
28770
+ }
28771
+ // If we didn't satisfy the fee estimation, increase the fee 10x to ensure it's accepted
28772
+ if (!satisfiedFeeEstimation) {
28773
+ finalFee *= 10n;
28774
+ }
28775
+ // Proceed with creating and signing the transaction
28724
28776
  const chainId = (await this.provider.getNetwork()).chainId;
28725
- let tx = await this.prepareTransaction(selection, inputPubKeys.map((pubkey) => pubkey), sendAddresses, changeAddresses, Number(chainId));
28726
- const gasLimit = await this.provider.estimateGas(tx);
28727
- const gasPrice = denominations[1]; // 0.005 Qi
28728
- const minerTip = (gasLimit * gasPrice) / 100n; // 1% extra as tip
28729
- // const feeData = await this.provider.getFeeData(originZone, true);
28730
- // const conversionRate = await this.provider.getLatestQuaiRate(originZone, feeData.gasPrice!);
28731
- // 5.6 Calculate total fee for the transaction using the gasLimit, gasPrice, and minerTip
28732
- const totalFee = gasLimit * gasPrice + minerTip;
28733
- // Get new selection with fee
28734
- selection = fewestCoinSelector.performSelection(spendTarget, totalFee);
28735
- // Determine if new addresses are needed for the change and spend outputs
28736
- const changeAddressesNeeded = selection.changeOutputs.length - changeAddresses.length;
28737
- if (changeAddressesNeeded > 0) {
28738
- const newChangeAddresses = await getChangeAddresses(changeAddressesNeeded);
28739
- changeAddresses.push(...newChangeAddresses);
28740
- }
28741
- const spendAddressesNeeded = selection.spendOutputs.length - sendAddresses.length;
28742
- if (spendAddressesNeeded > 0) {
28743
- const newSendAddresses = await getDestinationAddresses(spendAddressesNeeded);
28744
- sendAddresses.push(...newSendAddresses);
28745
- }
28746
- inputPubKeys = selection.inputs.map((input) => this.locateAddressInfo(input.address)?.pubKey);
28747
- tx = await this.prepareTransaction(selection, inputPubKeys.map((pubkey) => pubkey), sendAddresses, changeAddresses, Number(chainId));
28777
+ const tx = await this.prepareTransaction(selection, inputPubKeys.map((pubkey) => pubkey), sendAddresses, changeAddresses, Number(chainId));
28748
28778
  // Move used outpoints to pendingOutpoints
28749
28779
  this.moveOutpointsToPending(tx.txInputs);
28750
28780
  // Sign the transaction
@@ -28832,6 +28862,31 @@ class QiHDWallet extends AbstractHDWallet {
28832
28862
  tx.chainId = chainId;
28833
28863
  return tx;
28834
28864
  }
28865
+ prepareFeeEstimationTransaction(selection, inputPubKeys, sendAddresses, changeAddresses) {
28866
+ const txIn = selection.inputs.map((input, index) => ({
28867
+ previousOutpoint: { txHash: input.txhash, index: toQuantity(input.index) },
28868
+ pubkey: inputPubKeys[index],
28869
+ }));
28870
+ // 5.3 Create the "sender" outputs
28871
+ const senderOutputs = selection.spendOutputs.map((output, index) => ({
28872
+ address: sendAddresses[index],
28873
+ denomination: output.denomination,
28874
+ }));
28875
+ // 5.4 Create the "change" outputs
28876
+ const changeOutputs = selection.changeOutputs.map((output, index) => ({
28877
+ address: changeAddresses[index],
28878
+ denomination: output.denomination,
28879
+ }));
28880
+ const txOut = [...senderOutputs, ...changeOutputs].map((output) => ({
28881
+ address: output.address,
28882
+ denomination: toQuantity(output.denomination),
28883
+ }));
28884
+ return {
28885
+ txType: 2,
28886
+ txIn,
28887
+ txOut,
28888
+ };
28889
+ }
28835
28890
  /**
28836
28891
  * Checks the status of pending outpoints and updates the wallet's UTXO set accordingly.
28837
28892
  *
@@ -28970,7 +29025,7 @@ class QiHDWallet extends AbstractHDWallet {
28970
29025
  // (BIP47 addresses)
28971
29026
  const pcAddressInfo = addressInfo;
28972
29027
  const account = pcAddressInfo.account;
28973
- const index = pcAddressInfo.index - 1;
29028
+ const index = pcAddressInfo.index;
28974
29029
  const counterpartyPaymentCode = pcAddressInfo.derivationPath;
28975
29030
  if (!counterpartyPaymentCode) {
28976
29031
  throw new Error('Counterparty payment code not found for payment channel address');
@@ -29380,11 +29435,11 @@ class QiHDWallet extends AbstractHDWallet {
29380
29435
  const receiverPCodePublic = new PaymentCodePublic(ecc, bip32, buf.slice(1));
29381
29436
  const paymentCodeInfoArray = this._paymentCodeSendAddressMap.get(receiverPaymentCode);
29382
29437
  const lastIndex = this._findLastUsedIndex(paymentCodeInfoArray, account, zone);
29383
- let addrIndex = lastIndex;
29438
+ let addrIndex = lastIndex + 1;
29384
29439
  for (let attempts = 0; attempts < MAX_ADDRESS_DERIVATION_ATTEMPTS; attempts++) {
29385
- const address = receiverPCodePublic.getPaymentAddress(walletPCodePrivate, addrIndex++);
29440
+ const address = receiverPCodePublic.getPaymentAddress(walletPCodePrivate, addrIndex);
29386
29441
  if (this.isValidAddressForZone(address, zone)) {
29387
- const pubkey = receiverPCodePublic.derivePaymentPublicKey(walletPCodePrivate, addrIndex - 1);
29442
+ const pubkey = receiverPCodePublic.derivePaymentPublicKey(walletPCodePrivate, addrIndex);
29388
29443
  const pcInfo = {
29389
29444
  address,
29390
29445
  pubKey: hexlify(pubkey),
@@ -29403,6 +29458,7 @@ class QiHDWallet extends AbstractHDWallet {
29403
29458
  }
29404
29459
  return pcInfo;
29405
29460
  }
29461
+ addrIndex++;
29406
29462
  }
29407
29463
  throw new Error(`Failed to derive a valid address for the zone ${zone} after ${MAX_ADDRESS_DERIVATION_ATTEMPTS} attempts.`);
29408
29464
  }
@@ -29424,11 +29480,11 @@ class QiHDWallet extends AbstractHDWallet {
29424
29480
  const walletPCodePrivate = this._getPaymentCodePrivate(account);
29425
29481
  const paymentCodeInfoArray = this._addressesMap.get(senderPaymentCode);
29426
29482
  const lastIndex = this._findLastUsedIndex(paymentCodeInfoArray, account, zone);
29427
- let addrIndex = lastIndex;
29483
+ let addrIndex = lastIndex + 1;
29428
29484
  for (let attempts = 0; attempts < MAX_ADDRESS_DERIVATION_ATTEMPTS; attempts++) {
29429
- const address = walletPCodePrivate.getPaymentAddress(senderPCodePublic, addrIndex++);
29485
+ const address = walletPCodePrivate.getPaymentAddress(senderPCodePublic, addrIndex);
29430
29486
  if (this.isValidAddressForZone(address, zone)) {
29431
- const pubkey = walletPCodePrivate.derivePaymentPublicKey(senderPCodePublic, addrIndex - 1);
29487
+ const pubkey = walletPCodePrivate.derivePaymentPublicKey(senderPCodePublic, addrIndex);
29432
29488
  const pcInfo = {
29433
29489
  address,
29434
29490
  pubKey: hexlify(pubkey),
@@ -29447,6 +29503,7 @@ class QiHDWallet extends AbstractHDWallet {
29447
29503
  }
29448
29504
  return pcInfo;
29449
29505
  }
29506
+ addrIndex++;
29450
29507
  }
29451
29508
  throw new Error(`Failed to derive a valid address for the zone ${zone} after ${MAX_ADDRESS_DERIVATION_ATTEMPTS} attempts.`);
29452
29509
  }
@@ -30171,7 +30228,7 @@ async function getSubscription(_event, zone) {
30171
30228
  }
30172
30229
  if (isHexString(_event, 32)) {
30173
30230
  const eventBytes = getBytes(_event);
30174
- const ninthBit = (eventBytes[1] & 0x01) === 0x01;
30231
+ const ninthBit = (eventBytes[1] & 0x80) === 0x80;
30175
30232
  const hash = _event.toLowerCase();
30176
30233
  zone = toZone(hash.slice(0, 4));
30177
30234
  if (ninthBit) {
@@ -30997,6 +31054,14 @@ class AbstractProvider {
30997
31054
  zone: zone,
30998
31055
  }), '%response') * BigInt(2));
30999
31056
  }
31057
+ async estimateFeeForQi(_tx) {
31058
+ const zone = await this.zoneFromAddress(addressFromTransactionRequest(_tx));
31059
+ return getBigInt(await this.#perform({
31060
+ method: 'estimateFeeForQi',
31061
+ transaction: _tx,
31062
+ zone: zone,
31063
+ }), '%response');
31064
+ }
31000
31065
  async createAccessList(_tx) {
31001
31066
  let tx = this._getTransactionRequest(_tx);
31002
31067
  if (isPromise(tx)) {
@@ -31032,10 +31097,6 @@ class AbstractProvider {
31032
31097
  tx: this._getTransactionRequest(_tx),
31033
31098
  blockTag: this._getBlockTag(shard, _tx.blockTag),
31034
31099
  });
31035
- tx.accessList = (await this.createAccessList(tx)).map((it) => {
31036
- it.address = formatMixedCaseChecksumAddress(it.address);
31037
- return it;
31038
- });
31039
31100
  return await this.#checkNetwork(this.#call(tx, blockTag, -1, zone), shard);
31040
31101
  }
31041
31102
  // Account
@@ -31404,6 +31465,15 @@ class AbstractProvider {
31404
31465
  }
31405
31466
  return sub;
31406
31467
  }
31468
+ async startZoneSubscriptions(zone) {
31469
+ for (const sub of Array.from(this.#subs.values())) {
31470
+ if (sub.zone === zone) {
31471
+ if (sub.started) {
31472
+ await sub.subscriber.start();
31473
+ }
31474
+ }
31475
+ }
31476
+ }
31407
31477
  async on(event, listener, zone) {
31408
31478
  const sub = await this.#getSub(event, zone);
31409
31479
  sub.listeners.push({ listener, once: false });
@@ -32724,6 +32794,12 @@ class JsonRpcApiProvider extends AbstractProvider {
32724
32794
  args: [this.getRpcTransaction(req.transaction)],
32725
32795
  };
32726
32796
  }
32797
+ case 'estimateFeeForQi': {
32798
+ return {
32799
+ method: 'quai_estimateFeeForQi',
32800
+ args: [req.transaction],
32801
+ };
32802
+ }
32727
32803
  case 'createAccessList': {
32728
32804
  return {
32729
32805
  method: 'quai_createAccessList',
@@ -33927,7 +34003,7 @@ class WebSocketProvider extends SocketProvider {
33927
34003
  * @param {WebSocketLike} websocket - The WebSocket object.
33928
34004
  * @param {Shard} shard - The shard identifier.
33929
34005
  */
33930
- initWebSocket(websocket, shard) {
34006
+ initWebSocket(websocket, shard, port) {
33931
34007
  websocket.onerror = (error) => {
33932
34008
  console.log('WebsocketProvider error', error);
33933
34009
  websocket.close();
@@ -33937,6 +34013,13 @@ class WebSocketProvider extends SocketProvider {
33937
34013
  await this._start();
33938
34014
  this.resume();
33939
34015
  this.readyMap.set(shard, true);
34016
+ try {
34017
+ const zone = toZone(shard);
34018
+ this.provider.startZoneSubscriptions(zone);
34019
+ }
34020
+ catch (error) {
34021
+ // Intentionally left empty. Will catch if shard is prime or region, which isn't a zone
34022
+ }
33940
34023
  }
33941
34024
  catch (error) {
33942
34025
  console.log('failed to start WebsocketProvider', error);
@@ -33944,18 +34027,16 @@ class WebSocketProvider extends SocketProvider {
33944
34027
  // @TODO: now what? Attempt reconnect?
33945
34028
  }
33946
34029
  };
33947
- // @TODO: implement onclose
33948
- // websocket.onclose = () => {
33949
- // console.log('WebSocket closed. Attempting to reconnect...');
33950
- // setTimeout(() => {
33951
- // const baseUrl = websocket.url.split(':').slice(0, 2).join(':');
33952
- // const shardSuffix = this._getOption('usePathing') ? `/${fromShard(shard, 'nickname')}` : `:${port}`;
33953
- // const newWebSocket = this.createWebSocket(baseUrl, shardSuffix);
33954
- // this.initWebSocket(newWebSocket, shard, port);
33955
- // this.#websockets.push(newWebSocket);
33956
- // this._urlMap.set(shard, newWebSocket);
33957
- // }, 500); // Reconnect after 5 seconds
33958
- // };
34030
+ websocket.onclose = () => {
34031
+ setTimeout(() => {
34032
+ const baseUrl = websocket.url.split(':').slice(0, 2).join(':').split('/').slice(0, 3).join('/');
34033
+ const shardSuffix = this._getOption('usePathing') ? `/${fromShard(shard, 'nickname')}` : `:${port}`;
34034
+ const newWebSocket = this.createWebSocket(baseUrl, shardSuffix);
34035
+ this.initWebSocket(newWebSocket, shard, port);
34036
+ this.#websockets.push(newWebSocket);
34037
+ this._urlMap.set(shard, newWebSocket);
34038
+ }, 500); // Reconnect after .5 seconds
34039
+ };
33959
34040
  websocket.onmessage = (message) => {
33960
34041
  this._processMessage(message.data);
33961
34042
  };
@@ -34005,7 +34086,7 @@ class WebSocketProvider extends SocketProvider {
34005
34086
  : `:${port}`;
34006
34087
  const shardUrl = baseUrl.split(':').slice(0, 2).join(':');
34007
34088
  const websocket = this.createWebSocket(shardUrl, shardSuffix);
34008
- this.initWebSocket(websocket, shardEnum);
34089
+ this.initWebSocket(websocket, shardEnum, port);
34009
34090
  this.#websockets.push(websocket);
34010
34091
  this._urlMap.set(shardEnum, websocket);
34011
34092
  try {
@@ -34021,7 +34102,7 @@ class WebSocketProvider extends SocketProvider {
34021
34102
  for (const url of urls) {
34022
34103
  const baseUrl = `${url.split(':')[0]}:${url.split(':')[1]}`;
34023
34104
  const primeWebsocket = this.createWebSocket(baseUrl, primeSuffix);
34024
- this.initWebSocket(primeWebsocket, Shard.Prime);
34105
+ this.initWebSocket(primeWebsocket, Shard.Prime, 8001);
34025
34106
  this.#websockets.push(primeWebsocket);
34026
34107
  this._urlMap.set(Shard.Prime, primeWebsocket);
34027
34108
  await this.waitShardReady(Shard.Prime);
@@ -34030,7 +34111,7 @@ class WebSocketProvider extends SocketProvider {
34030
34111
  }
34031
34112
  else if (typeof urls === 'function') {
34032
34113
  const primeWebsocket = urls();
34033
- this.initWebSocket(primeWebsocket, Shard.Prime);
34114
+ this.initWebSocket(primeWebsocket, Shard.Prime, 8001);
34034
34115
  this.#websockets.push(primeWebsocket);
34035
34116
  this._urlMap.set(Shard.Prime, primeWebsocket);
34036
34117
  await this.waitShardReady(Shard.Prime);
@@ -34039,7 +34120,7 @@ class WebSocketProvider extends SocketProvider {
34039
34120
  }
34040
34121
  else {
34041
34122
  const primeWebsocket = urls;
34042
- this.initWebSocket(primeWebsocket, Shard.Prime);
34123
+ this.initWebSocket(primeWebsocket, Shard.Prime, 8001);
34043
34124
  this.#websockets.push(primeWebsocket);
34044
34125
  this._urlMap.set(Shard.Prime, primeWebsocket);
34045
34126
  await this.waitShardReady(Shard.Prime);