@ab-org/predicate-market-sdk 1.0.0 → 1.0.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 (91) hide show
  1. package/dist/index.d.ts +672 -22
  2. package/dist/index.js +4700 -23
  3. package/package.json +6 -5
  4. package/dist/auth/autoReconnect.d.ts +0 -11
  5. package/dist/auth/autoReconnect.js +0 -36
  6. package/dist/auth/bundledConfig.d.ts +0 -2
  7. package/dist/auth/bundledConfig.js +0 -19
  8. package/dist/auth/config.d.ts +0 -29
  9. package/dist/auth/config.js +0 -53
  10. package/dist/auth/google.d.ts +0 -43
  11. package/dist/auth/google.js +0 -147
  12. package/dist/auth/oidcRelay.d.ts +0 -11
  13. package/dist/auth/oidcRelay.js +0 -107
  14. package/dist/auth/twitter.d.ts +0 -7
  15. package/dist/auth/twitter.js +0 -94
  16. package/dist/auth/walletAccount.d.ts +0 -20
  17. package/dist/auth/walletAccount.js +0 -267
  18. package/dist/constants/chains.d.ts +0 -2
  19. package/dist/constants/chains.js +0 -3
  20. package/dist/modules/api.d.ts +0 -149
  21. package/dist/modules/api.js +0 -95
  22. package/dist/modules/balanceQuery.d.ts +0 -27
  23. package/dist/modules/balanceQuery.js +0 -60
  24. package/dist/modules/deposit.d.ts +0 -31
  25. package/dist/modules/deposit.js +0 -58
  26. package/dist/modules/marketData.d.ts +0 -8
  27. package/dist/modules/marketData.js +0 -107
  28. package/dist/modules/withdraw.d.ts +0 -31
  29. package/dist/modules/withdraw.js +0 -61
  30. package/dist/modules/withdrawDirect.d.ts +0 -14
  31. package/dist/modules/withdrawDirect.js +0 -33
  32. package/dist/modules/withdrawExecutor.d.ts +0 -56
  33. package/dist/modules/withdrawExecutor.js +0 -210
  34. package/dist/policyAdapter.d.ts +0 -11
  35. package/dist/policyAdapter.js +0 -38
  36. package/dist/types.d.ts +0 -62
  37. package/dist/types.js +0 -1
  38. package/dist/ui/DepositModal.d.ts +0 -36
  39. package/dist/ui/DepositModal.js +0 -354
  40. package/dist/ui/SignInModal.d.ts +0 -22
  41. package/dist/ui/SignInModal.js +0 -77
  42. package/dist/ui/SignInModal.sections.d.ts +0 -33
  43. package/dist/ui/SignInModal.sections.js +0 -45
  44. package/dist/ui/SignInModal.shared.d.ts +0 -15
  45. package/dist/ui/SignInModal.shared.js +0 -126
  46. package/dist/ui/WalletSelectionModal.d.ts +0 -14
  47. package/dist/ui/WalletSelectionModal.js +0 -54
  48. package/dist/ui/WithdrawModal.d.ts +0 -57
  49. package/dist/ui/WithdrawModal.js +0 -574
  50. package/dist/ui/components/CloseButton.d.ts +0 -4
  51. package/dist/ui/components/CloseButton.js +0 -15
  52. package/dist/ui/components/Countdown.d.ts +0 -16
  53. package/dist/ui/components/Countdown.js +0 -42
  54. package/dist/ui/components/DepositDetailsPanel.d.ts +0 -8
  55. package/dist/ui/components/DepositDetailsPanel.js +0 -143
  56. package/dist/ui/components/DropdownField.d.ts +0 -19
  57. package/dist/ui/components/DropdownField.js +0 -81
  58. package/dist/ui/components/Field.d.ts +0 -10
  59. package/dist/ui/components/Field.js +0 -21
  60. package/dist/ui/components/LoginRequiredOverlay.d.ts +0 -6
  61. package/dist/ui/components/LoginRequiredOverlay.js +0 -31
  62. package/dist/ui/components/ModalCard.d.ts +0 -9
  63. package/dist/ui/components/ModalCard.js +0 -14
  64. package/dist/ui/components/ModalFrame.d.ts +0 -9
  65. package/dist/ui/components/ModalFrame.js +0 -18
  66. package/dist/ui/components/PrimaryButton.d.ts +0 -2
  67. package/dist/ui/components/PrimaryButton.js +0 -14
  68. package/dist/ui/components/QRCodePanel.d.ts +0 -4
  69. package/dist/ui/components/QRCodePanel.js +0 -43
  70. package/dist/ui/components/Select.d.ts +0 -12
  71. package/dist/ui/components/Select.js +0 -29
  72. package/dist/ui/components/StepIndicator.d.ts +0 -7
  73. package/dist/ui/components/StepIndicator.js +0 -35
  74. package/dist/ui/components/Success.d.ts +0 -1
  75. package/dist/ui/components/Success.js +0 -4
  76. package/dist/ui/components/Toast.d.ts +0 -8
  77. package/dist/ui/components/Toast.js +0 -51
  78. package/dist/ui/hooks/useSession.d.ts +0 -2
  79. package/dist/ui/hooks/useSession.js +0 -10
  80. package/dist/ui/signInTypes.d.ts +0 -28
  81. package/dist/ui/signInTypes.js +0 -1
  82. package/dist/ui/theme.d.ts +0 -31
  83. package/dist/ui/theme.js +0 -31
  84. package/dist/ui/useSignInModalController.d.ts +0 -25
  85. package/dist/ui/useSignInModalController.js +0 -119
  86. package/dist/utils/env.d.ts +0 -1
  87. package/dist/utils/env.js +0 -63
  88. package/dist/utils/explorer.d.ts +0 -3
  89. package/dist/utils/explorer.js +0 -47
  90. package/dist/walletUtils.d.ts +0 -3
  91. package/dist/walletUtils.js +0 -3
package/dist/types.d.ts DELETED
@@ -1,62 +0,0 @@
1
- export interface CustodyAdapter {
2
- getDepositStatus(depositId: string): Promise<{
3
- status: string;
4
- txHash?: string;
5
- }>;
6
- requestWithdraw(params: {
7
- amount: string;
8
- token: string;
9
- chain: string;
10
- targetAddress: string;
11
- }): Promise<{
12
- requestId: string;
13
- }>;
14
- getWithdrawStatus(requestId: string): Promise<{
15
- status: string;
16
- txHash?: string;
17
- etaSeconds?: number;
18
- }>;
19
- }
20
- export interface ModalController<TConfig> {
21
- open(config?: TConfig): void;
22
- }
23
- export interface TokenInfo {
24
- symbol: string;
25
- name: string;
26
- decimals: number;
27
- iconUrl?: string;
28
- minAmount?: string;
29
- maxAmount?: string;
30
- }
31
- export interface ChainInfo {
32
- id: string;
33
- name: string;
34
- iconUrl?: string;
35
- confirmations?: number;
36
- estimatedTime?: string;
37
- }
38
- export interface QuoteRequest {
39
- token: string;
40
- chain: string;
41
- amount: string;
42
- direction: "deposit" | "withdraw";
43
- }
44
- export interface QuoteResult {
45
- quoteId: string;
46
- estimatedAmount: string;
47
- slippage: string;
48
- fee: string;
49
- feeToken: string;
50
- exchangeRate: string;
51
- expiresAt: number;
52
- }
53
- export interface DepositAddressResult {
54
- address: string;
55
- minimumDeposit?: string;
56
- }
57
- export interface MarketDataProvider {
58
- getSupportedTokens(direction: "deposit" | "withdraw"): Promise<TokenInfo[]>;
59
- getSupportedChains(token: string, direction: "deposit" | "withdraw"): Promise<ChainInfo[]>;
60
- getQuote(request: QuoteRequest): Promise<QuoteResult>;
61
- getDepositAddress(token: string, chain: string): Promise<DepositAddressResult>;
62
- }
package/dist/types.js DELETED
@@ -1 +0,0 @@
1
- export {};
@@ -1,36 +0,0 @@
1
- import { type ReactNode } from "react";
2
- import { type SelectOption } from "./components/DropdownField.js";
3
- export interface DepositModalProps {
4
- /** Pre-selected token id. */
5
- token?: string;
6
- /** Pre-selected chain id. */
7
- chain?: string;
8
- /** Available tokens (when not provided, fetched from getChains). */
9
- tokenOptions?: SelectOption[];
10
- /** Available chains (when not provided, derived from getChains by token). */
11
- chainOptions?: SelectOption[];
12
- /** Deposit address,必须由调用方传入;在已选 token+chain 时若未传入合法值将抛错。 */
13
- depositAddress?: string;
14
- /** e.g. "0.01 USDT" */
15
- minimumDeposit?: string;
16
- /** Icon rendered at the center of the QR code. */
17
- qrCenterIcon?: ReactNode;
18
- /** Extra icons shown on the Transfer Crypto row. */
19
- cryptoIcons?: ReactNode;
20
- /** Deposit amount for quote (optional; when set, quote is fetched and shown). */
21
- depositAmount?: string;
22
- /** Called for toast messages (copy, quote expired, wait for balance, transfer confirmed). */
23
- onShowToast?: (message: string) => void;
24
- /** When set, show "Transfer confirmed" toast and explorer link. */
25
- txHash?: string;
26
- /** Build explorer URL for tx; e.g. (chainId, txHash) => `https://bscscan.com/tx/${txHash}` */
27
- explorerTxUrl?: (chainId: string, txHash: string) => string;
28
- onTokenSelect?: (id: string) => void;
29
- onChainSelect?: (id: string) => void;
30
- onCopyAddress?: (address: string) => void;
31
- onBuyCrypto?: () => void;
32
- onSignIn?: () => void;
33
- onBack?: () => void;
34
- onClose?: () => void;
35
- }
36
- export declare const DepositModal: ({ token, chain, tokenOptions: tokenOptionsProp, chainOptions: chainOptionsProp, depositAddress, minimumDeposit, qrCenterIcon, cryptoIcons, depositAmount, onShowToast, txHash, explorerTxUrl, onTokenSelect, onChainSelect, onCopyAddress, onBuyCrypto, onSignIn, onBack, onClose, }: DepositModalProps) => import("react/jsx-runtime.js").JSX.Element;
@@ -1,354 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useState, useEffect, useCallback, useMemo, useRef } from "react";
3
- import { ModalFrame } from "./components/ModalFrame.js";
4
- import { StepIndicator } from "./components/StepIndicator.js";
5
- import { DropdownField } from "./components/DropdownField.js";
6
- import { Countdown } from "./components/Countdown.js";
7
- import { DepositDetailsPanel } from "./components/DepositDetailsPanel.js";
8
- import { LoginRequiredOverlay } from "./components/LoginRequiredOverlay.js";
9
- import { useSession } from "./hooks/useSession.js";
10
- import { colors, fonts, radii } from "./theme.js";
11
- import { getChains, quote, registerPlatform, } from "../modules/api.js";
12
- import { getEnv } from "../utils/env";
13
- /** 校验是否为合法的充值地址(传入值):非空且长度满足常见链地址格式 */
14
- function isValidDepositAddress(v) {
15
- return typeof v === "string" && v.trim().length >= 20;
16
- }
17
- /* ─── Icons ──────────────────────────────────── */
18
- const BackArrow = () => (_jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", children: _jsx("path", { d: "M15 6L9 12L15 18", stroke: colors.textPrimary, strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }));
19
- const TransferIcon = () => (_jsxs("svg", { width: "36", height: "36", viewBox: "0 0 36 36", fill: "none", children: [_jsx("circle", { cx: "18", cy: "18", r: "18", fill: "rgba(255,255,255,0.08)" }), _jsx("circle", { cx: "18", cy: "18", r: "7", stroke: colors.textPrimary, strokeWidth: "1.5" }), _jsx("circle", { cx: "18", cy: "18", r: "2.5", fill: colors.textPrimary }), _jsx("path", { d: "M18 7V11", stroke: colors.textPrimary, strokeWidth: "1.5", strokeLinecap: "round" }), _jsx("path", { d: "M18 25V29", stroke: colors.textPrimary, strokeWidth: "1.5", strokeLinecap: "round" }), _jsx("path", { d: "M7 18H11", stroke: colors.textPrimary, strokeWidth: "1.5", strokeLinecap: "round" }), _jsx("path", { d: "M25 18H29", stroke: colors.textPrimary, strokeWidth: "1.5", strokeLinecap: "round" })] }));
20
- const FiatIcon = () => (_jsxs("svg", { width: "36", height: "36", viewBox: "0 0 36 36", fill: "none", children: [_jsx("circle", { cx: "18", cy: "18", r: "18", fill: "rgba(255,255,255,0.06)" }), _jsx("circle", { cx: "18", cy: "18", r: "10", stroke: colors.textSecondary, strokeWidth: "1.5" }), _jsx("path", { d: "M18 12V24", stroke: colors.textSecondary, strokeWidth: "1.5", strokeLinecap: "round" }), _jsx("path", { d: "M15 15.5C15 14.12 16.34 13 18 13C19.66 13 21 14.12 21 15.5C21 16.88 19.66 18 18 18C16.34 18 15 19.12 15 20.5C15 21.88 16.34 23 18 23C19.66 23 21 21.88 21 20.5", stroke: colors.textSecondary, strokeWidth: "1.5", strokeLinecap: "round" })] }));
21
- const DefaultCryptoIcons = () => {
22
- const tokens = [
23
- { label: "B", bg: "#F7931A" },
24
- { label: "E", bg: "#627EEA" },
25
- { label: "≡", bg: "#26A17B" },
26
- { label: "$", bg: "#2775CA" },
27
- { label: "S", bg: "#9945FF" },
28
- { label: "A", bg: "#E84142" },
29
- ];
30
- return (_jsx("div", { style: { display: "flex", gap: 0 }, children: tokens.map((t, i) => (_jsx("div", { style: {
31
- width: 24,
32
- height: 24,
33
- borderRadius: "50%",
34
- background: t.bg,
35
- display: "flex",
36
- alignItems: "center",
37
- justifyContent: "center",
38
- fontSize: 11,
39
- fontWeight: 700,
40
- color: "#fff",
41
- marginLeft: i > 0 ? -4 : 0,
42
- border: `2px solid ${colors.card}`,
43
- boxSizing: "content-box",
44
- }, children: t.label }, i))) }));
45
- };
46
- /* ─── Helpers: derive options from getChains ─── */
47
- function chainsToTokenOptions(chains) {
48
- const bySymbol = new Map();
49
- for (const c of chains) {
50
- for (const t of c.tokens) {
51
- if (!bySymbol.has(t.symbol))
52
- bySymbol.set(t.symbol, { symbol: t.symbol, decimals: t.decimals });
53
- }
54
- }
55
- return Array.from(bySymbol.entries())
56
- .map(([id, { symbol }]) => ({
57
- id,
58
- label: symbol,
59
- subtitle: symbol,
60
- }));
61
- }
62
- function chainsToChainOptionsForToken(chains, tokenSymbol) {
63
- return chains
64
- .filter((c) => c.tokens.some((t) => t.symbol === tokenSymbol))
65
- .map((c) => ({
66
- id: c.chain_id,
67
- label: c.network,
68
- subtitle: `chainId: ${c.chain_id}`,
69
- icon: (_jsx("span", { style: {
70
- display: "inline-flex",
71
- alignItems: "center",
72
- justifyContent: "center",
73
- minWidth: 28,
74
- height: 28,
75
- padding: "0 6px",
76
- borderRadius: radii.card,
77
- background: "rgba(255,255,255,0.08)",
78
- fontSize: 12,
79
- fontWeight: 600,
80
- color: colors.textPrimary,
81
- fontFamily: fonts.family,
82
- }, children: c.network })),
83
- }));
84
- }
85
- function getTokenAddressForChain(chains, chainId, tokenSymbol) {
86
- const chain = chains.find((c) => c.chain_id === chainId);
87
- return chain?.tokens.find((t) => t.symbol === tokenSymbol)?.address;
88
- }
89
- /* ─── Main Component ─────────────────────────── */
90
- const FUNDING_TOKEN_SYMBOL = getEnv("FUNDING_TOKEN_SYMBOL");
91
- export const DepositModal = ({ token, chain, tokenOptions: tokenOptionsProp, chainOptions: chainOptionsProp, depositAddress, minimumDeposit, qrCenterIcon, cryptoIcons, depositAmount, onShowToast, txHash, explorerTxUrl, onTokenSelect, onChainSelect, onCopyAddress, onBuyCrypto, onSignIn, onBack, onClose, }) => {
92
- const session = useSession();
93
- const [view, setView] = useState("entry");
94
- const [copySuccessMessage, setCopySuccessMessage] = useState(null);
95
- const [apiChains, setApiChains] = useState(null);
96
- const [apiQuote, setApiQuote] = useState(null);
97
- const [loadingChains, setLoadingChains] = useState(false);
98
- const [loadingQuote, setLoadingQuote] = useState(false);
99
- const [quoteRefreshKey, setQuoteRefreshKey] = useState(0);
100
- const [internalDepositAddress, setInternalDepositAddress] = useState(undefined);
101
- const lastEmittedAddressRef = useRef(undefined);
102
- const lastEmittedChainRef = useRef(undefined);
103
- const tokenOptions = useMemo(() => {
104
- if (tokenOptionsProp?.length)
105
- return tokenOptionsProp;
106
- if (!apiChains?.length)
107
- return undefined;
108
- return chainsToTokenOptions(apiChains);
109
- }, [tokenOptionsProp, apiChains]);
110
- const chainOptions = useMemo(() => {
111
- if (chainOptionsProp?.length)
112
- return chainOptionsProp;
113
- if (!apiChains?.length || !token)
114
- return undefined;
115
- return chainsToChainOptionsForToken(apiChains, token);
116
- }, [chainOptionsProp, apiChains, token]);
117
- // 仅有一个 chain 选项时默认选中
118
- useEffect(() => {
119
- if (chainOptions?.length !== 1 || !onChainSelect)
120
- return;
121
- const onlyId = chainOptions[0].id;
122
- if (chain === onlyId)
123
- return;
124
- onChainSelect(onlyId);
125
- }, [chainOptions, chain, onChainSelect]);
126
- useEffect(() => {
127
- if (view !== "transfer")
128
- return;
129
- setLoadingChains(true);
130
- getChains()
131
- .then((res) => setApiChains(res?.chains ?? {}))
132
- .finally(() => setLoadingChains(false));
133
- }, [view]);
134
- // Fetch depositAddress internally when user is signed in and a chain has been selected.
135
- useEffect(() => {
136
- if (view !== "transfer")
137
- return;
138
- if (!session?.address || !chain)
139
- return;
140
- registerPlatform({
141
- platform_contract_address: session.address,
142
- chain_id: chain,
143
- })
144
- .then((res) => {
145
- if (res?.deposit_address) {
146
- setInternalDepositAddress(res.deposit_address);
147
- }
148
- })
149
- .catch(() => {
150
- // silent failure; UI will keep placeholder if any
151
- });
152
- }, [view, chain, session?.address]);
153
- useEffect(() => {
154
- if (!apiChains?.length || !token || !chain) {
155
- setApiQuote(null);
156
- return;
157
- }
158
- const tokenAddress = getTokenAddressForChain(apiChains, chain, token);
159
- if (!tokenAddress) {
160
- setApiQuote(null);
161
- return;
162
- }
163
- setLoadingQuote(true);
164
- console.log('setLoadingQuote', tokenAddress, depositAmount);
165
- quote({
166
- direction: "deposit",
167
- chain_id: chain,
168
- token_address: tokenAddress,
169
- token_amount: depositAmount || undefined,
170
- })
171
- .then((q) => setApiQuote(q ?? null))
172
- .catch((err) => {
173
- const message = err?.message ?? String(err);
174
- console.error('setLoadingQuote', message);
175
- if (onShowToast)
176
- onShowToast(message);
177
- setApiQuote({
178
- token_address: tokenAddress,
179
- token_symbol: token,
180
- token_decimals: 18,
181
- rate: "1",
182
- chain_id: Number(chain) || 56,
183
- deposit_address: "0x" + "0".repeat(39) + "1",
184
- dst_token_amount: depositAmount ?? "0",
185
- expires_at: new Date(Date.now() + 60000).toISOString(),
186
- });
187
- })
188
- .finally(() => setLoadingQuote(false));
189
- }, [apiChains, token, chain, depositAmount, quoteRefreshKey, onShowToast]);
190
- // Emit resolved address when external prop is provided/changes
191
- useEffect(() => {
192
- if (!chain)
193
- return;
194
- if (!depositAddress)
195
- return;
196
- if (lastEmittedAddressRef.current === depositAddress &&
197
- lastEmittedChainRef.current === chain) {
198
- return;
199
- }
200
- lastEmittedAddressRef.current = depositAddress;
201
- lastEmittedChainRef.current = chain;
202
- }, [depositAddress, chain]);
203
- const handleQuoteExpired = useCallback(() => {
204
- setQuoteRefreshKey((k) => k + 1);
205
- }, []);
206
- useEffect(() => {
207
- if (txHash && chain && onShowToast) {
208
- onShowToast("Transfer confirmed");
209
- }
210
- }, [txHash, chain, onShowToast]);
211
- if (!session) {
212
- return _jsx(LoginRequiredOverlay, { title: "Deposit", onSignIn: onSignIn, onClose: onClose });
213
- }
214
- const goToEntry = () => {
215
- setView("entry");
216
- onBack?.();
217
- };
218
- const handleCopyAddress = useCallback((address) => {
219
- onCopyAddress?.(address);
220
- onShowToast?.("Address copied");
221
- setCopySuccessMessage("Address copied");
222
- }, [onCopyAddress, onShowToast]);
223
- useEffect(() => {
224
- if (!copySuccessMessage)
225
- return;
226
- const t = setTimeout(() => setCopySuccessMessage(null), 2000);
227
- return () => clearTimeout(t);
228
- }, [copySuccessMessage]);
229
- return (_jsxs(ModalFrame, { onClose: onClose, contentStyle: { padding: "24px", position: "relative" }, children: [copySuccessMessage && (_jsx("div", { style: {
230
- position: "absolute",
231
- bottom: 24,
232
- left: "50%",
233
- transform: "translateX(-50%)",
234
- padding: "10px 20px",
235
- borderRadius: 8,
236
- background: "var(--pm-colors-card, #1a1a2e)",
237
- color: "var(--pm-colors-textPrimary, #fff)",
238
- fontSize: 13,
239
- fontWeight: 500,
240
- boxShadow: "0 4px 12px rgba(0,0,0,.25)",
241
- zIndex: 10,
242
- }, children: copySuccessMessage })), view === "entry" ? (_jsx(EntryView, { cryptoIcons: cryptoIcons, onTransferCrypto: () => setView("transfer"), onBuyCrypto: onBuyCrypto })) : (_jsx(TransferView, { token: token, chain: chain, tokenOptions: tokenOptions, chainOptions: chainOptions, depositAddress: depositAddress ?? internalDepositAddress, minimumDeposit: minimumDeposit, qrCenterIcon: qrCenterIcon, quote: apiQuote, quoteLoading: loadingQuote, txHash: txHash, chainIdForExplorer: chain, explorerTxUrl: explorerTxUrl, loadingChains: loadingChains, onTokenSelect: onTokenSelect, onChainSelect: onChainSelect, onCopyAddress: handleCopyAddress, onQuoteExpired: handleQuoteExpired, onRefreshQuote: () => {
243
- if (!apiChains?.length || !token || !chain)
244
- return;
245
- const tokenAddress = getTokenAddressForChain(apiChains, chain, token);
246
- if (tokenAddress) {
247
- setLoadingQuote(true);
248
- quote({ direction: "deposit", chain_id: chain, token_address: tokenAddress, token_amount: depositAmount })
249
- .then((q) => setApiQuote(q ?? null))
250
- .catch(() => {
251
- setApiQuote({
252
- token_address: tokenAddress,
253
- token_symbol: token,
254
- token_decimals: 18,
255
- rate: "1",
256
- chain_id: Number(chain) || 56,
257
- deposit_address: "0x" + "0".repeat(39) + "1",
258
- dst_token_amount: depositAmount ?? "0",
259
- expires_at: new Date(Date.now() + 60000).toISOString(),
260
- });
261
- })
262
- .finally(() => setLoadingQuote(false));
263
- }
264
- }, onShowToast: onShowToast, onBack: goToEntry }))] }));
265
- };
266
- /* ─── Entry View ─────────────────────────────── */
267
- const EntryView = ({ cryptoIcons, onTransferCrypto, onBuyCrypto: _onBuyCrypto, }) => (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 24 }, children: [_jsx("h2", { style: { margin: 0, fontSize: 24, fontWeight: 600, lineHeight: 1.4 }, children: "Deposit" }), _jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: [_jsxs("button", { type: "button", onClick: onTransferCrypto, style: {
268
- display: "flex",
269
- alignItems: "center",
270
- gap: 14,
271
- padding: "18px 20px",
272
- borderRadius: radii.card,
273
- border: `1px solid ${colors.border}`,
274
- background: "transparent",
275
- cursor: "pointer",
276
- textAlign: "left",
277
- fontFamily: fonts.family,
278
- width: "100%",
279
- transition: "border-color .15s",
280
- }, onMouseEnter: (e) => { e.target.closest("button").style.borderColor = colors.borderStrong; }, onMouseLeave: (e) => { e.target.closest("button").style.borderColor = colors.border; }, children: [_jsx(TransferIcon, {}), _jsxs("div", { style: { flex: 1, display: "flex", flexDirection: "column", gap: 2 }, children: [_jsx("span", { style: { color: colors.textPrimary, fontSize: 16, fontWeight: 600 }, children: "Transfer Crypto" }), _jsx("span", { style: { color: colors.textSecondary, fontSize: 13 }, children: "No limit \u00B7 Instant" })] }), cryptoIcons ?? _jsx(DefaultCryptoIcons, {})] }), _jsxs("div", { style: {
281
- display: "flex",
282
- alignItems: "center",
283
- gap: 14,
284
- padding: "18px 20px",
285
- borderRadius: radii.card,
286
- border: `1px solid ${colors.border}`,
287
- opacity: 0.55,
288
- }, children: [_jsx(FiatIcon, {}), _jsxs("div", { style: { flex: 1, display: "flex", flexDirection: "column", gap: 2 }, children: [_jsx("span", { style: { color: colors.textSecondary, fontSize: 16, fontWeight: 600 }, children: "Buy Crypto" }), _jsx("span", { style: { color: colors.textSecondary, fontSize: 13 }, children: "Debit card, credit card, ACH" })] }), _jsx("span", { style: {
289
- padding: "5px 12px",
290
- borderRadius: radii.pill,
291
- border: `1px solid ${colors.border}`,
292
- fontSize: 12,
293
- fontWeight: 500,
294
- color: colors.textSecondary,
295
- whiteSpace: "nowrap",
296
- }, children: "Coming Soon" })] })] })] }));
297
- /* ─── Transfer View (stepper) ────────────────── */
298
- const TransferView = ({ token, chain, tokenOptions, chainOptions, depositAddress, minimumDeposit, qrCenterIcon, quote: quoteData, quoteLoading, txHash, chainIdForExplorer, explorerTxUrl, loadingChains, onTokenSelect, onChainSelect, onCopyAddress, onQuoteExpired, onRefreshQuote, onShowToast, onBack, }) => {
299
- const activeStep = chain ? 2 : token ? 1 : 0;
300
- const stepActive = [!!token, !!chain, !!quoteData];
301
- const quoteExpired = useMemo(() => {
302
- if (!quoteData?.expires_at)
303
- return false;
304
- try {
305
- return new Date(quoteData.expires_at).getTime() < Date.now();
306
- }
307
- catch {
308
- return false;
309
- }
310
- }, [quoteData?.expires_at]);
311
- const didToastWait = useRef(false);
312
- useEffect(() => {
313
- if (!depositAddress || !onShowToast || didToastWait.current)
314
- return;
315
- didToastWait.current = true;
316
- onShowToast("Please wait for deposit-address balance to update");
317
- }, [depositAddress, onShowToast]);
318
- return (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 24 }, children: [_jsx("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: _jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12 }, children: [onBack && (_jsx("button", { type: "button", onClick: onBack, style: {
319
- background: "transparent",
320
- border: "none",
321
- cursor: "pointer",
322
- padding: 0,
323
- display: "flex",
324
- alignItems: "center",
325
- }, children: _jsx(BackArrow, {}) })), _jsx("h2", { style: { margin: 0, fontSize: 24, fontWeight: 600, lineHeight: 1.4 }, children: "Transfer Crypto" })] }) }), _jsxs("div", { style: { display: "flex", gap: 16, position: "relative" }, children: [_jsx(StepIndicator, { steps: 3, stepActive: stepActive, activeStep: activeStep }), _jsxs("div", { style: { flex: 1, display: "flex", flexDirection: "column", gap: 40 }, children: [_jsx(DropdownField, { label: "Select token", placeholder: loadingChains ? "Loading…" : "Token", value: token, options: tokenOptions, onSelect: onTokenSelect }), _jsx(DropdownField, { label: "Select chain", placeholder: loadingChains ? "Loading…" : "Chain", value: chain, options: chainOptions, onSelect: onChainSelect }), quoteData && token && chain && (_jsx("div", { id: "quote-panel", style: {
326
- padding: "12px 16px",
327
- borderRadius: radii.card,
328
- margin: "-10px 0",
329
- border: `1px solid ${colors.border}`,
330
- display: "flex",
331
- flexDirection: "column",
332
- gap: 8,
333
- }, children: quoteLoading ? (_jsx("span", { style: { fontSize: 13, color: colors.textSecondary }, children: "Loading\u2026" })) : (_jsxs(_Fragment, { children: [_jsxs("span", { style: { fontSize: 13, color: colors.textSecondary }, children: ["1 ", quoteData.token_symbol, " = ", quoteData.rate, " ", FUNDING_TOKEN_SYMBOL] }), quoteData.expires_at && (_jsx(Countdown, { expiresAt: quoteData.expires_at, isExpired: quoteExpired, onExpired: onQuoteExpired })), quoteExpired && (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [_jsx("span", { style: { fontSize: 13, color: "#f59e0b" }, children: "Quote expired, please refresh" }), onRefreshQuote && (_jsx("button", { type: "button", onClick: onRefreshQuote, style: {
334
- padding: "4px 12px",
335
- fontSize: 12,
336
- borderRadius: radii.pill,
337
- border: `1px solid ${colors.border}`,
338
- background: "transparent",
339
- color: colors.textPrimary,
340
- cursor: "pointer",
341
- fontFamily: fonts.family,
342
- }, children: "Refresh" }))] }))] })) })), _jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 8, marginTop: "-5px" }, id: "deposit-details", children: [_jsx("span", { style: { fontSize: 14, lineHeight: 1.4, color: colors.textPrimary }, children: "Deposit details" }), depositAddress ? (_jsxs(_Fragment, { children: [_jsx(DepositDetailsPanel, { address: depositAddress, tokenIcon: qrCenterIcon, minimumDeposit: minimumDeposit, onCopyAddress: onCopyAddress }), txHash && chainIdForExplorer && explorerTxUrl && (_jsx("a", { href: explorerTxUrl(chainIdForExplorer, txHash), target: "_blank", rel: "noopener noreferrer", style: {
343
- fontSize: 13,
344
- color: colors.textPrimary,
345
- textDecoration: "underline",
346
- }, children: "View on explorer" }))] })) : (_jsx("div", { style: {
347
- padding: "20px",
348
- borderRadius: radii.card,
349
- border: `1px solid ${colors.border}`,
350
- color: colors.textSecondary,
351
- fontSize: 13,
352
- textAlign: "center",
353
- }, children: "Select token and chain to view deposit details" }))] })] })] })] }));
354
- };
@@ -1,22 +0,0 @@
1
- import { type CubeSignerSession, type WalletSession } from "@ab-org/sdk-core";
2
- import type { GoogleCredential } from "../auth/google.js";
3
- import type { TwitterAuthResult } from "../auth/twitter.js";
4
- import type { SocialProvider, WalletItem } from "./signInTypes.js";
5
- export interface SignInModalProps {
6
- title?: string;
7
- socialProviders?: SocialProvider[];
8
- wallets?: WalletItem[];
9
- initialVisibleCount?: number;
10
- privacyPolicyUrl?: string;
11
- termsOfUseUrl?: string;
12
- onGoogleLogin?: (credential: GoogleCredential) => void;
13
- onTwitterLogin?: (result: TwitterAuthResult) => void;
14
- onCubeSignerSession?: (session: CubeSignerSession) => void;
15
- onWalletConnected?: (session: WalletSession, walletId: string) => void;
16
- onSocialLogin?: (providerId: string) => void;
17
- onWalletSelect?: (walletId: string) => void | Promise<void>;
18
- onDismiss?: () => void;
19
- onSuccess?: (session: WalletSession) => void;
20
- }
21
- export declare function clearSocialAccountInstance(): void;
22
- export declare const SignInModal: ({ title, socialProviders, wallets, initialVisibleCount, privacyPolicyUrl, termsOfUseUrl, onGoogleLogin, onTwitterLogin, onCubeSignerSession, onWalletConnected, onSocialLogin, onWalletSelect, onDismiss, onSuccess, }: SignInModalProps) => import("react/jsx-runtime.js").JSX.Element;
@@ -1,77 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from "react";
3
- import { sessionStore } from "@ab-org/sdk-core";
4
- import { getSDKConfig } from "../auth/config.js";
5
- import { clearSocialAccountInstance as clearEmbeddedWalletAccount } from "../auth/walletAccount.js";
6
- import { resolveSocialProviders } from "./SignInModal.shared.js";
7
- import { SignInModalFooter, SignInModalFrame, SignInModalSocialSection, SignInModalWalletGrid, } from "./SignInModal.sections.js";
8
- import { useSignInModalController } from "./useSignInModalController.js";
9
- import { Toast } from "./components/Toast.js";
10
- export function clearSocialAccountInstance() {
11
- try {
12
- clearEmbeddedWalletAccount();
13
- const storage = typeof localStorage !== "undefined" ? localStorage : null;
14
- const adapterId = storage?.getItem("ab:wallet:adapterId");
15
- const session = sessionStore.getState().session;
16
- const isSocialSession = session?.walletType === "social" ||
17
- session?.authSource === "google" ||
18
- session?.authSource === "twitter" ||
19
- adapterId === "cubist";
20
- if (!isSocialSession)
21
- return;
22
- sessionStore.clearSession();
23
- storage?.removeItem("ab:wallet:session");
24
- storage?.removeItem("ab:wallet:adapterId");
25
- }
26
- catch {
27
- clearEmbeddedWalletAccount();
28
- sessionStore.clearSession();
29
- }
30
- }
31
- export const SignInModal = ({ title = "Welcome to PredicateMarket", socialProviders, wallets, initialVisibleCount, privacyPolicyUrl = "#", termsOfUseUrl = "#", onGoogleLogin, onTwitterLogin, onCubeSignerSession, onWalletConnected, onSocialLogin, onWalletSelect, onDismiss, onSuccess, }) => {
32
- const sdkConfig = getSDKConfig();
33
- const effectiveSocialProviders = resolveSocialProviders(socialProviders ?? sdkConfig.signIn?.socialProviders);
34
- const effectiveWallets = wallets ?? sdkConfig.signIn?.wallets;
35
- const effectiveInitialVisibleCount = initialVisibleCount ?? sdkConfig.signIn?.initialVisibleCount ?? 5;
36
- const [toastError, setToastError] = useState(null);
37
- const { expanded, loadingProvider, loadingWalletId, visibleWallets, showExpandToggle, isBusy, handleSocialClick, handleWalletClick, toggleExpanded, } = useSignInModalController({
38
- wallets: effectiveWallets,
39
- initialVisibleCount: effectiveInitialVisibleCount,
40
- onGoogleLogin,
41
- onTwitterLogin,
42
- onCubeSignerSession,
43
- onWalletConnected,
44
- onSocialLogin,
45
- onWalletSelect,
46
- });
47
- return (_jsxs(SignInModalFrame, { id: "SignInModalFrame", title: title, onClose: onDismiss, footer: _jsx(SignInModalFooter, { privacyPolicyUrl: privacyPolicyUrl, termsOfUseUrl: termsOfUseUrl }), children: [toastError ? (_jsx(Toast, { message: toastError, variant: "error", duration: 5000, onClose: () => setToastError(null) })) : null, _jsx(SignInModalSocialSection, { id: "SignInModalSocialSection", socialProviders: effectiveSocialProviders, isBusy: isBusy, loadingProvider: loadingProvider, onSocialClick: async (providerId) => {
48
- try {
49
- const session = await handleSocialClick(providerId);
50
- if (!session)
51
- return;
52
- const normalizedAuthSource = providerId === "x"
53
- ? "twitter"
54
- : providerId;
55
- onSuccess?.({
56
- ...session,
57
- walletType: session.walletType ?? "social",
58
- authSource: session.authSource ?? normalizedAuthSource,
59
- });
60
- }
61
- catch (error) {
62
- const msg = error instanceof Error ? error.message : "Social login failed";
63
- setToastError(msg);
64
- }
65
- } }), _jsx(SignInModalWalletGrid, { wallets: visibleWallets, isBusy: isBusy, loadingWalletId: loadingWalletId, expanded: expanded, showExpandToggle: showExpandToggle, onWalletClick: async (walletId) => {
66
- try {
67
- const session = await handleWalletClick(walletId);
68
- if (session) {
69
- onSuccess?.(session);
70
- }
71
- }
72
- catch (error) {
73
- const msg = error instanceof Error ? error.message : "Wallet connect failed";
74
- setToastError(msg);
75
- }
76
- }, onToggleExpanded: toggleExpanded })] }));
77
- };
@@ -1,33 +0,0 @@
1
- import type { ReactNode } from "react";
2
- import type { SocialProvider, WalletItem } from "./signInTypes.js";
3
- export interface SignInModalSocialSectionProps {
4
- id: string;
5
- socialProviders: SocialProvider[];
6
- isBusy: boolean;
7
- loadingProvider: string | null;
8
- onSocialClick: (providerId: string) => void | Promise<void>;
9
- }
10
- export interface SignInModalFrameProps {
11
- id: string;
12
- title: string;
13
- onClose?: () => void;
14
- footer?: ReactNode;
15
- children: ReactNode;
16
- }
17
- export declare const SignInModalFrame: ({ id, title, onClose, footer, children, }: SignInModalFrameProps) => import("react/jsx-runtime.js").JSX.Element;
18
- export declare const SignInModalSocialSection: ({ id, socialProviders, isBusy, loadingProvider, onSocialClick, }: SignInModalSocialSectionProps) => import("react/jsx-runtime.js").JSX.Element;
19
- export interface SignInModalWalletGridProps {
20
- wallets: WalletItem[];
21
- isBusy: boolean;
22
- loadingWalletId: string | null;
23
- expanded: boolean;
24
- showExpandToggle: boolean;
25
- onWalletClick: (walletId: string) => void | Promise<void>;
26
- onToggleExpanded: () => void;
27
- }
28
- export declare const SignInModalWalletGrid: ({ wallets, isBusy, loadingWalletId, expanded, showExpandToggle, onWalletClick, onToggleExpanded, }: SignInModalWalletGridProps) => import("react/jsx-runtime.js").JSX.Element;
29
- export interface SignInModalFooterProps {
30
- privacyPolicyUrl: string;
31
- termsOfUseUrl: string;
32
- }
33
- export declare const SignInModalFooter: ({ privacyPolicyUrl, termsOfUseUrl, }: SignInModalFooterProps) => import("react/jsx-runtime.js").JSX.Element;
@@ -1,45 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { ModalFrame } from "./components/ModalFrame.js";
3
- import { colors, fonts, radii } from "./theme.js";
4
- import { DefaultWalletIcon, ExpandIcon, SpinnerIcon } from "./SignInModal.shared.js";
5
- export const SignInModalFrame = ({ id, title, onClose, footer, children, }) => (_jsx(ModalFrame, { onClose: onClose, cardStyle: { padding: "32px 24px" }, contentStyle: { alignItems: "center" }, children: _jsxs("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: 24, alignItems: "center" }, id: id, children: [_jsx("h2", { style: { margin: 0, fontSize: 24, fontWeight: 600, lineHeight: 1.4, textAlign: "center" }, children: title }), _jsx("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: 12, alignItems: "center" }, children: children }), footer] }) }));
6
- export const SignInModalSocialSection = ({ id, socialProviders, isBusy, loadingProvider, onSocialClick, }) => (_jsxs("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: 24 }, id: id, children: [_jsx("div", { style: { display: "flex", flexDirection: "column", gap: 16 }, children: socialProviders.map((provider) => {
7
- const isLoading = loadingProvider === provider.id;
8
- return (_jsxs("button", { type: "button", disabled: isBusy, onClick: () => onSocialClick(provider.id), style: {
9
- width: "100%",
10
- height: 48,
11
- borderRadius: radii.pill,
12
- border: `1px solid ${colors.border}`,
13
- background: "transparent",
14
- display: "flex",
15
- alignItems: "center",
16
- justifyContent: "center",
17
- gap: 12,
18
- cursor: isBusy ? "wait" : "pointer",
19
- padding: 12,
20
- boxSizing: "border-box",
21
- opacity: isLoading ? 0.6 : isBusy ? 0.8 : 1,
22
- transition: "opacity .15s",
23
- }, children: [isLoading ? _jsx(SpinnerIcon, {}) : provider.icon, _jsx("span", { style: { fontSize: 16, fontWeight: 500, lineHeight: 1.4, color: colors.textPrimary, fontFamily: fonts.family }, children: isLoading ? "Signing in..." : provider.label })] }, provider.id));
24
- }) }), _jsxs("div", { style: { display: "flex", alignItems: "center", gap: 20, width: "100%" }, children: [_jsx("div", { style: { flex: 1, height: 1, background: colors.border } }), _jsx("span", { style: { fontSize: 14, lineHeight: 1.4, color: colors.textPrimary, opacity: 0.4, whiteSpace: "nowrap" }, children: "Or connect a wallet" }), _jsx("div", { style: { flex: 1, height: 1, background: colors.border } })] })] }));
25
- export const SignInModalWalletGrid = ({ wallets, isBusy, loadingWalletId, expanded, showExpandToggle, onWalletClick, onToggleExpanded, }) => (_jsxs("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: 8, alignItems: "center", paddingTop: 12 }, children: [_jsx("div", { style: { width: "100%", display: "flex", flexWrap: "wrap", gap: "14px 0" }, children: wallets.map((wallet) => (_jsxs("button", { type: "button", disabled: isBusy, onClick: () => onWalletClick(wallet.id), style: {
26
- width: "25%",
27
- display: "flex",
28
- flexDirection: "column",
29
- alignItems: "center",
30
- gap: 4,
31
- background: "transparent",
32
- border: "none",
33
- cursor: isBusy ? "wait" : "pointer",
34
- padding: 0,
35
- opacity: loadingWalletId === wallet.id ? 0.7 : isBusy ? 0.85 : 1,
36
- }, children: [_jsx("div", { style: { width: 56, height: 56, display: "flex", alignItems: "center", justifyContent: "center" }, children: loadingWalletId === wallet.id ? (_jsx(SpinnerIcon, {})) : (wallet.icon ?? _jsx(DefaultWalletIcon, { walletId: wallet.id, name: wallet.name })) }), _jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: [_jsx("span", { style: { fontSize: 12, fontWeight: 500, lineHeight: 1.4, color: colors.textPrimary, fontFamily: fonts.family, textAlign: "center", whiteSpace: "nowrap" }, children: wallet.name }), loadingWalletId === wallet.id ? (_jsx("span", { style: { fontSize: 10, lineHeight: 1.4, color: colors.textSecondary, fontFamily: fonts.family }, children: "Connecting..." })) : wallet.installed ? (_jsx("span", { style: { fontSize: 10, lineHeight: 1.4, color: colors.accent, fontFamily: fonts.family }, children: "Installed" })) : wallet.installUrl ? (_jsx("a", { href: wallet.installUrl, target: "_blank", rel: "noopener noreferrer", onClick: (event) => event.stopPropagation(), style: { fontSize: 10, lineHeight: 1.4, color: colors.textSecondary, fontFamily: fonts.family, textDecoration: "underline" }, children: "Install" })) : null] })] }, wallet.id))) }), showExpandToggle && (_jsx("button", { type: "button", onClick: onToggleExpanded, style: {
37
- background: "transparent",
38
- border: "none",
39
- cursor: "pointer",
40
- display: "flex",
41
- alignItems: "center",
42
- justifyContent: "center",
43
- padding: 4,
44
- }, children: _jsx(ExpandIcon, { expanded: expanded }) }))] }));
45
- export const SignInModalFooter = ({ privacyPolicyUrl, termsOfUseUrl, }) => (_jsx("div", { style: { padding: "12px 0", display: "flex", justifyContent: "center", width: "100%" }, children: _jsxs("p", { style: { margin: 0, fontSize: 14, lineHeight: 1.4, color: colors.textSecondary, fontFamily: fonts.family, textAlign: "center" }, children: ["By continuing, I agree to the", " ", _jsx("a", { href: privacyPolicyUrl, style: { color: colors.textPrimary, textDecoration: "underline" }, target: "_blank", rel: "noopener noreferrer", children: "Privacy Policy" }), " ", "and", " ", _jsx("a", { href: termsOfUseUrl, style: { color: colors.textPrimary, textDecoration: "underline" }, target: "_blank", rel: "noopener noreferrer", children: "Terms of Use" })] }) }));