btc-wallet 0.4.6-beta → 0.4.7-beta

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.
@@ -50,6 +50,7 @@ export declare function getDepositAmount(amount: string, option?: {
50
50
  totalDepositAmount: number;
51
51
  protocolFee: number;
52
52
  repayAmount: string | number;
53
+ newAccountMinDepositAmount: string | number;
53
54
  }>;
54
55
  export declare function getCsnaAccountId(env: ENV): Promise<string>;
55
56
  interface ExecuteBTCDepositAndActionParams<T extends boolean = true> {
package/dist/index.js CHANGED
@@ -2675,35 +2675,107 @@ function createFloatingButtonWithIframe({
2675
2675
  }) {
2676
2676
  const button = document.createElement("img");
2677
2677
  button.id = "satoshi-wallet-button";
2678
- button.src = openImageUrl;
2678
+ const isIframeVisible = localStorage.getItem("btc-wallet-iframe-visible") === "true";
2679
+ button.src = isIframeVisible ? closeImageUrl : openImageUrl;
2680
+ iframe.style.display = isIframeVisible ? "block" : "none";
2681
+ const windowWidth = window.innerWidth;
2682
+ const windowHeight = window.innerHeight;
2683
+ const savedPosition = JSON.parse(
2684
+ localStorage.getItem("btc-wallet-button-position") || '{"right": "20px", "bottom": "20px"}'
2685
+ );
2686
+ const right = Math.min(Math.max(20, parseInt(savedPosition.right)), windowWidth - 80);
2687
+ const bottom = Math.min(Math.max(20, parseInt(savedPosition.bottom)), windowHeight - 80);
2679
2688
  Object.assign(button.style, {
2680
2689
  position: "fixed",
2681
- bottom: "20px",
2682
- right: "20px",
2690
+ bottom: `${bottom}px`,
2691
+ right: `${right}px`,
2683
2692
  zIndex: "100000",
2684
2693
  width: "60px",
2685
2694
  height: "60px",
2686
2695
  borderRadius: "50%",
2687
- cursor: "pointer",
2688
- transition: "transform 0.15s ease"
2696
+ cursor: "grab",
2697
+ transition: "transform 0.15s ease",
2698
+ userSelect: "none"
2689
2699
  });
2690
2700
  document.body.appendChild(button);
2691
- const iframeVisible = localStorage.getItem("iframeVisible") === "true" || localStorage.getItem("iframeVisible") === null;
2692
- button.src = iframeVisible ? closeImageUrl : openImageUrl;
2693
- iframe.style.display = iframeVisible ? "block" : "none";
2694
- button.onclick = function() {
2701
+ let isDragging = false;
2702
+ let startX = 0;
2703
+ let startY = 0;
2704
+ let initialRight = 0;
2705
+ let initialBottom = 0;
2706
+ let dragStartTime = 0;
2707
+ button.addEventListener("mousedown", (e) => {
2708
+ isDragging = true;
2709
+ startX = e.clientX;
2710
+ startY = e.clientY;
2711
+ initialRight = parseInt(button.style.right);
2712
+ initialBottom = parseInt(button.style.bottom);
2713
+ dragStartTime = Date.now();
2714
+ button.style.cursor = "grabbing";
2715
+ button.style.transition = "none";
2716
+ e.preventDefault();
2717
+ });
2718
+ document.addEventListener("mousemove", (e) => {
2719
+ if (!isDragging)
2720
+ return;
2721
+ const deltaX = startX - e.clientX;
2722
+ const deltaY = startY - e.clientY;
2723
+ let newRight = initialRight + deltaX;
2724
+ let newBottom = initialBottom + deltaY;
2725
+ newRight = Math.min(Math.max(20, newRight), windowWidth - 80);
2726
+ newBottom = Math.min(Math.max(20, newBottom), windowHeight - 80);
2727
+ const snapThreshold = 20;
2728
+ const buttonLeft = windowWidth - newRight - 60;
2729
+ if (buttonLeft < snapThreshold) {
2730
+ newRight = windowWidth - 80;
2731
+ } else if (buttonLeft > windowWidth - snapThreshold - 60) {
2732
+ newRight = 20;
2733
+ }
2734
+ if (newBottom < snapThreshold) {
2735
+ newBottom = 20;
2736
+ } else if (newBottom > windowHeight - snapThreshold - 60) {
2737
+ newBottom = windowHeight - 80;
2738
+ }
2739
+ button.style.right = `${newRight}px`;
2740
+ button.style.bottom = `${newBottom}px`;
2741
+ updateIframePosition(iframe, newRight, newBottom, windowWidth, windowHeight);
2742
+ });
2743
+ document.addEventListener("mouseup", () => {
2744
+ if (!isDragging)
2745
+ return;
2746
+ const dragEndTime = Date.now();
2747
+ const isDragEvent = dragEndTime - dragStartTime > 200;
2748
+ isDragging = false;
2749
+ button.style.cursor = "grab";
2750
+ button.style.transition = "transform 0.15s ease";
2751
+ localStorage.setItem(
2752
+ "btc-wallet-button-position",
2753
+ JSON.stringify({
2754
+ right: button.style.right,
2755
+ bottom: button.style.bottom
2756
+ })
2757
+ );
2758
+ if (!isDragEvent) {
2759
+ handleButtonClick();
2760
+ }
2761
+ });
2762
+ const handleButtonClick = () => {
2695
2763
  const isCurrentlyVisible = iframe.style.display === "block";
2696
2764
  button.style.transform = "scale(0.8)";
2697
2765
  setTimeout(() => {
2698
2766
  button.style.transform = "scale(1)";
2699
2767
  }, 150);
2700
- iframe.style.display = isCurrentlyVisible ? "none" : "block";
2701
- button.src = isCurrentlyVisible ? openImageUrl : closeImageUrl;
2702
- localStorage.setItem("iframeVisible", String(!isCurrentlyVisible));
2768
+ const newVisibleState = !isCurrentlyVisible;
2769
+ iframe.style.display = newVisibleState ? "block" : "none";
2770
+ button.src = newVisibleState ? closeImageUrl : openImageUrl;
2771
+ localStorage.setItem("btc-wallet-iframe-visible", String(newVisibleState));
2703
2772
  setTimeout(() => {
2704
- iframe.focus();
2773
+ if (newVisibleState) {
2774
+ iframe.focus();
2775
+ }
2705
2776
  }, 0);
2706
2777
  };
2778
+ button.onclick = null;
2707
2779
  return button;
2708
2780
  }
2709
2781
  function createIframe({
@@ -2714,6 +2786,7 @@ function createIframe({
2714
2786
  iframe.id = "satoshi-wallet-iframe";
2715
2787
  iframe.allow = "clipboard-read; clipboard-write";
2716
2788
  iframe.src = iframeUrl;
2789
+ const isVisible = localStorage.getItem("btc-wallet-iframe-visible") === "true";
2717
2790
  Object.assign(iframe.style, __spreadValues({
2718
2791
  position: "fixed",
2719
2792
  bottom: "90px",
@@ -2721,7 +2794,7 @@ function createIframe({
2721
2794
  zIndex: "100000",
2722
2795
  boxShadow: "0 0 10px rgba(0, 0, 0, 0.1)",
2723
2796
  borderRadius: "10px",
2724
- display: "block",
2797
+ display: isVisible ? "block" : "none",
2725
2798
  border: "none"
2726
2799
  }, iframeStyle));
2727
2800
  document.body.appendChild(iframe);
@@ -2779,6 +2852,20 @@ function removeWalletButton() {
2779
2852
  const iframe = document.getElementById("satoshi-wallet-iframe");
2780
2853
  iframe == null ? void 0 : iframe.remove();
2781
2854
  }
2855
+ function updateIframePosition(iframe, buttonRight, buttonBottom, windowWidth, windowHeight) {
2856
+ const iframeWidth = parseInt(iframe.style.width);
2857
+ const iframeHeight = parseInt(iframe.style.height);
2858
+ let iframeRight = buttonRight;
2859
+ let iframeBottom = buttonBottom + 70;
2860
+ if (iframeRight + iframeWidth > windowWidth - 20) {
2861
+ iframeRight = Math.max(20, windowWidth - iframeWidth - 20);
2862
+ }
2863
+ if (iframeBottom + iframeHeight > windowHeight - 20) {
2864
+ iframeBottom = Math.max(20, buttonBottom - iframeHeight - 10);
2865
+ }
2866
+ iframe.style.right = `${iframeRight}px`;
2867
+ iframe.style.bottom = `${iframeBottom}px`;
2868
+ }
2782
2869
 
2783
2870
  // src/utils/nearUtils.ts
2784
2871
  var import_near_api_js = require("near-api-js");
@@ -3247,6 +3334,7 @@ var import_coinselect = __toESM(require("coinselect"), 1);
3247
3334
  var NEAR_STORAGE_DEPOSIT_AMOUNT = "1250000000000000000000";
3248
3335
  var NBTC_STORAGE_DEPOSIT_AMOUNT = "3000";
3249
3336
  var GAS_LIMIT = "50000000000000";
3337
+ var NEW_ACCOUNT_MIN_DEPOSIT_AMOUNT = "1000";
3250
3338
  function getBtcProvider() {
3251
3339
  if (typeof window === "undefined" || !window.btcContext) {
3252
3340
  throw new Error("BTC Provider is not initialized.");
@@ -3416,12 +3504,14 @@ function getDepositAmount(amount, option) {
3416
3504
  } = yield nearCall(config.bridgeContractId, "get_config", {});
3417
3505
  const depositAmount = Math.max(Number(min_deposit_amount), Number(amount));
3418
3506
  const protocolFee = Math.max(Number(fee_min), Number(depositAmount) * fee_rate);
3419
- const totalDepositAmount = new import_big.default(depositAmount).plus(protocolFee).plus(repayAmount).round(0, import_big.default.roundDown).toNumber();
3507
+ const newAccountMinDepositAmount = !(accountInfo == null ? void 0 : accountInfo.nonce) ? NEW_ACCOUNT_MIN_DEPOSIT_AMOUNT : 0;
3508
+ const totalDepositAmount = new import_big.default(depositAmount).plus(protocolFee).plus(repayAmount).plus(newAccountMinDepositAmount).round(0, import_big.default.roundDown).toNumber();
3420
3509
  return {
3421
3510
  depositAmount,
3422
3511
  totalDepositAmount,
3423
3512
  protocolFee,
3424
- repayAmount
3513
+ repayAmount,
3514
+ newAccountMinDepositAmount
3425
3515
  };
3426
3516
  });
3427
3517
  }
@@ -3548,6 +3638,14 @@ function checkSatoshiWhitelist(btcAccountId, env = "mainnet") {
3548
3638
  return __async(this, null, function* () {
3549
3639
  if (env !== "private_mainnet")
3550
3640
  return;
3641
+ const hasShownNotice = localStorage.getItem("btc-wallet-private-mainnet-notice");
3642
+ if (!hasShownNotice) {
3643
+ Dialog.alert({
3644
+ title: "Notice",
3645
+ message: "You are currently using Satoshi Private Mainnet. This is a private version for testing. Please try a small amount of assets in Ramp"
3646
+ });
3647
+ localStorage.setItem("btc-wallet-private-mainnet-notice", "true");
3648
+ }
3551
3649
  if (!btcAccountId)
3552
3650
  return;
3553
3651
  const config = yield getConfig(env);
@@ -3712,24 +3810,41 @@ function uint8ArrayToHex(uint8Array) {
3712
3810
 
3713
3811
  // src/core/setupBTCWallet.ts
3714
3812
  var { transfer, functionCall } = import_transactions.actionCreators;
3813
+ var STORAGE_KEYS = {
3814
+ ACCOUNT: "btc-wallet-account",
3815
+ PUBLIC_KEY: "btc-wallet-publickey",
3816
+ BTC_PUBLIC_KEY: "btc-wallet-btc-publickey"
3817
+ };
3715
3818
  var state = {
3716
3819
  saveAccount(account) {
3717
- window.localStorage.setItem("btc-wallet-account", account);
3820
+ if (!account) {
3821
+ this.removeAccount();
3822
+ return;
3823
+ }
3824
+ window.localStorage.setItem(STORAGE_KEYS.ACCOUNT, account);
3718
3825
  },
3719
3826
  removeAccount() {
3720
- window.localStorage.removeItem("btc-wallet-account");
3827
+ window.localStorage.removeItem(STORAGE_KEYS.ACCOUNT);
3721
3828
  },
3722
3829
  savePublicKey(publicKey) {
3723
- window.localStorage.setItem("btc-wallet-publickey", publicKey);
3830
+ if (!publicKey) {
3831
+ this.removePublicKey();
3832
+ return;
3833
+ }
3834
+ window.localStorage.setItem(STORAGE_KEYS.PUBLIC_KEY, publicKey);
3724
3835
  },
3725
3836
  removePublicKey() {
3726
- window.localStorage.removeItem("btc-wallet-publickey");
3837
+ window.localStorage.removeItem(STORAGE_KEYS.PUBLIC_KEY);
3727
3838
  },
3728
3839
  saveBtcPublicKey(publicKey) {
3729
- window.localStorage.setItem("btc-wallet-btc-publickey", publicKey);
3840
+ if (!publicKey) {
3841
+ this.removeBtcPublicKey();
3842
+ return;
3843
+ }
3844
+ window.localStorage.setItem(STORAGE_KEYS.BTC_PUBLIC_KEY, publicKey);
3730
3845
  },
3731
3846
  removeBtcPublicKey() {
3732
- window.localStorage.removeItem("btc-wallet-btc-publickey");
3847
+ window.localStorage.removeItem(STORAGE_KEYS.BTC_PUBLIC_KEY);
3733
3848
  },
3734
3849
  clear() {
3735
3850
  this.removeAccount();
@@ -3737,17 +3852,39 @@ var state = {
3737
3852
  this.removeBtcPublicKey();
3738
3853
  },
3739
3854
  save(account, publicKey) {
3855
+ if (!account || !publicKey) {
3856
+ this.clear();
3857
+ return;
3858
+ }
3740
3859
  this.saveAccount(account);
3741
3860
  this.savePublicKey(publicKey);
3742
3861
  },
3743
3862
  getAccount() {
3744
- return window.localStorage.getItem("btc-wallet-account");
3863
+ return window.localStorage.getItem(STORAGE_KEYS.ACCOUNT);
3745
3864
  },
3746
3865
  getPublicKey() {
3747
- return window.localStorage.getItem("btc-wallet-publickey");
3866
+ return window.localStorage.getItem(STORAGE_KEYS.PUBLIC_KEY);
3748
3867
  },
3749
3868
  getBtcPublicKey() {
3750
- return window.localStorage.getItem("btc-wallet-btc-publickey");
3869
+ return window.localStorage.getItem(STORAGE_KEYS.BTC_PUBLIC_KEY);
3870
+ },
3871
+ isValid() {
3872
+ const account = this.getAccount();
3873
+ const publicKey = this.getPublicKey();
3874
+ const btcPublicKey = this.getBtcPublicKey();
3875
+ const allEmpty = !account && !publicKey && !btcPublicKey;
3876
+ const allExist = account && publicKey && btcPublicKey;
3877
+ return allEmpty || allExist;
3878
+ },
3879
+ syncSave(account, publicKey, btcPublicKey) {
3880
+ if (!account || !publicKey || !btcPublicKey) {
3881
+ this.clear();
3882
+ return;
3883
+ }
3884
+ this.clear();
3885
+ this.savePublicKey(publicKey);
3886
+ this.saveBtcPublicKey(btcPublicKey);
3887
+ this.saveAccount(account);
3751
3888
  }
3752
3889
  };
3753
3890
  var BTCWallet = (_0) => __async(void 0, [_0], function* ({
@@ -3774,16 +3911,33 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3774
3911
  const currentConfig = walletConfig[env];
3775
3912
  const walletNetwork = ["mainnet", "private_mainnet"].includes(env) ? "mainnet" : "testnet";
3776
3913
  yield initBtcContext();
3914
+ function validateWalletState() {
3915
+ const accountId = state.getAccount();
3916
+ const publicKey = state.getPublicKey();
3917
+ const btcPublicKey = state.getBtcPublicKey();
3918
+ if (!accountId && publicKey || accountId && !publicKey || !publicKey && btcPublicKey) {
3919
+ state.clear();
3920
+ return false;
3921
+ }
3922
+ return true;
3923
+ }
3777
3924
  function setupBtcContextListeners() {
3778
3925
  return __async(this, null, function* () {
3779
3926
  const handleConnectionUpdate = () => __async(this, null, function* () {
3780
3927
  yield checkBtcNetwork(walletNetwork);
3781
- const accountId = state.getAccount();
3928
+ if (!state.isValid()) {
3929
+ state.clear();
3930
+ }
3931
+ validateWalletState();
3782
3932
  const btcContext = window.btcContext;
3783
- if (accountId && btcContext.account) {
3784
- yield checkSatoshiWhitelist(btcContext.account, env);
3785
- removeWalletButton();
3786
- setupWalletButton(env, wallet, btcContext);
3933
+ if (btcContext.account) {
3934
+ const btcPublicKey = yield btcContext.getPublicKey();
3935
+ if (btcPublicKey) {
3936
+ const { nearAddress, nearPublicKey } = yield getNearAccountByBtcPublicKey(btcPublicKey);
3937
+ yield checkSatoshiWhitelist(btcContext.account, env);
3938
+ removeWalletButton();
3939
+ setupWalletButton(env, wallet, btcContext);
3940
+ }
3787
3941
  } else {
3788
3942
  removeWalletButton();
3789
3943
  setTimeout(() => {
@@ -3794,19 +3948,31 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3794
3948
  const context = window.btcContext.getContext();
3795
3949
  context.on("updatePublicKey", (btcPublicKey) => __async(this, null, function* () {
3796
3950
  console.log("updatePublicKey");
3797
- const { nearAddress } = yield getNearAccountByBtcPublicKey(btcPublicKey);
3798
- emitter.emit("accountsChanged", {
3799
- accounts: [{ accountId: nearAddress }]
3800
- });
3801
- yield handleConnectionUpdate();
3951
+ state.clear();
3952
+ try {
3953
+ const { nearAddress, nearPublicKey } = yield getNearAccountByBtcPublicKey(btcPublicKey);
3954
+ if (!nearAddress || !nearPublicKey) {
3955
+ throw new Error("Failed to get near account info");
3956
+ }
3957
+ emitter.emit("accountsChanged", {
3958
+ accounts: [{ accountId: nearAddress }]
3959
+ });
3960
+ yield handleConnectionUpdate();
3961
+ } catch (error) {
3962
+ console.error("Error updating public key:", error);
3963
+ state.clear();
3964
+ emitter.emit("accountsChanged", { accounts: [] });
3965
+ }
3802
3966
  }));
3803
3967
  context.on("btcLoginError", () => __async(this, null, function* () {
3804
3968
  console.log("btcLoginError");
3969
+ state.clear();
3805
3970
  emitter.emit("accountsChanged", { accounts: [] });
3806
3971
  yield handleConnectionUpdate();
3807
3972
  }));
3808
3973
  context.on("btcLogOut", () => __async(this, null, function* () {
3809
3974
  console.log("btcLogOut");
3975
+ state.clear();
3810
3976
  emitter.emit("accountsChanged", { accounts: [] });
3811
3977
  yield handleConnectionUpdate();
3812
3978
  }));
@@ -3850,9 +4016,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3850
4016
  "get_chain_signature_near_account_public_key",
3851
4017
  { btc_public_key: btcPublicKey }
3852
4018
  );
3853
- state.saveAccount(csna);
3854
- state.savePublicKey(nearPublicKey);
3855
- state.saveBtcPublicKey(btcPublicKey);
4019
+ state.syncSave(csna, nearPublicKey, btcPublicKey);
3856
4020
  return {
3857
4021
  nearAddress: csna,
3858
4022
  nearPublicKey
@@ -3862,10 +4026,8 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3862
4026
  function signIn(_02) {
3863
4027
  return __async(this, arguments, function* ({ contractId, methodNames }) {
3864
4028
  const btcContext = window.btcContext;
3865
- const accountId = state.getAccount();
3866
- const publicKey = state.getPublicKey();
3867
- console.log("isLogin:", accountId && publicKey);
3868
- if (!accountId || !publicKey) {
4029
+ state.clear();
4030
+ if (!state.getAccount() || !state.getPublicKey()) {
3869
4031
  yield btcContext.login();
3870
4032
  }
3871
4033
  const btcPublicKey = yield btcContext.getPublicKey();
@@ -3931,6 +4093,9 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
3931
4093
  }
3932
4094
  function signAndSendTransactions(params) {
3933
4095
  return __async(this, null, function* () {
4096
+ if (!validateWalletState()) {
4097
+ throw new Error("Wallet state is invalid, please reconnect your wallet.");
4098
+ }
3934
4099
  const btcContext = window.btcContext;
3935
4100
  const accountId = state.getAccount();
3936
4101
  const accountInfo = yield getAccountInfo(accountId, currentConfig.accountContractId);
@@ -4137,18 +4302,6 @@ function setupBTCWallet({
4137
4302
  env = "mainnet"
4138
4303
  } = {}) {
4139
4304
  console.log("\u26A1\uFE0F BTC Wallet Version:", getVersion(), "env:", env);
4140
- if (env === "private_mainnet" && typeof window !== "undefined") {
4141
- setTimeout(() => {
4142
- const hasShownNotice = localStorage.getItem("satoshi_private_mainnet_notice");
4143
- if (!hasShownNotice) {
4144
- Dialog.alert({
4145
- title: "Notice",
4146
- message: "You are currently using Satoshi Private Mainnet. This is a private version for testing. Please try a small amount of assets in Ramp"
4147
- });
4148
- localStorage.setItem("satoshi_private_mainnet_notice", "true");
4149
- }
4150
- }, 1e3);
4151
- }
4152
4305
  const btcWallet = () => __async(this, null, function* () {
4153
4306
  return {
4154
4307
  id: "btc-wallet",
@@ -4172,7 +4325,7 @@ function setupBTCWallet({
4172
4325
 
4173
4326
  // src/index.ts
4174
4327
  var getVersion = () => {
4175
- return "0.4.6-beta";
4328
+ return "0.4.7-beta";
4176
4329
  };
4177
4330
  if (typeof window !== "undefined") {
4178
4331
  window.__BTC_WALLET_VERSION = getVersion();