decane-connect-kit 2.2.2 → 2.2.3

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.cjs CHANGED
@@ -183,6 +183,9 @@ __export(index_exports, {
183
183
  DecaneError: () => DecaneError,
184
184
  DecaneErrorCode: () => DecaneErrorCode,
185
185
  DecaneKit: () => DecaneKit,
186
+ DecaneLogo: () => DecaneLogo,
187
+ DecaneMark: () => DecaneMark,
188
+ DecaneWordmark: () => DecaneWordmark,
186
189
  ExportNotAuthorizedError: () => ExportNotAuthorizedError,
187
190
  InvalidApiKeyError: () => InvalidApiKeyError,
188
191
  InvalidPinError: () => InvalidPinError,
@@ -211,6 +214,7 @@ __export(index_exports, {
211
214
  useSignMessage: () => useSignMessage,
212
215
  useSignTypedData: () => useSignTypedData,
213
216
  useSocialAuth: () => useSocialAuth,
217
+ useSocialBalance: () => useSocialBalance,
214
218
  useSocialWallet: () => useSocialWallet,
215
219
  useWalletSelector: () => useWalletSelector,
216
220
  verifyEmailCode: () => verifyEmailCode
@@ -2735,6 +2739,13 @@ async function signEvmTransaction(tee, chain, tx, jwt) {
2735
2739
  async function signEvmMessage(tee, chain, message, jwt) {
2736
2740
  return tee.sign({ chain, kind: "message", payload: message }, jwt);
2737
2741
  }
2742
+ async function signEvmTypedData(tee, chain, typedData, jwt) {
2743
+ const payload = JSON.stringify(
2744
+ typedData,
2745
+ (_k, v) => typeof v === "bigint" ? v.toString() : v
2746
+ );
2747
+ return tee.sign({ chain, kind: "typedData", payload }, jwt);
2748
+ }
2738
2749
 
2739
2750
  // src/social/signers/solana.ts
2740
2751
  var import_web3 = require("@solana/web3.js");
@@ -2973,10 +2984,7 @@ async function buildPortableBackup(deviceShare, recoveryShare, password, address
2973
2984
  };
2974
2985
  }
2975
2986
 
2976
- // src/social/client.ts
2977
- var DEFAULT_API_BASE = "https://backend.decane.app";
2978
- var DEFAULT_TEE_URL = "https://4405742df08d19abc549a05ade2a7154d98bd87f-8443.dstack-pha-prod9.phala.network";
2979
- var DEFAULT_SESSION_MINUTES = 30;
2987
+ // src/social/balance.ts
2980
2988
  var DEFAULT_RPCS = {
2981
2989
  "evm:1": "https://ethereum.publicnode.com",
2982
2990
  "evm:137": "https://polygon.publicnode.com",
@@ -2988,6 +2996,50 @@ var DEFAULT_RPCS = {
2988
2996
  "evm:84532": "https://base-sepolia.publicnode.com",
2989
2997
  "evm:31337": "http://localhost:8545"
2990
2998
  };
2999
+ var EVM_SYMBOLS = {
3000
+ "evm:137": "MATIC",
3001
+ "evm:56": "BNB"
3002
+ };
3003
+ function solanaEndpoint(chain, rpcUrls) {
3004
+ if (rpcUrls?.[chain]) return rpcUrls[chain];
3005
+ const cluster = chain.slice("solana:".length);
3006
+ return cluster === "devnet" ? "https://api.devnet.solana.com" : "https://api.mainnet-beta.solana.com";
3007
+ }
3008
+ async function fetchBalance(opts) {
3009
+ const { kind, address, chain, rpcUrls } = opts;
3010
+ if (kind === "evm") {
3011
+ const rpcUrl = rpcUrls?.[chain] ?? DEFAULT_RPCS[chain];
3012
+ if (!rpcUrl) {
3013
+ throw new Error(
3014
+ `No RPC URL for ${chain}. Pass rpcUrls: { '${chain}': 'https://...' } in social config.`
3015
+ );
3016
+ }
3017
+ const { JsonRpcProvider, formatEther } = await import("ethers");
3018
+ const wei = await new JsonRpcProvider(rpcUrl).getBalance(address);
3019
+ return { raw: wei, formatted: formatEther(wei), symbol: EVM_SYMBOLS[chain] ?? "ETH", decimals: 18 };
3020
+ }
3021
+ const { Connection, PublicKey, LAMPORTS_PER_SOL } = await import("@solana/web3.js");
3022
+ const lamports = await new Connection(solanaEndpoint(chain, rpcUrls)).getBalance(
3023
+ new PublicKey(address)
3024
+ );
3025
+ return {
3026
+ raw: BigInt(lamports),
3027
+ formatted: String(lamports / LAMPORTS_PER_SOL),
3028
+ symbol: "SOL",
3029
+ decimals: 9
3030
+ };
3031
+ }
3032
+ function formatBalanceDisplay(value) {
3033
+ if (value == null) return "\u2014";
3034
+ const n = Number(value);
3035
+ if (!Number.isFinite(n)) return value;
3036
+ return n === 0 ? "0" : n < 1e-4 ? "<0.0001" : n.toFixed(4).replace(/\.?0+$/, "");
3037
+ }
3038
+
3039
+ // src/social/client.ts
3040
+ var DEFAULT_API_BASE = "https://backend.decane.app";
3041
+ var DEFAULT_TEE_URL = "https://4405742df08d19abc549a05ade2a7154d98bd87f-8443.dstack-pha-prod9.phala.network";
3042
+ var DEFAULT_SESSION_MINUTES = 30;
2991
3043
  function makePersistKey(apiKey) {
2992
3044
  return `decane:social:${apiKey.slice(0, 20)}`;
2993
3045
  }
@@ -3485,6 +3537,23 @@ async function createDecaneConnect(config) {
3485
3537
  const txResponse = await provider.broadcastTransaction(signedTx);
3486
3538
  return txResponse.hash;
3487
3539
  },
3540
+ async signTypedData(req) {
3541
+ const tee = session.requireActive();
3542
+ if (!req.chain.startsWith("evm:")) {
3543
+ throw new CallSequenceError("signTypedData is EVM-only (EIP-712).");
3544
+ }
3545
+ return signEvmTypedData(
3546
+ tee,
3547
+ req.chain,
3548
+ {
3549
+ domain: req.domain,
3550
+ types: req.types,
3551
+ message: req.message,
3552
+ primaryType: req.primaryType
3553
+ },
3554
+ auth?.jwt
3555
+ );
3556
+ },
3488
3557
  async signSolanaTransaction(serializedTx) {
3489
3558
  const tee = session.requireActive();
3490
3559
  let tx;
@@ -3510,6 +3579,42 @@ async function createDecaneConnect(config) {
3510
3579
  getAddresses() {
3511
3580
  return auth?.addresses ?? persisted?.addresses ?? null;
3512
3581
  },
3582
+ // Native-token balance. Read-only public chain data, so it works whenever an
3583
+ // address is known — including while the wallet is locked (no TEE session
3584
+ // needed). `chain` defaults to the first configured EVM chain, else the
3585
+ // first Solana chain.
3586
+ async getBalance(chain) {
3587
+ const addresses = auth?.addresses ?? persisted?.addresses;
3588
+ if (!addresses) throw new CallSequenceError("Not connected \u2014 no wallet address known");
3589
+ const resolvedChain = chain ?? config.chains.find((c) => c.startsWith("evm:")) ?? config.chains.find((c) => c.startsWith("solana:"));
3590
+ if (!resolvedChain) throw new CallSequenceError("No chain configured");
3591
+ const kind = resolvedChain.startsWith("solana:") ? "solana" : "evm";
3592
+ const address = kind === "evm" ? addresses.evm : addresses.solana;
3593
+ if (!address) throw new CallSequenceError(`This wallet has no ${kind} address`);
3594
+ return fetchBalance({ kind, address, chain: resolvedChain, rpcUrls: config.rpcUrls });
3595
+ },
3596
+ // Balances across every configured chain the wallet has an address for.
3597
+ // Per-chain failures resolve to null rather than rejecting the whole call,
3598
+ // so one dead RPC doesn't blank the entire list.
3599
+ async getBalances() {
3600
+ const addresses = auth?.addresses ?? persisted?.addresses;
3601
+ if (!addresses) throw new CallSequenceError("Not connected \u2014 no wallet address known");
3602
+ const targets = config.chains.filter((c) => {
3603
+ const kind = c.startsWith("solana:") ? "solana" : "evm";
3604
+ return kind === "evm" ? !!addresses.evm : !!addresses.solana;
3605
+ });
3606
+ return Promise.all(
3607
+ targets.map(async (chain) => {
3608
+ const kind = chain.startsWith("solana:") ? "solana" : "evm";
3609
+ const address = kind === "evm" ? addresses.evm : addresses.solana;
3610
+ try {
3611
+ return { chain, balance: await fetchBalance({ kind, address, chain, rpcUrls: config.rpcUrls }) };
3612
+ } catch {
3613
+ return { chain, balance: null };
3614
+ }
3615
+ })
3616
+ );
3617
+ },
3513
3618
  async rotateShares(opts) {
3514
3619
  if (!auth) throw new CallSequenceError("Not connected \u2014 call connect() first");
3515
3620
  const tee = session.requireActive();
@@ -3756,6 +3861,31 @@ var CSS_VARS = {
3756
3861
 
3757
3862
  // src/ui/icons.tsx
3758
3863
  var import_react = __toESM(require("react"), 1);
3864
+ var DECAGON_OUTER = "12,2 17.88,3.91 21.51,8.91 21.51,15.09 17.88,20.09 12,22 6.12,20.09 2.49,15.09 2.49,8.91 6.12,3.91";
3865
+ var DECAGON_INNER = "12,7.4 14.7,8.28 16.37,10.58 16.37,13.42 14.7,15.72 12,16.6 9.3,15.72 7.63,13.42 7.63,10.58 9.3,8.28";
3866
+ function DecaneMark({ size = 24, muted = false }) {
3867
+ const color = muted ? "var(--dc-text-muted)" : "var(--dc-accent)";
3868
+ return /* @__PURE__ */ import_react.default.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", "aria-hidden": true, style: { flexShrink: 0, display: "block" } }, /* @__PURE__ */ import_react.default.createElement("polygon", { points: DECAGON_OUTER, fill: color, fillOpacity: muted ? 0.08 : 0.1, stroke: color, strokeWidth: "1.4", strokeLinejoin: "round" }), /* @__PURE__ */ import_react.default.createElement("polygon", { points: DECAGON_INNER, fill: color, fillOpacity: muted ? 0.55 : 0.95 }));
3869
+ }
3870
+ function DecaneWordmark({ size = 15, muted = false }) {
3871
+ return /* @__PURE__ */ import_react.default.createElement(
3872
+ "span",
3873
+ {
3874
+ style: {
3875
+ fontFamily: "var(--dc-font-sans, system-ui, sans-serif)",
3876
+ fontWeight: 800,
3877
+ fontSize: size,
3878
+ letterSpacing: "-0.03em",
3879
+ color: muted ? "var(--dc-text-muted)" : "var(--dc-text)",
3880
+ lineHeight: 1
3881
+ }
3882
+ },
3883
+ "decane"
3884
+ );
3885
+ }
3886
+ function DecaneLogo({ size = 20, muted = false }) {
3887
+ return /* @__PURE__ */ import_react.default.createElement("span", { style: { display: "inline-flex", alignItems: "center", gap: size * 0.34 } }, /* @__PURE__ */ import_react.default.createElement(DecaneMark, { size, muted }), /* @__PURE__ */ import_react.default.createElement(DecaneWordmark, { size: size * 0.78, muted }));
3888
+ }
3759
3889
  function WalletIcon({ src, name, size = 36 }) {
3760
3890
  if (src) {
3761
3891
  return /* @__PURE__ */ import_react.default.createElement(
@@ -4709,40 +4839,17 @@ function useBalance(kind, address, chain, rpcUrls) {
4709
4839
  if (!address || !chain) return;
4710
4840
  let cancelled = false;
4711
4841
  setState((s) => ({ ...s, loading: true }));
4712
- (async () => {
4713
- try {
4714
- if (kind === "evm") {
4715
- const rpcUrl = rpcUrls?.[chain] ?? DEFAULT_RPCS[chain];
4716
- if (!rpcUrl) {
4717
- if (!cancelled) setState({ loading: false, value: null, symbol: "ETH" });
4718
- return;
4719
- }
4720
- const { JsonRpcProvider, formatEther } = await import("ethers");
4721
- const wei = await new JsonRpcProvider(rpcUrl).getBalance(address);
4722
- if (!cancelled) setState({ loading: false, value: formatEther(wei), symbol: "ETH" });
4723
- } else {
4724
- const cluster = chain.slice("solana:".length);
4725
- const endpoint = rpcUrls?.[chain] ?? (cluster === "devnet" ? "https://api.devnet.solana.com" : "https://api.mainnet-beta.solana.com");
4726
- const { Connection, PublicKey, LAMPORTS_PER_SOL } = await import("@solana/web3.js");
4727
- const lamports = await new Connection(endpoint).getBalance(new PublicKey(address));
4728
- if (!cancelled) setState({ loading: false, value: String(lamports / LAMPORTS_PER_SOL), symbol: "SOL" });
4729
- }
4730
- } catch {
4731
- if (!cancelled) setState({ loading: false, value: null, symbol: kind === "evm" ? "ETH" : "SOL" });
4732
- }
4733
- })();
4842
+ fetchBalance({ kind, address, chain, rpcUrls }).then((b) => {
4843
+ if (!cancelled) setState({ loading: false, value: b.formatted, symbol: b.symbol });
4844
+ }).catch(() => {
4845
+ if (!cancelled) setState({ loading: false, value: null, symbol: kind === "evm" ? "ETH" : "SOL" });
4846
+ });
4734
4847
  return () => {
4735
4848
  cancelled = true;
4736
4849
  };
4737
4850
  }, [kind, address, chain, rpcUrls]);
4738
4851
  return state;
4739
4852
  }
4740
- function formatBalance(value) {
4741
- if (value == null) return "\u2014";
4742
- const n = Number(value);
4743
- if (!Number.isFinite(n)) return value;
4744
- return n === 0 ? "0" : n < 1e-4 ? "<0.0001" : n.toFixed(4).replace(/\.?0+$/, "");
4745
- }
4746
4853
  function AddressRow({
4747
4854
  label,
4748
4855
  address,
@@ -4758,7 +4865,7 @@ function AddressRow({
4758
4865
  borderRadius: 10,
4759
4866
  padding: "10px 14px",
4760
4867
  marginBottom: 8
4761
- } }, /* @__PURE__ */ import_react3.default.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 5 } }, /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontSize: 10, fontWeight: 700, color: "var(--dc-text-muted)", letterSpacing: "0.06em", textTransform: "uppercase" } }, label), /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontSize: 11, fontFamily: "monospace", color: "var(--dc-text)" } }, balance.loading ? "\u2026" : `${formatBalance(balance.value)} ${balance.symbol}`)), /* @__PURE__ */ import_react3.default.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8 } }, /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontSize: 13, fontFamily: "monospace", color: "var(--dc-text)", letterSpacing: "0.02em" } }, short), /* @__PURE__ */ import_react3.default.createElement(CopyButton, { value: address })));
4868
+ } }, /* @__PURE__ */ import_react3.default.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 5 } }, /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontSize: 10, fontWeight: 700, color: "var(--dc-text-muted)", letterSpacing: "0.06em", textTransform: "uppercase" } }, label), /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontSize: 11, fontFamily: "monospace", color: "var(--dc-text)" } }, balance.loading ? "\u2026" : `${formatBalanceDisplay(balance.value)} ${balance.symbol}`)), /* @__PURE__ */ import_react3.default.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8 } }, /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontSize: 13, fontFamily: "monospace", color: "var(--dc-text)", letterSpacing: "0.02em" } }, short), /* @__PURE__ */ import_react3.default.createElement(CopyButton, { value: address })));
4762
4869
  }
4763
4870
  function SignInView({
4764
4871
  onGoogleSignIn,
@@ -5135,34 +5242,17 @@ function SocialWalletModal({
5135
5242
  top: 0,
5136
5243
  zIndex: 1,
5137
5244
  background: "linear-gradient(90deg, transparent, var(--dc-accent) 30%, var(--dc-accent) 70%, transparent)"
5138
- } }), /* @__PURE__ */ import_react3.default.createElement("div", { style: { padding: "18px 20px 16px", display: "flex", alignItems: "center", gap: 10 } }, /* @__PURE__ */ import_react3.default.createElement("div", { style: {
5139
- width: 34,
5140
- height: 34,
5141
- borderRadius: 10,
5245
+ } }), /* @__PURE__ */ import_react3.default.createElement("div", { style: { padding: "18px 20px 16px", display: "flex", alignItems: "center", gap: 11 } }, /* @__PURE__ */ import_react3.default.createElement("div", { style: {
5246
+ width: 38,
5247
+ height: 38,
5248
+ borderRadius: 11,
5142
5249
  background: "var(--dc-surface)",
5143
5250
  border: "1px solid var(--dc-border)",
5144
5251
  display: "flex",
5145
5252
  alignItems: "center",
5146
5253
  justifyContent: "center",
5147
5254
  flexShrink: 0
5148
- } }, /* @__PURE__ */ import_react3.default.createElement("svg", { width: "16", height: "18", viewBox: "0 0 16 18", fill: "none" }, /* @__PURE__ */ import_react3.default.createElement(
5149
- "path",
5150
- {
5151
- d: "M8 1L1.5 3.5V8.5C1.5 12.09 4.35 15.4 8 16.5C11.65 15.4 14.5 12.09 14.5 8.5V3.5L8 1Z",
5152
- stroke: "var(--dc-accent)",
5153
- strokeWidth: "1.4",
5154
- strokeLinejoin: "round"
5155
- }
5156
- ), /* @__PURE__ */ import_react3.default.createElement(
5157
- "path",
5158
- {
5159
- d: "M5.5 9L7 10.5L10.5 7",
5160
- stroke: "var(--dc-accent)",
5161
- strokeWidth: "1.4",
5162
- strokeLinecap: "round",
5163
- strokeLinejoin: "round"
5164
- }
5165
- ))), /* @__PURE__ */ import_react3.default.createElement("div", { style: { flex: 1 } }, /* @__PURE__ */ import_react3.default.createElement("div", { style: { fontSize: 15, fontWeight: 800, color: "var(--dc-text)", letterSpacing: "-0.02em" } }, "Social Wallet"), /* @__PURE__ */ import_react3.default.createElement("div", { style: { fontSize: 11, color: "var(--dc-text-muted)", marginTop: 1 } }, "Decane non-custodial \xB7 key split three ways")), /* @__PURE__ */ import_react3.default.createElement(
5255
+ } }, /* @__PURE__ */ import_react3.default.createElement(DecaneMark, { size: 22 })), /* @__PURE__ */ import_react3.default.createElement("div", { style: { flex: 1 } }, /* @__PURE__ */ import_react3.default.createElement("div", { style: { display: "flex", alignItems: "baseline", gap: 6 } }, /* @__PURE__ */ import_react3.default.createElement(DecaneWordmark, { size: 15 }), /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontSize: 13, fontWeight: 700, color: "var(--dc-text-muted)", letterSpacing: "-0.01em" } }, "wallet")), /* @__PURE__ */ import_react3.default.createElement("div", { style: { fontSize: 11, color: "var(--dc-text-muted)", marginTop: 2 } }, "Non-custodial \xB7 key split three ways")), /* @__PURE__ */ import_react3.default.createElement(
5166
5256
  "button",
5167
5257
  {
5168
5258
  onClick: onClose,
@@ -5265,7 +5355,14 @@ function SocialWalletModal({
5265
5355
  }
5266
5356
  },
5267
5357
  disconnecting ? "Signing out\u2026" : "Sign out"
5268
- ))))
5358
+ ))), /* @__PURE__ */ import_react3.default.createElement("div", { style: {
5359
+ padding: "11px 16px",
5360
+ borderTop: "1px solid var(--dc-border)",
5361
+ display: "flex",
5362
+ alignItems: "center",
5363
+ justifyContent: "center",
5364
+ gap: 6
5365
+ } }, /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontSize: 10.5, color: "var(--dc-text-muted)", letterSpacing: "0.02em" } }, "Secured by"), /* @__PURE__ */ import_react3.default.createElement(DecaneMark, { size: 13, muted: true }), /* @__PURE__ */ import_react3.default.createElement(DecaneWordmark, { size: 11, muted: true })))
5269
5366
  );
5270
5367
  return (0, import_react_dom2.createPortal)(modal, document.body);
5271
5368
  }
@@ -5451,6 +5548,21 @@ function DecaneKit({ config, children }) {
5451
5548
  if (!sdk) throw new Error("Social wallet not connected");
5452
5549
  return sdk.signSolanaTransaction(tx);
5453
5550
  }, []);
5551
+ const socialSignTypedData = (0, import_react4.useCallback)(async (req) => {
5552
+ const sdk = socialRef.current;
5553
+ if (!sdk) throw new Error("Social wallet not connected");
5554
+ return sdk.signTypedData({ ...req, chain: req.chain });
5555
+ }, []);
5556
+ const socialGetBalance = (0, import_react4.useCallback)(async (chain) => {
5557
+ const sdk = socialRef.current;
5558
+ if (!sdk) throw new Error("Social wallet not connected");
5559
+ return sdk.getBalance(chain);
5560
+ }, []);
5561
+ const socialGetBalances = (0, import_react4.useCallback)(async () => {
5562
+ const sdk = socialRef.current;
5563
+ if (!sdk) throw new Error("Social wallet not connected");
5564
+ return sdk.getBalances();
5565
+ }, []);
5454
5566
  const socialRotateShares = (0, import_react4.useCallback)(async (opts) => {
5455
5567
  const sdk = socialRef.current;
5456
5568
  if (!sdk) throw new Error("Social wallet not connected");
@@ -5506,7 +5618,10 @@ function DecaneKit({ config, children }) {
5506
5618
  socialDisconnect,
5507
5619
  socialSignMessage,
5508
5620
  socialSendTransaction,
5621
+ socialGetBalance,
5622
+ socialGetBalances,
5509
5623
  socialSignSolanaTransaction,
5624
+ socialSignTypedData,
5510
5625
  socialRotateShares,
5511
5626
  socialExportPortableBackup,
5512
5627
  socialHasRecoveryShare,
@@ -5704,6 +5819,9 @@ function useSocialWallet() {
5704
5819
  socialSignMessage,
5705
5820
  socialSendTransaction,
5706
5821
  socialSignSolanaTransaction,
5822
+ socialSignTypedData,
5823
+ socialGetBalance,
5824
+ socialGetBalances,
5707
5825
  socialRotateShares,
5708
5826
  socialExportPortableBackup,
5709
5827
  socialHasRecoveryShare,
@@ -5740,6 +5858,18 @@ function useSocialWallet() {
5740
5858
  (tx) => run(() => socialSignSolanaTransaction(tx)),
5741
5859
  [socialSignSolanaTransaction]
5742
5860
  );
5861
+ const signTypedData = (0, import_react5.useCallback)(
5862
+ (req) => run(() => socialSignTypedData(req)),
5863
+ [socialSignTypedData]
5864
+ );
5865
+ const getBalance = (0, import_react5.useCallback)(
5866
+ (chain) => run(() => socialGetBalance(chain)),
5867
+ [socialGetBalance]
5868
+ );
5869
+ const getBalances = (0, import_react5.useCallback)(
5870
+ () => run(() => socialGetBalances()),
5871
+ [socialGetBalances]
5872
+ );
5743
5873
  const unlock = (0, import_react5.useCallback)(async () => {
5744
5874
  setError(null);
5745
5875
  try {
@@ -5801,6 +5931,10 @@ function useSocialWallet() {
5801
5931
  signMessage,
5802
5932
  sendTransaction,
5803
5933
  signSolanaTransaction: signSolanaTransaction2,
5934
+ signTypedData,
5935
+ // Balances (native token; read-only, works while locked)
5936
+ getBalance,
5937
+ getBalances,
5804
5938
  // Recovery (2-of-3 Shamir share set)
5805
5939
  rotateShares,
5806
5940
  exportPortableBackup,
@@ -5812,6 +5946,52 @@ function useSocialWallet() {
5812
5946
  clearError: () => setError(null)
5813
5947
  };
5814
5948
  }
5949
+ function useSocialBalance(chain) {
5950
+ const { socialAuth, socialGetBalance } = useDecaneContext();
5951
+ const [balance, setBalance] = (0, import_react5.useState)(null);
5952
+ const [loading, setLoading] = (0, import_react5.useState)(false);
5953
+ const [error, setError] = (0, import_react5.useState)(null);
5954
+ const addrKey = `${socialAuth.addresses?.evm ?? ""}|${socialAuth.addresses?.solana ?? ""}`;
5955
+ const refetch = (0, import_react5.useCallback)(async () => {
5956
+ if (!socialAuth.addresses) {
5957
+ setBalance(null);
5958
+ return;
5959
+ }
5960
+ setLoading(true);
5961
+ setError(null);
5962
+ try {
5963
+ setBalance(await socialGetBalance(chain));
5964
+ } catch (e) {
5965
+ setError(e.message);
5966
+ setBalance(null);
5967
+ } finally {
5968
+ setLoading(false);
5969
+ }
5970
+ }, [socialGetBalance, chain, socialAuth.addresses]);
5971
+ (0, import_react5.useEffect)(() => {
5972
+ let cancelled = false;
5973
+ if (!socialAuth.addresses) {
5974
+ setBalance(null);
5975
+ return;
5976
+ }
5977
+ setLoading(true);
5978
+ setError(null);
5979
+ socialGetBalance(chain).then((b) => {
5980
+ if (!cancelled) setBalance(b);
5981
+ }).catch((e) => {
5982
+ if (!cancelled) {
5983
+ setError(e.message);
5984
+ setBalance(null);
5985
+ }
5986
+ }).finally(() => {
5987
+ if (!cancelled) setLoading(false);
5988
+ });
5989
+ return () => {
5990
+ cancelled = true;
5991
+ };
5992
+ }, [addrKey, chain]);
5993
+ return { balance, loading, error, refetch };
5994
+ }
5815
5995
  function toDecaneError(err) {
5816
5996
  if (err instanceof DecaneError) return err;
5817
5997
  const msg = err instanceof Error ? err.message : err?.message != null ? String(err.message) : String(err);
@@ -6045,6 +6225,9 @@ function useSignTypedData() {
6045
6225
  DecaneError,
6046
6226
  DecaneErrorCode,
6047
6227
  DecaneKit,
6228
+ DecaneLogo,
6229
+ DecaneMark,
6230
+ DecaneWordmark,
6048
6231
  ExportNotAuthorizedError,
6049
6232
  InvalidApiKeyError,
6050
6233
  InvalidPinError,
@@ -6073,6 +6256,7 @@ function useSignTypedData() {
6073
6256
  useSignMessage,
6074
6257
  useSignTypedData,
6075
6258
  useSocialAuth,
6259
+ useSocialBalance,
6076
6260
  useSocialWallet,
6077
6261
  useWalletSelector,
6078
6262
  verifyEmailCode