btc-wallet 0.3.3 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,3 +5,7 @@ export declare const defaultTokenIcon = "https://static.particle.network/token-l
5
5
  export declare const ipfsToSrc: (ipfs: string) => string;
6
6
  export declare const checkBTCVersion: (accountContracts: AAOptions["accountContracts"], accountContractKey: string, version: string) => boolean;
7
7
  export declare const delay: (ms: number) => Promise<unknown>;
8
+ export declare function retryOperation<T>(operation: () => Promise<T> | T, shouldStop: (result: T) => boolean, { maxRetries, delayMs, }?: {
9
+ maxRetries?: number;
10
+ delayMs?: number;
11
+ }): Promise<T>;
@@ -7,5 +7,5 @@ interface RequestOptions<T> extends RequestInit {
7
7
  maxPollingAttempts?: number;
8
8
  shouldStopPolling?: (response: T) => boolean;
9
9
  }
10
- export default function request<T>(url: string, options?: RequestOptions<T>): Promise<T>;
10
+ export default function request<T = any>(url: string, options?: RequestOptions<T>): Promise<T>;
11
11
  export {};
package/esm/index.js CHANGED
@@ -270,7 +270,7 @@ var _network, _event;
270
270
  var XverseConnector = class extends BaseConnector {
271
271
  constructor() {
272
272
  super();
273
- __privateAdd(this, _network, "Mainnet");
273
+ __privateAdd(this, _network, "Testnet");
274
274
  __privateAdd(this, _event, new EventEmitter());
275
275
  this.metadata = {
276
276
  id: "xverse",
@@ -690,7 +690,16 @@ var useAccounts = () => {
690
690
  // src/hooks/useBTCProvider.ts
691
691
  import { useCallback } from "react";
692
692
  var useBTCProvider = () => {
693
- const { connector, provider, accounts, getPublicKey, signMessage, getNetwork, switchNetwork, sendBitcoin: sendBitcoin2 } = useConnectProvider();
693
+ const {
694
+ connector,
695
+ provider,
696
+ accounts,
697
+ getPublicKey,
698
+ signMessage,
699
+ getNetwork: getNetwork2,
700
+ switchNetwork,
701
+ sendBitcoin: sendBitcoin2
702
+ } = useConnectProvider();
694
703
  const sendInscription = useCallback(
695
704
  (address, inscriptionId, options) => __async(void 0, null, function* () {
696
705
  if (!connector) {
@@ -701,7 +710,17 @@ var useBTCProvider = () => {
701
710
  }),
702
711
  [connector]
703
712
  );
704
- return { provider, accounts, getPublicKey, signMessage, getNetwork, switchNetwork, sendBitcoin: sendBitcoin2, sendInscription, connector };
713
+ return {
714
+ provider,
715
+ accounts,
716
+ getPublicKey,
717
+ signMessage,
718
+ getNetwork: getNetwork2,
719
+ switchNetwork,
720
+ sendBitcoin: sendBitcoin2,
721
+ sendInscription,
722
+ connector
723
+ };
705
724
  };
706
725
 
707
726
  // src/hooks/useConnectModal.ts
@@ -1290,6 +1309,27 @@ var checkBTCVersion = (accountContracts, accountContractKey, version) => {
1290
1309
  return accountContracts[accountContractKey].some((item) => item.version === version);
1291
1310
  };
1292
1311
  var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
1312
+ function retryOperation(_0, _1) {
1313
+ return __async(this, arguments, function* (operation, shouldStop, {
1314
+ maxRetries = 3,
1315
+ delayMs = 1e3
1316
+ } = {}) {
1317
+ let retries = 0;
1318
+ while (retries <= maxRetries) {
1319
+ const result = yield operation();
1320
+ if (shouldStop(result)) {
1321
+ return result;
1322
+ }
1323
+ if (retries === maxRetries) {
1324
+ console.warn("Max retries reached");
1325
+ return result;
1326
+ }
1327
+ retries++;
1328
+ yield delay(delayMs);
1329
+ }
1330
+ throw new Error("Unexpected execution path");
1331
+ });
1332
+ }
1293
1333
 
1294
1334
  // src/utils/ethereumUtils.ts
1295
1335
  import {
@@ -2069,7 +2109,7 @@ var ConnectProvider = ({
2069
2109
  }),
2070
2110
  [connector]
2071
2111
  );
2072
- const getNetwork = useCallback7(() => __async(void 0, null, function* () {
2112
+ const getNetwork2 = useCallback7(() => __async(void 0, null, function* () {
2073
2113
  if (!connector) {
2074
2114
  throw new Error("Wallet not connected!");
2075
2115
  }
@@ -2253,7 +2293,7 @@ var ConnectProvider = ({
2253
2293
  signMessage,
2254
2294
  evmAccount,
2255
2295
  smartAccount,
2256
- getNetwork,
2296
+ getNetwork: getNetwork2,
2257
2297
  switchNetwork,
2258
2298
  sendBitcoin: sendBitcoin2,
2259
2299
  accountContract,
@@ -2407,21 +2447,18 @@ function InitBtcWalletSelectorContext() {
2407
2447
  }
2408
2448
  function useBtcWalletSelector() {
2409
2449
  const { openConnectModal, openConnectModalAsync, disconnect, requestDirectAccount } = useConnectModal();
2410
- const { accounts, sendBitcoin: sendBitcoin2, getPublicKey, provider, signMessage, connector } = useBTCProvider();
2450
+ const { accounts, sendBitcoin: sendBitcoin2, getPublicKey, provider, signMessage, connector, getNetwork: getNetwork2 } = useBTCProvider();
2411
2451
  const publicKey = useRef(null);
2412
2452
  const signMessageFn = useRef(null);
2413
2453
  const connectorRef = useRef(null);
2414
- const providerRef = useRef(null);
2415
- const [updater, setUpdater] = useState8(1);
2416
2454
  const context = useContext2(WalletSelectorContext);
2417
2455
  useEffect6(() => {
2418
2456
  if (provider) {
2419
2457
  getPublicKey().then((res) => {
2420
2458
  publicKey.current = res;
2421
2459
  });
2422
- providerRef.current = provider;
2423
2460
  }
2424
- }, [provider, updater]);
2461
+ }, [provider]);
2425
2462
  useEffect6(() => {
2426
2463
  signMessageFn.current = signMessage;
2427
2464
  }, [signMessage]);
@@ -2444,67 +2481,53 @@ function useBtcWalletSelector() {
2444
2481
  }
2445
2482
  };
2446
2483
  }, [connector]);
2447
- return {
2448
- login: () => __async(this, null, function* () {
2449
- const account = accounts && accounts.length ? accounts[0] : null;
2450
- if (account) {
2451
- return account;
2452
- }
2453
- setUpdater(updater + 1);
2454
- if (openConnectModal) {
2455
- yield openConnectModal();
2456
- }
2457
- return null;
2458
- }),
2459
- autoConnect: () => __async(this, null, function* () {
2460
- let times = 0;
2461
- while (!connectorRef.current) {
2462
- yield delay(500);
2463
- if (times++ > 10) {
2464
- return null;
2465
- }
2466
- }
2467
- requestDirectAccount(connectorRef.current).catch((e) => {
2468
- context.emit("btcLoginError");
2469
- });
2470
- }),
2471
- logout: () => {
2472
- const accountId = accounts && accounts.length ? accounts[0] : null;
2473
- if (!accountId)
2474
- return;
2475
- disconnect == null ? void 0 : disconnect();
2476
- context.emit("btcLogOut");
2477
- },
2478
- account: accounts && accounts.length ? accounts[0] : null,
2479
- getPublicKey: () => __async(this, null, function* () {
2480
- let times = 0;
2481
- while (!publicKey.current) {
2482
- yield delay(1e3);
2483
- if (times++ > 10) {
2484
- return null;
2484
+ const hook = useMemo6(() => {
2485
+ return {
2486
+ login: () => __async(this, null, function* () {
2487
+ const account = accounts && accounts.length ? accounts[0] : null;
2488
+ if (account) {
2489
+ return account;
2485
2490
  }
2486
- }
2487
- return publicKey.current;
2488
- }),
2489
- signMessage: (msg) => {
2490
- return signMessageFn.current(msg);
2491
- },
2492
- getContext: () => {
2493
- return context;
2494
- },
2495
- getBalance: () => __async(this, null, function* () {
2496
- let times = 0;
2497
- while (!providerRef.current) {
2498
- yield delay(500);
2499
- if (times++ > 10) {
2500
- return null;
2491
+ if (openConnectModal) {
2492
+ yield openConnectModal();
2501
2493
  }
2502
- }
2503
- const { total } = yield providerRef.current.getBalance();
2504
- return total;
2505
- }),
2506
- sendBitcoin: sendBitcoin2
2507
- };
2494
+ return null;
2495
+ }),
2496
+ autoConnect: () => __async(this, null, function* () {
2497
+ requestDirectAccount(connectorRef.current).catch((e) => {
2498
+ context.emit("btcLoginError");
2499
+ });
2500
+ }),
2501
+ logout: () => {
2502
+ const accountId = accounts && accounts.length ? accounts[0] : null;
2503
+ if (!accountId)
2504
+ return;
2505
+ disconnect == null ? void 0 : disconnect();
2506
+ context.emit("btcLogOut");
2507
+ },
2508
+ account: accounts && accounts.length ? accounts[0] : null,
2509
+ getPublicKey: () => {
2510
+ return publicKey.current;
2511
+ },
2512
+ signMessage: (msg) => {
2513
+ return signMessageFn.current(msg);
2514
+ },
2515
+ getContext: () => {
2516
+ return context;
2517
+ },
2518
+ getNetwork: getNetwork2,
2519
+ sendBitcoin: sendBitcoin2
2520
+ };
2521
+ }, [
2522
+ accounts,
2523
+ context,
2524
+ disconnect,
2525
+ getNetwork2,
2526
+ openConnectModal,
2527
+ requestDirectAccount,
2528
+ sendBitcoin2
2529
+ ]);
2530
+ return hook;
2508
2531
  }
2509
2532
 
2510
2533
  // src/core/setupBTCWallet.ts
@@ -2910,8 +2933,15 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
2910
2933
  }
2911
2934
  ];
2912
2935
  }
2913
- const btcAccount = yield btcContext.login();
2914
- const btcPublicKey = yield btcContext.getPublicKey();
2936
+ yield btcContext.login();
2937
+ const btcPublicKey = yield retryOperation(btcContext.getPublicKey, (res) => !!res, {
2938
+ maxRetries: 40,
2939
+ delayMs: 3e3
2940
+ });
2941
+ console.log("btcPublicKey:", btcPublicKey);
2942
+ if (!btcPublicKey) {
2943
+ throw new Error("No connected BTC wallet, please connect your BTC wallet first.");
2944
+ }
2915
2945
  const { nearTempAddress, nearTempPublicKey } = yield getNearAccountByBtcPublicKey(btcPublicKey);
2916
2946
  return [
2917
2947
  {
@@ -3146,11 +3176,31 @@ function pollTransactionStatuses(network, hashes) {
3146
3176
  });
3147
3177
  }
3148
3178
 
3149
- // src/core/bridgeSupplyUtils.ts
3179
+ // src/core/btcUtils.ts
3150
3180
  import { providers as providers2 } from "near-api-js";
3151
3181
  import Big from "big.js";
3152
- function nearViewMethod(contractId, methodName, args, network) {
3182
+ function getBtcProvider() {
3183
+ if (typeof window === "undefined" || !window.btcContext) {
3184
+ throw new Error("BTC Provider is not initialized.");
3185
+ }
3186
+ return window.btcContext;
3187
+ }
3188
+ function getNetwork() {
3153
3189
  return __async(this, null, function* () {
3190
+ const network = yield getBtcProvider().getNetwork();
3191
+ console.log("btc network:", network);
3192
+ return network === "livenet" ? "mainnet" : "testnet";
3193
+ });
3194
+ }
3195
+ function getBtcRpcUrl() {
3196
+ return __async(this, null, function* () {
3197
+ const network = yield getNetwork();
3198
+ return btcRpcUrls[network];
3199
+ });
3200
+ }
3201
+ function nearViewMethod(contractId, methodName, args) {
3202
+ return __async(this, null, function* () {
3203
+ const network = yield getNetwork();
3154
3204
  const nearProvider = new providers2.FailoverRpcProvider(
3155
3205
  nearRpcUrls[network].map(
3156
3206
  (url) => new providers2.JsonRpcProvider({ url })
@@ -3166,41 +3216,16 @@ function nearViewMethod(contractId, methodName, args, network) {
3166
3216
  return JSON.parse(Buffer.from(res.result).toString());
3167
3217
  });
3168
3218
  }
3169
- function getDepositAddress(btcPublicKey, contractId, network) {
3219
+ function getDepositAddress(btcPublicKey, contractId) {
3170
3220
  return __async(this, null, function* () {
3171
- const res = yield nearViewMethod(
3172
- contractId,
3173
- "get_user_dapp_deposit_address",
3174
- {
3175
- deposit_type: {
3176
- BtcPublicKey: { btc_public_key: btcPublicKey, dapp_operation: "Burrowland->Supply" }
3177
- }
3178
- },
3179
- network
3180
- );
3221
+ const res = yield nearViewMethod(contractId, "get_user_dapp_deposit_address", {
3222
+ deposit_type: {
3223
+ BtcPublicKey: { btc_public_key: btcPublicKey, dapp_operation: "Burrowland->Supply" }
3224
+ }
3225
+ });
3181
3226
  return res;
3182
3227
  });
3183
3228
  }
3184
- function getGasPrice(network) {
3185
- return __async(this, null, function* () {
3186
- const defaultFeeRate = 100;
3187
- try {
3188
- const btcRpcUrl = btcRpcUrls[network];
3189
- const res = yield fetch(`${btcRpcUrl}/v1/fees/recommended`).then((res2) => res2.json());
3190
- const feeRate = res.fastestFee;
3191
- return feeRate || defaultFeeRate;
3192
- } catch (error) {
3193
- return defaultFeeRate;
3194
- }
3195
- });
3196
- }
3197
- function sendBitcoin(btcProvider, address, amount, feeRate) {
3198
- return __async(this, null, function* () {
3199
- const satoshis = new Big(amount).mul(__pow(10, 8)).toNumber();
3200
- const txHash = yield btcProvider.sendBitcoin(address, satoshis, { feeRate });
3201
- return txHash;
3202
- });
3203
- }
3204
3229
  function receiveDepositMsg(_0, _1) {
3205
3230
  return __async(this, arguments, function* (baseUrl, {
3206
3231
  btcPublicKey,
@@ -3225,27 +3250,63 @@ function checkTransactionStatus(baseUrl, txHash) {
3225
3250
  return res;
3226
3251
  });
3227
3252
  }
3253
+ function getBtcGasPrice() {
3254
+ return __async(this, null, function* () {
3255
+ const defaultFeeRate = 100;
3256
+ try {
3257
+ const btcRpcUrl = yield getBtcRpcUrl();
3258
+ const res = yield fetch(`${btcRpcUrl}/v1/fees/recommended`).then((res2) => res2.json());
3259
+ const feeRate = res.fastestFee;
3260
+ return feeRate || defaultFeeRate;
3261
+ } catch (error) {
3262
+ return defaultFeeRate;
3263
+ }
3264
+ });
3265
+ }
3266
+ function getBtcBalance() {
3267
+ return __async(this, null, function* () {
3268
+ var _a;
3269
+ const { account } = yield retryOperation(getBtcProvider, (res2) => !!res2.account);
3270
+ if (!account) {
3271
+ console.error("BTC Account is not available.");
3272
+ return { rawBalance: 0, balance: 0 };
3273
+ }
3274
+ const btcRpcUrl = yield getBtcRpcUrl();
3275
+ const res = yield fetch(`${btcRpcUrl}/address/${account}/utxo`).then((res2) => res2.json());
3276
+ const rawBalance = (_a = res.filter((item) => {
3277
+ var _a2;
3278
+ return (_a2 = item == null ? void 0 : item.status) == null ? void 0 : _a2.confirmed;
3279
+ })) == null ? void 0 : _a.reduce((acc, cur) => acc + cur.value, 0);
3280
+ const balance = rawBalance / __pow(10, 8);
3281
+ return { rawBalance, balance };
3282
+ });
3283
+ }
3284
+ function sendBitcoin(address, amount, feeRate) {
3285
+ return __async(this, null, function* () {
3286
+ const { sendBitcoin: sendBitcoin2 } = getBtcProvider();
3287
+ const satoshis = new Big(amount).mul(__pow(10, 8)).toNumber();
3288
+ const txHash = yield sendBitcoin2(address, satoshis, { feeRate });
3289
+ return txHash;
3290
+ });
3291
+ }
3228
3292
  function executeBurrowSupply(_0) {
3229
3293
  return __async(this, arguments, function* ({
3230
3294
  amount,
3231
3295
  feeRate,
3232
- environment = "mainnet"
3296
+ isDev = false
3233
3297
  }) {
3234
3298
  try {
3235
- if (typeof window === "undefined" || !window.btcContext) {
3236
- throw new Error("BTC Provider is not initialized.");
3237
- }
3238
- const btcProvider = window.btcContext;
3239
- const network = environment === "dev" ? "testnet" : environment;
3240
- const config = walletConfig[environment];
3241
- const btcPublicKey = yield btcProvider.getPublicKey();
3299
+ const { getPublicKey } = getBtcProvider();
3300
+ const network = yield getNetwork();
3301
+ const config = walletConfig[isDev ? "dev" : network];
3302
+ const btcPublicKey = yield getPublicKey();
3242
3303
  if (!btcPublicKey) {
3243
3304
  throw new Error("BTC Public Key is not available.");
3244
3305
  }
3245
- const address = yield getDepositAddress(btcPublicKey, config.contractId, network);
3246
- const _feeRate = feeRate || (yield getGasPrice(network));
3306
+ const address = yield getDepositAddress(btcPublicKey, config.contractId);
3307
+ const _feeRate = feeRate || (yield getBtcGasPrice());
3247
3308
  console.log("feeRate", _feeRate);
3248
- const txHash = yield sendBitcoin(btcProvider, address, amount, _feeRate);
3309
+ const txHash = yield sendBitcoin(address, amount, _feeRate);
3249
3310
  const receiveDepositMsgRes = yield receiveDepositMsg(config.base_url, { btcPublicKey, txHash });
3250
3311
  console.log("receiveDepositMsg resp:", receiveDepositMsgRes);
3251
3312
  const checkTransactionStatusRes = yield checkTransactionStatus(config.base_url, txHash);
@@ -3258,7 +3319,7 @@ function executeBurrowSupply(_0) {
3258
3319
 
3259
3320
  // src/index.ts
3260
3321
  var getVersion = () => {
3261
- return "0.3.3";
3322
+ return "0.3.5";
3262
3323
  };
3263
3324
  if (typeof window !== "undefined") {
3264
3325
  window.__PARTICLE_BTC_CONNECT_VERSION = getVersion();
@@ -3277,7 +3338,10 @@ export {
3277
3338
  WizzConnector,
3278
3339
  XverseConnector,
3279
3340
  executeBurrowSupply,
3341
+ getBtcBalance,
3342
+ getBtcGasPrice,
3280
3343
  getVersion,
3344
+ sendBitcoin,
3281
3345
  setupBTCWallet,
3282
3346
  useAccountContract,
3283
3347
  useAccounts,