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/esm/index.js CHANGED
@@ -368,11 +368,11 @@ var MobileWalletConnect = class {
368
368
  }
369
369
  static redirectToWallet(walletId) {
370
370
  return __async(this, null, function* () {
371
- var _a;
372
371
  if (isMobile()) {
373
372
  const currentUrl = window.location.href;
374
373
  const universalLink = this.getUniversalLink(walletId, currentUrl);
375
- if (!universalLink) {
374
+ const showGuideDialog = () => __async(this, null, function* () {
375
+ var _a;
376
376
  try {
377
377
  yield (_a = navigator.clipboard) == null ? void 0 : _a.writeText(currentUrl);
378
378
  } catch (error) {
@@ -390,9 +390,23 @@ var MobileWalletConnect = class {
390
390
  `,
391
391
  dangerouslyUseHTML: true
392
392
  });
393
+ });
394
+ if (!universalLink) {
395
+ yield showGuideDialog();
393
396
  return false;
394
397
  }
398
+ const openWallet = () => {
399
+ const iframe = document.createElement("iframe");
400
+ iframe.style.display = "none";
401
+ iframe.src = universalLink;
402
+ document.body.appendChild(iframe);
403
+ setTimeout(() => __async(this, null, function* () {
404
+ document.body.removeChild(iframe);
405
+ yield showGuideDialog();
406
+ }), 2e3);
407
+ };
395
408
  window.location.href = universalLink;
409
+ setTimeout(openWallet, 100);
396
410
  return true;
397
411
  }
398
412
  return false;
@@ -2820,7 +2834,10 @@ import { sha256 } from "js-sha256";
2820
2834
  var walletConfig = {
2821
2835
  dev: {
2822
2836
  base_url: "https://api.dev.satoshibridge.top",
2823
- token: "nbtc-dev.testnet",
2837
+ btcToken: "nbtc-dev.testnet",
2838
+ btcTokenDecimals: 8,
2839
+ nearToken: "wrap.testnet",
2840
+ nearTokenDecimals: 24,
2824
2841
  accountContractId: "acc-dev.testnet",
2825
2842
  bridgeContractId: "brg-dev.testnet",
2826
2843
  walletUrl: "https://wallet-dev.satoshibridge.top",
@@ -2828,7 +2845,10 @@ var walletConfig = {
2828
2845
  },
2829
2846
  testnet: {
2830
2847
  base_url: "https://api.testnet.satoshibridge.top",
2831
- token: "nbtc2-nsp.testnet",
2848
+ btcToken: "nbtc2-nsp.testnet",
2849
+ btcTokenDecimals: 8,
2850
+ nearToken: "wrap.testnet",
2851
+ nearTokenDecimals: 24,
2832
2852
  accountContractId: "acc2-nsp.testnet",
2833
2853
  bridgeContractId: "brg2-nsp.testnet",
2834
2854
  walletUrl: "https://wallet-test.satoshibridge.top",
@@ -2836,7 +2856,10 @@ var walletConfig = {
2836
2856
  },
2837
2857
  private_mainnet: {
2838
2858
  base_url: "https://api.stg.satoshibridge.top",
2839
- token: "nbtc.toalice.near",
2859
+ btcToken: "nbtc.toalice.near",
2860
+ btcTokenDecimals: 8,
2861
+ nearToken: "wrap.near",
2862
+ nearTokenDecimals: 24,
2840
2863
  accountContractId: "acc.toalice.near",
2841
2864
  bridgeContractId: "brg.toalice.near",
2842
2865
  walletUrl: "https://wallet-stg.satoshibridge.top",
@@ -2844,7 +2867,10 @@ var walletConfig = {
2844
2867
  },
2845
2868
  mainnet: {
2846
2869
  base_url: "https://api.satos.network",
2847
- token: "nbtc.bridge.near",
2870
+ btcToken: "nbtc.bridge.near",
2871
+ btcTokenDecimals: 8,
2872
+ nearToken: "wrap.near",
2873
+ nearTokenDecimals: 24,
2848
2874
  accountContractId: "acc.ref-labs.near",
2849
2875
  bridgeContractId: "btc-connector.bridge.near",
2850
2876
  walletUrl: "https://wallet.satoshibridge.top",
@@ -2870,69 +2896,24 @@ import Big from "big.js";
2870
2896
 
2871
2897
  // src/utils/nearUtils.ts
2872
2898
  import { providers } from "near-api-js";
2873
- function nearCallFunction(contractId, methodName, args, options) {
2874
- return __async(this, null, function* () {
2875
- const nearProvider = (options == null ? void 0 : options.provider) || new providers.FailoverRpcProvider(
2876
- nearRpcUrls[options == null ? void 0 : options.network].map(
2877
- (url) => new providers.JsonRpcProvider({ url })
2878
- )
2879
- );
2880
- const res = yield nearProvider.query({
2881
- request_type: "call_function",
2882
- account_id: contractId,
2883
- method_name: methodName,
2884
- args_base64: Buffer.from(JSON.stringify(args)).toString("base64"),
2885
- finality: "final"
2886
- });
2887
- return JSON.parse(Buffer.from(res.result).toString());
2888
- });
2889
- }
2890
- function pollTransactionStatuses(network, hashes) {
2891
- return __async(this, null, function* () {
2892
- const provider = new providers.FailoverRpcProvider(
2893
- Object.values(nearRpcUrls[network]).map(
2894
- (url) => new providers.JsonRpcProvider({ url })
2895
- )
2896
- );
2897
- const maxAttempts = 30;
2898
- let currentAttempt = 0;
2899
- const pendingHashes = new Set(hashes);
2900
- const results = /* @__PURE__ */ new Map();
2901
- while (pendingHashes.size > 0 && currentAttempt < maxAttempts) {
2902
- currentAttempt++;
2903
- const promises = Array.from(pendingHashes).map((hash) => __async(this, null, function* () {
2904
- try {
2905
- const result2 = yield provider.txStatus(hash, "unused", "FINAL");
2906
- if (result2 && result2.status) {
2907
- console.log(`Transaction ${hash} result:`, result2);
2908
- results.set(hash, result2);
2909
- pendingHashes.delete(hash);
2910
- }
2911
- } catch (error) {
2912
- console.error(`Failed to fetch transaction status for ${hash}: ${error.message}`);
2913
- }
2914
- }));
2915
- yield Promise.all(promises);
2916
- if (pendingHashes.size > 0) {
2917
- if (currentAttempt === maxAttempts) {
2918
- throw new Error(
2919
- `Transactions not found after max attempts: ${Array.from(pendingHashes).join(", ")}`
2920
- );
2921
- }
2922
- console.log(
2923
- `Waiting for ${pendingHashes.size} transactions, retrying ${maxAttempts - currentAttempt} more times`
2924
- );
2925
- yield delay(1e4);
2926
- }
2927
- }
2928
- const result = hashes.map((hash) => results.get(hash)).filter(Boolean);
2929
- return result;
2930
- });
2931
- }
2932
2899
 
2933
2900
  // src/utils/request.ts
2934
2901
  var cache = /* @__PURE__ */ new Map();
2935
2902
  var defaultCacheTimeout = 3e3;
2903
+ function withCache(key, fetcher, timeout = defaultCacheTimeout) {
2904
+ const cached = cache.get(key);
2905
+ const isCacheValid = cached && Date.now() - cached.timestamp < timeout;
2906
+ if (isCacheValid) {
2907
+ return Promise.resolve(cached.data);
2908
+ }
2909
+ return fetcher().then((data) => {
2910
+ cache.set(key, { timestamp: Date.now(), data });
2911
+ setTimeout(() => {
2912
+ cache.delete(key);
2913
+ }, timeout);
2914
+ return data;
2915
+ });
2916
+ }
2936
2917
  function request(url, options) {
2937
2918
  return __async(this, null, function* () {
2938
2919
  var _a;
@@ -2974,13 +2955,7 @@ function request(url, options) {
2974
2955
  if (options.shouldStopPolling(data)) {
2975
2956
  return data;
2976
2957
  }
2977
- if (options.maxPollingAttempts && options.maxPollingAttempts > 0) {
2978
- yield new Promise((resolve) => setTimeout(resolve, options.pollingInterval));
2979
- return request(url, __spreadProps(__spreadValues({}, options), {
2980
- maxPollingAttempts: options.maxPollingAttempts - 1
2981
- }));
2982
- }
2983
- throw new Error("Polling failed: maximum attempts reached without meeting the condition");
2958
+ throw new Error("Polling should continue");
2984
2959
  }
2985
2960
  if (cacheKey) {
2986
2961
  cache.set(cacheKey, { timestamp: Date.now(), data });
@@ -2990,6 +2965,7 @@ function request(url, options) {
2990
2965
  }
2991
2966
  return data;
2992
2967
  } catch (err) {
2968
+ console.error(err);
2993
2969
  if (retryCount > 0) {
2994
2970
  console.log(`Retrying... attempts left: ${retryCount}`);
2995
2971
  return request(url, __spreadProps(__spreadValues({}, options), { retryCount: retryCount - 1 }));
@@ -3003,8 +2979,85 @@ function request(url, options) {
3003
2979
  }));
3004
2980
  }
3005
2981
  }
3006
- throw err;
2982
+ return Promise.reject(err);
2983
+ }
2984
+ });
2985
+ }
2986
+
2987
+ // src/utils/nearUtils.ts
2988
+ function getNearProvider(option) {
2989
+ return option.provider || new providers.FailoverRpcProvider(
2990
+ nearRpcUrls[option == null ? void 0 : option.network].map(
2991
+ (url) => new providers.JsonRpcProvider({ url })
2992
+ )
2993
+ );
2994
+ }
2995
+ function nearCallFunction(_0, _1, _2) {
2996
+ return __async(this, arguments, function* (contractId, methodName, args, options = {}) {
2997
+ if (!options.skipCache) {
2998
+ const cacheKey = `near:${contractId}:${methodName}:${args ? JSON.stringify(args) : ""}`;
2999
+ return withCache(
3000
+ cacheKey,
3001
+ () => executeNearCall(contractId, methodName, args, options),
3002
+ options.cacheTimeout
3003
+ );
3004
+ }
3005
+ return executeNearCall(contractId, methodName, args, options);
3006
+ });
3007
+ }
3008
+ function executeNearCall(contractId, methodName, args, options) {
3009
+ return __async(this, null, function* () {
3010
+ const nearProvider = getNearProvider(options);
3011
+ const res = yield nearProvider.query({
3012
+ request_type: "call_function",
3013
+ account_id: contractId,
3014
+ method_name: methodName,
3015
+ args_base64: Buffer.from(JSON.stringify(args)).toString("base64"),
3016
+ finality: "final"
3017
+ });
3018
+ return JSON.parse(Buffer.from(res.result).toString());
3019
+ });
3020
+ }
3021
+ function pollTransactionStatuses(network, hashes) {
3022
+ return __async(this, null, function* () {
3023
+ const provider = new providers.FailoverRpcProvider(
3024
+ Object.values(nearRpcUrls[network]).map(
3025
+ (url) => new providers.JsonRpcProvider({ url })
3026
+ )
3027
+ );
3028
+ const maxAttempts = 30;
3029
+ let currentAttempt = 0;
3030
+ const pendingHashes = new Set(hashes);
3031
+ const results = /* @__PURE__ */ new Map();
3032
+ while (pendingHashes.size > 0 && currentAttempt < maxAttempts) {
3033
+ currentAttempt++;
3034
+ const promises = Array.from(pendingHashes).map((hash) => __async(this, null, function* () {
3035
+ try {
3036
+ const result2 = yield provider.txStatus(hash, "unused", "FINAL");
3037
+ if (result2 && result2.status) {
3038
+ console.log(`Transaction ${hash} result:`, result2);
3039
+ results.set(hash, result2);
3040
+ pendingHashes.delete(hash);
3041
+ }
3042
+ } catch (error) {
3043
+ console.error(`Failed to fetch transaction status for ${hash}: ${error.message}`);
3044
+ }
3045
+ }));
3046
+ yield Promise.all(promises);
3047
+ if (pendingHashes.size > 0) {
3048
+ if (currentAttempt === maxAttempts) {
3049
+ throw new Error(
3050
+ `Transactions not found after max attempts: ${Array.from(pendingHashes).join(", ")}`
3051
+ );
3052
+ }
3053
+ console.log(
3054
+ `Waiting for ${pendingHashes.size} transactions, retrying ${maxAttempts - currentAttempt} more times`
3055
+ );
3056
+ yield delay(1e4);
3057
+ }
3007
3058
  }
3059
+ const result = hashes.map((hash) => results.get(hash)).filter(Boolean);
3060
+ return result;
3008
3061
  });
3009
3062
  }
3010
3063
 
@@ -3161,9 +3214,10 @@ function nearCall(contractId, methodName, args) {
3161
3214
  return nearCallFunction(contractId, methodName, args, { network });
3162
3215
  });
3163
3216
  }
3164
- function getAccountInfo(csna, accountContractId) {
3165
- return __async(this, null, function* () {
3166
- const accountInfo = yield nearCall(accountContractId, "get_account", {
3217
+ function getAccountInfo(_0) {
3218
+ return __async(this, arguments, function* ({ csna, env }) {
3219
+ const config = yield getConfig(env);
3220
+ const accountInfo = yield nearCall(config.accountContractId, "get_account", {
3167
3221
  account_id: csna
3168
3222
  }).catch((error) => {
3169
3223
  return void 0;
@@ -3172,16 +3226,46 @@ function getAccountInfo(csna, accountContractId) {
3172
3226
  return accountInfo;
3173
3227
  });
3174
3228
  }
3175
- function checkGasTokenBalance(csna, gasToken, minAmount, env) {
3229
+ function getTokenBalance(_0) {
3230
+ return __async(this, arguments, function* ({
3231
+ csna,
3232
+ tokenId,
3233
+ env
3234
+ }) {
3235
+ const network = yield getNetwork();
3236
+ const config = yield getConfig(env);
3237
+ const nearProvider = getNearProvider({ network });
3238
+ try {
3239
+ if (tokenId === config.nearToken) {
3240
+ const nearAccount = yield nearProvider.query({
3241
+ request_type: "view_account",
3242
+ account_id: csna,
3243
+ finality: "final"
3244
+ });
3245
+ const balance = parseFloat(nearAccount.amount) / __pow(10, config.nearTokenDecimals);
3246
+ return { balance, rawBalance: nearAccount.amount };
3247
+ } else {
3248
+ const res = yield nearCall(tokenId, "ft_balance_of", { account_id: csna });
3249
+ const decimals = tokenId === config.btcToken ? config.btcTokenDecimals : (yield nearCall(tokenId, "ft_metadata", {})).decimals;
3250
+ const balance = parseFloat(res) / __pow(10, decimals);
3251
+ return { balance, rawBalance: res };
3252
+ }
3253
+ } catch (error) {
3254
+ console.error("getTokenBalance error:", error);
3255
+ return { balance: 0, rawBalance: "0" };
3256
+ }
3257
+ });
3258
+ }
3259
+ function checkGasTokenBalance(csna, minAmount, env) {
3176
3260
  return __async(this, null, function* () {
3177
- const amount = yield nearCall(gasToken, "ft_balance_of", { account_id: csna });
3178
- console.log("gas token balance:", amount);
3179
- if (new Big(amount).lt(minAmount)) {
3261
+ const config = yield getConfig(env);
3262
+ const { rawBalance } = yield getTokenBalance({ csna, tokenId: config.btcToken, env });
3263
+ console.log("gas token balance:", rawBalance);
3264
+ if (new Big(rawBalance).lt(minAmount)) {
3180
3265
  yield Dialog.confirm({
3181
3266
  title: "Gas token balance is insufficient",
3182
3267
  message: "Please deposit gas token to continue, will open bridge website."
3183
3268
  });
3184
- const config = yield getConfig(env);
3185
3269
  window.open(config.bridgeUrl, "_blank");
3186
3270
  throw new Error("Gas token balance is insufficient");
3187
3271
  }
@@ -3262,18 +3346,6 @@ function getBtcBalance() {
3262
3346
  };
3263
3347
  });
3264
3348
  }
3265
- function getNBTCBalance(address, env) {
3266
- return __async(this, null, function* () {
3267
- const config = yield getConfig(env || "mainnet");
3268
- const rawBalance = yield nearCall(config.token, "ft_balance_of", {
3269
- account_id: address
3270
- });
3271
- const balance = new Big(rawBalance).div(__pow(10, 8)).round(8, Big.roundDown).toNumber();
3272
- const rawAvailableBalance = new Big(rawBalance).minus(1e3).toNumber();
3273
- const availableBalance = new Big(rawAvailableBalance).div(__pow(10, 8)).round(8, Big.roundDown).toNumber();
3274
- return { balance, availableBalance, rawBalance, rawAvailableBalance };
3275
- });
3276
- }
3277
3349
  function sendBitcoin(address, amount, feeRate) {
3278
3350
  return __async(this, null, function* () {
3279
3351
  const { sendBitcoin: sendBitcoin2 } = getBtcProvider();
@@ -3293,7 +3365,7 @@ function getDepositAmount(amount, option) {
3293
3365
  const _newAccountMinDepositAmount = (_a = option == null ? void 0 : option.newAccountMinDepositAmount) != null ? _a : true;
3294
3366
  const config = yield getConfig(env);
3295
3367
  const csna = yield getCsnaAccountId(env);
3296
- const accountInfo = yield getAccountInfo(csna, config.accountContractId);
3368
+ const accountInfo = yield getAccountInfo({ csna, env });
3297
3369
  const debtAction = yield checkGasTokenDebt(accountInfo, env, false);
3298
3370
  const repayAmount = (debtAction == null ? void 0 : debtAction.amount) || 0;
3299
3371
  const {
@@ -3372,7 +3444,7 @@ function executeBTCDepositAndAction(_0) {
3372
3444
  env,
3373
3445
  newAccountMinDepositAmount
3374
3446
  });
3375
- const accountInfo = yield getAccountInfo(csna, config.accountContractId);
3447
+ const accountInfo = yield getAccountInfo({ csna, env });
3376
3448
  const newActions = [];
3377
3449
  const debtAction = yield checkGasTokenDebt(accountInfo, env, false);
3378
3450
  if (debtAction) {
@@ -3386,12 +3458,12 @@ function executeBTCDepositAndAction(_0) {
3386
3458
  }));
3387
3459
  }
3388
3460
  const storageDepositMsg = {};
3389
- const registerRes = yield nearCall((action == null ? void 0 : action.receiver_id) || config.token, "storage_balance_of", {
3461
+ const registerRes = yield nearCall((action == null ? void 0 : action.receiver_id) || config.btcToken, "storage_balance_of", {
3390
3462
  account_id: csna
3391
3463
  });
3392
3464
  if (!(registerRes == null ? void 0 : registerRes.available)) {
3393
3465
  storageDepositMsg.storage_deposit_msg = {
3394
- contract_id: (action == null ? void 0 : action.receiver_id) || config.token,
3466
+ contract_id: (action == null ? void 0 : action.receiver_id) || config.btcToken,
3395
3467
  deposit: registerDeposit || NEAR_STORAGE_DEPOSIT_AMOUNT,
3396
3468
  registration_only: true
3397
3469
  };
@@ -3486,7 +3558,7 @@ function getWithdrawTransaction(_0) {
3486
3558
  env = "mainnet"
3487
3559
  }) {
3488
3560
  const provider = getBtcProvider();
3489
- const btcAddress = yield provider.account;
3561
+ const btcAddress = provider.account;
3490
3562
  const config = yield getConfig(env);
3491
3563
  const brgConfig = yield nearCall(config.bridgeContractId, "get_config", {});
3492
3564
  if (brgConfig.min_withdraw_amount) {
@@ -3510,7 +3582,7 @@ function getWithdrawTransaction(_0) {
3510
3582
  };
3511
3583
  });
3512
3584
  const _feeRate = feeRate || (yield getBtcGasPrice());
3513
- const { inputs, outputs, fee } = coinselect(
3585
+ let { inputs, outputs, fee } = coinselect(
3514
3586
  utxos,
3515
3587
  [{ address: btcAddress, value: Number(amount) }],
3516
3588
  Math.ceil(_feeRate)
@@ -3519,32 +3591,61 @@ function getWithdrawTransaction(_0) {
3519
3591
  throw new Error("The network is busy, please try again later.");
3520
3592
  }
3521
3593
  const maxBtcFee = Number(brgConfig.max_btc_gas_fee);
3522
- const newFee = fee;
3523
- const withdrawChangeAddress = brgConfig.change_address;
3524
- if (newFee > maxBtcFee) {
3594
+ const transactionFee = fee;
3595
+ const changeAddress = brgConfig.change_address;
3596
+ if (transactionFee > maxBtcFee) {
3525
3597
  throw new Error("Gas exceeds maximum value");
3526
3598
  }
3527
- let userOutput, noUserOutput;
3599
+ let recipientOutput, changeOutput;
3528
3600
  for (let i = 0; i < outputs.length; i++) {
3529
3601
  const output = outputs[i];
3530
3602
  if (output.value.toString() === amount.toString()) {
3531
- userOutput = output;
3603
+ recipientOutput = output;
3532
3604
  } else {
3533
- noUserOutput = output;
3605
+ changeOutput = output;
3534
3606
  }
3535
3607
  if (!output.address) {
3536
- output.address = withdrawChangeAddress;
3608
+ output.address = changeAddress;
3537
3609
  }
3538
3610
  }
3539
- userOutput.value = new Big(userOutput.value).minus(newFee).minus(withdrawFee).toNumber();
3540
- if (noUserOutput) {
3541
- noUserOutput.value = new Big(noUserOutput.value).plus(newFee).plus(withdrawFee).toNumber();
3611
+ recipientOutput.value = new Big(recipientOutput.value).minus(transactionFee).minus(withdrawFee).toNumber();
3612
+ if (changeOutput) {
3613
+ changeOutput.value = new Big(changeOutput.value).plus(transactionFee).plus(withdrawFee).toNumber();
3614
+ const remainingInputs = [...inputs];
3615
+ let smallestInput = Math.min.apply(
3616
+ null,
3617
+ remainingInputs.map((input) => input.value)
3618
+ );
3619
+ let remainingChangeAmount = changeOutput.value;
3620
+ while (remainingChangeAmount >= smallestInput && smallestInput > 0 && remainingInputs.length > 0) {
3621
+ remainingChangeAmount -= smallestInput;
3622
+ changeOutput.value = remainingChangeAmount;
3623
+ const smallestInputIndex = remainingInputs.findIndex(
3624
+ (input) => input.value === smallestInput
3625
+ );
3626
+ if (smallestInputIndex > -1) {
3627
+ remainingInputs.splice(smallestInputIndex, 1);
3628
+ }
3629
+ smallestInput = Math.min.apply(
3630
+ null,
3631
+ remainingInputs.map((input) => input.value)
3632
+ );
3633
+ }
3634
+ const minChangeAmount = Number(brgConfig.min_change_amount);
3635
+ let additionalFee = 0;
3636
+ if (changeOutput.value === 0) {
3637
+ outputs = outputs.filter((item) => item.value !== 0);
3638
+ } else if (changeOutput.value < minChangeAmount) {
3639
+ additionalFee = minChangeAmount - changeOutput.value;
3640
+ recipientOutput.value -= additionalFee;
3641
+ changeOutput.value = minChangeAmount;
3642
+ }
3542
3643
  } else {
3543
- noUserOutput = {
3544
- address: withdrawChangeAddress,
3545
- value: new Big(newFee).plus(withdrawFee).toNumber()
3644
+ changeOutput = {
3645
+ address: changeAddress,
3646
+ value: new Big(transactionFee).plus(withdrawFee).toNumber()
3546
3647
  };
3547
- outputs.push(noUserOutput);
3648
+ outputs.push(changeOutput);
3548
3649
  }
3549
3650
  const insufficientOutput = outputs.some((item) => item.value < 0);
3550
3651
  if (insufficientOutput) {
@@ -3552,7 +3653,7 @@ function getWithdrawTransaction(_0) {
3552
3653
  }
3553
3654
  const inputSum = inputs.reduce((sum, cur) => sum + Number(cur.value), 0);
3554
3655
  const outputSum = outputs.reduce((sum, cur) => sum + Number(cur.value), 0);
3555
- if (newFee + outputSum !== inputSum) {
3656
+ if (transactionFee + outputSum !== inputSum) {
3556
3657
  throw new Error("compute error");
3557
3658
  }
3558
3659
  const network = yield getNetwork();
@@ -3597,7 +3698,7 @@ function getWithdrawTransaction(_0) {
3597
3698
  };
3598
3699
  const csna = yield getCsnaAccountId(env);
3599
3700
  const transaction = {
3600
- receiverId: config.token,
3701
+ receiverId: config.btcToken,
3601
3702
  signerId: csna,
3602
3703
  actions: [
3603
3704
  {
@@ -4141,20 +4242,16 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
4141
4242
  throw new Error("Wallet state is invalid, please reconnect your wallet.");
4142
4243
  }
4143
4244
  const btcContext = window.btcContext;
4144
- const accountId = state.getAccount();
4145
- const accountInfo = yield getAccountInfo(accountId, currentConfig.accountContractId);
4245
+ const csna = state.getAccount();
4246
+ const accountInfo = yield getAccountInfo({ csna, env });
4146
4247
  yield checkGasTokenDebt(accountInfo, env, true);
4147
4248
  const trans = [...params.transactions];
4148
4249
  console.log("signAndSendTransactions raw trans:", trans);
4149
- const gasTokenBalance = (accountInfo == null ? void 0 : accountInfo.gas_token[currentConfig.token]) || "0";
4150
- const { transferGasTransaction, useNearPayGas, gasLimit } = yield calculateGasStrategy(
4151
- gasTokenBalance,
4152
- trans
4153
- );
4250
+ const { transferGasTransaction, useNearPayGas, gasLimit } = yield calculateGasStrategy(trans);
4154
4251
  console.log("transferGasTransaction:", transferGasTransaction);
4155
4252
  console.log("useNearPayGas:", useNearPayGas);
4156
4253
  console.log("gasLimit:", gasLimit);
4157
- yield checkGasTokenBalance(accountId, currentConfig.token, gasLimit, env);
4254
+ yield checkGasTokenBalance(csna, gasLimit, env);
4158
4255
  if (transferGasTransaction) {
4159
4256
  trans.unshift(transferGasTransaction);
4160
4257
  }
@@ -4162,14 +4259,14 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
4162
4259
  const newTrans = yield Promise.all(
4163
4260
  trans.map((transaction, index) => convertTransactionToTxHex(transaction, index))
4164
4261
  );
4165
- const nonceFromApi = yield getNonce(currentConfig.base_url, accountId);
4262
+ const nonceFromApi = yield getNonce(currentConfig.base_url, csna);
4166
4263
  const nonceFromContract = (accountInfo == null ? void 0 : accountInfo.nonce) || 0;
4167
4264
  const nonce = Number(nonceFromApi) > Number(nonceFromContract) ? String(nonceFromApi) : String(nonceFromContract);
4168
4265
  const intention = {
4169
4266
  chain_id: "397",
4170
- csna: accountId,
4267
+ csna,
4171
4268
  near_transactions: newTrans.map((t) => t.txHex),
4172
- gas_token: currentConfig.token,
4269
+ gas_token: currentConfig.btcToken,
4173
4270
  gas_limit: gasLimit,
4174
4271
  use_near_pay_gas: useNearPayGas,
4175
4272
  nonce
@@ -4182,7 +4279,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
4182
4279
  data: toHex(strIntention)
4183
4280
  });
4184
4281
  yield checkBtcTransactionStatus(currentConfig.base_url, signature);
4185
- const hash = newTrans.map((t) => t.hash);
4282
+ const hash = newTrans.slice(1).map((t) => t.hash);
4186
4283
  console.log("txHash:", hash);
4187
4284
  const result = yield pollTransactionStatuses(options.network.networkId, hash);
4188
4285
  return result;
@@ -4190,12 +4287,9 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
4190
4287
  }
4191
4288
  function calculateGasLimit(params) {
4192
4289
  return __async(this, null, function* () {
4193
- const accountId = state.getAccount();
4194
- const accountInfo = yield getAccountInfo(accountId, currentConfig.accountContractId);
4195
4290
  const trans = [...params.transactions];
4196
4291
  console.log("raw trans:", trans);
4197
- const gasTokenBalance = (accountInfo == null ? void 0 : accountInfo.gas_token[currentConfig.token]) || "0";
4198
- const { gasLimit } = yield calculateGasStrategy(gasTokenBalance, trans);
4292
+ const { gasLimit } = yield calculateGasStrategy(trans);
4199
4293
  return gasLimit;
4200
4294
  });
4201
4295
  }
@@ -4203,7 +4297,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
4203
4297
  return __async(this, null, function* () {
4204
4298
  return {
4205
4299
  signerId: accountId,
4206
- receiverId: currentConfig.token,
4300
+ receiverId: currentConfig.btcToken,
4207
4301
  actions: [
4208
4302
  {
4209
4303
  type: "FunctionCall",
@@ -4231,7 +4325,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
4231
4325
  } else {
4232
4326
  newGasLimit = yield getPredictedGasAmount(
4233
4327
  currentConfig.accountContractId,
4234
- currentConfig.token,
4328
+ currentConfig.btcToken,
4235
4329
  [transferTxHex, ...transactions2.map((t) => t.txHex)]
4236
4330
  );
4237
4331
  }
@@ -4252,31 +4346,61 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
4252
4346
  return gasAmount.toString();
4253
4347
  });
4254
4348
  }
4255
- function calculateGasStrategy(gasTokenBalance, transactions2) {
4349
+ function calculateGasStrategy(transactions2) {
4256
4350
  return __async(this, null, function* () {
4257
4351
  var _a;
4258
4352
  const accountId = state.getAccount();
4259
- const nearAccount = yield provider.query({
4260
- request_type: "view_account",
4261
- account_id: accountId,
4262
- finality: "final"
4353
+ const accountInfo = yield getAccountInfo({ csna: accountId, env });
4354
+ const gasTokenBalance = (accountInfo == null ? void 0 : accountInfo.gas_token[currentConfig.btcToken]) || "0";
4355
+ const { balance: nearBalance } = yield getTokenBalance({
4356
+ csna: accountId,
4357
+ tokenId: currentConfig.nearToken,
4358
+ env
4263
4359
  });
4264
- const availableBalance = parseFloat(nearAccount.amount) / __pow(10, 24);
4265
- console.log("available near balance:", availableBalance);
4360
+ const { balance: btcBalance } = yield getTokenBalance({
4361
+ csna: accountId,
4362
+ tokenId: currentConfig.btcToken,
4363
+ env
4364
+ });
4365
+ const transferAmount = transactions2.reduce(
4366
+ (acc, tx) => {
4367
+ tx.actions.forEach((action) => {
4368
+ if (action.params.deposit) {
4369
+ const amount = Number(action.params.deposit) / __pow(10, currentConfig.nearTokenDecimals);
4370
+ console.log("near deposit amount:", amount);
4371
+ acc.near = acc.near.plus(amount);
4372
+ }
4373
+ if (tx.receiverId === currentConfig.btcToken && ["ft_transfer_call", "ft_transfer"].includes(action.params.methodName)) {
4374
+ const amount = Number(action.params.args.amount) / __pow(10, currentConfig.btcTokenDecimals);
4375
+ console.log("btc transfer amount:", amount);
4376
+ acc.btc = acc.btc.plus(amount);
4377
+ }
4378
+ });
4379
+ return acc;
4380
+ },
4381
+ { near: new Big2(0), btc: new Big2(0) }
4382
+ );
4383
+ const nearAvailableBalance = new Big2(nearBalance).minus(transferAmount.near).toNumber();
4384
+ const btcAvailableBalance = new Big2(btcBalance).minus(transferAmount.btc).toNumber();
4385
+ if (btcAvailableBalance < 8e-6) {
4386
+ throw new Error("BTC balance is not enough, please deposit more BTC.");
4387
+ }
4388
+ console.log("available near balance:", nearAvailableBalance);
4389
+ console.log("available btc balance:", btcAvailableBalance);
4266
4390
  console.log("available gas token balance:", gasTokenBalance);
4267
4391
  const convertTx = yield Promise.all(
4268
4392
  transactions2.map((transaction, index) => convertTransactionToTxHex(transaction, index))
4269
4393
  );
4270
- if (availableBalance > 0.5) {
4394
+ if (nearAvailableBalance > 0.5) {
4271
4395
  console.log("near balance is enough, get the protocol fee of each transaction");
4272
4396
  const gasTokens = yield nearCall2(
4273
4397
  currentConfig.accountContractId,
4274
4398
  "list_gas_token",
4275
- { token_ids: [currentConfig.token] }
4399
+ { token_ids: [currentConfig.btcToken] }
4276
4400
  );
4277
4401
  console.log("list_gas_token gas tokens:", gasTokens);
4278
4402
  const perTxFee = Math.max(
4279
- Number(((_a = gasTokens[currentConfig.token]) == null ? void 0 : _a.per_tx_protocol_fee) || 0),
4403
+ Number(((_a = gasTokens[currentConfig.btcToken]) == null ? void 0 : _a.per_tx_protocol_fee) || 0),
4280
4404
  100
4281
4405
  );
4282
4406
  console.log("perTxFee:", perTxFee);
@@ -4294,7 +4418,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
4294
4418
  console.log("near balance is not enough, predict the gas token amount required");
4295
4419
  const adjustedGas = yield getPredictedGasAmount(
4296
4420
  currentConfig.accountContractId,
4297
- currentConfig.token,
4421
+ currentConfig.btcToken,
4298
4422
  convertTx.map((t) => t.txHex)
4299
4423
  );
4300
4424
  if (new Big2(gasTokenBalance).gte(adjustedGas)) {
@@ -4410,7 +4534,7 @@ function setupBTCWallet({
4410
4534
 
4411
4535
  // src/index.ts
4412
4536
  var getVersion = () => {
4413
- return "0.5.11-beta";
4537
+ return "0.5.13-beta";
4414
4538
  };
4415
4539
  if (typeof window !== "undefined") {
4416
4540
  window.__BTC_WALLET_VERSION = getVersion();
@@ -4440,7 +4564,7 @@ export {
4440
4564
  getConfig,
4441
4565
  getCsnaAccountId,
4442
4566
  getDepositAmount,
4443
- getNBTCBalance,
4567
+ getTokenBalance,
4444
4568
  getVersion,
4445
4569
  getWithdrawTransaction,
4446
4570
  sendBitcoin,