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.
- package/dist/quais.js +156 -75
- package/dist/quais.js.map +1 -1
- package/dist/quais.min.js +1 -1
- package/dist/quais.umd.js +156 -75
- package/dist/quais.umd.js.map +1 -1
- package/dist/quais.umd.min.js +1 -1
- package/examples/signing/pubkey-to-address.js +37 -0
- package/examples/wallets/qi-wallet-alice-bob-send-receive.js +90 -0
- package/examples/wallets/qi-wallet-convert-to-quai.js +73 -0
- package/examples/wallets/qi-wallet-send-qi-to-bob.js +87 -0
- package/examples/wallets/utils.js +132 -0
- package/lib/commonjs/providers/abstract-provider.d.ts +13 -4
- package/lib/commonjs/providers/abstract-provider.d.ts.map +1 -1
- package/lib/commonjs/providers/abstract-provider.js +18 -5
- package/lib/commonjs/providers/abstract-provider.js.map +1 -1
- package/lib/commonjs/providers/provider-jsonrpc.d.ts.map +1 -1
- package/lib/commonjs/providers/provider-jsonrpc.js +6 -0
- package/lib/commonjs/providers/provider-jsonrpc.js.map +1 -1
- package/lib/commonjs/providers/provider-websocket.d.ts +1 -1
- package/lib/commonjs/providers/provider-websocket.d.ts.map +1 -1
- package/lib/commonjs/providers/provider-websocket.js +22 -17
- package/lib/commonjs/providers/provider-websocket.js.map +1 -1
- package/lib/commonjs/providers/provider.d.ts +8 -0
- package/lib/commonjs/providers/provider.d.ts.map +1 -1
- package/lib/commonjs/providers/provider.js +7 -4
- package/lib/commonjs/providers/provider.js.map +1 -1
- package/lib/commonjs/providers/subscriber-polling.js +1 -1
- package/lib/commonjs/quais.d.ts +2 -2
- package/lib/commonjs/quais.d.ts.map +1 -1
- package/lib/commonjs/quais.js.map +1 -1
- package/lib/commonjs/transaction/utxo.d.ts +14 -0
- package/lib/commonjs/transaction/utxo.d.ts.map +1 -1
- package/lib/commonjs/transaction/utxo.js.map +1 -1
- package/lib/commonjs/wallet/index.d.ts +2 -2
- package/lib/commonjs/wallet/index.d.ts.map +1 -1
- package/lib/commonjs/wallet/index.js.map +1 -1
- package/lib/commonjs/wallet/payment-codes.d.ts.map +1 -1
- package/lib/commonjs/wallet/payment-codes.js +3 -4
- package/lib/commonjs/wallet/payment-codes.js.map +1 -1
- package/lib/commonjs/wallet/qi-hdwallet.d.ts +3 -2
- package/lib/commonjs/wallet/qi-hdwallet.d.ts.map +1 -1
- package/lib/commonjs/wallet/qi-hdwallet.js +98 -44
- package/lib/commonjs/wallet/qi-hdwallet.js.map +1 -1
- package/lib/esm/providers/abstract-provider.d.ts +13 -4
- package/lib/esm/providers/abstract-provider.d.ts.map +1 -1
- package/lib/esm/providers/abstract-provider.js +18 -5
- package/lib/esm/providers/abstract-provider.js.map +1 -1
- package/lib/esm/providers/provider-jsonrpc.d.ts.map +1 -1
- package/lib/esm/providers/provider-jsonrpc.js +6 -0
- package/lib/esm/providers/provider-jsonrpc.js.map +1 -1
- package/lib/esm/providers/provider-websocket.d.ts +1 -1
- package/lib/esm/providers/provider-websocket.d.ts.map +1 -1
- package/lib/esm/providers/provider-websocket.js +23 -18
- package/lib/esm/providers/provider-websocket.js.map +1 -1
- package/lib/esm/providers/provider.d.ts +8 -0
- package/lib/esm/providers/provider.d.ts.map +1 -1
- package/lib/esm/providers/provider.js +7 -4
- package/lib/esm/providers/provider.js.map +1 -1
- package/lib/esm/providers/subscriber-polling.js +1 -1
- package/lib/esm/quais.d.ts +2 -2
- package/lib/esm/quais.d.ts.map +1 -1
- package/lib/esm/quais.js.map +1 -1
- package/lib/esm/transaction/utxo.d.ts +14 -0
- package/lib/esm/transaction/utxo.d.ts.map +1 -1
- package/lib/esm/transaction/utxo.js.map +1 -1
- package/lib/esm/wallet/index.d.ts +2 -2
- package/lib/esm/wallet/index.d.ts.map +1 -1
- package/lib/esm/wallet/index.js.map +1 -1
- package/lib/esm/wallet/payment-codes.d.ts.map +1 -1
- package/lib/esm/wallet/payment-codes.js +4 -5
- package/lib/esm/wallet/payment-codes.js.map +1 -1
- package/lib/esm/wallet/qi-hdwallet.d.ts +3 -2
- package/lib/esm/wallet/qi-hdwallet.d.ts.map +1 -1
- package/lib/esm/wallet/qi-hdwallet.js +99 -45
- package/lib/esm/wallet/qi-hdwallet.js.map +1 -1
- package/package.json +1 -1
- package/src/providers/abstract-provider.ts +36 -9
- package/src/providers/provider-jsonrpc.ts +7 -0
- package/src/providers/provider-websocket.ts +22 -18
- package/src/providers/provider.ts +17 -7
- package/src/providers/subscriber-polling.ts +1 -1
- package/src/quais.ts +5 -0
- package/src/transaction/utxo.ts +16 -0
- package/src/wallet/index.ts +2 -2
- package/src/wallet/payment-codes.ts +4 -6
- 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
|
-
|
|
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
|
|
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 =
|
|
27677
|
-
return
|
|
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) ||
|
|
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
|
|
28689
|
-
const
|
|
28690
|
-
const
|
|
28691
|
-
for (let i = 0; i <
|
|
28692
|
-
if (
|
|
28693
|
-
|
|
28694
|
-
}
|
|
28695
|
-
if (
|
|
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 -
|
|
28702
|
+
const remainingAddressesNeeded = count - outpusChangeAddresses.length;
|
|
28700
28703
|
if (remainingAddressesNeeded > 0) {
|
|
28701
|
-
|
|
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
|
-
...
|
|
28708
|
-
...
|
|
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
|
|
28718
|
+
return outpusChangeAddresses.map((address) => address.address);
|
|
28716
28719
|
};
|
|
28717
28720
|
// 4. Get change addresses
|
|
28718
|
-
const changeAddresses = await
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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] &
|
|
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
|
-
|
|
33948
|
-
|
|
33949
|
-
|
|
33950
|
-
|
|
33951
|
-
|
|
33952
|
-
|
|
33953
|
-
|
|
33954
|
-
|
|
33955
|
-
|
|
33956
|
-
|
|
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);
|