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/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,