btc-wallet 0.3.10 → 0.3.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.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
package/dist/index.js
CHANGED
@@ -2754,9 +2754,7 @@ var nearRpcUrls = {
|
|
2754
2754
|
"https://near.drpc.org"
|
2755
2755
|
],
|
2756
2756
|
testnet: [
|
2757
|
-
"https://rpc.testnet.near.org"
|
2758
|
-
"https://near-testnet.lava.build",
|
2759
|
-
"https://near-testnet.drpc.org"
|
2757
|
+
"https://rpc.testnet.near.org"
|
2760
2758
|
]
|
2761
2759
|
};
|
2762
2760
|
var btcRpcUrls = {
|
@@ -2860,29 +2858,38 @@ function pollTransactionStatuses(network, hashes) {
|
|
2860
2858
|
(url) => new import_near_api_js.providers.JsonRpcProvider({ url })
|
2861
2859
|
)
|
2862
2860
|
);
|
2863
|
-
const maxAttempts =
|
2864
|
-
|
2865
|
-
|
2866
|
-
|
2867
|
-
|
2861
|
+
const maxAttempts = 30;
|
2862
|
+
let currentAttempt = 0;
|
2863
|
+
const pendingHashes = new Set(hashes);
|
2864
|
+
const results = /* @__PURE__ */ new Map();
|
2865
|
+
while (pendingHashes.size > 0 && currentAttempt < maxAttempts) {
|
2866
|
+
currentAttempt++;
|
2867
|
+
const promises = Array.from(pendingHashes).map((hash) => __async(this, null, function* () {
|
2868
2868
|
try {
|
2869
2869
|
const result = yield provider.txStatus(hash, "unused", "FINAL");
|
2870
2870
|
if (result && result.status) {
|
2871
2871
|
console.log(`Transaction ${hash} result:`, result);
|
2872
|
-
|
2872
|
+
results.set(hash, result);
|
2873
|
+
pendingHashes.delete(hash);
|
2873
2874
|
}
|
2874
2875
|
} catch (error) {
|
2875
2876
|
console.error(`Failed to fetch transaction status for ${hash}: ${error.message}`);
|
2876
2877
|
}
|
2877
|
-
|
2878
|
-
|
2878
|
+
}));
|
2879
|
+
yield Promise.all(promises);
|
2880
|
+
if (pendingHashes.size > 0) {
|
2881
|
+
if (currentAttempt === maxAttempts) {
|
2882
|
+
throw new Error(
|
2883
|
+
`Transactions not found after max attempts: ${Array.from(pendingHashes).join(", ")}`
|
2884
|
+
);
|
2879
2885
|
}
|
2886
|
+
console.log(
|
2887
|
+
`Waiting for ${pendingHashes.size} transactions, retrying ${maxAttempts - currentAttempt} more times`
|
2888
|
+
);
|
2880
2889
|
yield delay(1e4);
|
2881
|
-
console.log(`RPC request failed for ${hash}, retrying ${maxAttempts - attempt} more times`);
|
2882
2890
|
}
|
2883
|
-
}
|
2884
|
-
|
2885
|
-
return results;
|
2891
|
+
}
|
2892
|
+
return hashes.map((hash) => results.get(hash));
|
2886
2893
|
});
|
2887
2894
|
}
|
2888
2895
|
|
@@ -3088,80 +3095,31 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
3088
3095
|
return __async(this, null, function* () {
|
3089
3096
|
const btcContext = window.btcContext;
|
3090
3097
|
const accountId = state.getAccount();
|
3091
|
-
const
|
3092
|
-
|
3093
|
-
const
|
3094
|
-
request_type: "view_access_key",
|
3095
|
-
account_id: accountId,
|
3096
|
-
public_key: publicKey,
|
3097
|
-
finality: "final"
|
3098
|
-
});
|
3099
|
-
const accessKey = __spreadProps(__spreadValues({}, rawAccessKey), {
|
3100
|
-
nonce: BigInt(rawAccessKey.nonce || 0)
|
3101
|
-
});
|
3102
|
-
const publicKeyFormat = import_key_pair.PublicKey.from(publicKey);
|
3103
|
-
const { result_data: nearNonceFromApi } = yield getNearNonceFromApi(
|
3104
|
-
currentConfig.base_url,
|
3105
|
-
accountId
|
3106
|
-
);
|
3107
|
-
const { transferGasTransaction, useNearPayGas } = yield getGasConfig();
|
3098
|
+
const trans = [...params.transactions];
|
3099
|
+
console.log("raw trans:", trans);
|
3100
|
+
const { transferGasTransaction, useNearPayGas, gasLimit } = yield calculateGasStrategy(trans);
|
3108
3101
|
console.log("transferGasTransaction:", transferGasTransaction);
|
3109
3102
|
console.log("useNearPayGas:", useNearPayGas);
|
3110
|
-
|
3111
|
-
|
3112
|
-
|
3113
|
-
|
3114
|
-
|
3115
|
-
|
3116
|
-
|
3117
|
-
nearNonceNumber = BigInt(nearNonceFromApi) > nearNonceNumber ? BigInt(nearNonceFromApi) : nearNonceNumber;
|
3118
|
-
}
|
3119
|
-
const newActions = transaction.actions.map((action) => {
|
3120
|
-
switch (action.type) {
|
3121
|
-
case "FunctionCall":
|
3122
|
-
return functionCall(
|
3123
|
-
action.params.methodName,
|
3124
|
-
action.params.args,
|
3125
|
-
BigInt(action.params.gas),
|
3126
|
-
BigInt(action.params.deposit)
|
3127
|
-
);
|
3128
|
-
case "Transfer":
|
3129
|
-
return transfer(BigInt(action.params.deposit));
|
3130
|
-
}
|
3131
|
-
}).filter(Boolean);
|
3132
|
-
const _transaction = import_near_api_js2.transactions.createTransaction(
|
3133
|
-
accountId,
|
3134
|
-
publicKeyFormat,
|
3135
|
-
transaction.receiverId,
|
3136
|
-
BigInt(nearNonceNumber) + BigInt(index),
|
3137
|
-
newActions,
|
3138
|
-
(0, import_utils5.baseDecode)(header.hash)
|
3139
|
-
);
|
3140
|
-
const txBytes = (0, import_transaction.encodeTransaction)(_transaction);
|
3141
|
-
const txHex = Array.from(
|
3142
|
-
txBytes,
|
3143
|
-
(byte) => ("0" + (byte & 255).toString(16)).slice(-2)
|
3144
|
-
).join("");
|
3145
|
-
console.log("txHex:", txHex);
|
3146
|
-
const hash = import_bs58.default.encode(new Uint8Array(import_js_sha256.sha256.array(txBytes)));
|
3147
|
-
return { txBytes, txHex, hash };
|
3148
|
-
});
|
3149
|
-
const accountInfo = yield nearCall2(
|
3150
|
-
currentConfig.accountContractId,
|
3151
|
-
"get_account",
|
3152
|
-
{ account_id: accountId }
|
3103
|
+
console.log("gasLimit:", gasLimit);
|
3104
|
+
if (transferGasTransaction) {
|
3105
|
+
trans.unshift(transferGasTransaction);
|
3106
|
+
}
|
3107
|
+
console.log("calculateGasStrategy trans:", trans);
|
3108
|
+
const newTrans = yield Promise.all(
|
3109
|
+
trans.map((transaction, index) => convertTransactionToTxHex(transaction, index))
|
3153
3110
|
);
|
3154
3111
|
const { result_data: nonceFromApi } = yield getNonceFromApi(
|
3155
3112
|
currentConfig.base_url,
|
3156
3113
|
accountId
|
3157
3114
|
);
|
3115
|
+
const accountInfo = yield getAccountInfo();
|
3158
3116
|
const nonce = Number(nonceFromApi) > Number(accountInfo.nonce) ? String(nonceFromApi) : String(accountInfo.nonce);
|
3159
3117
|
const intention = {
|
3160
3118
|
chain_id: "397",
|
3161
3119
|
csna: accountId,
|
3162
|
-
near_transactions:
|
3120
|
+
near_transactions: newTrans.map((t) => t.txHex),
|
3163
3121
|
gas_token: currentConfig.token,
|
3164
|
-
gas_limit:
|
3122
|
+
gas_limit: gasLimit,
|
3165
3123
|
use_near_pay_gas: useNearPayGas,
|
3166
3124
|
nonce
|
3167
3125
|
};
|
@@ -3173,7 +3131,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
3173
3131
|
data: toHex(strIntention)
|
3174
3132
|
});
|
3175
3133
|
if (result.result_code === 0) {
|
3176
|
-
const hash =
|
3134
|
+
const hash = newTrans.map((t) => t.hash);
|
3177
3135
|
console.log("txHash:", hash);
|
3178
3136
|
const result2 = yield pollTransactionStatuses(options.network.networkId, hash);
|
3179
3137
|
return result2;
|
@@ -3182,8 +3140,71 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
3182
3140
|
}
|
3183
3141
|
});
|
3184
3142
|
}
|
3185
|
-
function
|
3143
|
+
function getAccountInfo() {
|
3144
|
+
return __async(this, null, function* () {
|
3145
|
+
const accountId = state.getAccount();
|
3146
|
+
const accountInfo = yield nearCall2(
|
3147
|
+
currentConfig.accountContractId,
|
3148
|
+
"get_account",
|
3149
|
+
{ account_id: accountId }
|
3150
|
+
);
|
3151
|
+
return accountInfo;
|
3152
|
+
});
|
3153
|
+
}
|
3154
|
+
function createGasTokenTransfer(accountId, amount) {
|
3155
|
+
return __async(this, null, function* () {
|
3156
|
+
return {
|
3157
|
+
signerId: accountId,
|
3158
|
+
receiverId: currentConfig.token,
|
3159
|
+
actions: [
|
3160
|
+
{
|
3161
|
+
type: "FunctionCall",
|
3162
|
+
params: {
|
3163
|
+
methodName: "ft_transfer_call",
|
3164
|
+
args: {
|
3165
|
+
receiver_id: currentConfig.accountContractId,
|
3166
|
+
amount,
|
3167
|
+
msg: JSON.stringify("Deposit")
|
3168
|
+
},
|
3169
|
+
gas: new import_big.default(50).mul(__pow(10, 12)).toFixed(0),
|
3170
|
+
deposit: "1"
|
3171
|
+
}
|
3172
|
+
}
|
3173
|
+
]
|
3174
|
+
};
|
3175
|
+
});
|
3176
|
+
}
|
3177
|
+
function recalculateGasWithTransfer(transferTx, transactions2, useNearPayGas, perTxFee) {
|
3178
|
+
return __async(this, null, function* () {
|
3179
|
+
const { txHex: transferTxHex } = yield convertTransactionToTxHex(transferTx);
|
3180
|
+
let newGasLimit;
|
3181
|
+
if (useNearPayGas && perTxFee) {
|
3182
|
+
newGasLimit = new import_big.default(perTxFee).mul(transactions2.length + 1).toFixed(0);
|
3183
|
+
} else {
|
3184
|
+
newGasLimit = yield getPredictedGasAmount(
|
3185
|
+
currentConfig.accountContractId,
|
3186
|
+
currentConfig.token,
|
3187
|
+
[transferTxHex, ...transactions2.map((t) => t.txHex)]
|
3188
|
+
);
|
3189
|
+
}
|
3190
|
+
transferTx.actions[0].params.args.amount = newGasLimit;
|
3191
|
+
return { transferGasTransaction: transferTx, useNearPayGas, gasLimit: newGasLimit };
|
3192
|
+
});
|
3193
|
+
}
|
3194
|
+
function getPredictedGasAmount(accountContractId, tokenId, transactions2) {
|
3195
|
+
return __async(this, null, function* () {
|
3196
|
+
const predictedGas = yield nearCall2(accountContractId, "predict_txs_gas_token_amount", {
|
3197
|
+
gas_token_id: tokenId,
|
3198
|
+
near_transactions: transactions2
|
3199
|
+
});
|
3200
|
+
const predictedGasAmount = new import_big.default(predictedGas).mul(1.2).toFixed(0);
|
3201
|
+
console.log("predictedGas:", predictedGasAmount);
|
3202
|
+
return predictedGasAmount;
|
3203
|
+
});
|
3204
|
+
}
|
3205
|
+
function calculateGasStrategy(transactions2) {
|
3186
3206
|
return __async(this, null, function* () {
|
3207
|
+
var _a;
|
3187
3208
|
const accountId = state.getAccount();
|
3188
3209
|
const nearAccount = yield provider.query({
|
3189
3210
|
request_type: "view_account",
|
@@ -3191,39 +3212,107 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
3191
3212
|
finality: "final"
|
3192
3213
|
});
|
3193
3214
|
const availableBalance = parseFloat(nearAccount.amount) / __pow(10, 24);
|
3215
|
+
console.log("available near balance:", availableBalance);
|
3216
|
+
const accountInfo = yield getAccountInfo();
|
3217
|
+
const gasTokenBalance = accountInfo.gas_token[currentConfig.token] || "0";
|
3218
|
+
console.log("available gas token balance:", gasTokenBalance);
|
3219
|
+
const convertTx = yield Promise.all(
|
3220
|
+
transactions2.map((transaction, index) => convertTransactionToTxHex(transaction, index))
|
3221
|
+
);
|
3194
3222
|
if (availableBalance > 0.2) {
|
3195
|
-
|
3223
|
+
const gasTokens = yield nearCall2(
|
3224
|
+
currentConfig.accountContractId,
|
3225
|
+
"list_gas_token",
|
3226
|
+
{ token_ids: [currentConfig.token] }
|
3227
|
+
);
|
3228
|
+
console.log("list_gas_token gas tokens:", gasTokens);
|
3229
|
+
const perTxFee = Math.max(
|
3230
|
+
Number(((_a = gasTokens[currentConfig.token]) == null ? void 0 : _a.per_tx_protocol_fee) || 0),
|
3231
|
+
100
|
3232
|
+
);
|
3233
|
+
console.log("perTxFee:", perTxFee);
|
3234
|
+
const protocolFee = new import_big.default(perTxFee || "0").mul(convertTx.length).toFixed(0);
|
3235
|
+
console.log("protocolFee:", protocolFee);
|
3236
|
+
if (new import_big.default(gasTokenBalance).gte(protocolFee)) {
|
3237
|
+
console.log("use near pay gas and enough gas token balance");
|
3238
|
+
return { useNearPayGas: true, gasLimit: protocolFee };
|
3239
|
+
} else {
|
3240
|
+
console.log("use near pay gas and not enough gas token balance");
|
3241
|
+
const transferTx = yield createGasTokenTransfer(accountId, protocolFee);
|
3242
|
+
return recalculateGasWithTransfer(transferTx, convertTx, true, perTxFee.toString());
|
3243
|
+
}
|
3196
3244
|
} else {
|
3197
|
-
|
3198
|
-
|
3199
|
-
|
3200
|
-
|
3201
|
-
|
3202
|
-
|
3203
|
-
|
3204
|
-
|
3205
|
-
|
3206
|
-
type: "FunctionCall",
|
3207
|
-
params: {
|
3208
|
-
methodName: "ft_transfer_call",
|
3209
|
-
args: {
|
3210
|
-
receiver_id: currentConfig.accountContractId,
|
3211
|
-
amount: currentConfig.gasTokenLimit,
|
3212
|
-
msg: "Deposit"
|
3213
|
-
},
|
3214
|
-
gas: new import_big.default(50).mul(__pow(10, 12)).toFixed(0),
|
3215
|
-
deposit: "1"
|
3216
|
-
}
|
3217
|
-
}
|
3218
|
-
]
|
3219
|
-
};
|
3220
|
-
return { transferGasTransaction, useNearPayGas: false };
|
3245
|
+
console.log("near balance is not enough, predict the gas token amount required");
|
3246
|
+
const adjustedGas = yield getPredictedGasAmount(
|
3247
|
+
currentConfig.accountContractId,
|
3248
|
+
currentConfig.token,
|
3249
|
+
convertTx.map((t) => t.txHex)
|
3250
|
+
);
|
3251
|
+
if (new import_big.default(gasTokenBalance).gte(adjustedGas)) {
|
3252
|
+
console.log("use gas token and gas token balance is enough");
|
3253
|
+
return { useNearPayGas: false, gasLimit: adjustedGas };
|
3221
3254
|
} else {
|
3222
|
-
|
3255
|
+
console.log("use gas token and gas token balance is not enough, need to transfer");
|
3256
|
+
const transferTx = yield createGasTokenTransfer(accountId, adjustedGas);
|
3257
|
+
return recalculateGasWithTransfer(transferTx, convertTx, false);
|
3223
3258
|
}
|
3224
3259
|
}
|
3225
3260
|
});
|
3226
3261
|
}
|
3262
|
+
function convertTransactionToTxHex(transaction, index = 0) {
|
3263
|
+
return __async(this, null, function* () {
|
3264
|
+
const accountId = state.getAccount();
|
3265
|
+
const publicKey = state.getPublicKey();
|
3266
|
+
const publicKeyFormat = import_key_pair.PublicKey.from(publicKey);
|
3267
|
+
const { header } = yield provider.block({
|
3268
|
+
finality: "final"
|
3269
|
+
});
|
3270
|
+
const rawAccessKey = yield provider.query({
|
3271
|
+
request_type: "view_access_key",
|
3272
|
+
account_id: accountId,
|
3273
|
+
public_key: publicKey,
|
3274
|
+
finality: "final"
|
3275
|
+
});
|
3276
|
+
const accessKey = __spreadProps(__spreadValues({}, rawAccessKey), {
|
3277
|
+
nonce: BigInt(rawAccessKey.nonce || 0)
|
3278
|
+
});
|
3279
|
+
const { result_data: nearNonceFromApi } = yield getNearNonceFromApi(
|
3280
|
+
currentConfig.base_url,
|
3281
|
+
accountId
|
3282
|
+
);
|
3283
|
+
let nearNonceNumber = accessKey.nonce + BigInt(1);
|
3284
|
+
if (nearNonceFromApi) {
|
3285
|
+
nearNonceNumber = BigInt(nearNonceFromApi) > nearNonceNumber ? BigInt(nearNonceFromApi) : nearNonceNumber;
|
3286
|
+
}
|
3287
|
+
const newActions = transaction.actions.map((action) => {
|
3288
|
+
switch (action.type) {
|
3289
|
+
case "FunctionCall":
|
3290
|
+
return functionCall(
|
3291
|
+
action.params.methodName,
|
3292
|
+
action.params.args,
|
3293
|
+
BigInt(action.params.gas),
|
3294
|
+
BigInt(action.params.deposit)
|
3295
|
+
);
|
3296
|
+
case "Transfer":
|
3297
|
+
return transfer(BigInt(action.params.deposit));
|
3298
|
+
}
|
3299
|
+
}).filter(Boolean);
|
3300
|
+
const _transaction = import_near_api_js2.transactions.createTransaction(
|
3301
|
+
accountId,
|
3302
|
+
publicKeyFormat,
|
3303
|
+
transaction.receiverId,
|
3304
|
+
BigInt(nearNonceNumber) + BigInt(index),
|
3305
|
+
newActions,
|
3306
|
+
(0, import_utils5.baseDecode)(header.hash)
|
3307
|
+
);
|
3308
|
+
const txBytes = (0, import_transaction.encodeTransaction)(_transaction);
|
3309
|
+
const txHex = Array.from(txBytes, (byte) => ("0" + (byte & 255).toString(16)).slice(-2)).join(
|
3310
|
+
""
|
3311
|
+
);
|
3312
|
+
const hash = import_bs58.default.encode(new Uint8Array(import_js_sha256.sha256.array(txBytes)));
|
3313
|
+
return { txBytes, txHex, hash };
|
3314
|
+
});
|
3315
|
+
}
|
3227
3316
|
function initWalletButton(network, wallet2) {
|
3228
3317
|
return __async(this, null, function* () {
|
3229
3318
|
const checkAndSetupWalletButton = () => {
|
@@ -3256,6 +3345,14 @@ function uploadBTCTx(url, data) {
|
|
3256
3345
|
body: data
|
3257
3346
|
});
|
3258
3347
|
}
|
3348
|
+
function toHex(originalString) {
|
3349
|
+
const charArray = originalString.split("");
|
3350
|
+
const asciiArray = charArray.map((char) => char.charCodeAt(0));
|
3351
|
+
const hexArray = asciiArray.map((code) => code.toString(16));
|
3352
|
+
let hexString = hexArray.join("");
|
3353
|
+
hexString = hexString.replace(/(^0+)/g, "");
|
3354
|
+
return hexString;
|
3355
|
+
}
|
3259
3356
|
function setupBTCWallet({
|
3260
3357
|
iconUrl = "https://assets.deltatrade.ai/assets/chain/btc.svg",
|
3261
3358
|
deprecated = false,
|
@@ -3283,14 +3380,6 @@ function setupBTCWallet({
|
|
3283
3380
|
});
|
3284
3381
|
return btcWallet;
|
3285
3382
|
}
|
3286
|
-
function toHex(originalString) {
|
3287
|
-
const charArray = originalString.split("");
|
3288
|
-
const asciiArray = charArray.map((char) => char.charCodeAt(0));
|
3289
|
-
const hexArray = asciiArray.map((code) => code.toString(16));
|
3290
|
-
let hexString = hexArray.join("");
|
3291
|
-
hexString = hexString.replace(/(^0+)/g, "");
|
3292
|
-
return hexString;
|
3293
|
-
}
|
3294
3383
|
|
3295
3384
|
// src/core/btcUtils.ts
|
3296
3385
|
var import_big2 = __toESM(require("big.js"), 1);
|
@@ -3370,18 +3459,23 @@ function getBtcGasPrice() {
|
|
3370
3459
|
}
|
3371
3460
|
function getBtcBalance() {
|
3372
3461
|
return __async(this, null, function* () {
|
3373
|
-
const { account } = yield retryOperation(getBtcProvider, (
|
3462
|
+
const { account } = yield retryOperation(getBtcProvider, (res) => !!res.account);
|
3374
3463
|
if (!account) {
|
3375
3464
|
console.error("BTC Account is not available.");
|
3376
3465
|
return { rawBalance: 0, balance: 0, maxSpendableBalance: 0 };
|
3377
3466
|
}
|
3378
3467
|
const btcRpcUrl = yield getBtcRpcUrl();
|
3379
|
-
const
|
3380
|
-
const rawBalance =
|
3468
|
+
const utxos = yield fetch(`${btcRpcUrl}/address/${account}/utxo`).then((res) => res.json());
|
3469
|
+
const rawBalance = (utxos == null ? void 0 : utxos.reduce((acc, cur) => acc + cur.value, 0)) || 0;
|
3381
3470
|
const balance = rawBalance / __pow(10, 8);
|
3382
3471
|
const feeRate = yield getBtcGasPrice();
|
3383
|
-
const
|
3384
|
-
const
|
3472
|
+
const inputSize = ((utxos == null ? void 0 : utxos.length) || 0) * 66;
|
3473
|
+
const outputSize = 34;
|
3474
|
+
const overheadSize = 10;
|
3475
|
+
const estimatedTxSize = inputSize + outputSize + overheadSize;
|
3476
|
+
const estimatedFee = estimatedTxSize * feeRate / __pow(10, 8);
|
3477
|
+
console.log("estimated fee:", estimatedFee);
|
3478
|
+
const availableBalance = Math.max(0, balance - estimatedFee);
|
3385
3479
|
return {
|
3386
3480
|
rawBalance,
|
3387
3481
|
balance,
|
@@ -3508,7 +3602,7 @@ function executeBTCDepositAndAction(_0) {
|
|
3508
3602
|
|
3509
3603
|
// src/index.ts
|
3510
3604
|
var getVersion = () => {
|
3511
|
-
return "0.3.
|
3605
|
+
return "0.3.11";
|
3512
3606
|
};
|
3513
3607
|
if (typeof window !== "undefined") {
|
3514
3608
|
window.__PARTICLE_BTC_CONNECT_VERSION = getVersion();
|