@rhinestone/deposit-modal 0.12.2 → 0.14.0

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 (68) hide show
  1. package/README.md +73 -18
  2. package/bridge-transcript.json +653 -0
  3. package/dist/ClaimModal-IKTJU43Y.cjs +13 -0
  4. package/dist/ClaimModal-SEKNWRMA.mjs +13 -0
  5. package/dist/{DepositModalReown-VG66OTIU.cjs → DepositModalReown-46LPVFB6.cjs} +58 -35
  6. package/dist/{DepositModalReown-TEC3MEZ4.mjs → DepositModalReown-Q2JMLT47.mjs} +45 -22
  7. package/dist/{QRCode-WUC652SH.mjs → QRCode-5RGIZZHL.mjs} +1 -1
  8. package/dist/{QRCode-5DXFNKI2.cjs → QRCode-JKXG4RHN.cjs} +2 -2
  9. package/dist/WithdrawModal-5ICGD4HJ.mjs +12 -0
  10. package/dist/WithdrawModal-VP6PMIRO.cjs +12 -0
  11. package/dist/{chunk-O7BCVQ6L.cjs → chunk-4KCSH4T3.cjs} +157 -199
  12. package/dist/chunk-6KG642KH.cjs +31 -0
  13. package/dist/{chunk-PWLEBV5V.cjs → chunk-7ICSHJFE.cjs} +296 -220
  14. package/dist/{chunk-J46WDSRD.mjs → chunk-7SR7ENVJ.mjs} +165 -89
  15. package/dist/{chunk-2TPSF77V.mjs → chunk-CFKC77SV.mjs} +455 -261
  16. package/dist/{chunk-75DVGSAX.cjs → chunk-DW2EQA2U.cjs} +6 -3
  17. package/dist/{chunk-FXXUIK4E.mjs → chunk-IN77XSWO.mjs} +899 -153
  18. package/dist/chunk-K4H6TGBE.mjs +31 -0
  19. package/dist/{chunk-SDSKIJC7.mjs → chunk-KTUVSKR4.mjs} +2410 -1177
  20. package/dist/{chunk-HL5NUKZW.cjs → chunk-LZFRL2AL.cjs} +3 -3
  21. package/dist/{chunk-UQIJU6HV.cjs → chunk-MTFJSE52.cjs} +499 -191
  22. package/dist/{chunk-FLVLYO64.mjs → chunk-PKML3XVS.mjs} +430 -122
  23. package/dist/{chunk-4ZXQPFNU.mjs → chunk-RN5VKWI6.mjs} +4 -1
  24. package/dist/{chunk-BRYNGLDM.cjs → chunk-V2OBGLJD.cjs} +961 -215
  25. package/dist/{chunk-3STTWRAN.mjs → chunk-VUATPOWJ.mjs} +147 -189
  26. package/dist/{chunk-JE4R5VA3.mjs → chunk-WUJIKCFU.mjs} +1 -1
  27. package/dist/chunk-X2IPAPXU.cjs +163 -0
  28. package/dist/{chunk-OIN4CXCP.cjs → chunk-YCQZJQO6.cjs} +2343 -1110
  29. package/dist/{chunk-TM7VGHAG.cjs → chunk-YWMWI7PZ.cjs} +462 -268
  30. package/dist/chunk-ZEO6ADM3.mjs +163 -0
  31. package/dist/claim.cjs +7 -6
  32. package/dist/claim.d.cts +11 -3
  33. package/dist/claim.d.ts +11 -3
  34. package/dist/claim.mjs +6 -5
  35. package/dist/{constants-FuzG3h4m.d.cts → constants-DBrWhJWE.d.cts} +12 -7
  36. package/dist/{constants-FuzG3h4m.d.ts → constants-DBrWhJWE.d.ts} +12 -7
  37. package/dist/constants.cjs +3 -9
  38. package/dist/constants.d.cts +2 -3
  39. package/dist/constants.d.ts +2 -3
  40. package/dist/constants.mjs +4 -10
  41. package/dist/deposit.cjs +8 -8
  42. package/dist/deposit.d.cts +2 -2
  43. package/dist/deposit.d.ts +2 -2
  44. package/dist/deposit.mjs +7 -7
  45. package/dist/embed.cjs +1476 -0
  46. package/dist/embed.d.cts +183 -0
  47. package/dist/embed.d.ts +183 -0
  48. package/dist/embed.mjs +1476 -0
  49. package/dist/index.cjs +11 -16
  50. package/dist/index.d.cts +3 -3
  51. package/dist/index.d.ts +3 -3
  52. package/dist/index.mjs +14 -19
  53. package/dist/modal-ui-state-OD1RmKkK.d.cts +30 -0
  54. package/dist/modal-ui-state-OD1RmKkK.d.ts +30 -0
  55. package/dist/polymarket.cjs +17 -7
  56. package/dist/polymarket.mjs +13 -3
  57. package/dist/styles.css +124 -98
  58. package/dist/types-Bho4OA03.d.ts +982 -0
  59. package/dist/types-DP_3KwlD.d.cts +982 -0
  60. package/dist/withdraw.cjs +6 -6
  61. package/dist/withdraw.d.cts +11 -3
  62. package/dist/withdraw.d.ts +11 -3
  63. package/dist/withdraw.mjs +5 -5
  64. package/package.json +59 -6
  65. package/dist/chunk-IAGFDSNC.mjs +0 -11
  66. package/dist/chunk-L32UI7LA.cjs +0 -11
  67. package/dist/types-BO4iP6fG.d.cts +0 -612
  68. package/dist/types-oFblf65g.d.ts +0 -612
@@ -0,0 +1,183 @@
1
+ import * as react from 'react';
2
+ import { T as TargetChain } from './caip-D8aRWdEY.cjs';
3
+ import { Y as OutputTokenRule, W as FiatMethodsConfig, d as AssetMigrationsConfig, P as DepositModalTheme, Q as DepositModalUIConfig } from './types-DP_3KwlD.cjs';
4
+ import { WalletClient, PublicClient, Address } from 'viem';
5
+ import { Transaction, Connection } from '@solana/web3.js';
6
+
7
+ interface SolanaWalletProvider {
8
+ signAndSendTransaction(transaction: Transaction): Promise<string | {
9
+ signature?: string;
10
+ hash?: string;
11
+ txid?: string;
12
+ transactionId?: string;
13
+ }>;
14
+ signTransaction?(transaction: Transaction): Promise<Transaction>;
15
+ publicKey?: {
16
+ toBase58(): string;
17
+ };
18
+ }
19
+
20
+ /**
21
+ * The wallet the flow signs with, unifying EVM and Solana access behind one
22
+ * object. AppKit is one implementation (`useReownWalletSession`); a host that
23
+ * holds its own wallet supplies another. Nothing here may reference AppKit —
24
+ * that an implementation can be written without importing it is the point.
25
+ */
26
+ interface WalletSession {
27
+ walletClient: WalletClient | undefined;
28
+ /**
29
+ * Whether this session can sign an EVM transaction right now. It is what the
30
+ * picker offers an EVM row on.
31
+ *
32
+ * Required, and answered by the implementation rather than inferred by the
33
+ * caller, because the caller can only infer it from whichever object it
34
+ * happens to check — and that has silently removed a connected user's wallet
35
+ * from the picker twice: once on `publicClient`, once on a resolvable viem
36
+ * chain. An implementation that has not thought about it now fails to
37
+ * compile.
38
+ *
39
+ * Distinct from `isReady`, which is about the provider having initialised.
40
+ *
41
+ * The invariant callers rely on: `true` means `walletClient` is defined, with
42
+ * an account and a chain bound.
43
+ */
44
+ canSignEvm: boolean;
45
+ /** Optional: every read falls back to `getPublicClient(chainId, rpcUrls)`,
46
+ * so an implementation with no wallet-backed client omits it. */
47
+ publicClient: PublicClient | undefined;
48
+ address: Address | undefined;
49
+ caipAddress?: string;
50
+ isConnected: boolean;
51
+ isReady: boolean;
52
+ icon?: string;
53
+ isSolana: boolean;
54
+ solanaAddress?: string;
55
+ solanaProvider?: SolanaWalletProvider;
56
+ /** RPC connection managed by the connected Solana wallet session, used for
57
+ * reads (blockhash, account info) instead of an app-configured RPC. */
58
+ solanaConnection?: Connection;
59
+ openConnect: () => void;
60
+ disconnect: () => void;
61
+ switchChain: (chainId: number) => Promise<void>;
62
+ }
63
+
64
+ /** A `window`, or anything shaped enough like one to hold the two globals. */
65
+ type ChannelTarget = Record<string, unknown>;
66
+
67
+ /**
68
+ * The message contract between the embed page and a native host.
69
+ *
70
+ * **This contract evolves; it is not frozen.** One URL serves every wrapper,
71
+ * and the handshake tells the page which protocol version and which
72
+ * capabilities the wrapper on the other side understands, so the page adapts
73
+ * at runtime. That puts the compatibility burden on the side we can actually
74
+ * update — a hosted page — rather than on app-store builds we cannot.
75
+ *
76
+ * The discipline that makes it safe:
77
+ *
78
+ * - an existing field never changes meaning, and never changes type;
79
+ * - new fields are optional, and a receiver ignores what it does not know;
80
+ * - an unknown event type is dropped, an unknown request method answers 4200;
81
+ * - behaviour that differs by wrapper version is gated on `HelloResult.protocol`
82
+ * and `HelloResult.capabilities` — what the HOST speaks. The page's own
83
+ * version tells it nothing it does not already know.
84
+ *
85
+ * A `/v1/` path exists only as an escape hatch for a break so fundamental the
86
+ * page cannot adapt to it. Reaching for it means every integrator ships an
87
+ * app-store release, so it is a last resort rather than a versioning scheme.
88
+ */
89
+
90
+ type EmbedMode = "deposit" | "withdraw" | "claim";
91
+ /**
92
+ * Every prop that survives a JSON hop. Names match the React props 1:1 on
93
+ * purpose — this is a transport, not a redesign, and a renamed field is a
94
+ * second thing to keep in sync forever.
95
+ *
96
+ * Config crosses the bridge and never the URL: a public URL taking a recipient
97
+ * and a backend URL is a phishing surface, and it would put keyed RPC
98
+ * endpoints into URL bars and logs.
99
+ */
100
+ interface EmbedConfig {
101
+ mode: EmbedMode;
102
+ backendUrl: string;
103
+ recipient: string;
104
+ /** Never a viem `Chain`. This value is hashed into the account salt, so its
105
+ * spelling is a deposit address. */
106
+ targetChain: TargetChain;
107
+ targetToken: string;
108
+ sourceChain?: number;
109
+ sourceToken?: string;
110
+ /** USD amount, or the case-insensitive sentinel `"max"`. */
111
+ defaultAmount?: string;
112
+ appBalanceUsd?: number;
113
+ outputTokenRules?: OutputTokenRule[];
114
+ rejectUnmapped?: boolean;
115
+ forceRegister?: boolean;
116
+ /**
117
+ * No `rpcUrls`. The web modal takes them so an integrator can route reads
118
+ * through their own endpoints, but those endpoints are usually keyed, and
119
+ * config crossing the bridge rather than the URL was to keep keyed endpoints
120
+ * out of logs — putting them in the handshake instead hands them to whatever
121
+ * the host logs, and to any frame that reaches an unscoped channel. The
122
+ * chain set already carries `publicRpcUrl`, so nothing is blocked without
123
+ * them, and a new optional field is the one change this contract makes
124
+ * cheaply: it can be added the day a client needs it, where removing it
125
+ * later could not.
126
+ */
127
+ enableWallet?: boolean;
128
+ enableFiatOnramp?: boolean;
129
+ enableQrTransfer?: boolean;
130
+ enableGaslessDeposit?: boolean;
131
+ enableExchangeConnect?: boolean;
132
+ /**
133
+ * Opt out of sending session analytics to Rhinestone. Default: on. The URL
134
+ * override the web props carry is deliberately absent — it exists for our own
135
+ * dev verification, and a bridge field can be added later but never removed.
136
+ */
137
+ enableAnalyticsIngest?: boolean;
138
+ fiatMethods?: FiatMethodsConfig;
139
+ assetMigrations?: AssetMigrationsConfig;
140
+ initialAssetMigration?: keyof AssetMigrationsConfig;
141
+ /**
142
+ * **The page never follows the OS on its own.** An absent `mode` is light,
143
+ * and `theme.mode: "system"` — protocol 2 — is what asks the page to read
144
+ * `prefers-color-scheme`. Following it silently would drop a dark funding
145
+ * sheet into a light single-appearance app the moment the user's phone
146
+ * switched, which is the host's call to make and not ours.
147
+ *
148
+ * **Appearance is not a mount-time value.** It can change while the sheet is
149
+ * open, so a host that tracks it re-sends its config over
150
+ * `session.configure`; the page repaints in place and the flow is not
151
+ * disturbed. This is why theming has to live in the bridge config rather
152
+ * than being handed over once at hello.
153
+ *
154
+ * **`"system"` does not mean the same thing on both platforms.** WKWebView
155
+ * reports the app's effective appearance. Android's WebView reports its
156
+ * theme's `isLightTheme`, which is *light* whenever the app never declares
157
+ * one — so an unthemed Android host reads light in OS dark mode, and reads
158
+ * it silently. A host that knows its own appearance should send `"light"` or
159
+ * `"dark"` and update it, which is also the only option for an app whose
160
+ * appearance is its own setting rather than the OS one.
161
+ */
162
+ theme?: DepositModalTheme;
163
+ uiConfig?: DepositModalUIConfig;
164
+ debug?: boolean;
165
+ /** Withdraw only. */
166
+ accountAddress?: string;
167
+ /** Claim only: prefills the lookup form. */
168
+ defaultTxHash?: string;
169
+ /** Claim only: seeds the refund destination, which the user can still edit.
170
+ * Deliberately never defaulted to the deposit's sender — returning funds to
171
+ * an exchange hot wallet can lose them. */
172
+ defaultDestination?: string;
173
+ }
174
+
175
+ interface DepositEmbedProps {
176
+ /** Where the injected channel lives. Defaults to this page's `window`. */
177
+ target?: ChannelTarget;
178
+ /** The handshake failed, so there is no session and no config to render. */
179
+ onFatal?: (error: unknown) => void;
180
+ }
181
+ declare function DepositEmbed({ target, onFatal }: DepositEmbedProps): react.JSX.Element | null;
182
+
183
+ export { DepositEmbed, type DepositEmbedProps, type EmbedConfig, type WalletSession };
@@ -0,0 +1,183 @@
1
+ import * as react from 'react';
2
+ import { T as TargetChain } from './caip-D8aRWdEY.js';
3
+ import { Y as OutputTokenRule, W as FiatMethodsConfig, d as AssetMigrationsConfig, P as DepositModalTheme, Q as DepositModalUIConfig } from './types-Bho4OA03.js';
4
+ import { WalletClient, PublicClient, Address } from 'viem';
5
+ import { Transaction, Connection } from '@solana/web3.js';
6
+
7
+ interface SolanaWalletProvider {
8
+ signAndSendTransaction(transaction: Transaction): Promise<string | {
9
+ signature?: string;
10
+ hash?: string;
11
+ txid?: string;
12
+ transactionId?: string;
13
+ }>;
14
+ signTransaction?(transaction: Transaction): Promise<Transaction>;
15
+ publicKey?: {
16
+ toBase58(): string;
17
+ };
18
+ }
19
+
20
+ /**
21
+ * The wallet the flow signs with, unifying EVM and Solana access behind one
22
+ * object. AppKit is one implementation (`useReownWalletSession`); a host that
23
+ * holds its own wallet supplies another. Nothing here may reference AppKit —
24
+ * that an implementation can be written without importing it is the point.
25
+ */
26
+ interface WalletSession {
27
+ walletClient: WalletClient | undefined;
28
+ /**
29
+ * Whether this session can sign an EVM transaction right now. It is what the
30
+ * picker offers an EVM row on.
31
+ *
32
+ * Required, and answered by the implementation rather than inferred by the
33
+ * caller, because the caller can only infer it from whichever object it
34
+ * happens to check — and that has silently removed a connected user's wallet
35
+ * from the picker twice: once on `publicClient`, once on a resolvable viem
36
+ * chain. An implementation that has not thought about it now fails to
37
+ * compile.
38
+ *
39
+ * Distinct from `isReady`, which is about the provider having initialised.
40
+ *
41
+ * The invariant callers rely on: `true` means `walletClient` is defined, with
42
+ * an account and a chain bound.
43
+ */
44
+ canSignEvm: boolean;
45
+ /** Optional: every read falls back to `getPublicClient(chainId, rpcUrls)`,
46
+ * so an implementation with no wallet-backed client omits it. */
47
+ publicClient: PublicClient | undefined;
48
+ address: Address | undefined;
49
+ caipAddress?: string;
50
+ isConnected: boolean;
51
+ isReady: boolean;
52
+ icon?: string;
53
+ isSolana: boolean;
54
+ solanaAddress?: string;
55
+ solanaProvider?: SolanaWalletProvider;
56
+ /** RPC connection managed by the connected Solana wallet session, used for
57
+ * reads (blockhash, account info) instead of an app-configured RPC. */
58
+ solanaConnection?: Connection;
59
+ openConnect: () => void;
60
+ disconnect: () => void;
61
+ switchChain: (chainId: number) => Promise<void>;
62
+ }
63
+
64
+ /** A `window`, or anything shaped enough like one to hold the two globals. */
65
+ type ChannelTarget = Record<string, unknown>;
66
+
67
+ /**
68
+ * The message contract between the embed page and a native host.
69
+ *
70
+ * **This contract evolves; it is not frozen.** One URL serves every wrapper,
71
+ * and the handshake tells the page which protocol version and which
72
+ * capabilities the wrapper on the other side understands, so the page adapts
73
+ * at runtime. That puts the compatibility burden on the side we can actually
74
+ * update — a hosted page — rather than on app-store builds we cannot.
75
+ *
76
+ * The discipline that makes it safe:
77
+ *
78
+ * - an existing field never changes meaning, and never changes type;
79
+ * - new fields are optional, and a receiver ignores what it does not know;
80
+ * - an unknown event type is dropped, an unknown request method answers 4200;
81
+ * - behaviour that differs by wrapper version is gated on `HelloResult.protocol`
82
+ * and `HelloResult.capabilities` — what the HOST speaks. The page's own
83
+ * version tells it nothing it does not already know.
84
+ *
85
+ * A `/v1/` path exists only as an escape hatch for a break so fundamental the
86
+ * page cannot adapt to it. Reaching for it means every integrator ships an
87
+ * app-store release, so it is a last resort rather than a versioning scheme.
88
+ */
89
+
90
+ type EmbedMode = "deposit" | "withdraw" | "claim";
91
+ /**
92
+ * Every prop that survives a JSON hop. Names match the React props 1:1 on
93
+ * purpose — this is a transport, not a redesign, and a renamed field is a
94
+ * second thing to keep in sync forever.
95
+ *
96
+ * Config crosses the bridge and never the URL: a public URL taking a recipient
97
+ * and a backend URL is a phishing surface, and it would put keyed RPC
98
+ * endpoints into URL bars and logs.
99
+ */
100
+ interface EmbedConfig {
101
+ mode: EmbedMode;
102
+ backendUrl: string;
103
+ recipient: string;
104
+ /** Never a viem `Chain`. This value is hashed into the account salt, so its
105
+ * spelling is a deposit address. */
106
+ targetChain: TargetChain;
107
+ targetToken: string;
108
+ sourceChain?: number;
109
+ sourceToken?: string;
110
+ /** USD amount, or the case-insensitive sentinel `"max"`. */
111
+ defaultAmount?: string;
112
+ appBalanceUsd?: number;
113
+ outputTokenRules?: OutputTokenRule[];
114
+ rejectUnmapped?: boolean;
115
+ forceRegister?: boolean;
116
+ /**
117
+ * No `rpcUrls`. The web modal takes them so an integrator can route reads
118
+ * through their own endpoints, but those endpoints are usually keyed, and
119
+ * config crossing the bridge rather than the URL was to keep keyed endpoints
120
+ * out of logs — putting them in the handshake instead hands them to whatever
121
+ * the host logs, and to any frame that reaches an unscoped channel. The
122
+ * chain set already carries `publicRpcUrl`, so nothing is blocked without
123
+ * them, and a new optional field is the one change this contract makes
124
+ * cheaply: it can be added the day a client needs it, where removing it
125
+ * later could not.
126
+ */
127
+ enableWallet?: boolean;
128
+ enableFiatOnramp?: boolean;
129
+ enableQrTransfer?: boolean;
130
+ enableGaslessDeposit?: boolean;
131
+ enableExchangeConnect?: boolean;
132
+ /**
133
+ * Opt out of sending session analytics to Rhinestone. Default: on. The URL
134
+ * override the web props carry is deliberately absent — it exists for our own
135
+ * dev verification, and a bridge field can be added later but never removed.
136
+ */
137
+ enableAnalyticsIngest?: boolean;
138
+ fiatMethods?: FiatMethodsConfig;
139
+ assetMigrations?: AssetMigrationsConfig;
140
+ initialAssetMigration?: keyof AssetMigrationsConfig;
141
+ /**
142
+ * **The page never follows the OS on its own.** An absent `mode` is light,
143
+ * and `theme.mode: "system"` — protocol 2 — is what asks the page to read
144
+ * `prefers-color-scheme`. Following it silently would drop a dark funding
145
+ * sheet into a light single-appearance app the moment the user's phone
146
+ * switched, which is the host's call to make and not ours.
147
+ *
148
+ * **Appearance is not a mount-time value.** It can change while the sheet is
149
+ * open, so a host that tracks it re-sends its config over
150
+ * `session.configure`; the page repaints in place and the flow is not
151
+ * disturbed. This is why theming has to live in the bridge config rather
152
+ * than being handed over once at hello.
153
+ *
154
+ * **`"system"` does not mean the same thing on both platforms.** WKWebView
155
+ * reports the app's effective appearance. Android's WebView reports its
156
+ * theme's `isLightTheme`, which is *light* whenever the app never declares
157
+ * one — so an unthemed Android host reads light in OS dark mode, and reads
158
+ * it silently. A host that knows its own appearance should send `"light"` or
159
+ * `"dark"` and update it, which is also the only option for an app whose
160
+ * appearance is its own setting rather than the OS one.
161
+ */
162
+ theme?: DepositModalTheme;
163
+ uiConfig?: DepositModalUIConfig;
164
+ debug?: boolean;
165
+ /** Withdraw only. */
166
+ accountAddress?: string;
167
+ /** Claim only: prefills the lookup form. */
168
+ defaultTxHash?: string;
169
+ /** Claim only: seeds the refund destination, which the user can still edit.
170
+ * Deliberately never defaulted to the deposit's sender — returning funds to
171
+ * an exchange hot wallet can lose them. */
172
+ defaultDestination?: string;
173
+ }
174
+
175
+ interface DepositEmbedProps {
176
+ /** Where the injected channel lives. Defaults to this page's `window`. */
177
+ target?: ChannelTarget;
178
+ /** The handshake failed, so there is no session and no config to render. */
179
+ onFatal?: (error: unknown) => void;
180
+ }
181
+ declare function DepositEmbed({ target, onFatal }: DepositEmbedProps): react.JSX.Element | null;
182
+
183
+ export { DepositEmbed, type DepositEmbedProps, type EmbedConfig, type WalletSession };