btc-wallet 0.3.10 → 0.3.11
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/index.js +213 -119
- package/dist/index.js.map +3 -3
- package/dist/utils/nearUtils.d.ts +1 -2
- package/esm/index.js +213 -119
- package/esm/index.js.map +2 -2
- package/package.json +1 -1
@@ -1,7 +1,6 @@
|
|
1
1
|
import type { ProviderService } from '@near-wallet-selector/core/src/lib/services';
|
2
|
-
import { providers } from 'near-api-js';
|
3
2
|
export declare function nearCallFunction<T>(contractId: string, methodName: string, args: any, options: {
|
4
3
|
network?: string;
|
5
4
|
provider?: ProviderService;
|
6
5
|
}): Promise<T>;
|
7
|
-
export declare function pollTransactionStatuses(network: string, hashes: string[]): Promise<
|
6
|
+
export declare function pollTransactionStatuses(network: string, hashes: string[]): Promise<any[]>;
|
package/esm/index.js
CHANGED
@@ -2714,9 +2714,7 @@ var nearRpcUrls = {
|
|
2714
2714
|
"https://near.drpc.org"
|
2715
2715
|
],
|
2716
2716
|
testnet: [
|
2717
|
-
"https://rpc.testnet.near.org"
|
2718
|
-
"https://near-testnet.lava.build",
|
2719
|
-
"https://near-testnet.drpc.org"
|
2717
|
+
"https://rpc.testnet.near.org"
|
2720
2718
|
]
|
2721
2719
|
};
|
2722
2720
|
var btcRpcUrls = {
|
@@ -2820,29 +2818,38 @@ function pollTransactionStatuses(network, hashes) {
|
|
2820
2818
|
(url) => new providers.JsonRpcProvider({ url })
|
2821
2819
|
)
|
2822
2820
|
);
|
2823
|
-
const maxAttempts =
|
2824
|
-
|
2825
|
-
|
2826
|
-
|
2827
|
-
|
2821
|
+
const maxAttempts = 30;
|
2822
|
+
let currentAttempt = 0;
|
2823
|
+
const pendingHashes = new Set(hashes);
|
2824
|
+
const results = /* @__PURE__ */ new Map();
|
2825
|
+
while (pendingHashes.size > 0 && currentAttempt < maxAttempts) {
|
2826
|
+
currentAttempt++;
|
2827
|
+
const promises = Array.from(pendingHashes).map((hash) => __async(this, null, function* () {
|
2828
2828
|
try {
|
2829
2829
|
const result = yield provider.txStatus(hash, "unused", "FINAL");
|
2830
2830
|
if (result && result.status) {
|
2831
2831
|
console.log(`Transaction ${hash} result:`, result);
|
2832
|
-
|
2832
|
+
results.set(hash, result);
|
2833
|
+
pendingHashes.delete(hash);
|
2833
2834
|
}
|
2834
2835
|
} catch (error) {
|
2835
2836
|
console.error(`Failed to fetch transaction status for ${hash}: ${error.message}`);
|
2836
2837
|
}
|
2837
|
-
|
2838
|
-
|
2838
|
+
}));
|
2839
|
+
yield Promise.all(promises);
|
2840
|
+
if (pendingHashes.size > 0) {
|
2841
|
+
if (currentAttempt === maxAttempts) {
|
2842
|
+
throw new Error(
|
2843
|
+
`Transactions not found after max attempts: ${Array.from(pendingHashes).join(", ")}`
|
2844
|
+
);
|
2839
2845
|
}
|
2846
|
+
console.log(
|
2847
|
+
`Waiting for ${pendingHashes.size} transactions, retrying ${maxAttempts - currentAttempt} more times`
|
2848
|
+
);
|
2840
2849
|
yield delay(1e4);
|
2841
|
-
console.log(`RPC request failed for ${hash}, retrying ${maxAttempts - attempt} more times`);
|
2842
2850
|
}
|
2843
|
-
}
|
2844
|
-
|
2845
|
-
return results;
|
2851
|
+
}
|
2852
|
+
return hashes.map((hash) => results.get(hash));
|
2846
2853
|
});
|
2847
2854
|
}
|
2848
2855
|
|
@@ -3048,80 +3055,31 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
3048
3055
|
return __async(this, null, function* () {
|
3049
3056
|
const btcContext = window.btcContext;
|
3050
3057
|
const accountId = state.getAccount();
|
3051
|
-
const
|
3052
|
-
|
3053
|
-
const
|
3054
|
-
request_type: "view_access_key",
|
3055
|
-
account_id: accountId,
|
3056
|
-
public_key: publicKey,
|
3057
|
-
finality: "final"
|
3058
|
-
});
|
3059
|
-
const accessKey = __spreadProps(__spreadValues({}, rawAccessKey), {
|
3060
|
-
nonce: BigInt(rawAccessKey.nonce || 0)
|
3061
|
-
});
|
3062
|
-
const publicKeyFormat = PublicKey.from(publicKey);
|
3063
|
-
const { result_data: nearNonceFromApi } = yield getNearNonceFromApi(
|
3064
|
-
currentConfig.base_url,
|
3065
|
-
accountId
|
3066
|
-
);
|
3067
|
-
const { transferGasTransaction, useNearPayGas } = yield getGasConfig();
|
3058
|
+
const trans = [...params.transactions];
|
3059
|
+
console.log("raw trans:", trans);
|
3060
|
+
const { transferGasTransaction, useNearPayGas, gasLimit } = yield calculateGasStrategy(trans);
|
3068
3061
|
console.log("transferGasTransaction:", transferGasTransaction);
|
3069
3062
|
console.log("useNearPayGas:", useNearPayGas);
|
3070
|
-
|
3071
|
-
|
3072
|
-
|
3073
|
-
|
3074
|
-
|
3075
|
-
|
3076
|
-
|
3077
|
-
nearNonceNumber = BigInt(nearNonceFromApi) > nearNonceNumber ? BigInt(nearNonceFromApi) : nearNonceNumber;
|
3078
|
-
}
|
3079
|
-
const newActions = transaction.actions.map((action) => {
|
3080
|
-
switch (action.type) {
|
3081
|
-
case "FunctionCall":
|
3082
|
-
return functionCall(
|
3083
|
-
action.params.methodName,
|
3084
|
-
action.params.args,
|
3085
|
-
BigInt(action.params.gas),
|
3086
|
-
BigInt(action.params.deposit)
|
3087
|
-
);
|
3088
|
-
case "Transfer":
|
3089
|
-
return transfer(BigInt(action.params.deposit));
|
3090
|
-
}
|
3091
|
-
}).filter(Boolean);
|
3092
|
-
const _transaction = transactions.createTransaction(
|
3093
|
-
accountId,
|
3094
|
-
publicKeyFormat,
|
3095
|
-
transaction.receiverId,
|
3096
|
-
BigInt(nearNonceNumber) + BigInt(index),
|
3097
|
-
newActions,
|
3098
|
-
baseDecode(header.hash)
|
3099
|
-
);
|
3100
|
-
const txBytes = encodeTransaction(_transaction);
|
3101
|
-
const txHex = Array.from(
|
3102
|
-
txBytes,
|
3103
|
-
(byte) => ("0" + (byte & 255).toString(16)).slice(-2)
|
3104
|
-
).join("");
|
3105
|
-
console.log("txHex:", txHex);
|
3106
|
-
const hash = bs58.encode(new Uint8Array(sha256.array(txBytes)));
|
3107
|
-
return { txBytes, txHex, hash };
|
3108
|
-
});
|
3109
|
-
const accountInfo = yield nearCall2(
|
3110
|
-
currentConfig.accountContractId,
|
3111
|
-
"get_account",
|
3112
|
-
{ account_id: accountId }
|
3063
|
+
console.log("gasLimit:", gasLimit);
|
3064
|
+
if (transferGasTransaction) {
|
3065
|
+
trans.unshift(transferGasTransaction);
|
3066
|
+
}
|
3067
|
+
console.log("calculateGasStrategy trans:", trans);
|
3068
|
+
const newTrans = yield Promise.all(
|
3069
|
+
trans.map((transaction, index) => convertTransactionToTxHex(transaction, index))
|
3113
3070
|
);
|
3114
3071
|
const { result_data: nonceFromApi } = yield getNonceFromApi(
|
3115
3072
|
currentConfig.base_url,
|
3116
3073
|
accountId
|
3117
3074
|
);
|
3075
|
+
const accountInfo = yield getAccountInfo();
|
3118
3076
|
const nonce = Number(nonceFromApi) > Number(accountInfo.nonce) ? String(nonceFromApi) : String(accountInfo.nonce);
|
3119
3077
|
const intention = {
|
3120
3078
|
chain_id: "397",
|
3121
3079
|
csna: accountId,
|
3122
|
-
near_transactions:
|
3080
|
+
near_transactions: newTrans.map((t) => t.txHex),
|
3123
3081
|
gas_token: currentConfig.token,
|
3124
|
-
gas_limit:
|
3082
|
+
gas_limit: gasLimit,
|
3125
3083
|
use_near_pay_gas: useNearPayGas,
|
3126
3084
|
nonce
|
3127
3085
|
};
|
@@ -3133,7 +3091,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
3133
3091
|
data: toHex(strIntention)
|
3134
3092
|
});
|
3135
3093
|
if (result.result_code === 0) {
|
3136
|
-
const hash =
|
3094
|
+
const hash = newTrans.map((t) => t.hash);
|
3137
3095
|
console.log("txHash:", hash);
|
3138
3096
|
const result2 = yield pollTransactionStatuses(options.network.networkId, hash);
|
3139
3097
|
return result2;
|
@@ -3142,8 +3100,71 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
3142
3100
|
}
|
3143
3101
|
});
|
3144
3102
|
}
|
3145
|
-
function
|
3103
|
+
function getAccountInfo() {
|
3104
|
+
return __async(this, null, function* () {
|
3105
|
+
const accountId = state.getAccount();
|
3106
|
+
const accountInfo = yield nearCall2(
|
3107
|
+
currentConfig.accountContractId,
|
3108
|
+
"get_account",
|
3109
|
+
{ account_id: accountId }
|
3110
|
+
);
|
3111
|
+
return accountInfo;
|
3112
|
+
});
|
3113
|
+
}
|
3114
|
+
function createGasTokenTransfer(accountId, amount) {
|
3115
|
+
return __async(this, null, function* () {
|
3116
|
+
return {
|
3117
|
+
signerId: accountId,
|
3118
|
+
receiverId: currentConfig.token,
|
3119
|
+
actions: [
|
3120
|
+
{
|
3121
|
+
type: "FunctionCall",
|
3122
|
+
params: {
|
3123
|
+
methodName: "ft_transfer_call",
|
3124
|
+
args: {
|
3125
|
+
receiver_id: currentConfig.accountContractId,
|
3126
|
+
amount,
|
3127
|
+
msg: JSON.stringify("Deposit")
|
3128
|
+
},
|
3129
|
+
gas: new Big(50).mul(__pow(10, 12)).toFixed(0),
|
3130
|
+
deposit: "1"
|
3131
|
+
}
|
3132
|
+
}
|
3133
|
+
]
|
3134
|
+
};
|
3135
|
+
});
|
3136
|
+
}
|
3137
|
+
function recalculateGasWithTransfer(transferTx, transactions2, useNearPayGas, perTxFee) {
|
3138
|
+
return __async(this, null, function* () {
|
3139
|
+
const { txHex: transferTxHex } = yield convertTransactionToTxHex(transferTx);
|
3140
|
+
let newGasLimit;
|
3141
|
+
if (useNearPayGas && perTxFee) {
|
3142
|
+
newGasLimit = new Big(perTxFee).mul(transactions2.length + 1).toFixed(0);
|
3143
|
+
} else {
|
3144
|
+
newGasLimit = yield getPredictedGasAmount(
|
3145
|
+
currentConfig.accountContractId,
|
3146
|
+
currentConfig.token,
|
3147
|
+
[transferTxHex, ...transactions2.map((t) => t.txHex)]
|
3148
|
+
);
|
3149
|
+
}
|
3150
|
+
transferTx.actions[0].params.args.amount = newGasLimit;
|
3151
|
+
return { transferGasTransaction: transferTx, useNearPayGas, gasLimit: newGasLimit };
|
3152
|
+
});
|
3153
|
+
}
|
3154
|
+
function getPredictedGasAmount(accountContractId, tokenId, transactions2) {
|
3155
|
+
return __async(this, null, function* () {
|
3156
|
+
const predictedGas = yield nearCall2(accountContractId, "predict_txs_gas_token_amount", {
|
3157
|
+
gas_token_id: tokenId,
|
3158
|
+
near_transactions: transactions2
|
3159
|
+
});
|
3160
|
+
const predictedGasAmount = new Big(predictedGas).mul(1.2).toFixed(0);
|
3161
|
+
console.log("predictedGas:", predictedGasAmount);
|
3162
|
+
return predictedGasAmount;
|
3163
|
+
});
|
3164
|
+
}
|
3165
|
+
function calculateGasStrategy(transactions2) {
|
3146
3166
|
return __async(this, null, function* () {
|
3167
|
+
var _a;
|
3147
3168
|
const accountId = state.getAccount();
|
3148
3169
|
const nearAccount = yield provider.query({
|
3149
3170
|
request_type: "view_account",
|
@@ -3151,39 +3172,107 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
3151
3172
|
finality: "final"
|
3152
3173
|
});
|
3153
3174
|
const availableBalance = parseFloat(nearAccount.amount) / __pow(10, 24);
|
3175
|
+
console.log("available near balance:", availableBalance);
|
3176
|
+
const accountInfo = yield getAccountInfo();
|
3177
|
+
const gasTokenBalance = accountInfo.gas_token[currentConfig.token] || "0";
|
3178
|
+
console.log("available gas token balance:", gasTokenBalance);
|
3179
|
+
const convertTx = yield Promise.all(
|
3180
|
+
transactions2.map((transaction, index) => convertTransactionToTxHex(transaction, index))
|
3181
|
+
);
|
3154
3182
|
if (availableBalance > 0.2) {
|
3155
|
-
|
3183
|
+
const gasTokens = yield nearCall2(
|
3184
|
+
currentConfig.accountContractId,
|
3185
|
+
"list_gas_token",
|
3186
|
+
{ token_ids: [currentConfig.token] }
|
3187
|
+
);
|
3188
|
+
console.log("list_gas_token gas tokens:", gasTokens);
|
3189
|
+
const perTxFee = Math.max(
|
3190
|
+
Number(((_a = gasTokens[currentConfig.token]) == null ? void 0 : _a.per_tx_protocol_fee) || 0),
|
3191
|
+
100
|
3192
|
+
);
|
3193
|
+
console.log("perTxFee:", perTxFee);
|
3194
|
+
const protocolFee = new Big(perTxFee || "0").mul(convertTx.length).toFixed(0);
|
3195
|
+
console.log("protocolFee:", protocolFee);
|
3196
|
+
if (new Big(gasTokenBalance).gte(protocolFee)) {
|
3197
|
+
console.log("use near pay gas and enough gas token balance");
|
3198
|
+
return { useNearPayGas: true, gasLimit: protocolFee };
|
3199
|
+
} else {
|
3200
|
+
console.log("use near pay gas and not enough gas token balance");
|
3201
|
+
const transferTx = yield createGasTokenTransfer(accountId, protocolFee);
|
3202
|
+
return recalculateGasWithTransfer(transferTx, convertTx, true, perTxFee.toString());
|
3203
|
+
}
|
3156
3204
|
} else {
|
3157
|
-
|
3158
|
-
|
3159
|
-
|
3160
|
-
|
3161
|
-
|
3162
|
-
|
3163
|
-
|
3164
|
-
|
3165
|
-
|
3166
|
-
type: "FunctionCall",
|
3167
|
-
params: {
|
3168
|
-
methodName: "ft_transfer_call",
|
3169
|
-
args: {
|
3170
|
-
receiver_id: currentConfig.accountContractId,
|
3171
|
-
amount: currentConfig.gasTokenLimit,
|
3172
|
-
msg: "Deposit"
|
3173
|
-
},
|
3174
|
-
gas: new Big(50).mul(__pow(10, 12)).toFixed(0),
|
3175
|
-
deposit: "1"
|
3176
|
-
}
|
3177
|
-
}
|
3178
|
-
]
|
3179
|
-
};
|
3180
|
-
return { transferGasTransaction, useNearPayGas: false };
|
3205
|
+
console.log("near balance is not enough, predict the gas token amount required");
|
3206
|
+
const adjustedGas = yield getPredictedGasAmount(
|
3207
|
+
currentConfig.accountContractId,
|
3208
|
+
currentConfig.token,
|
3209
|
+
convertTx.map((t) => t.txHex)
|
3210
|
+
);
|
3211
|
+
if (new Big(gasTokenBalance).gte(adjustedGas)) {
|
3212
|
+
console.log("use gas token and gas token balance is enough");
|
3213
|
+
return { useNearPayGas: false, gasLimit: adjustedGas };
|
3181
3214
|
} else {
|
3182
|
-
|
3215
|
+
console.log("use gas token and gas token balance is not enough, need to transfer");
|
3216
|
+
const transferTx = yield createGasTokenTransfer(accountId, adjustedGas);
|
3217
|
+
return recalculateGasWithTransfer(transferTx, convertTx, false);
|
3183
3218
|
}
|
3184
3219
|
}
|
3185
3220
|
});
|
3186
3221
|
}
|
3222
|
+
function convertTransactionToTxHex(transaction, index = 0) {
|
3223
|
+
return __async(this, null, function* () {
|
3224
|
+
const accountId = state.getAccount();
|
3225
|
+
const publicKey = state.getPublicKey();
|
3226
|
+
const publicKeyFormat = PublicKey.from(publicKey);
|
3227
|
+
const { header } = yield provider.block({
|
3228
|
+
finality: "final"
|
3229
|
+
});
|
3230
|
+
const rawAccessKey = yield provider.query({
|
3231
|
+
request_type: "view_access_key",
|
3232
|
+
account_id: accountId,
|
3233
|
+
public_key: publicKey,
|
3234
|
+
finality: "final"
|
3235
|
+
});
|
3236
|
+
const accessKey = __spreadProps(__spreadValues({}, rawAccessKey), {
|
3237
|
+
nonce: BigInt(rawAccessKey.nonce || 0)
|
3238
|
+
});
|
3239
|
+
const { result_data: nearNonceFromApi } = yield getNearNonceFromApi(
|
3240
|
+
currentConfig.base_url,
|
3241
|
+
accountId
|
3242
|
+
);
|
3243
|
+
let nearNonceNumber = accessKey.nonce + BigInt(1);
|
3244
|
+
if (nearNonceFromApi) {
|
3245
|
+
nearNonceNumber = BigInt(nearNonceFromApi) > nearNonceNumber ? BigInt(nearNonceFromApi) : nearNonceNumber;
|
3246
|
+
}
|
3247
|
+
const newActions = transaction.actions.map((action) => {
|
3248
|
+
switch (action.type) {
|
3249
|
+
case "FunctionCall":
|
3250
|
+
return functionCall(
|
3251
|
+
action.params.methodName,
|
3252
|
+
action.params.args,
|
3253
|
+
BigInt(action.params.gas),
|
3254
|
+
BigInt(action.params.deposit)
|
3255
|
+
);
|
3256
|
+
case "Transfer":
|
3257
|
+
return transfer(BigInt(action.params.deposit));
|
3258
|
+
}
|
3259
|
+
}).filter(Boolean);
|
3260
|
+
const _transaction = transactions.createTransaction(
|
3261
|
+
accountId,
|
3262
|
+
publicKeyFormat,
|
3263
|
+
transaction.receiverId,
|
3264
|
+
BigInt(nearNonceNumber) + BigInt(index),
|
3265
|
+
newActions,
|
3266
|
+
baseDecode(header.hash)
|
3267
|
+
);
|
3268
|
+
const txBytes = encodeTransaction(_transaction);
|
3269
|
+
const txHex = Array.from(txBytes, (byte) => ("0" + (byte & 255).toString(16)).slice(-2)).join(
|
3270
|
+
""
|
3271
|
+
);
|
3272
|
+
const hash = bs58.encode(new Uint8Array(sha256.array(txBytes)));
|
3273
|
+
return { txBytes, txHex, hash };
|
3274
|
+
});
|
3275
|
+
}
|
3187
3276
|
function initWalletButton(network, wallet2) {
|
3188
3277
|
return __async(this, null, function* () {
|
3189
3278
|
const checkAndSetupWalletButton = () => {
|
@@ -3216,6 +3305,14 @@ function uploadBTCTx(url, data) {
|
|
3216
3305
|
body: data
|
3217
3306
|
});
|
3218
3307
|
}
|
3308
|
+
function toHex(originalString) {
|
3309
|
+
const charArray = originalString.split("");
|
3310
|
+
const asciiArray = charArray.map((char) => char.charCodeAt(0));
|
3311
|
+
const hexArray = asciiArray.map((code) => code.toString(16));
|
3312
|
+
let hexString = hexArray.join("");
|
3313
|
+
hexString = hexString.replace(/(^0+)/g, "");
|
3314
|
+
return hexString;
|
3315
|
+
}
|
3219
3316
|
function setupBTCWallet({
|
3220
3317
|
iconUrl = "https://assets.deltatrade.ai/assets/chain/btc.svg",
|
3221
3318
|
deprecated = false,
|
@@ -3243,14 +3340,6 @@ function setupBTCWallet({
|
|
3243
3340
|
});
|
3244
3341
|
return btcWallet;
|
3245
3342
|
}
|
3246
|
-
function toHex(originalString) {
|
3247
|
-
const charArray = originalString.split("");
|
3248
|
-
const asciiArray = charArray.map((char) => char.charCodeAt(0));
|
3249
|
-
const hexArray = asciiArray.map((code) => code.toString(16));
|
3250
|
-
let hexString = hexArray.join("");
|
3251
|
-
hexString = hexString.replace(/(^0+)/g, "");
|
3252
|
-
return hexString;
|
3253
|
-
}
|
3254
3343
|
|
3255
3344
|
// src/core/btcUtils.ts
|
3256
3345
|
import Big2 from "big.js";
|
@@ -3330,18 +3419,23 @@ function getBtcGasPrice() {
|
|
3330
3419
|
}
|
3331
3420
|
function getBtcBalance() {
|
3332
3421
|
return __async(this, null, function* () {
|
3333
|
-
const { account } = yield retryOperation(getBtcProvider, (
|
3422
|
+
const { account } = yield retryOperation(getBtcProvider, (res) => !!res.account);
|
3334
3423
|
if (!account) {
|
3335
3424
|
console.error("BTC Account is not available.");
|
3336
3425
|
return { rawBalance: 0, balance: 0, maxSpendableBalance: 0 };
|
3337
3426
|
}
|
3338
3427
|
const btcRpcUrl = yield getBtcRpcUrl();
|
3339
|
-
const
|
3340
|
-
const rawBalance =
|
3428
|
+
const utxos = yield fetch(`${btcRpcUrl}/address/${account}/utxo`).then((res) => res.json());
|
3429
|
+
const rawBalance = (utxos == null ? void 0 : utxos.reduce((acc, cur) => acc + cur.value, 0)) || 0;
|
3341
3430
|
const balance = rawBalance / __pow(10, 8);
|
3342
3431
|
const feeRate = yield getBtcGasPrice();
|
3343
|
-
const
|
3344
|
-
const
|
3432
|
+
const inputSize = ((utxos == null ? void 0 : utxos.length) || 0) * 66;
|
3433
|
+
const outputSize = 34;
|
3434
|
+
const overheadSize = 10;
|
3435
|
+
const estimatedTxSize = inputSize + outputSize + overheadSize;
|
3436
|
+
const estimatedFee = estimatedTxSize * feeRate / __pow(10, 8);
|
3437
|
+
console.log("estimated fee:", estimatedFee);
|
3438
|
+
const availableBalance = Math.max(0, balance - estimatedFee);
|
3345
3439
|
return {
|
3346
3440
|
rawBalance,
|
3347
3441
|
balance,
|
@@ -3468,7 +3562,7 @@ function executeBTCDepositAndAction(_0) {
|
|
3468
3562
|
|
3469
3563
|
// src/index.ts
|
3470
3564
|
var getVersion = () => {
|
3471
|
-
return "0.3.
|
3565
|
+
return "0.3.11";
|
3472
3566
|
};
|
3473
3567
|
if (typeof window !== "undefined") {
|
3474
3568
|
window.__PARTICLE_BTC_CONNECT_VERSION = getVersion();
|