btc-wallet 0.3.32 → 0.3.34

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,7 +10,6 @@ export interface AccountInfo {
10
10
  }
11
11
  export interface DebtInfo {
12
12
  gas_token_id: string;
13
- transfer_amount: string;
14
13
  near_gas_debt_amount: string;
15
14
  protocol_fee_debt_amount: string;
16
15
  }
@@ -67,4 +66,5 @@ interface ExecuteBTCDepositAndActionParams<T extends boolean = true> {
67
66
  */
68
67
  type ExecuteBTCDepositAndActionReturn<T extends boolean> = T extends true ? FinalExecutionOutcome[] : string;
69
68
  export declare function executeBTCDepositAndAction<T extends boolean = true>({ action, amount, feeRate, fixedAmount, pollResult, registerDeposit, env, }: ExecuteBTCDepositAndActionParams<T>): Promise<ExecuteBTCDepositAndActionReturn<T>>;
69
+ export declare function checkSatoshiWhitelist(btcAccountId: string, env?: ENV): Promise<void>;
70
70
  export {};
package/dist/index.js CHANGED
@@ -92,6 +92,7 @@ __export(src_exports, {
92
92
  XverseConnector: () => XverseConnector,
93
93
  checkGasTokenArrears: () => checkGasTokenArrears,
94
94
  checkGasTokenBalance: () => checkGasTokenBalance,
95
+ checkSatoshiWhitelist: () => checkSatoshiWhitelist,
95
96
  estimateDepositAmount: () => estimateDepositAmount,
96
97
  executeBTCDepositAndAction: () => executeBTCDepositAndAction,
97
98
  getAccountInfo: () => getAccountInfo,
@@ -2428,10 +2429,8 @@ function BtcWalletSelectorContextProvider({
2428
2429
  const [isProcessing, setIsProcessing] = (0, import_react11.useState)(false);
2429
2430
  const connectors = [
2430
2431
  new UnisatConnector(),
2431
- new XverseConnector(),
2432
2432
  new OKXConnector(),
2433
- new BitgetConnector(),
2434
- new MagicEdenConnector()
2433
+ new BitgetConnector()
2435
2434
  ];
2436
2435
  const walletSelectorContextValue = (0, import_react11.useMemo)(() => {
2437
2436
  const simpleFn = {};
@@ -2644,7 +2643,7 @@ var walletConfig = {
2644
2643
  accountContractId: "acc.toalice.near",
2645
2644
  bridgeContractId: "brg.toalice.near",
2646
2645
  walletUrl: "https://wallet-stg.satoshibridge.top",
2647
- bridgeUrl: "https://stg.satoshibridge.top/"
2646
+ bridgeUrl: "https://ramp.satos.network/"
2648
2647
  },
2649
2648
  mainnet: {
2650
2649
  base_url: "https://api.mainnet.satoshibridge.top",
@@ -2991,14 +2990,24 @@ function receiveTransaction(url, data) {
2991
2990
  return result_data;
2992
2991
  });
2993
2992
  }
2993
+ function preReceiveDepositMsg(_0, _1) {
2994
+ return __async(this, arguments, function* (url, { btcPublicKey, depositType = 1, postActions, extraMsg }) {
2995
+ const { result_code, result_message, result_data } = yield request(
2996
+ `${url}/v1/preReceiveDepositMsg`,
2997
+ {
2998
+ method: "POST",
2999
+ body: { btcPublicKey, depositType, postActions, extraMsg }
3000
+ }
3001
+ );
3002
+ console.log("preReceiveDepositMsg resp:", { result_code, result_message, result_data });
3003
+ if (result_code !== 0) {
3004
+ throw new Error(result_message);
3005
+ }
3006
+ return result_data;
3007
+ });
3008
+ }
2994
3009
  function receiveDepositMsg(_0, _1) {
2995
- return __async(this, arguments, function* (url, {
2996
- btcPublicKey,
2997
- txHash,
2998
- depositType = 1,
2999
- postActions,
3000
- extraMsg
3001
- }) {
3010
+ return __async(this, arguments, function* (url, { btcPublicKey, txHash, depositType = 1, postActions, extraMsg }) {
3002
3011
  const { result_code, result_message, result_data } = yield request(
3003
3012
  `${url}/v1/receiveDepositMsg`,
3004
3013
  {
@@ -3049,6 +3058,15 @@ function checkBtcTransactionStatus(url, sig) {
3049
3058
  return result_data;
3050
3059
  });
3051
3060
  }
3061
+ function getWhitelist(url) {
3062
+ return __async(this, null, function* () {
3063
+ const data = yield request(`${url}/v1/whitelist/users`).catch((error) => {
3064
+ console.error("getWhitelist error:", error);
3065
+ return [];
3066
+ });
3067
+ return data;
3068
+ });
3069
+ }
3052
3070
 
3053
3071
  // src/utils/Dialog.ts
3054
3072
  var Dialog = class {
@@ -3090,13 +3108,22 @@ var Dialog = class {
3090
3108
  });
3091
3109
  }
3092
3110
  static alert(options) {
3111
+ const messageEl = options.dangerouslyUseHTML ? { dangerouslySetInnerHTML: { __html: options.message } } : { children: options.message };
3093
3112
  return new Promise((resolve) => {
3113
+ var _a;
3094
3114
  this.injectStyles();
3095
3115
  const container = document.createElement("div");
3096
3116
  container.innerHTML = this.template;
3117
+ (_a = container.querySelector(".dialog-overlay")) == null ? void 0 : _a.classList.add("dialog-alert");
3118
+ if (options.closable === false) {
3119
+ const overlay = container.querySelector(".dialog-overlay");
3120
+ overlay.style.pointerEvents = "none";
3121
+ const dialogContainer = container.querySelector(".dialog-container");
3122
+ dialogContainer.style.pointerEvents = "auto";
3123
+ }
3097
3124
  document.body.appendChild(container);
3098
3125
  const titleEl = container.querySelector(".dialog-title");
3099
- const messageEl = container.querySelector(".dialog-message");
3126
+ const messageEl2 = container.querySelector(".dialog-message");
3100
3127
  const confirmBtn = container.querySelector(".dialog-confirm-btn");
3101
3128
  const cancelBtn = container.querySelector(".dialog-cancel-btn");
3102
3129
  if (options.title) {
@@ -3104,9 +3131,15 @@ var Dialog = class {
3104
3131
  } else {
3105
3132
  titleEl.style.display = "none";
3106
3133
  }
3107
- messageEl.textContent = options.message;
3134
+ messageEl2.innerHTML = options.message;
3108
3135
  cancelBtn.style.display = "none";
3136
+ if (options.closable === false) {
3137
+ confirmBtn.style.display = "none";
3138
+ }
3109
3139
  const cleanup = () => {
3140
+ if (options.closable === false) {
3141
+ return;
3142
+ }
3110
3143
  document.body.removeChild(container);
3111
3144
  };
3112
3145
  confirmBtn.addEventListener("click", () => {
@@ -3124,7 +3157,7 @@ Dialog.template = `
3124
3157
  <div class="dialog-message"></div>
3125
3158
  <div class="dialog-buttons">
3126
3159
  <button class="dialog-cancel-btn">Cancel</button>
3127
- <button class="dialog-confirm-btn">Confirm</button>
3160
+ <button class="dialog-confirm-btn">OK</button>
3128
3161
  </div>
3129
3162
  </div>
3130
3163
  </div>
@@ -3168,6 +3201,9 @@ Dialog.style = `
3168
3201
  justify-content: flex-end;
3169
3202
  gap: 12px;
3170
3203
  }
3204
+ .dialog-alert .dialog-buttons {
3205
+ justify-content: center;
3206
+ }
3171
3207
  .dialog-confirm-btn {
3172
3208
  padding: 8px 24px;
3173
3209
  background-color: #ff7a00;
@@ -3292,23 +3328,26 @@ function checkGasTokenBalance(csna, gasToken, minAmount, env) {
3292
3328
  }
3293
3329
  function checkGasTokenArrears(accountInfo, env, autoDeposit) {
3294
3330
  return __async(this, null, function* () {
3295
- var _a, _b, _c, _d;
3296
- if (!((_a = accountInfo == null ? void 0 : accountInfo.debt_info) == null ? void 0 : _a.transfer_amount) || !((_b = accountInfo == null ? void 0 : accountInfo.relayer_fee) == null ? void 0 : _b.amount))
3331
+ var _a, _b, _c;
3332
+ const debtAmount = new import_big.default(((_a = accountInfo == null ? void 0 : accountInfo.debt_info) == null ? void 0 : _a.near_gas_debt_amount) || 0).plus(((_b = accountInfo == null ? void 0 : accountInfo.debt_info) == null ? void 0 : _b.protocol_fee_debt_amount) || 0).toString();
3333
+ const relayerFeeAmount = ((_c = accountInfo == null ? void 0 : accountInfo.relayer_fee) == null ? void 0 : _c.amount) || "0";
3334
+ const hasDebtArrears = new import_big.default(debtAmount).gt(0);
3335
+ const hasRelayerFeeArrears = new import_big.default(relayerFeeAmount).gt(0);
3336
+ if (!hasDebtArrears && !hasRelayerFeeArrears)
3297
3337
  return;
3298
3338
  const config = yield getConfig(env);
3299
- const arrearsType = accountInfo.debt_info.transfer_amount ? "Deposit" : ((_c = accountInfo.relayer_fee) == null ? void 0 : _c.amount) ? "RelayerFee" : void 0;
3300
- const transferAmount = arrearsType === "Deposit" ? accountInfo.debt_info.transfer_amount : (_d = accountInfo.relayer_fee) == null ? void 0 : _d.amount;
3339
+ const transferAmount = hasDebtArrears ? debtAmount : relayerFeeAmount;
3301
3340
  console.log("get_account:", accountInfo);
3302
3341
  const action = {
3303
3342
  receiver_id: config.accountContractId,
3304
3343
  amount: transferAmount,
3305
- msg: JSON.stringify(arrearsType)
3344
+ msg: JSON.stringify(hasDebtArrears ? "Repay" : "RelayerFee")
3306
3345
  };
3307
3346
  if (!autoDeposit)
3308
3347
  return action;
3309
3348
  const confirmed = yield Dialog.confirm({
3310
- title: arrearsType === "Deposit" ? "Has gas token arrears" : "Has relayer fee arrears",
3311
- message: arrearsType === "Deposit" ? "You have gas token arrears, please deposit gas token to continue." : "You have relayer fee arrears, please deposit relayer fee to continue."
3349
+ title: hasDebtArrears ? "Has gas token arrears" : "Has relayer fee arrears",
3350
+ message: hasDebtArrears ? "You have gas token arrears, please deposit gas token to continue." : "You have relayer fee arrears, please deposit relayer fee to continue."
3312
3351
  });
3313
3352
  if (confirmed) {
3314
3353
  yield executeBTCDepositAndAction({ action, env });
@@ -3502,8 +3541,14 @@ function executeBTCDepositAndAction(_0) {
3502
3541
  console.log("user deposit address:", userDepositAddress);
3503
3542
  console.log("send amount:", sendAmount);
3504
3543
  console.log("fee rate:", _feeRate);
3505
- const txHash = yield sendBitcoin(userDepositAddress, Number(sendAmount), _feeRate);
3506
3544
  const postActionsStr = newActions.length > 0 ? JSON.stringify(newActions) : void 0;
3545
+ yield preReceiveDepositMsg(config.base_url, {
3546
+ btcPublicKey,
3547
+ depositType: postActionsStr || depositMsg.extra_msg ? 1 : 0,
3548
+ postActions: postActionsStr,
3549
+ extraMsg: depositMsg.extra_msg
3550
+ });
3551
+ const txHash = yield sendBitcoin(userDepositAddress, Number(sendAmount), _feeRate);
3507
3552
  yield receiveDepositMsg(config.base_url, {
3508
3553
  btcPublicKey,
3509
3554
  txHash,
@@ -3525,6 +3570,28 @@ function executeBTCDepositAndAction(_0) {
3525
3570
  }
3526
3571
  });
3527
3572
  }
3573
+ function checkSatoshiWhitelist(btcAccountId, env = "mainnet") {
3574
+ return __async(this, null, function* () {
3575
+ if (env !== "private_mainnet")
3576
+ return;
3577
+ if (!btcAccountId)
3578
+ return;
3579
+ const config = yield getConfig(env);
3580
+ const whitelist = yield getWhitelist(config.base_url);
3581
+ if (!(whitelist == null ? void 0 : whitelist.length))
3582
+ return;
3583
+ const isWhitelisted = whitelist.includes(btcAccountId);
3584
+ if (!isWhitelisted) {
3585
+ Dialog.alert({
3586
+ title: "Account is not whitelisted",
3587
+ message: `Sorry, you are not whitelisted. Please fill out the form to get whitelisted. <a style="color: #ff7a00; text-decoration: underline;" href="https://forms.gle/rrTP1ZbGU5mRZpHdA" target="_blank">https://forms.gle/rrTP1ZbGU5mRZpHdA</a>`,
3588
+ dangerouslyUseHTML: true,
3589
+ closable: false
3590
+ });
3591
+ throw new Error("Account is not whitelisted");
3592
+ }
3593
+ });
3594
+ }
3528
3595
 
3529
3596
  // src/core/setupBTCWallet.ts
3530
3597
  var { transfer, functionCall } = import_transactions.actionCreators;
@@ -3583,7 +3650,8 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3583
3650
  signMessage,
3584
3651
  isSignedIn,
3585
3652
  signAndSendTransaction,
3586
- signAndSendTransactions
3653
+ signAndSendTransactions,
3654
+ calculateGasLimit
3587
3655
  };
3588
3656
  const env = metadata.env || options.network.networkId || "mainnet";
3589
3657
  const currentConfig = walletConfig[env];
@@ -3596,6 +3664,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3596
3664
  const accountId = state.getAccount();
3597
3665
  const btcContext = window.btcContext;
3598
3666
  if (accountId && btcContext.account) {
3667
+ yield checkSatoshiWhitelist(btcContext.account, env);
3599
3668
  removeWalletButton();
3600
3669
  setupWalletButton(env, wallet, btcContext);
3601
3670
  } else {
@@ -3792,6 +3861,17 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3792
3861
  return result;
3793
3862
  });
3794
3863
  }
3864
+ function calculateGasLimit(params) {
3865
+ return __async(this, null, function* () {
3866
+ const accountId = state.getAccount();
3867
+ const accountInfo = yield getAccountInfo(accountId, currentConfig.accountContractId);
3868
+ const trans = [...params.transactions];
3869
+ console.log("raw trans:", trans);
3870
+ const gasTokenBalance = (accountInfo == null ? void 0 : accountInfo.gas_token[currentConfig.token]) || "0";
3871
+ const { gasLimit } = yield calculateGasStrategy(gasTokenBalance, trans);
3872
+ return gasLimit;
3873
+ });
3874
+ }
3795
3875
  function createGasTokenTransfer(accountId, amount) {
3796
3876
  return __async(this, null, function* () {
3797
3877
  return {
@@ -3845,58 +3925,17 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3845
3925
  }
3846
3926
  function calculateGasStrategy(gasTokenBalance, transactions2) {
3847
3927
  return __async(this, null, function* () {
3848
- var _a;
3849
3928
  const accountId = state.getAccount();
3850
- const nearAccount = yield provider.query({
3851
- request_type: "view_account",
3852
- account_id: accountId,
3853
- finality: "final"
3854
- });
3855
- const availableBalance = parseFloat(nearAccount.amount) / __pow(10, 24);
3856
- console.log("available near balance:", availableBalance);
3857
- console.log("available gas token balance:", gasTokenBalance);
3858
3929
  const convertTx = yield Promise.all(
3859
3930
  transactions2.map((transaction, index) => convertTransactionToTxHex(transaction, index))
3860
3931
  );
3861
- if (availableBalance > 0.2) {
3862
- console.log("near balance is enough, get the protocol fee of each transaction");
3863
- const gasTokens = yield nearCall2(
3864
- currentConfig.accountContractId,
3865
- "list_gas_token",
3866
- { token_ids: [currentConfig.token] }
3867
- );
3868
- console.log("list_gas_token gas tokens:", gasTokens);
3869
- const perTxFee = Math.max(
3870
- Number(((_a = gasTokens[currentConfig.token]) == null ? void 0 : _a.per_tx_protocol_fee) || 0),
3871
- 100
3872
- );
3873
- console.log("perTxFee:", perTxFee);
3874
- const protocolFee = new import_big2.default(perTxFee || "0").mul(convertTx.length).toFixed(0);
3875
- console.log("protocolFee:", protocolFee);
3876
- if (new import_big2.default(gasTokenBalance).gte(protocolFee)) {
3877
- console.log("use near pay gas and enough gas token balance");
3878
- return { useNearPayGas: true, gasLimit: protocolFee };
3879
- } else {
3880
- console.log("use near pay gas and not enough gas token balance");
3881
- const transferTx = yield createGasTokenTransfer(accountId, protocolFee);
3882
- return recalculateGasWithTransfer(transferTx, convertTx, true, perTxFee.toString());
3883
- }
3884
- } else {
3885
- console.log("near balance is not enough, predict the gas token amount required");
3886
- const adjustedGas = yield getPredictedGasAmount(
3887
- currentConfig.accountContractId,
3888
- currentConfig.token,
3889
- convertTx.map((t) => t.txHex)
3890
- );
3891
- if (new import_big2.default(gasTokenBalance).gte(adjustedGas)) {
3892
- console.log("use gas token and gas token balance is enough");
3893
- return { useNearPayGas: false, gasLimit: adjustedGas };
3894
- } else {
3895
- console.log("use gas token and gas token balance is not enough, need to transfer");
3896
- const transferTx = yield createGasTokenTransfer(accountId, adjustedGas);
3897
- return recalculateGasWithTransfer(transferTx, convertTx, false);
3898
- }
3899
- }
3932
+ const adjustedGas = yield getPredictedGasAmount(
3933
+ currentConfig.accountContractId,
3934
+ currentConfig.token,
3935
+ convertTx.map((t) => t.txHex)
3936
+ );
3937
+ const transferTx = yield createGasTokenTransfer(accountId, adjustedGas);
3938
+ return recalculateGasWithTransfer(transferTx, convertTx, false);
3900
3939
  });
3901
3940
  }
3902
3941
  function convertTransactionToTxHex(transaction, index = 0) {
@@ -3912,9 +3951,12 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3912
3951
  account_id: accountId,
3913
3952
  public_key: publicKey,
3914
3953
  finality: "final"
3954
+ }).catch((e) => {
3955
+ console.log("view_access_key error:", e);
3956
+ return void 0;
3915
3957
  });
3916
3958
  const accessKey = __spreadProps(__spreadValues({}, rawAccessKey), {
3917
- nonce: BigInt(rawAccessKey.nonce || 0)
3959
+ nonce: BigInt((rawAccessKey == null ? void 0 : rawAccessKey.nonce) || 0)
3918
3960
  });
3919
3961
  const nearNonceFromApi = yield getNearNonce(currentConfig.base_url, accountId);
3920
3962
  let nearNonceNumber = accessKey.nonce + BigInt(1);
@@ -3975,6 +4017,18 @@ function setupBTCWallet({
3975
4017
  env = "mainnet"
3976
4018
  } = {}) {
3977
4019
  console.log("\u26A1\uFE0F BTC Wallet Version:", getVersion(), "env:", env);
4020
+ if (env === "private_mainnet" && typeof window !== "undefined") {
4021
+ setTimeout(() => {
4022
+ const hasShownNotice = localStorage.getItem("satoshi_private_mainnet_notice");
4023
+ if (!hasShownNotice) {
4024
+ Dialog.alert({
4025
+ title: "Notice",
4026
+ message: "You are currently using Satoshi Private Mainnet. This is a private version for testing. Please try a small amount of assets in Bridge"
4027
+ });
4028
+ localStorage.setItem("satoshi_private_mainnet_notice", "true");
4029
+ }
4030
+ }, 1e3);
4031
+ }
3978
4032
  const btcWallet = () => __async(this, null, function* () {
3979
4033
  return {
3980
4034
  id: "btc-wallet",
@@ -3998,7 +4052,7 @@ function setupBTCWallet({
3998
4052
 
3999
4053
  // src/index.ts
4000
4054
  var getVersion = () => {
4001
- return "0.3.32";
4055
+ return "0.3.34";
4002
4056
  };
4003
4057
  if (typeof window !== "undefined") {
4004
4058
  window.__BTC_WALLET_VERSION = getVersion();