btc-wallet 0.5.11-beta → 0.5.13-beta

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 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();