btc-wallet 0.3.6 → 0.3.8

Sign up to get free protection for your applications and to get access to all the features.
package/dist/config.d.ts CHANGED
@@ -4,6 +4,7 @@ export declare const walletConfig: Record<string, {
4
4
  accountContractId: string;
5
5
  bridgeContractId: string;
6
6
  walletUrl: string;
7
+ gasTokenLimit: string;
7
8
  }>;
8
9
  export declare const nearRpcUrls: {
9
10
  mainnet: string[];
@@ -1,9 +1,19 @@
1
1
  export declare function getBtcGasPrice(): Promise<number>;
2
2
  export declare function getBtcBalance(): Promise<{
3
+ rawBalance: number;
4
+ balance: number;
5
+ maxSpendableBalance: number;
6
+ availableBalance?: undefined;
7
+ } | {
3
8
  rawBalance: any;
4
9
  balance: number;
10
+ availableBalance: number;
11
+ maxSpendableBalance?: undefined;
5
12
  }>;
6
13
  export declare function sendBitcoin(address: string, amount: number, feeRate: number): Promise<string>;
14
+ export declare function estimateDepositAmount(amount: string, option?: {
15
+ isDev: boolean;
16
+ }): Promise<string>;
7
17
  interface ExecuteBTCDepositAndActionParams {
8
18
  action: {
9
19
  receiver_id: string;
package/dist/index.js CHANGED
@@ -90,6 +90,7 @@ __export(src_exports, {
90
90
  UnisatConnector: () => UnisatConnector,
91
91
  WizzConnector: () => WizzConnector,
92
92
  XverseConnector: () => XverseConnector,
93
+ estimateDepositAmount: () => estimateDepositAmount,
93
94
  executeBTCDepositAndAction: () => executeBTCDepositAndAction,
94
95
  getBtcBalance: () => getBtcBalance,
95
96
  getBtcGasPrice: () => getBtcGasPrice,
@@ -2725,21 +2726,24 @@ var walletConfig = {
2725
2726
  token: "nbtc-dev.testnet",
2726
2727
  accountContractId: "acc-dev.testnet",
2727
2728
  bridgeContractId: "brg-dev.testnet",
2728
- walletUrl: "https://wallet-dev.satoshibridge.top"
2729
+ walletUrl: "https://wallet-dev.satoshibridge.top",
2730
+ gasTokenLimit: "3000"
2729
2731
  },
2730
2732
  testnet: {
2731
2733
  base_url: "https://api.testnet.satoshibridge.top",
2732
2734
  token: "nbtc2-nsp.testnet",
2733
2735
  accountContractId: "dev2-nsp.testnet",
2734
2736
  bridgeContractId: "brg2-nsp.testnet",
2735
- walletUrl: "https://wallet-test.satoshibridge.top"
2737
+ walletUrl: "https://wallet-test.satoshibridge.top",
2738
+ gasTokenLimit: "3000"
2736
2739
  },
2737
2740
  mainnet: {
2738
2741
  base_url: "https://api.mainnet.satoshibridge.top",
2739
2742
  token: "",
2740
2743
  accountContractId: "",
2741
2744
  bridgeContractId: "",
2742
- walletUrl: "https://wallet.satoshibridge.top"
2745
+ walletUrl: "https://wallet.satoshibridge.top",
2746
+ gasTokenLimit: "3000"
2743
2747
  }
2744
2748
  };
2745
2749
  var nearRpcUrls = {
@@ -2883,6 +2887,7 @@ function pollTransactionStatuses(network, hashes) {
2883
2887
  }
2884
2888
 
2885
2889
  // src/core/setupBTCWallet.ts
2890
+ var import_big = __toESM(require("big.js"), 1);
2886
2891
  var { transfer, functionCall } = import_transactions.actionCreators;
2887
2892
  var state = {
2888
2893
  saveAccount(account) {
@@ -3099,6 +3104,10 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3099
3104
  currentConfig.base_url,
3100
3105
  accountId
3101
3106
  );
3107
+ const { transferGasTransaction, useNearPayGas } = yield getGasConfig();
3108
+ if (!useNearPayGas && transferGasTransaction) {
3109
+ params.transactions.unshift(transferGasTransaction);
3110
+ }
3102
3111
  const newTransactions = params.transactions.map((transaction, index) => {
3103
3112
  let nearNonceNumber = accessKey.nonce + BigInt(1);
3104
3113
  if (nearNonceFromApi) {
@@ -3149,19 +3158,10 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3149
3158
  csna: accountId,
3150
3159
  near_transactions: newTransactions.map((t) => t.txHex),
3151
3160
  gas_token: currentConfig.token,
3152
- gas_limit: "3000",
3153
- use_near_pay_gas: false,
3161
+ gas_limit: currentConfig.gasTokenLimit,
3162
+ use_near_pay_gas: useNearPayGas,
3154
3163
  nonce
3155
3164
  };
3156
- const nearAccount = yield provider.query({
3157
- request_type: "view_account",
3158
- account_id: accountId,
3159
- finality: "final"
3160
- });
3161
- const availableBalance = parseFloat(nearAccount.amount) / __pow(10, 24);
3162
- if (availableBalance > 0.2) {
3163
- intention.use_near_pay_gas = true;
3164
- }
3165
3165
  const strIntention = JSON.stringify(intention);
3166
3166
  const signature = yield btcContext.signMessage(strIntention);
3167
3167
  const result = yield uploadBTCTx(currentConfig.base_url, {
@@ -3179,6 +3179,48 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3179
3179
  }
3180
3180
  });
3181
3181
  }
3182
+ function getGasConfig() {
3183
+ return __async(this, null, function* () {
3184
+ const accountId = state.getAccount();
3185
+ const nearAccount = yield provider.query({
3186
+ request_type: "view_account",
3187
+ account_id: accountId,
3188
+ finality: "final"
3189
+ });
3190
+ const availableBalance = parseFloat(nearAccount.amount) / __pow(10, 24);
3191
+ if (availableBalance > 0.2) {
3192
+ return { useNearPayGas: true };
3193
+ } else {
3194
+ const gasTokenBalance = yield nearCall2(currentConfig.token, "ft_balance_of", {
3195
+ account_id: accountId
3196
+ });
3197
+ if (new import_big.default(gasTokenBalance).gt(currentConfig.gasTokenLimit)) {
3198
+ const transferGasTransaction = {
3199
+ signerId: accountId,
3200
+ receiverId: currentConfig.token,
3201
+ actions: [
3202
+ {
3203
+ type: "FunctionCall",
3204
+ params: {
3205
+ methodName: "ft_transfer_call",
3206
+ args: {
3207
+ receiver_id: currentConfig.accountContractId,
3208
+ amount: currentConfig.gasTokenLimit,
3209
+ msg: "Deposit"
3210
+ },
3211
+ gas: new import_big.default(50).mul(__pow(10, 12)).toFixed(0),
3212
+ deposit: "1"
3213
+ }
3214
+ }
3215
+ ]
3216
+ };
3217
+ return { transferGasTransaction, useNearPayGas: false };
3218
+ } else {
3219
+ throw new Error("No enough gas token balance");
3220
+ }
3221
+ }
3222
+ });
3223
+ }
3182
3224
  function initWalletButton(network, wallet2) {
3183
3225
  return __async(this, null, function* () {
3184
3226
  const checkAndSetupWalletButton = () => {
@@ -3248,7 +3290,7 @@ function toHex(originalString) {
3248
3290
  }
3249
3291
 
3250
3292
  // src/core/btcUtils.ts
3251
- var import_big = __toESM(require("big.js"), 1);
3293
+ var import_big2 = __toESM(require("big.js"), 1);
3252
3294
  function getBtcProvider() {
3253
3295
  if (typeof window === "undefined" || !window.btcContext) {
3254
3296
  throw new Error("BTC Provider is not initialized.");
@@ -3268,6 +3310,12 @@ function getBtcRpcUrl() {
3268
3310
  return btcRpcUrls[network];
3269
3311
  });
3270
3312
  }
3313
+ function getConfig(isDev) {
3314
+ return __async(this, null, function* () {
3315
+ const network = yield getNetwork();
3316
+ return walletConfig[isDev ? "dev" : network];
3317
+ });
3318
+ }
3271
3319
  function nearCall(contractId, methodName, args) {
3272
3320
  return __async(this, null, function* () {
3273
3321
  const network = yield getNetwork();
@@ -3322,13 +3370,20 @@ function getBtcBalance() {
3322
3370
  const { account } = yield retryOperation(getBtcProvider, (res2) => !!res2.account);
3323
3371
  if (!account) {
3324
3372
  console.error("BTC Account is not available.");
3325
- return { rawBalance: 0, balance: 0 };
3373
+ return { rawBalance: 0, balance: 0, maxSpendableBalance: 0 };
3326
3374
  }
3327
3375
  const btcRpcUrl = yield getBtcRpcUrl();
3328
3376
  const res = yield fetch(`${btcRpcUrl}/address/${account}/utxo`).then((res2) => res2.json());
3329
3377
  const rawBalance = res == null ? void 0 : res.reduce((acc, cur) => acc + cur.value, 0);
3330
3378
  const balance = rawBalance / __pow(10, 8);
3331
- return { rawBalance, balance };
3379
+ const feeRate = yield getBtcGasPrice();
3380
+ const maxGasFee = feeRate * 250 / __pow(10, 8);
3381
+ const availableBalance = Math.max(0, balance - maxGasFee);
3382
+ return {
3383
+ rawBalance,
3384
+ balance,
3385
+ availableBalance
3386
+ };
3332
3387
  });
3333
3388
  }
3334
3389
  function sendBitcoin(address, amount, feeRate) {
@@ -3338,6 +3393,20 @@ function sendBitcoin(address, amount, feeRate) {
3338
3393
  return txHash;
3339
3394
  });
3340
3395
  }
3396
+ function estimateDepositAmount(amount, option) {
3397
+ return __async(this, null, function* () {
3398
+ const config = yield getConfig((option == null ? void 0 : option.isDev) || false);
3399
+ const {
3400
+ deposit_bridge_fee: { fee_min, fee_rate }
3401
+ } = yield nearCall(
3402
+ config.bridgeContractId,
3403
+ "get_config",
3404
+ {}
3405
+ );
3406
+ const fee = Math.max(Number(fee_min), Number(amount) * fee_rate);
3407
+ return new import_big2.default(amount).minus(fee).toFixed(0);
3408
+ });
3409
+ }
3341
3410
  function executeBTCDepositAndAction(_0) {
3342
3411
  return __async(this, arguments, function* ({
3343
3412
  action,
@@ -3346,18 +3415,26 @@ function executeBTCDepositAndAction(_0) {
3346
3415
  }) {
3347
3416
  try {
3348
3417
  const { getPublicKey } = getBtcProvider();
3349
- const network = yield getNetwork();
3350
- const config = walletConfig[isDev ? "dev" : network];
3418
+ const config = yield getConfig(isDev);
3351
3419
  const btcPublicKey = yield getPublicKey();
3352
- const _action = Object.assign({}, action);
3420
+ const _action = Object.assign(
3421
+ {},
3422
+ __spreadProps(__spreadValues({}, action), {
3423
+ gas: new import_big2.default(100).mul(__pow(10, 12)).toFixed(0)
3424
+ })
3425
+ );
3353
3426
  if (!btcPublicKey) {
3354
3427
  throw new Error("BTC Public Key is not available.");
3355
3428
  }
3356
3429
  if (!_action.receiver_id) {
3357
3430
  throw new Error("action.receiver_id is required");
3358
3431
  }
3359
- if (!_action.amount || !new import_big.default(_action.amount || 0).gt(0)) {
3360
- throw new Error("action.amount is required and must be greater than 0");
3432
+ const amountWithFee = yield estimateDepositAmount(_action.amount, {
3433
+ isDev
3434
+ });
3435
+ _action.amount = amountWithFee;
3436
+ if (!_action.amount || !new import_big2.default(_action.amount || 0).gt(0)) {
3437
+ throw new Error("action.amount is required or deposit amount is not enough");
3361
3438
  }
3362
3439
  const csna = yield nearCall(
3363
3440
  config.accountContractId,
@@ -3366,37 +3443,48 @@ function executeBTCDepositAndAction(_0) {
3366
3443
  btc_public_key: btcPublicKey
3367
3444
  }
3368
3445
  );
3369
- _action.amount = new import_big.default(_action.amount).toString();
3370
- _action.gas = new import_big.default(100).mul(__pow(10, 12)).toFixed(0);
3371
3446
  const depositMsg = {
3372
3447
  recipient_id: csna,
3373
3448
  post_actions: [_action]
3374
3449
  };
3450
+ const storageDepositMsg = {};
3451
+ const accountInfo = yield nearCall(
3452
+ config.accountContractId,
3453
+ "get_account",
3454
+ {
3455
+ account_id: csna
3456
+ }
3457
+ );
3458
+ if (!(accountInfo == null ? void 0 : accountInfo.nonce)) {
3459
+ storageDepositMsg.btc_public_key = btcPublicKey;
3460
+ }
3375
3461
  const registerRes = yield nearCall(action.receiver_id, "storage_balance_of", {
3376
3462
  account_id: csna
3377
3463
  });
3378
3464
  if (!(registerRes == null ? void 0 : registerRes.available)) {
3379
- const storageDepositMsg = {
3380
- storage_deposit_msg: {
3381
- contract_id: action.receiver_id,
3382
- deposit: new import_big.default(0.25).mul(__pow(10, 24)).toFixed(0),
3383
- registration_only: true
3384
- },
3385
- btc_public_key: btcPublicKey
3465
+ storageDepositMsg.storage_deposit_msg = {
3466
+ contract_id: action.receiver_id,
3467
+ deposit: new import_big2.default(0.25).mul(__pow(10, 24)).toFixed(0),
3468
+ registration_only: true
3386
3469
  };
3470
+ }
3471
+ if (Object.keys(storageDepositMsg).length > 0) {
3387
3472
  depositMsg.extra_msg = JSON.stringify(storageDepositMsg);
3388
3473
  }
3389
- console.log("depositMsg", depositMsg);
3474
+ console.log("get_user_deposit_address params:", { deposit_msg: depositMsg });
3390
3475
  const userDepositAddress = yield nearCall(
3391
3476
  config.bridgeContractId,
3392
3477
  "get_user_deposit_address",
3393
3478
  { deposit_msg: depositMsg }
3394
3479
  );
3395
- console.log("userDepositAddress", userDepositAddress);
3396
3480
  const _feeRate = feeRate || (yield getBtcGasPrice());
3481
+ console.log("user deposit address:", userDepositAddress);
3482
+ console.log("deposit amount:", new import_big2.default(action.amount).toNumber());
3483
+ console.log("receive amount:", new import_big2.default(_action.amount).toNumber());
3484
+ console.log("fee rate:", _feeRate);
3397
3485
  const txHash = yield sendBitcoin(
3398
3486
  userDepositAddress,
3399
- new import_big.default(action.amount).toNumber(),
3487
+ new import_big2.default(action.amount).toNumber(),
3400
3488
  _feeRate
3401
3489
  );
3402
3490
  yield receiveDepositMsg(config.base_url, {
@@ -3417,7 +3505,7 @@ function executeBTCDepositAndAction(_0) {
3417
3505
 
3418
3506
  // src/index.ts
3419
3507
  var getVersion = () => {
3420
- return "0.3.6";
3508
+ return "0.3.8";
3421
3509
  };
3422
3510
  if (typeof window !== "undefined") {
3423
3511
  window.__PARTICLE_BTC_CONNECT_VERSION = getVersion();