btc-wallet 0.3.11 → 0.3.13

Sign up to get free protection for your applications and to get access to all the features.
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();