@spicenet-io/spiceflow-ui 1.7.2 → 1.7.4

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/dist/index.js CHANGED
@@ -84,10 +84,10 @@ const CHAIN_CONFIGS = {
84
84
  moralisName: "",
85
85
  supportedTokens: [
86
86
  {
87
- address: "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d",
87
+ address: "0xBeB51deb2018b67b35d5695Fd15bb30D452c7868",
88
88
  name: "USD Coin",
89
89
  symbol: "USDC",
90
- decimals: 6
90
+ decimals: 18
91
91
  }
92
92
  ]
93
93
  },
@@ -118,10 +118,10 @@ const CHAIN_CONFIGS = {
118
118
  moralisName: "0x14a34",
119
119
  supportedTokens: [
120
120
  {
121
- address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
121
+ address: "0xf370dC3765f81aC9dD2FEBd59Fb4e710330B0BC8",
122
122
  name: "USD Coin",
123
123
  symbol: "USDC",
124
- decimals: 6
124
+ decimals: 18
125
125
  },
126
126
  {
127
127
  address: "0x4Fc381B6CC6Df8cF1c1bD46D184475bE5b7A3c62",
@@ -911,7 +911,7 @@ const useAssets = ({
911
911
  address,
912
912
  supportedChains,
913
913
  fetchBalances: fetchBalances2,
914
- refreshInterval = 3e4
914
+ refreshInterval = 1e4
915
915
  // 30 seconds default
916
916
  }) => {
917
917
  const [assets, setAssets] = useState([]);
@@ -3164,6 +3164,39 @@ class RelayerService {
3164
3164
  throw error;
3165
3165
  }
3166
3166
  }
3167
+ async requestSpiceUsdAirdrop(params) {
3168
+ try {
3169
+ const response = await fetch(
3170
+ `${this.baseUrl}/airdrop/${params.chainId}/spiceUsd`,
3171
+ {
3172
+ method: "POST",
3173
+ headers: {
3174
+ "Content-Type": "application/json"
3175
+ },
3176
+ body: JSON.stringify({ wallet: params.address })
3177
+ }
3178
+ );
3179
+ const data = await response.json().catch(() => ({}));
3180
+ if (!response.ok) {
3181
+ const msg = data && (data.error || data.message) || "Failed to request airdrop";
3182
+ return { success: false, errorMessage: String(msg) };
3183
+ }
3184
+ if (data && typeof data.error === "string") {
3185
+ return { success: false, errorMessage: data.error };
3186
+ }
3187
+ if (data && (data.txHash || data.amount)) {
3188
+ return {
3189
+ success: true,
3190
+ txHash: data.txHash,
3191
+ amount: data.amount
3192
+ };
3193
+ }
3194
+ return { success: true };
3195
+ } catch (error) {
3196
+ const msg = error?.message && typeof error.message === "string" ? error.message : "Failed to request airdrop";
3197
+ return { success: false, errorMessage: msg };
3198
+ }
3199
+ }
3167
3200
  }
3168
3201
  const relayerService = new RelayerService();
3169
3202
  const createInitialSteps = (chainBatches, customGetChainName) => {
@@ -3912,7 +3945,8 @@ const SwapWidget = ({
3912
3945
 
3913
3946
  const DepositWidget = ({
3914
3947
  depositBatches,
3915
- tokenAddress = "0x0",
3948
+ tokenAddress,
3949
+ tokenDecimals,
3916
3950
  supportedChains,
3917
3951
  theme: themeMode = "light",
3918
3952
  styles,
@@ -4102,7 +4136,10 @@ const DepositWidget = ({
4102
4136
  [
4103
4137
  {
4104
4138
  tokenAddress,
4105
- tokenAmount: parseEther(selectedDepositAsset.amount)
4139
+ tokenAmount: parseUnits(
4140
+ selectedDepositAsset.amount,
4141
+ tokenDecimals
4142
+ )
4106
4143
  }
4107
4144
  ]
4108
4145
  ]
@@ -4613,6 +4650,7 @@ const DepositWidgetModal = ({
4613
4650
  // Pass through all DepositWidget props
4614
4651
  depositBatches,
4615
4652
  tokenAddress,
4653
+ tokenDecimals,
4616
4654
  supportedChains,
4617
4655
  theme: themeMode = "light",
4618
4656
  styles,
@@ -4678,6 +4716,7 @@ const DepositWidgetModal = ({
4678
4716
  {
4679
4717
  depositBatches,
4680
4718
  tokenAddress,
4719
+ tokenDecimals,
4681
4720
  supportedChains,
4682
4721
  theme: themeMode,
4683
4722
  styles: {
@@ -6238,45 +6277,93 @@ const DepositConfirmationModal = ({
6238
6277
  style: {
6239
6278
  display: "flex",
6240
6279
  alignItems: "center",
6241
- gap: "8px",
6242
- marginBottom: theme.spacing.md,
6243
- cursor: "pointer"
6280
+ justifyContent: "space-between",
6281
+ marginBottom: theme.spacing.md
6244
6282
  },
6245
- onClick: toggleDetails,
6246
6283
  children: [
6247
- /* @__PURE__ */ jsx(
6248
- "span",
6284
+ /* @__PURE__ */ jsxs(
6285
+ "div",
6249
6286
  {
6250
6287
  style: {
6251
- fontSize: "13px",
6252
- fontWeight: theme.typography.fontWeight.medium,
6253
- color: "#6b7280",
6254
- fontFamily: styles?.fontFamily || theme.typography.fontFamily
6288
+ display: "flex",
6289
+ alignItems: "center",
6290
+ gap: "8px",
6291
+ cursor: "pointer"
6255
6292
  },
6256
- children: "Transaction Details"
6293
+ onClick: toggleDetails,
6294
+ children: [
6295
+ /* @__PURE__ */ jsx(
6296
+ "span",
6297
+ {
6298
+ style: {
6299
+ fontSize: "13px",
6300
+ fontWeight: theme.typography.fontWeight.medium,
6301
+ color: "#6b7280",
6302
+ fontFamily: styles?.fontFamily || theme.typography.fontFamily
6303
+ },
6304
+ children: "Transaction Details"
6305
+ }
6306
+ ),
6307
+ /* @__PURE__ */ jsx(
6308
+ "svg",
6309
+ {
6310
+ width: "16",
6311
+ height: "16",
6312
+ viewBox: "0 0 16 16",
6313
+ fill: "none",
6314
+ style: {
6315
+ transform: isDetailsExpanded ? "rotate(180deg)" : "rotate(0deg)",
6316
+ transition: "transform 0.3s ease"
6317
+ },
6318
+ children: /* @__PURE__ */ jsx(
6319
+ "path",
6320
+ {
6321
+ d: "M4 6L8 10L12 6",
6322
+ stroke: "#6b7280",
6323
+ strokeWidth: "2",
6324
+ strokeLinecap: "round",
6325
+ strokeLinejoin: "round"
6326
+ }
6327
+ )
6328
+ }
6329
+ )
6330
+ ]
6257
6331
  }
6258
6332
  ),
6259
6333
  /* @__PURE__ */ jsx(
6260
- "svg",
6334
+ "button",
6261
6335
  {
6262
- width: "16",
6263
- height: "16",
6264
- viewBox: "0 0 16 16",
6265
- fill: "none",
6336
+ onClick: (e) => {
6337
+ e.stopPropagation();
6338
+ onClose();
6339
+ },
6266
6340
  style: {
6267
- transform: isDetailsExpanded ? "rotate(180deg)" : "rotate(0deg)",
6268
- transition: "transform 0.3s ease"
6341
+ background: "none",
6342
+ border: "none",
6343
+ cursor: "pointer",
6344
+ padding: "4px",
6345
+ display: "flex",
6346
+ alignItems: "center",
6347
+ justifyContent: "center",
6348
+ color: "#6b7280",
6349
+ transition: "color 0.2s ease"
6269
6350
  },
6270
- children: /* @__PURE__ */ jsx(
6351
+ onMouseEnter: (e) => {
6352
+ e.currentTarget.style.color = "#1f2937";
6353
+ },
6354
+ onMouseLeave: (e) => {
6355
+ e.currentTarget.style.color = "#6b7280";
6356
+ },
6357
+ children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx(
6271
6358
  "path",
6272
6359
  {
6273
- d: "M4 6L8 10L12 6",
6274
- stroke: "#6b7280",
6360
+ d: "M12 4L4 12M4 4L12 12",
6361
+ stroke: "currentColor",
6275
6362
  strokeWidth: "2",
6276
6363
  strokeLinecap: "round",
6277
6364
  strokeLinejoin: "round"
6278
6365
  }
6279
- )
6366
+ ) })
6280
6367
  }
6281
6368
  )
6282
6369
  ]
@@ -6972,6 +7059,9 @@ const DepositModal = React.memo(
6972
7059
  null
6973
7060
  );
6974
7061
  const [showAirdropTooltip, setShowAirdropTooltip] = useState(false);
7062
+ const [airdropLoading, setAirdropLoading] = useState(false);
7063
+ const [airdropMessage, setAirdropMessage] = useState(null);
7064
+ const [airdropError, setAirdropError] = useState(null);
6975
7065
  const {
6976
7066
  intentStatus,
6977
7067
  startStatusPolling,
@@ -7008,13 +7098,6 @@ const DepositModal = React.memo(
7008
7098
  "Submitting deposit data to backend after bridging completes:",
7009
7099
  depositData
7010
7100
  );
7011
- for (const data of depositData) {
7012
- console.log("Calling submitSpiceDeposit with:", data);
7013
- await relayerService.submitSpiceDeposit(data);
7014
- console.log(
7015
- `Successfully submitted deposit for txHash: ${data.txHash} on chainId: ${data.chainId}`
7016
- );
7017
- }
7018
7101
  }
7019
7102
  setPostDepositStatus("success");
7020
7103
  setPostDepositAmount(bridgedAmount);
@@ -7047,6 +7130,116 @@ const DepositModal = React.memo(
7047
7130
  }, [isOpen]);
7048
7131
  useMemo(() => {
7049
7132
  }, [depositAmount]);
7133
+ const handleRpcError = useCallback((error2) => {
7134
+ const errorMessage = error2?.message || String(error2 || "");
7135
+ const errorDetails = error2?.details || "";
7136
+ const errorString = `${errorMessage} ${errorDetails}`.toLowerCase();
7137
+ if (errorString.includes("internal json-rpc error") || errorString.includes("internal error") || errorString.includes("an internal error was received")) {
7138
+ return "Network error occurred. Please try again.";
7139
+ }
7140
+ return errorMessage || "Transaction failed";
7141
+ }, []);
7142
+ const handleAirdropClick = useCallback(async () => {
7143
+ const targetAddress = sourceAddress || address;
7144
+ const SOLVER_ADDRESS = "0x111115763723b53395308ec4c9ab9d5fb0844cae";
7145
+ setAirdropMessage(null);
7146
+ setAirdropError(null);
7147
+ if (!targetAddress) {
7148
+ setAirdropError("Connect your wallet before requesting an airdrop");
7149
+ return;
7150
+ }
7151
+ const selectedChainId = selectedDepositAssets[0]?.asset?.chainId ?? supportedChains[0];
7152
+ if (!selectedChainId) {
7153
+ setAirdropError("No chain selected for airdrop");
7154
+ return;
7155
+ }
7156
+ if (!externalWalletClient) {
7157
+ setAirdropError("External wallet not connected");
7158
+ return;
7159
+ }
7160
+ setAirdropLoading(true);
7161
+ try {
7162
+ if (currentChain?.id !== selectedChainId) {
7163
+ setAirdropMessage("Switching network...");
7164
+ try {
7165
+ await switchChainAsync({ chainId: selectedChainId });
7166
+ let attempts = 0;
7167
+ const maxAttempts = 20;
7168
+ while (attempts < maxAttempts) {
7169
+ await new Promise((resolve) => setTimeout(resolve, 100));
7170
+ if (currentChainRef.current?.id === selectedChainId) {
7171
+ break;
7172
+ }
7173
+ attempts++;
7174
+ }
7175
+ if (currentChainRef.current?.id !== selectedChainId) {
7176
+ throw new Error(
7177
+ `Failed to switch to chain ${selectedChainId}. Please switch manually in your wallet.`
7178
+ );
7179
+ }
7180
+ } catch (switchError) {
7181
+ if (switchError.code === 4902 || switchError.name === "ChainNotConfiguredError") {
7182
+ throw new Error(
7183
+ `Chain ${selectedChainId} is not configured in your wallet. Please add it manually.`
7184
+ );
7185
+ }
7186
+ throw switchError;
7187
+ }
7188
+ }
7189
+ setAirdropMessage("Estimating required gas amount...");
7190
+ const client = getClientForChain(selectedChainId);
7191
+ const gasPrice = await client.getGasPrice();
7192
+ const estimatedGasLimit = BigInt(65e3);
7193
+ const gasCost = estimatedGasLimit * gasPrice;
7194
+ const bufferMultiplier = BigInt(120);
7195
+ const gasDepositAmount = gasCost * bufferMultiplier / BigInt(100);
7196
+ console.log("GAS: ", gasDepositAmount);
7197
+ setAirdropMessage("Sending gas deposit to solver...");
7198
+ const gasDepositTx = await externalWalletClient.sendTransaction({
7199
+ to: SOLVER_ADDRESS,
7200
+ value: gasDepositAmount
7201
+ });
7202
+ setAirdropMessage("Waiting for transaction confirmation...");
7203
+ const receipt = await client.waitForTransactionReceipt({
7204
+ hash: gasDepositTx,
7205
+ timeout: 12e4,
7206
+ pollingInterval: 2e3,
7207
+ confirmations: 2
7208
+ });
7209
+ if (receipt.status !== "success") {
7210
+ throw new Error("Gas deposit transaction failed");
7211
+ }
7212
+ setAirdropMessage("Requesting airdrop...");
7213
+ const result = await relayerService.requestSpiceUsdAirdrop({
7214
+ chainId: selectedChainId,
7215
+ address: targetAddress
7216
+ });
7217
+ if (!result.success) {
7218
+ setAirdropError(result.errorMessage || "Failed to request airdrop");
7219
+ return;
7220
+ }
7221
+ if (result.txHash || result.amount) {
7222
+ const amountText = result.amount ? ` ${result.amount}` : "";
7223
+ setAirdropMessage(`Airdrop${amountText} requested successfully.`);
7224
+ return;
7225
+ }
7226
+ setAirdropMessage("Airdrop requested successfully.");
7227
+ } catch (e) {
7228
+ const msg = handleRpcError(e);
7229
+ setAirdropError(msg);
7230
+ } finally {
7231
+ setAirdropLoading(false);
7232
+ }
7233
+ }, [
7234
+ address,
7235
+ sourceAddress,
7236
+ selectedDepositAssets,
7237
+ supportedChains,
7238
+ externalWalletClient,
7239
+ currentChain,
7240
+ switchChainAsync,
7241
+ handleRpcError
7242
+ ]);
7050
7243
  const handleDepositAssetSelect = (asset, index) => {
7051
7244
  setSelectedDepositAssets((prev) => {
7052
7245
  const updated = [...prev];
@@ -7549,10 +7742,8 @@ const DepositModal = React.memo(
7549
7742
  errorMessage = "Transaction rejected by user";
7550
7743
  } else if (error2?.message?.includes("does not match the target chain") || error2?.message?.includes("Current Chain ID")) {
7551
7744
  errorMessage = "Network mismatch detected. Please click the button again to proceed.";
7552
- } else if (error2 instanceof Error) {
7553
- errorMessage = error2.message;
7554
- } else if (typeof error2 === "string") {
7555
- errorMessage = error2;
7745
+ } else {
7746
+ errorMessage = handleRpcError(error2);
7556
7747
  }
7557
7748
  setError(errorMessage);
7558
7749
  } finally {
@@ -7569,12 +7760,15 @@ const DepositModal = React.memo(
7569
7760
  const allAvailable = supportedChains.flatMap(
7570
7761
  (chainId) => getAllAssetsForChain(chainId, assets)
7571
7762
  );
7763
+ const withBalance = allAvailable.filter(
7764
+ (asset) => asset.balance > BigInt(0)
7765
+ );
7572
7766
  if (allowedTokens && allowedTokens.length > 0) {
7573
- return allAvailable.filter(
7767
+ return withBalance.filter(
7574
7768
  (asset) => allowedTokens.includes(asset.symbol.toLowerCase()) || asset.isNative && allowedTokens.includes("native")
7575
7769
  );
7576
7770
  }
7577
- return allAvailable;
7771
+ return withBalance;
7578
7772
  }, [supportedChains, assets, allowedTokens]);
7579
7773
  const secondAssetOptions = useMemo(() => {
7580
7774
  if (!selectedDepositAssets[0]?.asset) {
@@ -7660,95 +7854,121 @@ const DepositModal = React.memo(
7660
7854
  {
7661
7855
  style: {
7662
7856
  display: "flex",
7663
- justifyContent: "flex-end",
7857
+ justifyContent: "space-between",
7664
7858
  alignItems: "center",
7665
- gap: "4px",
7666
7859
  marginBottom: "8px"
7667
7860
  },
7668
7861
  children: [
7669
7862
  /* @__PURE__ */ jsx(
7670
- "button",
7863
+ "div",
7671
7864
  {
7672
- onClick: () => {
7673
- },
7674
7865
  style: {
7675
- padding: "4px 8px",
7676
- borderRadius: "4px",
7677
- border: "1px solid #D1D5DB",
7678
- background: "#E5E7EB",
7679
- color: "#4B5563",
7680
7866
  fontSize: "11px",
7681
- fontWeight: 500,
7682
- cursor: "pointer",
7683
- display: "flex",
7684
- alignItems: "center",
7685
- gap: "4px",
7686
- transition: "all 0.2s",
7687
- whiteSpace: "nowrap"
7688
- },
7689
- onMouseEnter: (e) => {
7690
- e.currentTarget.style.color = "#1F2937";
7691
- e.currentTarget.style.background = "#D1D5DB";
7692
- },
7693
- onMouseLeave: (e) => {
7694
- e.currentTarget.style.color = "#4B5563";
7695
- e.currentTarget.style.background = "#E5E7EB";
7867
+ color: airdropError ? "#b91c1c" : "#047857",
7868
+ fontFamily: styles?.fontFamily || theme.typography.fontFamily,
7869
+ flex: 1,
7870
+ minWidth: 0
7696
7871
  },
7697
- children: "Airdrop"
7872
+ children: airdropError || airdropMessage || ""
7698
7873
  }
7699
7874
  ),
7700
7875
  /* @__PURE__ */ jsxs(
7701
7876
  "div",
7702
7877
  {
7703
- onMouseEnter: () => setShowAirdropTooltip(true),
7704
- onMouseLeave: () => setShowAirdropTooltip(false),
7705
7878
  style: {
7706
- position: "relative",
7707
- width: "14px",
7708
- height: "14px",
7709
- borderRadius: "50%",
7710
- backgroundColor: "#9CA3AF",
7711
- color: "white",
7712
7879
  display: "flex",
7713
- alignItems: "center",
7714
- justifyContent: "center",
7715
- fontSize: "9px",
7716
- fontWeight: "bold",
7717
- cursor: "help"
7880
+ gap: "4px",
7881
+ flexShrink: 0,
7882
+ alignItems: "center"
7718
7883
  },
7719
7884
  children: [
7720
- "i",
7721
- showAirdropTooltip && /* @__PURE__ */ jsxs(
7885
+ /* @__PURE__ */ jsx(
7886
+ "button",
7887
+ {
7888
+ onClick: handleAirdropClick,
7889
+ disabled: airdropLoading,
7890
+ style: {
7891
+ padding: "4px 8px",
7892
+ borderRadius: "4px",
7893
+ border: "1px solid #D1D5DB",
7894
+ background: "#E5E7EB",
7895
+ color: "#4B5563",
7896
+ fontSize: "11px",
7897
+ fontWeight: 500,
7898
+ cursor: airdropLoading ? "default" : "pointer",
7899
+ transition: "all 0.2s",
7900
+ display: "flex",
7901
+ alignItems: "center"
7902
+ },
7903
+ onMouseEnter: (e) => {
7904
+ if (!airdropLoading) {
7905
+ e.currentTarget.style.color = "#1F2937";
7906
+ e.currentTarget.style.background = "#D1D5DB";
7907
+ }
7908
+ },
7909
+ onMouseLeave: (e) => {
7910
+ e.currentTarget.style.color = "#4B5563";
7911
+ e.currentTarget.style.background = "#E5E7EB";
7912
+ },
7913
+ children: airdropLoading ? "Requesting..." : "Airdrop"
7914
+ }
7915
+ ),
7916
+ /* @__PURE__ */ jsxs(
7722
7917
  "div",
7723
7918
  {
7919
+ onMouseEnter: () => setShowAirdropTooltip(true),
7920
+ onMouseLeave: () => setShowAirdropTooltip(false),
7724
7921
  style: {
7725
- position: "absolute",
7726
- bottom: "calc(100% + 8px)",
7727
- right: 0,
7728
- backgroundColor: "#1F2937",
7922
+ position: "relative",
7923
+ width: "14px",
7924
+ height: "14px",
7925
+ borderRadius: "50%",
7926
+ backgroundColor: "#9CA3AF",
7729
7927
  color: "white",
7730
- padding: "8px 12px",
7731
- borderRadius: "6px",
7732
- fontSize: "12px",
7733
- whiteSpace: "nowrap",
7734
- boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)",
7735
- zIndex: 100
7928
+ display: "flex",
7929
+ alignItems: "center",
7930
+ justifyContent: "center",
7931
+ fontSize: "9px",
7932
+ fontWeight: "bold",
7933
+ cursor: "help",
7934
+ flexShrink: 0
7736
7935
  },
7737
7936
  children: [
7738
- "This is testnet USDC, and it won't be available on mainnet",
7739
- /* @__PURE__ */ jsx(
7937
+ "i",
7938
+ showAirdropTooltip && /* @__PURE__ */ jsxs(
7740
7939
  "div",
7741
7940
  {
7742
7941
  style: {
7743
7942
  position: "absolute",
7744
- top: "100%",
7745
- right: "10px",
7746
- width: 0,
7747
- height: 0,
7748
- borderLeft: "6px solid transparent",
7749
- borderRight: "6px solid transparent",
7750
- borderTop: "6px solid #1F2937"
7751
- }
7943
+ bottom: "calc(100% + 8px)",
7944
+ right: 0,
7945
+ backgroundColor: "#1F2937",
7946
+ color: "white",
7947
+ padding: "8px 12px",
7948
+ borderRadius: "6px",
7949
+ fontSize: "12px",
7950
+ whiteSpace: "nowrap",
7951
+ boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)",
7952
+ zIndex: 100
7953
+ },
7954
+ children: [
7955
+ "This is testnet USDC, and it won't be available on mainnet",
7956
+ /* @__PURE__ */ jsx(
7957
+ "div",
7958
+ {
7959
+ style: {
7960
+ position: "absolute",
7961
+ top: "100%",
7962
+ right: "10px",
7963
+ width: 0,
7964
+ height: 0,
7965
+ borderLeft: "6px solid transparent",
7966
+ borderRight: "6px solid transparent",
7967
+ borderTop: "6px solid #1F2937"
7968
+ }
7969
+ }
7970
+ )
7971
+ ]
7752
7972
  }
7753
7973
  )
7754
7974
  ]
@@ -7825,95 +8045,121 @@ const DepositModal = React.memo(
7825
8045
  {
7826
8046
  style: {
7827
8047
  display: "flex",
7828
- justifyContent: "flex-end",
8048
+ justifyContent: "space-between",
7829
8049
  alignItems: "center",
7830
- gap: "4px",
7831
8050
  marginBottom: "8px"
7832
8051
  },
7833
8052
  children: [
7834
8053
  /* @__PURE__ */ jsx(
7835
- "button",
8054
+ "div",
7836
8055
  {
7837
- onClick: () => {
7838
- },
7839
8056
  style: {
7840
- padding: "4px 8px",
7841
- borderRadius: "4px",
7842
- border: "1px solid #D1D5DB",
7843
- background: "#E5E7EB",
7844
- color: "#4B5563",
7845
8057
  fontSize: "11px",
7846
- fontWeight: 500,
7847
- cursor: "pointer",
7848
- display: "flex",
7849
- alignItems: "center",
7850
- gap: "4px",
7851
- transition: "all 0.2s",
7852
- whiteSpace: "nowrap"
7853
- },
7854
- onMouseEnter: (e) => {
7855
- e.currentTarget.style.color = "#1F2937";
7856
- e.currentTarget.style.background = "#D1D5DB";
7857
- },
7858
- onMouseLeave: (e) => {
7859
- e.currentTarget.style.color = "#4B5563";
7860
- e.currentTarget.style.background = "#E5E7EB";
8058
+ color: airdropError ? "#b91c1c" : "#047857",
8059
+ fontFamily: styles?.fontFamily || theme.typography.fontFamily,
8060
+ flex: 1,
8061
+ minWidth: 0
7861
8062
  },
7862
- children: "Airdrop"
8063
+ children: airdropError || airdropMessage || ""
7863
8064
  }
7864
8065
  ),
7865
8066
  /* @__PURE__ */ jsxs(
7866
8067
  "div",
7867
8068
  {
7868
- onMouseEnter: () => setShowAirdropTooltip(true),
7869
- onMouseLeave: () => setShowAirdropTooltip(false),
7870
8069
  style: {
7871
- position: "relative",
7872
- width: "14px",
7873
- height: "14px",
7874
- borderRadius: "50%",
7875
- backgroundColor: "#9CA3AF",
7876
- color: "white",
7877
8070
  display: "flex",
7878
- alignItems: "center",
7879
- justifyContent: "center",
7880
- fontSize: "9px",
7881
- fontWeight: "bold",
7882
- cursor: "help"
8071
+ gap: "4px",
8072
+ flexShrink: 0,
8073
+ alignItems: "center"
7883
8074
  },
7884
8075
  children: [
7885
- "i",
7886
- showAirdropTooltip && /* @__PURE__ */ jsxs(
8076
+ /* @__PURE__ */ jsx(
8077
+ "button",
8078
+ {
8079
+ onClick: handleAirdropClick,
8080
+ disabled: airdropLoading,
8081
+ style: {
8082
+ padding: "4px 8px",
8083
+ borderRadius: "4px",
8084
+ border: "1px solid #D1D5DB",
8085
+ background: "#E5E7EB",
8086
+ color: "#4B5563",
8087
+ fontSize: "11px",
8088
+ fontWeight: 500,
8089
+ cursor: airdropLoading ? "default" : "pointer",
8090
+ transition: "all 0.2s",
8091
+ display: "flex",
8092
+ alignItems: "center"
8093
+ },
8094
+ onMouseEnter: (e) => {
8095
+ if (!airdropLoading) {
8096
+ e.currentTarget.style.color = "#1F2937";
8097
+ e.currentTarget.style.background = "#D1D5DB";
8098
+ }
8099
+ },
8100
+ onMouseLeave: (e) => {
8101
+ e.currentTarget.style.color = "#4B5563";
8102
+ e.currentTarget.style.background = "#E5E7EB";
8103
+ },
8104
+ children: airdropLoading ? "Requesting..." : "Airdrop"
8105
+ }
8106
+ ),
8107
+ /* @__PURE__ */ jsxs(
7887
8108
  "div",
7888
8109
  {
8110
+ onMouseEnter: () => setShowAirdropTooltip(true),
8111
+ onMouseLeave: () => setShowAirdropTooltip(false),
7889
8112
  style: {
7890
- position: "absolute",
7891
- bottom: "calc(100% + 8px)",
7892
- right: 0,
7893
- backgroundColor: "#1F2937",
8113
+ position: "relative",
8114
+ width: "14px",
8115
+ height: "14px",
8116
+ borderRadius: "50%",
8117
+ backgroundColor: "#9CA3AF",
7894
8118
  color: "white",
7895
- padding: "8px 12px",
7896
- borderRadius: "6px",
7897
- fontSize: "12px",
7898
- whiteSpace: "nowrap",
7899
- boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)",
7900
- zIndex: 100
8119
+ display: "flex",
8120
+ alignItems: "center",
8121
+ justifyContent: "center",
8122
+ fontSize: "9px",
8123
+ fontWeight: "bold",
8124
+ cursor: "help",
8125
+ flexShrink: 0
7901
8126
  },
7902
8127
  children: [
7903
- "This is testnet USDC, and it won't be available on mainnet",
7904
- /* @__PURE__ */ jsx(
8128
+ "i",
8129
+ showAirdropTooltip && /* @__PURE__ */ jsxs(
7905
8130
  "div",
7906
8131
  {
7907
8132
  style: {
7908
8133
  position: "absolute",
7909
- top: "100%",
7910
- right: "10px",
7911
- width: 0,
7912
- height: 0,
7913
- borderLeft: "6px solid transparent",
7914
- borderRight: "6px solid transparent",
7915
- borderTop: "6px solid #1F2937"
7916
- }
8134
+ bottom: "calc(100% + 8px)",
8135
+ right: 0,
8136
+ backgroundColor: "#1F2937",
8137
+ color: "white",
8138
+ padding: "8px 12px",
8139
+ borderRadius: "6px",
8140
+ fontSize: "12px",
8141
+ whiteSpace: "nowrap",
8142
+ boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)",
8143
+ zIndex: 100
8144
+ },
8145
+ children: [
8146
+ "This is testnet USDC, and it won't be available on mainnet",
8147
+ /* @__PURE__ */ jsx(
8148
+ "div",
8149
+ {
8150
+ style: {
8151
+ position: "absolute",
8152
+ top: "100%",
8153
+ right: "10px",
8154
+ width: 0,
8155
+ height: 0,
8156
+ borderLeft: "6px solid transparent",
8157
+ borderRight: "6px solid transparent",
8158
+ borderTop: "6px solid #1F2937"
8159
+ }
8160
+ }
8161
+ )
8162
+ ]
7917
8163
  }
7918
8164
  )
7919
8165
  ]
@@ -10010,105 +10256,8 @@ const formatCurrencyWithDecimals = (amount) => {
10010
10256
  maximumFractionDigits: 5
10011
10257
  }).format(rounded);
10012
10258
  };
10013
- const defaultBalanceData = {
10014
- totalBalance: 10333,
10015
- percentageChange: 2.15,
10016
- tradingAccounts: [
10017
- { id: "hyperliquid", name: "HYPERLIQUID", balance: 800 },
10018
- { id: "lighter", name: "LIGHTER", balance: 1200 }
10019
- ],
10020
- freeCollateral: 8e3,
10021
- freeCollateralItems: [
10022
- {
10023
- id: "usdc-eth",
10024
- name: "USDC",
10025
- balance: 3e3,
10026
- subtitle: "USD COIN",
10027
- iconColor: "#2775CA",
10028
- networks: [11155111]
10029
- },
10030
- // Ethereum Sepolia
10031
- {
10032
- id: "usdc-arb",
10033
- name: "USDC",
10034
- balance: 2e3,
10035
- subtitle: "USD COIN",
10036
- iconColor: "#2775CA",
10037
- networks: [42161]
10038
- },
10039
- // Arbitrum
10040
- {
10041
- id: "usdc-base",
10042
- name: "USDC",
10043
- balance: 1500,
10044
- subtitle: "USD COIN",
10045
- iconColor: "#2775CA",
10046
- networks: [84532]
10047
- },
10048
- // Base Sepolia
10049
- {
10050
- id: "weth",
10051
- name: "WETH",
10052
- balance: 500,
10053
- subtitle: "WRAPPED ETH",
10054
- iconColor: "#627EEA",
10055
- networks: [11155111]
10056
- },
10057
- {
10058
- id: "uniswap-pt",
10059
- name: "UNISWAP PT",
10060
- balance: 500,
10061
- iconColor: "#FF007A",
10062
- networks: [11155111]
10063
- },
10064
- {
10065
- id: "pendle-pt",
10066
- name: "PENDLE PT",
10067
- balance: 500,
10068
- iconColor: "#6366F1",
10069
- networks: [11155111]
10070
- }
10071
- ],
10072
- defiPositions: 2333,
10073
- defiPositionsItems: [
10074
- {
10075
- id: "uniswap-v4",
10076
- name: "UNISWAP V4",
10077
- balance: 1166.5,
10078
- iconColor: "#FF007A"
10079
- },
10080
- {
10081
- id: "pendle-pt-defi",
10082
- name: "PENDLE PT",
10083
- balance: 1166.5,
10084
- iconColor: "#6366F1"
10085
- }
10086
- ],
10087
- credit: 2333,
10088
- creditItems: [
10089
- {
10090
- id: "usdc-credit",
10091
- name: "USDC",
10092
- balance: 1e3,
10093
- subtitle: "USD COIN",
10094
- iconColor: "#2775CA"
10095
- },
10096
- {
10097
- id: "uniswap-lp",
10098
- name: "UNISWAP LP",
10099
- balance: 666.5,
10100
- iconColor: "#FF007A"
10101
- },
10102
- {
10103
- id: "pendle-pt-credit",
10104
- name: "PENDLE PT",
10105
- balance: 666.5,
10106
- iconColor: "#6366F1"
10107
- }
10108
- ]
10109
- };
10110
10259
  const SpiceBalance = ({
10111
- balanceData = defaultBalanceData,
10260
+ balanceData,
10112
10261
  isLoading = false,
10113
10262
  styles,
10114
10263
  className = "",
@@ -10204,24 +10353,6 @@ const SpiceBalance = ({
10204
10353
  balanceData.freeCollateralItems,
10205
10354
  balanceData.freeCollateral
10206
10355
  ]);
10207
- useMemo(() => {
10208
- if (balanceData.defiPositionsItems) {
10209
- return balanceData.defiPositionsItems.reduce(
10210
- (sum, item) => sum + item.balance,
10211
- 0
10212
- );
10213
- }
10214
- return balanceData.defiPositions;
10215
- }, [balanceData.defiPositionsItems, balanceData.defiPositions]);
10216
- useMemo(() => {
10217
- if (balanceData.creditItems) {
10218
- return balanceData.creditItems.reduce(
10219
- (sum, item) => sum + item.balance,
10220
- 0
10221
- );
10222
- }
10223
- return balanceData.credit;
10224
- }, [balanceData.creditItems, balanceData.credit]);
10225
10356
  const maskBalance = (value) => {
10226
10357
  return isBalanceVisible ? value : "******";
10227
10358
  };
@@ -11956,7 +12087,7 @@ const LpModal = ({
11956
12087
  };
11957
12088
 
11958
12089
  const useFromInput = () => {
11959
- const [fromAmount, setFromAmount] = useState("");
12090
+ const [fromAmount, setFromAmount] = useState("0");
11960
12091
  return {
11961
12092
  fromAmount,
11962
12093
  setFromAmount
@@ -11964,7 +12095,7 @@ const useFromInput = () => {
11964
12095
  };
11965
12096
 
11966
12097
  const useToInputUpdate = () => {
11967
- const [toAmount, setToAmount] = useState("");
12098
+ const [toAmount, setToAmount] = useState("0");
11968
12099
  const updateToAmount = useCallback((amount) => {
11969
12100
  setToAmount(amount);
11970
12101
  }, []);
@@ -11976,7 +12107,7 @@ const useToInputUpdate = () => {
11976
12107
  };
11977
12108
 
11978
12109
  const useDepositInput = () => {
11979
- const [depositAmount, setDepositAmount] = useState("");
12110
+ const [depositAmount, setDepositAmount] = useState("0");
11980
12111
  return {
11981
12112
  depositAmount,
11982
12113
  setDepositAmount