btc-wallet 0.3.6 → 0.3.8

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/esm/index.js CHANGED
@@ -2686,21 +2686,24 @@ 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"
2689
+ walletUrl: "https://wallet-dev.satoshibridge.top",
2690
+ gasTokenLimit: "3000"
2690
2691
  },
2691
2692
  testnet: {
2692
2693
  base_url: "https://api.testnet.satoshibridge.top",
2693
2694
  token: "nbtc2-nsp.testnet",
2694
2695
  accountContractId: "dev2-nsp.testnet",
2695
2696
  bridgeContractId: "brg2-nsp.testnet",
2696
- walletUrl: "https://wallet-test.satoshibridge.top"
2697
+ walletUrl: "https://wallet-test.satoshibridge.top",
2698
+ gasTokenLimit: "3000"
2697
2699
  },
2698
2700
  mainnet: {
2699
2701
  base_url: "https://api.mainnet.satoshibridge.top",
2700
2702
  token: "",
2701
2703
  accountContractId: "",
2702
2704
  bridgeContractId: "",
2703
- walletUrl: "https://wallet.satoshibridge.top"
2705
+ walletUrl: "https://wallet.satoshibridge.top",
2706
+ gasTokenLimit: "3000"
2704
2707
  }
2705
2708
  };
2706
2709
  var nearRpcUrls = {
@@ -2844,6 +2847,7 @@ function pollTransactionStatuses(network, hashes) {
2844
2847
  }
2845
2848
 
2846
2849
  // src/core/setupBTCWallet.ts
2850
+ import Big from "big.js";
2847
2851
  var { transfer, functionCall } = actionCreators;
2848
2852
  var state = {
2849
2853
  saveAccount(account) {
@@ -3060,6 +3064,10 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3060
3064
  currentConfig.base_url,
3061
3065
  accountId
3062
3066
  );
3067
+ const { transferGasTransaction, useNearPayGas } = yield getGasConfig();
3068
+ if (!useNearPayGas && transferGasTransaction) {
3069
+ params.transactions.unshift(transferGasTransaction);
3070
+ }
3063
3071
  const newTransactions = params.transactions.map((transaction, index) => {
3064
3072
  let nearNonceNumber = accessKey.nonce + BigInt(1);
3065
3073
  if (nearNonceFromApi) {
@@ -3110,19 +3118,10 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3110
3118
  csna: accountId,
3111
3119
  near_transactions: newTransactions.map((t) => t.txHex),
3112
3120
  gas_token: currentConfig.token,
3113
- gas_limit: "3000",
3114
- use_near_pay_gas: false,
3121
+ gas_limit: currentConfig.gasTokenLimit,
3122
+ use_near_pay_gas: useNearPayGas,
3115
3123
  nonce
3116
3124
  };
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
- }
3126
3125
  const strIntention = JSON.stringify(intention);
3127
3126
  const signature = yield btcContext.signMessage(strIntention);
3128
3127
  const result = yield uploadBTCTx(currentConfig.base_url, {
@@ -3140,6 +3139,48 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3140
3139
  }
3141
3140
  });
3142
3141
  }
3142
+ function getGasConfig() {
3143
+ return __async(this, null, function* () {
3144
+ const accountId = state.getAccount();
3145
+ const nearAccount = yield provider.query({
3146
+ request_type: "view_account",
3147
+ account_id: accountId,
3148
+ finality: "final"
3149
+ });
3150
+ const availableBalance = parseFloat(nearAccount.amount) / __pow(10, 24);
3151
+ if (availableBalance > 0.2) {
3152
+ return { useNearPayGas: true };
3153
+ } else {
3154
+ const gasTokenBalance = yield nearCall2(currentConfig.token, "ft_balance_of", {
3155
+ account_id: accountId
3156
+ });
3157
+ if (new Big(gasTokenBalance).gt(currentConfig.gasTokenLimit)) {
3158
+ const transferGasTransaction = {
3159
+ signerId: accountId,
3160
+ receiverId: currentConfig.token,
3161
+ actions: [
3162
+ {
3163
+ type: "FunctionCall",
3164
+ params: {
3165
+ methodName: "ft_transfer_call",
3166
+ args: {
3167
+ receiver_id: currentConfig.accountContractId,
3168
+ amount: currentConfig.gasTokenLimit,
3169
+ msg: "Deposit"
3170
+ },
3171
+ gas: new Big(50).mul(__pow(10, 12)).toFixed(0),
3172
+ deposit: "1"
3173
+ }
3174
+ }
3175
+ ]
3176
+ };
3177
+ return { transferGasTransaction, useNearPayGas: false };
3178
+ } else {
3179
+ throw new Error("No enough gas token balance");
3180
+ }
3181
+ }
3182
+ });
3183
+ }
3143
3184
  function initWalletButton(network, wallet2) {
3144
3185
  return __async(this, null, function* () {
3145
3186
  const checkAndSetupWalletButton = () => {
@@ -3209,7 +3250,7 @@ function toHex(originalString) {
3209
3250
  }
3210
3251
 
3211
3252
  // src/core/btcUtils.ts
3212
- import Big from "big.js";
3253
+ import Big2 from "big.js";
3213
3254
  function getBtcProvider() {
3214
3255
  if (typeof window === "undefined" || !window.btcContext) {
3215
3256
  throw new Error("BTC Provider is not initialized.");
@@ -3229,6 +3270,12 @@ function getBtcRpcUrl() {
3229
3270
  return btcRpcUrls[network];
3230
3271
  });
3231
3272
  }
3273
+ function getConfig(isDev) {
3274
+ return __async(this, null, function* () {
3275
+ const network = yield getNetwork();
3276
+ return walletConfig[isDev ? "dev" : network];
3277
+ });
3278
+ }
3232
3279
  function nearCall(contractId, methodName, args) {
3233
3280
  return __async(this, null, function* () {
3234
3281
  const network = yield getNetwork();
@@ -3283,13 +3330,20 @@ function getBtcBalance() {
3283
3330
  const { account } = yield retryOperation(getBtcProvider, (res2) => !!res2.account);
3284
3331
  if (!account) {
3285
3332
  console.error("BTC Account is not available.");
3286
- return { rawBalance: 0, balance: 0 };
3333
+ return { rawBalance: 0, balance: 0, maxSpendableBalance: 0 };
3287
3334
  }
3288
3335
  const btcRpcUrl = yield getBtcRpcUrl();
3289
3336
  const res = yield fetch(`${btcRpcUrl}/address/${account}/utxo`).then((res2) => res2.json());
3290
3337
  const rawBalance = res == null ? void 0 : res.reduce((acc, cur) => acc + cur.value, 0);
3291
3338
  const balance = rawBalance / __pow(10, 8);
3292
- return { rawBalance, balance };
3339
+ const feeRate = yield getBtcGasPrice();
3340
+ const maxGasFee = feeRate * 250 / __pow(10, 8);
3341
+ const availableBalance = Math.max(0, balance - maxGasFee);
3342
+ return {
3343
+ rawBalance,
3344
+ balance,
3345
+ availableBalance
3346
+ };
3293
3347
  });
3294
3348
  }
3295
3349
  function sendBitcoin(address, amount, feeRate) {
@@ -3299,6 +3353,20 @@ function sendBitcoin(address, amount, feeRate) {
3299
3353
  return txHash;
3300
3354
  });
3301
3355
  }
3356
+ function estimateDepositAmount(amount, option) {
3357
+ return __async(this, null, function* () {
3358
+ const config = yield getConfig((option == null ? void 0 : option.isDev) || false);
3359
+ const {
3360
+ deposit_bridge_fee: { fee_min, fee_rate }
3361
+ } = yield nearCall(
3362
+ config.bridgeContractId,
3363
+ "get_config",
3364
+ {}
3365
+ );
3366
+ const fee = Math.max(Number(fee_min), Number(amount) * fee_rate);
3367
+ return new Big2(amount).minus(fee).toFixed(0);
3368
+ });
3369
+ }
3302
3370
  function executeBTCDepositAndAction(_0) {
3303
3371
  return __async(this, arguments, function* ({
3304
3372
  action,
@@ -3307,18 +3375,26 @@ function executeBTCDepositAndAction(_0) {
3307
3375
  }) {
3308
3376
  try {
3309
3377
  const { getPublicKey } = getBtcProvider();
3310
- const network = yield getNetwork();
3311
- const config = walletConfig[isDev ? "dev" : network];
3378
+ const config = yield getConfig(isDev);
3312
3379
  const btcPublicKey = yield getPublicKey();
3313
- const _action = Object.assign({}, action);
3380
+ const _action = Object.assign(
3381
+ {},
3382
+ __spreadProps(__spreadValues({}, action), {
3383
+ gas: new Big2(100).mul(__pow(10, 12)).toFixed(0)
3384
+ })
3385
+ );
3314
3386
  if (!btcPublicKey) {
3315
3387
  throw new Error("BTC Public Key is not available.");
3316
3388
  }
3317
3389
  if (!_action.receiver_id) {
3318
3390
  throw new Error("action.receiver_id is required");
3319
3391
  }
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");
3392
+ const amountWithFee = yield estimateDepositAmount(_action.amount, {
3393
+ isDev
3394
+ });
3395
+ _action.amount = amountWithFee;
3396
+ if (!_action.amount || !new Big2(_action.amount || 0).gt(0)) {
3397
+ throw new Error("action.amount is required or deposit amount is not enough");
3322
3398
  }
3323
3399
  const csna = yield nearCall(
3324
3400
  config.accountContractId,
@@ -3327,37 +3403,48 @@ function executeBTCDepositAndAction(_0) {
3327
3403
  btc_public_key: btcPublicKey
3328
3404
  }
3329
3405
  );
3330
- _action.amount = new Big(_action.amount).toString();
3331
- _action.gas = new Big(100).mul(__pow(10, 12)).toFixed(0);
3332
3406
  const depositMsg = {
3333
3407
  recipient_id: csna,
3334
3408
  post_actions: [_action]
3335
3409
  };
3410
+ const storageDepositMsg = {};
3411
+ const accountInfo = yield nearCall(
3412
+ config.accountContractId,
3413
+ "get_account",
3414
+ {
3415
+ account_id: csna
3416
+ }
3417
+ );
3418
+ if (!(accountInfo == null ? void 0 : accountInfo.nonce)) {
3419
+ storageDepositMsg.btc_public_key = btcPublicKey;
3420
+ }
3336
3421
  const registerRes = yield nearCall(action.receiver_id, "storage_balance_of", {
3337
3422
  account_id: csna
3338
3423
  });
3339
3424
  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
3425
+ storageDepositMsg.storage_deposit_msg = {
3426
+ contract_id: action.receiver_id,
3427
+ deposit: new Big2(0.25).mul(__pow(10, 24)).toFixed(0),
3428
+ registration_only: true
3347
3429
  };
3430
+ }
3431
+ if (Object.keys(storageDepositMsg).length > 0) {
3348
3432
  depositMsg.extra_msg = JSON.stringify(storageDepositMsg);
3349
3433
  }
3350
- console.log("depositMsg", depositMsg);
3434
+ console.log("get_user_deposit_address params:", { deposit_msg: depositMsg });
3351
3435
  const userDepositAddress = yield nearCall(
3352
3436
  config.bridgeContractId,
3353
3437
  "get_user_deposit_address",
3354
3438
  { deposit_msg: depositMsg }
3355
3439
  );
3356
- console.log("userDepositAddress", userDepositAddress);
3357
3440
  const _feeRate = feeRate || (yield getBtcGasPrice());
3441
+ console.log("user deposit address:", userDepositAddress);
3442
+ console.log("deposit amount:", new Big2(action.amount).toNumber());
3443
+ console.log("receive amount:", new Big2(_action.amount).toNumber());
3444
+ console.log("fee rate:", _feeRate);
3358
3445
  const txHash = yield sendBitcoin(
3359
3446
  userDepositAddress,
3360
- new Big(action.amount).toNumber(),
3447
+ new Big2(action.amount).toNumber(),
3361
3448
  _feeRate
3362
3449
  );
3363
3450
  yield receiveDepositMsg(config.base_url, {
@@ -3378,7 +3465,7 @@ function executeBTCDepositAndAction(_0) {
3378
3465
 
3379
3466
  // src/index.ts
3380
3467
  var getVersion = () => {
3381
- return "0.3.6";
3468
+ return "0.3.8";
3382
3469
  };
3383
3470
  if (typeof window !== "undefined") {
3384
3471
  window.__PARTICLE_BTC_CONNECT_VERSION = getVersion();
@@ -3396,6 +3483,7 @@ export {
3396
3483
  UnisatConnector,
3397
3484
  WizzConnector,
3398
3485
  XverseConnector,
3486
+ estimateDepositAmount,
3399
3487
  executeBTCDepositAndAction,
3400
3488
  getBtcBalance,
3401
3489
  getBtcGasPrice,