@openfort/react 1.6.0 → 1.6.1

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.
Files changed (48) hide show
  1. package/build/components/Common/Modal/index.js +14 -0
  2. package/build/components/Common/Modal/index.js.map +1 -1
  3. package/build/components/Openfort/types.d.ts +1 -1
  4. package/build/components/Pages/AssetInventory/SolanaAssetInventory.js +7 -7
  5. package/build/components/Pages/DepositWallet/index.js +15 -10
  6. package/build/components/Pages/DepositWallet/index.js.map +1 -1
  7. package/build/components/Pages/ExportKey/index.js +44 -4
  8. package/build/components/Pages/ExportKey/index.js.map +1 -1
  9. package/build/components/Pages/ExportKey/styles.d.ts +5 -0
  10. package/build/components/Pages/ExportKey/styles.js +47 -0
  11. package/build/components/Pages/ExportKey/styles.js.map +1 -0
  12. package/build/components/Pages/Receive/index.js +2 -2
  13. package/build/components/Pages/SelectToken/SolanaSelectToken.js +7 -7
  14. package/build/components/Pages/SelectToken/index.js +7 -3
  15. package/build/components/Pages/SelectToken/index.js.map +1 -1
  16. package/build/components/Pages/Send/EthereumSend.js +25 -5
  17. package/build/components/Pages/Send/EthereumSend.js.map +1 -1
  18. package/build/components/Pages/Send/SolanaSend.js +23 -4
  19. package/build/components/Pages/Send/SolanaSend.js.map +1 -1
  20. package/build/components/Pages/Send/styles.d.ts +17 -11
  21. package/build/components/Pages/Send/styles.js +104 -49
  22. package/build/components/Pages/Send/styles.js.map +1 -1
  23. package/build/components/Pages/SendConfirmation/ConfirmationSummary.d.ts +3 -1
  24. package/build/components/Pages/SendConfirmation/ConfirmationSummary.js +2 -2
  25. package/build/components/Pages/SendConfirmation/EstimatedFees.d.ts +3 -1
  26. package/build/components/Pages/SendConfirmation/EstimatedFees.js +22 -15
  27. package/build/components/Pages/SendConfirmation/EstimatedFees.js.map +1 -1
  28. package/build/components/Pages/SendConfirmation/SolanaSendConfirmation.js +17 -5
  29. package/build/components/Pages/SendConfirmation/SolanaSendConfirmation.js.map +1 -1
  30. package/build/components/Pages/SendConfirmation/index.js +11 -5
  31. package/build/components/Pages/SendConfirmation/index.js.map +1 -1
  32. package/build/components/Pages/SendConfirmation/styles.d.ts +3 -1
  33. package/build/components/Pages/SendConfirmation/styles.js +20 -6
  34. package/build/components/Pages/SendConfirmation/styles.js.map +1 -1
  35. package/build/components/Pages/SignMessage/index.js +44 -19
  36. package/build/components/Pages/SignMessage/index.js.map +1 -1
  37. package/build/components/Pages/SignMessage/styles.d.ts +2 -3
  38. package/build/components/Pages/SignMessage/styles.js +19 -2
  39. package/build/components/Pages/SignMessage/styles.js.map +1 -1
  40. package/build/hooks/openfort/useSignMessage.d.ts +2 -2
  41. package/build/hooks/openfort/useUI.js +4 -2
  42. package/build/hooks/openfort/useUI.js.map +1 -1
  43. package/build/solana/transfer.d.ts +12 -0
  44. package/build/solana/transfer.js +29 -1
  45. package/build/solana/transfer.js.map +1 -1
  46. package/build/version.d.ts +1 -1
  47. package/build/version.js +1 -1
  48. package/package.json +1 -1
@@ -3,99 +3,154 @@ import styled from '../../../styles/styled/index.js';
3
3
  const Form = styled.form `
4
4
  display: flex;
5
5
  flex-direction: column;
6
- gap: 20px;
6
+ gap: 14px;
7
7
  margin-top: 20px;
8
8
  `;
9
- const Field = styled.div `
9
+ /** Rounded container shared by the "To" and "Amount" boxes. */
10
+ const SendCard = styled.div `
10
11
  display: flex;
11
12
  flex-direction: column;
13
+ gap: 10px;
14
+ padding: 14px 16px;
15
+ border-radius: var(--ck-secondary-button-border-radius);
16
+ border: 1px solid var(--ck-body-divider);
17
+ background: var(--ck-secondary-button-background);
12
18
  text-align: left;
13
19
  `;
14
- const FieldLabel = styled.span `
15
- font-size: 14px;
20
+ const CardLabel = styled.span `
21
+ font-size: 13px;
16
22
  font-weight: 600;
17
- color: var(--ck-body-color);
23
+ color: var(--ck-body-color-muted);
18
24
  `;
19
- const TokenSelectorButton = styled.button `
25
+ /** "To" box: inline label, recipient input, and a Paste button. */
26
+ const ToRow = styled.div `
20
27
  display: flex;
21
28
  align-items: center;
22
- justify-content: space-between;
23
- width: 100%;
24
- margin-top: 12px;
25
- padding: 12px 16px;
26
- border-radius: var(--ck-secondary-button-border-radius);
29
+ gap: 10px;
30
+ `;
31
+ const RecipientInput = styled.input `
32
+ flex: 1;
33
+ min-width: 0;
34
+ border: none;
35
+ background: transparent;
36
+ color: var(--ck-body-color);
37
+ font-size: 15px;
38
+ font-weight: 500;
39
+ padding: 0;
40
+ outline: none;
41
+
42
+ &::placeholder {
43
+ color: var(--ck-body-color-muted);
44
+ }
45
+ `;
46
+ const PasteButton = styled.button `
47
+ flex-shrink: 0;
48
+ padding: 6px 12px;
49
+ border-radius: 16px;
27
50
  border: 1px solid var(--ck-body-divider);
28
- background: var(--ck-secondary-button-background);
51
+ background: var(--ck-body-background);
29
52
  color: var(--ck-body-color);
53
+ font-size: 12px;
54
+ font-weight: 600;
30
55
  cursor: pointer;
31
- transition: background 150ms ease, border-color 150ms ease, color 150ms ease;
32
- text-align: left;
56
+ transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
33
57
 
34
58
  &:hover {
35
59
  background: var(--ck-secondary-button-hover-background);
36
- border-color: var(--ck-body-color-muted);
37
60
  }
38
61
  `;
39
- const TokenSelectorContent = styled.div `
62
+ /** "Amount" box: large amount input with an inline token selector. */
63
+ const AmountRow = styled.div `
40
64
  display: flex;
41
- flex-direction: column;
42
- gap: 2px;
43
- overflow: hidden;
65
+ align-items: center;
66
+ gap: 10px;
44
67
  `;
45
- const TokenSelectorValue = styled.span `
46
- font-size: ${(props) => (props.$primary ? '15px' : '13px')};
47
- font-weight: ${(props) => (props.$primary ? 600 : 500)};
48
- color: ${(props) => {
49
- if (props.$primary)
50
- return 'var(--ck-body-color)';
51
- if (props.$muted)
52
- return 'var(--ck-body-color-muted)';
53
- return 'var(--ck-body-color-muted)';
54
- }};
55
- white-space: nowrap;
56
- overflow: hidden;
57
- text-overflow: ellipsis;
68
+ const AmountField = styled.input `
69
+ flex: 1;
70
+ min-width: 0;
71
+ border: none;
72
+ background: transparent;
73
+ color: var(--ck-body-color);
74
+ font-size: 28px;
75
+ font-weight: 600;
76
+ line-height: 1.1;
77
+ padding: 0;
78
+ outline: none;
79
+
80
+ &::placeholder {
81
+ color: var(--ck-body-color-muted);
82
+ }
58
83
  `;
59
- const TokenSelectorRight = styled.div `
84
+ const PillLogo = styled.span `
60
85
  display: flex;
61
86
  align-items: center;
62
- gap: 6px;
63
- color: var(--ck-body-color-muted);
87
+ width: 22px;
88
+ flex-shrink: 0;
64
89
  `;
65
- const MaxButton = styled.button `
90
+ const TokenPill = styled.button `
91
+ display: flex;
92
+ align-items: center;
93
+ gap: 6px;
66
94
  flex-shrink: 0;
67
- padding: 6px 14px;
68
- border-radius: 16px;
95
+ padding: 7px 12px;
96
+ border-radius: 999px;
69
97
  border: 1px solid var(--ck-body-divider);
70
98
  background: var(--ck-body-background);
71
99
  color: var(--ck-body-color);
72
- font-size: 12px;
100
+ font-size: 14px;
73
101
  font-weight: 600;
74
102
  cursor: pointer;
75
- transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
103
+ transition: background 150ms ease, border-color 150ms ease, color 150ms ease;
76
104
 
77
105
  &:hover {
78
106
  background: var(--ck-secondary-button-hover-background);
107
+ border-color: var(--ck-body-color-muted);
79
108
  }
109
+ `;
110
+ /** Bottom row of the amount box: fiat value (left), balance + Use max (right). */
111
+ const AmountMeta = styled.div `
112
+ display: flex;
113
+ align-items: center;
114
+ justify-content: space-between;
115
+ gap: 8px;
116
+ `;
117
+ const MetaText = styled.span `
118
+ font-size: 13px;
119
+ font-weight: 500;
120
+ color: var(--ck-body-color-muted);
121
+ white-space: nowrap;
122
+ overflow: hidden;
123
+ text-overflow: ellipsis;
124
+ `;
125
+ const BalanceMeta = styled.span `
126
+ display: flex;
127
+ align-items: center;
128
+ gap: 6px;
129
+ flex-shrink: 0;
130
+ font-size: 13px;
131
+ font-weight: 500;
132
+ color: var(--ck-body-color-muted);
133
+ `;
134
+ const UseMaxButton = styled.button `
135
+ border: none;
136
+ background: none;
137
+ padding: 0;
138
+ font-size: 13px;
139
+ font-weight: 600;
140
+ color: var(--ck-accent-color, var(--ck-focus-color, #1a88f8));
141
+ cursor: pointer;
80
142
 
81
143
  &:disabled {
82
144
  opacity: 0.5;
83
145
  cursor: not-allowed;
84
- background: var(--ck-body-background-secondary);
85
146
  }
86
147
  `;
87
- const HelperText = styled.span `
88
- display: block;
89
- margin-top: 8px;
90
- font-size: 13px;
91
- color: var(--ck-body-color-muted);
92
- `;
93
148
  const ErrorText = styled.span `
94
149
  display: block;
95
- margin-top: 6px;
150
+ margin-top: 2px;
96
151
  font-size: 13px;
97
152
  color: var(--ck-body-color-danger);
98
153
  `;
99
154
 
100
- export { ErrorText, Field, FieldLabel, Form, HelperText, MaxButton, TokenSelectorButton, TokenSelectorContent, TokenSelectorRight, TokenSelectorValue };
155
+ export { AmountField, AmountMeta, AmountRow, BalanceMeta, CardLabel, ErrorText, Form, MetaText, PasteButton, PillLogo, RecipientInput, SendCard, ToRow, TokenPill, UseMaxButton };
101
156
  //# sourceMappingURL=styles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"styles.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"styles.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -17,11 +17,13 @@ interface ConfirmationSummaryProps {
17
17
  fee: ReactNode;
18
18
  /** The wallet the funds are paid from. */
19
19
  payWith?: ConfirmationAddress;
20
+ /** Current balance of the pay-with wallet, e.g. "134.32 USDC". */
21
+ balance?: string;
20
22
  }
21
23
  /**
22
24
  * Shared, chain-agnostic transaction preview used by the EVM and Solana send
23
25
  * confirmation screens. Renders the approval-style rows (Total / To / Network /
24
26
  * Estimated fee) plus a "Pay with" card.
25
27
  */
26
- export declare function ConfirmationSummary({ amount, symbol, fiat, to, networkName, networkIcon, fee, payWith, }: ConfirmationSummaryProps): import("react/jsx-runtime").JSX.Element;
28
+ export declare function ConfirmationSummary({ amount, symbol, fiat, to, networkName, networkIcon, fee, payWith, balance, }: ConfirmationSummaryProps): import("react/jsx-runtime").JSX.Element;
27
29
  export {};
@@ -7,8 +7,8 @@ import { SummaryList, SummaryItem, SummaryLabel, AmountValue, FiatValue, Address
7
7
  * confirmation screens. Renders the approval-style rows (Total / To / Network /
8
8
  * Estimated fee) plus a "Pay with" card.
9
9
  */
10
- function ConfirmationSummary({ amount, symbol, fiat, to, networkName, networkIcon, fee, payWith, }) {
11
- return (jsxs(Fragment, { children: [jsxs(SummaryList, { children: [jsxs(SummaryItem, { children: [jsx(SummaryLabel, { children: "Total" }), jsxs(AmountValue, { children: [amount || '0', " ", symbol, fiat ? jsxs(FiatValue, { children: ["\u2248 ", fiat] }) : null] })] }), jsxs(SummaryItem, { children: [jsx(SummaryLabel, { children: "To" }), jsx(AddressValue, { children: to ? (jsx(CopyText, { size: "1rem", value: to.value, children: to.display })) : ('--') })] }), jsxs(SummaryItem, { children: [jsx(SummaryLabel, { children: "Network" }), jsxs(NetworkValue, { children: [networkIcon, networkName] })] }), jsxs(SummaryItem, { children: [jsx(SummaryLabel, { children: "Estimated fee" }), fee] })] }), jsxs(PayWithCard, { children: [jsxs(PayWithMeta, { children: [jsx(SummaryLabel, { children: "Pay with" }), jsx(PayWithAddress, { children: payWith ? (jsx(CopyText, { size: "0.875rem", value: payWith.value, children: payWith.display })) : ('--') })] }), jsxs(PayWithBadge, { children: [amount || '0', " ", symbol] })] })] }));
10
+ function ConfirmationSummary({ amount, symbol, fiat, to, networkName, networkIcon, fee, payWith, balance, }) {
11
+ return (jsxs(Fragment, { children: [jsxs(SummaryList, { children: [jsxs(SummaryItem, { children: [jsx(SummaryLabel, { children: "Total" }), jsxs(AmountValue, { children: [amount || '0', " ", symbol, fiat ? jsxs(FiatValue, { children: ["\u2248 ", fiat] }) : null] })] }), jsxs(SummaryItem, { children: [jsx(SummaryLabel, { children: "To" }), jsx(AddressValue, { children: to ? (jsx(CopyText, { size: "1rem", value: to.value, children: to.display })) : ('--') })] }), jsxs(SummaryItem, { children: [jsx(SummaryLabel, { children: "Network" }), jsxs(NetworkValue, { children: [networkIcon, networkName] })] }), jsxs(SummaryItem, { children: [jsx(SummaryLabel, { children: "Estimated fee" }), fee] })] }), jsxs(PayWithCard, { children: [jsxs(PayWithMeta, { children: [jsx(SummaryLabel, { children: "Pay with" }), jsx(PayWithAddress, { children: payWith ? (jsx(CopyText, { size: "0.875rem", value: payWith.value, children: payWith.display })) : ('--') })] }), balance ? jsx(PayWithBadge, { children: balance }) : null] })] }));
12
12
  }
13
13
 
14
14
  export { ConfirmationSummary };
@@ -8,6 +8,8 @@ type EstimatedFeesProps = {
8
8
  nativeSymbol: string;
9
9
  enabled?: boolean;
10
10
  hideInfoIcon?: boolean;
11
+ /** When fees are sponsored, show the estimate struck through next to "Sponsored". */
12
+ sponsored?: boolean;
11
13
  };
12
- export declare const EstimatedFees: ({ account, to, value, data, chainId, nativeSymbol, enabled, hideInfoIcon, }: EstimatedFeesProps) => import("react/jsx-runtime").JSX.Element;
14
+ export declare const EstimatedFees: ({ account, to, value, data, chainId, nativeSymbol, enabled, hideInfoIcon, sponsored, }: EstimatedFeesProps) => import("react/jsx-runtime").JSX.Element;
13
15
  export {};
@@ -1,4 +1,4 @@
1
- import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { createPublicClient, http, formatUnits } from 'viem';
3
3
  import { useEthereumWalletAssets } from '../../../ethereum/hooks/useEthereumWalletAssets.js';
4
4
  import { useAsyncData } from '../../../shared/hooks/useAsyncData.js';
@@ -7,7 +7,7 @@ import { getDefaultEthereumRpcUrl } from '../../../utils/rpc.js';
7
7
  import Tooltip from '../../Common/Tooltip/index.js';
8
8
  import { useOpenfort } from '../../Openfort/useOpenfort.js';
9
9
  import { formatBalance } from '../Send/utils.js';
10
- import { InfoIconWrapper } from './styles.js';
10
+ import { InfoIconWrapper, FeeStrike, SponsoredText } from './styles.js';
11
11
 
12
12
  const InfoIcon = () => (jsxs("svg", { "aria-hidden": "true", width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsx("circle", { cx: "7", cy: "7", r: "6", stroke: "currentColor", strokeWidth: "1.5" }), jsx("path", { d: "M7 10V6.5M7 4.5H7.005", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })] }));
13
13
  const usdFormatter = new Intl.NumberFormat('en-US', {
@@ -16,8 +16,8 @@ const usdFormatter = new Intl.NumberFormat('en-US', {
16
16
  minimumFractionDigits: 2,
17
17
  maximumFractionDigits: 4,
18
18
  });
19
- const EstimatedFees = ({ account, to, value, data, chainId, nativeSymbol, enabled = true, hideInfoIcon = false, }) => {
20
- var _a, _b, _c;
19
+ const EstimatedFees = ({ account, to, value, data, chainId, nativeSymbol, enabled = true, hideInfoIcon = false, sponsored = false, }) => {
20
+ var _a, _b, _c, _d;
21
21
  const { walletConfig } = useOpenfort();
22
22
  const { data: assets } = useEthereumWalletAssets();
23
23
  const pricePerToken = (_c = (_b = (_a = assets === null || assets === void 0 ? void 0 : assets.find((a) => a.type === 'native')) === null || _a === void 0 ? void 0 : _a.metadata) === null || _b === void 0 ? void 0 : _b.fiat) === null || _c === void 0 ? void 0 : _c.value;
@@ -49,19 +49,26 @@ const EstimatedFees = ({ account, to, value, data, chainId, nativeSymbol, enable
49
49
  },
50
50
  enabled: enabled && !!account && !!to && !!chainId,
51
51
  });
52
- // Handle query states
53
- if (!gas.data || gas.error) {
54
- return jsx(Fragment, { children: "--" });
52
+ // Format the estimate (USD when a native price is known, otherwise native units).
53
+ const gasUnits = (_d = gas.data) === null || _d === void 0 ? void 0 : _d.gasLimit;
54
+ let feeText = null;
55
+ if (gas.data && !gas.error) {
56
+ const gasCost = gas.data.estimatedCost;
57
+ if (pricePerToken !== undefined) {
58
+ feeText = `≈ ${usdFormatter.format(Number.parseFloat(formatUnits(gasCost, 18)) * pricePerToken)}`;
59
+ }
60
+ else {
61
+ feeText = `≈ ${formatBalance(gasCost, 18)} ${nativeSymbol}`;
62
+ }
55
63
  }
56
- const gasCost = gas.data.estimatedCost;
57
- const gasUnits = gas.data.gasLimit;
58
- if (pricePerToken !== undefined) {
59
- const gasCostInEth = Number.parseFloat(formatUnits(gasCost, 18));
60
- const gasCostInUsd = gasCostInEth * pricePerToken;
61
- return (jsxs(Fragment, { children: ["\u2248 ", usdFormatter.format(gasCostInUsd), !hideInfoIcon && (jsx(Tooltip, { message: `${gasUnits.toString()} gas units (paid in ${nativeSymbol})`, delay: 0.2, children: jsx(InfoIconWrapper, { children: jsx(InfoIcon, {}) }) }))] }));
64
+ const info = !hideInfoIcon && gasUnits ? (jsx(Tooltip, { message: `${gasUnits.toString()} gas units (paid in ${nativeSymbol})`, delay: 0.2, children: jsx(InfoIconWrapper, { children: jsx(InfoIcon, {}) }) })) : null;
65
+ // Sponsored: show what it would have cost, struck through, next to "Sponsored".
66
+ if (sponsored) {
67
+ return (jsxs(Fragment, { children: [feeText && jsx(FeeStrike, { children: feeText }), jsx(SponsoredText, { children: "Sponsored" })] }));
62
68
  }
63
- // Fallback to native token if price not available
64
- return (jsxs(Fragment, { children: ["\u2248 ", formatBalance(gasCost, 18), " ", nativeSymbol, !hideInfoIcon && (jsx(Tooltip, { message: `${gasUnits.toString()} gas units`, delay: 0.2, children: jsx(InfoIconWrapper, { children: jsx(InfoIcon, {}) }) }))] }));
69
+ if (!feeText)
70
+ return jsx(Fragment, { children: "--" });
71
+ return (jsxs(Fragment, { children: [feeText, info] }));
65
72
  };
66
73
 
67
74
  export { EstimatedFees };
@@ -1 +1 @@
1
- {"version":3,"file":"EstimatedFees.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"EstimatedFees.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,10 +1,12 @@
1
- import { jsxs, jsx } from 'react/jsx-runtime';
1
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import { ChainTypeEnum } from '@openfort/openfort-js';
3
3
  import { useState, useEffect } from 'react';
4
4
  import { parseUnits } from 'viem';
5
+ import { currencyLogoUrl } from '../../../constants/logos.js';
6
+ import { useAsyncData } from '../../../shared/hooks/useAsyncData.js';
5
7
  import { getExplorerUrl } from '../../../shared/utils/explorer.js';
6
8
  import { useSolanaEmbeddedWallet } from '../../../solana/hooks/useSolanaEmbeddedWallet.js';
7
- import { sendSplTokenGasless, sendSplToken, sendSolGasless, sendSol } from '../../../solana/transfer.js';
9
+ import { estimateSolanaTransferFeeLamports, sendSplTokenGasless, sendSplToken, sendSolGasless, sendSol } from '../../../solana/transfer.js';
8
10
  import 'detect-browser';
9
11
  import { truncateSolanaAddress } from '../../../utils/format.js';
10
12
  import Button from '../../Common/Button/index.js';
@@ -13,12 +15,13 @@ import { ModalHeading, ModalBody } from '../../Common/Modal/styles.js';
13
15
  import { routes } from '../../Openfort/types.js';
14
16
  import { useOpenfort } from '../../Openfort/useOpenfort.js';
15
17
  import { PageContent } from '../../PageContent/index.js';
18
+ import { formatBalance, formatBalanceWithSymbol } from '../Send/utils.js';
16
19
  import { ConfirmationSummary } from './ConfirmationSummary.js';
17
- import { ButtonRow, SponsoredFee, FeesValue, ErrorContainer, ErrorTitle, ErrorMessage } from './styles.js';
20
+ import { ButtonRow, FeesValue, FeeStrike, SponsoredText, ErrorContainer, ErrorTitle, ErrorMessage } from './styles.js';
18
21
 
19
22
  const SOL_DECIMALS = 9;
20
23
  const SolanaSendConfirmation = () => {
21
- var _a, _b;
24
+ var _a, _b, _c;
22
25
  const { sendForm, setRoute, publishableKey, triggerResize, walletConfig } = useOpenfort();
23
26
  const wallet = useSolanaEmbeddedWallet();
24
27
  const address = wallet.status === 'connected' ? wallet.address : undefined;
@@ -32,6 +35,15 @@ const SolanaSendConfirmation = () => {
32
35
  const decimals = asset.type === 'spl' ? asset.metadata.decimals : SOL_DECIMALS;
33
36
  // Fees are sponsored from config (the SVM counterpart of ethereumFeeSponsorshipId).
34
37
  const isSponsored = Boolean((_b = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.solana) === null || _b === void 0 ? void 0 : _b.sponsorFees);
38
+ // Real network fee from the RPC (getFeeForMessage). Null while loading or on failure.
39
+ const feeQuery = useAsyncData({
40
+ queryKey: ['sol-fee', address, recipient, rpcUrl],
41
+ queryFn: () => address && recipient && rpcUrl
42
+ ? estimateSolanaTransferFeeLamports({ from: address, to: recipient, rpcUrl })
43
+ : Promise.resolve(null),
44
+ enabled: Boolean(address && recipient && rpcUrl),
45
+ });
46
+ const feeText = feeQuery.data != null ? `≈ ${formatBalance(feeQuery.data, SOL_DECIMALS)} SOL` : null;
35
47
  const [isLoading, setIsLoading] = useState(false);
36
48
  const [signature, setSignature] = useState(null);
37
49
  const [error, setError] = useState(null);
@@ -114,7 +126,7 @@ const SolanaSendConfirmation = () => {
114
126
  if (signature) {
115
127
  return (jsxs(PageContent, { children: [jsx(Loader, { isSuccess: true, header: "Transfer sent", description: `${amount} ${symbol} sent successfully` }), jsxs(ButtonRow, { children: [jsx(Button, { variant: "primary", onClick: handleViewExplorer, children: "View on Explorer" }), jsx(Button, { variant: "secondary", onClick: handleFinish, children: "Back to profile" })] })] }));
116
128
  }
117
- return (jsxs(PageContent, { onBack: routes.SOL_SEND, children: [jsx(ModalHeading, { children: "Confirm transfer" }), jsx(ModalBody, { children: "Review the transaction before sending." }), jsx(ConfirmationSummary, { amount: amount || '0', symbol: symbol, to: recipient ? { display: truncateSolanaAddress(recipient), value: recipient } : undefined, networkName: `Solana ${cluster.charAt(0).toUpperCase()}${cluster.slice(1)}`, payWith: address ? { display: truncateSolanaAddress(address), value: address } : undefined, fee: isSponsored ? jsx(SponsoredFee, { children: "Sponsored \u00B7 gasless" }) : jsx(FeesValue, { children: "Network fee" }) }), error && (jsxs(ErrorContainer, { children: [jsx(ErrorTitle, { children: "Transaction failed" }), jsx(ErrorMessage, { children: error })] })), jsxs(ButtonRow, { children: [jsx(Button, { variant: "primary", onClick: handleConfirm, disabled: !address || isLoading, waiting: isLoading, children: isLoading ? 'Confirming...' : 'Confirm' }), jsx(Button, { variant: "secondary", onClick: () => setRoute(routes.SOL_SEND), disabled: isLoading, children: "Cancel" })] })] }));
129
+ return (jsxs(PageContent, { onBack: routes.SOL_SEND, children: [jsx(ModalHeading, { children: "Confirm transfer" }), jsx(ModalBody, { children: "Review the transaction before sending." }), jsx(ConfirmationSummary, { amount: amount || '0', symbol: symbol, to: recipient ? { display: truncateSolanaAddress(recipient), value: recipient } : undefined, networkName: `Solana ${cluster.charAt(0).toUpperCase()}${cluster.slice(1)}`, networkIcon: currencyLogoUrl('SOL') ? jsx("img", { src: (_c = currencyLogoUrl('SOL')) !== null && _c !== void 0 ? _c : '', alt: "" }) : undefined, balance: formatBalanceWithSymbol(asset.balance, decimals, symbol), payWith: address ? { display: truncateSolanaAddress(address), value: address } : undefined, fee: jsx(FeesValue, { children: isSponsored ? (jsxs(Fragment, { children: [feeText && jsx(FeeStrike, { children: feeText }), " ", jsx(SponsoredText, { children: "Sponsored" })] })) : ((feeText !== null && feeText !== void 0 ? feeText : '--')) }) }), error && (jsxs(ErrorContainer, { children: [jsx(ErrorTitle, { children: "Transaction failed" }), jsx(ErrorMessage, { children: error })] })), jsxs(ButtonRow, { children: [jsx(Button, { variant: "primary", onClick: handleConfirm, disabled: !address || isLoading, waiting: isLoading, children: isLoading ? 'Confirming...' : 'Confirm' }), jsx(Button, { variant: "secondary", onClick: () => setRoute(routes.SOL_SEND), disabled: isLoading, children: "Cancel" })] })] }));
118
130
  };
119
131
 
120
132
  export { SolanaSendConfirmation };
@@ -1 +1 @@
1
- {"version":3,"file":"SolanaSendConfirmation.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"SolanaSendConfirmation.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -3,6 +3,7 @@ import { ChainTypeEnum } from '@openfort/openfort-js';
3
3
  import { useMemo, useEffect, useState, useRef } from 'react';
4
4
  import { isAddress, createPublicClient, http, erc20Abi, parseUnits, encodeFunctionData } from 'viem';
5
5
  import { TickIcon } from '../../../assets/icons.js';
6
+ import { chainLogoUrl } from '../../../constants/logos.js';
6
7
  import { useEthereumEmbeddedWallet } from '../../../ethereum/hooks/useEthereumEmbeddedWallet.js';
7
8
  import { useEthereumWalletAssets } from '../../../ethereum/hooks/useEthereumWalletAssets.js';
8
9
  import { useBalance } from '../../../hooks/useBalance.js';
@@ -20,16 +21,16 @@ import { ModalHeading, ModalBody } from '../../Common/Modal/styles.js';
20
21
  import { routes } from '../../Openfort/types.js';
21
22
  import { useOpenfort } from '../../Openfort/useOpenfort.js';
22
23
  import { PageContent } from '../../PageContent/index.js';
23
- import { sanitizeForParsing, isSameToken, getAssetDecimals, getAssetSymbol } from '../Send/utils.js';
24
+ import { sanitizeForParsing, isSameToken, getAssetDecimals, getAssetSymbol, formatBalanceWithSymbol } from '../Send/utils.js';
24
25
  import { ConfirmationSummary } from './ConfirmationSummary.js';
25
26
  import { EstimatedFees } from './EstimatedFees.js';
26
- import { ButtonRow, SponsoredFee, FeesValue, StatusMessage, ErrorContainer, ErrorTitle, ErrorMessage, ErrorAction } from './styles.js';
27
+ import { ButtonRow, FeesValue, StatusMessage, ErrorContainer, ErrorTitle, ErrorMessage, ErrorAction } from './styles.js';
27
28
 
28
29
  const SendConfirmation = () => {
29
- var _a, _b, _c, _d, _e, _f;
30
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
30
31
  const wallet = useEthereumEmbeddedWallet();
31
32
  const { chainType } = useOpenfortCore();
32
- const { sendForm, setRoute, triggerResize, walletConfig } = useOpenfort();
33
+ const { sendForm, setRoute, triggerResize, walletConfig, chains } = useOpenfort();
33
34
  const address = wallet.status === 'connected' ? wallet.address : undefined;
34
35
  const chainId = wallet.status === 'connected' ? wallet.chainId : undefined;
35
36
  const blockExplorerUrl = chainId ? getExplorerUrl(ChainTypeEnum.EVM, { chainId }) : undefined;
@@ -316,12 +317,17 @@ const SendConfirmation = () => {
316
317
  return null;
317
318
  return `$${(n * perToken).toFixed(2)}`;
318
319
  }, [(_f = (_e = token.metadata) === null || _e === void 0 ? void 0 : _e.fiat) === null || _f === void 0 ? void 0 : _f.value, normalisedAmount]);
320
+ // Prefer the configured chain's display name over the numeric id fallback.
321
+ const networkName = (_h = (_g = chains === null || chains === void 0 ? void 0 : chains.find((c) => c.id === chainId)) === null || _g === void 0 ? void 0 : _g.name) !== null && _h !== void 0 ? _h : getChainName(chainId !== null && chainId !== void 0 ? chainId : 0);
322
+ const balanceLabel = currentBalance !== undefined
323
+ ? formatBalanceWithSymbol(currentBalance, (_j = getAssetDecimals(token)) !== null && _j !== void 0 ? _j : 18, getAssetSymbol(token))
324
+ : undefined;
319
325
  if (isSuccess) {
320
326
  const successAmount = normalisedAmount || '0';
321
327
  const successSymbol = getAssetSymbol(token);
322
328
  return (jsxs(PageContent, { children: [jsx(Loader, { isSuccess: true, header: "Transfer Sent", description: `${successAmount} ${successSymbol} sent successfully` }), jsxs(ButtonRow, { children: [blockExplorerUrl && (jsx(Button, { variant: "primary", onClick: handleOpenBlockExplorer, children: "View on Explorer" })), jsx(Button, { variant: "secondary", onClick: handleFinish, children: "Back to profile" })] })] }));
323
329
  }
324
- return (jsxs(PageContent, { children: [jsx(ModalHeading, { children: "Confirm transfer" }), jsx(ModalBody, { children: "Review the transaction before sending." }), jsx(ConfirmationSummary, { amount: normalisedAmount || '0', symbol: getAssetSymbol(token), fiat: fiatTotal, to: recipientAddress ? { display: truncateEthAddress(recipientAddress), value: recipientAddress } : undefined, networkName: getChainName(chainId !== null && chainId !== void 0 ? chainId : 0), payWith: address ? { display: truncateEthAddress(address), value: address } : undefined, fee: isSponsored ? (jsx(SponsoredFee, { children: "Sponsored \u00B7 gasless" })) : (jsx(FeesValue, { children: jsx(EstimatedFees, { account: address, to: token.type === 'erc20' ? token.address : recipientAddress, value: token.type === 'native' && parsedAmount ? parsedAmount : undefined, data: transferData, chainId: chainId, nativeSymbol: nativeSymbol, enabled: Boolean(address && recipientAddress && parsedAmount && parsedAmount > BigInt(0)), hideInfoIcon: false }) })) }), insufficientBalance && !isSuccess && (jsx(StatusMessage, { "$status": "error", children: "Insufficient balance for this transfer." })), errorDetails && (jsxs(ErrorContainer, { children: [jsx(ErrorTitle, { children: errorDetails.title }), jsx(ErrorMessage, { children: errorDetails.message }), errorDetails.action && jsx(ErrorAction, { children: errorDetails.action })] })), jsxs(ButtonRow, { children: [jsx(Button, { variant: "primary", onClick: isSuccess ? handleOpenBlockExplorer : handleConfirm, disabled: isSuccess
330
+ return (jsxs(PageContent, { children: [jsx(ModalHeading, { children: "Confirm transfer" }), jsx(ModalBody, { children: "Review the transaction before sending." }), jsx(ConfirmationSummary, { amount: normalisedAmount || '0', symbol: getAssetSymbol(token), fiat: fiatTotal, to: recipientAddress ? { display: truncateEthAddress(recipientAddress), value: recipientAddress } : undefined, networkName: networkName, networkIcon: chainLogoUrl(chainId) ? jsx("img", { src: (_k = chainLogoUrl(chainId)) !== null && _k !== void 0 ? _k : '', alt: "" }) : undefined, balance: balanceLabel, payWith: address ? { display: truncateEthAddress(address), value: address } : undefined, fee: jsx(FeesValue, { children: jsx(EstimatedFees, { account: address, to: token.type === 'erc20' ? token.address : recipientAddress, value: token.type === 'native' && parsedAmount ? parsedAmount : undefined, data: transferData, chainId: chainId, nativeSymbol: nativeSymbol, enabled: Boolean(address && recipientAddress && parsedAmount && parsedAmount > BigInt(0)), sponsored: isSponsored, hideInfoIcon: false }) }) }), insufficientBalance && !isSuccess && (jsx(StatusMessage, { "$status": "error", children: "Insufficient balance for this transfer." })), errorDetails && (jsxs(ErrorContainer, { children: [jsx(ErrorTitle, { children: errorDetails.title }), jsx(ErrorMessage, { children: errorDetails.message }), errorDetails.action && jsx(ErrorAction, { children: errorDetails.action })] })), jsxs(ButtonRow, { children: [jsx(Button, { variant: "primary", onClick: isSuccess ? handleOpenBlockExplorer : handleConfirm, disabled: isSuccess
325
331
  ? false
326
332
  : isLoading ||
327
333
  Boolean(transactionHash) ||
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -8,7 +8,9 @@ export declare const FeesValue: import("styled-components").StyledComponent<"spa
8
8
  }, never>;
9
9
  export declare const FiatValue: import("styled-components").StyledComponent<"span", any, {}, never>;
10
10
  export declare const NetworkValue: import("styled-components").StyledComponent<"span", any, {}, never>;
11
- export declare const SponsoredFee: import("styled-components").StyledComponent<"span", any, {}, never>;
11
+ /** The would-be fee, struck through, shown next to "Sponsored". */
12
+ export declare const FeeStrike: import("styled-components").StyledComponent<"span", any, {}, never>;
13
+ export declare const SponsoredText: import("styled-components").StyledComponent<"span", any, {}, never>;
12
14
  export declare const PayWithCard: import("styled-components").StyledComponent<"div", any, {}, never>;
13
15
  export declare const PayWithMeta: import("styled-components").StyledComponent<"div", any, {}, never>;
14
16
  export declare const PayWithAddress: import("styled-components").StyledComponent<"span", any, {}, never>;
@@ -1,4 +1,5 @@
1
1
  import styled from '../../../styles/styled/index.js';
2
+ import { ButtonContainer } from '../../Common/Button/styles.js';
2
3
 
3
4
  const SummaryList = styled.div `
4
5
  display: flex;
@@ -64,8 +65,14 @@ const NetworkValue = styled(SummaryValue) `
64
65
  border-radius: 50%;
65
66
  }
66
67
  `;
67
- const SponsoredFee = styled(SummaryValue) `
68
+ /** The would-be fee, struck through, shown next to "Sponsored". */
69
+ const FeeStrike = styled.span `
70
+ text-decoration: line-through;
71
+ opacity: 0.55;
72
+ `;
73
+ const SponsoredText = styled.span `
68
74
  color: var(--ck-body-color-valid, #16a34a);
75
+ font-weight: 600;
69
76
  `;
70
77
  const PayWithCard = styled.div `
71
78
  display: flex;
@@ -94,8 +101,8 @@ const PayWithBadge = styled.span `
94
101
  border-radius: 999px;
95
102
  font-size: 13px;
96
103
  font-weight: 600;
97
- color: var(--ck-body-color-valid, #16a34a);
98
- background: var(--ck-body-background, rgba(22, 163, 74, 0.12));
104
+ color: var(--ck-body-color);
105
+ background: var(--ck-body-background);
99
106
  `;
100
107
  const InfoIconWrapper = styled.span `
101
108
  color: var(--ck-body-color-muted);
@@ -115,9 +122,16 @@ const InfoIconWrapper = styled.span `
115
122
  `;
116
123
  const ButtonRow = styled.div `
117
124
  display: flex;
118
- flex-direction: column;
119
- gap: 4px;
125
+ gap: 12px;
120
126
  margin-top: 24px;
127
+
128
+ > button {
129
+ flex: 1;
130
+ }
131
+
132
+ ${ButtonContainer} {
133
+ margin: 0;
134
+ }
121
135
  `;
122
136
  const StatusMessage = styled.div `
123
137
  margin-top: 16px;
@@ -157,5 +171,5 @@ const ErrorAction = styled.div `
157
171
  line-height: 1.4;
158
172
  `;
159
173
 
160
- export { AddressValue, AmountValue, ButtonRow, ErrorAction, ErrorContainer, ErrorMessage, ErrorTitle, FeesValue, FiatValue, InfoIconWrapper, NetworkValue, PayWithAddress, PayWithBadge, PayWithCard, PayWithMeta, SponsoredFee, StatusMessage, SummaryItem, SummaryLabel, SummaryList };
174
+ export { AddressValue, AmountValue, ButtonRow, ErrorAction, ErrorContainer, ErrorMessage, ErrorTitle, FeeStrike, FeesValue, FiatValue, InfoIconWrapper, NetworkValue, PayWithAddress, PayWithBadge, PayWithCard, PayWithMeta, SponsoredText, StatusMessage, SummaryItem, SummaryLabel, SummaryList };
161
175
  //# sourceMappingURL=styles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"styles.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"styles.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,11 +1,14 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { ChainTypeEnum } from '@openfort/openfort-js';
2
3
  import { useState, useRef, useEffect } from 'react';
3
4
  import { useEthereumEmbeddedWallet } from '../../../ethereum/hooks/useEthereumEmbeddedWallet.js';
5
+ import { useOpenfortCore } from '../../../openfort/useOpenfort.js';
6
+ import { useSolanaEmbeddedWallet } from '../../../solana/hooks/useSolanaEmbeddedWallet.js';
4
7
  import Button from '../../Common/Button/index.js';
5
8
  import { CopyButton } from '../../Common/CopyToClipboard/CopyButton.js';
6
9
  import { useOpenfort } from '../../Openfort/useOpenfort.js';
7
10
  import { PageContent } from '../../PageContent/index.js';
8
- import { SuccessWrap, SuccessCircle, SuccessTitle, SignaturePreview, SignContent, Subtitle, MessageBox, CopyRow, ErrorText, DataList, DataItem, DataKey } from './styles.js';
11
+ import { SuccessWrap, SuccessCircle, SuccessTitle, SignaturePreview, SignContent, Subtitle, MessageBox, Footer, CopyRow, ErrorText, DataList, DataItem, DataKey } from './styles.js';
9
12
 
10
13
  /** Renders an EIP-712 value as a readable nested bullet list. */
11
14
  function DataNode({ value }) {
@@ -17,17 +20,29 @@ function DataNode({ value }) {
17
20
  const SignMessage = () => {
18
21
  var _a;
19
22
  const { signRequest, setSignRequest, setOpen, uiConfig, triggerResize } = useOpenfort();
23
+ const { chainType } = useOpenfortCore();
20
24
  const wallet = useEthereumEmbeddedWallet();
25
+ const solana = useSolanaEmbeddedWallet();
21
26
  const [signing, setSigning] = useState(false);
22
27
  const [error, setError] = useState(null);
23
28
  const [signature, setSignature] = useState(null);
24
29
  const settledRef = useRef(false);
30
+ const mountedRef = useRef(false);
25
31
  // Reject the pending request if the screen unmounts before signing (the user
26
- // closed the modal or navigated away).
32
+ // closed the modal or navigated away). React StrictMode invokes effect cleanup
33
+ // on a dev-only synchronous remount, so defer the reject to a microtask: the
34
+ // immediate remount flips mountedRef back to true and cancels the spurious
35
+ // "User rejected" that would otherwise fire while the wallet UI is still open.
27
36
  useEffect(() => {
37
+ mountedRef.current = true;
38
+ const request = signRequest;
28
39
  return () => {
29
- if (!settledRef.current)
30
- signRequest === null || signRequest === void 0 ? void 0 : signRequest.reject(new Error('User rejected the signature request'));
40
+ mountedRef.current = false;
41
+ queueMicrotask(() => {
42
+ if (!mountedRef.current && !settledRef.current) {
43
+ request === null || request === void 0 ? void 0 : request.reject(new Error('User rejected the signature request'));
44
+ }
45
+ });
31
46
  };
32
47
  }, [signRequest]);
33
48
  // Content height changes between the views; re-measure.
@@ -46,16 +61,26 @@ const SignMessage = () => {
46
61
  setError(null);
47
62
  setSigning(true);
48
63
  try {
49
- const provider = await ((_a = wallet.activeWallet) === null || _a === void 0 ? void 0 : _a.getProvider());
50
- const address = wallet.address;
51
- if (!provider || !address)
52
- throw new Error('No connected wallet to sign with');
53
- const signed = (signRequest.kind === 'message'
54
- ? await provider.request({ method: 'personal_sign', params: [signRequest.message, address] })
55
- : await provider.request({
56
- method: 'eth_signTypedData_v4',
57
- params: [address, JSON.stringify(signRequest.typedData)],
58
- }));
64
+ let signed;
65
+ if (chainType === ChainTypeEnum.SVM) {
66
+ if (signRequest.kind !== 'message')
67
+ throw new Error('Typed data signing is not supported on Solana.');
68
+ if (solana.status !== 'connected')
69
+ throw new Error('No connected wallet to sign with');
70
+ signed = await solana.provider.signMessage(signRequest.message);
71
+ }
72
+ else {
73
+ const provider = await ((_a = wallet.activeWallet) === null || _a === void 0 ? void 0 : _a.getProvider());
74
+ const address = wallet.address;
75
+ if (!provider || !address)
76
+ throw new Error('No connected wallet to sign with');
77
+ signed = (signRequest.kind === 'message'
78
+ ? await provider.request({ method: 'personal_sign', params: [signRequest.message, address] })
79
+ : await provider.request({
80
+ method: 'eth_signTypedData_v4',
81
+ params: [address, JSON.stringify(signRequest.typedData)],
82
+ }));
83
+ }
59
84
  settledRef.current = true;
60
85
  signRequest.resolve(signed);
61
86
  setSignature(signed);
@@ -70,11 +95,11 @@ const SignMessage = () => {
70
95
  if (signature) {
71
96
  return (jsx(PageContent, { onBack: null, children: jsxs(SuccessWrap, { children: [jsx(SuccessCircle, { children: jsx("svg", { width: "28", height: "28", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: jsx("path", { d: "M20 6 9 17l-5-5", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) }), jsx(SuccessTitle, { children: "Message signed" }), jsx(SignaturePreview, { children: `${signature.slice(0, 14)}…${signature.slice(-12)}` }), jsx(Button, { variant: "primary", onClick: close, children: "Done" })] }) }));
72
97
  }
73
- return (jsx(PageContent, { onBack: null, children: jsxs(SignContent, { children: [jsxs(Subtitle, { children: [appName, " wants you to sign a message. It will not cost you any fees."] }), signRequest.kind === 'message' ? (jsx(MessageBox, { children: signRequest.message })) : (jsxs(Fragment, { children: [jsx(MessageBox, { "$scroll": true, children: jsx(DataNode, { value: {
74
- domain: signRequest.typedData.domain,
75
- primaryType: signRequest.typedData.primaryType,
76
- message: signRequest.typedData.message,
77
- } }) }), jsx(CopyRow, { children: jsx(CopyButton, { value: JSON.stringify(signRequest.typedData, null, 2), children: "Copy to clipboard" }) })] })), error && jsx(ErrorText, { children: error }), jsx(Button, { variant: "primary", onClick: handleSign, waiting: signing, disabled: signing, arrow: true, children: "Sign and continue" })] }) }));
98
+ return (jsx(PageContent, { onBack: null, children: jsxs(SignContent, { children: [jsxs(Subtitle, { children: [appName, " wants you to sign a message. It will not cost you any fees."] }), signRequest.kind === 'message' ? (jsx(MessageBox, { children: signRequest.message })) : (jsx(MessageBox, { children: jsx(DataNode, { value: {
99
+ domain: signRequest.typedData.domain,
100
+ primaryType: signRequest.typedData.primaryType,
101
+ message: signRequest.typedData.message,
102
+ } }) })), jsxs(Footer, { children: [signRequest.kind === 'typedData' && (jsx(CopyRow, { children: jsx(CopyButton, { value: JSON.stringify(signRequest.typedData, null, 2), children: "Copy to clipboard" }) })), error && jsx(ErrorText, { children: error }), jsx(Button, { variant: "primary", onClick: handleSign, waiting: signing, disabled: signing, arrow: true, children: "Sign and continue" })] })] }) }));
78
103
  };
79
104
 
80
105
  export { SignMessage as default };