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