btc-wallet 0.3.31 → 0.3.33

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,9 @@
1
+ interface DialogOptions {
2
+ title: string;
3
+ message: string;
4
+ dangerouslyUseHTML?: boolean;
5
+ closable?: boolean;
6
+ }
1
7
  export declare class Dialog {
2
8
  private static template;
3
9
  private static style;
@@ -6,8 +12,6 @@ export declare class Dialog {
6
12
  title?: string;
7
13
  message: string;
8
14
  }): Promise<boolean>;
9
- static alert(options: {
10
- title?: string;
11
- message: string;
12
- }): Promise<void>;
15
+ static alert(options: DialogOptions): Promise<void>;
13
16
  }
17
+ export {};
@@ -9,3 +9,4 @@ export declare function retryOperation<T>(operation: () => Promise<T> | T, shoul
9
9
  maxRetries?: number;
10
10
  delayMs?: number;
11
11
  }): Promise<T>;
12
+ export declare function toHex(originalString: string): string;
@@ -1,13 +1,15 @@
1
1
  export declare function getNonce(url: string, accountId: string): Promise<string>;
2
2
  export declare function getNearNonce(url: string, accountId: string): Promise<string>;
3
3
  export declare function receiveTransaction(url: string, data: any): Promise<any>;
4
- export declare function receiveDepositMsg(url: string, { btcPublicKey, txHash, depositType, postActions, extraMsg, }: {
4
+ interface ReceiveDepositMsgParams {
5
5
  btcPublicKey: string;
6
6
  txHash: string;
7
7
  depositType?: number;
8
8
  postActions?: string;
9
9
  extraMsg?: string;
10
- }): Promise<any>;
10
+ }
11
+ export declare function preReceiveDepositMsg(url: string, { btcPublicKey, depositType, postActions, extraMsg }: Omit<ReceiveDepositMsgParams, 'txHash'>): Promise<any>;
12
+ export declare function receiveDepositMsg(url: string, { btcPublicKey, txHash, depositType, postActions, extraMsg }: ReceiveDepositMsgParams): Promise<any>;
11
13
  export declare function checkBridgeTransactionStatus(url: string, txHash: string): Promise<{
12
14
  Status: number;
13
15
  ToTxHash: string;
@@ -16,3 +18,5 @@ export declare function checkBtcTransactionStatus(url: string, sig: string): Pro
16
18
  Status: number;
17
19
  NearHashList: string[];
18
20
  }>;
21
+ export declare function getWhitelist(url: string): Promise<string[]>;
22
+ export {};
package/esm/index.js CHANGED
@@ -1332,6 +1332,14 @@ function retryOperation(_0, _1) {
1332
1332
  throw new Error("Unexpected execution path");
1333
1333
  });
1334
1334
  }
1335
+ function toHex(originalString) {
1336
+ const charArray = originalString.split("");
1337
+ const asciiArray = charArray.map((char) => char.charCodeAt(0));
1338
+ const hexArray = asciiArray.map((code) => code.toString(16));
1339
+ let hexString = hexArray.join("");
1340
+ hexString = hexString.replace(/(^0+)/g, "");
1341
+ return hexString;
1342
+ }
1335
1343
 
1336
1344
  // src/utils/ethereumUtils.ts
1337
1345
  import {
@@ -2374,10 +2382,8 @@ function BtcWalletSelectorContextProvider({
2374
2382
  const [isProcessing, setIsProcessing] = useState8(false);
2375
2383
  const connectors = [
2376
2384
  new UnisatConnector(),
2377
- new XverseConnector(),
2378
2385
  new OKXConnector(),
2379
- new BitgetConnector(),
2380
- new MagicEdenConnector()
2386
+ new BitgetConnector()
2381
2387
  ];
2382
2388
  const walletSelectorContextValue = useMemo6(() => {
2383
2389
  const simpleFn = {};
@@ -2590,7 +2596,7 @@ var walletConfig = {
2590
2596
  accountContractId: "acc.toalice.near",
2591
2597
  bridgeContractId: "brg.toalice.near",
2592
2598
  walletUrl: "https://wallet-stg.satoshibridge.top",
2593
- bridgeUrl: "https://stg.satoshibridge.top/"
2599
+ bridgeUrl: "https://ramp.satos.network/"
2594
2600
  },
2595
2601
  mainnet: {
2596
2602
  base_url: "https://api.mainnet.satoshibridge.top",
@@ -2937,14 +2943,24 @@ function receiveTransaction(url, data) {
2937
2943
  return result_data;
2938
2944
  });
2939
2945
  }
2946
+ function preReceiveDepositMsg(_0, _1) {
2947
+ return __async(this, arguments, function* (url, { btcPublicKey, depositType = 1, postActions, extraMsg }) {
2948
+ const { result_code, result_message, result_data } = yield request(
2949
+ `${url}/v1/preReceiveDepositMsg`,
2950
+ {
2951
+ method: "POST",
2952
+ body: { btcPublicKey, depositType, postActions, extraMsg }
2953
+ }
2954
+ );
2955
+ console.log("preReceiveDepositMsg resp:", { result_code, result_message, result_data });
2956
+ if (result_code !== 0) {
2957
+ throw new Error(result_message);
2958
+ }
2959
+ return result_data;
2960
+ });
2961
+ }
2940
2962
  function receiveDepositMsg(_0, _1) {
2941
- return __async(this, arguments, function* (url, {
2942
- btcPublicKey,
2943
- txHash,
2944
- depositType = 1,
2945
- postActions,
2946
- extraMsg
2947
- }) {
2963
+ return __async(this, arguments, function* (url, { btcPublicKey, txHash, depositType = 1, postActions, extraMsg }) {
2948
2964
  const { result_code, result_message, result_data } = yield request(
2949
2965
  `${url}/v1/receiveDepositMsg`,
2950
2966
  {
@@ -2979,7 +2995,7 @@ function checkBridgeTransactionStatus(url, txHash) {
2979
2995
  }
2980
2996
  function checkBtcTransactionStatus(url, sig) {
2981
2997
  return __async(this, null, function* () {
2982
- const { result_code, result_message, result_data } = yield request(`${url}/v1/btcTx?sig=${sig}`, {
2998
+ const { result_code, result_message, result_data } = yield request(`${url}/v1/btcTx?sig=${toHex(sig)}`, {
2983
2999
  timeout: 3e5,
2984
3000
  pollingInterval: 5e3,
2985
3001
  maxPollingAttempts: 60,
@@ -2995,6 +3011,15 @@ function checkBtcTransactionStatus(url, sig) {
2995
3011
  return result_data;
2996
3012
  });
2997
3013
  }
3014
+ function getWhitelist(url) {
3015
+ return __async(this, null, function* () {
3016
+ const data = yield request(`${url}/v1/whitelist/users`).catch((error) => {
3017
+ console.error("getWhitelist error:", error);
3018
+ return [];
3019
+ });
3020
+ return data;
3021
+ });
3022
+ }
2998
3023
 
2999
3024
  // src/utils/Dialog.ts
3000
3025
  var Dialog = class {
@@ -3036,13 +3061,22 @@ var Dialog = class {
3036
3061
  });
3037
3062
  }
3038
3063
  static alert(options) {
3064
+ const messageEl = options.dangerouslyUseHTML ? { dangerouslySetInnerHTML: { __html: options.message } } : { children: options.message };
3039
3065
  return new Promise((resolve) => {
3066
+ var _a;
3040
3067
  this.injectStyles();
3041
3068
  const container = document.createElement("div");
3042
3069
  container.innerHTML = this.template;
3070
+ (_a = container.querySelector(".dialog-overlay")) == null ? void 0 : _a.classList.add("dialog-alert");
3071
+ if (options.closable === false) {
3072
+ const overlay = container.querySelector(".dialog-overlay");
3073
+ overlay.style.pointerEvents = "none";
3074
+ const dialogContainer = container.querySelector(".dialog-container");
3075
+ dialogContainer.style.pointerEvents = "auto";
3076
+ }
3043
3077
  document.body.appendChild(container);
3044
3078
  const titleEl = container.querySelector(".dialog-title");
3045
- const messageEl = container.querySelector(".dialog-message");
3079
+ const messageEl2 = container.querySelector(".dialog-message");
3046
3080
  const confirmBtn = container.querySelector(".dialog-confirm-btn");
3047
3081
  const cancelBtn = container.querySelector(".dialog-cancel-btn");
3048
3082
  if (options.title) {
@@ -3050,9 +3084,15 @@ var Dialog = class {
3050
3084
  } else {
3051
3085
  titleEl.style.display = "none";
3052
3086
  }
3053
- messageEl.textContent = options.message;
3087
+ messageEl2.innerHTML = options.message;
3054
3088
  cancelBtn.style.display = "none";
3089
+ if (options.closable === false) {
3090
+ confirmBtn.style.display = "none";
3091
+ }
3055
3092
  const cleanup = () => {
3093
+ if (options.closable === false) {
3094
+ return;
3095
+ }
3056
3096
  document.body.removeChild(container);
3057
3097
  };
3058
3098
  confirmBtn.addEventListener("click", () => {
@@ -3070,7 +3110,7 @@ Dialog.template = `
3070
3110
  <div class="dialog-message"></div>
3071
3111
  <div class="dialog-buttons">
3072
3112
  <button class="dialog-cancel-btn">Cancel</button>
3073
- <button class="dialog-confirm-btn">Confirm</button>
3113
+ <button class="dialog-confirm-btn">OK</button>
3074
3114
  </div>
3075
3115
  </div>
3076
3116
  </div>
@@ -3114,6 +3154,9 @@ Dialog.style = `
3114
3154
  justify-content: flex-end;
3115
3155
  gap: 12px;
3116
3156
  }
3157
+ .dialog-alert .dialog-buttons {
3158
+ justify-content: center;
3159
+ }
3117
3160
  .dialog-confirm-btn {
3118
3161
  padding: 8px 24px;
3119
3162
  background-color: #ff7a00;
@@ -3238,23 +3281,26 @@ function checkGasTokenBalance(csna, gasToken, minAmount, env) {
3238
3281
  }
3239
3282
  function checkGasTokenArrears(accountInfo, env, autoDeposit) {
3240
3283
  return __async(this, null, function* () {
3241
- var _a, _b, _c, _d;
3242
- 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))
3284
+ var _a, _b, _c;
3285
+ const debtAmount = new Big(((_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();
3286
+ const relayerFeeAmount = ((_c = accountInfo == null ? void 0 : accountInfo.relayer_fee) == null ? void 0 : _c.amount) || "0";
3287
+ const hasDebtArrears = new Big(debtAmount).gt(0);
3288
+ const hasRelayerFeeArrears = new Big(relayerFeeAmount).gt(0);
3289
+ if (!hasDebtArrears && !hasRelayerFeeArrears)
3243
3290
  return;
3244
3291
  const config = yield getConfig(env);
3245
- const arrearsType = accountInfo.debt_info.transfer_amount ? "Deposit" : ((_c = accountInfo.relayer_fee) == null ? void 0 : _c.amount) ? "RelayerFee" : void 0;
3246
- const transferAmount = arrearsType === "Deposit" ? accountInfo.debt_info.transfer_amount : (_d = accountInfo.relayer_fee) == null ? void 0 : _d.amount;
3292
+ const transferAmount = hasDebtArrears ? debtAmount : relayerFeeAmount;
3247
3293
  console.log("get_account:", accountInfo);
3248
3294
  const action = {
3249
3295
  receiver_id: config.accountContractId,
3250
3296
  amount: transferAmount,
3251
- msg: JSON.stringify(arrearsType)
3297
+ msg: JSON.stringify(hasDebtArrears ? "Repay" : "RelayerFee")
3252
3298
  };
3253
3299
  if (!autoDeposit)
3254
3300
  return action;
3255
3301
  const confirmed = yield Dialog.confirm({
3256
- title: arrearsType === "Deposit" ? "Has gas token arrears" : "Has relayer fee arrears",
3257
- 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."
3302
+ title: hasDebtArrears ? "Has gas token arrears" : "Has relayer fee arrears",
3303
+ message: hasDebtArrears ? "You have gas token arrears, please deposit gas token to continue." : "You have relayer fee arrears, please deposit relayer fee to continue."
3258
3304
  });
3259
3305
  if (confirmed) {
3260
3306
  yield executeBTCDepositAndAction({ action, env });
@@ -3448,8 +3494,14 @@ function executeBTCDepositAndAction(_0) {
3448
3494
  console.log("user deposit address:", userDepositAddress);
3449
3495
  console.log("send amount:", sendAmount);
3450
3496
  console.log("fee rate:", _feeRate);
3451
- const txHash = yield sendBitcoin(userDepositAddress, Number(sendAmount), _feeRate);
3452
3497
  const postActionsStr = newActions.length > 0 ? JSON.stringify(newActions) : void 0;
3498
+ yield preReceiveDepositMsg(config.base_url, {
3499
+ btcPublicKey,
3500
+ depositType: postActionsStr || depositMsg.extra_msg ? 1 : 0,
3501
+ postActions: postActionsStr,
3502
+ extraMsg: depositMsg.extra_msg
3503
+ });
3504
+ const txHash = yield sendBitcoin(userDepositAddress, Number(sendAmount), _feeRate);
3453
3505
  yield receiveDepositMsg(config.base_url, {
3454
3506
  btcPublicKey,
3455
3507
  txHash,
@@ -3471,6 +3523,28 @@ function executeBTCDepositAndAction(_0) {
3471
3523
  }
3472
3524
  });
3473
3525
  }
3526
+ function checkSatoshiWhitelist(btcAccountId, env = "mainnet") {
3527
+ return __async(this, null, function* () {
3528
+ if (env !== "private_mainnet")
3529
+ return;
3530
+ if (!btcAccountId)
3531
+ return;
3532
+ const config = yield getConfig(env);
3533
+ const whitelist = yield getWhitelist(config.base_url);
3534
+ if (!(whitelist == null ? void 0 : whitelist.length))
3535
+ return;
3536
+ const isWhitelisted = whitelist.includes(btcAccountId);
3537
+ if (!isWhitelisted) {
3538
+ Dialog.alert({
3539
+ title: "Account is not whitelisted",
3540
+ 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>`,
3541
+ dangerouslyUseHTML: true,
3542
+ closable: false
3543
+ });
3544
+ throw new Error("Account is not whitelisted");
3545
+ }
3546
+ });
3547
+ }
3474
3548
 
3475
3549
  // src/core/setupBTCWallet.ts
3476
3550
  var { transfer, functionCall } = actionCreators;
@@ -3529,7 +3603,8 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3529
3603
  signMessage,
3530
3604
  isSignedIn,
3531
3605
  signAndSendTransaction,
3532
- signAndSendTransactions
3606
+ signAndSendTransactions,
3607
+ calculateGasLimit
3533
3608
  };
3534
3609
  const env = metadata.env || options.network.networkId || "mainnet";
3535
3610
  const currentConfig = walletConfig[env];
@@ -3542,6 +3617,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3542
3617
  const accountId = state.getAccount();
3543
3618
  const btcContext = window.btcContext;
3544
3619
  if (accountId && btcContext.account) {
3620
+ yield checkSatoshiWhitelist(btcContext.account, env);
3545
3621
  removeWalletButton();
3546
3622
  setupWalletButton(env, wallet, btcContext);
3547
3623
  } else {
@@ -3738,6 +3814,17 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3738
3814
  return result;
3739
3815
  });
3740
3816
  }
3817
+ function calculateGasLimit(params) {
3818
+ return __async(this, null, function* () {
3819
+ const accountId = state.getAccount();
3820
+ const accountInfo = yield getAccountInfo(accountId, currentConfig.accountContractId);
3821
+ const trans = [...params.transactions];
3822
+ console.log("raw trans:", trans);
3823
+ const gasTokenBalance = (accountInfo == null ? void 0 : accountInfo.gas_token[currentConfig.token]) || "0";
3824
+ const { gasLimit } = yield calculateGasStrategy(gasTokenBalance, trans);
3825
+ return gasLimit;
3826
+ });
3827
+ }
3741
3828
  function createGasTokenTransfer(accountId, amount) {
3742
3829
  return __async(this, null, function* () {
3743
3830
  return {
@@ -3791,58 +3878,17 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3791
3878
  }
3792
3879
  function calculateGasStrategy(gasTokenBalance, transactions2) {
3793
3880
  return __async(this, null, function* () {
3794
- var _a;
3795
3881
  const accountId = state.getAccount();
3796
- const nearAccount = yield provider.query({
3797
- request_type: "view_account",
3798
- account_id: accountId,
3799
- finality: "final"
3800
- });
3801
- const availableBalance = parseFloat(nearAccount.amount) / __pow(10, 24);
3802
- console.log("available near balance:", availableBalance);
3803
- console.log("available gas token balance:", gasTokenBalance);
3804
3882
  const convertTx = yield Promise.all(
3805
3883
  transactions2.map((transaction, index) => convertTransactionToTxHex(transaction, index))
3806
3884
  );
3807
- if (availableBalance > 0.2) {
3808
- console.log("near balance is enough, get the protocol fee of each transaction");
3809
- const gasTokens = yield nearCall2(
3810
- currentConfig.accountContractId,
3811
- "list_gas_token",
3812
- { token_ids: [currentConfig.token] }
3813
- );
3814
- console.log("list_gas_token gas tokens:", gasTokens);
3815
- const perTxFee = Math.max(
3816
- Number(((_a = gasTokens[currentConfig.token]) == null ? void 0 : _a.per_tx_protocol_fee) || 0),
3817
- 100
3818
- );
3819
- console.log("perTxFee:", perTxFee);
3820
- const protocolFee = new Big2(perTxFee || "0").mul(convertTx.length).toFixed(0);
3821
- console.log("protocolFee:", protocolFee);
3822
- if (new Big2(gasTokenBalance).gte(protocolFee)) {
3823
- console.log("use near pay gas and enough gas token balance");
3824
- return { useNearPayGas: true, gasLimit: protocolFee };
3825
- } else {
3826
- console.log("use near pay gas and not enough gas token balance");
3827
- const transferTx = yield createGasTokenTransfer(accountId, protocolFee);
3828
- return recalculateGasWithTransfer(transferTx, convertTx, true, perTxFee.toString());
3829
- }
3830
- } else {
3831
- console.log("near balance is not enough, predict the gas token amount required");
3832
- const adjustedGas = yield getPredictedGasAmount(
3833
- currentConfig.accountContractId,
3834
- currentConfig.token,
3835
- convertTx.map((t) => t.txHex)
3836
- );
3837
- if (new Big2(gasTokenBalance).gte(adjustedGas)) {
3838
- console.log("use gas token and gas token balance is enough");
3839
- return { useNearPayGas: false, gasLimit: adjustedGas };
3840
- } else {
3841
- console.log("use gas token and gas token balance is not enough, need to transfer");
3842
- const transferTx = yield createGasTokenTransfer(accountId, adjustedGas);
3843
- return recalculateGasWithTransfer(transferTx, convertTx, false);
3844
- }
3845
- }
3885
+ const adjustedGas = yield getPredictedGasAmount(
3886
+ currentConfig.accountContractId,
3887
+ currentConfig.token,
3888
+ convertTx.map((t) => t.txHex)
3889
+ );
3890
+ const transferTx = yield createGasTokenTransfer(accountId, adjustedGas);
3891
+ return recalculateGasWithTransfer(transferTx, convertTx, false);
3846
3892
  });
3847
3893
  }
3848
3894
  function convertTransactionToTxHex(transaction, index = 0) {
@@ -3913,14 +3959,6 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3913
3959
  }
3914
3960
  return wallet;
3915
3961
  });
3916
- function toHex(originalString) {
3917
- const charArray = originalString.split("");
3918
- const asciiArray = charArray.map((char) => char.charCodeAt(0));
3919
- const hexArray = asciiArray.map((code) => code.toString(16));
3920
- let hexString = hexArray.join("");
3921
- hexString = hexString.replace(/(^0+)/g, "");
3922
- return hexString;
3923
- }
3924
3962
  function setupBTCWallet({
3925
3963
  iconUrl = "https://assets.deltatrade.ai/assets/chain/btc.svg",
3926
3964
  deprecated = false,
@@ -3929,6 +3967,18 @@ function setupBTCWallet({
3929
3967
  env = "mainnet"
3930
3968
  } = {}) {
3931
3969
  console.log("\u26A1\uFE0F BTC Wallet Version:", getVersion(), "env:", env);
3970
+ if (env === "private_mainnet" && typeof window !== "undefined") {
3971
+ setTimeout(() => {
3972
+ const hasShownNotice = localStorage.getItem("satoshi_private_mainnet_notice");
3973
+ if (!hasShownNotice) {
3974
+ Dialog.alert({
3975
+ title: "Notice",
3976
+ message: "You are currently using Satoshi Private Mainnet. This is a private version for testing. Please try a small amount of assets in Bridge"
3977
+ });
3978
+ localStorage.setItem("satoshi_private_mainnet_notice", "true");
3979
+ }
3980
+ }, 1e3);
3981
+ }
3932
3982
  const btcWallet = () => __async(this, null, function* () {
3933
3983
  return {
3934
3984
  id: "btc-wallet",
@@ -3952,7 +4002,7 @@ function setupBTCWallet({
3952
4002
 
3953
4003
  // src/index.ts
3954
4004
  var getVersion = () => {
3955
- return "0.3.31";
4005
+ return "0.3.33";
3956
4006
  };
3957
4007
  if (typeof window !== "undefined") {
3958
4008
  window.__BTC_WALLET_VERSION = getVersion();
@@ -3972,6 +4022,7 @@ export {
3972
4022
  XverseConnector,
3973
4023
  checkGasTokenArrears,
3974
4024
  checkGasTokenBalance,
4025
+ checkSatoshiWhitelist,
3975
4026
  estimateDepositAmount,
3976
4027
  executeBTCDepositAndAction,
3977
4028
  getAccountInfo,