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/config.d.ts +0 -1
- package/dist/core/btcUtils.d.ts +31 -10
- package/dist/index.js +621 -340
- package/dist/index.js.map +4 -4
- package/dist/utils/Dialog.d.ts +13 -0
- package/dist/utils/request.d.ts +1 -1
- package/dist/utils/satoshi.d.ts +18 -0
- package/esm/index.js +619 -338
- package/esm/index.js.map +4 -4
- package/package.json +1 -1
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
|
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
|
-
|
2897
|
+
throw err;
|
2831
2898
|
}
|
2832
2899
|
});
|
2833
2900
|
}
|
2834
2901
|
|
2835
|
-
// src/utils/
|
2836
|
-
|
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
|
2840
|
-
|
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
|
-
|
2845
|
-
|
2846
|
-
|
2847
|
-
|
2848
|
-
|
2849
|
-
|
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
|
-
|
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
|
2980
|
+
function checkBtcTransactionStatus(url, sig) {
|
2855
2981
|
return __async(this, null, function* () {
|
2856
|
-
const
|
2857
|
-
|
2858
|
-
|
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
|
2862
|
-
|
2863
|
-
const
|
2864
|
-
|
2865
|
-
|
2866
|
-
|
2867
|
-
|
2868
|
-
|
2869
|
-
|
2870
|
-
|
2871
|
-
|
2872
|
-
|
2873
|
-
|
2874
|
-
|
2875
|
-
|
2876
|
-
|
2877
|
-
|
2878
|
-
|
2879
|
-
|
2880
|
-
|
2881
|
-
|
2882
|
-
|
2883
|
-
|
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
|
-
|
2887
|
-
|
2888
|
-
|
2889
|
-
|
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
|
2957
|
-
const
|
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
|
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
|
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
|
-
|
3658
|
+
yield receiveTransaction(currentConfig.base_url, {
|
3129
3659
|
sig: signature,
|
3130
3660
|
btcPubKey: state.getBtcPublicKey(),
|
3131
3661
|
data: toHex(strIntention)
|
3132
3662
|
});
|
3133
|
-
|
3134
|
-
|
3135
|
-
|
3136
|
-
|
3137
|
-
|
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
|
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
|
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
|
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
|
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(((
|
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
|
3749
|
+
const protocolFee = new import_big2.default(perTxFee || "0").mul(convertTx.length).toFixed(0);
|
3235
3750
|
console.log("protocolFee:", protocolFee);
|
3236
|
-
if (new
|
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
|
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
|
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,
|
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.
|
3886
|
+
return "0.3.13";
|
3606
3887
|
};
|
3607
3888
|
if (typeof window !== "undefined") {
|
3608
3889
|
window.__PARTICLE_BTC_CONNECT_VERSION = getVersion();
|