btc-wallet 0.3.5 → 0.3.6

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.
@@ -0,0 +1,7 @@
1
+ import type { ProviderService } from '@near-wallet-selector/core/src/lib/services';
2
+ import { providers } from 'near-api-js';
3
+ export declare function nearCallFunction<T>(contractId: string, methodName: string, args: any, options: {
4
+ network?: string;
5
+ provider?: ProviderService;
6
+ }): Promise<T>;
7
+ export declare function pollTransactionStatuses(network: string, hashes: string[]): Promise<(providers.FinalExecutionOutcome | undefined)[]>;
package/esm/index.js CHANGED
@@ -2458,7 +2458,7 @@ function useBtcWalletSelector() {
2458
2458
  publicKey.current = res;
2459
2459
  });
2460
2460
  }
2461
- }, [provider]);
2461
+ }, [getPublicKey, provider]);
2462
2462
  useEffect6(() => {
2463
2463
  signMessageFn.current = signMessage;
2464
2464
  }, [signMessage]);
@@ -2480,18 +2480,15 @@ function useBtcWalletSelector() {
2480
2480
  connector.removeListener("accountsChanged", fn);
2481
2481
  }
2482
2482
  };
2483
- }, [connector]);
2483
+ }, [connector, context, getPublicKey]);
2484
2484
  const hook = useMemo6(() => {
2485
2485
  return {
2486
2486
  login: () => __async(this, null, function* () {
2487
- const account = accounts && accounts.length ? accounts[0] : null;
2488
- if (account) {
2489
- return account;
2490
- }
2491
- if (openConnectModal) {
2492
- yield openConnectModal();
2487
+ const account = accounts == null ? void 0 : accounts[0];
2488
+ if (!account) {
2489
+ openConnectModal == null ? void 0 : openConnectModal();
2493
2490
  }
2494
- return null;
2491
+ return account;
2495
2492
  }),
2496
2493
  autoConnect: () => __async(this, null, function* () {
2497
2494
  requestDirectAccount(connectorRef.current).catch((e) => {
@@ -2499,13 +2496,13 @@ function useBtcWalletSelector() {
2499
2496
  });
2500
2497
  }),
2501
2498
  logout: () => {
2502
- const accountId = accounts && accounts.length ? accounts[0] : null;
2499
+ const accountId = accounts == null ? void 0 : accounts[0];
2503
2500
  if (!accountId)
2504
2501
  return;
2505
2502
  disconnect == null ? void 0 : disconnect();
2506
2503
  context.emit("btcLogOut");
2507
2504
  },
2508
- account: accounts && accounts.length ? accounts[0] : null,
2505
+ account: accounts == null ? void 0 : accounts[0],
2509
2506
  getPublicKey: () => {
2510
2507
  return publicKey.current;
2511
2508
  },
@@ -2531,7 +2528,7 @@ function useBtcWalletSelector() {
2531
2528
  }
2532
2529
 
2533
2530
  // src/core/setupBTCWallet.ts
2534
- import { providers, transactions } from "near-api-js";
2531
+ import { transactions } from "near-api-js";
2535
2532
  import { actionCreators } from "@near-js/transactions";
2536
2533
  import { PublicKey } from "near-api-js/lib/utils/key_pair";
2537
2534
  import { encodeTransaction } from "near-api-js/lib/transaction";
@@ -2686,20 +2683,23 @@ function removeWalletButton() {
2686
2683
  var walletConfig = {
2687
2684
  dev: {
2688
2685
  base_url: "https://api.dev.satoshibridge.top",
2689
- token: "nbtc1-nsp.testnet",
2690
- contractId: "dev1-nsp.testnet",
2686
+ token: "nbtc-dev.testnet",
2687
+ accountContractId: "acc-dev.testnet",
2688
+ bridgeContractId: "brg-dev.testnet",
2691
2689
  walletUrl: "https://wallet-dev.satoshibridge.top"
2692
2690
  },
2693
2691
  testnet: {
2694
2692
  base_url: "https://api.testnet.satoshibridge.top",
2695
2693
  token: "nbtc2-nsp.testnet",
2696
- contractId: "dev2-nsp.testnet",
2694
+ accountContractId: "dev2-nsp.testnet",
2695
+ bridgeContractId: "brg2-nsp.testnet",
2697
2696
  walletUrl: "https://wallet-test.satoshibridge.top"
2698
2697
  },
2699
2698
  mainnet: {
2700
2699
  base_url: "https://api.mainnet.satoshibridge.top",
2701
2700
  token: "",
2702
- contractId: "",
2701
+ accountContractId: "",
2702
+ bridgeContractId: "",
2703
2703
  walletUrl: "https://wallet.satoshibridge.top"
2704
2704
  }
2705
2705
  };
@@ -2711,8 +2711,8 @@ var nearRpcUrls = {
2711
2711
  "https://near.drpc.org"
2712
2712
  ],
2713
2713
  testnet: [
2714
- "https://near-testnet.lava.build",
2715
2714
  "https://rpc.testnet.near.org",
2715
+ "https://near-testnet.lava.build",
2716
2716
  "https://near-testnet.drpc.org"
2717
2717
  ]
2718
2718
  };
@@ -2791,6 +2791,58 @@ function request(url, options) {
2791
2791
  });
2792
2792
  }
2793
2793
 
2794
+ // src/utils/nearUtils.ts
2795
+ import { providers } from "near-api-js";
2796
+ function nearCallFunction(contractId, methodName, args, options) {
2797
+ return __async(this, null, function* () {
2798
+ const nearProvider = (options == null ? void 0 : options.provider) || new providers.FailoverRpcProvider(
2799
+ nearRpcUrls[options == null ? void 0 : options.network].map(
2800
+ (url) => new providers.JsonRpcProvider({ url })
2801
+ )
2802
+ );
2803
+ const res = yield nearProvider.query({
2804
+ request_type: "call_function",
2805
+ account_id: contractId,
2806
+ method_name: methodName,
2807
+ args_base64: Buffer.from(JSON.stringify(args)).toString("base64"),
2808
+ finality: "final"
2809
+ });
2810
+ return JSON.parse(Buffer.from(res.result).toString());
2811
+ });
2812
+ }
2813
+ function pollTransactionStatuses(network, hashes) {
2814
+ return __async(this, null, function* () {
2815
+ const provider = new providers.FailoverRpcProvider(
2816
+ Object.values(nearRpcUrls[network]).map(
2817
+ (url) => new providers.JsonRpcProvider({ url })
2818
+ )
2819
+ );
2820
+ const maxAttempts = 3;
2821
+ const pollStatus = (hash) => __async(this, null, function* () {
2822
+ let attempt = 0;
2823
+ while (attempt < maxAttempts) {
2824
+ attempt++;
2825
+ try {
2826
+ const result = yield provider.txStatus(hash, "unused", "FINAL");
2827
+ if (result && result.status) {
2828
+ console.log(`Transaction ${hash} result:`, result);
2829
+ return result;
2830
+ }
2831
+ } catch (error) {
2832
+ console.error(`Failed to fetch transaction status for ${hash}: ${error.message}`);
2833
+ }
2834
+ if (attempt === maxAttempts) {
2835
+ throw new Error(`Transaction not found after max attempts: ${hash}`);
2836
+ }
2837
+ yield delay(1e4);
2838
+ console.log(`RPC request failed for ${hash}, retrying ${maxAttempts - attempt} more times`);
2839
+ }
2840
+ });
2841
+ const results = yield Promise.all(hashes.map((hash) => pollStatus(hash)));
2842
+ return results;
2843
+ });
2844
+ }
2845
+
2794
2846
  // src/core/setupBTCWallet.ts
2795
2847
  var { transfer, functionCall } = actionCreators;
2796
2848
  var state = {
@@ -2888,28 +2940,23 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
2888
2940
  }
2889
2941
  }), 500);
2890
2942
  }
2891
- function viewMethod(_02) {
2892
- return __async(this, arguments, function* ({ method, args = {} }) {
2893
- const res = yield provider.query({
2894
- request_type: "call_function",
2895
- account_id: currentConfig.contractId,
2896
- method_name: method,
2897
- args_base64: Buffer.from(JSON.stringify(args)).toString("base64"),
2898
- finality: "optimistic"
2899
- });
2900
- return JSON.parse(Buffer.from(res.result).toString());
2943
+ function nearCall2(contractId, methodName, args) {
2944
+ return __async(this, null, function* () {
2945
+ return nearCallFunction(contractId, methodName, args, { provider });
2901
2946
  });
2902
2947
  }
2903
2948
  function getNearAccountByBtcPublicKey(btcPublicKey) {
2904
2949
  return __async(this, null, function* () {
2905
- const nearTempAddress = yield viewMethod({
2906
- method: "get_chain_signature_near_account",
2907
- args: { btc_public_key: btcPublicKey }
2908
- });
2909
- const nearTempPublicKey = yield viewMethod({
2910
- method: "get_chain_signature_near_account_public_key",
2911
- args: { btc_public_key: btcPublicKey }
2912
- });
2950
+ const nearTempAddress = yield nearCall2(
2951
+ currentConfig.accountContractId,
2952
+ "get_chain_signature_near_account_id",
2953
+ { btc_public_key: btcPublicKey }
2954
+ );
2955
+ const nearTempPublicKey = yield nearCall2(
2956
+ currentConfig.accountContractId,
2957
+ "get_chain_signature_near_account_public_key",
2958
+ { btc_public_key: btcPublicKey }
2959
+ );
2913
2960
  state.saveAccount(nearTempAddress);
2914
2961
  state.savePublicKey(nearTempPublicKey);
2915
2962
  state.saveBtcPublicKey(btcPublicKey);
@@ -3009,11 +3056,14 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3009
3056
  nonce: BigInt(rawAccessKey.nonce || 0)
3010
3057
  });
3011
3058
  const publicKeyFormat = PublicKey.from(publicKey);
3012
- const nearNonceApi = yield getNearNonceFromApi(currentConfig.base_url, accountId);
3059
+ const { result_data: nearNonceFromApi } = yield getNearNonceFromApi(
3060
+ currentConfig.base_url,
3061
+ accountId
3062
+ );
3013
3063
  const newTransactions = params.transactions.map((transaction, index) => {
3014
3064
  let nearNonceNumber = accessKey.nonce + BigInt(1);
3015
- if (nearNonceApi) {
3016
- nearNonceNumber = BigInt(nearNonceApi.result_data) > nearNonceNumber ? BigInt(nearNonceApi.result_data) : nearNonceNumber;
3065
+ if (nearNonceFromApi) {
3066
+ nearNonceNumber = BigInt(nearNonceFromApi) > nearNonceNumber ? BigInt(nearNonceFromApi) : nearNonceNumber;
3017
3067
  }
3018
3068
  const newActions = transaction.actions.map((action) => {
3019
3069
  switch (action.type) {
@@ -3045,20 +3095,34 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3045
3095
  const hash = bs58.encode(new Uint8Array(sha256.array(txBytes)));
3046
3096
  return { txBytes, txHex, hash };
3047
3097
  });
3048
- const accountInfo = yield viewMethod({
3049
- method: "get_account",
3050
- args: { account_id: accountId }
3051
- });
3052
- const nonceApi = yield getNonceFromApi(currentConfig.base_url, accountId);
3053
- const nonce = Number(nonceApi == null ? void 0 : nonceApi.result_data) > Number(accountInfo.nonce) ? String(nonceApi == null ? void 0 : nonceApi.result_data) : String(accountInfo.nonce);
3098
+ const accountInfo = yield nearCall2(
3099
+ currentConfig.accountContractId,
3100
+ "get_account",
3101
+ { account_id: accountId }
3102
+ );
3103
+ const { result_data: nonceFromApi } = yield getNonceFromApi(
3104
+ currentConfig.base_url,
3105
+ accountId
3106
+ );
3107
+ const nonce = Number(nonceFromApi) > Number(accountInfo.nonce) ? String(nonceFromApi) : String(accountInfo.nonce);
3054
3108
  const intention = {
3055
3109
  chain_id: "397",
3056
3110
  csna: accountId,
3057
3111
  near_transactions: newTransactions.map((t) => t.txHex),
3058
3112
  gas_token: currentConfig.token,
3059
3113
  gas_limit: "3000",
3114
+ use_near_pay_gas: false,
3060
3115
  nonce
3061
3116
  };
3117
+ const nearAccount = yield provider.query({
3118
+ request_type: "view_account",
3119
+ account_id: accountId,
3120
+ finality: "final"
3121
+ });
3122
+ const availableBalance = parseFloat(nearAccount.amount) / __pow(10, 24);
3123
+ if (availableBalance > 0.2) {
3124
+ intention.use_near_pay_gas = true;
3125
+ }
3062
3126
  const strIntention = JSON.stringify(intention);
3063
3127
  const signature = yield btcContext.signMessage(strIntention);
3064
3128
  const result = yield uploadBTCTx(currentConfig.base_url, {
@@ -3143,41 +3207,8 @@ function toHex(originalString) {
3143
3207
  hexString = hexString.replace(/(^0+)/g, "");
3144
3208
  return hexString;
3145
3209
  }
3146
- function pollTransactionStatuses(network, hashes) {
3147
- return __async(this, null, function* () {
3148
- const provider = new providers.FailoverRpcProvider(
3149
- Object.values(nearRpcUrls[network]).map(
3150
- (url) => new providers.JsonRpcProvider({ url })
3151
- )
3152
- );
3153
- const maxAttempts = 3;
3154
- const pollStatus = (hash) => __async(this, null, function* () {
3155
- let attempt = 0;
3156
- while (attempt < maxAttempts) {
3157
- attempt++;
3158
- try {
3159
- const result = yield provider.txStatus(hash, "unused", "FINAL");
3160
- if (result && result.status) {
3161
- console.log(`Transaction ${hash} result:`, result);
3162
- return result;
3163
- }
3164
- } catch (error) {
3165
- console.error(`Failed to fetch transaction status for ${hash}: ${error.message}`);
3166
- }
3167
- if (attempt === maxAttempts) {
3168
- throw new Error(`Transaction not found after max attempts: ${hash}`);
3169
- }
3170
- yield delay(1e4);
3171
- console.log(`RPC request failed for ${hash}, retrying ${maxAttempts - attempt} more times`);
3172
- }
3173
- });
3174
- const results = yield Promise.all(hashes.map((hash) => pollStatus(hash)));
3175
- return results;
3176
- });
3177
- }
3178
3210
 
3179
3211
  // src/core/btcUtils.ts
3180
- import { providers as providers2 } from "near-api-js";
3181
3212
  import Big from "big.js";
3182
3213
  function getBtcProvider() {
3183
3214
  if (typeof window === "undefined" || !window.btcContext) {
@@ -3198,55 +3229,39 @@ function getBtcRpcUrl() {
3198
3229
  return btcRpcUrls[network];
3199
3230
  });
3200
3231
  }
3201
- function nearViewMethod(contractId, methodName, args) {
3232
+ function nearCall(contractId, methodName, args) {
3202
3233
  return __async(this, null, function* () {
3203
3234
  const network = yield getNetwork();
3204
- const nearProvider = new providers2.FailoverRpcProvider(
3205
- nearRpcUrls[network].map(
3206
- (url) => new providers2.JsonRpcProvider({ url })
3207
- )
3208
- );
3209
- const res = yield nearProvider.query({
3210
- request_type: "call_function",
3211
- account_id: contractId,
3212
- method_name: methodName,
3213
- args_base64: Buffer.from(JSON.stringify(args)).toString("base64"),
3214
- finality: "optimistic"
3215
- });
3216
- return JSON.parse(Buffer.from(res.result).toString());
3217
- });
3218
- }
3219
- function getDepositAddress(btcPublicKey, contractId) {
3220
- return __async(this, null, function* () {
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
- });
3226
- return res;
3235
+ return nearCallFunction(contractId, methodName, args, { network });
3227
3236
  });
3228
3237
  }
3229
3238
  function receiveDepositMsg(_0, _1) {
3230
3239
  return __async(this, arguments, function* (baseUrl, {
3231
3240
  btcPublicKey,
3232
3241
  txHash,
3233
- depositType = 1
3242
+ depositType = 1,
3243
+ postActions,
3244
+ extraMsg
3234
3245
  }) {
3235
3246
  const res = yield request(`${baseUrl}/v1/receiveDepositMsg`, {
3236
3247
  method: "POST",
3237
- body: { btcPublicKey, txHash, depositType }
3248
+ body: { btcPublicKey, txHash, depositType, postActions, extraMsg }
3238
3249
  });
3250
+ console.log("receiveDepositMsg resp:", res);
3239
3251
  return res;
3240
3252
  });
3241
3253
  }
3242
3254
  function checkTransactionStatus(baseUrl, txHash) {
3243
3255
  return __async(this, null, function* () {
3244
- const res = yield request(`${baseUrl}/v1/bridgeFromTx?fromTxHash=${txHash}`, {
3245
- timeout: 6e4,
3246
- pollingInterval: 5e3,
3247
- maxPollingAttempts: 10,
3248
- shouldStopPolling: (res2) => res2.result_code === 0
3249
- });
3256
+ const res = yield request(
3257
+ `${baseUrl}/v1/bridgeFromTx?fromTxHash=${txHash}&fromChainId=1`,
3258
+ {
3259
+ timeout: 6e4,
3260
+ pollingInterval: 5e3,
3261
+ maxPollingAttempts: 10,
3262
+ shouldStopPolling: (res2) => res2.result_code === 0
3263
+ }
3264
+ );
3250
3265
  return res;
3251
3266
  });
3252
3267
  }
@@ -3265,7 +3280,6 @@ function getBtcGasPrice() {
3265
3280
  }
3266
3281
  function getBtcBalance() {
3267
3282
  return __async(this, null, function* () {
3268
- var _a;
3269
3283
  const { account } = yield retryOperation(getBtcProvider, (res2) => !!res2.account);
3270
3284
  if (!account) {
3271
3285
  console.error("BTC Account is not available.");
@@ -3273,10 +3287,7 @@ function getBtcBalance() {
3273
3287
  }
3274
3288
  const btcRpcUrl = yield getBtcRpcUrl();
3275
3289
  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);
3290
+ const rawBalance = res == null ? void 0 : res.reduce((acc, cur) => acc + cur.value, 0);
3280
3291
  const balance = rawBalance / __pow(10, 8);
3281
3292
  return { rawBalance, balance };
3282
3293
  });
@@ -3284,14 +3295,13 @@ function getBtcBalance() {
3284
3295
  function sendBitcoin(address, amount, feeRate) {
3285
3296
  return __async(this, null, function* () {
3286
3297
  const { sendBitcoin: sendBitcoin2 } = getBtcProvider();
3287
- const satoshis = new Big(amount).mul(__pow(10, 8)).toNumber();
3288
- const txHash = yield sendBitcoin2(address, satoshis, { feeRate });
3298
+ const txHash = yield sendBitcoin2(address, amount, { feeRate });
3289
3299
  return txHash;
3290
3300
  });
3291
3301
  }
3292
- function executeBurrowSupply(_0) {
3302
+ function executeBTCDepositAndAction(_0) {
3293
3303
  return __async(this, arguments, function* ({
3294
- amount,
3304
+ action,
3295
3305
  feeRate,
3296
3306
  isDev = false
3297
3307
  }) {
@@ -3300,26 +3310,75 @@ function executeBurrowSupply(_0) {
3300
3310
  const network = yield getNetwork();
3301
3311
  const config = walletConfig[isDev ? "dev" : network];
3302
3312
  const btcPublicKey = yield getPublicKey();
3313
+ const _action = Object.assign({}, action);
3303
3314
  if (!btcPublicKey) {
3304
3315
  throw new Error("BTC Public Key is not available.");
3305
3316
  }
3306
- const address = yield getDepositAddress(btcPublicKey, config.contractId);
3317
+ if (!_action.receiver_id) {
3318
+ throw new Error("action.receiver_id is required");
3319
+ }
3320
+ if (!_action.amount || !new Big(_action.amount || 0).gt(0)) {
3321
+ throw new Error("action.amount is required and must be greater than 0");
3322
+ }
3323
+ const csna = yield nearCall(
3324
+ config.accountContractId,
3325
+ "get_chain_signature_near_account_id",
3326
+ {
3327
+ btc_public_key: btcPublicKey
3328
+ }
3329
+ );
3330
+ _action.amount = new Big(_action.amount).toString();
3331
+ _action.gas = new Big(100).mul(__pow(10, 12)).toFixed(0);
3332
+ const depositMsg = {
3333
+ recipient_id: csna,
3334
+ post_actions: [_action]
3335
+ };
3336
+ const registerRes = yield nearCall(action.receiver_id, "storage_balance_of", {
3337
+ account_id: csna
3338
+ });
3339
+ if (!(registerRes == null ? void 0 : registerRes.available)) {
3340
+ const storageDepositMsg = {
3341
+ storage_deposit_msg: {
3342
+ contract_id: action.receiver_id,
3343
+ deposit: new Big(0.25).mul(__pow(10, 24)).toFixed(0),
3344
+ registration_only: true
3345
+ },
3346
+ btc_public_key: btcPublicKey
3347
+ };
3348
+ depositMsg.extra_msg = JSON.stringify(storageDepositMsg);
3349
+ }
3350
+ console.log("depositMsg", depositMsg);
3351
+ const userDepositAddress = yield nearCall(
3352
+ config.bridgeContractId,
3353
+ "get_user_deposit_address",
3354
+ { deposit_msg: depositMsg }
3355
+ );
3356
+ console.log("userDepositAddress", userDepositAddress);
3307
3357
  const _feeRate = feeRate || (yield getBtcGasPrice());
3308
- console.log("feeRate", _feeRate);
3309
- const txHash = yield sendBitcoin(address, amount, _feeRate);
3310
- const receiveDepositMsgRes = yield receiveDepositMsg(config.base_url, { btcPublicKey, txHash });
3311
- console.log("receiveDepositMsg resp:", receiveDepositMsgRes);
3358
+ const txHash = yield sendBitcoin(
3359
+ userDepositAddress,
3360
+ new Big(action.amount).toNumber(),
3361
+ _feeRate
3362
+ );
3363
+ yield receiveDepositMsg(config.base_url, {
3364
+ btcPublicKey,
3365
+ txHash,
3366
+ postActions: JSON.stringify(depositMsg.post_actions),
3367
+ extraMsg: depositMsg.extra_msg || ""
3368
+ });
3312
3369
  const checkTransactionStatusRes = yield checkTransactionStatus(config.base_url, txHash);
3313
3370
  console.log("checkTransactionStatus resp:", checkTransactionStatusRes);
3371
+ return checkTransactionStatusRes.result_code === 0 ? { result: "success" } : { result: "failed", error: checkTransactionStatusRes.result_message };
3314
3372
  } catch (error) {
3315
3373
  console.error("Error executing Bridge+BurrowSupply:", error);
3374
+ return { result: "failed", error: error.message };
3316
3375
  }
3317
3376
  });
3318
3377
  }
3319
3378
 
3320
3379
  // src/index.ts
3321
3380
  var getVersion = () => {
3322
- return "0.3.5";
3381
+ return "0.3.6";
3323
3382
  };
3324
3383
  if (typeof window !== "undefined") {
3325
3384
  window.__PARTICLE_BTC_CONNECT_VERSION = getVersion();
@@ -3337,7 +3396,7 @@ export {
3337
3396
  UnisatConnector,
3338
3397
  WizzConnector,
3339
3398
  XverseConnector,
3340
- executeBurrowSupply,
3399
+ executeBTCDepositAndAction,
3341
3400
  getBtcBalance,
3342
3401
  getBtcGasPrice,
3343
3402
  getVersion,