@openfort/react 1.6.0 → 1.6.2
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/build/components/Common/Modal/index.js +14 -0
- package/build/components/Common/Modal/index.js.map +1 -1
- package/build/components/Openfort/types.d.ts +1 -1
- package/build/components/Pages/AssetInventory/SolanaAssetInventory.js +47 -8
- package/build/components/Pages/AssetInventory/SolanaAssetInventory.js.map +1 -1
- package/build/components/Pages/AssetInventory/index.js +50 -6
- package/build/components/Pages/AssetInventory/index.js.map +1 -1
- package/build/components/Pages/Connected/EthereumConnected.js +2 -5
- package/build/components/Pages/Connected/EthereumConnected.js.map +1 -1
- package/build/components/Pages/DepositWallet/index.js +15 -10
- package/build/components/Pages/DepositWallet/index.js.map +1 -1
- package/build/components/Pages/ExportKey/index.js +44 -4
- package/build/components/Pages/ExportKey/index.js.map +1 -1
- package/build/components/Pages/ExportKey/styles.d.ts +5 -0
- package/build/components/Pages/ExportKey/styles.js +47 -0
- package/build/components/Pages/ExportKey/styles.js.map +1 -0
- package/build/components/Pages/Receive/index.js +2 -2
- package/build/components/Pages/SelectToken/SolanaSelectToken.js +7 -7
- package/build/components/Pages/SelectToken/index.js +7 -3
- package/build/components/Pages/SelectToken/index.js.map +1 -1
- package/build/components/Pages/Send/EthereumSend.js +25 -5
- package/build/components/Pages/Send/EthereumSend.js.map +1 -1
- package/build/components/Pages/Send/SolanaSend.js +23 -4
- package/build/components/Pages/Send/SolanaSend.js.map +1 -1
- package/build/components/Pages/Send/styles.d.ts +17 -11
- package/build/components/Pages/Send/styles.js +104 -49
- package/build/components/Pages/Send/styles.js.map +1 -1
- package/build/components/Pages/SendConfirmation/ConfirmationSummary.d.ts +3 -1
- package/build/components/Pages/SendConfirmation/ConfirmationSummary.js +2 -2
- package/build/components/Pages/SendConfirmation/EstimatedFees.d.ts +3 -1
- package/build/components/Pages/SendConfirmation/EstimatedFees.js +22 -15
- package/build/components/Pages/SendConfirmation/EstimatedFees.js.map +1 -1
- package/build/components/Pages/SendConfirmation/SolanaSendConfirmation.js +17 -5
- package/build/components/Pages/SendConfirmation/SolanaSendConfirmation.js.map +1 -1
- package/build/components/Pages/SendConfirmation/index.js +11 -5
- package/build/components/Pages/SendConfirmation/index.js.map +1 -1
- package/build/components/Pages/SendConfirmation/styles.d.ts +3 -1
- package/build/components/Pages/SendConfirmation/styles.js +20 -6
- package/build/components/Pages/SendConfirmation/styles.js.map +1 -1
- package/build/components/Pages/SignMessage/index.js +44 -19
- package/build/components/Pages/SignMessage/index.js.map +1 -1
- package/build/components/Pages/SignMessage/styles.d.ts +2 -3
- package/build/components/Pages/SignMessage/styles.js +19 -2
- package/build/components/Pages/SignMessage/styles.js.map +1 -1
- package/build/constants/defaultAssets.d.ts +18 -0
- package/build/constants/defaultAssets.js +70 -0
- package/build/constants/defaultAssets.js.map +1 -0
- package/build/hooks/openfort/useSignMessage.d.ts +2 -2
- package/build/hooks/openfort/useUI.js +4 -2
- package/build/hooks/openfort/useUI.js.map +1 -1
- package/build/solana/transfer.d.ts +12 -0
- package/build/solana/transfer.js +29 -1
- package/build/solana/transfer.js.map +1 -1
- package/build/version.d.ts +1 -1
- package/build/version.js +1 -1
- package/package.json +1 -1
|
@@ -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,
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
98
|
-
background: var(--ck-body-background
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
30
|
-
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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 })) : (
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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 };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
export declare const SignContent: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
2
2
|
export declare const Subtitle: import("styled-components").StyledComponent<"p", any, {}, never>;
|
|
3
|
-
export declare const MessageBox: import("styled-components").StyledComponent<"div", any, {
|
|
4
|
-
|
|
5
|
-
}, never>;
|
|
3
|
+
export declare const MessageBox: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
4
|
+
export declare const Footer: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
6
5
|
export declare const DataList: import("styled-components").StyledComponent<"ul", any, {}, never>;
|
|
7
6
|
export declare const DataItem: import("styled-components").StyledComponent<"li", any, {}, never>;
|
|
8
7
|
export declare const DataKey: import("styled-components").StyledComponent<"span", any, {}, never>;
|
|
@@ -4,8 +4,15 @@ const SignContent = styled.div `
|
|
|
4
4
|
display: flex;
|
|
5
5
|
flex-direction: column;
|
|
6
6
|
gap: 16px;
|
|
7
|
+
min-height: 0;
|
|
8
|
+
/* Cap to the modal viewport (InnerContainer caps at 88vh) so the message body
|
|
9
|
+
is the only part that scrolls and the Sign button stays pinned and reachable
|
|
10
|
+
on small screens. 112px ≈ PageContent top padding + PageContents padding,
|
|
11
|
+
mirroring DepositWallet's Layout. */
|
|
12
|
+
max-height: calc(88vh - 112px);
|
|
7
13
|
`;
|
|
8
14
|
const Subtitle = styled.p `
|
|
15
|
+
flex-shrink: 0;
|
|
9
16
|
margin: 0;
|
|
10
17
|
text-align: center;
|
|
11
18
|
font-size: 15px;
|
|
@@ -13,6 +20,11 @@ const Subtitle = styled.p `
|
|
|
13
20
|
color: var(--ck-body-color-muted, #999);
|
|
14
21
|
`;
|
|
15
22
|
const MessageBox = styled.div `
|
|
23
|
+
flex: 1 1 auto;
|
|
24
|
+
min-height: 0;
|
|
25
|
+
overflow-y: auto;
|
|
26
|
+
-webkit-overflow-scrolling: touch;
|
|
27
|
+
overscroll-behavior: contain;
|
|
16
28
|
padding: 16px;
|
|
17
29
|
border-radius: 12px;
|
|
18
30
|
background: var(--ck-body-background-secondary, rgba(0, 0, 0, 0.04));
|
|
@@ -22,7 +34,12 @@ const MessageBox = styled.div `
|
|
|
22
34
|
text-align: left;
|
|
23
35
|
word-break: break-word;
|
|
24
36
|
white-space: pre-wrap;
|
|
25
|
-
|
|
37
|
+
`;
|
|
38
|
+
const Footer = styled.div `
|
|
39
|
+
flex-shrink: 0;
|
|
40
|
+
display: flex;
|
|
41
|
+
flex-direction: column;
|
|
42
|
+
gap: 12px;
|
|
26
43
|
`;
|
|
27
44
|
const DataList = styled.ul `
|
|
28
45
|
margin: 0;
|
|
@@ -78,5 +95,5 @@ const SignaturePreview = styled.code `
|
|
|
78
95
|
text-align: center;
|
|
79
96
|
`;
|
|
80
97
|
|
|
81
|
-
export { CopyRow, DataItem, DataKey, DataList, ErrorText, MessageBox, SignContent, SignaturePreview, Subtitle, SuccessCircle, SuccessTitle, SuccessWrap };
|
|
98
|
+
export { CopyRow, DataItem, DataKey, DataList, ErrorText, Footer, MessageBox, SignContent, SignaturePreview, Subtitle, SuccessCircle, SuccessTitle, SuccessWrap };
|
|
82
99
|
//# 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Hex } from 'viem';
|
|
2
|
+
/** A default token surfaced when no custom assets are configured. */
|
|
3
|
+
type DefaultAsset = {
|
|
4
|
+
symbol: string;
|
|
5
|
+
name: string;
|
|
6
|
+
decimals: number;
|
|
7
|
+
address: Hex;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Default ERC-20 assets per chain id, mirroring the set returned by
|
|
11
|
+
* `wallet_getAssets` — see https://www.openfort.io/docs/configuration/default-assets.
|
|
12
|
+
* Used to surface common tokens (USDC / USDT / DAI / wrapped native) in the asset
|
|
13
|
+
* inventory even at zero balance. Native tokens come from `getNativeCurrency`.
|
|
14
|
+
*/
|
|
15
|
+
export declare const DEFAULT_ASSETS: Record<number, DefaultAsset[]>;
|
|
16
|
+
/** Whether a symbol is a ~$1 stablecoin (for the inventory's USD estimate). */
|
|
17
|
+
export declare function isStableSymbol(symbol: string): boolean;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default ERC-20 assets per chain id, mirroring the set returned by
|
|
3
|
+
* `wallet_getAssets` — see https://www.openfort.io/docs/configuration/default-assets.
|
|
4
|
+
* Used to surface common tokens (USDC / USDT / DAI / wrapped native) in the asset
|
|
5
|
+
* inventory even at zero balance. Native tokens come from `getNativeCurrency`.
|
|
6
|
+
*/
|
|
7
|
+
const DEFAULT_ASSETS = {
|
|
8
|
+
// Ethereum Mainnet
|
|
9
|
+
1: [
|
|
10
|
+
{ symbol: 'USDC', name: 'USD Coin', decimals: 6, address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' },
|
|
11
|
+
{ symbol: 'USDT', name: 'Tether USD', decimals: 6, address: '0xdAC17F958D2ee523a2206206994597C13D831ec7' },
|
|
12
|
+
{ symbol: 'DAI', name: 'Dai Stablecoin', decimals: 18, address: '0x6B175474E89094C44Da98b954EedeAC495271d0F' },
|
|
13
|
+
{ symbol: 'WETH', name: 'Wrapped Ether', decimals: 18, address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' },
|
|
14
|
+
],
|
|
15
|
+
// Optimism
|
|
16
|
+
10: [
|
|
17
|
+
{ symbol: 'USDC', name: 'USD Coin', decimals: 6, address: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85' },
|
|
18
|
+
{ symbol: 'USDT', name: 'Tether USD', decimals: 6, address: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58' },
|
|
19
|
+
{ symbol: 'DAI', name: 'Dai Stablecoin', decimals: 18, address: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1' },
|
|
20
|
+
{ symbol: 'WETH', name: 'Wrapped Ether', decimals: 18, address: '0x4200000000000000000000000000000000000006' },
|
|
21
|
+
],
|
|
22
|
+
// BSC
|
|
23
|
+
56: [
|
|
24
|
+
{ symbol: 'USDC', name: 'USD Coin', decimals: 18, address: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d' },
|
|
25
|
+
{ symbol: 'USDT', name: 'Tether USD', decimals: 18, address: '0x55d398326f99059fF775485246999027B3197955' },
|
|
26
|
+
{ symbol: 'DAI', name: 'Dai Stablecoin', decimals: 18, address: '0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3' },
|
|
27
|
+
{ symbol: 'WBNB', name: 'Wrapped BNB', decimals: 18, address: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c' },
|
|
28
|
+
],
|
|
29
|
+
// Polygon
|
|
30
|
+
137: [
|
|
31
|
+
{ symbol: 'USDC', name: 'USD Coin', decimals: 6, address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359' },
|
|
32
|
+
{ symbol: 'USDT', name: 'Tether USD', decimals: 6, address: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F' },
|
|
33
|
+
{ symbol: 'DAI', name: 'Dai Stablecoin', decimals: 18, address: '0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063' },
|
|
34
|
+
{ symbol: 'WMATIC', name: 'Wrapped Matic', decimals: 18, address: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270' },
|
|
35
|
+
],
|
|
36
|
+
// Base
|
|
37
|
+
8453: [
|
|
38
|
+
{ symbol: 'USDC', name: 'USD Coin', decimals: 6, address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' },
|
|
39
|
+
{ symbol: 'DAI', name: 'Dai Stablecoin', decimals: 18, address: '0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb' },
|
|
40
|
+
{ symbol: 'WETH', name: 'Wrapped Ether', decimals: 18, address: '0x4200000000000000000000000000000000000006' },
|
|
41
|
+
],
|
|
42
|
+
// Arbitrum
|
|
43
|
+
42161: [
|
|
44
|
+
{ symbol: 'USDC', name: 'USD Coin', decimals: 6, address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831' },
|
|
45
|
+
{ symbol: 'USDT', name: 'Tether USD', decimals: 6, address: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9' },
|
|
46
|
+
{ symbol: 'DAI', name: 'Dai Stablecoin', decimals: 18, address: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1' },
|
|
47
|
+
{ symbol: 'WETH', name: 'Wrapped Ether', decimals: 18, address: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1' },
|
|
48
|
+
],
|
|
49
|
+
// Avalanche
|
|
50
|
+
43114: [
|
|
51
|
+
{ symbol: 'USDC', name: 'USD Coin', decimals: 6, address: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E' },
|
|
52
|
+
{ symbol: 'USDT', name: 'Tether USD', decimals: 6, address: '0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7' },
|
|
53
|
+
{ symbol: 'DAI.e', name: 'Dai Stablecoin', decimals: 18, address: '0xd586E7F844cEa2F87f50152665BCbc2C279D8d70' },
|
|
54
|
+
{ symbol: 'WETH.e', name: 'Wrapped Ether', decimals: 18, address: '0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB' },
|
|
55
|
+
],
|
|
56
|
+
// Sepolia
|
|
57
|
+
11155111: [{ symbol: 'USDC', name: 'USD Coin', decimals: 6, address: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238' }],
|
|
58
|
+
// Amoy
|
|
59
|
+
80002: [{ symbol: 'USDC', name: 'USD Coin', decimals: 6, address: '0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582' }],
|
|
60
|
+
// Base Sepolia
|
|
61
|
+
84532: [{ symbol: 'USDC', name: 'USD Coin', decimals: 6, address: '0x036CbD53842c5426634e7929541eC2318f3dCF7e' }],
|
|
62
|
+
};
|
|
63
|
+
const STABLE_SYMBOLS = new Set(['USDC', 'USDT', 'DAI', 'DAI.E']);
|
|
64
|
+
/** Whether a symbol is a ~$1 stablecoin (for the inventory's USD estimate). */
|
|
65
|
+
function isStableSymbol(symbol) {
|
|
66
|
+
return STABLE_SYMBOLS.has(symbol.toUpperCase());
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export { DEFAULT_ASSETS, isStableSymbol };
|
|
70
|
+
//# sourceMappingURL=defaultAssets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaultAssets.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -21,7 +21,7 @@ import { type SignTypedDataPayload } from '../../components/Openfort/types';
|
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
23
|
export declare function useSignMessage(): {
|
|
24
|
-
signMessage: (message: string) => Promise
|
|
25
|
-
signTypedData: (typedData: SignTypedDataPayload) => Promise
|
|
24
|
+
signMessage: (message: string) => Promise<string>;
|
|
25
|
+
signTypedData: (typedData: SignTypedDataPayload) => Promise<string>;
|
|
26
26
|
isPending: boolean;
|
|
27
27
|
};
|
|
@@ -22,7 +22,9 @@ const safeRoutes = {
|
|
|
22
22
|
routes.PROVIDERS,
|
|
23
23
|
routes.PROFILE,
|
|
24
24
|
routes.SEND,
|
|
25
|
+
routes.SOL_SEND,
|
|
25
26
|
routes.RECEIVE,
|
|
27
|
+
routes.SOL_RECEIVE,
|
|
26
28
|
routes.DEPOSIT,
|
|
27
29
|
routes.BUY,
|
|
28
30
|
routes.EXPORT_KEY,
|
|
@@ -133,8 +135,8 @@ function useUI() {
|
|
|
133
135
|
openSwitchNetworks: () => gotoAndOpen(routes.ETH_SWITCH_NETWORK),
|
|
134
136
|
openProviders: () => gotoAndOpen(routes.PROVIDERS),
|
|
135
137
|
openWallets: () => gotoAndOpen({ route: routes.CONNECTORS, connectType: 'linkIfUserConnectIfNoUser' }),
|
|
136
|
-
openSend: (tx) => tx ? openSendPreview(tx) : gotoAndOpen(routes.SEND),
|
|
137
|
-
openReceive: () => gotoAndOpen(routes.RECEIVE),
|
|
138
|
+
openSend: (tx) => tx ? openSendPreview(tx) : gotoAndOpen(chainType === ChainTypeEnum.SVM ? routes.SOL_SEND : routes.SEND),
|
|
139
|
+
openReceive: () => gotoAndOpen(chainType === ChainTypeEnum.SVM ? routes.SOL_RECEIVE : routes.RECEIVE),
|
|
138
140
|
openFunding: () => gotoAndOpen(routes.DEPOSIT),
|
|
139
141
|
openBuy: () => gotoAndOpen(routes.BUY),
|
|
140
142
|
openExportKey: () => gotoAndOpen(routes.EXPORT_KEY),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUI.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useUI.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -58,4 +58,16 @@ type SendSplTokenGaslessParams = {
|
|
|
58
58
|
};
|
|
59
59
|
/** Send an SPL token transfer with fees sponsored by the Openfort paymaster (Kora). */
|
|
60
60
|
export declare function sendSplTokenGasless({ from, to, mint, amount, provider, cluster, publishableKey, }: SendSplTokenGaslessParams): Promise<string>;
|
|
61
|
+
/**
|
|
62
|
+
* Read the network fee (in lamports) for a single-signer transfer from the RPC
|
|
63
|
+
* via `getFeeForMessage`. Returns null on any failure so callers can fall back to
|
|
64
|
+
* a neutral "--" rather than a fabricated number. The base fee is per-signature
|
|
65
|
+
* and identical for native and SPL transfers (a single fee-payer signature), so a
|
|
66
|
+
* representative SOL transfer message is enough to price it.
|
|
67
|
+
*/
|
|
68
|
+
export declare function estimateSolanaTransferFeeLamports({ from, to, rpcUrl, }: {
|
|
69
|
+
from: string;
|
|
70
|
+
to: string;
|
|
71
|
+
rpcUrl: string;
|
|
72
|
+
}): Promise<bigint | null>;
|
|
61
73
|
export {};
|
package/build/solana/transfer.js
CHANGED
|
@@ -214,6 +214,34 @@ async function sendSplTokenGasless({ from, to, mint, amount, provider, cluster,
|
|
|
214
214
|
publishableKey,
|
|
215
215
|
});
|
|
216
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* Read the network fee (in lamports) for a single-signer transfer from the RPC
|
|
219
|
+
* via `getFeeForMessage`. Returns null on any failure so callers can fall back to
|
|
220
|
+
* a neutral "--" rather than a fabricated number. The base fee is per-signature
|
|
221
|
+
* and identical for native and SPL transfers (a single fee-payer signature), so a
|
|
222
|
+
* representative SOL transfer message is enough to price it.
|
|
223
|
+
*/
|
|
224
|
+
async function estimateSolanaTransferFeeLamports({ from, to, rpcUrl, }) {
|
|
225
|
+
try {
|
|
226
|
+
const kit = await import('@solana/kit');
|
|
227
|
+
const { getTransferSolInstruction } = await import('@solana-program/system');
|
|
228
|
+
const fromAddress = kit.address(from);
|
|
229
|
+
const rpc = kit.createSolanaRpc(rpcUrl);
|
|
230
|
+
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
|
|
231
|
+
const message = kit.pipe(kit.createTransactionMessage({ version: 0 }), (tx) => kit.setTransactionMessageFeePayer(fromAddress, tx), (tx) => kit.setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), (tx) => kit.appendTransactionMessageInstruction(getTransferSolInstruction({
|
|
232
|
+
source: kit.createNoopSigner(fromAddress),
|
|
233
|
+
destination: kit.address(to),
|
|
234
|
+
amount: kit.lamports(BigInt(1)),
|
|
235
|
+
}), tx));
|
|
236
|
+
const compiled = kit.compileTransactionMessage(message);
|
|
237
|
+
const base64Message = kit.getBase64Decoder().decode(kit.getCompiledTransactionMessageEncoder().encode(compiled));
|
|
238
|
+
const { value } = await rpc.getFeeForMessage(base64Message).send();
|
|
239
|
+
return value == null ? null : BigInt(value);
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
217
245
|
|
|
218
|
-
export { sendSol, sendSolGasless, sendSplToken, sendSplTokenGasless };
|
|
246
|
+
export { estimateSolanaTransferFeeLamports, sendSol, sendSolGasless, sendSplToken, sendSplTokenGasless };
|
|
219
247
|
//# sourceMappingURL=transfer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transfer.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"transfer.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/build/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const OPENFORT_VERSION = "1.6.
|
|
1
|
+
export declare const OPENFORT_VERSION = "1.6.2";
|
package/build/version.js
CHANGED