btc-wallet 0.5.11-beta → 0.5.13-beta

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.js CHANGED
@@ -102,7 +102,7 @@ __export(src_exports, {
102
102
  getConfig: () => getConfig,
103
103
  getCsnaAccountId: () => getCsnaAccountId,
104
104
  getDepositAmount: () => getDepositAmount,
105
- getNBTCBalance: () => getNBTCBalance,
105
+ getTokenBalance: () => getTokenBalance,
106
106
  getVersion: () => getVersion,
107
107
  getWithdrawTransaction: () => getWithdrawTransaction,
108
108
  sendBitcoin: () => sendBitcoin,
@@ -432,11 +432,11 @@ var MobileWalletConnect = class {
432
432
  }
433
433
  static redirectToWallet(walletId) {
434
434
  return __async(this, null, function* () {
435
- var _a;
436
435
  if (isMobile()) {
437
436
  const currentUrl = window.location.href;
438
437
  const universalLink = this.getUniversalLink(walletId, currentUrl);
439
- if (!universalLink) {
438
+ const showGuideDialog = () => __async(this, null, function* () {
439
+ var _a;
440
440
  try {
441
441
  yield (_a = navigator.clipboard) == null ? void 0 : _a.writeText(currentUrl);
442
442
  } catch (error) {
@@ -454,9 +454,23 @@ var MobileWalletConnect = class {
454
454
  `,
455
455
  dangerouslyUseHTML: true
456
456
  });
457
+ });
458
+ if (!universalLink) {
459
+ yield showGuideDialog();
457
460
  return false;
458
461
  }
462
+ const openWallet = () => {
463
+ const iframe = document.createElement("iframe");
464
+ iframe.style.display = "none";
465
+ iframe.src = universalLink;
466
+ document.body.appendChild(iframe);
467
+ setTimeout(() => __async(this, null, function* () {
468
+ document.body.removeChild(iframe);
469
+ yield showGuideDialog();
470
+ }), 2e3);
471
+ };
459
472
  window.location.href = universalLink;
473
+ setTimeout(openWallet, 100);
460
474
  return true;
461
475
  }
462
476
  return false;
@@ -2870,7 +2884,10 @@ var import_js_sha256 = require("js-sha256");
2870
2884
  var walletConfig = {
2871
2885
  dev: {
2872
2886
  base_url: "https://api.dev.satoshibridge.top",
2873
- token: "nbtc-dev.testnet",
2887
+ btcToken: "nbtc-dev.testnet",
2888
+ btcTokenDecimals: 8,
2889
+ nearToken: "wrap.testnet",
2890
+ nearTokenDecimals: 24,
2874
2891
  accountContractId: "acc-dev.testnet",
2875
2892
  bridgeContractId: "brg-dev.testnet",
2876
2893
  walletUrl: "https://wallet-dev.satoshibridge.top",
@@ -2878,7 +2895,10 @@ var walletConfig = {
2878
2895
  },
2879
2896
  testnet: {
2880
2897
  base_url: "https://api.testnet.satoshibridge.top",
2881
- token: "nbtc2-nsp.testnet",
2898
+ btcToken: "nbtc2-nsp.testnet",
2899
+ btcTokenDecimals: 8,
2900
+ nearToken: "wrap.testnet",
2901
+ nearTokenDecimals: 24,
2882
2902
  accountContractId: "acc2-nsp.testnet",
2883
2903
  bridgeContractId: "brg2-nsp.testnet",
2884
2904
  walletUrl: "https://wallet-test.satoshibridge.top",
@@ -2886,7 +2906,10 @@ var walletConfig = {
2886
2906
  },
2887
2907
  private_mainnet: {
2888
2908
  base_url: "https://api.stg.satoshibridge.top",
2889
- token: "nbtc.toalice.near",
2909
+ btcToken: "nbtc.toalice.near",
2910
+ btcTokenDecimals: 8,
2911
+ nearToken: "wrap.near",
2912
+ nearTokenDecimals: 24,
2890
2913
  accountContractId: "acc.toalice.near",
2891
2914
  bridgeContractId: "brg.toalice.near",
2892
2915
  walletUrl: "https://wallet-stg.satoshibridge.top",
@@ -2894,7 +2917,10 @@ var walletConfig = {
2894
2917
  },
2895
2918
  mainnet: {
2896
2919
  base_url: "https://api.satos.network",
2897
- token: "nbtc.bridge.near",
2920
+ btcToken: "nbtc.bridge.near",
2921
+ btcTokenDecimals: 8,
2922
+ nearToken: "wrap.near",
2923
+ nearTokenDecimals: 24,
2898
2924
  accountContractId: "acc.ref-labs.near",
2899
2925
  bridgeContractId: "btc-connector.bridge.near",
2900
2926
  walletUrl: "https://wallet.satoshibridge.top",
@@ -2920,69 +2946,24 @@ var import_big = __toESM(require("big.js"), 1);
2920
2946
 
2921
2947
  // src/utils/nearUtils.ts
2922
2948
  var import_near_api_js = require("near-api-js");
2923
- function nearCallFunction(contractId, methodName, args, options) {
2924
- return __async(this, null, function* () {
2925
- const nearProvider = (options == null ? void 0 : options.provider) || new import_near_api_js.providers.FailoverRpcProvider(
2926
- nearRpcUrls[options == null ? void 0 : options.network].map(
2927
- (url) => new import_near_api_js.providers.JsonRpcProvider({ url })
2928
- )
2929
- );
2930
- const res = yield nearProvider.query({
2931
- request_type: "call_function",
2932
- account_id: contractId,
2933
- method_name: methodName,
2934
- args_base64: Buffer.from(JSON.stringify(args)).toString("base64"),
2935
- finality: "final"
2936
- });
2937
- return JSON.parse(Buffer.from(res.result).toString());
2938
- });
2939
- }
2940
- function pollTransactionStatuses(network, hashes) {
2941
- return __async(this, null, function* () {
2942
- const provider = new import_near_api_js.providers.FailoverRpcProvider(
2943
- Object.values(nearRpcUrls[network]).map(
2944
- (url) => new import_near_api_js.providers.JsonRpcProvider({ url })
2945
- )
2946
- );
2947
- const maxAttempts = 30;
2948
- let currentAttempt = 0;
2949
- const pendingHashes = new Set(hashes);
2950
- const results = /* @__PURE__ */ new Map();
2951
- while (pendingHashes.size > 0 && currentAttempt < maxAttempts) {
2952
- currentAttempt++;
2953
- const promises = Array.from(pendingHashes).map((hash) => __async(this, null, function* () {
2954
- try {
2955
- const result2 = yield provider.txStatus(hash, "unused", "FINAL");
2956
- if (result2 && result2.status) {
2957
- console.log(`Transaction ${hash} result:`, result2);
2958
- results.set(hash, result2);
2959
- pendingHashes.delete(hash);
2960
- }
2961
- } catch (error) {
2962
- console.error(`Failed to fetch transaction status for ${hash}: ${error.message}`);
2963
- }
2964
- }));
2965
- yield Promise.all(promises);
2966
- if (pendingHashes.size > 0) {
2967
- if (currentAttempt === maxAttempts) {
2968
- throw new Error(
2969
- `Transactions not found after max attempts: ${Array.from(pendingHashes).join(", ")}`
2970
- );
2971
- }
2972
- console.log(
2973
- `Waiting for ${pendingHashes.size} transactions, retrying ${maxAttempts - currentAttempt} more times`
2974
- );
2975
- yield delay(1e4);
2976
- }
2977
- }
2978
- const result = hashes.map((hash) => results.get(hash)).filter(Boolean);
2979
- return result;
2980
- });
2981
- }
2982
2949
 
2983
2950
  // src/utils/request.ts
2984
2951
  var cache = /* @__PURE__ */ new Map();
2985
2952
  var defaultCacheTimeout = 3e3;
2953
+ function withCache(key, fetcher, timeout = defaultCacheTimeout) {
2954
+ const cached = cache.get(key);
2955
+ const isCacheValid = cached && Date.now() - cached.timestamp < timeout;
2956
+ if (isCacheValid) {
2957
+ return Promise.resolve(cached.data);
2958
+ }
2959
+ return fetcher().then((data) => {
2960
+ cache.set(key, { timestamp: Date.now(), data });
2961
+ setTimeout(() => {
2962
+ cache.delete(key);
2963
+ }, timeout);
2964
+ return data;
2965
+ });
2966
+ }
2986
2967
  function request(url, options) {
2987
2968
  return __async(this, null, function* () {
2988
2969
  var _a;
@@ -3024,13 +3005,7 @@ function request(url, options) {
3024
3005
  if (options.shouldStopPolling(data)) {
3025
3006
  return data;
3026
3007
  }
3027
- if (options.maxPollingAttempts && options.maxPollingAttempts > 0) {
3028
- yield new Promise((resolve) => setTimeout(resolve, options.pollingInterval));
3029
- return request(url, __spreadProps(__spreadValues({}, options), {
3030
- maxPollingAttempts: options.maxPollingAttempts - 1
3031
- }));
3032
- }
3033
- throw new Error("Polling failed: maximum attempts reached without meeting the condition");
3008
+ throw new Error("Polling should continue");
3034
3009
  }
3035
3010
  if (cacheKey) {
3036
3011
  cache.set(cacheKey, { timestamp: Date.now(), data });
@@ -3040,6 +3015,7 @@ function request(url, options) {
3040
3015
  }
3041
3016
  return data;
3042
3017
  } catch (err) {
3018
+ console.error(err);
3043
3019
  if (retryCount > 0) {
3044
3020
  console.log(`Retrying... attempts left: ${retryCount}`);
3045
3021
  return request(url, __spreadProps(__spreadValues({}, options), { retryCount: retryCount - 1 }));
@@ -3053,8 +3029,85 @@ function request(url, options) {
3053
3029
  }));
3054
3030
  }
3055
3031
  }
3056
- throw err;
3032
+ return Promise.reject(err);
3033
+ }
3034
+ });
3035
+ }
3036
+
3037
+ // src/utils/nearUtils.ts
3038
+ function getNearProvider(option) {
3039
+ return option.provider || new import_near_api_js.providers.FailoverRpcProvider(
3040
+ nearRpcUrls[option == null ? void 0 : option.network].map(
3041
+ (url) => new import_near_api_js.providers.JsonRpcProvider({ url })
3042
+ )
3043
+ );
3044
+ }
3045
+ function nearCallFunction(_0, _1, _2) {
3046
+ return __async(this, arguments, function* (contractId, methodName, args, options = {}) {
3047
+ if (!options.skipCache) {
3048
+ const cacheKey = `near:${contractId}:${methodName}:${args ? JSON.stringify(args) : ""}`;
3049
+ return withCache(
3050
+ cacheKey,
3051
+ () => executeNearCall(contractId, methodName, args, options),
3052
+ options.cacheTimeout
3053
+ );
3054
+ }
3055
+ return executeNearCall(contractId, methodName, args, options);
3056
+ });
3057
+ }
3058
+ function executeNearCall(contractId, methodName, args, options) {
3059
+ return __async(this, null, function* () {
3060
+ const nearProvider = getNearProvider(options);
3061
+ const res = yield nearProvider.query({
3062
+ request_type: "call_function",
3063
+ account_id: contractId,
3064
+ method_name: methodName,
3065
+ args_base64: Buffer.from(JSON.stringify(args)).toString("base64"),
3066
+ finality: "final"
3067
+ });
3068
+ return JSON.parse(Buffer.from(res.result).toString());
3069
+ });
3070
+ }
3071
+ function pollTransactionStatuses(network, hashes) {
3072
+ return __async(this, null, function* () {
3073
+ const provider = new import_near_api_js.providers.FailoverRpcProvider(
3074
+ Object.values(nearRpcUrls[network]).map(
3075
+ (url) => new import_near_api_js.providers.JsonRpcProvider({ url })
3076
+ )
3077
+ );
3078
+ const maxAttempts = 30;
3079
+ let currentAttempt = 0;
3080
+ const pendingHashes = new Set(hashes);
3081
+ const results = /* @__PURE__ */ new Map();
3082
+ while (pendingHashes.size > 0 && currentAttempt < maxAttempts) {
3083
+ currentAttempt++;
3084
+ const promises = Array.from(pendingHashes).map((hash) => __async(this, null, function* () {
3085
+ try {
3086
+ const result2 = yield provider.txStatus(hash, "unused", "FINAL");
3087
+ if (result2 && result2.status) {
3088
+ console.log(`Transaction ${hash} result:`, result2);
3089
+ results.set(hash, result2);
3090
+ pendingHashes.delete(hash);
3091
+ }
3092
+ } catch (error) {
3093
+ console.error(`Failed to fetch transaction status for ${hash}: ${error.message}`);
3094
+ }
3095
+ }));
3096
+ yield Promise.all(promises);
3097
+ if (pendingHashes.size > 0) {
3098
+ if (currentAttempt === maxAttempts) {
3099
+ throw new Error(
3100
+ `Transactions not found after max attempts: ${Array.from(pendingHashes).join(", ")}`
3101
+ );
3102
+ }
3103
+ console.log(
3104
+ `Waiting for ${pendingHashes.size} transactions, retrying ${maxAttempts - currentAttempt} more times`
3105
+ );
3106
+ yield delay(1e4);
3107
+ }
3057
3108
  }
3109
+ const result = hashes.map((hash) => results.get(hash)).filter(Boolean);
3110
+ return result;
3058
3111
  });
3059
3112
  }
3060
3113
 
@@ -3211,9 +3264,10 @@ function nearCall(contractId, methodName, args) {
3211
3264
  return nearCallFunction(contractId, methodName, args, { network });
3212
3265
  });
3213
3266
  }
3214
- function getAccountInfo(csna, accountContractId) {
3215
- return __async(this, null, function* () {
3216
- const accountInfo = yield nearCall(accountContractId, "get_account", {
3267
+ function getAccountInfo(_0) {
3268
+ return __async(this, arguments, function* ({ csna, env }) {
3269
+ const config = yield getConfig(env);
3270
+ const accountInfo = yield nearCall(config.accountContractId, "get_account", {
3217
3271
  account_id: csna
3218
3272
  }).catch((error) => {
3219
3273
  return void 0;
@@ -3222,16 +3276,46 @@ function getAccountInfo(csna, accountContractId) {
3222
3276
  return accountInfo;
3223
3277
  });
3224
3278
  }
3225
- function checkGasTokenBalance(csna, gasToken, minAmount, env) {
3279
+ function getTokenBalance(_0) {
3280
+ return __async(this, arguments, function* ({
3281
+ csna,
3282
+ tokenId,
3283
+ env
3284
+ }) {
3285
+ const network = yield getNetwork();
3286
+ const config = yield getConfig(env);
3287
+ const nearProvider = getNearProvider({ network });
3288
+ try {
3289
+ if (tokenId === config.nearToken) {
3290
+ const nearAccount = yield nearProvider.query({
3291
+ request_type: "view_account",
3292
+ account_id: csna,
3293
+ finality: "final"
3294
+ });
3295
+ const balance = parseFloat(nearAccount.amount) / __pow(10, config.nearTokenDecimals);
3296
+ return { balance, rawBalance: nearAccount.amount };
3297
+ } else {
3298
+ const res = yield nearCall(tokenId, "ft_balance_of", { account_id: csna });
3299
+ const decimals = tokenId === config.btcToken ? config.btcTokenDecimals : (yield nearCall(tokenId, "ft_metadata", {})).decimals;
3300
+ const balance = parseFloat(res) / __pow(10, decimals);
3301
+ return { balance, rawBalance: res };
3302
+ }
3303
+ } catch (error) {
3304
+ console.error("getTokenBalance error:", error);
3305
+ return { balance: 0, rawBalance: "0" };
3306
+ }
3307
+ });
3308
+ }
3309
+ function checkGasTokenBalance(csna, minAmount, env) {
3226
3310
  return __async(this, null, function* () {
3227
- const amount = yield nearCall(gasToken, "ft_balance_of", { account_id: csna });
3228
- console.log("gas token balance:", amount);
3229
- if (new import_big.default(amount).lt(minAmount)) {
3311
+ const config = yield getConfig(env);
3312
+ const { rawBalance } = yield getTokenBalance({ csna, tokenId: config.btcToken, env });
3313
+ console.log("gas token balance:", rawBalance);
3314
+ if (new import_big.default(rawBalance).lt(minAmount)) {
3230
3315
  yield Dialog.confirm({
3231
3316
  title: "Gas token balance is insufficient",
3232
3317
  message: "Please deposit gas token to continue, will open bridge website."
3233
3318
  });
3234
- const config = yield getConfig(env);
3235
3319
  window.open(config.bridgeUrl, "_blank");
3236
3320
  throw new Error("Gas token balance is insufficient");
3237
3321
  }
@@ -3312,18 +3396,6 @@ function getBtcBalance() {
3312
3396
  };
3313
3397
  });
3314
3398
  }
3315
- function getNBTCBalance(address, env) {
3316
- return __async(this, null, function* () {
3317
- const config = yield getConfig(env || "mainnet");
3318
- const rawBalance = yield nearCall(config.token, "ft_balance_of", {
3319
- account_id: address
3320
- });
3321
- const balance = new import_big.default(rawBalance).div(__pow(10, 8)).round(8, import_big.default.roundDown).toNumber();
3322
- const rawAvailableBalance = new import_big.default(rawBalance).minus(1e3).toNumber();
3323
- const availableBalance = new import_big.default(rawAvailableBalance).div(__pow(10, 8)).round(8, import_big.default.roundDown).toNumber();
3324
- return { balance, availableBalance, rawBalance, rawAvailableBalance };
3325
- });
3326
- }
3327
3399
  function sendBitcoin(address, amount, feeRate) {
3328
3400
  return __async(this, null, function* () {
3329
3401
  const { sendBitcoin: sendBitcoin2 } = getBtcProvider();
@@ -3343,7 +3415,7 @@ function getDepositAmount(amount, option) {
3343
3415
  const _newAccountMinDepositAmount = (_a = option == null ? void 0 : option.newAccountMinDepositAmount) != null ? _a : true;
3344
3416
  const config = yield getConfig(env);
3345
3417
  const csna = yield getCsnaAccountId(env);
3346
- const accountInfo = yield getAccountInfo(csna, config.accountContractId);
3418
+ const accountInfo = yield getAccountInfo({ csna, env });
3347
3419
  const debtAction = yield checkGasTokenDebt(accountInfo, env, false);
3348
3420
  const repayAmount = (debtAction == null ? void 0 : debtAction.amount) || 0;
3349
3421
  const {
@@ -3422,7 +3494,7 @@ function executeBTCDepositAndAction(_0) {
3422
3494
  env,
3423
3495
  newAccountMinDepositAmount
3424
3496
  });
3425
- const accountInfo = yield getAccountInfo(csna, config.accountContractId);
3497
+ const accountInfo = yield getAccountInfo({ csna, env });
3426
3498
  const newActions = [];
3427
3499
  const debtAction = yield checkGasTokenDebt(accountInfo, env, false);
3428
3500
  if (debtAction) {
@@ -3436,12 +3508,12 @@ function executeBTCDepositAndAction(_0) {
3436
3508
  }));
3437
3509
  }
3438
3510
  const storageDepositMsg = {};
3439
- const registerRes = yield nearCall((action == null ? void 0 : action.receiver_id) || config.token, "storage_balance_of", {
3511
+ const registerRes = yield nearCall((action == null ? void 0 : action.receiver_id) || config.btcToken, "storage_balance_of", {
3440
3512
  account_id: csna
3441
3513
  });
3442
3514
  if (!(registerRes == null ? void 0 : registerRes.available)) {
3443
3515
  storageDepositMsg.storage_deposit_msg = {
3444
- contract_id: (action == null ? void 0 : action.receiver_id) || config.token,
3516
+ contract_id: (action == null ? void 0 : action.receiver_id) || config.btcToken,
3445
3517
  deposit: registerDeposit || NEAR_STORAGE_DEPOSIT_AMOUNT,
3446
3518
  registration_only: true
3447
3519
  };
@@ -3536,7 +3608,7 @@ function getWithdrawTransaction(_0) {
3536
3608
  env = "mainnet"
3537
3609
  }) {
3538
3610
  const provider = getBtcProvider();
3539
- const btcAddress = yield provider.account;
3611
+ const btcAddress = provider.account;
3540
3612
  const config = yield getConfig(env);
3541
3613
  const brgConfig = yield nearCall(config.bridgeContractId, "get_config", {});
3542
3614
  if (brgConfig.min_withdraw_amount) {
@@ -3560,7 +3632,7 @@ function getWithdrawTransaction(_0) {
3560
3632
  };
3561
3633
  });
3562
3634
  const _feeRate = feeRate || (yield getBtcGasPrice());
3563
- const { inputs, outputs, fee } = (0, import_coinselect.default)(
3635
+ let { inputs, outputs, fee } = (0, import_coinselect.default)(
3564
3636
  utxos,
3565
3637
  [{ address: btcAddress, value: Number(amount) }],
3566
3638
  Math.ceil(_feeRate)
@@ -3569,32 +3641,61 @@ function getWithdrawTransaction(_0) {
3569
3641
  throw new Error("The network is busy, please try again later.");
3570
3642
  }
3571
3643
  const maxBtcFee = Number(brgConfig.max_btc_gas_fee);
3572
- const newFee = fee;
3573
- const withdrawChangeAddress = brgConfig.change_address;
3574
- if (newFee > maxBtcFee) {
3644
+ const transactionFee = fee;
3645
+ const changeAddress = brgConfig.change_address;
3646
+ if (transactionFee > maxBtcFee) {
3575
3647
  throw new Error("Gas exceeds maximum value");
3576
3648
  }
3577
- let userOutput, noUserOutput;
3649
+ let recipientOutput, changeOutput;
3578
3650
  for (let i = 0; i < outputs.length; i++) {
3579
3651
  const output = outputs[i];
3580
3652
  if (output.value.toString() === amount.toString()) {
3581
- userOutput = output;
3653
+ recipientOutput = output;
3582
3654
  } else {
3583
- noUserOutput = output;
3655
+ changeOutput = output;
3584
3656
  }
3585
3657
  if (!output.address) {
3586
- output.address = withdrawChangeAddress;
3658
+ output.address = changeAddress;
3587
3659
  }
3588
3660
  }
3589
- userOutput.value = new import_big.default(userOutput.value).minus(newFee).minus(withdrawFee).toNumber();
3590
- if (noUserOutput) {
3591
- noUserOutput.value = new import_big.default(noUserOutput.value).plus(newFee).plus(withdrawFee).toNumber();
3661
+ recipientOutput.value = new import_big.default(recipientOutput.value).minus(transactionFee).minus(withdrawFee).toNumber();
3662
+ if (changeOutput) {
3663
+ changeOutput.value = new import_big.default(changeOutput.value).plus(transactionFee).plus(withdrawFee).toNumber();
3664
+ const remainingInputs = [...inputs];
3665
+ let smallestInput = Math.min.apply(
3666
+ null,
3667
+ remainingInputs.map((input) => input.value)
3668
+ );
3669
+ let remainingChangeAmount = changeOutput.value;
3670
+ while (remainingChangeAmount >= smallestInput && smallestInput > 0 && remainingInputs.length > 0) {
3671
+ remainingChangeAmount -= smallestInput;
3672
+ changeOutput.value = remainingChangeAmount;
3673
+ const smallestInputIndex = remainingInputs.findIndex(
3674
+ (input) => input.value === smallestInput
3675
+ );
3676
+ if (smallestInputIndex > -1) {
3677
+ remainingInputs.splice(smallestInputIndex, 1);
3678
+ }
3679
+ smallestInput = Math.min.apply(
3680
+ null,
3681
+ remainingInputs.map((input) => input.value)
3682
+ );
3683
+ }
3684
+ const minChangeAmount = Number(brgConfig.min_change_amount);
3685
+ let additionalFee = 0;
3686
+ if (changeOutput.value === 0) {
3687
+ outputs = outputs.filter((item) => item.value !== 0);
3688
+ } else if (changeOutput.value < minChangeAmount) {
3689
+ additionalFee = minChangeAmount - changeOutput.value;
3690
+ recipientOutput.value -= additionalFee;
3691
+ changeOutput.value = minChangeAmount;
3692
+ }
3592
3693
  } else {
3593
- noUserOutput = {
3594
- address: withdrawChangeAddress,
3595
- value: new import_big.default(newFee).plus(withdrawFee).toNumber()
3694
+ changeOutput = {
3695
+ address: changeAddress,
3696
+ value: new import_big.default(transactionFee).plus(withdrawFee).toNumber()
3596
3697
  };
3597
- outputs.push(noUserOutput);
3698
+ outputs.push(changeOutput);
3598
3699
  }
3599
3700
  const insufficientOutput = outputs.some((item) => item.value < 0);
3600
3701
  if (insufficientOutput) {
@@ -3602,7 +3703,7 @@ function getWithdrawTransaction(_0) {
3602
3703
  }
3603
3704
  const inputSum = inputs.reduce((sum, cur) => sum + Number(cur.value), 0);
3604
3705
  const outputSum = outputs.reduce((sum, cur) => sum + Number(cur.value), 0);
3605
- if (newFee + outputSum !== inputSum) {
3706
+ if (transactionFee + outputSum !== inputSum) {
3606
3707
  throw new Error("compute error");
3607
3708
  }
3608
3709
  const network = yield getNetwork();
@@ -3647,7 +3748,7 @@ function getWithdrawTransaction(_0) {
3647
3748
  };
3648
3749
  const csna = yield getCsnaAccountId(env);
3649
3750
  const transaction = {
3650
- receiverId: config.token,
3751
+ receiverId: config.btcToken,
3651
3752
  signerId: csna,
3652
3753
  actions: [
3653
3754
  {
@@ -4191,20 +4292,16 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
4191
4292
  throw new Error("Wallet state is invalid, please reconnect your wallet.");
4192
4293
  }
4193
4294
  const btcContext = window.btcContext;
4194
- const accountId = state.getAccount();
4195
- const accountInfo = yield getAccountInfo(accountId, currentConfig.accountContractId);
4295
+ const csna = state.getAccount();
4296
+ const accountInfo = yield getAccountInfo({ csna, env });
4196
4297
  yield checkGasTokenDebt(accountInfo, env, true);
4197
4298
  const trans = [...params.transactions];
4198
4299
  console.log("signAndSendTransactions raw trans:", trans);
4199
- const gasTokenBalance = (accountInfo == null ? void 0 : accountInfo.gas_token[currentConfig.token]) || "0";
4200
- const { transferGasTransaction, useNearPayGas, gasLimit } = yield calculateGasStrategy(
4201
- gasTokenBalance,
4202
- trans
4203
- );
4300
+ const { transferGasTransaction, useNearPayGas, gasLimit } = yield calculateGasStrategy(trans);
4204
4301
  console.log("transferGasTransaction:", transferGasTransaction);
4205
4302
  console.log("useNearPayGas:", useNearPayGas);
4206
4303
  console.log("gasLimit:", gasLimit);
4207
- yield checkGasTokenBalance(accountId, currentConfig.token, gasLimit, env);
4304
+ yield checkGasTokenBalance(csna, gasLimit, env);
4208
4305
  if (transferGasTransaction) {
4209
4306
  trans.unshift(transferGasTransaction);
4210
4307
  }
@@ -4212,14 +4309,14 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
4212
4309
  const newTrans = yield Promise.all(
4213
4310
  trans.map((transaction, index) => convertTransactionToTxHex(transaction, index))
4214
4311
  );
4215
- const nonceFromApi = yield getNonce(currentConfig.base_url, accountId);
4312
+ const nonceFromApi = yield getNonce(currentConfig.base_url, csna);
4216
4313
  const nonceFromContract = (accountInfo == null ? void 0 : accountInfo.nonce) || 0;
4217
4314
  const nonce = Number(nonceFromApi) > Number(nonceFromContract) ? String(nonceFromApi) : String(nonceFromContract);
4218
4315
  const intention = {
4219
4316
  chain_id: "397",
4220
- csna: accountId,
4317
+ csna,
4221
4318
  near_transactions: newTrans.map((t) => t.txHex),
4222
- gas_token: currentConfig.token,
4319
+ gas_token: currentConfig.btcToken,
4223
4320
  gas_limit: gasLimit,
4224
4321
  use_near_pay_gas: useNearPayGas,
4225
4322
  nonce
@@ -4232,7 +4329,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
4232
4329
  data: toHex(strIntention)
4233
4330
  });
4234
4331
  yield checkBtcTransactionStatus(currentConfig.base_url, signature);
4235
- const hash = newTrans.map((t) => t.hash);
4332
+ const hash = newTrans.slice(1).map((t) => t.hash);
4236
4333
  console.log("txHash:", hash);
4237
4334
  const result = yield pollTransactionStatuses(options.network.networkId, hash);
4238
4335
  return result;
@@ -4240,12 +4337,9 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
4240
4337
  }
4241
4338
  function calculateGasLimit(params) {
4242
4339
  return __async(this, null, function* () {
4243
- const accountId = state.getAccount();
4244
- const accountInfo = yield getAccountInfo(accountId, currentConfig.accountContractId);
4245
4340
  const trans = [...params.transactions];
4246
4341
  console.log("raw trans:", trans);
4247
- const gasTokenBalance = (accountInfo == null ? void 0 : accountInfo.gas_token[currentConfig.token]) || "0";
4248
- const { gasLimit } = yield calculateGasStrategy(gasTokenBalance, trans);
4342
+ const { gasLimit } = yield calculateGasStrategy(trans);
4249
4343
  return gasLimit;
4250
4344
  });
4251
4345
  }
@@ -4253,7 +4347,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
4253
4347
  return __async(this, null, function* () {
4254
4348
  return {
4255
4349
  signerId: accountId,
4256
- receiverId: currentConfig.token,
4350
+ receiverId: currentConfig.btcToken,
4257
4351
  actions: [
4258
4352
  {
4259
4353
  type: "FunctionCall",
@@ -4281,7 +4375,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
4281
4375
  } else {
4282
4376
  newGasLimit = yield getPredictedGasAmount(
4283
4377
  currentConfig.accountContractId,
4284
- currentConfig.token,
4378
+ currentConfig.btcToken,
4285
4379
  [transferTxHex, ...transactions2.map((t) => t.txHex)]
4286
4380
  );
4287
4381
  }
@@ -4302,31 +4396,61 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
4302
4396
  return gasAmount.toString();
4303
4397
  });
4304
4398
  }
4305
- function calculateGasStrategy(gasTokenBalance, transactions2) {
4399
+ function calculateGasStrategy(transactions2) {
4306
4400
  return __async(this, null, function* () {
4307
4401
  var _a;
4308
4402
  const accountId = state.getAccount();
4309
- const nearAccount = yield provider.query({
4310
- request_type: "view_account",
4311
- account_id: accountId,
4312
- finality: "final"
4403
+ const accountInfo = yield getAccountInfo({ csna: accountId, env });
4404
+ const gasTokenBalance = (accountInfo == null ? void 0 : accountInfo.gas_token[currentConfig.btcToken]) || "0";
4405
+ const { balance: nearBalance } = yield getTokenBalance({
4406
+ csna: accountId,
4407
+ tokenId: currentConfig.nearToken,
4408
+ env
4313
4409
  });
4314
- const availableBalance = parseFloat(nearAccount.amount) / __pow(10, 24);
4315
- console.log("available near balance:", availableBalance);
4410
+ const { balance: btcBalance } = yield getTokenBalance({
4411
+ csna: accountId,
4412
+ tokenId: currentConfig.btcToken,
4413
+ env
4414
+ });
4415
+ const transferAmount = transactions2.reduce(
4416
+ (acc, tx) => {
4417
+ tx.actions.forEach((action) => {
4418
+ if (action.params.deposit) {
4419
+ const amount = Number(action.params.deposit) / __pow(10, currentConfig.nearTokenDecimals);
4420
+ console.log("near deposit amount:", amount);
4421
+ acc.near = acc.near.plus(amount);
4422
+ }
4423
+ if (tx.receiverId === currentConfig.btcToken && ["ft_transfer_call", "ft_transfer"].includes(action.params.methodName)) {
4424
+ const amount = Number(action.params.args.amount) / __pow(10, currentConfig.btcTokenDecimals);
4425
+ console.log("btc transfer amount:", amount);
4426
+ acc.btc = acc.btc.plus(amount);
4427
+ }
4428
+ });
4429
+ return acc;
4430
+ },
4431
+ { near: new import_big2.default(0), btc: new import_big2.default(0) }
4432
+ );
4433
+ const nearAvailableBalance = new import_big2.default(nearBalance).minus(transferAmount.near).toNumber();
4434
+ const btcAvailableBalance = new import_big2.default(btcBalance).minus(transferAmount.btc).toNumber();
4435
+ if (btcAvailableBalance < 8e-6) {
4436
+ throw new Error("BTC balance is not enough, please deposit more BTC.");
4437
+ }
4438
+ console.log("available near balance:", nearAvailableBalance);
4439
+ console.log("available btc balance:", btcAvailableBalance);
4316
4440
  console.log("available gas token balance:", gasTokenBalance);
4317
4441
  const convertTx = yield Promise.all(
4318
4442
  transactions2.map((transaction, index) => convertTransactionToTxHex(transaction, index))
4319
4443
  );
4320
- if (availableBalance > 0.5) {
4444
+ if (nearAvailableBalance > 0.5) {
4321
4445
  console.log("near balance is enough, get the protocol fee of each transaction");
4322
4446
  const gasTokens = yield nearCall2(
4323
4447
  currentConfig.accountContractId,
4324
4448
  "list_gas_token",
4325
- { token_ids: [currentConfig.token] }
4449
+ { token_ids: [currentConfig.btcToken] }
4326
4450
  );
4327
4451
  console.log("list_gas_token gas tokens:", gasTokens);
4328
4452
  const perTxFee = Math.max(
4329
- Number(((_a = gasTokens[currentConfig.token]) == null ? void 0 : _a.per_tx_protocol_fee) || 0),
4453
+ Number(((_a = gasTokens[currentConfig.btcToken]) == null ? void 0 : _a.per_tx_protocol_fee) || 0),
4330
4454
  100
4331
4455
  );
4332
4456
  console.log("perTxFee:", perTxFee);
@@ -4344,7 +4468,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
4344
4468
  console.log("near balance is not enough, predict the gas token amount required");
4345
4469
  const adjustedGas = yield getPredictedGasAmount(
4346
4470
  currentConfig.accountContractId,
4347
- currentConfig.token,
4471
+ currentConfig.btcToken,
4348
4472
  convertTx.map((t) => t.txHex)
4349
4473
  );
4350
4474
  if (new import_big2.default(gasTokenBalance).gte(adjustedGas)) {
@@ -4460,7 +4584,7 @@ function setupBTCWallet({
4460
4584
 
4461
4585
  // src/index.ts
4462
4586
  var getVersion = () => {
4463
- return "0.5.11-beta";
4587
+ return "0.5.13-beta";
4464
4588
  };
4465
4589
  if (typeof window !== "undefined") {
4466
4590
  window.__BTC_WALLET_VERSION = getVersion();