btc-wallet 0.3.11 → 0.3.13

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
@@ -90,10 +90,13 @@ __export(src_exports, {
90
90
  UnisatConnector: () => UnisatConnector,
91
91
  WizzConnector: () => WizzConnector,
92
92
  XverseConnector: () => XverseConnector,
93
+ checkGasTokenArrears: () => checkGasTokenArrears,
93
94
  estimateDepositAmount: () => estimateDepositAmount,
94
95
  executeBTCDepositAndAction: () => executeBTCDepositAndAction,
96
+ getAccountInfo: () => getAccountInfo,
95
97
  getBtcBalance: () => getBtcBalance,
96
98
  getBtcGasPrice: () => getBtcGasPrice,
99
+ getDepositAmount: () => getDepositAmount,
97
100
  getVersion: () => getVersion,
98
101
  sendBitcoin: () => sendBitcoin,
99
102
  setupBTCWallet: () => setupBTCWallet,
@@ -2572,7 +2575,7 @@ var import_near_api_js2 = require("near-api-js");
2572
2575
  var import_transactions = require("@near-js/transactions");
2573
2576
  var import_key_pair = require("near-api-js/lib/utils/key_pair");
2574
2577
  var import_transaction = require("near-api-js/lib/transaction");
2575
- var import_utils5 = require("@near-js/utils");
2578
+ var import_utils6 = require("@near-js/utils");
2576
2579
  var import_bs58 = __toESM(require("bs58"), 1);
2577
2580
  var import_js_sha256 = require("js-sha256");
2578
2581
 
@@ -2726,24 +2729,21 @@ var walletConfig = {
2726
2729
  token: "nbtc-dev.testnet",
2727
2730
  accountContractId: "acc-dev.testnet",
2728
2731
  bridgeContractId: "brg-dev.testnet",
2729
- walletUrl: "https://wallet-dev.satoshibridge.top",
2730
- gasTokenLimit: "3000"
2732
+ walletUrl: "https://wallet-dev.satoshibridge.top"
2731
2733
  },
2732
2734
  testnet: {
2733
2735
  base_url: "https://api.testnet.satoshibridge.top",
2734
2736
  token: "nbtc2-nsp.testnet",
2735
2737
  accountContractId: "dev2-nsp.testnet",
2736
2738
  bridgeContractId: "brg2-nsp.testnet",
2737
- walletUrl: "https://wallet-test.satoshibridge.top",
2738
- gasTokenLimit: "3000"
2739
+ walletUrl: "https://wallet-test.satoshibridge.top"
2739
2740
  },
2740
2741
  mainnet: {
2741
2742
  base_url: "https://api.mainnet.satoshibridge.top",
2742
2743
  token: "",
2743
2744
  accountContractId: "",
2744
2745
  bridgeContractId: "",
2745
- walletUrl: "https://wallet.satoshibridge.top",
2746
- gasTokenLimit: "3000"
2746
+ walletUrl: "https://wallet.satoshibridge.top"
2747
2747
  }
2748
2748
  };
2749
2749
  var nearRpcUrls = {
@@ -2753,15 +2753,80 @@ var nearRpcUrls = {
2753
2753
  "https://free.rpc.fastnear.com",
2754
2754
  "https://near.drpc.org"
2755
2755
  ],
2756
- testnet: [
2757
- "https://rpc.testnet.near.org"
2758
- ]
2756
+ testnet: ["https://rpc.testnet.near.org"]
2759
2757
  };
2760
2758
  var btcRpcUrls = {
2761
2759
  mainnet: "https://mempool.space/api",
2762
2760
  testnet: "https://mempool.space/testnet/api"
2763
2761
  };
2764
2762
 
2763
+ // src/utils/nearUtils.ts
2764
+ var import_near_api_js = require("near-api-js");
2765
+ function nearCallFunction(contractId, methodName, args, options) {
2766
+ return __async(this, null, function* () {
2767
+ const nearProvider = (options == null ? void 0 : options.provider) || new import_near_api_js.providers.FailoverRpcProvider(
2768
+ nearRpcUrls[options == null ? void 0 : options.network].map(
2769
+ (url) => new import_near_api_js.providers.JsonRpcProvider({ url })
2770
+ )
2771
+ );
2772
+ const res = yield nearProvider.query({
2773
+ request_type: "call_function",
2774
+ account_id: contractId,
2775
+ method_name: methodName,
2776
+ args_base64: Buffer.from(JSON.stringify(args)).toString("base64"),
2777
+ finality: "final"
2778
+ });
2779
+ return JSON.parse(Buffer.from(res.result).toString());
2780
+ });
2781
+ }
2782
+ function pollTransactionStatuses(network, hashes) {
2783
+ return __async(this, null, function* () {
2784
+ const provider = new import_near_api_js.providers.FailoverRpcProvider(
2785
+ Object.values(nearRpcUrls[network]).map(
2786
+ (url) => new import_near_api_js.providers.JsonRpcProvider({ url })
2787
+ )
2788
+ );
2789
+ const maxAttempts = 30;
2790
+ let currentAttempt = 0;
2791
+ const pendingHashes = new Set(hashes);
2792
+ const results = /* @__PURE__ */ new Map();
2793
+ while (pendingHashes.size > 0 && currentAttempt < maxAttempts) {
2794
+ currentAttempt++;
2795
+ const promises = Array.from(pendingHashes).map((hash) => __async(this, null, function* () {
2796
+ try {
2797
+ const result = yield provider.txStatus(hash, "unused", "FINAL");
2798
+ if (result && result.status) {
2799
+ console.log(`Transaction ${hash} result:`, result);
2800
+ results.set(hash, result);
2801
+ pendingHashes.delete(hash);
2802
+ }
2803
+ } catch (error) {
2804
+ console.error(`Failed to fetch transaction status for ${hash}: ${error.message}`);
2805
+ }
2806
+ }));
2807
+ yield Promise.all(promises);
2808
+ if (pendingHashes.size > 0) {
2809
+ if (currentAttempt === maxAttempts) {
2810
+ throw new Error(
2811
+ `Transactions not found after max attempts: ${Array.from(pendingHashes).join(", ")}`
2812
+ );
2813
+ }
2814
+ console.log(
2815
+ `Waiting for ${pendingHashes.size} transactions, retrying ${maxAttempts - currentAttempt} more times`
2816
+ );
2817
+ yield delay(1e4);
2818
+ }
2819
+ }
2820
+ return hashes.map((hash) => results.get(hash));
2821
+ });
2822
+ }
2823
+
2824
+ // src/core/setupBTCWallet.ts
2825
+ var import_big2 = __toESM(require("big.js"), 1);
2826
+
2827
+ // src/core/btcUtils.ts
2828
+ var import_big = __toESM(require("big.js"), 1);
2829
+
2765
2830
  // src/utils/request.ts
2766
2831
  var cache = /* @__PURE__ */ new Map();
2767
2832
  var defaultCacheTimeout = 3e3;
@@ -2802,18 +2867,20 @@ function request(url, options) {
2802
2867
  if (!res.ok)
2803
2868
  throw new Error(res.statusText);
2804
2869
  const data = yield res.json();
2870
+ if (options == null ? void 0 : options.shouldStopPolling) {
2871
+ if (options.shouldStopPolling(data)) {
2872
+ return data;
2873
+ }
2874
+ throw new Error("Polling should continue");
2875
+ }
2805
2876
  if (cacheKey) {
2806
2877
  cache.set(cacheKey, { timestamp: Date.now(), data });
2807
2878
  setTimeout(() => {
2808
2879
  cache.delete(cacheKey);
2809
2880
  }, cacheTimeout);
2810
2881
  }
2811
- if ((options == null ? void 0 : options.shouldStopPolling) && options.shouldStopPolling(data)) {
2812
- return data;
2813
- }
2814
2882
  return data;
2815
2883
  } catch (err) {
2816
- console.error(err);
2817
2884
  if (retryCount > 0) {
2818
2885
  console.log(`Retrying... attempts left: ${retryCount}`);
2819
2886
  return request(url, __spreadProps(__spreadValues({}, options), { retryCount: retryCount - 1 }));
@@ -2827,74 +2894,533 @@ function request(url, options) {
2827
2894
  }));
2828
2895
  }
2829
2896
  }
2830
- return Promise.reject(err);
2897
+ throw err;
2831
2898
  }
2832
2899
  });
2833
2900
  }
2834
2901
 
2835
- // src/utils/nearUtils.ts
2836
- var import_near_api_js = require("near-api-js");
2837
- function nearCallFunction(contractId, methodName, args, options) {
2902
+ // src/utils/satoshi.ts
2903
+ function getNonce(url, accountId) {
2838
2904
  return __async(this, null, function* () {
2839
- const nearProvider = (options == null ? void 0 : options.provider) || new import_near_api_js.providers.FailoverRpcProvider(
2840
- nearRpcUrls[options == null ? void 0 : options.network].map(
2841
- (url) => new import_near_api_js.providers.JsonRpcProvider({ url })
2842
- )
2905
+ const { result_code, result_message, result_data } = yield request(
2906
+ `${url}/v1/nonce?csna=${accountId}`
2843
2907
  );
2844
- const res = yield nearProvider.query({
2845
- request_type: "call_function",
2846
- account_id: contractId,
2847
- method_name: methodName,
2848
- args_base64: Buffer.from(JSON.stringify(args)).toString("base64"),
2849
- finality: "final"
2908
+ if (result_code !== 0) {
2909
+ throw new Error(result_message);
2910
+ }
2911
+ return result_data;
2912
+ });
2913
+ }
2914
+ function getNearNonce(url, accountId) {
2915
+ return __async(this, null, function* () {
2916
+ const { result_code, result_message, result_data } = yield request(
2917
+ `${url}/v1/nonceNear?csna=${accountId}`
2918
+ );
2919
+ if (result_code !== 0) {
2920
+ throw new Error(result_message);
2921
+ }
2922
+ return result_data;
2923
+ });
2924
+ }
2925
+ function receiveTransaction(url, data) {
2926
+ return __async(this, null, function* () {
2927
+ const { result_code, result_message, result_data } = yield request(
2928
+ `${url}/v1/receiveTransaction`,
2929
+ {
2930
+ method: "POST",
2931
+ body: data
2932
+ }
2933
+ );
2934
+ if (result_code !== 0) {
2935
+ throw new Error(result_message);
2936
+ }
2937
+ return result_data;
2938
+ });
2939
+ }
2940
+ function receiveDepositMsg(_0, _1) {
2941
+ return __async(this, arguments, function* (url, {
2942
+ btcPublicKey,
2943
+ txHash,
2944
+ depositType = 1,
2945
+ postActions,
2946
+ extraMsg
2947
+ }) {
2948
+ const { result_code, result_message, result_data } = yield request(
2949
+ `${url}/v1/receiveDepositMsg`,
2950
+ {
2951
+ method: "POST",
2952
+ body: { btcPublicKey, txHash, depositType, postActions, extraMsg }
2953
+ }
2954
+ );
2955
+ console.log("receiveDepositMsg resp:", { result_code, result_message, result_data });
2956
+ if (result_code !== 0) {
2957
+ throw new Error(result_message);
2958
+ }
2959
+ return result_data;
2960
+ });
2961
+ }
2962
+ function checkBridgeTransactionStatus(url, txHash) {
2963
+ return __async(this, null, function* () {
2964
+ const { result_code, result_message, result_data } = yield request(`${url}/v1/bridgeFromTx?fromTxHash=${txHash}&fromChainId=1`, {
2965
+ timeout: 3e5,
2966
+ pollingInterval: 5e3,
2967
+ maxPollingAttempts: 60,
2968
+ shouldStopPolling: (res) => {
2969
+ var _a;
2970
+ return res.result_code === 0 && [4, 102].includes(((_a = res.result_data) == null ? void 0 : _a.Status) || 0);
2971
+ }
2850
2972
  });
2851
- return JSON.parse(Buffer.from(res.result).toString());
2973
+ console.log("checkTransactionStatus resp:", { result_code, result_message, result_data });
2974
+ if ((result_data == null ? void 0 : result_data.Status) !== 4) {
2975
+ throw new Error(result_message);
2976
+ }
2977
+ return result_data;
2852
2978
  });
2853
2979
  }
2854
- function pollTransactionStatuses(network, hashes) {
2980
+ function checkBtcTransactionStatus(url, sig) {
2855
2981
  return __async(this, null, function* () {
2856
- const provider = new import_near_api_js.providers.FailoverRpcProvider(
2857
- Object.values(nearRpcUrls[network]).map(
2858
- (url) => new import_near_api_js.providers.JsonRpcProvider({ url })
2859
- )
2982
+ const { result_code, result_message, result_data } = yield request(`${url}/v1/btcTx?sig=${sig}`, {
2983
+ timeout: 3e5,
2984
+ pollingInterval: 5e3,
2985
+ maxPollingAttempts: 60,
2986
+ shouldStopPolling: (res) => {
2987
+ var _a;
2988
+ return res.result_code === 0 && [3, 101, 102].includes(((_a = res.result_data) == null ? void 0 : _a.Status) || 0);
2989
+ }
2990
+ });
2991
+ console.log("checkBtcTransactionStatus resp:", { result_code, result_message, result_data });
2992
+ if ((result_data == null ? void 0 : result_data.Status) !== 3) {
2993
+ throw new Error(result_message);
2994
+ }
2995
+ return result_data;
2996
+ });
2997
+ }
2998
+
2999
+ // src/utils/Dialog.ts
3000
+ var Dialog = class {
3001
+ static injectStyles() {
3002
+ if (!document.querySelector("#dialog-styles")) {
3003
+ const styleSheet = document.createElement("style");
3004
+ styleSheet.id = "dialog-styles";
3005
+ styleSheet.textContent = this.style;
3006
+ document.head.appendChild(styleSheet);
3007
+ }
3008
+ }
3009
+ static confirm(options) {
3010
+ return new Promise((resolve) => {
3011
+ this.injectStyles();
3012
+ const container = document.createElement("div");
3013
+ container.innerHTML = this.template;
3014
+ document.body.appendChild(container);
3015
+ const titleEl = container.querySelector(".dialog-title");
3016
+ const messageEl = container.querySelector(".dialog-message");
3017
+ const confirmBtn = container.querySelector(".dialog-confirm-btn");
3018
+ const cancelBtn = container.querySelector(".dialog-cancel-btn");
3019
+ if (options.title) {
3020
+ titleEl.textContent = options.title;
3021
+ } else {
3022
+ titleEl.style.display = "none";
3023
+ }
3024
+ messageEl.textContent = options.message;
3025
+ const cleanup = () => {
3026
+ document.body.removeChild(container);
3027
+ };
3028
+ confirmBtn.addEventListener("click", () => {
3029
+ cleanup();
3030
+ resolve(true);
3031
+ });
3032
+ cancelBtn.addEventListener("click", () => {
3033
+ cleanup();
3034
+ resolve(false);
3035
+ });
3036
+ });
3037
+ }
3038
+ static alert(options) {
3039
+ return new Promise((resolve) => {
3040
+ this.injectStyles();
3041
+ const container = document.createElement("div");
3042
+ container.innerHTML = this.template;
3043
+ document.body.appendChild(container);
3044
+ const titleEl = container.querySelector(".dialog-title");
3045
+ const messageEl = container.querySelector(".dialog-message");
3046
+ const confirmBtn = container.querySelector(".dialog-confirm-btn");
3047
+ const cancelBtn = container.querySelector(".dialog-cancel-btn");
3048
+ if (options.title) {
3049
+ titleEl.textContent = options.title;
3050
+ } else {
3051
+ titleEl.style.display = "none";
3052
+ }
3053
+ messageEl.textContent = options.message;
3054
+ cancelBtn.style.display = "none";
3055
+ const cleanup = () => {
3056
+ document.body.removeChild(container);
3057
+ };
3058
+ confirmBtn.addEventListener("click", () => {
3059
+ cleanup();
3060
+ resolve();
3061
+ });
3062
+ });
3063
+ }
3064
+ };
3065
+ Dialog.template = `
3066
+ <div class="dialog-overlay">
3067
+ <div class="dialog-container">
3068
+ <div class="dialog-content">
3069
+ <div class="dialog-title"></div>
3070
+ <div class="dialog-message"></div>
3071
+ <div class="dialog-buttons">
3072
+ <button class="dialog-cancel-btn">Cancel</button>
3073
+ <button class="dialog-confirm-btn">Confirm</button>
3074
+ </div>
3075
+ </div>
3076
+ </div>
3077
+ </div>
3078
+ `;
3079
+ Dialog.style = `
3080
+ .dialog-overlay {
3081
+ position: fixed;
3082
+ top: 0;
3083
+ left: 0;
3084
+ right: 0;
3085
+ bottom: 0;
3086
+ background-color: rgba(0, 0, 0, 0.75);
3087
+ display: flex;
3088
+ align-items: center;
3089
+ justify-content: center;
3090
+ z-index: 999999;
3091
+ backdrop-filter: blur(4px);
3092
+ }
3093
+ .dialog-container {
3094
+ background: #21232f;
3095
+ border-radius: 12px;
3096
+ padding: 24px;
3097
+ width: 350px;
3098
+ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.3);
3099
+ }
3100
+ .dialog-title {
3101
+ font-size: 18px;
3102
+ font-weight: 600;
3103
+ margin-bottom: 16px;
3104
+ color: #ffffff;
3105
+ }
3106
+ .dialog-message {
3107
+ margin-bottom: 24px;
3108
+ line-height: 1.6;
3109
+ color: rgba(255, 255, 255, 0.8);
3110
+ font-size: 14px;
3111
+ }
3112
+ .dialog-buttons {
3113
+ display: flex;
3114
+ justify-content: flex-end;
3115
+ gap: 12px;
3116
+ }
3117
+ .dialog-confirm-btn {
3118
+ padding: 8px 24px;
3119
+ background-color: #ff7a00;
3120
+ color: white;
3121
+ border: none;
3122
+ border-radius: 6px;
3123
+ cursor: pointer;
3124
+ font-size: 14px;
3125
+ font-weight: 500;
3126
+ transition: all 0.2s ease;
3127
+ }
3128
+ .dialog-confirm-btn:hover {
3129
+ background-color: #ff8f1f;
3130
+ transform: translateY(-1px);
3131
+ }
3132
+ .dialog-confirm-btn:active {
3133
+ transform: translateY(0);
3134
+ }
3135
+ .dialog-cancel-btn {
3136
+ padding: 8px 24px;
3137
+ background-color: rgba(255, 255, 255, 0.1);
3138
+ color: rgba(255, 255, 255, 0.8);
3139
+ border: none;
3140
+ border-radius: 6px;
3141
+ cursor: pointer;
3142
+ font-size: 14px;
3143
+ font-weight: 500;
3144
+ transition: all 0.2s ease;
3145
+ }
3146
+ .dialog-cancel-btn:hover {
3147
+ background-color: rgba(255, 255, 255, 0.15);
3148
+ transform: translateY(-1px);
3149
+ }
3150
+ .dialog-cancel-btn:active {
3151
+ transform: translateY(0);
3152
+ }
3153
+
3154
+ .dialog-overlay {
3155
+ animation: fadeIn 0.2s ease;
3156
+ }
3157
+ .dialog-container {
3158
+ animation: slideIn 0.2s ease;
3159
+ }
3160
+ @keyframes fadeIn {
3161
+ from {
3162
+ opacity: 0;
3163
+ }
3164
+ to {
3165
+ opacity: 1;
3166
+ }
3167
+ }
3168
+ @keyframes slideIn {
3169
+ from {
3170
+ transform: translateY(-20px);
3171
+ opacity: 0;
3172
+ }
3173
+ to {
3174
+ transform: translateY(0);
3175
+ opacity: 1;
3176
+ }
3177
+ }
3178
+ `;
3179
+
3180
+ // src/core/btcUtils.ts
3181
+ function getBtcProvider() {
3182
+ if (typeof window === "undefined" || !window.btcContext) {
3183
+ throw new Error("BTC Provider is not initialized.");
3184
+ }
3185
+ return window.btcContext;
3186
+ }
3187
+ function getNetwork() {
3188
+ return __async(this, null, function* () {
3189
+ const network = yield getBtcProvider().getNetwork();
3190
+ console.log("btc network:", network);
3191
+ return network === "livenet" ? "mainnet" : "testnet";
3192
+ });
3193
+ }
3194
+ function getBtcRpcUrl() {
3195
+ return __async(this, null, function* () {
3196
+ const network = yield getNetwork();
3197
+ return btcRpcUrls[network];
3198
+ });
3199
+ }
3200
+ function getConfig(isDev) {
3201
+ return __async(this, null, function* () {
3202
+ const network = yield getNetwork();
3203
+ return walletConfig[isDev ? "dev" : network];
3204
+ });
3205
+ }
3206
+ function nearCall(contractId, methodName, args) {
3207
+ return __async(this, null, function* () {
3208
+ const network = yield getNetwork();
3209
+ return nearCallFunction(contractId, methodName, args, { network });
3210
+ });
3211
+ }
3212
+ function getAccountInfo(csna, accountContractId) {
3213
+ return __async(this, null, function* () {
3214
+ const accountInfo = yield nearCall(accountContractId, "get_account", { account_id: csna });
3215
+ return accountInfo;
3216
+ });
3217
+ }
3218
+ function checkGasTokenArrears(debtInfo, isDev, autoDeposit) {
3219
+ return __async(this, null, function* () {
3220
+ const config = yield getConfig(isDev);
3221
+ const transferAmount = debtInfo.transfer_amount || "0";
3222
+ console.log("get_account debtInfo:", debtInfo);
3223
+ if (transferAmount === "0")
3224
+ return;
3225
+ const action = {
3226
+ receiver_id: config.token,
3227
+ amount: transferAmount,
3228
+ msg: JSON.stringify("Deposit")
3229
+ };
3230
+ if (!autoDeposit)
3231
+ return action;
3232
+ const confirmed = yield Dialog.confirm({
3233
+ title: "Has gas token arrears",
3234
+ message: "You have gas token arrears, please deposit gas token to continue."
3235
+ });
3236
+ if (confirmed) {
3237
+ yield executeBTCDepositAndAction({ action, isDev });
3238
+ yield Dialog.alert({
3239
+ title: "Deposit success",
3240
+ message: "Deposit success, will continue to execute transaction."
3241
+ });
3242
+ } else {
3243
+ throw new Error("Deposit failed, please deposit gas token first.");
3244
+ }
3245
+ });
3246
+ }
3247
+ function getBtcGasPrice() {
3248
+ return __async(this, null, function* () {
3249
+ const network = yield getNetwork();
3250
+ const defaultFeeRate = network === "mainnet" ? 5 : 2500;
3251
+ try {
3252
+ const btcRpcUrl = yield getBtcRpcUrl();
3253
+ const res = yield fetch(`${btcRpcUrl}/v1/fees/recommended`).then((res2) => res2.json());
3254
+ const feeRate = res.fastestFee;
3255
+ return feeRate || defaultFeeRate;
3256
+ } catch (error) {
3257
+ return defaultFeeRate;
3258
+ }
3259
+ });
3260
+ }
3261
+ function getBtcBalance() {
3262
+ return __async(this, null, function* () {
3263
+ const { account } = yield retryOperation(getBtcProvider, (res) => !!res.account);
3264
+ if (!account) {
3265
+ console.error("BTC Account is not available.");
3266
+ return { rawBalance: 0, balance: 0, maxSpendableBalance: 0 };
3267
+ }
3268
+ const btcRpcUrl = yield getBtcRpcUrl();
3269
+ const utxos = yield fetch(`${btcRpcUrl}/address/${account}/utxo`).then((res) => res.json());
3270
+ const rawBalance = (utxos == null ? void 0 : utxos.reduce((acc, cur) => acc + cur.value, 0)) || 0;
3271
+ const balance = rawBalance / __pow(10, 8);
3272
+ const feeRate = yield getBtcGasPrice();
3273
+ const inputSize = ((utxos == null ? void 0 : utxos.length) || 0) * 66;
3274
+ const outputSize = 34;
3275
+ const overheadSize = 10;
3276
+ const estimatedTxSize = inputSize + outputSize + overheadSize;
3277
+ const estimatedFee = estimatedTxSize * feeRate / __pow(10, 8);
3278
+ console.log("estimated fee:", estimatedFee);
3279
+ const availableBalance = Math.max(0, balance - estimatedFee);
3280
+ return {
3281
+ rawBalance,
3282
+ balance,
3283
+ availableBalance
3284
+ };
3285
+ });
3286
+ }
3287
+ function sendBitcoin(address, amount, feeRate) {
3288
+ return __async(this, null, function* () {
3289
+ const { sendBitcoin: sendBitcoin2 } = getBtcProvider();
3290
+ const txHash = yield sendBitcoin2(address, amount, { feeRate });
3291
+ return txHash;
3292
+ });
3293
+ }
3294
+ var MINIMUM_DEPOSIT_AMOUNT = 5e3;
3295
+ var MINIMUM_DEPOSIT_AMOUNT_BASE = 1e3;
3296
+ function estimateDepositAmount(amount, option) {
3297
+ return __async(this, null, function* () {
3298
+ const { receiveAmount } = yield getDepositAmount(amount, __spreadProps(__spreadValues({}, option), { isEstimate: true }));
3299
+ return receiveAmount;
3300
+ });
3301
+ }
3302
+ function getDepositAmount(amount, option) {
3303
+ return __async(this, null, function* () {
3304
+ const config = yield getConfig((option == null ? void 0 : option.isDev) || false);
3305
+ const {
3306
+ deposit_bridge_fee: { fee_min, fee_rate }
3307
+ } = yield nearCall(
3308
+ config.bridgeContractId,
3309
+ "get_config",
3310
+ {}
2860
3311
  );
2861
- const maxAttempts = 30;
2862
- let currentAttempt = 0;
2863
- const pendingHashes = new Set(hashes);
2864
- const results = /* @__PURE__ */ new Map();
2865
- while (pendingHashes.size > 0 && currentAttempt < maxAttempts) {
2866
- currentAttempt++;
2867
- const promises = Array.from(pendingHashes).map((hash) => __async(this, null, function* () {
2868
- try {
2869
- const result = yield provider.txStatus(hash, "unused", "FINAL");
2870
- if (result && result.status) {
2871
- console.log(`Transaction ${hash} result:`, result);
2872
- results.set(hash, result);
2873
- pendingHashes.delete(hash);
2874
- }
2875
- } catch (error) {
2876
- console.error(`Failed to fetch transaction status for ${hash}: ${error.message}`);
2877
- }
2878
- }));
2879
- yield Promise.all(promises);
2880
- if (pendingHashes.size > 0) {
2881
- if (currentAttempt === maxAttempts) {
2882
- throw new Error(
2883
- `Transactions not found after max attempts: ${Array.from(pendingHashes).join(", ")}`
2884
- );
3312
+ const depositAmount = (option == null ? void 0 : option.isEstimate) ? Number(amount) : Math.max(MINIMUM_DEPOSIT_AMOUNT + MINIMUM_DEPOSIT_AMOUNT_BASE, Number(amount));
3313
+ const fee = Math.max(Number(fee_min), Number(depositAmount) * fee_rate);
3314
+ const receiveAmount = new import_big.default(depositAmount).minus(fee).round(0, import_big.default.roundDown).toNumber();
3315
+ return {
3316
+ depositAmount,
3317
+ receiveAmount: Math.max(receiveAmount, 0),
3318
+ fee
3319
+ };
3320
+ });
3321
+ }
3322
+ function executeBTCDepositAndAction(_0) {
3323
+ return __async(this, arguments, function* ({
3324
+ action,
3325
+ amount,
3326
+ feeRate,
3327
+ fixedAmount = true,
3328
+ isDev = false
3329
+ }) {
3330
+ var _a;
3331
+ try {
3332
+ const { getPublicKey } = getBtcProvider();
3333
+ const config = yield getConfig(isDev);
3334
+ const btcPublicKey = yield getPublicKey();
3335
+ if (!btcPublicKey) {
3336
+ throw new Error("BTC Public Key is not available.");
3337
+ }
3338
+ if (!amount && !action) {
3339
+ throw new Error("amount or action is required");
3340
+ }
3341
+ const csna = yield nearCall(
3342
+ config.accountContractId,
3343
+ "get_chain_signature_near_account_id",
3344
+ {
3345
+ btc_public_key: btcPublicKey
2885
3346
  }
2886
- console.log(
2887
- `Waiting for ${pendingHashes.size} transactions, retrying ${maxAttempts - currentAttempt} more times`
2888
- );
2889
- yield delay(1e4);
3347
+ );
3348
+ const rawDepositAmount = (_a = action ? action.amount : amount) != null ? _a : "0";
3349
+ if (new import_big.default(rawDepositAmount).lt(0)) {
3350
+ throw new Error("amount must be greater than 0");
3351
+ }
3352
+ const { depositAmount } = yield getDepositAmount(rawDepositAmount, {
3353
+ isDev
3354
+ });
3355
+ const accountInfo = yield getAccountInfo(csna, config.accountContractId);
3356
+ const newActions = [];
3357
+ const gasLimit = new import_big.default(50).mul(__pow(10, 12)).toFixed(0);
3358
+ const repayAction = yield checkGasTokenArrears(accountInfo.debt_info, isDev);
3359
+ if (repayAction) {
3360
+ newActions.push(__spreadProps(__spreadValues({}, repayAction), {
3361
+ gas: gasLimit
3362
+ }));
3363
+ }
3364
+ if (action) {
3365
+ newActions.push(__spreadProps(__spreadValues({}, action), {
3366
+ amount: (repayAction == null ? void 0 : repayAction.amount) && !fixedAmount ? new import_big.default(depositAmount).minus(repayAction.amount).toString() : depositAmount.toString(),
3367
+ gas: gasLimit
3368
+ }));
3369
+ }
3370
+ const depositMsg = {
3371
+ recipient_id: csna,
3372
+ post_actions: newActions.length > 0 ? newActions : void 0
3373
+ };
3374
+ const storageDepositMsg = {};
3375
+ if (!(accountInfo == null ? void 0 : accountInfo.nonce)) {
3376
+ storageDepositMsg.btc_public_key = btcPublicKey;
3377
+ }
3378
+ const registerRes = yield nearCall((action == null ? void 0 : action.receiver_id) || config.token, "storage_balance_of", {
3379
+ account_id: csna
3380
+ });
3381
+ if (!(registerRes == null ? void 0 : registerRes.available)) {
3382
+ storageDepositMsg.storage_deposit_msg = {
3383
+ contract_id: (action == null ? void 0 : action.receiver_id) || config.token,
3384
+ deposit: new import_big.default(0.25).mul(__pow(10, 24)).toFixed(0),
3385
+ registration_only: true
3386
+ };
2890
3387
  }
3388
+ if (Object.keys(storageDepositMsg).length > 0) {
3389
+ depositMsg.extra_msg = JSON.stringify(storageDepositMsg);
3390
+ }
3391
+ console.log("get_user_deposit_address params:", { deposit_msg: depositMsg });
3392
+ const userDepositAddress = yield nearCall(
3393
+ config.bridgeContractId,
3394
+ "get_user_deposit_address",
3395
+ { deposit_msg: depositMsg }
3396
+ );
3397
+ const _feeRate = feeRate || (yield getBtcGasPrice());
3398
+ const sendAmount = (repayAction == null ? void 0 : repayAction.amount) && fixedAmount ? new import_big.default(depositAmount).plus((repayAction == null ? void 0 : repayAction.amount) || 0).toString() : depositAmount;
3399
+ console.log("user deposit address:", userDepositAddress);
3400
+ console.log("send amount:", sendAmount);
3401
+ console.log("fee rate:", _feeRate);
3402
+ const txHash = yield sendBitcoin(userDepositAddress, Number(sendAmount), _feeRate);
3403
+ const postActionsStr = newActions.length > 0 ? JSON.stringify(newActions) : void 0;
3404
+ yield receiveDepositMsg(config.base_url, {
3405
+ btcPublicKey,
3406
+ txHash,
3407
+ depositType: postActionsStr || depositMsg.extra_msg ? 1 : 0,
3408
+ postActions: postActionsStr,
3409
+ extraMsg: depositMsg.extra_msg
3410
+ });
3411
+ const checkTransactionStatusRes = yield checkBridgeTransactionStatus(config.base_url, txHash);
3412
+ console.log("checkBridgeTransactionStatus resp:", checkTransactionStatusRes);
3413
+ const network = yield getNetwork();
3414
+ const result = yield pollTransactionStatuses(network, [checkTransactionStatusRes.ToTxHash]);
3415
+ return result;
3416
+ } catch (error) {
3417
+ console.error("executeBTCDepositAndAction error:", error);
3418
+ throw error;
2891
3419
  }
2892
- return hashes.map((hash) => results.get(hash));
2893
3420
  });
2894
3421
  }
2895
3422
 
2896
3423
  // src/core/setupBTCWallet.ts
2897
- var import_big = __toESM(require("big.js"), 1);
2898
3424
  var { transfer, functionCall } = import_transactions.actionCreators;
2899
3425
  var state = {
2900
3426
  saveAccount(account) {
@@ -2944,6 +3470,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
2944
3470
  id,
2945
3471
  provider
2946
3472
  }) {
3473
+ var _a;
2947
3474
  const wallet = {
2948
3475
  signIn,
2949
3476
  signOut,
@@ -2953,8 +3480,9 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
2953
3480
  signAndSendTransaction,
2954
3481
  signAndSendTransactions
2955
3482
  };
2956
- const currentConfig = "isDev" in metadata && metadata.isDev ? walletConfig.dev : walletConfig[options.network.networkId];
2957
- const walletNetwork = "isDev" in metadata && metadata.isDev ? "dev" : options.network.networkId;
3483
+ const isDev = (_a = "isDev" in metadata && metadata.isDev) != null ? _a : false;
3484
+ const currentConfig = isDev ? walletConfig.dev : walletConfig[options.network.networkId];
3485
+ const walletNetwork = isDev ? "dev" : options.network.networkId;
2958
3486
  initWalletButton(walletNetwork, wallet);
2959
3487
  if (!inter) {
2960
3488
  inter = setInterval(() => __async(void 0, null, function* () {
@@ -3095,9 +3623,15 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3095
3623
  return __async(this, null, function* () {
3096
3624
  const btcContext = window.btcContext;
3097
3625
  const accountId = state.getAccount();
3626
+ const accountInfo = yield getAccountInfo(accountId, currentConfig.accountContractId);
3627
+ yield checkGasTokenArrears(accountInfo.debt_info, isDev, true);
3098
3628
  const trans = [...params.transactions];
3099
3629
  console.log("raw trans:", trans);
3100
- const { transferGasTransaction, useNearPayGas, gasLimit } = yield calculateGasStrategy(trans);
3630
+ const gasTokenBalance = accountInfo.gas_token[currentConfig.token] || "0";
3631
+ const { transferGasTransaction, useNearPayGas, gasLimit } = yield calculateGasStrategy(
3632
+ gasTokenBalance,
3633
+ trans
3634
+ );
3101
3635
  console.log("transferGasTransaction:", transferGasTransaction);
3102
3636
  console.log("useNearPayGas:", useNearPayGas);
3103
3637
  console.log("gasLimit:", gasLimit);
@@ -3108,11 +3642,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3108
3642
  const newTrans = yield Promise.all(
3109
3643
  trans.map((transaction, index) => convertTransactionToTxHex(transaction, index))
3110
3644
  );
3111
- const { result_data: nonceFromApi } = yield getNonceFromApi(
3112
- currentConfig.base_url,
3113
- accountId
3114
- );
3115
- const accountInfo = yield getAccountInfo();
3645
+ const nonceFromApi = yield getNonce(currentConfig.base_url, accountId);
3116
3646
  const nonce = Number(nonceFromApi) > Number(accountInfo.nonce) ? String(nonceFromApi) : String(accountInfo.nonce);
3117
3647
  const intention = {
3118
3648
  chain_id: "397",
@@ -3125,30 +3655,16 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3125
3655
  };
3126
3656
  const strIntention = JSON.stringify(intention);
3127
3657
  const signature = yield btcContext.signMessage(strIntention);
3128
- const result = yield uploadBTCTx(currentConfig.base_url, {
3658
+ yield receiveTransaction(currentConfig.base_url, {
3129
3659
  sig: signature,
3130
3660
  btcPubKey: state.getBtcPublicKey(),
3131
3661
  data: toHex(strIntention)
3132
3662
  });
3133
- if (result.result_code === 0) {
3134
- const hash = newTrans.map((t) => t.hash);
3135
- console.log("txHash:", hash);
3136
- const result2 = yield pollTransactionStatuses(options.network.networkId, hash);
3137
- return result2;
3138
- } else {
3139
- return null;
3140
- }
3141
- });
3142
- }
3143
- function getAccountInfo() {
3144
- return __async(this, null, function* () {
3145
- const accountId = state.getAccount();
3146
- const accountInfo = yield nearCall2(
3147
- currentConfig.accountContractId,
3148
- "get_account",
3149
- { account_id: accountId }
3150
- );
3151
- return accountInfo;
3663
+ yield checkBtcTransactionStatus(currentConfig.base_url, signature);
3664
+ const hash = newTrans.map((t) => t.hash);
3665
+ console.log("txHash:", hash);
3666
+ const result = yield pollTransactionStatuses(options.network.networkId, hash);
3667
+ return result;
3152
3668
  });
3153
3669
  }
3154
3670
  function createGasTokenTransfer(accountId, amount) {
@@ -3166,7 +3682,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3166
3682
  amount,
3167
3683
  msg: JSON.stringify("Deposit")
3168
3684
  },
3169
- gas: new import_big.default(50).mul(__pow(10, 12)).toFixed(0),
3685
+ gas: new import_big2.default(50).mul(__pow(10, 12)).toFixed(0),
3170
3686
  deposit: "1"
3171
3687
  }
3172
3688
  }
@@ -3179,7 +3695,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3179
3695
  const { txHex: transferTxHex } = yield convertTransactionToTxHex(transferTx);
3180
3696
  let newGasLimit;
3181
3697
  if (useNearPayGas && perTxFee) {
3182
- newGasLimit = new import_big.default(perTxFee).mul(transactions2.length + 1).toFixed(0);
3698
+ newGasLimit = new import_big2.default(perTxFee).mul(transactions2.length + 1).toFixed(0);
3183
3699
  } else {
3184
3700
  newGasLimit = yield getPredictedGasAmount(
3185
3701
  currentConfig.accountContractId,
@@ -3197,14 +3713,14 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3197
3713
  gas_token_id: tokenId,
3198
3714
  near_transactions: transactions2
3199
3715
  });
3200
- const predictedGasAmount = new import_big.default(predictedGas).mul(1.2).toFixed(0);
3716
+ const predictedGasAmount = new import_big2.default(predictedGas).mul(1.2).toFixed(0);
3201
3717
  console.log("predictedGas:", predictedGasAmount);
3202
3718
  return predictedGasAmount;
3203
3719
  });
3204
3720
  }
3205
- function calculateGasStrategy(transactions2) {
3721
+ function calculateGasStrategy(gasTokenBalance, transactions2) {
3206
3722
  return __async(this, null, function* () {
3207
- var _a;
3723
+ var _a2;
3208
3724
  const accountId = state.getAccount();
3209
3725
  const nearAccount = yield provider.query({
3210
3726
  request_type: "view_account",
@@ -3213,13 +3729,12 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3213
3729
  });
3214
3730
  const availableBalance = parseFloat(nearAccount.amount) / __pow(10, 24);
3215
3731
  console.log("available near balance:", availableBalance);
3216
- const accountInfo = yield getAccountInfo();
3217
- const gasTokenBalance = accountInfo.gas_token[currentConfig.token] || "0";
3218
3732
  console.log("available gas token balance:", gasTokenBalance);
3219
3733
  const convertTx = yield Promise.all(
3220
3734
  transactions2.map((transaction, index) => convertTransactionToTxHex(transaction, index))
3221
3735
  );
3222
3736
  if (availableBalance > 0.2) {
3737
+ console.log("near balance is enough, get the protocol fee of each transaction");
3223
3738
  const gasTokens = yield nearCall2(
3224
3739
  currentConfig.accountContractId,
3225
3740
  "list_gas_token",
@@ -3227,13 +3742,13 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3227
3742
  );
3228
3743
  console.log("list_gas_token gas tokens:", gasTokens);
3229
3744
  const perTxFee = Math.max(
3230
- Number(((_a = gasTokens[currentConfig.token]) == null ? void 0 : _a.per_tx_protocol_fee) || 0),
3745
+ Number(((_a2 = gasTokens[currentConfig.token]) == null ? void 0 : _a2.per_tx_protocol_fee) || 0),
3231
3746
  100
3232
3747
  );
3233
3748
  console.log("perTxFee:", perTxFee);
3234
- const protocolFee = new import_big.default(perTxFee || "0").mul(convertTx.length).toFixed(0);
3749
+ const protocolFee = new import_big2.default(perTxFee || "0").mul(convertTx.length).toFixed(0);
3235
3750
  console.log("protocolFee:", protocolFee);
3236
- if (new import_big.default(gasTokenBalance).gte(protocolFee)) {
3751
+ if (new import_big2.default(gasTokenBalance).gte(protocolFee)) {
3237
3752
  console.log("use near pay gas and enough gas token balance");
3238
3753
  return { useNearPayGas: true, gasLimit: protocolFee };
3239
3754
  } else {
@@ -3248,7 +3763,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3248
3763
  currentConfig.token,
3249
3764
  convertTx.map((t) => t.txHex)
3250
3765
  );
3251
- if (new import_big.default(gasTokenBalance).gte(adjustedGas)) {
3766
+ if (new import_big2.default(gasTokenBalance).gte(adjustedGas)) {
3252
3767
  console.log("use gas token and gas token balance is enough");
3253
3768
  return { useNearPayGas: false, gasLimit: adjustedGas };
3254
3769
  } else {
@@ -3276,10 +3791,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3276
3791
  const accessKey = __spreadProps(__spreadValues({}, rawAccessKey), {
3277
3792
  nonce: BigInt(rawAccessKey.nonce || 0)
3278
3793
  });
3279
- const { result_data: nearNonceFromApi } = yield getNearNonceFromApi(
3280
- currentConfig.base_url,
3281
- accountId
3282
- );
3794
+ const nearNonceFromApi = yield getNearNonce(currentConfig.base_url, accountId);
3283
3795
  let nearNonceNumber = accessKey.nonce + BigInt(1);
3284
3796
  if (nearNonceFromApi) {
3285
3797
  nearNonceNumber = BigInt(nearNonceFromApi) > nearNonceNumber ? BigInt(nearNonceFromApi) : nearNonceNumber;
@@ -3303,7 +3815,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3303
3815
  transaction.receiverId,
3304
3816
  BigInt(nearNonceNumber) + BigInt(index),
3305
3817
  newActions,
3306
- (0, import_utils5.baseDecode)(header.hash)
3818
+ (0, import_utils6.baseDecode)(header.hash)
3307
3819
  );
3308
3820
  const txBytes = (0, import_transaction.encodeTransaction)(_transaction);
3309
3821
  const txHex = Array.from(txBytes, (byte) => ("0" + (byte & 255).toString(16)).slice(-2)).join(
@@ -3333,18 +3845,6 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3333
3845
  }
3334
3846
  return wallet;
3335
3847
  });
3336
- function getNonceFromApi(url, accountId) {
3337
- return request(`${url}/v1/nonce?csna=${accountId}`);
3338
- }
3339
- function getNearNonceFromApi(url, accountId) {
3340
- return request(`${url}/v1/nonceNear?csna=${accountId}`);
3341
- }
3342
- function uploadBTCTx(url, data) {
3343
- return request(`${url}/v1/receiveTransaction`, {
3344
- method: "POST",
3345
- body: data
3346
- });
3347
- }
3348
3848
  function toHex(originalString) {
3349
3849
  const charArray = originalString.split("");
3350
3850
  const asciiArray = charArray.map((char) => char.charCodeAt(0));
@@ -3381,228 +3881,9 @@ function setupBTCWallet({
3381
3881
  return btcWallet;
3382
3882
  }
3383
3883
 
3384
- // src/core/btcUtils.ts
3385
- var import_big2 = __toESM(require("big.js"), 1);
3386
- function getBtcProvider() {
3387
- if (typeof window === "undefined" || !window.btcContext) {
3388
- throw new Error("BTC Provider is not initialized.");
3389
- }
3390
- return window.btcContext;
3391
- }
3392
- function getNetwork() {
3393
- return __async(this, null, function* () {
3394
- const network = yield getBtcProvider().getNetwork();
3395
- console.log("btc network:", network);
3396
- return network === "livenet" ? "mainnet" : "testnet";
3397
- });
3398
- }
3399
- function getBtcRpcUrl() {
3400
- return __async(this, null, function* () {
3401
- const network = yield getNetwork();
3402
- return btcRpcUrls[network];
3403
- });
3404
- }
3405
- function getConfig(isDev) {
3406
- return __async(this, null, function* () {
3407
- const network = yield getNetwork();
3408
- return walletConfig[isDev ? "dev" : network];
3409
- });
3410
- }
3411
- function nearCall(contractId, methodName, args) {
3412
- return __async(this, null, function* () {
3413
- const network = yield getNetwork();
3414
- return nearCallFunction(contractId, methodName, args, { network });
3415
- });
3416
- }
3417
- function receiveDepositMsg(_0, _1) {
3418
- return __async(this, arguments, function* (baseUrl, {
3419
- btcPublicKey,
3420
- txHash,
3421
- depositType = 1,
3422
- postActions,
3423
- extraMsg
3424
- }) {
3425
- const res = yield request(`${baseUrl}/v1/receiveDepositMsg`, {
3426
- method: "POST",
3427
- body: { btcPublicKey, txHash, depositType, postActions, extraMsg }
3428
- });
3429
- console.log("receiveDepositMsg resp:", res);
3430
- return res;
3431
- });
3432
- }
3433
- function checkTransactionStatus(baseUrl, txHash) {
3434
- return __async(this, null, function* () {
3435
- const res = yield request(
3436
- `${baseUrl}/v1/bridgeFromTx?fromTxHash=${txHash}&fromChainId=1`,
3437
- {
3438
- timeout: 6e4,
3439
- pollingInterval: 5e3,
3440
- maxPollingAttempts: 10,
3441
- shouldStopPolling: (res2) => res2.result_code === 0
3442
- }
3443
- );
3444
- return res;
3445
- });
3446
- }
3447
- function getBtcGasPrice() {
3448
- return __async(this, null, function* () {
3449
- const defaultFeeRate = 100;
3450
- try {
3451
- const btcRpcUrl = yield getBtcRpcUrl();
3452
- const res = yield fetch(`${btcRpcUrl}/v1/fees/recommended`).then((res2) => res2.json());
3453
- const feeRate = res.fastestFee;
3454
- return feeRate || defaultFeeRate;
3455
- } catch (error) {
3456
- return defaultFeeRate;
3457
- }
3458
- });
3459
- }
3460
- function getBtcBalance() {
3461
- return __async(this, null, function* () {
3462
- const { account } = yield retryOperation(getBtcProvider, (res) => !!res.account);
3463
- if (!account) {
3464
- console.error("BTC Account is not available.");
3465
- return { rawBalance: 0, balance: 0, maxSpendableBalance: 0 };
3466
- }
3467
- const btcRpcUrl = yield getBtcRpcUrl();
3468
- const utxos = yield fetch(`${btcRpcUrl}/address/${account}/utxo`).then((res) => res.json());
3469
- const rawBalance = (utxos == null ? void 0 : utxos.reduce((acc, cur) => acc + cur.value, 0)) || 0;
3470
- const balance = rawBalance / __pow(10, 8);
3471
- const feeRate = yield getBtcGasPrice();
3472
- const inputSize = ((utxos == null ? void 0 : utxos.length) || 0) * 66;
3473
- const outputSize = 34;
3474
- const overheadSize = 10;
3475
- const estimatedTxSize = inputSize + outputSize + overheadSize;
3476
- const estimatedFee = estimatedTxSize * feeRate / __pow(10, 8);
3477
- console.log("estimated fee:", estimatedFee);
3478
- const availableBalance = Math.max(0, balance - estimatedFee);
3479
- return {
3480
- rawBalance,
3481
- balance,
3482
- availableBalance
3483
- };
3484
- });
3485
- }
3486
- function sendBitcoin(address, amount, feeRate) {
3487
- return __async(this, null, function* () {
3488
- const { sendBitcoin: sendBitcoin2 } = getBtcProvider();
3489
- const txHash = yield sendBitcoin2(address, amount, { feeRate });
3490
- return txHash;
3491
- });
3492
- }
3493
- function estimateDepositAmount(amount, option) {
3494
- return __async(this, null, function* () {
3495
- const config = yield getConfig((option == null ? void 0 : option.isDev) || false);
3496
- const {
3497
- deposit_bridge_fee: { fee_min, fee_rate }
3498
- } = yield nearCall(
3499
- config.bridgeContractId,
3500
- "get_config",
3501
- {}
3502
- );
3503
- const fee = Math.max(Number(fee_min), Number(amount) * fee_rate);
3504
- return new import_big2.default(amount).minus(fee).toFixed(0);
3505
- });
3506
- }
3507
- function executeBTCDepositAndAction(_0) {
3508
- return __async(this, arguments, function* ({
3509
- action,
3510
- feeRate,
3511
- isDev = false
3512
- }) {
3513
- try {
3514
- const { getPublicKey } = getBtcProvider();
3515
- const config = yield getConfig(isDev);
3516
- const btcPublicKey = yield getPublicKey();
3517
- const _action = Object.assign(
3518
- {},
3519
- __spreadProps(__spreadValues({}, action), {
3520
- gas: new import_big2.default(100).mul(__pow(10, 12)).toFixed(0)
3521
- })
3522
- );
3523
- if (!btcPublicKey) {
3524
- throw new Error("BTC Public Key is not available.");
3525
- }
3526
- if (!_action.receiver_id) {
3527
- throw new Error("action.receiver_id is required");
3528
- }
3529
- const amountWithFee = yield estimateDepositAmount(_action.amount, {
3530
- isDev
3531
- });
3532
- _action.amount = amountWithFee;
3533
- if (!_action.amount || !new import_big2.default(_action.amount || 0).gt(0)) {
3534
- throw new Error("action.amount is required or deposit amount is not enough");
3535
- }
3536
- const csna = yield nearCall(
3537
- config.accountContractId,
3538
- "get_chain_signature_near_account_id",
3539
- {
3540
- btc_public_key: btcPublicKey
3541
- }
3542
- );
3543
- const depositMsg = {
3544
- recipient_id: csna,
3545
- post_actions: [_action]
3546
- };
3547
- const storageDepositMsg = {};
3548
- const accountInfo = yield nearCall(
3549
- config.accountContractId,
3550
- "get_account",
3551
- {
3552
- account_id: csna
3553
- }
3554
- );
3555
- if (!(accountInfo == null ? void 0 : accountInfo.nonce)) {
3556
- storageDepositMsg.btc_public_key = btcPublicKey;
3557
- }
3558
- const registerRes = yield nearCall(action.receiver_id, "storage_balance_of", {
3559
- account_id: csna
3560
- });
3561
- if (!(registerRes == null ? void 0 : registerRes.available)) {
3562
- storageDepositMsg.storage_deposit_msg = {
3563
- contract_id: action.receiver_id,
3564
- deposit: new import_big2.default(0.25).mul(__pow(10, 24)).toFixed(0),
3565
- registration_only: true
3566
- };
3567
- }
3568
- if (Object.keys(storageDepositMsg).length > 0) {
3569
- depositMsg.extra_msg = JSON.stringify(storageDepositMsg);
3570
- }
3571
- console.log("get_user_deposit_address params:", { deposit_msg: depositMsg });
3572
- const userDepositAddress = yield nearCall(
3573
- config.bridgeContractId,
3574
- "get_user_deposit_address",
3575
- { deposit_msg: depositMsg }
3576
- );
3577
- const _feeRate = feeRate || (yield getBtcGasPrice());
3578
- console.log("user deposit address:", userDepositAddress);
3579
- console.log("deposit amount:", new import_big2.default(action.amount).toNumber());
3580
- console.log("receive amount:", new import_big2.default(_action.amount).toNumber());
3581
- console.log("fee rate:", _feeRate);
3582
- const txHash = yield sendBitcoin(
3583
- userDepositAddress,
3584
- new import_big2.default(action.amount).toNumber(),
3585
- _feeRate
3586
- );
3587
- yield receiveDepositMsg(config.base_url, {
3588
- btcPublicKey,
3589
- txHash,
3590
- postActions: JSON.stringify(depositMsg.post_actions),
3591
- extraMsg: depositMsg.extra_msg
3592
- });
3593
- const checkTransactionStatusRes = yield checkTransactionStatus(config.base_url, txHash);
3594
- console.log("checkTransactionStatus resp:", checkTransactionStatusRes);
3595
- return checkTransactionStatusRes.result_code === 0 ? { result: "success" } : { result: "failed", error: checkTransactionStatusRes.result_message };
3596
- } catch (error) {
3597
- console.error("Error executing Bridge+BurrowSupply:", error);
3598
- return { result: "failed", error: error.message };
3599
- }
3600
- });
3601
- }
3602
-
3603
3884
  // src/index.ts
3604
3885
  var getVersion = () => {
3605
- return "0.3.11";
3886
+ return "0.3.13";
3606
3887
  };
3607
3888
  if (typeof window !== "undefined") {
3608
3889
  window.__PARTICLE_BTC_CONNECT_VERSION = getVersion();