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.
@@ -0,0 +1,16 @@
1
+ export declare function getBtcGasPrice(): Promise<number>;
2
+ export declare function getBtcBalance(): Promise<{
3
+ rawBalance: any;
4
+ balance: number;
5
+ }>;
6
+ export declare function sendBitcoin(address: string, amount: string, feeRate: number): Promise<string>;
7
+ interface ExecuteBurrowSupplyParams {
8
+ /** btc amount, e.g. 0.01 */
9
+ amount: string;
10
+ /** fee rate, if not provided, will use the recommended fee rate from the btc node */
11
+ feeRate?: number;
12
+ /** is dev environment */
13
+ isDev?: boolean;
14
+ }
15
+ export declare function executeBurrowSupply({ amount, feeRate, isDev, }: ExecuteBurrowSupplyParams): Promise<void>;
16
+ export {};
@@ -5,13 +5,13 @@ export declare function BtcWalletSelectorContextProvider({ children, }: {
5
5
  }): import("react/jsx-runtime").JSX.Element;
6
6
  export declare function useBtcWalletSelector(): {
7
7
  login: () => Promise<string | null>;
8
- autoConnect: () => Promise<null | undefined>;
8
+ autoConnect: () => Promise<void>;
9
9
  logout: () => void;
10
10
  account: string | null;
11
- getPublicKey: () => Promise<any>;
11
+ getPublicKey: () => any;
12
12
  signMessage: (msg: string) => any;
13
13
  getContext: () => any;
14
- getBalance: () => Promise<any>;
14
+ getNetwork: () => Promise<"livenet" | "testnet">;
15
15
  sendBitcoin: (toAddress: string, satoshis: number, options?: {
16
16
  feeRate: number;
17
17
  }) => Promise<string>;
package/dist/index.d.ts CHANGED
@@ -3,5 +3,5 @@ export { ConnectProvider } from './context';
3
3
  export * from './hooks';
4
4
  export * from './core/btcWalletSelectorContext';
5
5
  export * from './core/setupBTCWallet';
6
- export * from './core/bridgeSupplyUtils';
6
+ export * from './core/btcUtils';
7
7
  export declare const getVersion: () => string;
package/dist/index.js CHANGED
@@ -91,7 +91,10 @@ __export(src_exports, {
91
91
  WizzConnector: () => WizzConnector,
92
92
  XverseConnector: () => XverseConnector,
93
93
  executeBurrowSupply: () => executeBurrowSupply,
94
+ getBtcBalance: () => getBtcBalance,
95
+ getBtcGasPrice: () => getBtcGasPrice,
94
96
  getVersion: () => getVersion,
97
+ sendBitcoin: () => sendBitcoin,
95
98
  setupBTCWallet: () => setupBTCWallet,
96
99
  useAccountContract: () => useAccountContract,
97
100
  useAccounts: () => useAccounts,
@@ -320,7 +323,7 @@ var _network, _event;
320
323
  var XverseConnector = class extends BaseConnector {
321
324
  constructor() {
322
325
  super();
323
- __privateAdd(this, _network, "Mainnet");
326
+ __privateAdd(this, _network, "Testnet");
324
327
  __privateAdd(this, _event, new import_events.default());
325
328
  this.metadata = {
326
329
  id: "xverse",
@@ -740,7 +743,16 @@ var useAccounts = () => {
740
743
  // src/hooks/useBTCProvider.ts
741
744
  var import_react = require("react");
742
745
  var useBTCProvider = () => {
743
- const { connector, provider, accounts, getPublicKey, signMessage, getNetwork, switchNetwork, sendBitcoin: sendBitcoin2 } = useConnectProvider();
746
+ const {
747
+ connector,
748
+ provider,
749
+ accounts,
750
+ getPublicKey,
751
+ signMessage,
752
+ getNetwork: getNetwork2,
753
+ switchNetwork,
754
+ sendBitcoin: sendBitcoin2
755
+ } = useConnectProvider();
744
756
  const sendInscription = (0, import_react.useCallback)(
745
757
  (address, inscriptionId, options) => __async(void 0, null, function* () {
746
758
  if (!connector) {
@@ -751,7 +763,17 @@ var useBTCProvider = () => {
751
763
  }),
752
764
  [connector]
753
765
  );
754
- return { provider, accounts, getPublicKey, signMessage, getNetwork, switchNetwork, sendBitcoin: sendBitcoin2, sendInscription, connector };
766
+ return {
767
+ provider,
768
+ accounts,
769
+ getPublicKey,
770
+ signMessage,
771
+ getNetwork: getNetwork2,
772
+ switchNetwork,
773
+ sendBitcoin: sendBitcoin2,
774
+ sendInscription,
775
+ connector
776
+ };
755
777
  };
756
778
 
757
779
  // src/hooks/useConnectModal.ts
@@ -1340,6 +1362,27 @@ var checkBTCVersion = (accountContracts, accountContractKey, version) => {
1340
1362
  return accountContracts[accountContractKey].some((item) => item.version === version);
1341
1363
  };
1342
1364
  var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
1365
+ function retryOperation(_0, _1) {
1366
+ return __async(this, arguments, function* (operation, shouldStop, {
1367
+ maxRetries = 3,
1368
+ delayMs = 1e3
1369
+ } = {}) {
1370
+ let retries = 0;
1371
+ while (retries <= maxRetries) {
1372
+ const result = yield operation();
1373
+ if (shouldStop(result)) {
1374
+ return result;
1375
+ }
1376
+ if (retries === maxRetries) {
1377
+ console.warn("Max retries reached");
1378
+ return result;
1379
+ }
1380
+ retries++;
1381
+ yield delay(delayMs);
1382
+ }
1383
+ throw new Error("Unexpected execution path");
1384
+ });
1385
+ }
1343
1386
 
1344
1387
  // src/utils/ethereumUtils.ts
1345
1388
  var import_util2 = require("@ethereumjs/util");
@@ -2105,7 +2148,7 @@ var ConnectProvider = ({
2105
2148
  }),
2106
2149
  [connector]
2107
2150
  );
2108
- const getNetwork = (0, import_react10.useCallback)(() => __async(void 0, null, function* () {
2151
+ const getNetwork2 = (0, import_react10.useCallback)(() => __async(void 0, null, function* () {
2109
2152
  if (!connector) {
2110
2153
  throw new Error("Wallet not connected!");
2111
2154
  }
@@ -2289,7 +2332,7 @@ var ConnectProvider = ({
2289
2332
  signMessage,
2290
2333
  evmAccount,
2291
2334
  smartAccount,
2292
- getNetwork,
2335
+ getNetwork: getNetwork2,
2293
2336
  switchNetwork,
2294
2337
  sendBitcoin: sendBitcoin2,
2295
2338
  accountContract,
@@ -2443,21 +2486,18 @@ function InitBtcWalletSelectorContext() {
2443
2486
  }
2444
2487
  function useBtcWalletSelector() {
2445
2488
  const { openConnectModal, openConnectModalAsync, disconnect, requestDirectAccount } = useConnectModal();
2446
- const { accounts, sendBitcoin: sendBitcoin2, getPublicKey, provider, signMessage, connector } = useBTCProvider();
2489
+ const { accounts, sendBitcoin: sendBitcoin2, getPublicKey, provider, signMessage, connector, getNetwork: getNetwork2 } = useBTCProvider();
2447
2490
  const publicKey = (0, import_react11.useRef)(null);
2448
2491
  const signMessageFn = (0, import_react11.useRef)(null);
2449
2492
  const connectorRef = (0, import_react11.useRef)(null);
2450
- const providerRef = (0, import_react11.useRef)(null);
2451
- const [updater, setUpdater] = (0, import_react11.useState)(1);
2452
2493
  const context = (0, import_react11.useContext)(WalletSelectorContext);
2453
2494
  (0, import_react11.useEffect)(() => {
2454
2495
  if (provider) {
2455
2496
  getPublicKey().then((res) => {
2456
2497
  publicKey.current = res;
2457
2498
  });
2458
- providerRef.current = provider;
2459
2499
  }
2460
- }, [provider, updater]);
2500
+ }, [provider]);
2461
2501
  (0, import_react11.useEffect)(() => {
2462
2502
  signMessageFn.current = signMessage;
2463
2503
  }, [signMessage]);
@@ -2480,67 +2520,53 @@ function useBtcWalletSelector() {
2480
2520
  }
2481
2521
  };
2482
2522
  }, [connector]);
2483
- return {
2484
- login: () => __async(this, null, function* () {
2485
- const account = accounts && accounts.length ? accounts[0] : null;
2486
- if (account) {
2487
- return account;
2488
- }
2489
- setUpdater(updater + 1);
2490
- if (openConnectModal) {
2491
- yield openConnectModal();
2492
- }
2493
- return null;
2494
- }),
2495
- autoConnect: () => __async(this, null, function* () {
2496
- let times = 0;
2497
- while (!connectorRef.current) {
2498
- yield delay(500);
2499
- if (times++ > 10) {
2500
- return null;
2501
- }
2502
- }
2503
- requestDirectAccount(connectorRef.current).catch((e) => {
2504
- context.emit("btcLoginError");
2505
- });
2506
- }),
2507
- logout: () => {
2508
- const accountId = accounts && accounts.length ? accounts[0] : null;
2509
- if (!accountId)
2510
- return;
2511
- disconnect == null ? void 0 : disconnect();
2512
- context.emit("btcLogOut");
2513
- },
2514
- account: accounts && accounts.length ? accounts[0] : null,
2515
- getPublicKey: () => __async(this, null, function* () {
2516
- let times = 0;
2517
- while (!publicKey.current) {
2518
- yield delay(1e3);
2519
- if (times++ > 10) {
2520
- return null;
2523
+ const hook = (0, import_react11.useMemo)(() => {
2524
+ return {
2525
+ login: () => __async(this, null, function* () {
2526
+ const account = accounts && accounts.length ? accounts[0] : null;
2527
+ if (account) {
2528
+ return account;
2521
2529
  }
2522
- }
2523
- return publicKey.current;
2524
- }),
2525
- signMessage: (msg) => {
2526
- return signMessageFn.current(msg);
2527
- },
2528
- getContext: () => {
2529
- return context;
2530
- },
2531
- getBalance: () => __async(this, null, function* () {
2532
- let times = 0;
2533
- while (!providerRef.current) {
2534
- yield delay(500);
2535
- if (times++ > 10) {
2536
- return null;
2530
+ if (openConnectModal) {
2531
+ yield openConnectModal();
2537
2532
  }
2538
- }
2539
- const { total } = yield providerRef.current.getBalance();
2540
- return total;
2541
- }),
2542
- sendBitcoin: sendBitcoin2
2543
- };
2533
+ return null;
2534
+ }),
2535
+ autoConnect: () => __async(this, null, function* () {
2536
+ requestDirectAccount(connectorRef.current).catch((e) => {
2537
+ context.emit("btcLoginError");
2538
+ });
2539
+ }),
2540
+ logout: () => {
2541
+ const accountId = accounts && accounts.length ? accounts[0] : null;
2542
+ if (!accountId)
2543
+ return;
2544
+ disconnect == null ? void 0 : disconnect();
2545
+ context.emit("btcLogOut");
2546
+ },
2547
+ account: accounts && accounts.length ? accounts[0] : null,
2548
+ getPublicKey: () => {
2549
+ return publicKey.current;
2550
+ },
2551
+ signMessage: (msg) => {
2552
+ return signMessageFn.current(msg);
2553
+ },
2554
+ getContext: () => {
2555
+ return context;
2556
+ },
2557
+ getNetwork: getNetwork2,
2558
+ sendBitcoin: sendBitcoin2
2559
+ };
2560
+ }, [
2561
+ accounts,
2562
+ context,
2563
+ disconnect,
2564
+ getNetwork2,
2565
+ openConnectModal,
2566
+ requestDirectAccount,
2567
+ sendBitcoin2
2568
+ ]);
2569
+ return hook;
2544
2570
  }
2545
2571
 
2546
2572
  // src/core/setupBTCWallet.ts
@@ -2548,7 +2574,7 @@ var import_near_api_js = require("near-api-js");
2548
2574
  var import_transactions = require("@near-js/transactions");
2549
2575
  var import_key_pair = require("near-api-js/lib/utils/key_pair");
2550
2576
  var import_transaction = require("near-api-js/lib/transaction");
2551
- var import_utils6 = require("@near-js/utils");
2577
+ var import_utils5 = require("@near-js/utils");
2552
2578
  var import_bs58 = __toESM(require("bs58"), 1);
2553
2579
  var import_js_sha256 = require("js-sha256");
2554
2580
 
@@ -2946,8 +2972,15 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
2946
2972
  }
2947
2973
  ];
2948
2974
  }
2949
- const btcAccount = yield btcContext.login();
2950
- const btcPublicKey = yield btcContext.getPublicKey();
2975
+ yield btcContext.login();
2976
+ const btcPublicKey = yield retryOperation(btcContext.getPublicKey, (res) => !!res, {
2977
+ maxRetries: 40,
2978
+ delayMs: 3e3
2979
+ });
2980
+ console.log("btcPublicKey:", btcPublicKey);
2981
+ if (!btcPublicKey) {
2982
+ throw new Error("No connected BTC wallet, please connect your BTC wallet first.");
2983
+ }
2951
2984
  const { nearTempAddress, nearTempPublicKey } = yield getNearAccountByBtcPublicKey(btcPublicKey);
2952
2985
  return [
2953
2986
  {
@@ -3040,7 +3073,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3040
3073
  transaction.receiverId,
3041
3074
  BigInt(nearNonceNumber) + BigInt(index),
3042
3075
  newActions,
3043
- (0, import_utils6.baseDecode)(header.hash)
3076
+ (0, import_utils5.baseDecode)(header.hash)
3044
3077
  );
3045
3078
  const txBytes = (0, import_transaction.encodeTransaction)(_transaction);
3046
3079
  const txHex = Array.from(
@@ -3182,11 +3215,31 @@ function pollTransactionStatuses(network, hashes) {
3182
3215
  });
3183
3216
  }
3184
3217
 
3185
- // src/core/bridgeSupplyUtils.ts
3218
+ // src/core/btcUtils.ts
3186
3219
  var import_near_api_js2 = require("near-api-js");
3187
3220
  var import_big = __toESM(require("big.js"), 1);
3188
- function nearViewMethod(contractId, methodName, args, network) {
3221
+ function getBtcProvider() {
3222
+ if (typeof window === "undefined" || !window.btcContext) {
3223
+ throw new Error("BTC Provider is not initialized.");
3224
+ }
3225
+ return window.btcContext;
3226
+ }
3227
+ function getNetwork() {
3189
3228
  return __async(this, null, function* () {
3229
+ const network = yield getBtcProvider().getNetwork();
3230
+ console.log("btc network:", network);
3231
+ return network === "livenet" ? "mainnet" : "testnet";
3232
+ });
3233
+ }
3234
+ function getBtcRpcUrl() {
3235
+ return __async(this, null, function* () {
3236
+ const network = yield getNetwork();
3237
+ return btcRpcUrls[network];
3238
+ });
3239
+ }
3240
+ function nearViewMethod(contractId, methodName, args) {
3241
+ return __async(this, null, function* () {
3242
+ const network = yield getNetwork();
3190
3243
  const nearProvider = new import_near_api_js2.providers.FailoverRpcProvider(
3191
3244
  nearRpcUrls[network].map(
3192
3245
  (url) => new import_near_api_js2.providers.JsonRpcProvider({ url })
@@ -3202,41 +3255,16 @@ function nearViewMethod(contractId, methodName, args, network) {
3202
3255
  return JSON.parse(Buffer.from(res.result).toString());
3203
3256
  });
3204
3257
  }
3205
- function getDepositAddress(btcPublicKey, contractId, network) {
3258
+ function getDepositAddress(btcPublicKey, contractId) {
3206
3259
  return __async(this, null, function* () {
3207
- const res = yield nearViewMethod(
3208
- contractId,
3209
- "get_user_dapp_deposit_address",
3210
- {
3211
- deposit_type: {
3212
- BtcPublicKey: { btc_public_key: btcPublicKey, dapp_operation: "Burrowland->Supply" }
3213
- }
3214
- },
3215
- network
3216
- );
3260
+ const res = yield nearViewMethod(contractId, "get_user_dapp_deposit_address", {
3261
+ deposit_type: {
3262
+ BtcPublicKey: { btc_public_key: btcPublicKey, dapp_operation: "Burrowland->Supply" }
3263
+ }
3264
+ });
3217
3265
  return res;
3218
3266
  });
3219
3267
  }
3220
- function getGasPrice(network) {
3221
- return __async(this, null, function* () {
3222
- const defaultFeeRate = 100;
3223
- try {
3224
- const btcRpcUrl = btcRpcUrls[network];
3225
- const res = yield fetch(`${btcRpcUrl}/v1/fees/recommended`).then((res2) => res2.json());
3226
- const feeRate = res.fastestFee;
3227
- return feeRate || defaultFeeRate;
3228
- } catch (error) {
3229
- return defaultFeeRate;
3230
- }
3231
- });
3232
- }
3233
- function sendBitcoin(btcProvider, address, amount, feeRate) {
3234
- return __async(this, null, function* () {
3235
- const satoshis = new import_big.default(amount).mul(__pow(10, 8)).toNumber();
3236
- const txHash = yield btcProvider.sendBitcoin(address, satoshis, { feeRate });
3237
- return txHash;
3238
- });
3239
- }
3240
3268
  function receiveDepositMsg(_0, _1) {
3241
3269
  return __async(this, arguments, function* (baseUrl, {
3242
3270
  btcPublicKey,
@@ -3261,27 +3289,63 @@ function checkTransactionStatus(baseUrl, txHash) {
3261
3289
  return res;
3262
3290
  });
3263
3291
  }
3292
+ function getBtcGasPrice() {
3293
+ return __async(this, null, function* () {
3294
+ const defaultFeeRate = 100;
3295
+ try {
3296
+ const btcRpcUrl = yield getBtcRpcUrl();
3297
+ const res = yield fetch(`${btcRpcUrl}/v1/fees/recommended`).then((res2) => res2.json());
3298
+ const feeRate = res.fastestFee;
3299
+ return feeRate || defaultFeeRate;
3300
+ } catch (error) {
3301
+ return defaultFeeRate;
3302
+ }
3303
+ });
3304
+ }
3305
+ function getBtcBalance() {
3306
+ return __async(this, null, function* () {
3307
+ var _a;
3308
+ const { account } = yield retryOperation(getBtcProvider, (res2) => !!res2.account);
3309
+ if (!account) {
3310
+ console.error("BTC Account is not available.");
3311
+ return { rawBalance: 0, balance: 0 };
3312
+ }
3313
+ const btcRpcUrl = yield getBtcRpcUrl();
3314
+ const res = yield fetch(`${btcRpcUrl}/address/${account}/utxo`).then((res2) => res2.json());
3315
+ const rawBalance = (_a = res.filter((item) => {
3316
+ var _a2;
3317
+ return (_a2 = item == null ? void 0 : item.status) == null ? void 0 : _a2.confirmed;
3318
+ })) == null ? void 0 : _a.reduce((acc, cur) => acc + cur.value, 0);
3319
+ const balance = rawBalance / __pow(10, 8);
3320
+ return { rawBalance, balance };
3321
+ });
3322
+ }
3323
+ function sendBitcoin(address, amount, feeRate) {
3324
+ return __async(this, null, function* () {
3325
+ const { sendBitcoin: sendBitcoin2 } = getBtcProvider();
3326
+ const satoshis = new import_big.default(amount).mul(__pow(10, 8)).toNumber();
3327
+ const txHash = yield sendBitcoin2(address, satoshis, { feeRate });
3328
+ return txHash;
3329
+ });
3330
+ }
3264
3331
  function executeBurrowSupply(_0) {
3265
3332
  return __async(this, arguments, function* ({
3266
3333
  amount,
3267
3334
  feeRate,
3268
- environment = "mainnet"
3335
+ isDev = false
3269
3336
  }) {
3270
3337
  try {
3271
- if (typeof window === "undefined" || !window.btcContext) {
3272
- throw new Error("BTC Provider is not initialized.");
3273
- }
3274
- const btcProvider = window.btcContext;
3275
- const network = environment === "dev" ? "testnet" : environment;
3276
- const config = walletConfig[environment];
3277
- const btcPublicKey = yield btcProvider.getPublicKey();
3338
+ const { getPublicKey } = getBtcProvider();
3339
+ const network = yield getNetwork();
3340
+ const config = walletConfig[isDev ? "dev" : network];
3341
+ const btcPublicKey = yield getPublicKey();
3278
3342
  if (!btcPublicKey) {
3279
3343
  throw new Error("BTC Public Key is not available.");
3280
3344
  }
3281
- const address = yield getDepositAddress(btcPublicKey, config.contractId, network);
3282
- const _feeRate = feeRate || (yield getGasPrice(network));
3345
+ const address = yield getDepositAddress(btcPublicKey, config.contractId);
3346
+ const _feeRate = feeRate || (yield getBtcGasPrice());
3283
3347
  console.log("feeRate", _feeRate);
3284
- const txHash = yield sendBitcoin(btcProvider, address, amount, _feeRate);
3348
+ const txHash = yield sendBitcoin(address, amount, _feeRate);
3285
3349
  const receiveDepositMsgRes = yield receiveDepositMsg(config.base_url, { btcPublicKey, txHash });
3286
3350
  console.log("receiveDepositMsg resp:", receiveDepositMsgRes);
3287
3351
  const checkTransactionStatusRes = yield checkTransactionStatus(config.base_url, txHash);
@@ -3294,7 +3358,7 @@ function executeBurrowSupply(_0) {
3294
3358
 
3295
3359
  // src/index.ts
3296
3360
  var getVersion = () => {
3297
- return "0.3.3";
3361
+ return "0.3.5";
3298
3362
  };
3299
3363
  if (typeof window !== "undefined") {
3300
3364
  window.__PARTICLE_BTC_CONNECT_VERSION = getVersion();