@nexus-cross/crossx-sdk-core 0.0.0-beta.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.
Files changed (94) hide show
  1. package/README.md +302 -0
  2. package/dist/__tests__/mocks/MockCryptoPort.d.ts +15 -0
  3. package/dist/__tests__/mocks/MockCryptoPort.d.ts.map +1 -0
  4. package/dist/__tests__/mocks/MockOAuthPort.d.ts +11 -0
  5. package/dist/__tests__/mocks/MockOAuthPort.d.ts.map +1 -0
  6. package/dist/__tests__/mocks/MockStoragePort.d.ts +18 -0
  7. package/dist/__tests__/mocks/MockStoragePort.d.ts.map +1 -0
  8. package/dist/__tests__/mocks/MockTransportPort.d.ts +14 -0
  9. package/dist/__tests__/mocks/MockTransportPort.d.ts.map +1 -0
  10. package/dist/__tests__/mocks/MockWalletProviderPort.d.ts +28 -0
  11. package/dist/__tests__/mocks/MockWalletProviderPort.d.ts.map +1 -0
  12. package/dist/__tests__/sdk/CROSSxSDK.test.d.ts +2 -0
  13. package/dist/__tests__/sdk/CROSSxSDK.test.d.ts.map +1 -0
  14. package/dist/__tests__/sdk/EthereumProvider.test.d.ts +2 -0
  15. package/dist/__tests__/sdk/EthereumProvider.test.d.ts.map +1 -0
  16. package/dist/__tests__/usecases/SignInUseCase.test.d.ts +2 -0
  17. package/dist/__tests__/usecases/SignInUseCase.test.d.ts.map +1 -0
  18. package/dist/__tests__/usecases/SignOutUseCase.test.d.ts +2 -0
  19. package/dist/__tests__/usecases/SignOutUseCase.test.d.ts.map +1 -0
  20. package/dist/__tests__/usecases/WithdrawUseCase.test.d.ts +2 -0
  21. package/dist/__tests__/usecases/WithdrawUseCase.test.d.ts.map +1 -0
  22. package/dist/adapters/confirmation/BrowserConfirmationAdapter.d.ts +36 -0
  23. package/dist/adapters/confirmation/BrowserConfirmationAdapter.d.ts.map +1 -0
  24. package/dist/adapters/crypto/JoseCryptoAdapter.d.ts +16 -0
  25. package/dist/adapters/crypto/JoseCryptoAdapter.d.ts.map +1 -0
  26. package/dist/adapters/index.d.ts +10 -0
  27. package/dist/adapters/index.d.ts.map +1 -0
  28. package/dist/adapters/oauth/BrowserOAuthAdapter.d.ts +7 -0
  29. package/dist/adapters/oauth/BrowserOAuthAdapter.d.ts.map +1 -0
  30. package/dist/adapters/storage/LocalStorageAdapter.d.ts +10 -0
  31. package/dist/adapters/storage/LocalStorageAdapter.d.ts.map +1 -0
  32. package/dist/adapters/transport/FetchTransportAdapter.d.ts +6 -0
  33. package/dist/adapters/transport/FetchTransportAdapter.d.ts.map +1 -0
  34. package/dist/adapters/wallet/MockWalletProviderAdapter.d.ts +28 -0
  35. package/dist/adapters/wallet/MockWalletProviderAdapter.d.ts.map +1 -0
  36. package/dist/adapters/wallet/RemoteWalletProviderAdapter.d.ts +47 -0
  37. package/dist/adapters/wallet/RemoteWalletProviderAdapter.d.ts.map +1 -0
  38. package/dist/adapters/wallet/types.d.ts +112 -0
  39. package/dist/adapters/wallet/types.d.ts.map +1 -0
  40. package/dist/core/index.d.ts +9 -0
  41. package/dist/core/index.d.ts.map +1 -0
  42. package/dist/core/ports/ConfirmationPort.d.ts +74 -0
  43. package/dist/core/ports/ConfirmationPort.d.ts.map +1 -0
  44. package/dist/core/ports/CryptoPort.d.ts +43 -0
  45. package/dist/core/ports/CryptoPort.d.ts.map +1 -0
  46. package/dist/core/ports/LoggerPort.d.ts +23 -0
  47. package/dist/core/ports/LoggerPort.d.ts.map +1 -0
  48. package/dist/core/ports/OAuthPort.d.ts +18 -0
  49. package/dist/core/ports/OAuthPort.d.ts.map +1 -0
  50. package/dist/core/ports/StoragePort.d.ts +25 -0
  51. package/dist/core/ports/StoragePort.d.ts.map +1 -0
  52. package/dist/core/ports/TransportPort.d.ts +24 -0
  53. package/dist/core/ports/TransportPort.d.ts.map +1 -0
  54. package/dist/core/ports/WalletProviderPort.d.ts +106 -0
  55. package/dist/core/ports/WalletProviderPort.d.ts.map +1 -0
  56. package/dist/core/ports/index.d.ts +12 -0
  57. package/dist/core/ports/index.d.ts.map +1 -0
  58. package/dist/core/services/TokenMemoryStore.d.ts +17 -0
  59. package/dist/core/services/TokenMemoryStore.d.ts.map +1 -0
  60. package/dist/core/types/caip.d.ts +119 -0
  61. package/dist/core/types/caip.d.ts.map +1 -0
  62. package/dist/core/types/chain.d.ts +90 -0
  63. package/dist/core/types/chain.d.ts.map +1 -0
  64. package/dist/core/types/errors.d.ts +56 -0
  65. package/dist/core/types/errors.d.ts.map +1 -0
  66. package/dist/core/types/index.d.ts +309 -0
  67. package/dist/core/types/index.d.ts.map +1 -0
  68. package/dist/core/types/prepare.d.ts +21 -0
  69. package/dist/core/types/prepare.d.ts.map +1 -0
  70. package/dist/core/usecases/MigrateWalletUseCase.d.ts +10 -0
  71. package/dist/core/usecases/MigrateWalletUseCase.d.ts.map +1 -0
  72. package/dist/core/usecases/SignInUseCase.d.ts +38 -0
  73. package/dist/core/usecases/SignInUseCase.d.ts.map +1 -0
  74. package/dist/core/usecases/SignOutUseCase.d.ts +10 -0
  75. package/dist/core/usecases/SignOutUseCase.d.ts.map +1 -0
  76. package/dist/core/usecases/WithdrawUseCase.d.ts +11 -0
  77. package/dist/core/usecases/WithdrawUseCase.d.ts.map +1 -0
  78. package/dist/core/usecases/index.d.ts +9 -0
  79. package/dist/core/usecases/index.d.ts.map +1 -0
  80. package/dist/core/utils/apiUrl.d.ts +16 -0
  81. package/dist/core/utils/apiUrl.d.ts.map +1 -0
  82. package/dist/core/utils/logger.d.ts +19 -0
  83. package/dist/core/utils/logger.d.ts.map +1 -0
  84. package/dist/index.cjs +939 -0
  85. package/dist/index.d.ts +14 -0
  86. package/dist/index.d.ts.map +1 -0
  87. package/dist/index.js +4773 -0
  88. package/dist/sdk/CROSSxSDK.d.ts +278 -0
  89. package/dist/sdk/CROSSxSDK.d.ts.map +1 -0
  90. package/dist/sdk/EthereumProvider.d.ts +32 -0
  91. package/dist/sdk/EthereumProvider.d.ts.map +1 -0
  92. package/dist/sdk/factory.d.ts +8 -0
  93. package/dist/sdk/factory.d.ts.map +1 -0
  94. package/package.json +52 -0
package/dist/index.js ADDED
@@ -0,0 +1,4773 @@
1
+ var dr = Object.defineProperty;
2
+ var ur = (s, e, r) => e in s ? dr(s, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : s[e] = r;
3
+ var w = (s, e, r) => ur(s, typeof e != "symbol" ? e + "" : e, r);
4
+ import { decodeJwt as hr } from "jose";
5
+ var p = /* @__PURE__ */ ((s) => (s.AUTH_NOT_INITIALIZED = "AUTH_NOT_INITIALIZED", s.AUTH_FAILED = "AUTH_FAILED", s.AUTH_TOKEN_INVALID = "AUTH_TOKEN_INVALID", s.AUTH_TOKEN_EXPIRED = "AUTH_TOKEN_EXPIRED", s.AUTH_NOT_AUTHENTICATED = "AUTH_NOT_AUTHENTICATED", s.WALLET_NOT_FOUND = "WALLET_NOT_FOUND", s.WALLET_CREATION_FAILED = "WALLET_CREATION_FAILED", s.SIGN_FAILED = "SIGN_FAILED", s.SIGN_REJECTED = "SIGN_REJECTED", s.TX_FAILED = "TX_FAILED", s.TX_REJECTED = "TX_REJECTED", s.USER_REJECTED = "USER_REJECTED", s.TX_INVALID_PARAMS = "TX_INVALID_PARAMS", s.NETWORK_ERROR = "NETWORK_ERROR", s.NETWORK_NOT_CONFIGURED = "NETWORK_NOT_CONFIGURED", s.INVALID_CHAIN = "INVALID_CHAIN", s.CHAIN_NOT_SUPPORTED = "CHAIN_NOT_SUPPORTED", s.CHAIN_ADAPTER_NOT_FOUND = "CHAIN_ADAPTER_NOT_FOUND", s.NOT_IMPLEMENTED = "NOT_IMPLEMENTED", s.SIGNATURE_FAILED = "SIGNATURE_FAILED", s.TRANSACTION_FAILED = "TRANSACTION_FAILED", s.PREPARE_FAILED = "PREPARE_FAILED", s.PREPARE_EXPIRED = "PREPARE_EXPIRED", s.PREPARE_MISMATCH = "PREPARE_MISMATCH", s.MIGRATION_FAILED = "MIGRATION_FAILED", s.MIGRATION_BACKUP_EXISTS = "MIGRATION_BACKUP_EXISTS", s.GATEWAY_INTERNAL_ERROR = "GATEWAY_INTERNAL_ERROR", s.GATEWAY_LOCK_CONFLICT = "GATEWAY_LOCK_CONFLICT", s.PROJECT_ID_MISSING = "PROJECT_ID_MISSING", s.ORIGIN_OR_APP_ID_MISSING = "ORIGIN_OR_APP_ID_MISSING", s.INVALID_APP_TYPE = "INVALID_APP_TYPE", s.PROJECT_NOT_REGISTERED = "PROJECT_NOT_REGISTERED", s.SIGNATURE_SIGNER_MISMATCH = "SIGNATURE_SIGNER_MISMATCH", s.INVALID_CONFIG = "INVALID_CONFIG", s.UNKNOWN_ERROR = "UNKNOWN_ERROR", s))(p || {});
6
+ class m extends Error {
7
+ constructor(e, r, t) {
8
+ super(r), this.code = e, this.details = t, this.name = "CROSSxError", Object.setPrototypeOf(this, m.prototype);
9
+ }
10
+ toJSON() {
11
+ return {
12
+ name: this.name,
13
+ code: this.code,
14
+ message: this.message,
15
+ details: this.details
16
+ };
17
+ }
18
+ }
19
+ class fr {
20
+ constructor(e, r) {
21
+ this.sdk = e, this.chainId = r, this._listeners = /* @__PURE__ */ new Map();
22
+ }
23
+ // ──────────────────────────────────────────────
24
+ // EIP-1193 request
25
+ // ──────────────────────────────────────────────
26
+ async request({ method: e, params: r = [] }) {
27
+ switch (e) {
28
+ case "eth_accounts":
29
+ case "eth_requestAccounts": {
30
+ const t = await this.sdk.getAddress();
31
+ return t ? [t.address] : [];
32
+ }
33
+ case "eth_chainId":
34
+ return this._caip2ToHex(this.chainId);
35
+ case "net_version":
36
+ return this.chainId.split(":")[1] ?? "1";
37
+ case "eth_signTransaction": {
38
+ const t = this._normalizeEIP1193Tx(r[0]);
39
+ return (await this.sdk.signTransaction(this.chainId, t)).signedTx;
40
+ }
41
+ case "eth_sendTransaction": {
42
+ const t = this._normalizeEIP1193Tx(r[0]);
43
+ return (await this.sdk.sendTransaction(this.chainId, t)).txHash;
44
+ }
45
+ case "personal_sign":
46
+ case "eth_sign":
47
+ throw new m(
48
+ p.NOT_IMPLEMENTED,
49
+ `${e} is not yet supported. Use sdk.signMessage() directly.`
50
+ );
51
+ case "eth_signTypedData":
52
+ case "eth_signTypedData_v1":
53
+ case "eth_signTypedData_v3":
54
+ case "eth_signTypedData_v4":
55
+ throw new m(
56
+ p.NOT_IMPLEMENTED,
57
+ `${e} is not yet supported. Use sdk.signTypedData() directly.`
58
+ );
59
+ default:
60
+ return this.sdk.walletRpc(e, r, this.chainId);
61
+ }
62
+ }
63
+ // ──────────────────────────────────────────────
64
+ // EIP-1193 이벤트
65
+ // ──────────────────────────────────────────────
66
+ on(e, r) {
67
+ return this._listeners.has(e) || this._listeners.set(e, /* @__PURE__ */ new Set()), this._listeners.get(e).add(r), this;
68
+ }
69
+ removeListener(e, r) {
70
+ var t;
71
+ return (t = this._listeners.get(e)) == null || t.delete(r), this;
72
+ }
73
+ /** 내부적으로 이벤트를 발행 (accountsChanged, chainChanged 등) */
74
+ emit(e, ...r) {
75
+ var t;
76
+ (t = this._listeners.get(e)) == null || t.forEach((n) => n(...r));
77
+ }
78
+ // ──────────────────────────────────────────────
79
+ // helpers
80
+ // ──────────────────────────────────────────────
81
+ /** CAIP-2 → EVM hex chainId (e.g. 'eip155:612044' → '0x956cc') */
82
+ _caip2ToHex(e) {
83
+ const r = e.split(":");
84
+ return `0x${parseInt(r[1] ?? "1", 10).toString(16)}`;
85
+ }
86
+ /**
87
+ * EIP-1193 tx 파라미터를 SDK UnsignedTransaction 형식으로 변환.
88
+ * EIP-1193에서는 gasLimit 대신 gas 를 사용하는 경우가 있으므로 정규화.
89
+ */
90
+ _normalizeEIP1193Tx(e) {
91
+ return {
92
+ from: e.from,
93
+ to: e.to,
94
+ value: e.value,
95
+ data: e.data,
96
+ gasLimit: e.gasLimit ?? e.gas,
97
+ gasPrice: e.gasPrice,
98
+ maxFeePerGas: e.maxFeePerGas,
99
+ maxPriorityFeePerGas: e.maxPriorityFeePerGas,
100
+ nonce: e.nonce !== void 0 ? parseInt(String(e.nonce), 16) : void 0,
101
+ chainId: parseInt(this.chainId.split(":")[1] ?? "1", 10)
102
+ };
103
+ }
104
+ }
105
+ const ht = "__crossx-confirm-style", te = "__crossx-confirm-overlay", gr = {
106
+ light: {
107
+ bg: "#FFFFFF",
108
+ border: "rgba(18,18,18,0.05)",
109
+ titleColor: "#121212",
110
+ subtitleColor: "rgba(18,18,18,0.7)",
111
+ labelColor: "rgba(18,18,18,0.5)",
112
+ valueColor: "#121212",
113
+ pillBg: "rgba(18,18,18,0.05)",
114
+ pillFromColor: "rgba(18,18,18,0.5)",
115
+ pillAmtColor: "#121212",
116
+ divider: "rgba(18,18,18,0.1)",
117
+ closeColor: "#121212",
118
+ closeHoverBg: "rgba(18,18,18,0.05)",
119
+ copyColor: "rgba(18,18,18,0.5)",
120
+ inputBg: "#FFFFFF",
121
+ inputBorder: "rgba(18,18,18,0.1)",
122
+ hintColor: "rgba(18,18,18,0.5)",
123
+ primary: "#019D92",
124
+ primaryGlow: "rgba(1,157,146,0.15)",
125
+ secondary: "#E70077",
126
+ onPrimary: "#FFFFFF"
127
+ },
128
+ dark: {
129
+ bg: "#121212",
130
+ border: "rgba(255,255,255,0.05)",
131
+ titleColor: "#FFFFFF",
132
+ subtitleColor: "rgba(255,255,255,0.7)",
133
+ labelColor: "rgba(255,255,255,0.5)",
134
+ valueColor: "#FFFFFF",
135
+ pillBg: "rgba(255,255,255,0.05)",
136
+ pillFromColor: "rgba(255,255,255,0.5)",
137
+ pillAmtColor: "#FFFFFF",
138
+ divider: "rgba(255,255,255,0.1)",
139
+ closeColor: "#FFFFFF",
140
+ closeHoverBg: "rgba(255,255,255,0.05)",
141
+ copyColor: "rgba(255,255,255,0.5)",
142
+ inputBg: "#121212",
143
+ inputBorder: "rgba(255,255,255,0.1)",
144
+ hintColor: "rgba(255,255,255,0.5)",
145
+ primary: "#019D92",
146
+ primaryGlow: "rgba(1,157,146,0.15)",
147
+ secondary: "#E70077",
148
+ onPrimary: "#FFFFFF"
149
+ }
150
+ };
151
+ function ft(s, e) {
152
+ const r = gr[s], t = e == null ? void 0 : e[s];
153
+ return t ? {
154
+ ...r,
155
+ // ── Brand
156
+ ...t.primary !== void 0 && { primary: t.primary },
157
+ ...t.secondary !== void 0 && { secondary: t.secondary },
158
+ ...t.onPrimary !== void 0 && { onPrimary: t.onPrimary },
159
+ // ── Border
160
+ ...t.borderDefault !== void 0 && { border: t.borderDefault },
161
+ ...t.borderSubtle !== void 0 && { divider: t.borderSubtle, inputBorder: t.borderSubtle },
162
+ // ── TextIcon
163
+ ...t.textIconPrimary !== void 0 && {
164
+ titleColor: t.textIconPrimary,
165
+ valueColor: t.textIconPrimary,
166
+ pillAmtColor: t.textIconPrimary,
167
+ closeColor: t.textIconPrimary
168
+ },
169
+ ...t.textIconSecondary !== void 0 && { subtitleColor: t.textIconSecondary },
170
+ ...t.textIconTertiary !== void 0 && {
171
+ labelColor: t.textIconTertiary,
172
+ pillFromColor: t.textIconTertiary,
173
+ copyColor: t.textIconTertiary,
174
+ hintColor: t.textIconTertiary
175
+ },
176
+ // ── Surface
177
+ ...t.surfaceDefault !== void 0 && { pillBg: t.surfaceDefault, closeHoverBg: t.surfaceDefault },
178
+ ...t.bg !== void 0 && { bg: t.bg, inputBg: t.bg }
179
+ } : r;
180
+ }
181
+ const pr = `
182
+ @import url('https://fonts.googleapis.com/css2?family=Sora:wght@400;600&display=swap');
183
+
184
+ #${te} {
185
+ position: fixed;
186
+ inset: 0;
187
+ z-index: 2147483647;
188
+ display: flex;
189
+ align-items: center;
190
+ justify-content: center;
191
+ background: rgba(0,0,0,0.55);
192
+ font-family: 'Sora', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
193
+ animation: __crossx-fade-in 0.15s ease;
194
+ }
195
+ @keyframes __crossx-fade-in {
196
+ from { opacity: 0; }
197
+ to { opacity: 1; }
198
+ }
199
+
200
+ .__crossx-card {
201
+ background: var(--cx-bg);
202
+ border: 4px solid var(--cx-border);
203
+ border-radius: 24px;
204
+ width: 383px;
205
+ max-width: calc(100vw - 32px);
206
+ overflow: hidden;
207
+ position: relative;
208
+ animation: __crossx-slide-up 0.18s ease;
209
+ }
210
+ @keyframes __crossx-slide-up {
211
+ from { transform: translateY(20px); opacity: 0; }
212
+ to { transform: translateY(0); opacity: 1; }
213
+ }
214
+
215
+ /* ── Header ─────────────────────────────────────────────────────── */
216
+ .__crossx-header {
217
+ padding: 24px 24px 20px;
218
+ position: relative;
219
+ }
220
+ .__crossx-title {
221
+ font-size: 22px;
222
+ font-weight: 600;
223
+ line-height: 1.3;
224
+ color: var(--cx-title);
225
+ margin: 0 0 4px 0;
226
+ padding-right: 36px;
227
+ }
228
+ .__crossx-subtitle {
229
+ font-size: 14px;
230
+ font-weight: 400;
231
+ line-height: 1.3;
232
+ color: var(--cx-subtitle);
233
+ margin: 0;
234
+ }
235
+ .__crossx-close {
236
+ position: absolute;
237
+ top: 12px;
238
+ right: 12px;
239
+ width: 32px;
240
+ height: 32px;
241
+ border: none;
242
+ background: none;
243
+ cursor: pointer;
244
+ color: var(--cx-close);
245
+ border-radius: 8px;
246
+ display: flex;
247
+ align-items: center;
248
+ justify-content: center;
249
+ padding: 0;
250
+ appearance: none;
251
+ -webkit-appearance: none;
252
+ box-shadow: none;
253
+ outline: none;
254
+ }
255
+ .__crossx-close:hover,
256
+ .__crossx-close:focus {
257
+ background: none;
258
+ box-shadow: none;
259
+ outline: none;
260
+ filter: none;
261
+ transform: none;
262
+ }
263
+ .__crossx-close svg { display: block; }
264
+
265
+ /* ── Divider ─────────────────────────────────────────────────────── */
266
+ .__crossx-divider {
267
+ border: none;
268
+ border-top: 1px solid var(--cx-divider);
269
+ margin: 0;
270
+ }
271
+
272
+ /* ── Body ────────────────────────────────────────────────────────── */
273
+ .__crossx-body {
274
+ padding: 20px 24px 24px;
275
+ display: flex;
276
+ flex-direction: column;
277
+ gap: 16px;
278
+ }
279
+
280
+ /* Info rows */
281
+ .__crossx-rows {
282
+ display: flex;
283
+ flex-direction: column;
284
+ gap: 4px;
285
+ }
286
+ .__crossx-row {
287
+ display: flex;
288
+ align-items: center;
289
+ height: 20px;
290
+ }
291
+ .__crossx-row-label {
292
+ font-size: 13px;
293
+ font-weight: 400;
294
+ line-height: 1.3;
295
+ color: var(--cx-label);
296
+ width: 100px;
297
+ flex-shrink: 0;
298
+ }
299
+ .__crossx-row-value {
300
+ font-size: 13px;
301
+ font-weight: 400;
302
+ line-height: 1.3;
303
+ color: var(--cx-value);
304
+ flex: 1;
305
+ text-align: right;
306
+ display: flex;
307
+ align-items: center;
308
+ justify-content: flex-end;
309
+ gap: 4px;
310
+ min-width: 0;
311
+ overflow: hidden;
312
+ }
313
+ .__crossx-addr-text {
314
+ white-space: nowrap;
315
+ overflow: hidden;
316
+ text-overflow: ellipsis;
317
+ }
318
+ .__crossx-copy-btn {
319
+ background: none;
320
+ border: none;
321
+ cursor: pointer;
322
+ color: var(--cx-copy);
323
+ padding: 0;
324
+ display: flex;
325
+ align-items: center;
326
+ flex-shrink: 0;
327
+ opacity: 0.7;
328
+ transition: opacity 0.12s;
329
+ }
330
+ .__crossx-copy-btn:hover { opacity: 1; }
331
+
332
+ /* Amount pill */
333
+ .__crossx-pill {
334
+ background: var(--cx-pill-bg);
335
+ border-radius: 12px;
336
+ padding: 16px;
337
+ display: flex;
338
+ align-items: center;
339
+ gap: 8px;
340
+ }
341
+ .__crossx-pill-from {
342
+ font-size: 16px;
343
+ font-weight: 600;
344
+ line-height: 1.3;
345
+ color: var(--cx-pill-from);
346
+ white-space: nowrap;
347
+ overflow: hidden;
348
+ text-overflow: ellipsis;
349
+ flex-shrink: 1;
350
+ min-width: 0;
351
+ }
352
+ .__crossx-pill-amount {
353
+ font-size: 16px;
354
+ font-weight: 600;
355
+ line-height: 1.3;
356
+ color: var(--cx-pill-amt);
357
+ text-align: right;
358
+ white-space: nowrap;
359
+ flex-shrink: 0;
360
+ margin-left: auto;
361
+ }
362
+
363
+ /* Message box */
364
+ .__crossx-msg-box {
365
+ background: var(--cx-pill-bg);
366
+ border-radius: 12px;
367
+ padding: 16px;
368
+ max-height: 160px;
369
+ overflow-y: auto;
370
+ word-break: break-all;
371
+ font-size: 13px;
372
+ font-weight: 400;
373
+ line-height: 1.5;
374
+ color: var(--cx-value);
375
+ white-space: pre-wrap;
376
+ }
377
+
378
+
379
+ /* ── Migration Found Modal ─────────────────────────────────────── */
380
+ .__crossx-card--migration {
381
+ width: 560px;
382
+ }
383
+ .__crossx-subtitle--body {
384
+ font-size: 16px;
385
+ font-weight: 500;
386
+ line-height: 1.5;
387
+ color: var(--cx-subtitle);
388
+ margin: 0;
389
+ letter-spacing: -0.16px;
390
+ font-family: 'Pretendard', 'Sora', -apple-system, sans-serif;
391
+ }
392
+ .__crossx-mig-info {
393
+ display: flex;
394
+ flex-direction: column;
395
+ gap: 4px;
396
+ }
397
+ .__crossx-mig-info-title {
398
+ font-size: 14px;
399
+ font-weight: 600;
400
+ line-height: 1.4;
401
+ color: var(--cx-value);
402
+ margin: 0;
403
+ font-family: 'Pretendard', 'Sora', -apple-system, sans-serif;
404
+ }
405
+ .__crossx-mig-info-desc {
406
+ font-size: 14px;
407
+ font-weight: 400;
408
+ line-height: 1.4;
409
+ color: var(--cx-subtitle);
410
+ margin: 0;
411
+ font-family: 'Pretendard', 'Sora', -apple-system, sans-serif;
412
+ }
413
+ .__crossx-recover-btn {
414
+ display: flex;
415
+ align-items: center;
416
+ gap: 16px;
417
+ width: 100%;
418
+ padding: 16px;
419
+ background: var(--cx-pill-bg);
420
+ border: 1px solid var(--cx-pill-bg);
421
+ border-radius: 20px;
422
+ cursor: pointer;
423
+ appearance: none;
424
+ -webkit-appearance: none;
425
+ -webkit-tap-highlight-color: transparent;
426
+ box-shadow: none;
427
+ outline: none;
428
+ }
429
+ .__crossx-recover-btn:hover,
430
+ .__crossx-recover-btn:focus {
431
+ background: var(--cx-pill-bg);
432
+ border-color: var(--cx-pill-bg);
433
+ opacity: 1;
434
+ box-shadow: none;
435
+ outline: none;
436
+ filter: none;
437
+ transform: none;
438
+ }
439
+ .__crossx-recover-label {
440
+ font-size: 18px;
441
+ font-weight: 700;
442
+ line-height: 1.3;
443
+ color: var(--cx-value);
444
+ font-family: 'Pretendard', 'Sora', -apple-system, sans-serif;
445
+ }
446
+ .__crossx-skip-btn {
447
+ font-size: 16px;
448
+ font-weight: 400;
449
+ line-height: 1.3;
450
+ color: var(--cx-subtitle);
451
+ text-decoration: underline;
452
+ cursor: pointer;
453
+ text-align: center;
454
+ display: block;
455
+ background: none;
456
+ border: none;
457
+ width: 100%;
458
+ font-family: 'Sora', -apple-system, sans-serif;
459
+ padding: 0;
460
+ appearance: none;
461
+ -webkit-appearance: none;
462
+ -webkit-tap-highlight-color: transparent;
463
+ box-shadow: none;
464
+ outline: none;
465
+ }
466
+ .__crossx-skip-btn:hover,
467
+ .__crossx-skip-btn:focus {
468
+ background: none;
469
+ color: var(--cx-subtitle);
470
+ opacity: 1;
471
+ box-shadow: none;
472
+ outline: none;
473
+ filter: none;
474
+ transform: none;
475
+ text-decoration: underline;
476
+ }
477
+
478
+ /* ── PIN Input Modal ───────────────────────────────────────────── */
479
+ .__crossx-pin-center {
480
+ display: flex;
481
+ flex-direction: column;
482
+ align-items: center;
483
+ justify-content: center;
484
+ height: 272px;
485
+ gap: 16px;
486
+ padding: 20px 64px 24px;
487
+ }
488
+ .__crossx-pin-inputs {
489
+ display: flex;
490
+ gap: 16px;
491
+ }
492
+ .__crossx-pin-input {
493
+ width: 72px;
494
+ height: 72px;
495
+ border: 1px solid var(--cx-input-border);
496
+ border-radius: 8px;
497
+ background: var(--cx-input-bg);
498
+ text-align: center;
499
+ font-size: 32px;
500
+ font-weight: 600;
501
+ font-family: 'Sora', sans-serif;
502
+ color: var(--cx-value);
503
+ outline: none;
504
+ transition: border-color 0.15s, box-shadow 0.15s;
505
+ -webkit-text-security: disc;
506
+ }
507
+ .__crossx-pin-input:focus {
508
+ border-color: var(--cx-primary);
509
+ box-shadow: 0 0 0 2px var(--cx-primary-glow);
510
+ }
511
+ .__crossx-pin-input.--error {
512
+ border-color: var(--cx-secondary);
513
+ }
514
+ .__crossx-pin-hint {
515
+ font-size: 16px;
516
+ font-weight: 500;
517
+ line-height: 1.5;
518
+ color: var(--cx-subtitle);
519
+ text-align: center;
520
+ font-family: 'Pretendard', -apple-system, sans-serif;
521
+ letter-spacing: -0.16px;
522
+ margin: 0;
523
+ }
524
+ .__crossx-pin-error-text {
525
+ font-size: 14px;
526
+ font-weight: 500;
527
+ line-height: 1.4;
528
+ color: var(--cx-secondary);
529
+ text-align: center;
530
+ margin: 0;
531
+ }
532
+
533
+ /* ── Signature Request modals (message & typed data) ───────── */
534
+ .__crossx-sig-subtitle {
535
+ font-size: 18px;
536
+ font-weight: 600;
537
+ line-height: 1.3;
538
+ color: var(--cx-title);
539
+ text-align: center;
540
+ margin: 0;
541
+ }
542
+ .__crossx-sig-origin { color: var(--cx-primary); }
543
+ .__crossx-addr-pill {
544
+ background: var(--cx-pill-bg);
545
+ border-radius: 12px;
546
+ padding: 16px;
547
+ display: flex;
548
+ align-items: center;
549
+ justify-content: center;
550
+ gap: 8px;
551
+ color: var(--cx-value);
552
+ }
553
+ .__crossx-addr-pill-text {
554
+ font-size: 18px;
555
+ font-weight: 600;
556
+ line-height: 1.3;
557
+ color: var(--cx-value);
558
+ }
559
+ .__crossx-warning {
560
+ font-size: 14px;
561
+ font-weight: 400;
562
+ line-height: 1.3;
563
+ color: var(--cx-subtitle);
564
+ text-align: center;
565
+ margin: 0;
566
+ }
567
+ .__crossx-msg-raw {
568
+ font-size: 14px;
569
+ font-weight: 400;
570
+ line-height: 1.3;
571
+ color: var(--cx-label);
572
+ white-space: pre-wrap;
573
+ word-break: break-all;
574
+ max-height: 200px;
575
+ overflow-y: auto;
576
+ margin: 0;
577
+ }
578
+ .__crossx-td-rows {
579
+ display: flex;
580
+ flex-direction: column;
581
+ gap: 4px;
582
+ }
583
+ .__crossx-td-row {
584
+ display: flex;
585
+ align-items: center;
586
+ justify-content: space-between;
587
+ min-height: 20px;
588
+ gap: 20px;
589
+ }
590
+ .__crossx-td-label {
591
+ font-size: 13px;
592
+ font-weight: 400;
593
+ line-height: 1.3;
594
+ color: var(--cx-label);
595
+ flex-shrink: 0;
596
+ }
597
+ .__crossx-td-value {
598
+ font-size: 13px;
599
+ font-weight: 400;
600
+ line-height: 1.3;
601
+ color: var(--cx-value);
602
+ text-align: right;
603
+ display: flex;
604
+ align-items: center;
605
+ justify-content: flex-end;
606
+ gap: 4px;
607
+ min-width: 0;
608
+ }
609
+
610
+ /* ── Transaction modals ────────────────────────────────────── */
611
+ .__crossx-tx-subtitle {
612
+ font-size: 14px;
613
+ font-weight: 400;
614
+ line-height: 1.3;
615
+ color: var(--cx-subtitle);
616
+ margin: 0;
617
+ }
618
+ .__crossx-raw-tx {
619
+ background: var(--cx-pill-bg);
620
+ border-radius: 12px;
621
+ padding: 16px;
622
+ font-size: 13px;
623
+ font-weight: 400;
624
+ line-height: 1.6;
625
+ color: var(--cx-label);
626
+ white-space: pre-wrap;
627
+ word-break: break-all;
628
+ max-height: 180px;
629
+ overflow-y: auto;
630
+ margin: 0;
631
+ width: 100%;
632
+ box-sizing: border-box;
633
+ }
634
+ .__crossx-approve-btn {
635
+ width: 100%;
636
+ padding: 16px;
637
+ border: 1px solid rgba(18,18,18,0.05);
638
+ border-radius: 12px;
639
+ background: var(--cx-primary);
640
+ color: var(--cx-on-primary);
641
+ font-family: 'Pretendard', 'Sora', -apple-system, sans-serif;
642
+ font-size: 18px;
643
+ font-weight: 700;
644
+ line-height: 1.3;
645
+ cursor: pointer;
646
+ transition: opacity 0.12s, transform 0.1s;
647
+ }
648
+ .__crossx-approve-btn:hover { opacity: 0.9; }
649
+ .__crossx-approve-btn:active { transform: scale(0.98); }
650
+ .__crossx-btn-row {
651
+ display: flex;
652
+ gap: 8px;
653
+ width: 100%;
654
+ }
655
+ .__crossx-cancel-btn {
656
+ flex: 1;
657
+ padding: 16px;
658
+ border: 1px solid var(--cx-primary);
659
+ border-radius: 12px;
660
+ background: none;
661
+ color: var(--cx-primary);
662
+ font-family: 'Pretendard', 'Sora', -apple-system, sans-serif;
663
+ font-size: 18px;
664
+ font-weight: 700;
665
+ line-height: 1.3;
666
+ cursor: pointer;
667
+ transition: opacity 0.12s;
668
+ }
669
+ .__crossx-cancel-btn:hover { opacity: 0.8; }
670
+ .__crossx-confirm-btn {
671
+ flex: 1;
672
+ padding: 16px;
673
+ border: 1px solid rgba(18,18,18,0.05);
674
+ border-radius: 12px;
675
+ background: var(--cx-primary);
676
+ color: var(--cx-on-primary);
677
+ font-family: 'Pretendard', 'Sora', -apple-system, sans-serif;
678
+ font-size: 18px;
679
+ font-weight: 700;
680
+ line-height: 1.3;
681
+ cursor: pointer;
682
+ transition: opacity 0.12s, transform 0.1s;
683
+ }
684
+ .__crossx-confirm-btn:hover { opacity: 0.9; }
685
+ .__crossx-confirm-btn:active { transform: scale(0.98); }
686
+
687
+ /* ── Transaction Complete Modal ────────────────────────────── */
688
+ .__crossx-complete-body {
689
+ padding: 32px 24px 24px;
690
+ display: flex;
691
+ flex-direction: column;
692
+ align-items: center;
693
+ gap: 20px;
694
+ }
695
+ .__crossx-check-wrap {
696
+ width: 72px;
697
+ height: 72px;
698
+ border-radius: 50%;
699
+ background: var(--cx-primary);
700
+ display: flex;
701
+ align-items: center;
702
+ justify-content: center;
703
+ flex-shrink: 0;
704
+ animation: __crossx-pop-in 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
705
+ }
706
+ @keyframes __crossx-pop-in {
707
+ from { transform: scale(0.5); opacity: 0; }
708
+ to { transform: scale(1); opacity: 1; }
709
+ }
710
+ .__crossx-complete-texts {
711
+ display: flex;
712
+ flex-direction: column;
713
+ align-items: center;
714
+ gap: 6px;
715
+ text-align: center;
716
+ }
717
+ .__crossx-complete-title {
718
+ font-size: 22px;
719
+ font-weight: 700;
720
+ line-height: 1.3;
721
+ color: var(--cx-title);
722
+ margin: 0;
723
+ font-family: 'Pretendard', 'Sora', -apple-system, sans-serif;
724
+ }
725
+ .__crossx-complete-subtitle {
726
+ font-size: 14px;
727
+ font-weight: 400;
728
+ line-height: 1.5;
729
+ color: var(--cx-subtitle);
730
+ margin: 0;
731
+ }
732
+ .__crossx-complete-rows {
733
+ width: 100%;
734
+ display: flex;
735
+ flex-direction: column;
736
+ gap: 4px;
737
+ }
738
+ .__crossx-complete-amount {
739
+ width: 100%;
740
+ background: var(--cx-pill-bg);
741
+ border-radius: 12px;
742
+ padding: 16px;
743
+ font-size: 20px;
744
+ font-weight: 700;
745
+ line-height: 1.3;
746
+ color: var(--cx-title);
747
+ text-align: center;
748
+ font-family: 'Pretendard', 'Sora', -apple-system, sans-serif;
749
+ }
750
+ .__crossx-complete-btn-col {
751
+ display: flex;
752
+ flex-direction: column;
753
+ gap: 8px;
754
+ width: 100%;
755
+ }
756
+ .__crossx-explorer-btn {
757
+ width: 100%;
758
+ padding: 16px;
759
+ border: 1px solid var(--cx-primary);
760
+ border-radius: 12px;
761
+ background: none;
762
+ color: var(--cx-primary);
763
+ font-family: 'Pretendard', 'Sora', -apple-system, sans-serif;
764
+ font-size: 18px;
765
+ font-weight: 700;
766
+ line-height: 1.3;
767
+ cursor: pointer;
768
+ text-decoration: none;
769
+ display: flex;
770
+ align-items: center;
771
+ justify-content: center;
772
+ gap: 6px;
773
+ transition: opacity 0.12s;
774
+ box-sizing: border-box;
775
+ appearance: none;
776
+ -webkit-appearance: none;
777
+ }
778
+ .__crossx-explorer-btn:hover { opacity: 0.8; }
779
+ .__crossx-done-btn {
780
+ width: 100%;
781
+ padding: 16px;
782
+ border: 1px solid rgba(18,18,18,0.05);
783
+ border-radius: 12px;
784
+ background: var(--cx-primary);
785
+ color: var(--cx-on-primary);
786
+ font-family: 'Pretendard', 'Sora', -apple-system, sans-serif;
787
+ font-size: 18px;
788
+ font-weight: 700;
789
+ line-height: 1.3;
790
+ cursor: pointer;
791
+ transition: opacity 0.12s, transform 0.1s;
792
+ appearance: none;
793
+ -webkit-appearance: none;
794
+ }
795
+ .__crossx-done-btn:hover { opacity: 0.9; }
796
+ .__crossx-done-btn:active { transform: scale(0.98); }
797
+
798
+ /* ── Login Selector Modal ──────────────────────────────────── */
799
+ .__crossx-login-btn-row {
800
+ display: flex;
801
+ gap: 8px;
802
+ width: 100%;
803
+ }
804
+ .__crossx-login-btn {
805
+ flex: 1;
806
+ display: flex;
807
+ flex-direction: column;
808
+ gap: 16px;
809
+ padding: 16px;
810
+ background: var(--cx-pill-bg);
811
+ border: 1px solid var(--cx-border);
812
+ border-radius: 20px;
813
+ cursor: pointer;
814
+ align-items: flex-start;
815
+ justify-content: center;
816
+ appearance: none;
817
+ -webkit-appearance: none;
818
+ -webkit-tap-highlight-color: transparent;
819
+ box-shadow: none;
820
+ outline: none;
821
+ transition: opacity 0.12s;
822
+ min-width: 0;
823
+ }
824
+ .__crossx-login-btn:hover { opacity: 0.8; }
825
+ .__crossx-login-btn:focus {
826
+ outline: none;
827
+ box-shadow: none;
828
+ }
829
+ .__crossx-login-btn-label {
830
+ font-size: 18px;
831
+ font-weight: 700;
832
+ line-height: 1.3;
833
+ color: var(--cx-value);
834
+ font-family: 'Pretendard', 'Sora', -apple-system, sans-serif;
835
+ text-align: left;
836
+ white-space: nowrap;
837
+ }
838
+ .__crossx-login-icon {
839
+ width: 40px;
840
+ height: 40px;
841
+ flex-shrink: 0;
842
+ display: flex;
843
+ align-items: center;
844
+ justify-content: center;
845
+ }
846
+ .__crossx-login-terms {
847
+ font-size: 12px;
848
+ font-weight: 400;
849
+ line-height: 1.3;
850
+ color: var(--cx-subtitle);
851
+ text-align: center;
852
+ font-family: 'Pretendard', 'Sora', -apple-system, sans-serif;
853
+ margin: 0;
854
+ width: 100%;
855
+ }
856
+ .__crossx-login-terms-link {
857
+ color: var(--cx-primary);
858
+ text-decoration: none;
859
+ }
860
+
861
+ /* ── Mobile bottom sheet ───────────────────────────────────── */
862
+ @media (max-width: 480px) {
863
+ #${te} { align-items: flex-end; }
864
+ .__crossx-card {
865
+ width: 100%;
866
+ max-width: 100%;
867
+ border-radius: 24px 24px 0 0;
868
+ border-bottom: none;
869
+ max-height: 85vh;
870
+ overflow-y: auto;
871
+ animation: __crossx-slide-up-mobile 0.25s ease;
872
+ }
873
+ .__crossx-login-btn-row {
874
+ flex-direction: column;
875
+ }
876
+ .__crossx-login-btn-label {
877
+ white-space: normal;
878
+ }
879
+ }
880
+ @keyframes __crossx-slide-up-mobile {
881
+ from { transform: translateY(100%); }
882
+ to { transform: translateY(0); }
883
+ }
884
+ `;
885
+ function Se() {
886
+ let s = document.getElementById(ht);
887
+ s || (s = document.createElement("style"), s.id = ht, document.head.appendChild(s)), s.textContent = pr;
888
+ }
889
+ function he(s) {
890
+ return s ? s.length <= 13 ? s : `${s.slice(0, 6)}…${s.slice(-4)}` : "—";
891
+ }
892
+ function xr(s, e = "CROSS", r = 18) {
893
+ if (!s || s === "0x" || s === "0x0") return null;
894
+ try {
895
+ const t = BigInt(s);
896
+ if (t === 0n) return null;
897
+ const n = 10 ** r, o = Number(t) / n;
898
+ return o === 0 ? null : `${o.toPrecision(6).replace(/\.?0+$/, "")} ${e}`;
899
+ } catch {
900
+ return null;
901
+ }
902
+ }
903
+ const gt = {
904
+ 1: "Ethereum Mainnet",
905
+ 5: "Goerli Testnet",
906
+ 11155111: "Ethereum Sepolia",
907
+ 17e3: "Ethereum Holesky",
908
+ 10: "Optimism",
909
+ 420: "Optimism Goerli",
910
+ 42161: "Arbitrum One",
911
+ 421614: "Arbitrum Sepolia",
912
+ 8453: "Base",
913
+ 84532: "Base Sepolia",
914
+ 137: "Polygon",
915
+ 80002: "Polygon Amoy",
916
+ 56: "BNB Smart Chain",
917
+ 97: "BNB Testnet",
918
+ 43114: "Avalanche C-Chain",
919
+ 43113: "Avalanche Fuji",
920
+ 250: "Fantom Opera",
921
+ 612044: "CROSS Testnet",
922
+ 612055: "CROSS Mainnet"
923
+ }, _r = {
924
+ 1: "https://etherscan.io",
925
+ 5: "https://goerli.etherscan.io",
926
+ 11155111: "https://sepolia.etherscan.io",
927
+ 17e3: "https://holesky.etherscan.io",
928
+ 10: "https://optimistic.etherscan.io",
929
+ 420: "https://goerli-optimism.etherscan.io",
930
+ 42161: "https://arbiscan.io",
931
+ 421614: "https://sepolia.arbiscan.io",
932
+ 8453: "https://basescan.org",
933
+ 84532: "https://sepolia.basescan.org",
934
+ 137: "https://polygonscan.com",
935
+ 80002: "https://amoy.polygonscan.com",
936
+ 56: "https://bscscan.com",
937
+ 97: "https://testnet.bscscan.com",
938
+ 43114: "https://snowtrace.io",
939
+ 43113: "https://testnet.snowtrace.io",
940
+ 612044: "https://explorer-testnet.crossx.ai",
941
+ 612055: "https://explorer.crossx.ai"
942
+ };
943
+ function mr(s, e) {
944
+ const r = parseInt(s.split(":")[1] ?? "", 10), t = isNaN(r) ? void 0 : _r[r];
945
+ return t ? `${t}/tx/${e}` : null;
946
+ }
947
+ function Qe(s) {
948
+ const e = parseInt(s.split(":")[1] ?? "", 10);
949
+ return !isNaN(e) && gt[e] ? gt[e] : s;
950
+ }
951
+ function pt(s, e) {
952
+ if (s === 0n) return "0";
953
+ const r = 10n ** BigInt(e), t = s / r, i = (s % r).toString().padStart(e, "0").slice(0, 6).replace(/0+$/, "");
954
+ return i ? `${t}.${i}` : `${t}`;
955
+ }
956
+ function Pt(s) {
957
+ const { gasLimit: e, gasPrice: r, maxFeePerGas: t, nativeSymbol: n = "ETH", nativeDecimals: o = 18 } = s;
958
+ if (!e) return "—";
959
+ try {
960
+ const i = BigInt(e);
961
+ if (t) {
962
+ const a = i * BigInt(t);
963
+ return `${pt(a, o)} ${n}`;
964
+ }
965
+ if (r) {
966
+ const a = i * BigInt(r);
967
+ return `${pt(a, o)} ${n}`;
968
+ }
969
+ return `${i.toLocaleString()} gas`;
970
+ } catch {
971
+ return e;
972
+ }
973
+ }
974
+ const Ie = `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
975
+ <rect x="9" y="9" width="13" height="13" rx="2"/>
976
+ <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>
977
+ </svg>`, fe = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round">
978
+ <line x1="18" y1="6" x2="6" y2="18"/>
979
+ <line x1="6" y1="6" x2="18" y2="18"/>
980
+ </svg>`;
981
+ function wr(s) {
982
+ return `<svg width="28" height="28" viewBox="0 0 28 28" fill="none">
983
+ <circle cx="14" cy="14" r="14" fill="${s}"/>
984
+ <path d="M14 7.5L19.2 10.5V16.5L14 19.5L8.8 16.5V10.5L14 7.5Z" fill="white" opacity="0.9"/>
985
+ </svg>`;
986
+ }
987
+ const et = `<svg width="20" height="20" viewBox="0 0 20 20" fill="none">
988
+ <rect x="2" y="5" width="16" height="12" rx="2" stroke="currentColor" stroke-width="1.5"/>
989
+ <path d="M2 9h16" stroke="currentColor" stroke-width="1.5"/>
990
+ <rect x="12.5" y="11.5" width="3.5" height="2.5" rx="0.75" fill="currentColor"/>
991
+ </svg>`;
992
+ function ge(s) {
993
+ return [
994
+ `--cx-bg:${s.bg}`,
995
+ `--cx-border:${s.border}`,
996
+ `--cx-title:${s.titleColor}`,
997
+ `--cx-subtitle:${s.subtitleColor}`,
998
+ `--cx-label:${s.labelColor}`,
999
+ `--cx-value:${s.valueColor}`,
1000
+ `--cx-pill-bg:${s.pillBg}`,
1001
+ `--cx-pill-from:${s.pillFromColor}`,
1002
+ `--cx-pill-amt:${s.pillAmtColor}`,
1003
+ `--cx-divider:${s.divider}`,
1004
+ `--cx-close:${s.closeColor}`,
1005
+ `--cx-close-hover:${s.closeHoverBg}`,
1006
+ `--cx-copy:${s.copyColor}`,
1007
+ `--cx-input-bg:${s.inputBg}`,
1008
+ `--cx-input-border:${s.inputBorder}`,
1009
+ `--cx-hint:${s.hintColor}`,
1010
+ `--cx-primary:${s.primary}`,
1011
+ `--cx-primary-glow:${s.primaryGlow}`,
1012
+ `--cx-secondary:${s.secondary}`,
1013
+ `--cx-on-primary:${s.onPrimary}`
1014
+ ].join(";");
1015
+ }
1016
+ function oe(s, e) {
1017
+ return `
1018
+ <div class="__crossx-row">
1019
+ <span class="__crossx-row-label">${s}</span>
1020
+ <div class="__crossx-row-value">${e}</div>
1021
+ </div>`;
1022
+ }
1023
+ function yr(s, e) {
1024
+ const r = e, t = He(), n = s.to ? `<span class="__crossx-addr-text">${he(s.to)}</span>
1025
+ <button class="__crossx-copy-btn" data-copy="${s.to}" title="Copy address">${Ie}</button>` : "<span>—</span>", o = `<span>${Pt(s)}</span>`, i = s.data && s.data !== "0x" ? s.data : "0x", a = document.createElement("div");
1026
+ return a.id = te, a.innerHTML = `
1027
+ <div class="__crossx-card __crossx-card--migration" style="${ge(r)}" role="dialog" aria-modal="true" aria-labelledby="__crossx-ttl">
1028
+ <div class="__crossx-header">
1029
+ <p class="__crossx-title" id="__crossx-ttl">Signature Request</p>
1030
+ <button class="__crossx-close" id="__crossx-close-btn" aria-label="Close">${fe}</button>
1031
+ </div>
1032
+ <hr class="__crossx-divider">
1033
+ <div class="__crossx-body">
1034
+ <p class="__crossx-sig-subtitle">
1035
+ <span class="__crossx-sig-origin">${X(t)} </span>is requesting a Signature
1036
+ </p>
1037
+ <div class="__crossx-addr-pill">
1038
+ ${et}
1039
+ <span class="__crossx-addr-pill-text">${he(s.from)}</span>
1040
+ </div>
1041
+ <p class="__crossx-warning">After you sign, changes or cancellations are not possible.</p>
1042
+ <hr class="__crossx-divider">
1043
+ <div class="__crossx-rows">
1044
+ ${oe("To", n)}
1045
+ ${oe("Network", `<span>${Qe(s.chainId)}</span>`)}
1046
+ ${oe("Estimated fee", o)}
1047
+ </div>
1048
+ <pre class="__crossx-raw-tx">${X(i)}</pre>
1049
+ <div class="__crossx-btn-row">
1050
+ <button class="__crossx-cancel-btn" id="__crossx-cancel-btn">Cancel</button>
1051
+ <button class="__crossx-confirm-btn" id="__crossx-confirm-btn">Sign</button>
1052
+ </div>
1053
+ </div>
1054
+ </div>
1055
+ `, a;
1056
+ }
1057
+ function br(s, e) {
1058
+ const r = e, t = s.nativeSymbol ?? "ETH", n = s.nativeDecimals ?? 18, o = He(), i = s.to ? `<span class="__crossx-addr-text">${he(s.to)}</span>
1059
+ <button class="__crossx-copy-btn" data-copy="${s.to}" title="Copy address">${Ie}</button>` : "<span>—</span>", a = `<span>${Pt(s)}</span>`, l = xr(s.value, t, n) ?? (s.data && s.data !== "0x" ? "Contract Call" : `0 ${t}`), d = document.createElement("div");
1060
+ return d.id = te, d.innerHTML = `
1061
+ <div class="__crossx-card __crossx-card--migration" style="${ge(r)}" role="dialog" aria-modal="true" aria-labelledby="__crossx-ttl">
1062
+ <div class="__crossx-header">
1063
+ <p class="__crossx-title" id="__crossx-ttl">Approve transaction</p>
1064
+ <button class="__crossx-close" id="__crossx-close-btn" aria-label="Close">${fe}</button>
1065
+ </div>
1066
+ <hr class="__crossx-divider">
1067
+ <div class="__crossx-body">
1068
+ <p class="__crossx-tx-subtitle">
1069
+ <span class="__crossx-sig-origin">${X(o)}</span> wants your permission to approve the following transaction.
1070
+ </p>
1071
+ <div class="__crossx-rows">
1072
+ ${oe("To", i)}
1073
+ ${oe("Network", `<span>${Qe(s.chainId)}</span>`)}
1074
+ ${oe("Estimated fee", a)}
1075
+ </div>
1076
+ <div class="__crossx-pill">
1077
+ <span class="__crossx-pill-from">${he(s.from)}</span>
1078
+ <span class="__crossx-pill-amount">${l}</span>
1079
+ </div>
1080
+ <button class="__crossx-approve-btn" id="__crossx-confirm-btn">Approve</button>
1081
+ </div>
1082
+ </div>
1083
+ `, d;
1084
+ }
1085
+ function He() {
1086
+ var s;
1087
+ try {
1088
+ return ((s = window.location) == null ? void 0 : s.hostname) || "This site";
1089
+ } catch {
1090
+ return "This site";
1091
+ }
1092
+ }
1093
+ function X(s) {
1094
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
1095
+ }
1096
+ function vr(s) {
1097
+ return typeof s == "string" && /^0x[0-9a-fA-F]{40}$/i.test(s);
1098
+ }
1099
+ function Er(s) {
1100
+ if (typeof s == "string") return X(s);
1101
+ if (typeof s == "number" || typeof s == "bigint" || typeof s == "boolean") return String(s);
1102
+ try {
1103
+ return X(JSON.stringify(s));
1104
+ } catch {
1105
+ return String(s);
1106
+ }
1107
+ }
1108
+ const Sr = `<svg width="36" height="36" viewBox="0 0 36 36" fill="none">
1109
+ <path d="M8 18L15 25L28 11" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
1110
+ </svg>`, Tr = `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1111
+ <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>
1112
+ <polyline points="15 3 21 3 21 9"/>
1113
+ <line x1="10" y1="14" x2="21" y2="3"/>
1114
+ </svg>`;
1115
+ function Ir(s, e) {
1116
+ const r = mr(s.chainId, s.txHash), t = Qe(s.chainId), n = `${s.txHash.slice(0, 10)}…${s.txHash.slice(-8)}`, o = r ? `<a class="__crossx-explorer-btn" id="__crossx-explorer-btn" href="${r}" target="_blank" rel="noopener noreferrer">
1117
+ ${Tr} View on Explorer
1118
+ </a>` : "", i = s.amount ? `<div class="__crossx-complete-amount">${X(s.amount)}</div>` : "", a = s.to ? oe("To", `<span class="__crossx-addr-text">${he(s.to)}</span>
1119
+ <button class="__crossx-copy-btn" data-copy="${s.to}" title="Copy address">${Ie}</button>`) : "", c = document.createElement("div");
1120
+ return c.id = te, c.innerHTML = `
1121
+ <div class="__crossx-card __crossx-card--migration" style="${ge(e)}" role="dialog" aria-modal="true" aria-labelledby="__crossx-ttl">
1122
+ <div class="__crossx-header">
1123
+ <button class="__crossx-close" id="__crossx-close-btn" aria-label="Close">${fe}</button>
1124
+ </div>
1125
+ <div class="__crossx-complete-body">
1126
+ <div class="__crossx-check-wrap">${Sr}</div>
1127
+ <div class="__crossx-complete-texts">
1128
+ <p class="__crossx-complete-title" id="__crossx-ttl">Transaction Sent</p>
1129
+ <p class="__crossx-complete-subtitle">Your transaction has been submitted to the network.</p>
1130
+ </div>
1131
+ ${i}
1132
+ <div class="__crossx-complete-rows">
1133
+ ${a}
1134
+ ${oe("Network", `<span>${X(t)}</span>`)}
1135
+ ${oe("Tx Hash", `<span class="__crossx-addr-text">${X(n)}</span>
1136
+ <button class="__crossx-copy-btn" data-copy="${s.txHash}" title="Copy tx hash">${Ie}</button>`)}
1137
+ </div>
1138
+ <div class="__crossx-complete-btn-col">
1139
+ ${o}
1140
+ <button class="__crossx-done-btn" id="__crossx-done-btn">Done</button>
1141
+ </div>
1142
+ </div>
1143
+ </div>
1144
+ `, c;
1145
+ }
1146
+ function Ar(s, e) {
1147
+ const r = e, t = He(), n = X(s.message), o = document.createElement("div");
1148
+ return o.id = te, o.innerHTML = `
1149
+ <div class="__crossx-card __crossx-card--migration" style="${ge(r)}" role="dialog" aria-modal="true" aria-labelledby="__crossx-ttl">
1150
+ <div class="__crossx-header">
1151
+ <p class="__crossx-title" id="__crossx-ttl">Signature Request</p>
1152
+ <button class="__crossx-close" id="__crossx-close-btn" aria-label="Close">${fe}</button>
1153
+ </div>
1154
+ <hr class="__crossx-divider">
1155
+ <div class="__crossx-body">
1156
+ <p class="__crossx-sig-subtitle">
1157
+ <span class="__crossx-sig-origin">${X(t)} </span>is requesting a Signature
1158
+ </p>
1159
+ <div class="__crossx-addr-pill">
1160
+ ${et}
1161
+ <span class="__crossx-addr-pill-text">${he(s.from)}</span>
1162
+ </div>
1163
+ <p class="__crossx-warning">After you sign, changes or cancellations are not possible.</p>
1164
+ <hr class="__crossx-divider">
1165
+ <div class="__crossx-msg-raw">${n}</div>
1166
+ <div class="__crossx-btn-row">
1167
+ <button class="__crossx-cancel-btn" id="__crossx-cancel-btn">Cancel</button>
1168
+ <button class="__crossx-confirm-btn" id="__crossx-confirm-btn">Confirm</button>
1169
+ </div>
1170
+ </div>
1171
+ </div>
1172
+ `, o;
1173
+ }
1174
+ function Rr(s, e) {
1175
+ const r = e, t = He();
1176
+ let n = {};
1177
+ if (typeof s.typedData == "string")
1178
+ try {
1179
+ n = JSON.parse(s.typedData);
1180
+ } catch {
1181
+ }
1182
+ else s.typedData && typeof s.typedData == "object" && (n = s.typedData);
1183
+ const o = n.primaryType ?? "—", i = n.message ?? {};
1184
+ let a = `
1185
+ <div class="__crossx-td-row">
1186
+ <span class="__crossx-td-label">Primary Type</span>
1187
+ <span class="__crossx-td-value">${X(o)}</span>
1188
+ </div>`;
1189
+ for (const [l, d] of Object.entries(i)) {
1190
+ const f = Er(d), _ = vr(d) ? `<span class="__crossx-addr-text">${he(d)}</span>
1191
+ <button class="__crossx-copy-btn" data-copy="${d}" title="Copy">${Ie}</button>` : `<span>${f}</span>`;
1192
+ a += `
1193
+ <div class="__crossx-td-row">
1194
+ <span class="__crossx-td-label">${X(l)}</span>
1195
+ <div class="__crossx-td-value">${_}</div>
1196
+ </div>`;
1197
+ }
1198
+ const c = document.createElement("div");
1199
+ return c.id = te, c.innerHTML = `
1200
+ <div class="__crossx-card __crossx-card--migration" style="${ge(r)}" role="dialog" aria-modal="true" aria-labelledby="__crossx-ttl">
1201
+ <div class="__crossx-header">
1202
+ <p class="__crossx-title" id="__crossx-ttl">Signature Request</p>
1203
+ <button class="__crossx-close" id="__crossx-close-btn" aria-label="Close">${fe}</button>
1204
+ </div>
1205
+ <hr class="__crossx-divider">
1206
+ <div class="__crossx-body">
1207
+ <p class="__crossx-sig-subtitle">
1208
+ <span class="__crossx-sig-origin">${X(t)} </span>is requesting a Signature
1209
+ </p>
1210
+ <div class="__crossx-addr-pill">
1211
+ ${et}
1212
+ <span class="__crossx-addr-pill-text">${he(s.from)}</span>
1213
+ </div>
1214
+ <p class="__crossx-warning">After you sign, changes or cancellations are not possible.</p>
1215
+ <hr class="__crossx-divider">
1216
+ <div class="__crossx-td-rows">${a}</div>
1217
+ <div class="__crossx-btn-row">
1218
+ <button class="__crossx-cancel-btn" id="__crossx-cancel-btn">Cancel</button>
1219
+ <button class="__crossx-confirm-btn" id="__crossx-confirm-btn">Confirm</button>
1220
+ </div>
1221
+ </div>
1222
+ </div>
1223
+ `, c;
1224
+ }
1225
+ const Or = `<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
1226
+ <path d="M26.693 21.193c-.028-3.168 2.587-4.712 2.706-4.786-1.477-2.16-3.77-2.454-4.58-2.484-1.944-.197-3.804 1.148-4.793 1.148-.992 0-2.52-1.12-4.147-1.09-2.13.032-4.1 1.239-5.198 3.133-2.222 3.855-.569 9.562 1.593 12.69 1.061 1.535 2.318 3.258 3.975 3.196 1.6-.064 2.2-1.03 4.133-1.03 1.928 0 2.48 1.03 4.172.997 1.72-.03 2.806-1.56 3.862-3.1 1.211-1.779 1.713-3.495 1.74-3.583-.037-.017-3.427-1.316-3.463-5.09z" fill="currentColor"/>
1227
+ <path d="M23.527 11.876c.877-1.065 1.471-2.545 1.31-4.024-1.266.053-2.807.845-3.718 1.907-.813.946-1.53 2.468-1.34 3.915 1.41.107 2.852-.716 3.748-1.798z" fill="currentColor"/>
1228
+ </svg>`, Nr = `<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
1229
+ <path d="M38.06 20.44c0-1.34-.12-2.63-.34-3.87H20.5v7.32h9.84c-.42 2.28-1.71 4.21-3.65 5.51v4.57h5.91c3.46-3.19 5.46-7.88 5.46-13.53z" fill="#4285F4"/>
1230
+ <path d="M20.5 38.5c4.94 0 9.09-1.64 12.12-4.44l-5.91-4.57c-1.64 1.1-3.73 1.75-6.21 1.75-4.77 0-8.82-3.22-10.26-7.55H4.16v4.72A18.49 18.49 0 0 0 20.5 38.5z" fill="#34A853"/>
1231
+ <path d="M10.24 23.69A11.16 11.16 0 0 1 9.66 20c0-1.28.22-2.52.58-3.69v-4.72H4.16A18.49 18.49 0 0 0 2 20c0 2.97.71 5.78 1.97 8.28l6.27-4.59z" fill="#FBBC05"/>
1232
+ <path d="M20.5 8.76c2.69 0 5.1.92 7 2.73l5.24-5.24C29.58 3.36 25.43 1.5 20.5 1.5A18.49 18.49 0 0 0 4.16 11.59l6.08 4.72C11.68 11.98 15.73 8.76 20.5 8.76z" fill="#EA4335"/>
1233
+ </svg>`;
1234
+ function kr(s) {
1235
+ const e = s, r = document.createElement("div");
1236
+ return r.id = te, r.innerHTML = `
1237
+ <div class="__crossx-card __crossx-card--migration" style="${ge(e)}" role="dialog" aria-modal="true" aria-labelledby="__crossx-ttl">
1238
+ <div class="__crossx-header">
1239
+ <div style="display:flex;flex-direction:column;gap:4px;padding-right:36px;">
1240
+ <p class="__crossx-title" id="__crossx-ttl" style="padding-right:0;">Welcome onboard</p>
1241
+ <p class="__crossx-subtitle">Creating CROSSx Embedded Wallet</p>
1242
+ </div>
1243
+ <button class="__crossx-close" id="__crossx-close-btn" aria-label="Close">${fe}</button>
1244
+ </div>
1245
+ <hr class="__crossx-divider">
1246
+ <div class="__crossx-body">
1247
+ <div class="__crossx-login-btn-row">
1248
+ <button class="__crossx-login-btn" id="__crossx-apple-btn" type="button">
1249
+ <span class="__crossx-login-icon" style="color:var(--cx-value);">${Or}</span>
1250
+ <span class="__crossx-login-btn-label">Sign in with&nbsp;&nbsp;Apple</span>
1251
+ </button>
1252
+ <button class="__crossx-login-btn" id="__crossx-google-btn" type="button">
1253
+ <span class="__crossx-login-icon">${Nr}</span>
1254
+ <span class="__crossx-login-btn-label">Sign in with&nbsp;&nbsp;Google</span>
1255
+ </button>
1256
+ </div>
1257
+ <hr class="__crossx-divider">
1258
+ <p class="__crossx-login-terms">
1259
+ By continuing, you agree to NEXUS&nbsp;<a class="__crossx-login-terms-link" href="#" tabindex="-1">Terms of Service</a>&nbsp;and consent to its&nbsp;<a class="__crossx-login-terms-link" href="#" tabindex="-1">Privacy Policy.</a>
1260
+ </p>
1261
+ </div>
1262
+ </div>
1263
+ `, r;
1264
+ }
1265
+ function Cr(s) {
1266
+ const e = s, r = document.createElement("div");
1267
+ return r.id = te, r.innerHTML = `
1268
+ <div class="__crossx-card __crossx-card--migration" style="${ge(e)}" role="dialog" aria-modal="true" aria-labelledby="__crossx-ttl">
1269
+ <div class="__crossx-header">
1270
+ <p class="__crossx-title" id="__crossx-ttl">Wallet Found on Social Account 🎉</p>
1271
+ <p class="__crossx-subtitle--body">We found a wallet linked to your social account. Enter your 4-digit PIN to restore your assets.</p>
1272
+ <button class="__crossx-close" id="__crossx-close-btn" aria-label="Close">${fe}</button>
1273
+ </div>
1274
+ <hr class="__crossx-divider">
1275
+ <div class="__crossx-body">
1276
+ <div class="__crossx-mig-info">
1277
+ <p class="__crossx-mig-info-title">What is a Recovery Wallet?</p>
1278
+ <p class="__crossx-mig-info-desc">It safely restores and integrates all your previous assets. Simply verify your PIN to get started.</p>
1279
+ </div>
1280
+ <button class="__crossx-recover-btn" id="__crossx-recover-btn">
1281
+ <span>${wr(e.primary)}</span>
1282
+ <span class="__crossx-recover-label">Recover My Wallet</span>
1283
+ </button>
1284
+ <button class="__crossx-skip-btn" id="__crossx-skip-btn">Skip for Now</button>
1285
+ </div>
1286
+ </div>
1287
+ `, r;
1288
+ }
1289
+ function Pr(s, e) {
1290
+ const r = s, t = e ? `<p class="__crossx-pin-error-text">${e}</p>` : "", n = document.createElement("div");
1291
+ return n.id = te, n.innerHTML = `
1292
+ <div class="__crossx-card __crossx-card--migration" style="${ge(r)}" role="dialog" aria-modal="true" aria-labelledby="__crossx-ttl">
1293
+ <div class="__crossx-header">
1294
+ <p class="__crossx-title" id="__crossx-ttl">Recover My Wallet</p>
1295
+ <button class="__crossx-close" id="__crossx-close-btn" aria-label="Close">${fe}</button>
1296
+ </div>
1297
+ <hr class="__crossx-divider">
1298
+ <div class="__crossx-pin-center">
1299
+ <div class="__crossx-pin-inputs">
1300
+ <input class="__crossx-pin-input" type="tel" maxlength="1" inputmode="numeric" pattern="[0-9]" autocomplete="off">
1301
+ <input class="__crossx-pin-input" type="tel" maxlength="1" inputmode="numeric" pattern="[0-9]" autocomplete="off">
1302
+ <input class="__crossx-pin-input" type="tel" maxlength="1" inputmode="numeric" pattern="[0-9]" autocomplete="off">
1303
+ <input class="__crossx-pin-input" type="tel" maxlength="1" inputmode="numeric" pattern="[0-9]" autocomplete="off">
1304
+ </div>
1305
+ <p class="__crossx-pin-hint">Enter your 4-digit PIN to recover your wallet.</p>
1306
+ ${t}
1307
+ </div>
1308
+ </div>
1309
+ `, n;
1310
+ }
1311
+ function Lr(s, e, r) {
1312
+ var n;
1313
+ const t = s.querySelectorAll(".__crossx-pin-input");
1314
+ t.forEach((o, i) => {
1315
+ o.addEventListener("input", () => {
1316
+ const a = o.value.replace(/\D/g, "");
1317
+ o.value = a ? a[0] : "", a && i < 3 && t[i + 1].focus();
1318
+ const c = Array.from(t).map((l) => l.value).join("");
1319
+ c.length === 4 && setTimeout(() => e(c), 200);
1320
+ }), o.addEventListener("keydown", (a) => {
1321
+ a.key === "Backspace" && !o.value && i > 0 && (t[i - 1].focus(), t[i - 1].value = ""), a.key === "Escape" && r();
1322
+ }), o.addEventListener("keypress", (a) => {
1323
+ /[0-9]/.test(a.key) || a.preventDefault();
1324
+ }), o.addEventListener("paste", (a) => {
1325
+ var d;
1326
+ a.preventDefault();
1327
+ const c = (((d = a.clipboardData) == null ? void 0 : d.getData("text")) ?? "").replace(/\D/g, "").slice(0, 4);
1328
+ if (!c) return;
1329
+ c.split("").forEach((f, y) => {
1330
+ t[y] && (t[y].value = f);
1331
+ });
1332
+ const l = Math.min(c.length, 3);
1333
+ t[l].focus(), c.length === 4 && setTimeout(() => e(c), 200);
1334
+ });
1335
+ }), (n = t[0]) == null || n.focus();
1336
+ }
1337
+ class Br {
1338
+ constructor(e = "light", r) {
1339
+ this.theme = e, this.overrides = r, this.tokens = ft(e, r);
1340
+ }
1341
+ setTheme(e, r) {
1342
+ this.theme = e, r !== void 0 && (this.overrides = r), this.tokens = ft(e, this.overrides);
1343
+ }
1344
+ getTheme() {
1345
+ return this.theme;
1346
+ }
1347
+ /**
1348
+ * 로그인 프로바이더 선택 팝업: "Welcome onboard"
1349
+ * Apple / Google 버튼을 표시하고 선택된 프로바이더를 반환합니다.
1350
+ * @returns 'google' | 'apple' | null(취소)
1351
+ */
1352
+ showLoginSelector() {
1353
+ return new Promise((e) => {
1354
+ var a, c, l;
1355
+ Se();
1356
+ const r = kr(this.tokens);
1357
+ document.body.appendChild(r);
1358
+ const t = () => r.remove(), n = (d) => {
1359
+ t(), e(d);
1360
+ }, o = () => {
1361
+ t(), e(null);
1362
+ };
1363
+ (a = r.querySelector("#__crossx-apple-btn")) == null || a.addEventListener("click", () => n("apple")), (c = r.querySelector("#__crossx-google-btn")) == null || c.addEventListener("click", () => n("google")), (l = r.querySelector("#__crossx-close-btn")) == null || l.addEventListener("click", o), r.addEventListener("click", (d) => {
1364
+ d.target === r && o();
1365
+ }), r.querySelectorAll(".__crossx-login-terms-link").forEach((d) => {
1366
+ d.addEventListener("click", (f) => f.preventDefault());
1367
+ });
1368
+ const i = (d) => {
1369
+ d.key === "Escape" && (document.removeEventListener("keydown", i), o());
1370
+ };
1371
+ document.addEventListener("keydown", i);
1372
+ });
1373
+ }
1374
+ /**
1375
+ * 마이그레이션 발견 팝업: "Wallet Found on Social Account"
1376
+ * @returns 'recover' 또는 'skip'
1377
+ */
1378
+ showMigrationFoundPrompt() {
1379
+ return new Promise((e) => {
1380
+ var a, c, l;
1381
+ Se();
1382
+ const r = Cr(this.tokens);
1383
+ document.body.appendChild(r);
1384
+ const t = () => r.remove(), n = () => {
1385
+ t(), e("recover");
1386
+ }, o = () => {
1387
+ t(), e("skip");
1388
+ };
1389
+ (a = r.querySelector("#__crossx-recover-btn")) == null || a.addEventListener("click", n), (c = r.querySelector("#__crossx-skip-btn")) == null || c.addEventListener("click", o), (l = r.querySelector("#__crossx-close-btn")) == null || l.addEventListener("click", o), r.addEventListener("click", (d) => {
1390
+ d.target === r && o();
1391
+ });
1392
+ const i = (d) => {
1393
+ d.key === "Escape" && (document.removeEventListener("keydown", i), o());
1394
+ };
1395
+ document.addEventListener("keydown", i);
1396
+ });
1397
+ }
1398
+ /**
1399
+ * PIN 입력 팝업: "Recover My Wallet"
1400
+ * @param errorMessage 이전 시도 실패 시 에러 메시지
1401
+ * @returns 4자리 PIN 문자열 또는 null(취소)
1402
+ */
1403
+ showPinInputPrompt(e) {
1404
+ return new Promise((r) => {
1405
+ var a;
1406
+ Se();
1407
+ const t = Pr(this.tokens, e);
1408
+ document.body.appendChild(t);
1409
+ const n = () => t.remove(), o = (c) => {
1410
+ n(), r(c);
1411
+ }, i = () => {
1412
+ n(), r(null);
1413
+ };
1414
+ Lr(t, o, i), (a = t.querySelector("#__crossx-close-btn")) == null || a.addEventListener("click", i), t.addEventListener("click", (c) => {
1415
+ c.target === t && i();
1416
+ });
1417
+ });
1418
+ }
1419
+ /**
1420
+ * 트랜잭션 전송 완료 팝업을 표시합니다.
1421
+ * "Done" 버튼 클릭, 닫기 버튼 클릭, 배경 클릭, Escape 키로 닫힙니다.
1422
+ */
1423
+ showTransactionComplete(e) {
1424
+ return new Promise((r) => {
1425
+ var a, c;
1426
+ Se();
1427
+ const t = Ir(e, this.tokens);
1428
+ document.body.appendChild(t);
1429
+ const n = () => t.remove(), o = () => {
1430
+ n(), r();
1431
+ };
1432
+ (a = t.querySelector("#__crossx-done-btn")) == null || a.addEventListener("click", o), (c = t.querySelector("#__crossx-close-btn")) == null || c.addEventListener("click", o), t.querySelectorAll(".__crossx-copy-btn").forEach((l) => {
1433
+ l.addEventListener("click", (d) => {
1434
+ var y;
1435
+ d.stopPropagation();
1436
+ const f = l.dataset.copy;
1437
+ f && ((y = navigator.clipboard) == null || y.writeText(f).catch(() => {
1438
+ }));
1439
+ });
1440
+ }), t.addEventListener("click", (l) => {
1441
+ l.target === t && o();
1442
+ });
1443
+ const i = (l) => {
1444
+ l.key === "Escape" && (document.removeEventListener("keydown", i), o());
1445
+ };
1446
+ document.addEventListener("keydown", i);
1447
+ });
1448
+ }
1449
+ requestConfirmation(e) {
1450
+ return new Promise((r) => {
1451
+ var c, l, d;
1452
+ Se();
1453
+ let t;
1454
+ e.type === "sign-message" ? t = Ar(e, this.tokens) : e.type === "sign-typed-data" ? t = Rr(e, this.tokens) : e.type === "sign" ? t = yr(e, this.tokens) : t = br(e, this.tokens), document.body.appendChild(t);
1455
+ const n = () => t.remove(), o = () => {
1456
+ n(), r(!0);
1457
+ }, i = () => {
1458
+ n(), r(!1);
1459
+ };
1460
+ (c = t.querySelector("#__crossx-confirm-btn")) == null || c.addEventListener("click", o), (l = t.querySelector("#__crossx-cancel-btn")) == null || l.addEventListener("click", i), (d = t.querySelector("#__crossx-close-btn")) == null || d.addEventListener("click", i), t.querySelectorAll(".__crossx-copy-btn").forEach((f) => {
1461
+ f.addEventListener("click", (y) => {
1462
+ var E;
1463
+ y.stopPropagation();
1464
+ const _ = f.dataset.copy;
1465
+ _ && ((E = navigator.clipboard) == null || E.writeText(_).catch(() => {
1466
+ }));
1467
+ });
1468
+ }), t.addEventListener("click", (f) => {
1469
+ f.target === t && i();
1470
+ });
1471
+ const a = (f) => {
1472
+ f.key === "Escape" && (document.removeEventListener("keydown", a), i());
1473
+ };
1474
+ document.addEventListener("keydown", a);
1475
+ });
1476
+ }
1477
+ }
1478
+ let xe = null;
1479
+ function xt(s) {
1480
+ xe = s;
1481
+ }
1482
+ const g = {
1483
+ log(...s) {
1484
+ if (xe) {
1485
+ xe.log(...s);
1486
+ return;
1487
+ }
1488
+ },
1489
+ warn(...s) {
1490
+ if (xe) {
1491
+ xe.warn(...s);
1492
+ return;
1493
+ }
1494
+ },
1495
+ error(...s) {
1496
+ if (xe) {
1497
+ xe.error(...s);
1498
+ return;
1499
+ }
1500
+ }
1501
+ }, Ge = "crossx_access_token", Oe = "crossx_refresh_token", Ne = "crossx_user_info";
1502
+ class $r {
1503
+ constructor(e, r, t, n, o, i, a) {
1504
+ this.config = e, this.storage = r, this.crypto = t, this.oauth = n, this.transport = o, this.walletProvider = i, this.tokenStore = a, this._refreshPromise = null;
1505
+ }
1506
+ async execute(e) {
1507
+ var o, i, a, c;
1508
+ let r, t, n = !1;
1509
+ try {
1510
+ const l = e == null ? void 0 : e.provider;
1511
+ let d = "/login";
1512
+ l === "google" ? d = "/google" : l === "apple" && (d = "/apple");
1513
+ const f = this.config.oauthServiceUrl, y = `${f}${d}`;
1514
+ g.log(`[CROSSx] OAuth 팝업 열기 (${l || "일반"} 로그인):`, y);
1515
+ const _ = await this.oauth.openAuth({
1516
+ authUrl: y,
1517
+ expectedOrigin: new URL(f).origin
1518
+ });
1519
+ g.log("[CROSSx] OAuth Firebase 토큰 받음 (length:", _.length, ")");
1520
+ const E = this.config.authApiUrl, { accessToken: O, refreshToken: S } = await this.exchangeFirebaseToken(_, E);
1521
+ g.log("[CROSSx] CROSSx access_token 교환 성공"), r = this.crypto.decodeJWT(O), g.log("[CROSSx] access_token 디코딩 — sub:", r.sub, "exp:", r.exp);
1522
+ const C = await this.crypto.verifyJWT(O);
1523
+ if (n = C.signatureVerified ?? !1, g.log("[CROSSx] access_token 검증 결과:", C.valid), !C.valid)
1524
+ throw g.error("[CROSSx] access_token 검증 실패"), new Error("Invalid access token");
1525
+ const U = C.payload;
1526
+ let F, B;
1527
+ try {
1528
+ const q = this.crypto.decodeJWT(_);
1529
+ B = (o = q == null ? void 0 : q.firebase) == null ? void 0 : o.sign_in_provider;
1530
+ const K = ((i = q == null ? void 0 : q.firebase) == null ? void 0 : i.identities) ?? {};
1531
+ B === "google.com" ? F = (a = K["google.com"]) == null ? void 0 : a[0] : B === "apple.com" && (F = (c = K["apple.com"]) == null ? void 0 : c[0]), g.log("[CROSSx] OAuth provider sub 추출 — provider:", B, "hasProviderSub:", !!F);
1532
+ } catch {
1533
+ g.warn("[CROSSx] firebaseToken에서 providerSub 추출 실패, fallback으로 sub 사용");
1534
+ }
1535
+ t = {
1536
+ id: U.sub,
1537
+ email: U.email,
1538
+ ...U,
1539
+ ...B ? { signInProvider: B } : {},
1540
+ ...F ? { providerSub: F } : {}
1541
+ }, g.log("[CROSSx] 사용자 정보 — id:", t.id), this.tokenStore.set(O), await this.storage.set(Ge, O), S && await this.storage.set(Oe, S), await this.storage.set(Ne, t), g.log("[CROSSx] 토큰 및 사용자 정보 저장 완료");
1542
+ } catch (l) {
1543
+ return g.error("[CROSSx] SignIn 에러 (OAuth/토큰 교환 단계):", l), {
1544
+ success: !1,
1545
+ error: l instanceof Error ? l.message : "Sign in failed"
1546
+ };
1547
+ }
1548
+ return g.log("[CROSSx][Migration Phase 1] OAuth 로그인 완료, 지갑 로드 시작 — userId:", t.id), this.loadWallet(t, n);
1549
+ }
1550
+ /**
1551
+ * Firebase 토큰 → CROSSx access_token 교환
1552
+ * POST {authApiUrl}/social/login
1553
+ */
1554
+ async exchangeFirebaseToken(e, r) {
1555
+ const t = `${r}/cross-auth/social/login`;
1556
+ g.log("[CROSSx] Firebase 토큰 교환 요청:", t);
1557
+ const n = await this.transport.request({
1558
+ url: t,
1559
+ method: "POST",
1560
+ headers: { "Content-Type": "application/json" },
1561
+ body: { auth_code: e, login_type: "firebase" }
1562
+ });
1563
+ g.log("[CROSSx] 토큰 교환 응답 — status:", n.status);
1564
+ const o = n.data;
1565
+ if (o != null && o.code && o.code !== 200 && o.code > 0)
1566
+ throw new m(
1567
+ p.AUTH_FAILED,
1568
+ `Token exchange failed (code ${o.code}): ${o.message}`
1569
+ );
1570
+ const i = (o == null ? void 0 : o.data) ?? o, a = i == null ? void 0 : i.access_token, c = i == null ? void 0 : i.refresh_token;
1571
+ if (!a)
1572
+ throw g.error("[CROSSx] 교환 응답에서 access_token을 찾을 수 없음:", n), new m(
1573
+ p.AUTH_FAILED,
1574
+ "access_token not found in exchange response"
1575
+ );
1576
+ return { accessToken: a, refreshToken: c };
1577
+ }
1578
+ /**
1579
+ * 세션 복원
1580
+ *
1581
+ * 우선순위:
1582
+ * 1. 메모리에 유효한 access_token이 있으면 그대로 사용 (같은 탭 내 SDK 재초기화)
1583
+ * 2. 없으면 localStorage의 refresh_token으로 silentRefresh 시도
1584
+ * 3. refresh_token도 없거나 만료 → null (로그인 화면으로)
1585
+ */
1586
+ async restoreSession() {
1587
+ try {
1588
+ const e = this.tokenStore.get();
1589
+ if (e) {
1590
+ const o = await this.crypto.verifyJWT(e);
1591
+ if (o.valid) {
1592
+ const i = await this.storage.get(Ne);
1593
+ if (i)
1594
+ return g.log("[CROSSx] restoreSession — 메모리 토큰 유효, 세션 복원"), this.loadWallet(i, o.signatureVerified);
1595
+ }
1596
+ this.tokenStore.clear();
1597
+ }
1598
+ const r = await this.storage.get(Oe);
1599
+ if (!r)
1600
+ return g.log("[CROSSx] restoreSession — refresh_token 없음, 세션 복원 생략"), null;
1601
+ g.log("[CROSSx] restoreSession — refresh_token 발견, silentRefresh 시도");
1602
+ const t = await this.silentRefresh(r);
1603
+ this.tokenStore.set(t);
1604
+ const n = await this.storage.get(Ne);
1605
+ return n ? (g.log("[CROSSx] restoreSession — silentRefresh 성공, 세션 복원 — userId:", n.id), this.loadWallet(n, !1)) : null;
1606
+ } catch (e) {
1607
+ return g.log("[CROSSx] restoreSession — 세션 복원 실패, 스토리지 정리:", e), this.tokenStore.clear(), await this.storage.remove(Oe), await this.storage.remove(Ne), null;
1608
+ }
1609
+ }
1610
+ /**
1611
+ * refresh_token으로 새 access_token 발급 (silent refresh)
1612
+ * 동시 호출 시 단일 요청으로 deduplicate.
1613
+ */
1614
+ silentRefresh(e) {
1615
+ return this._refreshPromise ? this._refreshPromise : (this._refreshPromise = this._doSilentRefresh(e).finally(() => {
1616
+ this._refreshPromise = null;
1617
+ }), this._refreshPromise);
1618
+ }
1619
+ async _doSilentRefresh(e) {
1620
+ const t = `${this.config.authApiUrl}/cross-auth/social/refresh`, n = this.tokenStore.get() ?? await this.storage.get(Ge) ?? "", o = {
1621
+ refresh_token: e,
1622
+ access_token: n
1623
+ }, i = await this.transport.request({
1624
+ url: t,
1625
+ method: "POST",
1626
+ headers: { "Content-Type": "application/json" },
1627
+ body: o
1628
+ });
1629
+ g.log("[CROSSx] silentRefresh 응답 — status:", i.status);
1630
+ const a = i.data;
1631
+ if (a != null && a.code && a.code !== 200 && a.code > 0)
1632
+ throw new m(
1633
+ p.AUTH_FAILED,
1634
+ `Silent refresh failed (code ${a.code}): ${a.message}`
1635
+ );
1636
+ const c = (a == null ? void 0 : a.data) ?? a, l = c == null ? void 0 : c.token, d = c == null ? void 0 : c.refresh;
1637
+ if (!l)
1638
+ throw new m(p.AUTH_FAILED, "Silent refresh failed: no token in response");
1639
+ return this.tokenStore.set(l), await this.storage.set(Ge, l), d && await this.storage.set(Oe, d), g.log("[CROSSx] silentRefresh 성공"), l;
1640
+ }
1641
+ async loadWallet(e, r) {
1642
+ let t, n = !1;
1643
+ try {
1644
+ g.log("[CROSSx][Migration Phase 2] POST /mnemonic/create 호출 — userId:", e.id), t = (await this.walletProvider.getOrCreateWallet(e.id)).address, g.log("[CROSSx][Migration Phase 2] 지갑 로드 완료 (기존 백업 없음) — address:", t);
1645
+ } catch (o) {
1646
+ o instanceof m && o.code === p.MIGRATION_BACKUP_EXISTS ? (g.log("[CROSSx][Migration Phase 2] Gateway -10012 감지 → needsMigration = true"), n = !0) : g.warn("[CROSSx][Migration Phase 2] 지갑 로드 실패 (로그인은 유지):", o);
1647
+ }
1648
+ return g.log("[CROSSx][Migration Phase 2] loadWallet 결과 — address:", t, "needsMigration:", n), { success: !0, address: t, user: e, needsMigration: n, tokenSignatureVerified: r };
1649
+ }
1650
+ }
1651
+ const Mr = "crossx_access_token", Dr = "crossx_refresh_token", Ur = "crossx_user_info";
1652
+ class Hr {
1653
+ constructor(e, r) {
1654
+ this.storage = e, this.tokenStore = r;
1655
+ }
1656
+ async execute() {
1657
+ this.tokenStore.clear(), await this.storage.remove(Mr), await this.storage.remove(Dr), await this.storage.remove(Ur);
1658
+ }
1659
+ }
1660
+ const Fr = "crossx_access_token", qr = "crossx_refresh_token", Gr = "crossx_user_info", Wr = "I agree to delete my data";
1661
+ class Vr {
1662
+ constructor(e, r, t) {
1663
+ this.storage = e, this.walletProvider = r, this.tokenStore = t;
1664
+ }
1665
+ async execute() {
1666
+ if (!this.tokenStore.has())
1667
+ throw new m(
1668
+ p.AUTH_NOT_AUTHENTICATED,
1669
+ "인증되지 않은 상태입니다"
1670
+ );
1671
+ if (g.log("[CROSSx] 계정 탈퇴 처리 시작"), !this.walletProvider.withdraw)
1672
+ throw new m(
1673
+ p.NOT_IMPLEMENTED,
1674
+ "현재 환경에서는 탈퇴 기능을 지원하지 않습니다"
1675
+ );
1676
+ await this.walletProvider.withdraw(Wr), this.tokenStore.clear(), await this.storage.remove(Fr), await this.storage.remove(qr), await this.storage.remove(Gr), g.log("[CROSSx] 탈퇴 완료");
1677
+ }
1678
+ }
1679
+ class zr {
1680
+ constructor(e, r) {
1681
+ this.storage = e, this.walletProvider = r;
1682
+ }
1683
+ async execute(e, r) {
1684
+ if (!this.walletProvider.migrateWallet)
1685
+ throw new m(
1686
+ p.NOT_IMPLEMENTED,
1687
+ "Migration is not supported in the current environment"
1688
+ );
1689
+ g.log("[CROSSx][Migration Phase 4] MigrateWalletUseCase.execute() — pin 길이:", e.length, "sub:", r);
1690
+ const t = await this.walletProvider.migrateWallet(e, r);
1691
+ return g.log("[CROSSx][Migration Phase 5] MigrateWalletUseCase 완료 — address:", t.address), {
1692
+ address: t.address
1693
+ };
1694
+ }
1695
+ }
1696
+ const se = class se {
1697
+ constructor(e, r, t, n, o, i, a) {
1698
+ this.storage = r, this.crypto = t, this.transport = n, this.oauth = o, this.walletProvider = i, this.initialized = !1, this.authenticated = !1, this.userId = null, this.address = null, this.userEmail = null, this.loginType = null, this.providerSub = null, this.tokenSignatureVerified = !1, this._config = Object.freeze({ ...e }), e.logger && xt(e.logger), this.confirmation = new Br(e.theme ?? "light", e.themeTokens), this.signInUseCase = new $r(
1699
+ e,
1700
+ r,
1701
+ t,
1702
+ o,
1703
+ n,
1704
+ i,
1705
+ a
1706
+ ), this.signOutUseCase = new Hr(r, a), this.withdrawUseCase = new Vr(r, i, a), this.migrateWalletUseCase = new zr(r, i);
1707
+ }
1708
+ get config() {
1709
+ return this._config;
1710
+ }
1711
+ // ============================================================================
1712
+ // 초기화 & 인증
1713
+ // ============================================================================
1714
+ /**
1715
+ * SDK 초기화 및 세션 복원 시도
1716
+ *
1717
+ * @returns 복원된 세션이 있으면 `AuthResult`, 없으면 `null`
1718
+ *
1719
+ * @example
1720
+ * const session = await sdk.initialize();
1721
+ * if (session) {
1722
+ * console.log('자동 로그인:', session.address);
1723
+ * }
1724
+ */
1725
+ async initialize() {
1726
+ if (this.initialized) return this.authenticated ? { success: !0, address: this.address ?? void 0 } : null;
1727
+ console.log("[CROSSx SDK] v0.1.0 initializing...");
1728
+ try {
1729
+ const e = await this.signInUseCase.restoreSession();
1730
+ return e != null && e.success && this.applyAuthResult(e), this.initialized = !0, e ?? null;
1731
+ } catch (e) {
1732
+ throw new m(p.AUTH_NOT_INITIALIZED, "SDK initialization failed", e);
1733
+ }
1734
+ }
1735
+ async signIn(e) {
1736
+ this.ensureInitialized();
1737
+ let r = e;
1738
+ if (!(e != null && e.provider)) {
1739
+ const t = await this.confirmation.showLoginSelector();
1740
+ if (t === null)
1741
+ return { success: !1, error: "User cancelled login" };
1742
+ r = { ...e, provider: t };
1743
+ }
1744
+ try {
1745
+ const t = await this.signInUseCase.execute(r);
1746
+ return t.success && this.applyAuthResult(t), t;
1747
+ } catch (t) {
1748
+ throw new m(p.AUTH_FAILED, "Sign in failed", t);
1749
+ }
1750
+ }
1751
+ async signOut() {
1752
+ this.ensureInitialized();
1753
+ try {
1754
+ await this.signOutUseCase.execute(), this.clearAuthState();
1755
+ } catch (e) {
1756
+ throw new m(p.UNKNOWN_ERROR, "Sign out failed", e);
1757
+ }
1758
+ }
1759
+ async withdraw() {
1760
+ this.ensureAuthenticated(), await this.withdrawUseCase.execute(), this.clearAuthState();
1761
+ }
1762
+ isAuthenticated() {
1763
+ return this.authenticated;
1764
+ }
1765
+ /**
1766
+ * 현재 로그인 상태 확인 (isAuthenticated() 별칭)
1767
+ * Android SDK의 isLoggedIn()과 동일합니다.
1768
+ */
1769
+ isLoggedIn() {
1770
+ return this.isAuthenticated();
1771
+ }
1772
+ /**
1773
+ * 로그인 상태를 보장합니다.
1774
+ *
1775
+ * - 이미 인증된 상태면 즉시 `true` 반환
1776
+ * - 세션이 없어도 refresh_token이 유효하면 자동 복원 후 `true` 반환
1777
+ * - 복원 불가하면 `false` 반환 (에러를 throw하지 않습니다)
1778
+ *
1779
+ * @example
1780
+ * if (await sdk.ensureLoggedIn()) {
1781
+ * // 인증된 상태에서 작업
1782
+ * } else {
1783
+ * // 로그인 화면으로 이동
1784
+ * }
1785
+ */
1786
+ async ensureLoggedIn() {
1787
+ if (!this.initialized) return !1;
1788
+ if (this.authenticated) return !0;
1789
+ try {
1790
+ const e = await this.signInUseCase.restoreSession();
1791
+ return e != null && e.success ? (this.applyAuthResult(e), !0) : !1;
1792
+ } catch {
1793
+ return !1;
1794
+ }
1795
+ }
1796
+ /**
1797
+ * 현재 로그인한 사용자의 상세 정보를 반환합니다.
1798
+ * Android SDK의 getUserInfo()와 동일합니다.
1799
+ *
1800
+ * @returns `{ id, email?, loginType?, addresses }`
1801
+ */
1802
+ async getUserInfo() {
1803
+ return this.ensureAuthenticated(), {
1804
+ id: this.userId,
1805
+ email: this.userEmail ?? void 0,
1806
+ loginType: this.loginType ?? void 0,
1807
+ addresses: this.address ? [this.address] : [],
1808
+ tokenSignatureVerified: this.tokenSignatureVerified
1809
+ };
1810
+ }
1811
+ // ============================================================================
1812
+ // 마이그레이션
1813
+ // ============================================================================
1814
+ /**
1815
+ * CROSSx 지갑 → Embedded Wallet 마이그레이션
1816
+ *
1817
+ * 클라우드 백업에서 기존 CROSSx 지갑을 복구하여
1818
+ * Embedded Wallet으로 전환합니다.
1819
+ *
1820
+ * create 시 -10012 에러(기존 백업 발견)가 발생하면 자동으로 호출됩니다.
1821
+ *
1822
+ * @param pin 4자리 PIN (클라우드 백업 복호화용)
1823
+ * @returns 마이그레이션 결과 (address, shareC)
1824
+ */
1825
+ async migrateWallet(e) {
1826
+ if (this.ensureAuthenticated(), !this.userId)
1827
+ throw new m(p.AUTH_NOT_AUTHENTICATED, "User ID not found");
1828
+ try {
1829
+ const r = await this.migrateWalletUseCase.execute(e, this.userId);
1830
+ return this.address = r.address, g.log("[CROSSx] migrateWallet 완료 — address:", r.address), r;
1831
+ } catch (r) {
1832
+ throw r instanceof m ? r : new m(
1833
+ p.MIGRATION_FAILED,
1834
+ "Wallet migration failed",
1835
+ r
1836
+ );
1837
+ }
1838
+ }
1839
+ // ============================================================================
1840
+ // 주소 조회
1841
+ // ============================================================================
1842
+ /**
1843
+ * 지갑 주소 조회
1844
+ *
1845
+ * - `index` 생략 시: 로그인 후 로드된 기본 주소를 반환 (`{ address, index: 0 }`)
1846
+ * - `index` 지정 시: 해당 인덱스의 주소를 서버에서 조회하여 반환
1847
+ *
1848
+ * @param index 주소 파생 인덱스 (생략 가능)
1849
+ * @returns `{ address, index }` 또는 주소가 없으면 `null`
1850
+ */
1851
+ async getAddress(e) {
1852
+ if (e !== void 0) {
1853
+ if (this.ensureAuthenticated(), !this.userId)
1854
+ throw new m(p.AUTH_NOT_AUTHENTICATED, "User ID not found");
1855
+ return { address: (await this.walletProvider.getAddress(this.userId, e)).address, index: e };
1856
+ }
1857
+ return !this.authenticated || !this.address ? null : { address: this.address, index: 0 };
1858
+ }
1859
+ /**
1860
+ * 사용자의 지갑 주소 목록 반환
1861
+ * Android SDK의 getAddresses()와 동일합니다.
1862
+ *
1863
+ * @returns `[{ address, index }]` 형식의 배열
1864
+ */
1865
+ async getAddresses() {
1866
+ return this.ensureAuthenticated(), this.address ? [{ address: this.address, index: 0 }] : [];
1867
+ }
1868
+ // ============================================================================
1869
+ // 테마
1870
+ // ============================================================================
1871
+ /**
1872
+ * 컨펌 모달 테마를 런타임에 변경합니다.
1873
+ * 다음 모달이 열릴 때부터 적용됩니다.
1874
+ *
1875
+ * @param themeMode 'light' | 'dark' (생략 시 기존 config.theme 유지)
1876
+ * @param themeTokens 모드별 색상 오버라이드 (생략 시 기존 config.themeTokens 유지)
1877
+ *
1878
+ * @example
1879
+ * sdk.applyTheme('dark');
1880
+ * sdk.applyTheme('dark', { dark: { primary: '#4D9FFF', bg: '#121212' } });
1881
+ */
1882
+ applyTheme(e = this._config.theme ?? "light", r = this._config.themeTokens ?? {}) {
1883
+ this._config = Object.freeze({ ...this._config, theme: e, themeTokens: r }), this.confirmation.setTheme(e, r);
1884
+ }
1885
+ /**
1886
+ * 지갑 생성 (로그인 후 지갑이 없는 경우)
1887
+ * 기존 CROSSx 백업이 발견되면 자동으로 마이그레이션 플로우 실행
1888
+ */
1889
+ async createWallet() {
1890
+ if (this.ensureAuthenticated(), !this.userId)
1891
+ throw new m(p.AUTH_NOT_AUTHENTICATED, "User ID not found");
1892
+ g.log("[CROSSx] 지갑 생성 시작");
1893
+ try {
1894
+ const e = await this.walletProvider.getOrCreateWallet(this.userId);
1895
+ return this.address = e.address, g.log("[CROSSx] 지갑 생성 완료:", e.address), { address: e.address };
1896
+ } catch (e) {
1897
+ if (e instanceof m && e.code === p.MIGRATION_BACKUP_EXISTS) {
1898
+ const r = this.providerSub ?? this.userId;
1899
+ g.log("[CROSSx][Migration Phase 3] createWallet() — Gateway -10012 감지, 마이그레이션 UI 시작 — migrationSub:", r);
1900
+ const t = await this.handleMigrationFlow(r);
1901
+ if (t)
1902
+ return this.address = t.address, { address: t.address };
1903
+ throw new m(
1904
+ p.MIGRATION_FAILED,
1905
+ "Migration skipped by user"
1906
+ );
1907
+ }
1908
+ throw e;
1909
+ }
1910
+ }
1911
+ // ============================================================================
1912
+ // 서명
1913
+ // ============================================================================
1914
+ /**
1915
+ * 메시지 서명
1916
+ * @param chainId CAIP-2 체인 ID (예: 'eip155:612055')
1917
+ * @param message 서명할 메시지
1918
+ * @param opts 서명 옵션 (index, dappName, accountName)
1919
+ * @todo 백엔드 메시지 서명 전용 엔드포인트 추가 후 구현
1920
+ */
1921
+ async signMessage(e, r, t) {
1922
+ if (this.ensureAuthenticated(), !this.userId)
1923
+ throw new m(p.AUTH_NOT_AUTHENTICATED, "User ID not found");
1924
+ const n = t == null ? void 0 : t.index, o = await this.walletProvider.getAddress(this.userId, n ?? 0);
1925
+ let i;
1926
+ if (this.walletProvider.prepare && (i = (await this.walletProvider.prepare("sign-message", { message: r, from: o.address })).uuid), !await this.confirmation.requestConfirmation({
1927
+ type: "sign-message",
1928
+ chainId: e,
1929
+ from: o.address,
1930
+ message: r,
1931
+ dappName: t == null ? void 0 : t.dappName,
1932
+ accountName: t == null ? void 0 : t.accountName
1933
+ }))
1934
+ throw new m(p.USER_REJECTED, "User rejected message signing");
1935
+ try {
1936
+ const c = await this.walletProvider.signMessage(
1937
+ this.userId,
1938
+ e,
1939
+ r,
1940
+ t == null ? void 0 : t.index,
1941
+ i,
1942
+ o.address
1943
+ );
1944
+ return this.verifySignatureSigner(r, c.signature, o.address), {
1945
+ chainId: e,
1946
+ signature: c.signature,
1947
+ message: r,
1948
+ address: o.address
1949
+ };
1950
+ } catch (c) {
1951
+ throw c instanceof m ? c : new m(p.SIGNATURE_FAILED, `Message signing failed (${e})`, c);
1952
+ }
1953
+ }
1954
+ /**
1955
+ * EIP-712 Typed Data 서명 — /mnemonic/sign-typed-data
1956
+ * @param chainId CAIP-2 체인 ID (예: 'eip155:612055')
1957
+ * @param typedData EIP-712 typed structured data (파싱된 객체)
1958
+ * @param opts 서명 옵션 (index, dappName, accountName)
1959
+ */
1960
+ async signTypedData(e, r, t) {
1961
+ if (this.ensureAuthenticated(), !this.userId)
1962
+ throw new m(p.AUTH_NOT_AUTHENTICATED, "User ID not found");
1963
+ if (!this.walletProvider.signTypedData)
1964
+ throw new m(p.NOT_IMPLEMENTED, "signTypedData is not implemented");
1965
+ const n = await this.walletProvider.getAddress(this.userId, (t == null ? void 0 : t.index) ?? 0);
1966
+ let o;
1967
+ if (this.walletProvider.prepare && (o = (await this.walletProvider.prepare("sign-typed-data", { typedData: r, from: n.address })).uuid), !await this.confirmation.requestConfirmation({
1968
+ type: "sign-typed-data",
1969
+ chainId: e,
1970
+ from: n.address,
1971
+ typedData: r,
1972
+ dappName: t == null ? void 0 : t.dappName,
1973
+ accountName: t == null ? void 0 : t.accountName
1974
+ }))
1975
+ throw new m(p.USER_REJECTED, "User rejected typed data signing");
1976
+ try {
1977
+ const a = await this.walletProvider.signTypedData(
1978
+ this.userId,
1979
+ e,
1980
+ r,
1981
+ t == null ? void 0 : t.index,
1982
+ o,
1983
+ n.address
1984
+ );
1985
+ return se.validateSignatureFormat(a.signature), {
1986
+ chainId: e,
1987
+ signature: a.signature,
1988
+ address: n.address
1989
+ };
1990
+ } catch (a) {
1991
+ throw a instanceof m ? a : new m(p.SIGNATURE_FAILED, `Typed data signing failed (${e})`, a);
1992
+ }
1993
+ }
1994
+ // ============================================================================
1995
+ // 트랜잭션
1996
+ // ============================================================================
1997
+ /**
1998
+ * 트랜잭션 서명 (전송 없음) — /mnemonic/sign
1999
+ * @param chainId CAIP-2 체인 ID (예: 'eip155:612055')
2000
+ * @param tx EVM 트랜잭션 요청
2001
+ * @param opts 서명 옵션 (index, dappName, accountName)
2002
+ */
2003
+ async signTransaction(e, r, t) {
2004
+ if (this.ensureAuthenticated(), !this.userId)
2005
+ throw new m(p.AUTH_NOT_AUTHENTICATED, "User ID not found");
2006
+ let n;
2007
+ this.walletProvider.prepare && (n = (await this.walletProvider.prepare("sign", { tx: r })).uuid);
2008
+ const o = this.getNativeCurrency(e);
2009
+ if (!await this.confirmation.requestConfirmation({
2010
+ type: "sign",
2011
+ chainId: e,
2012
+ from: r.from,
2013
+ to: r.to,
2014
+ value: r.value,
2015
+ data: r.data,
2016
+ gasLimit: r.gasLimit,
2017
+ gasPrice: r.gasPrice,
2018
+ maxFeePerGas: r.maxFeePerGas,
2019
+ maxPriorityFeePerGas: r.maxPriorityFeePerGas,
2020
+ nativeSymbol: o.symbol,
2021
+ nativeDecimals: o.decimals,
2022
+ dappName: t == null ? void 0 : t.dappName,
2023
+ accountName: t == null ? void 0 : t.accountName
2024
+ }))
2025
+ throw new m(p.USER_REJECTED, "User rejected transaction signing");
2026
+ try {
2027
+ const a = await this.walletProvider.signTransaction(
2028
+ this.userId,
2029
+ e,
2030
+ r,
2031
+ t == null ? void 0 : t.index,
2032
+ n
2033
+ );
2034
+ return se.validateSignedTxFormat(a.signature), {
2035
+ chainId: e,
2036
+ signedTx: a.signature,
2037
+ txHash: a.txHash ?? ""
2038
+ };
2039
+ } catch (a) {
2040
+ if (a instanceof m) throw a;
2041
+ const c = a instanceof Error ? a.message : String(a);
2042
+ throw new m(
2043
+ p.SIGNATURE_FAILED,
2044
+ `Transaction signing failed (${e}): ${c}`,
2045
+ a
2046
+ );
2047
+ }
2048
+ }
2049
+ /**
2050
+ * 트랜잭션 전송
2051
+ * @param chainId CAIP-2 체인 ID (예: 'eip155:612055')
2052
+ * @param tx EVM 트랜잭션 요청
2053
+ * @param opts 서명 옵션 (index, dappName, accountName)
2054
+ */
2055
+ async sendTransaction(e, r, t) {
2056
+ if (this.ensureAuthenticated(), !this.userId)
2057
+ throw new m(p.AUTH_NOT_AUTHENTICATED, "User ID not found");
2058
+ let n;
2059
+ this.walletProvider.prepare && (n = (await this.walletProvider.prepare("send", { tx: r })).uuid);
2060
+ const o = this.getNativeCurrency(e);
2061
+ if (!await this.confirmation.requestConfirmation({
2062
+ type: "send",
2063
+ chainId: e,
2064
+ from: r.from,
2065
+ to: r.to,
2066
+ value: r.value,
2067
+ data: r.data,
2068
+ gasLimit: r.gasLimit,
2069
+ gasPrice: r.gasPrice,
2070
+ maxFeePerGas: r.maxFeePerGas,
2071
+ maxPriorityFeePerGas: r.maxPriorityFeePerGas,
2072
+ nativeSymbol: o.symbol,
2073
+ nativeDecimals: o.decimals,
2074
+ dappName: t == null ? void 0 : t.dappName,
2075
+ accountName: t == null ? void 0 : t.accountName
2076
+ }))
2077
+ throw new m(p.USER_REJECTED, "User rejected transaction");
2078
+ try {
2079
+ let a;
2080
+ if (this.walletProvider.sendTransaction)
2081
+ a = (await this.walletProvider.sendTransaction(
2082
+ this.userId,
2083
+ e,
2084
+ r,
2085
+ n
2086
+ )).txHash;
2087
+ else {
2088
+ const l = await this.walletProvider.signTransaction(
2089
+ this.userId,
2090
+ e,
2091
+ r,
2092
+ t == null ? void 0 : t.index,
2093
+ n
2094
+ );
2095
+ a = l.txHash ?? l.signature;
2096
+ }
2097
+ const c = se.formatTxAmount(r.value, o.symbol, o.decimals);
2098
+ return this.confirmation.showTransactionComplete({
2099
+ chainId: e,
2100
+ txHash: a,
2101
+ to: r.to,
2102
+ amount: c,
2103
+ nativeSymbol: o.symbol
2104
+ }).catch(() => {
2105
+ }), { chainId: e, txHash: a, status: "pending" };
2106
+ } catch (a) {
2107
+ const c = a instanceof Error ? a.message : String(a);
2108
+ throw new m(
2109
+ p.TRANSACTION_FAILED,
2110
+ `Transaction failed (${e}): ${c}`,
2111
+ a
2112
+ );
2113
+ }
2114
+ }
2115
+ /**
2116
+ * 트랜잭션 Receipt 조회 (eth_getTransactionReceipt)
2117
+ * 아직 채굴되지 않은 경우 null 반환
2118
+ */
2119
+ async getTransactionReceipt(e, r) {
2120
+ if (!this.walletProvider.getTransactionReceipt) return null;
2121
+ try {
2122
+ return await this.walletProvider.getTransactionReceipt(e, r);
2123
+ } catch {
2124
+ return null;
2125
+ }
2126
+ }
2127
+ /**
2128
+ * 트랜잭션이 채굴될 때까지 폴링
2129
+ * @param txHash 트랜잭션 해시
2130
+ * @param chainId CAIP-2 체인 ID
2131
+ * @param opts.intervalMs 폴링 간격 (기본 2000ms)
2132
+ * @param opts.timeoutMs 최대 대기 시간 (기본 60000ms)
2133
+ */
2134
+ async waitForTxAndGetReceipt(e, r, t = {}) {
2135
+ const n = t.intervalMs ?? 1e3, o = 1e4, i = t.timeoutMs ?? 6e4, a = Date.now() + i;
2136
+ let c = n;
2137
+ for (; Date.now() < a; ) {
2138
+ const l = await this.getTransactionReceipt(e, r);
2139
+ if (l) return l;
2140
+ await new Promise((d) => setTimeout(d, c)), c = Math.min(c * 2, o);
2141
+ }
2142
+ throw new m(
2143
+ p.UNKNOWN_ERROR,
2144
+ `Transaction receipt timeout (${e})`
2145
+ );
2146
+ }
2147
+ /**
2148
+ * 트랜잭션 전송 후 Receipt가 확인될 때까지 폴링하여 결과를 반환.
2149
+ *
2150
+ * sendTransaction + waitForTxAndGetReceipt 을 하나로 합친 편의 메서드.
2151
+ * 폴링 주기/타임아웃은 SDKConfig.receiptPolling 값을 사용하며
2152
+ * opts 인자로 개별 호출 시 오버라이드할 수 있습니다.
2153
+ *
2154
+ * @param chainId CAIP-2 체인 ID (예: 'eip155:612044')
2155
+ * @param tx 서명되지 않은 트랜잭션 객체
2156
+ * @param opts 폴링 옵션 오버라이드 (생략 시 config 값 사용)
2157
+ *
2158
+ * @example
2159
+ * const { txHash, receipt } = await sdk.sendTransactionWithWaitForReceipt('eip155:612044', tx);
2160
+ * logger.log(receipt.status); // '0x1' | '0x0'
2161
+ */
2162
+ async sendTransactionWithWaitForReceipt(e, r, t = {}) {
2163
+ var c, l;
2164
+ const { txHash: n } = await this.sendTransaction(e, r), o = t.intervalMs ?? ((c = this._config.receiptPolling) == null ? void 0 : c.intervalMs) ?? 2e3, i = t.timeoutMs ?? ((l = this._config.receiptPolling) == null ? void 0 : l.timeoutMs) ?? 6e4, a = await this.waitForTxAndGetReceipt(n, e, { intervalMs: o, timeoutMs: i });
2165
+ return { chainId: e, txHash: n, receipt: a };
2166
+ }
2167
+ /**
2168
+ * 현재 nonce 조회 (eth_getTransactionCount, pending 기준)
2169
+ * @param chainId CAIP-2 체인 ID (예: 'eip155:612044')
2170
+ */
2171
+ async getNonce(e) {
2172
+ this.ensureAuthenticated();
2173
+ const r = this.address;
2174
+ if (!r) return 0;
2175
+ if (!this.walletProvider.getTransactionCount)
2176
+ throw new m(p.NOT_IMPLEMENTED, "getTransactionCount is not implemented");
2177
+ try {
2178
+ return await this.walletProvider.getTransactionCount(r, e);
2179
+ } catch (t) {
2180
+ const n = t instanceof Error ? t.message : String(t);
2181
+ throw new m(p.UNKNOWN_ERROR, `Failed to get nonce: ${n}`, t);
2182
+ }
2183
+ }
2184
+ /**
2185
+ * 잔액 조회
2186
+ * @param chainId CAIP-2 체인 ID (예: 'eip155:612044')
2187
+ * @returns wei (hex) 및 포맷된 문자열
2188
+ */
2189
+ async getBalance(e) {
2190
+ this.ensureAuthenticated();
2191
+ const r = this.address;
2192
+ if (!r)
2193
+ return { wei: "0x0", formatted: "0", chainId: e };
2194
+ if (!this.walletProvider.getBalance)
2195
+ throw new m(p.NOT_IMPLEMENTED, "getBalance is not implemented");
2196
+ try {
2197
+ const t = await this.walletProvider.getBalance(r, e);
2198
+ return { wei: t, formatted: se.formatWei(t), chainId: e };
2199
+ } catch (t) {
2200
+ const n = t instanceof Error ? t.message : String(t);
2201
+ throw new m(p.UNKNOWN_ERROR, `Failed to get balance (${e}): ${n}`, t);
2202
+ }
2203
+ }
2204
+ static formatWei(e) {
2205
+ if (!e || e === "0x0" || e === "0x") return "0";
2206
+ try {
2207
+ const r = BigInt(e);
2208
+ if (r === 0n) return "0";
2209
+ const t = BigInt("1000000000000000000"), n = r / t, i = (r % t).toString().padStart(18, "0").replace(/0+$/, "").slice(0, 6);
2210
+ return i ? `${n}.${i}` : `${n}`;
2211
+ } catch {
2212
+ return "?";
2213
+ }
2214
+ }
2215
+ // ============================================================================
2216
+ // EIP-1193 Provider
2217
+ // ============================================================================
2218
+ /**
2219
+ * EIP-1193 호환 Ethereum Provider 반환.
2220
+ *
2221
+ * 읽기 전용 RPC (eth_call, eth_getBalance, …) → /wallet/rpc 프록시
2222
+ * 서명·전송 (eth_sendTransaction, eth_signTransaction) → Wallet Gateway
2223
+ *
2224
+ * @param chainId CAIP-2 체인 ID (예: 'eip155:612044')
2225
+ *
2226
+ * @example
2227
+ * const provider = sdk.getProvider('eip155:612044');
2228
+ * // ethers.js
2229
+ * const ethersProvider = new ethers.BrowserProvider(provider);
2230
+ * // viem
2231
+ * const client = createWalletClient({ transport: custom(provider) });
2232
+ */
2233
+ getProvider(e) {
2234
+ return this.ensureAuthenticated(), new fr(this, e);
2235
+ }
2236
+ /**
2237
+ * 범용 JSON-RPC 요청 — /wallet/rpc 프록시.
2238
+ * getProvider() 내부 및 직접 호출 모두 가능.
2239
+ *
2240
+ * @example
2241
+ * const result = await sdk.walletRpc('eth_call', [{ to, data }, 'latest'], 'eip155:612044');
2242
+ */
2243
+ async walletRpc(e, r, t) {
2244
+ if (this.ensureAuthenticated(), !this.walletProvider.rpcRequest)
2245
+ throw new m(p.NOT_IMPLEMENTED, "rpcRequest is not implemented");
2246
+ try {
2247
+ return await this.walletProvider.rpcRequest(e, r, t);
2248
+ } catch (n) {
2249
+ const o = n instanceof Error ? n.message : String(n);
2250
+ throw new m(p.UNKNOWN_ERROR, `rpcRequest failed [${e}] (${t}): ${o}`, n);
2251
+ }
2252
+ }
2253
+ // ============================================================================
2254
+ // 내부 헬퍼
2255
+ // ============================================================================
2256
+ /**
2257
+ * hex wei → "X.XXXX {symbol}" 표시 문자열. value가 0이거나 없으면 null 반환.
2258
+ * Contract call(data만 있고 value=0) 등은 표시하지 않기 위해 null을 반환합니다.
2259
+ */
2260
+ static formatTxAmount(e, r, t) {
2261
+ if (!(!e || e === "0x" || e === "0x0"))
2262
+ try {
2263
+ const n = BigInt(e);
2264
+ if (n === 0n) return;
2265
+ const o = 10n ** BigInt(t), i = n / o, c = (n % o).toString().padStart(t, "0").slice(0, 6).replace(/0+$/, "");
2266
+ return `${c ? `${i}.${c}` : `${i}`} ${r}`;
2267
+ } catch {
2268
+ return;
2269
+ }
2270
+ }
2271
+ /** CAIP-2 chainId (예: 'eip155:612044') → 네이티브 토큰 심볼/소수점 */
2272
+ getNativeCurrency(e) {
2273
+ const r = parseInt(e.split(":")[1] ?? "0", 10);
2274
+ return se.CHAIN_NATIVE_CURRENCY[r] ?? { symbol: "ETH", decimals: 18 };
2275
+ }
2276
+ /**
2277
+ * 마이그레이션 팝업 플로우
2278
+ * 1) "Wallet Found" 팝업 → Recover / Skip
2279
+ * 2) "PIN 입력" 팝업 → 4자리 PIN 입력 (재시도 지원)
2280
+ * 3) migrateWallet API 호출
2281
+ */
2282
+ async handleMigrationFlow(e) {
2283
+ g.log('[CROSSx][Migration Phase 3] "Wallet Found" 팝업 표시');
2284
+ const r = await this.confirmation.showMigrationFoundPrompt();
2285
+ if (g.log("[CROSSx][Migration Phase 3] 사용자 선택:", r), r === "skip")
2286
+ return g.log("[CROSSx][Migration Phase 3] 사용자가 마이그레이션을 건너뜀 → 종료"), null;
2287
+ let t, n = 0;
2288
+ for (; ; ) {
2289
+ n++, g.log(`[CROSSx][Migration Phase 4] PIN 입력 팝업 표시 (시도 #${n})`, t ? `— 이전 에러: ${t}` : "");
2290
+ const o = await this.confirmation.showPinInputPrompt(t);
2291
+ if (o === null)
2292
+ return g.log("[CROSSx][Migration Phase 4] 사용자가 PIN 입력을 취소함 → 종료"), null;
2293
+ g.log(`[CROSSx][Migration Phase 4] PIN 입력 완료 (${o.length}자리), Gateway 마이그레이션 API 호출`);
2294
+ try {
2295
+ const i = await this.migrateWalletUseCase.execute(o, e);
2296
+ return g.log("[CROSSx][Migration Phase 5] 마이그레이션 성공 — address:", i.address), i;
2297
+ } catch (i) {
2298
+ if (i instanceof m && i.code === p.MIGRATION_FAILED) {
2299
+ g.warn(`[CROSSx][Migration Phase 4] PIN 불일치 (시도 #${n}) — 재시도 요청`), t = "Incorrect PIN. Please try again.";
2300
+ continue;
2301
+ }
2302
+ throw g.error("[CROSSx][Migration Phase 4] 마이그레이션 실패 (복구 불가):", i), i;
2303
+ }
2304
+ }
2305
+ }
2306
+ /** ECDSA 서명 형식 검증 (65 bytes = 130 hex chars) */
2307
+ static validateSignatureFormat(e) {
2308
+ const r = e.startsWith("0x") ? e.slice(2) : e;
2309
+ if (!/^[0-9a-fA-F]+$/.test(r))
2310
+ throw new m(p.SIGNATURE_FAILED, "Invalid signature: not a valid hex string");
2311
+ if (r.length !== 130)
2312
+ throw new m(
2313
+ p.SIGNATURE_FAILED,
2314
+ `Invalid signature length: expected 130 hex chars (65 bytes), got ${r.length}`
2315
+ );
2316
+ }
2317
+ /** RLP-encoded signed transaction 형식 검증 */
2318
+ static validateSignedTxFormat(e) {
2319
+ const r = e.startsWith("0x") ? e.slice(2) : e;
2320
+ if (!/^[0-9a-fA-F]+$/.test(r))
2321
+ throw new m(p.SIGNATURE_FAILED, "Invalid signedTx: not a valid hex string");
2322
+ if (r.length < 2)
2323
+ throw new m(p.SIGNATURE_FAILED, "Invalid signedTx: too short");
2324
+ }
2325
+ /**
2326
+ * Gateway 서명 응답의 ecrecover 검증 (XF-036)
2327
+ *
2328
+ * CryptoPort.recoverPersonalSignSigner 가 구현되어 있으면
2329
+ * 복원된 주소와 기대 주소를 비교하여 불일치 시 에러를 throw합니다.
2330
+ */
2331
+ verifySignatureSigner(e, r, t) {
2332
+ if (this.crypto.recoverPersonalSignSigner)
2333
+ try {
2334
+ const n = this.crypto.recoverPersonalSignSigner(e, r);
2335
+ if (n.toLowerCase() !== t.toLowerCase())
2336
+ throw g.error("[CROSSx] 서명 검증 실패: 서명자 주소 불일치", {
2337
+ expected: t,
2338
+ recovered: n
2339
+ }), new m(
2340
+ p.SIGNATURE_SIGNER_MISMATCH,
2341
+ `Signature signer mismatch: expected ${t}, recovered ${n}`
2342
+ );
2343
+ g.log("[CROSSx] 서명 ecrecover 검증 성공");
2344
+ } catch (n) {
2345
+ if (n instanceof m) throw n;
2346
+ g.warn("[CROSSx] ecrecover 검증 중 예외 (무시):", n);
2347
+ }
2348
+ }
2349
+ /** AuthResult를 내부 상태에 반영합니다. */
2350
+ applyAuthResult(e) {
2351
+ var r, t, n, o;
2352
+ this.authenticated = e.success, this.userId = ((r = e.user) == null ? void 0 : r.id) ?? null, this.address = e.address ?? null, this.userEmail = ((t = e.user) == null ? void 0 : t.email) ?? null, this.providerSub = ((n = e.user) == null ? void 0 : n.providerSub) ?? null, this.loginType = se.normalizeLoginType((o = e.user) == null ? void 0 : o.signInProvider), this.tokenSignatureVerified = e.tokenSignatureVerified ?? !1;
2353
+ }
2354
+ /** 인증 상태를 초기화합니다. */
2355
+ clearAuthState() {
2356
+ this.authenticated = !1, this.userId = null, this.address = null, this.userEmail = null, this.providerSub = null, this.loginType = null, this.tokenSignatureVerified = !1;
2357
+ }
2358
+ /**
2359
+ * Firebase sign_in_provider 값을 정규화합니다.
2360
+ * 'google.com' → 'google', 'apple.com' → 'apple'
2361
+ */
2362
+ static normalizeLoginType(e) {
2363
+ return e ? e.includes("google") ? "google" : e.includes("apple") ? "apple" : e : null;
2364
+ }
2365
+ ensureInitialized() {
2366
+ if (!this.initialized)
2367
+ throw new m(
2368
+ p.AUTH_NOT_INITIALIZED,
2369
+ "SDK is not initialized. Call initialize() first."
2370
+ );
2371
+ }
2372
+ ensureAuthenticated() {
2373
+ if (this.ensureInitialized(), !this.authenticated)
2374
+ throw new m(
2375
+ p.AUTH_NOT_AUTHENTICATED,
2376
+ "Not authenticated. Call signIn() first."
2377
+ );
2378
+ }
2379
+ /**
2380
+ * SDK 리소스를 정리합니다.
2381
+ *
2382
+ * 내부 상태 초기화, 커스텀 로거 해제 등을 수행합니다.
2383
+ * dispose 후 SDK 인스턴스는 더 이상 사용할 수 없습니다.
2384
+ */
2385
+ dispose() {
2386
+ this.clearAuthState(), this.initialized = !1, xt(null);
2387
+ }
2388
+ };
2389
+ se.CHAIN_NATIVE_CURRENCY = {
2390
+ 1: { symbol: "ETH", decimals: 18 },
2391
+ // Ethereum Mainnet
2392
+ 5: { symbol: "ETH", decimals: 18 },
2393
+ // Goerli
2394
+ 11155111: { symbol: "ETH", decimals: 18 },
2395
+ // Sepolia
2396
+ 17e3: { symbol: "ETH", decimals: 18 },
2397
+ // Holesky
2398
+ 10: { symbol: "ETH", decimals: 18 },
2399
+ // Optimism
2400
+ 420: { symbol: "ETH", decimals: 18 },
2401
+ // Optimism Goerli
2402
+ 42161: { symbol: "ETH", decimals: 18 },
2403
+ // Arbitrum One
2404
+ 421614: { symbol: "ETH", decimals: 18 },
2405
+ // Arbitrum Sepolia
2406
+ 8453: { symbol: "ETH", decimals: 18 },
2407
+ // Base
2408
+ 84532: { symbol: "ETH", decimals: 18 },
2409
+ // Base Sepolia
2410
+ 137: { symbol: "POL", decimals: 18 },
2411
+ // Polygon
2412
+ 80002: { symbol: "POL", decimals: 18 },
2413
+ // Polygon Amoy
2414
+ 56: { symbol: "BNB", decimals: 18 },
2415
+ // BNB Smart Chain
2416
+ 97: { symbol: "BNB", decimals: 18 },
2417
+ // BNB Testnet
2418
+ 43114: { symbol: "AVAX", decimals: 18 },
2419
+ // Avalanche C-Chain
2420
+ 43113: { symbol: "AVAX", decimals: 18 },
2421
+ // Avalanche Fuji
2422
+ 250: { symbol: "FTM", decimals: 18 },
2423
+ // Fantom Opera
2424
+ 612044: { symbol: "tCROSS", decimals: 18 },
2425
+ // CROSSx Mainnet
2426
+ 612055: { symbol: "CROSS", decimals: 18 }
2427
+ // CROSSx Testnet
2428
+ };
2429
+ let Ye = se;
2430
+ class Kr {
2431
+ constructor() {
2432
+ this.prefix = "crossx_";
2433
+ }
2434
+ async set(e, r) {
2435
+ try {
2436
+ const t = JSON.stringify(r);
2437
+ localStorage.setItem(this.prefix + e, t);
2438
+ } catch (t) {
2439
+ throw g.error("Storage set error:", t), t;
2440
+ }
2441
+ }
2442
+ async get(e) {
2443
+ try {
2444
+ const r = localStorage.getItem(this.prefix + e);
2445
+ return r ? JSON.parse(r) : null;
2446
+ } catch (r) {
2447
+ return g.error("Storage get error:", r), null;
2448
+ }
2449
+ }
2450
+ async remove(e) {
2451
+ try {
2452
+ localStorage.removeItem(this.prefix + e);
2453
+ } catch (r) {
2454
+ throw g.error("Storage remove error:", r), r;
2455
+ }
2456
+ }
2457
+ async clear() {
2458
+ try {
2459
+ Object.keys(localStorage).forEach((r) => {
2460
+ r.startsWith(this.prefix) && localStorage.removeItem(r);
2461
+ });
2462
+ } catch (e) {
2463
+ throw g.error("Storage clear error:", e), e;
2464
+ }
2465
+ }
2466
+ }
2467
+ /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2468
+ function tt(s) {
2469
+ return s instanceof Uint8Array || ArrayBuffer.isView(s) && s.constructor.name === "Uint8Array";
2470
+ }
2471
+ function ie(s, e = "") {
2472
+ if (!Number.isSafeInteger(s) || s < 0) {
2473
+ const r = e && `"${e}" `;
2474
+ throw new Error(`${r}expected integer >= 0, got ${s}`);
2475
+ }
2476
+ }
2477
+ function M(s, e, r = "") {
2478
+ const t = tt(s), n = s == null ? void 0 : s.length, o = e !== void 0;
2479
+ if (!t || o && n !== e) {
2480
+ const i = r && `"${r}" `, a = o ? ` of length ${e}` : "", c = t ? `length=${n}` : `type=${typeof s}`;
2481
+ throw new Error(i + "expected Uint8Array" + a + ", got " + c);
2482
+ }
2483
+ return s;
2484
+ }
2485
+ function Lt(s) {
2486
+ if (typeof s != "function" || typeof s.create != "function")
2487
+ throw new Error("Hash must wrapped by utils.createHasher");
2488
+ ie(s.outputLen), ie(s.blockLen);
2489
+ }
2490
+ function be(s, e = !0) {
2491
+ if (s.destroyed)
2492
+ throw new Error("Hash instance has been destroyed");
2493
+ if (e && s.finished)
2494
+ throw new Error("Hash#digest() has already been called");
2495
+ }
2496
+ function Bt(s, e) {
2497
+ M(s, void 0, "digestInto() output");
2498
+ const r = e.outputLen;
2499
+ if (s.length < r)
2500
+ throw new Error('"digestInto() output" expected to be of length >=' + r);
2501
+ }
2502
+ function jr(s) {
2503
+ return new Uint32Array(s.buffer, s.byteOffset, Math.floor(s.byteLength / 4));
2504
+ }
2505
+ function ve(...s) {
2506
+ for (let e = 0; e < s.length; e++)
2507
+ s[e].fill(0);
2508
+ }
2509
+ function We(s) {
2510
+ return new DataView(s.buffer, s.byteOffset, s.byteLength);
2511
+ }
2512
+ function ee(s, e) {
2513
+ return s << 32 - e | s >>> e;
2514
+ }
2515
+ const Yr = new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68;
2516
+ function Zr(s) {
2517
+ return s << 24 & 4278190080 | s << 8 & 16711680 | s >>> 8 & 65280 | s >>> 24 & 255;
2518
+ }
2519
+ function Xr(s) {
2520
+ for (let e = 0; e < s.length; e++)
2521
+ s[e] = Zr(s[e]);
2522
+ return s;
2523
+ }
2524
+ const _t = Yr ? (s) => s : Xr, $t = /* @ts-ignore */ typeof Uint8Array.from([]).toHex == "function" && typeof Uint8Array.fromHex == "function", Jr = /* @__PURE__ */ Array.from({ length: 256 }, (s, e) => e.toString(16).padStart(2, "0"));
2525
+ function Ae(s) {
2526
+ if (M(s), $t)
2527
+ return s.toHex();
2528
+ let e = "";
2529
+ for (let r = 0; r < s.length; r++)
2530
+ e += Jr[s[r]];
2531
+ return e;
2532
+ }
2533
+ const re = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
2534
+ function mt(s) {
2535
+ if (s >= re._0 && s <= re._9)
2536
+ return s - re._0;
2537
+ if (s >= re.A && s <= re.F)
2538
+ return s - (re.A - 10);
2539
+ if (s >= re.a && s <= re.f)
2540
+ return s - (re.a - 10);
2541
+ }
2542
+ function $e(s) {
2543
+ if (typeof s != "string")
2544
+ throw new Error("hex string expected, got " + typeof s);
2545
+ if ($t)
2546
+ return Uint8Array.fromHex(s);
2547
+ const e = s.length, r = e / 2;
2548
+ if (e % 2)
2549
+ throw new Error("hex string expected, got unpadded hex of length " + e);
2550
+ const t = new Uint8Array(r);
2551
+ for (let n = 0, o = 0; n < r; n++, o += 2) {
2552
+ const i = mt(s.charCodeAt(o)), a = mt(s.charCodeAt(o + 1));
2553
+ if (i === void 0 || a === void 0) {
2554
+ const c = s[o] + s[o + 1];
2555
+ throw new Error('hex string expected, got non-hex character "' + c + '" at index ' + o);
2556
+ }
2557
+ t[n] = i * 16 + a;
2558
+ }
2559
+ return t;
2560
+ }
2561
+ function ue(...s) {
2562
+ let e = 0;
2563
+ for (let t = 0; t < s.length; t++) {
2564
+ const n = s[t];
2565
+ M(n), e += n.length;
2566
+ }
2567
+ const r = new Uint8Array(e);
2568
+ for (let t = 0, n = 0; t < s.length; t++) {
2569
+ const o = s[t];
2570
+ r.set(o, n), n += o.length;
2571
+ }
2572
+ return r;
2573
+ }
2574
+ function Mt(s, e = {}) {
2575
+ const r = (n, o) => s(o).update(n).digest(), t = s(void 0);
2576
+ return r.outputLen = t.outputLen, r.blockLen = t.blockLen, r.create = (n) => s(n), Object.assign(r, e), Object.freeze(r);
2577
+ }
2578
+ function Dt(s = 32) {
2579
+ const e = typeof globalThis == "object" ? globalThis.crypto : null;
2580
+ if (typeof (e == null ? void 0 : e.getRandomValues) != "function")
2581
+ throw new Error("crypto.getRandomValues must be defined");
2582
+ return e.getRandomValues(new Uint8Array(s));
2583
+ }
2584
+ const Qr = (s) => ({
2585
+ oid: Uint8Array.from([6, 9, 96, 134, 72, 1, 101, 3, 4, 2, s])
2586
+ });
2587
+ function es(s, e, r) {
2588
+ return s & e ^ ~s & r;
2589
+ }
2590
+ function ts(s, e, r) {
2591
+ return s & e ^ s & r ^ e & r;
2592
+ }
2593
+ class rs {
2594
+ constructor(e, r, t, n) {
2595
+ w(this, "blockLen");
2596
+ w(this, "outputLen");
2597
+ w(this, "padOffset");
2598
+ w(this, "isLE");
2599
+ // For partial updates less than block size
2600
+ w(this, "buffer");
2601
+ w(this, "view");
2602
+ w(this, "finished", !1);
2603
+ w(this, "length", 0);
2604
+ w(this, "pos", 0);
2605
+ w(this, "destroyed", !1);
2606
+ this.blockLen = e, this.outputLen = r, this.padOffset = t, this.isLE = n, this.buffer = new Uint8Array(e), this.view = We(this.buffer);
2607
+ }
2608
+ update(e) {
2609
+ be(this), M(e);
2610
+ const { view: r, buffer: t, blockLen: n } = this, o = e.length;
2611
+ for (let i = 0; i < o; ) {
2612
+ const a = Math.min(n - this.pos, o - i);
2613
+ if (a === n) {
2614
+ const c = We(e);
2615
+ for (; n <= o - i; i += n)
2616
+ this.process(c, i);
2617
+ continue;
2618
+ }
2619
+ t.set(e.subarray(i, i + a), this.pos), this.pos += a, i += a, this.pos === n && (this.process(r, 0), this.pos = 0);
2620
+ }
2621
+ return this.length += e.length, this.roundClean(), this;
2622
+ }
2623
+ digestInto(e) {
2624
+ be(this), Bt(e, this), this.finished = !0;
2625
+ const { buffer: r, view: t, blockLen: n, isLE: o } = this;
2626
+ let { pos: i } = this;
2627
+ r[i++] = 128, ve(this.buffer.subarray(i)), this.padOffset > n - i && (this.process(t, 0), i = 0);
2628
+ for (let f = i; f < n; f++)
2629
+ r[f] = 0;
2630
+ t.setBigUint64(n - 8, BigInt(this.length * 8), o), this.process(t, 0);
2631
+ const a = We(e), c = this.outputLen;
2632
+ if (c % 4)
2633
+ throw new Error("_sha2: outputLen must be aligned to 32bit");
2634
+ const l = c / 4, d = this.get();
2635
+ if (l > d.length)
2636
+ throw new Error("_sha2: outputLen bigger than state");
2637
+ for (let f = 0; f < l; f++)
2638
+ a.setUint32(4 * f, d[f], o);
2639
+ }
2640
+ digest() {
2641
+ const { buffer: e, outputLen: r } = this;
2642
+ this.digestInto(e);
2643
+ const t = e.slice(0, r);
2644
+ return this.destroy(), t;
2645
+ }
2646
+ _cloneInto(e) {
2647
+ e || (e = new this.constructor()), e.set(...this.get());
2648
+ const { blockLen: r, buffer: t, length: n, finished: o, destroyed: i, pos: a } = this;
2649
+ return e.destroyed = i, e.finished = o, e.length = n, e.pos = a, n % r && e.buffer.set(t), e;
2650
+ }
2651
+ clone() {
2652
+ return this._cloneInto();
2653
+ }
2654
+ }
2655
+ const ce = /* @__PURE__ */ Uint32Array.from([
2656
+ 1779033703,
2657
+ 3144134277,
2658
+ 1013904242,
2659
+ 2773480762,
2660
+ 1359893119,
2661
+ 2600822924,
2662
+ 528734635,
2663
+ 1541459225
2664
+ ]), ke = /* @__PURE__ */ BigInt(2 ** 32 - 1), wt = /* @__PURE__ */ BigInt(32);
2665
+ function ss(s, e = !1) {
2666
+ return e ? { h: Number(s & ke), l: Number(s >> wt & ke) } : { h: Number(s >> wt & ke) | 0, l: Number(s & ke) | 0 };
2667
+ }
2668
+ function ns(s, e = !1) {
2669
+ const r = s.length;
2670
+ let t = new Uint32Array(r), n = new Uint32Array(r);
2671
+ for (let o = 0; o < r; o++) {
2672
+ const { h: i, l: a } = ss(s[o], e);
2673
+ [t[o], n[o]] = [i, a];
2674
+ }
2675
+ return [t, n];
2676
+ }
2677
+ const os = (s, e, r) => s << r | e >>> 32 - r, is = (s, e, r) => e << r | s >>> 32 - r, as = (s, e, r) => e << r - 32 | s >>> 64 - r, cs = (s, e, r) => s << r - 32 | e >>> 64 - r, ls = /* @__PURE__ */ Uint32Array.from([
2678
+ 1116352408,
2679
+ 1899447441,
2680
+ 3049323471,
2681
+ 3921009573,
2682
+ 961987163,
2683
+ 1508970993,
2684
+ 2453635748,
2685
+ 2870763221,
2686
+ 3624381080,
2687
+ 310598401,
2688
+ 607225278,
2689
+ 1426881987,
2690
+ 1925078388,
2691
+ 2162078206,
2692
+ 2614888103,
2693
+ 3248222580,
2694
+ 3835390401,
2695
+ 4022224774,
2696
+ 264347078,
2697
+ 604807628,
2698
+ 770255983,
2699
+ 1249150122,
2700
+ 1555081692,
2701
+ 1996064986,
2702
+ 2554220882,
2703
+ 2821834349,
2704
+ 2952996808,
2705
+ 3210313671,
2706
+ 3336571891,
2707
+ 3584528711,
2708
+ 113926993,
2709
+ 338241895,
2710
+ 666307205,
2711
+ 773529912,
2712
+ 1294757372,
2713
+ 1396182291,
2714
+ 1695183700,
2715
+ 1986661051,
2716
+ 2177026350,
2717
+ 2456956037,
2718
+ 2730485921,
2719
+ 2820302411,
2720
+ 3259730800,
2721
+ 3345764771,
2722
+ 3516065817,
2723
+ 3600352804,
2724
+ 4094571909,
2725
+ 275423344,
2726
+ 430227734,
2727
+ 506948616,
2728
+ 659060556,
2729
+ 883997877,
2730
+ 958139571,
2731
+ 1322822218,
2732
+ 1537002063,
2733
+ 1747873779,
2734
+ 1955562222,
2735
+ 2024104815,
2736
+ 2227730452,
2737
+ 2361852424,
2738
+ 2428436474,
2739
+ 2756734187,
2740
+ 3204031479,
2741
+ 3329325298
2742
+ ]), le = /* @__PURE__ */ new Uint32Array(64);
2743
+ class ds extends rs {
2744
+ constructor(e) {
2745
+ super(64, e, 8, !1);
2746
+ }
2747
+ get() {
2748
+ const { A: e, B: r, C: t, D: n, E: o, F: i, G: a, H: c } = this;
2749
+ return [e, r, t, n, o, i, a, c];
2750
+ }
2751
+ // prettier-ignore
2752
+ set(e, r, t, n, o, i, a, c) {
2753
+ this.A = e | 0, this.B = r | 0, this.C = t | 0, this.D = n | 0, this.E = o | 0, this.F = i | 0, this.G = a | 0, this.H = c | 0;
2754
+ }
2755
+ process(e, r) {
2756
+ for (let f = 0; f < 16; f++, r += 4)
2757
+ le[f] = e.getUint32(r, !1);
2758
+ for (let f = 16; f < 64; f++) {
2759
+ const y = le[f - 15], _ = le[f - 2], E = ee(y, 7) ^ ee(y, 18) ^ y >>> 3, O = ee(_, 17) ^ ee(_, 19) ^ _ >>> 10;
2760
+ le[f] = O + le[f - 7] + E + le[f - 16] | 0;
2761
+ }
2762
+ let { A: t, B: n, C: o, D: i, E: a, F: c, G: l, H: d } = this;
2763
+ for (let f = 0; f < 64; f++) {
2764
+ const y = ee(a, 6) ^ ee(a, 11) ^ ee(a, 25), _ = d + y + es(a, c, l) + ls[f] + le[f] | 0, O = (ee(t, 2) ^ ee(t, 13) ^ ee(t, 22)) + ts(t, n, o) | 0;
2765
+ d = l, l = c, c = a, a = i + _ | 0, i = o, o = n, n = t, t = _ + O | 0;
2766
+ }
2767
+ t = t + this.A | 0, n = n + this.B | 0, o = o + this.C | 0, i = i + this.D | 0, a = a + this.E | 0, c = c + this.F | 0, l = l + this.G | 0, d = d + this.H | 0, this.set(t, n, o, i, a, c, l, d);
2768
+ }
2769
+ roundClean() {
2770
+ ve(le);
2771
+ }
2772
+ destroy() {
2773
+ this.set(0, 0, 0, 0, 0, 0, 0, 0), ve(this.buffer);
2774
+ }
2775
+ }
2776
+ class us extends ds {
2777
+ constructor() {
2778
+ super(32);
2779
+ // We cannot use array here since array allows indexing by variable
2780
+ // which means optimizer/compiler cannot use registers.
2781
+ w(this, "A", ce[0] | 0);
2782
+ w(this, "B", ce[1] | 0);
2783
+ w(this, "C", ce[2] | 0);
2784
+ w(this, "D", ce[3] | 0);
2785
+ w(this, "E", ce[4] | 0);
2786
+ w(this, "F", ce[5] | 0);
2787
+ w(this, "G", ce[6] | 0);
2788
+ w(this, "H", ce[7] | 0);
2789
+ }
2790
+ }
2791
+ const hs = /* @__PURE__ */ Mt(
2792
+ () => new us(),
2793
+ /* @__PURE__ */ Qr(1)
2794
+ );
2795
+ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2796
+ const rt = /* @__PURE__ */ BigInt(0), Ze = /* @__PURE__ */ BigInt(1);
2797
+ function Me(s, e = "") {
2798
+ if (typeof s != "boolean") {
2799
+ const r = e && `"${e}" `;
2800
+ throw new Error(r + "expected boolean, got type=" + typeof s);
2801
+ }
2802
+ return s;
2803
+ }
2804
+ function Ut(s) {
2805
+ if (typeof s == "bigint") {
2806
+ if (!Be(s))
2807
+ throw new Error("positive bigint expected, got " + s);
2808
+ } else
2809
+ ie(s);
2810
+ return s;
2811
+ }
2812
+ function Ce(s) {
2813
+ const e = Ut(s).toString(16);
2814
+ return e.length & 1 ? "0" + e : e;
2815
+ }
2816
+ function Ht(s) {
2817
+ if (typeof s != "string")
2818
+ throw new Error("hex string expected, got " + typeof s);
2819
+ return s === "" ? rt : BigInt("0x" + s);
2820
+ }
2821
+ function Fe(s) {
2822
+ return Ht(Ae(s));
2823
+ }
2824
+ function Ft(s) {
2825
+ return Ht(Ae(fs(M(s)).reverse()));
2826
+ }
2827
+ function st(s, e) {
2828
+ ie(e), s = Ut(s);
2829
+ const r = $e(s.toString(16).padStart(e * 2, "0"));
2830
+ if (r.length !== e)
2831
+ throw new Error("number too large");
2832
+ return r;
2833
+ }
2834
+ function qt(s, e) {
2835
+ return st(s, e).reverse();
2836
+ }
2837
+ function fs(s) {
2838
+ return Uint8Array.from(s);
2839
+ }
2840
+ const Be = (s) => typeof s == "bigint" && rt <= s;
2841
+ function gs(s, e, r) {
2842
+ return Be(s) && Be(e) && Be(r) && e <= s && s < r;
2843
+ }
2844
+ function ps(s, e, r, t) {
2845
+ if (!gs(e, r, t))
2846
+ throw new Error("expected valid " + s + ": " + r + " <= n < " + t + ", got " + e);
2847
+ }
2848
+ function xs(s) {
2849
+ let e;
2850
+ for (e = 0; s > rt; s >>= Ze, e += 1)
2851
+ ;
2852
+ return e;
2853
+ }
2854
+ const nt = (s) => (Ze << BigInt(s)) - Ze;
2855
+ function _s(s, e, r) {
2856
+ if (ie(s, "hashLen"), ie(e, "qByteLen"), typeof r != "function")
2857
+ throw new Error("hmacFn must be a function");
2858
+ const t = (S) => new Uint8Array(S), n = Uint8Array.of(), o = Uint8Array.of(0), i = Uint8Array.of(1), a = 1e3;
2859
+ let c = t(s), l = t(s), d = 0;
2860
+ const f = () => {
2861
+ c.fill(1), l.fill(0), d = 0;
2862
+ }, y = (...S) => r(l, ue(c, ...S)), _ = (S = n) => {
2863
+ l = y(o, S), c = y(), S.length !== 0 && (l = y(i, S), c = y());
2864
+ }, E = () => {
2865
+ if (d++ >= a)
2866
+ throw new Error("drbg: tried max amount of iterations");
2867
+ let S = 0;
2868
+ const C = [];
2869
+ for (; S < e; ) {
2870
+ c = y();
2871
+ const U = c.slice();
2872
+ C.push(U), S += c.length;
2873
+ }
2874
+ return ue(...C);
2875
+ };
2876
+ return (S, C) => {
2877
+ f(), _(S);
2878
+ let U;
2879
+ for (; !(U = C(E())); )
2880
+ _();
2881
+ return f(), U;
2882
+ };
2883
+ }
2884
+ function ot(s, e = {}, r = {}) {
2885
+ if (!s || typeof s != "object")
2886
+ throw new Error("expected valid options object");
2887
+ function t(o, i, a) {
2888
+ const c = s[o];
2889
+ if (a && c === void 0)
2890
+ return;
2891
+ const l = typeof c;
2892
+ if (l !== i || c === null)
2893
+ throw new Error(`param "${o}" is invalid: expected ${i}, got ${l}`);
2894
+ }
2895
+ const n = (o, i) => Object.entries(o).forEach(([a, c]) => t(a, c, i));
2896
+ n(e, !1), n(r, !0);
2897
+ }
2898
+ function yt(s) {
2899
+ const e = /* @__PURE__ */ new WeakMap();
2900
+ return (r, ...t) => {
2901
+ const n = e.get(r);
2902
+ if (n !== void 0)
2903
+ return n;
2904
+ const o = s(r, ...t);
2905
+ return e.set(r, o), o;
2906
+ };
2907
+ }
2908
+ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2909
+ const Y = /* @__PURE__ */ BigInt(0), z = /* @__PURE__ */ BigInt(1), _e = /* @__PURE__ */ BigInt(2), Gt = /* @__PURE__ */ BigInt(3), Wt = /* @__PURE__ */ BigInt(4), Vt = /* @__PURE__ */ BigInt(5), ms = /* @__PURE__ */ BigInt(7), zt = /* @__PURE__ */ BigInt(8), ws = /* @__PURE__ */ BigInt(9), Kt = /* @__PURE__ */ BigInt(16);
2910
+ function Q(s, e) {
2911
+ const r = s % e;
2912
+ return r >= Y ? r : e + r;
2913
+ }
2914
+ function J(s, e, r) {
2915
+ let t = s;
2916
+ for (; e-- > Y; )
2917
+ t *= t, t %= r;
2918
+ return t;
2919
+ }
2920
+ function bt(s, e) {
2921
+ if (s === Y)
2922
+ throw new Error("invert: expected non-zero number");
2923
+ if (e <= Y)
2924
+ throw new Error("invert: expected positive modulus, got " + e);
2925
+ let r = Q(s, e), t = e, n = Y, o = z;
2926
+ for (; r !== Y; ) {
2927
+ const a = t / r, c = t % r, l = n - o * a;
2928
+ t = r, r = c, n = o, o = l;
2929
+ }
2930
+ if (t !== z)
2931
+ throw new Error("invert: does not exist");
2932
+ return Q(n, e);
2933
+ }
2934
+ function it(s, e, r) {
2935
+ if (!s.eql(s.sqr(e), r))
2936
+ throw new Error("Cannot find square root");
2937
+ }
2938
+ function jt(s, e) {
2939
+ const r = (s.ORDER + z) / Wt, t = s.pow(e, r);
2940
+ return it(s, t, e), t;
2941
+ }
2942
+ function ys(s, e) {
2943
+ const r = (s.ORDER - Vt) / zt, t = s.mul(e, _e), n = s.pow(t, r), o = s.mul(e, n), i = s.mul(s.mul(o, _e), n), a = s.mul(o, s.sub(i, s.ONE));
2944
+ return it(s, a, e), a;
2945
+ }
2946
+ function bs(s) {
2947
+ const e = qe(s), r = Yt(s), t = r(e, e.neg(e.ONE)), n = r(e, t), o = r(e, e.neg(t)), i = (s + ms) / Kt;
2948
+ return (a, c) => {
2949
+ let l = a.pow(c, i), d = a.mul(l, t);
2950
+ const f = a.mul(l, n), y = a.mul(l, o), _ = a.eql(a.sqr(d), c), E = a.eql(a.sqr(f), c);
2951
+ l = a.cmov(l, d, _), d = a.cmov(y, f, E);
2952
+ const O = a.eql(a.sqr(d), c), S = a.cmov(l, d, O);
2953
+ return it(a, S, c), S;
2954
+ };
2955
+ }
2956
+ function Yt(s) {
2957
+ if (s < Gt)
2958
+ throw new Error("sqrt is not defined for small field");
2959
+ let e = s - z, r = 0;
2960
+ for (; e % _e === Y; )
2961
+ e /= _e, r++;
2962
+ let t = _e;
2963
+ const n = qe(s);
2964
+ for (; vt(n, t) === 1; )
2965
+ if (t++ > 1e3)
2966
+ throw new Error("Cannot find square root: probably non-prime P");
2967
+ if (r === 1)
2968
+ return jt;
2969
+ let o = n.pow(t, e);
2970
+ const i = (e + z) / _e;
2971
+ return function(c, l) {
2972
+ if (c.is0(l))
2973
+ return l;
2974
+ if (vt(c, l) !== 1)
2975
+ throw new Error("Cannot find square root");
2976
+ let d = r, f = c.mul(c.ONE, o), y = c.pow(l, e), _ = c.pow(l, i);
2977
+ for (; !c.eql(y, c.ONE); ) {
2978
+ if (c.is0(y))
2979
+ return c.ZERO;
2980
+ let E = 1, O = c.sqr(y);
2981
+ for (; !c.eql(O, c.ONE); )
2982
+ if (E++, O = c.sqr(O), E === d)
2983
+ throw new Error("Cannot find square root");
2984
+ const S = z << BigInt(d - E - 1), C = c.pow(f, S);
2985
+ d = E, f = c.sqr(C), y = c.mul(y, f), _ = c.mul(_, C);
2986
+ }
2987
+ return _;
2988
+ };
2989
+ }
2990
+ function vs(s) {
2991
+ return s % Wt === Gt ? jt : s % zt === Vt ? ys : s % Kt === ws ? bs(s) : Yt(s);
2992
+ }
2993
+ const Es = [
2994
+ "create",
2995
+ "isValid",
2996
+ "is0",
2997
+ "neg",
2998
+ "inv",
2999
+ "sqrt",
3000
+ "sqr",
3001
+ "eql",
3002
+ "add",
3003
+ "sub",
3004
+ "mul",
3005
+ "pow",
3006
+ "div",
3007
+ "addN",
3008
+ "subN",
3009
+ "mulN",
3010
+ "sqrN"
3011
+ ];
3012
+ function Ss(s) {
3013
+ const e = {
3014
+ ORDER: "bigint",
3015
+ BYTES: "number",
3016
+ BITS: "number"
3017
+ }, r = Es.reduce((t, n) => (t[n] = "function", t), e);
3018
+ return ot(s, r), s;
3019
+ }
3020
+ function Ts(s, e, r) {
3021
+ if (r < Y)
3022
+ throw new Error("invalid exponent, negatives unsupported");
3023
+ if (r === Y)
3024
+ return s.ONE;
3025
+ if (r === z)
3026
+ return e;
3027
+ let t = s.ONE, n = e;
3028
+ for (; r > Y; )
3029
+ r & z && (t = s.mul(t, n)), n = s.sqr(n), r >>= z;
3030
+ return t;
3031
+ }
3032
+ function Zt(s, e, r = !1) {
3033
+ const t = new Array(e.length).fill(r ? s.ZERO : void 0), n = e.reduce((i, a, c) => s.is0(a) ? i : (t[c] = i, s.mul(i, a)), s.ONE), o = s.inv(n);
3034
+ return e.reduceRight((i, a, c) => s.is0(a) ? i : (t[c] = s.mul(i, t[c]), s.mul(i, a)), o), t;
3035
+ }
3036
+ function vt(s, e) {
3037
+ const r = (s.ORDER - z) / _e, t = s.pow(e, r), n = s.eql(t, s.ONE), o = s.eql(t, s.ZERO), i = s.eql(t, s.neg(s.ONE));
3038
+ if (!n && !o && !i)
3039
+ throw new Error("invalid Legendre symbol result");
3040
+ return n ? 1 : o ? 0 : -1;
3041
+ }
3042
+ function Is(s, e) {
3043
+ e !== void 0 && ie(e);
3044
+ const r = e !== void 0 ? e : s.toString(2).length, t = Math.ceil(r / 8);
3045
+ return { nBitLength: r, nByteLength: t };
3046
+ }
3047
+ class As {
3048
+ constructor(e, r = {}) {
3049
+ w(this, "ORDER");
3050
+ w(this, "BITS");
3051
+ w(this, "BYTES");
3052
+ w(this, "isLE");
3053
+ w(this, "ZERO", Y);
3054
+ w(this, "ONE", z);
3055
+ w(this, "_lengths");
3056
+ w(this, "_sqrt");
3057
+ // cached sqrt
3058
+ w(this, "_mod");
3059
+ var i;
3060
+ if (e <= Y)
3061
+ throw new Error("invalid field: expected ORDER > 0, got " + e);
3062
+ let t;
3063
+ this.isLE = !1, r != null && typeof r == "object" && (typeof r.BITS == "number" && (t = r.BITS), typeof r.sqrt == "function" && (this.sqrt = r.sqrt), typeof r.isLE == "boolean" && (this.isLE = r.isLE), r.allowedLengths && (this._lengths = (i = r.allowedLengths) == null ? void 0 : i.slice()), typeof r.modFromBytes == "boolean" && (this._mod = r.modFromBytes));
3064
+ const { nBitLength: n, nByteLength: o } = Is(e, t);
3065
+ if (o > 2048)
3066
+ throw new Error("invalid field: expected ORDER of <= 2048 bytes");
3067
+ this.ORDER = e, this.BITS = n, this.BYTES = o, this._sqrt = void 0, Object.preventExtensions(this);
3068
+ }
3069
+ create(e) {
3070
+ return Q(e, this.ORDER);
3071
+ }
3072
+ isValid(e) {
3073
+ if (typeof e != "bigint")
3074
+ throw new Error("invalid field element: expected bigint, got " + typeof e);
3075
+ return Y <= e && e < this.ORDER;
3076
+ }
3077
+ is0(e) {
3078
+ return e === Y;
3079
+ }
3080
+ // is valid and invertible
3081
+ isValidNot0(e) {
3082
+ return !this.is0(e) && this.isValid(e);
3083
+ }
3084
+ isOdd(e) {
3085
+ return (e & z) === z;
3086
+ }
3087
+ neg(e) {
3088
+ return Q(-e, this.ORDER);
3089
+ }
3090
+ eql(e, r) {
3091
+ return e === r;
3092
+ }
3093
+ sqr(e) {
3094
+ return Q(e * e, this.ORDER);
3095
+ }
3096
+ add(e, r) {
3097
+ return Q(e + r, this.ORDER);
3098
+ }
3099
+ sub(e, r) {
3100
+ return Q(e - r, this.ORDER);
3101
+ }
3102
+ mul(e, r) {
3103
+ return Q(e * r, this.ORDER);
3104
+ }
3105
+ pow(e, r) {
3106
+ return Ts(this, e, r);
3107
+ }
3108
+ div(e, r) {
3109
+ return Q(e * bt(r, this.ORDER), this.ORDER);
3110
+ }
3111
+ // Same as above, but doesn't normalize
3112
+ sqrN(e) {
3113
+ return e * e;
3114
+ }
3115
+ addN(e, r) {
3116
+ return e + r;
3117
+ }
3118
+ subN(e, r) {
3119
+ return e - r;
3120
+ }
3121
+ mulN(e, r) {
3122
+ return e * r;
3123
+ }
3124
+ inv(e) {
3125
+ return bt(e, this.ORDER);
3126
+ }
3127
+ sqrt(e) {
3128
+ return this._sqrt || (this._sqrt = vs(this.ORDER)), this._sqrt(this, e);
3129
+ }
3130
+ toBytes(e) {
3131
+ return this.isLE ? qt(e, this.BYTES) : st(e, this.BYTES);
3132
+ }
3133
+ fromBytes(e, r = !1) {
3134
+ M(e);
3135
+ const { _lengths: t, BYTES: n, isLE: o, ORDER: i, _mod: a } = this;
3136
+ if (t) {
3137
+ if (!t.includes(e.length) || e.length > n)
3138
+ throw new Error("Field.fromBytes: expected " + t + " bytes, got " + e.length);
3139
+ const l = new Uint8Array(n);
3140
+ l.set(e, o ? 0 : l.length - e.length), e = l;
3141
+ }
3142
+ if (e.length !== n)
3143
+ throw new Error("Field.fromBytes: expected " + n + " bytes, got " + e.length);
3144
+ let c = o ? Ft(e) : Fe(e);
3145
+ if (a && (c = Q(c, i)), !r && !this.isValid(c))
3146
+ throw new Error("invalid field element: outside of range 0..ORDER");
3147
+ return c;
3148
+ }
3149
+ // TODO: we don't need it here, move out to separate fn
3150
+ invertBatch(e) {
3151
+ return Zt(this, e);
3152
+ }
3153
+ // We can't move this out because Fp6, Fp12 implement it
3154
+ // and it's unclear what to return in there.
3155
+ cmov(e, r, t) {
3156
+ return t ? r : e;
3157
+ }
3158
+ }
3159
+ function qe(s, e = {}) {
3160
+ return new As(s, e);
3161
+ }
3162
+ function Xt(s) {
3163
+ if (typeof s != "bigint")
3164
+ throw new Error("field order must be bigint");
3165
+ const e = s.toString(2).length;
3166
+ return Math.ceil(e / 8);
3167
+ }
3168
+ function Jt(s) {
3169
+ const e = Xt(s);
3170
+ return e + Math.ceil(e / 2);
3171
+ }
3172
+ function Rs(s, e, r = !1) {
3173
+ M(s);
3174
+ const t = s.length, n = Xt(e), o = Jt(e);
3175
+ if (t < 16 || t < o || t > 1024)
3176
+ throw new Error("expected " + o + "-1024 bytes of input, got " + t);
3177
+ const i = r ? Ft(s) : Fe(s), a = Q(i, e - z) + z;
3178
+ return r ? qt(a, n) : st(a, n);
3179
+ }
3180
+ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
3181
+ const Ee = /* @__PURE__ */ BigInt(0), me = /* @__PURE__ */ BigInt(1);
3182
+ function De(s, e) {
3183
+ const r = e.negate();
3184
+ return s ? r : e;
3185
+ }
3186
+ function Et(s, e) {
3187
+ const r = Zt(s.Fp, e.map((t) => t.Z));
3188
+ return e.map((t, n) => s.fromAffine(t.toAffine(r[n])));
3189
+ }
3190
+ function Qt(s, e) {
3191
+ if (!Number.isSafeInteger(s) || s <= 0 || s > e)
3192
+ throw new Error("invalid window size, expected [1.." + e + "], got W=" + s);
3193
+ }
3194
+ function Ve(s, e) {
3195
+ Qt(s, e);
3196
+ const r = Math.ceil(e / s) + 1, t = 2 ** (s - 1), n = 2 ** s, o = nt(s), i = BigInt(s);
3197
+ return { windows: r, windowSize: t, mask: o, maxNumber: n, shiftBy: i };
3198
+ }
3199
+ function St(s, e, r) {
3200
+ const { windowSize: t, mask: n, maxNumber: o, shiftBy: i } = r;
3201
+ let a = Number(s & n), c = s >> i;
3202
+ a > t && (a -= o, c += me);
3203
+ const l = e * t, d = l + Math.abs(a) - 1, f = a === 0, y = a < 0, _ = e % 2 !== 0;
3204
+ return { nextN: c, offset: d, isZero: f, isNeg: y, isNegF: _, offsetF: l };
3205
+ }
3206
+ const ze = /* @__PURE__ */ new WeakMap(), er = /* @__PURE__ */ new WeakMap();
3207
+ function Ke(s) {
3208
+ return er.get(s) || 1;
3209
+ }
3210
+ function Tt(s) {
3211
+ if (s !== Ee)
3212
+ throw new Error("invalid wNAF");
3213
+ }
3214
+ class Os {
3215
+ // Parametrized with a given Point class (not individual point)
3216
+ constructor(e, r) {
3217
+ w(this, "BASE");
3218
+ w(this, "ZERO");
3219
+ w(this, "Fn");
3220
+ w(this, "bits");
3221
+ this.BASE = e.BASE, this.ZERO = e.ZERO, this.Fn = e.Fn, this.bits = r;
3222
+ }
3223
+ // non-const time multiplication ladder
3224
+ _unsafeLadder(e, r, t = this.ZERO) {
3225
+ let n = e;
3226
+ for (; r > Ee; )
3227
+ r & me && (t = t.add(n)), n = n.double(), r >>= me;
3228
+ return t;
3229
+ }
3230
+ /**
3231
+ * Creates a wNAF precomputation window. Used for caching.
3232
+ * Default window size is set by `utils.precompute()` and is equal to 8.
3233
+ * Number of precomputed points depends on the curve size:
3234
+ * 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:
3235
+ * - 𝑊 is the window size
3236
+ * - 𝑛 is the bitlength of the curve order.
3237
+ * For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
3238
+ * @param point Point instance
3239
+ * @param W window size
3240
+ * @returns precomputed point tables flattened to a single array
3241
+ */
3242
+ precomputeWindow(e, r) {
3243
+ const { windows: t, windowSize: n } = Ve(r, this.bits), o = [];
3244
+ let i = e, a = i;
3245
+ for (let c = 0; c < t; c++) {
3246
+ a = i, o.push(a);
3247
+ for (let l = 1; l < n; l++)
3248
+ a = a.add(i), o.push(a);
3249
+ i = a.double();
3250
+ }
3251
+ return o;
3252
+ }
3253
+ /**
3254
+ * Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
3255
+ * More compact implementation:
3256
+ * https://github.com/paulmillr/noble-secp256k1/blob/47cb1669b6e506ad66b35fe7d76132ae97465da2/index.ts#L502-L541
3257
+ * @returns real and fake (for const-time) points
3258
+ */
3259
+ wNAF(e, r, t) {
3260
+ if (!this.Fn.isValid(t))
3261
+ throw new Error("invalid scalar");
3262
+ let n = this.ZERO, o = this.BASE;
3263
+ const i = Ve(e, this.bits);
3264
+ for (let a = 0; a < i.windows; a++) {
3265
+ const { nextN: c, offset: l, isZero: d, isNeg: f, isNegF: y, offsetF: _ } = St(t, a, i);
3266
+ t = c, d ? o = o.add(De(y, r[_])) : n = n.add(De(f, r[l]));
3267
+ }
3268
+ return Tt(t), { p: n, f: o };
3269
+ }
3270
+ /**
3271
+ * Implements ec unsafe (non const-time) multiplication using precomputed tables and w-ary non-adjacent form.
3272
+ * @param acc accumulator point to add result of multiplication
3273
+ * @returns point
3274
+ */
3275
+ wNAFUnsafe(e, r, t, n = this.ZERO) {
3276
+ const o = Ve(e, this.bits);
3277
+ for (let i = 0; i < o.windows && t !== Ee; i++) {
3278
+ const { nextN: a, offset: c, isZero: l, isNeg: d } = St(t, i, o);
3279
+ if (t = a, !l) {
3280
+ const f = r[c];
3281
+ n = n.add(d ? f.negate() : f);
3282
+ }
3283
+ }
3284
+ return Tt(t), n;
3285
+ }
3286
+ getPrecomputes(e, r, t) {
3287
+ let n = ze.get(r);
3288
+ return n || (n = this.precomputeWindow(r, e), e !== 1 && (typeof t == "function" && (n = t(n)), ze.set(r, n))), n;
3289
+ }
3290
+ cached(e, r, t) {
3291
+ const n = Ke(e);
3292
+ return this.wNAF(n, this.getPrecomputes(n, e, t), r);
3293
+ }
3294
+ unsafe(e, r, t, n) {
3295
+ const o = Ke(e);
3296
+ return o === 1 ? this._unsafeLadder(e, r, n) : this.wNAFUnsafe(o, this.getPrecomputes(o, e, t), r, n);
3297
+ }
3298
+ // We calculate precomputes for elliptic curve point multiplication
3299
+ // using windowed method. This specifies window size and
3300
+ // stores precomputed values. Usually only base point would be precomputed.
3301
+ createCache(e, r) {
3302
+ Qt(r, this.bits), er.set(e, r), ze.delete(e);
3303
+ }
3304
+ hasCache(e) {
3305
+ return Ke(e) !== 1;
3306
+ }
3307
+ }
3308
+ function Ns(s, e, r, t) {
3309
+ let n = e, o = s.ZERO, i = s.ZERO;
3310
+ for (; r > Ee || t > Ee; )
3311
+ r & me && (o = o.add(n)), t & me && (i = i.add(n)), n = n.double(), r >>= me, t >>= me;
3312
+ return { p1: o, p2: i };
3313
+ }
3314
+ function It(s, e, r) {
3315
+ if (e) {
3316
+ if (e.ORDER !== s)
3317
+ throw new Error("Field.ORDER must match order: Fp == p, Fn == n");
3318
+ return Ss(e), e;
3319
+ } else
3320
+ return qe(s, { isLE: r });
3321
+ }
3322
+ function ks(s, e, r = {}, t) {
3323
+ if (t === void 0 && (t = s === "edwards"), !e || typeof e != "object")
3324
+ throw new Error(`expected valid ${s} CURVE object`);
3325
+ for (const c of ["p", "n", "h"]) {
3326
+ const l = e[c];
3327
+ if (!(typeof l == "bigint" && l > Ee))
3328
+ throw new Error(`CURVE.${c} must be positive bigint`);
3329
+ }
3330
+ const n = It(e.p, r.Fp, t), o = It(e.n, r.Fn, t), a = ["Gx", "Gy", "a", "b"];
3331
+ for (const c of a)
3332
+ if (!n.isValid(e[c]))
3333
+ throw new Error(`CURVE.${c} must be valid field element of CURVE.Fp`);
3334
+ return e = Object.freeze(Object.assign({}, e)), { CURVE: e, Fp: n, Fn: o };
3335
+ }
3336
+ function Cs(s, e) {
3337
+ return function(t) {
3338
+ const n = s(t);
3339
+ return { secretKey: n, publicKey: e(n) };
3340
+ };
3341
+ }
3342
+ class tr {
3343
+ constructor(e, r) {
3344
+ w(this, "oHash");
3345
+ w(this, "iHash");
3346
+ w(this, "blockLen");
3347
+ w(this, "outputLen");
3348
+ w(this, "finished", !1);
3349
+ w(this, "destroyed", !1);
3350
+ if (Lt(e), M(r, void 0, "key"), this.iHash = e.create(), typeof this.iHash.update != "function")
3351
+ throw new Error("Expected instance of class which extends utils.Hash");
3352
+ this.blockLen = this.iHash.blockLen, this.outputLen = this.iHash.outputLen;
3353
+ const t = this.blockLen, n = new Uint8Array(t);
3354
+ n.set(r.length > t ? e.create().update(r).digest() : r);
3355
+ for (let o = 0; o < n.length; o++)
3356
+ n[o] ^= 54;
3357
+ this.iHash.update(n), this.oHash = e.create();
3358
+ for (let o = 0; o < n.length; o++)
3359
+ n[o] ^= 106;
3360
+ this.oHash.update(n), ve(n);
3361
+ }
3362
+ update(e) {
3363
+ return be(this), this.iHash.update(e), this;
3364
+ }
3365
+ digestInto(e) {
3366
+ be(this), M(e, this.outputLen, "output"), this.finished = !0, this.iHash.digestInto(e), this.oHash.update(e), this.oHash.digestInto(e), this.destroy();
3367
+ }
3368
+ digest() {
3369
+ const e = new Uint8Array(this.oHash.outputLen);
3370
+ return this.digestInto(e), e;
3371
+ }
3372
+ _cloneInto(e) {
3373
+ e || (e = Object.create(Object.getPrototypeOf(this), {}));
3374
+ const { oHash: r, iHash: t, finished: n, destroyed: o, blockLen: i, outputLen: a } = this;
3375
+ return e = e, e.finished = n, e.destroyed = o, e.blockLen = i, e.outputLen = a, e.oHash = r._cloneInto(e.oHash), e.iHash = t._cloneInto(e.iHash), e;
3376
+ }
3377
+ clone() {
3378
+ return this._cloneInto();
3379
+ }
3380
+ destroy() {
3381
+ this.destroyed = !0, this.oHash.destroy(), this.iHash.destroy();
3382
+ }
3383
+ }
3384
+ const rr = (s, e, r) => new tr(s, e).update(r).digest();
3385
+ rr.create = (s, e) => new tr(s, e);
3386
+ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
3387
+ const At = (s, e) => (s + (s >= 0 ? e : -e) / sr) / e;
3388
+ function Ps(s, e, r) {
3389
+ const [[t, n], [o, i]] = e, a = At(i * s, r), c = At(-n * s, r);
3390
+ let l = s - a * t - c * o, d = -a * n - c * i;
3391
+ const f = l < ne, y = d < ne;
3392
+ f && (l = -l), y && (d = -d);
3393
+ const _ = nt(Math.ceil(xs(r) / 2)) + ye;
3394
+ if (l < ne || l >= _ || d < ne || d >= _)
3395
+ throw new Error("splitScalar (endomorphism): failed, k=" + s);
3396
+ return { k1neg: f, k1: l, k2neg: y, k2: d };
3397
+ }
3398
+ function Xe(s) {
3399
+ if (!["compact", "recovered", "der"].includes(s))
3400
+ throw new Error('Signature format must be "compact", "recovered", or "der"');
3401
+ return s;
3402
+ }
3403
+ function je(s, e) {
3404
+ const r = {};
3405
+ for (let t of Object.keys(e))
3406
+ r[t] = s[t] === void 0 ? e[t] : s[t];
3407
+ return Me(r.lowS, "lowS"), Me(r.prehash, "prehash"), r.format !== void 0 && Xe(r.format), r;
3408
+ }
3409
+ class Ls extends Error {
3410
+ constructor(e = "") {
3411
+ super(e);
3412
+ }
3413
+ }
3414
+ const de = {
3415
+ // asn.1 DER encoding utils
3416
+ Err: Ls,
3417
+ // Basic building block is TLV (Tag-Length-Value)
3418
+ _tlv: {
3419
+ encode: (s, e) => {
3420
+ const { Err: r } = de;
3421
+ if (s < 0 || s > 256)
3422
+ throw new r("tlv.encode: wrong tag");
3423
+ if (e.length & 1)
3424
+ throw new r("tlv.encode: unpadded data");
3425
+ const t = e.length / 2, n = Ce(t);
3426
+ if (n.length / 2 & 128)
3427
+ throw new r("tlv.encode: long form length too big");
3428
+ const o = t > 127 ? Ce(n.length / 2 | 128) : "";
3429
+ return Ce(s) + o + n + e;
3430
+ },
3431
+ // v - value, l - left bytes (unparsed)
3432
+ decode(s, e) {
3433
+ const { Err: r } = de;
3434
+ let t = 0;
3435
+ if (s < 0 || s > 256)
3436
+ throw new r("tlv.encode: wrong tag");
3437
+ if (e.length < 2 || e[t++] !== s)
3438
+ throw new r("tlv.decode: wrong tlv");
3439
+ const n = e[t++], o = !!(n & 128);
3440
+ let i = 0;
3441
+ if (!o)
3442
+ i = n;
3443
+ else {
3444
+ const c = n & 127;
3445
+ if (!c)
3446
+ throw new r("tlv.decode(long): indefinite length not supported");
3447
+ if (c > 4)
3448
+ throw new r("tlv.decode(long): byte length is too big");
3449
+ const l = e.subarray(t, t + c);
3450
+ if (l.length !== c)
3451
+ throw new r("tlv.decode: length bytes not complete");
3452
+ if (l[0] === 0)
3453
+ throw new r("tlv.decode(long): zero leftmost byte");
3454
+ for (const d of l)
3455
+ i = i << 8 | d;
3456
+ if (t += c, i < 128)
3457
+ throw new r("tlv.decode(long): not minimal encoding");
3458
+ }
3459
+ const a = e.subarray(t, t + i);
3460
+ if (a.length !== i)
3461
+ throw new r("tlv.decode: wrong value length");
3462
+ return { v: a, l: e.subarray(t + i) };
3463
+ }
3464
+ },
3465
+ // https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,
3466
+ // since we always use positive integers here. It must always be empty:
3467
+ // - add zero byte if exists
3468
+ // - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)
3469
+ _int: {
3470
+ encode(s) {
3471
+ const { Err: e } = de;
3472
+ if (s < ne)
3473
+ throw new e("integer: negative integers are not allowed");
3474
+ let r = Ce(s);
3475
+ if (Number.parseInt(r[0], 16) & 8 && (r = "00" + r), r.length & 1)
3476
+ throw new e("unexpected DER parsing assertion: unpadded hex");
3477
+ return r;
3478
+ },
3479
+ decode(s) {
3480
+ const { Err: e } = de;
3481
+ if (s[0] & 128)
3482
+ throw new e("invalid signature integer: negative");
3483
+ if (s[0] === 0 && !(s[1] & 128))
3484
+ throw new e("invalid signature integer: unnecessary leading zero");
3485
+ return Fe(s);
3486
+ }
3487
+ },
3488
+ toSig(s) {
3489
+ const { Err: e, _int: r, _tlv: t } = de, n = M(s, void 0, "signature"), { v: o, l: i } = t.decode(48, n);
3490
+ if (i.length)
3491
+ throw new e("invalid signature: left bytes after parsing");
3492
+ const { v: a, l: c } = t.decode(2, o), { v: l, l: d } = t.decode(2, c);
3493
+ if (d.length)
3494
+ throw new e("invalid signature: left bytes after parsing");
3495
+ return { r: r.decode(a), s: r.decode(l) };
3496
+ },
3497
+ hexFromSig(s) {
3498
+ const { _tlv: e, _int: r } = de, t = e.encode(2, r.encode(s.r)), n = e.encode(2, r.encode(s.s)), o = t + n;
3499
+ return e.encode(48, o);
3500
+ }
3501
+ }, ne = BigInt(0), ye = BigInt(1), sr = BigInt(2), Pe = BigInt(3), Bs = BigInt(4);
3502
+ function $s(s, e = {}) {
3503
+ const r = ks("weierstrass", s, e), { Fp: t, Fn: n } = r;
3504
+ let o = r.CURVE;
3505
+ const { h: i, n: a } = o;
3506
+ ot(e, {}, {
3507
+ allowInfinityPoint: "boolean",
3508
+ clearCofactor: "function",
3509
+ isTorsionFree: "function",
3510
+ fromBytes: "function",
3511
+ toBytes: "function",
3512
+ endo: "object"
3513
+ });
3514
+ const { endo: c } = e;
3515
+ if (c && (!t.is0(o.a) || typeof c.beta != "bigint" || !Array.isArray(c.basises)))
3516
+ throw new Error('invalid endo: expected "beta": bigint and "basises": array');
3517
+ const l = or(t, n);
3518
+ function d() {
3519
+ if (!t.isOdd)
3520
+ throw new Error("compression is not supported: Field does not have .isOdd()");
3521
+ }
3522
+ function f(P, h, u) {
3523
+ const { x, y: v } = h.toAffine(), I = t.toBytes(x);
3524
+ if (Me(u, "isCompressed"), u) {
3525
+ d();
3526
+ const T = !t.isOdd(v);
3527
+ return ue(nr(T), I);
3528
+ } else
3529
+ return ue(Uint8Array.of(4), I, t.toBytes(v));
3530
+ }
3531
+ function y(P) {
3532
+ M(P, void 0, "Point");
3533
+ const { publicKey: h, publicKeyUncompressed: u } = l, x = P.length, v = P[0], I = P.subarray(1);
3534
+ if (x === h && (v === 2 || v === 3)) {
3535
+ const T = t.fromBytes(I);
3536
+ if (!t.isValid(T))
3537
+ throw new Error("bad point: is not on curve, wrong x");
3538
+ const A = O(T);
3539
+ let b;
3540
+ try {
3541
+ b = t.sqrt(A);
3542
+ } catch (H) {
3543
+ const $ = H instanceof Error ? ": " + H.message : "";
3544
+ throw new Error("bad point: is not on curve, sqrt error" + $);
3545
+ }
3546
+ d();
3547
+ const R = t.isOdd(b);
3548
+ return (v & 1) === 1 !== R && (b = t.neg(b)), { x: T, y: b };
3549
+ } else if (x === u && v === 4) {
3550
+ const T = t.BYTES, A = t.fromBytes(I.subarray(0, T)), b = t.fromBytes(I.subarray(T, T * 2));
3551
+ if (!S(A, b))
3552
+ throw new Error("bad point: is not on curve");
3553
+ return { x: A, y: b };
3554
+ } else
3555
+ throw new Error(`bad point: got length ${x}, expected compressed=${h} or uncompressed=${u}`);
3556
+ }
3557
+ const _ = e.toBytes || f, E = e.fromBytes || y;
3558
+ function O(P) {
3559
+ const h = t.sqr(P), u = t.mul(h, P);
3560
+ return t.add(t.add(u, t.mul(P, o.a)), o.b);
3561
+ }
3562
+ function S(P, h) {
3563
+ const u = t.sqr(h), x = O(P);
3564
+ return t.eql(u, x);
3565
+ }
3566
+ if (!S(o.Gx, o.Gy))
3567
+ throw new Error("bad curve params: generator point");
3568
+ const C = t.mul(t.pow(o.a, Pe), Bs), U = t.mul(t.sqr(o.b), BigInt(27));
3569
+ if (t.is0(t.add(C, U)))
3570
+ throw new Error("bad curve params: a or b");
3571
+ function F(P, h, u = !1) {
3572
+ if (!t.isValid(h) || u && t.is0(h))
3573
+ throw new Error(`bad point coordinate ${P}`);
3574
+ return h;
3575
+ }
3576
+ function B(P) {
3577
+ if (!(P instanceof j))
3578
+ throw new Error("Weierstrass Point expected");
3579
+ }
3580
+ function q(P) {
3581
+ if (!c || !c.basises)
3582
+ throw new Error("no endo");
3583
+ return Ps(P, c.basises, n.ORDER);
3584
+ }
3585
+ const K = yt((P, h) => {
3586
+ const { X: u, Y: x, Z: v } = P;
3587
+ if (t.eql(v, t.ONE))
3588
+ return { x: u, y: x };
3589
+ const I = P.is0();
3590
+ h == null && (h = I ? t.ONE : t.inv(v));
3591
+ const T = t.mul(u, h), A = t.mul(x, h), b = t.mul(v, h);
3592
+ if (I)
3593
+ return { x: t.ZERO, y: t.ZERO };
3594
+ if (!t.eql(b, t.ONE))
3595
+ throw new Error("invZ was invalid");
3596
+ return { x: T, y: A };
3597
+ }), we = yt((P) => {
3598
+ if (P.is0()) {
3599
+ if (e.allowInfinityPoint && !t.is0(P.Y))
3600
+ return;
3601
+ throw new Error("bad point: ZERO");
3602
+ }
3603
+ const { x: h, y: u } = P.toAffine();
3604
+ if (!t.isValid(h) || !t.isValid(u))
3605
+ throw new Error("bad point: x or y not field elements");
3606
+ if (!S(h, u))
3607
+ throw new Error("bad point: equation left != right");
3608
+ if (!P.isTorsionFree())
3609
+ throw new Error("bad point: not in prime-order subgroup");
3610
+ return !0;
3611
+ });
3612
+ function ae(P, h, u, x, v) {
3613
+ return u = new j(t.mul(u.X, P), u.Y, u.Z), h = De(x, h), u = De(v, u), h.add(u);
3614
+ }
3615
+ const L = class L {
3616
+ /** Does NOT validate if the point is valid. Use `.assertValidity()`. */
3617
+ constructor(h, u, x) {
3618
+ w(this, "X");
3619
+ w(this, "Y");
3620
+ w(this, "Z");
3621
+ this.X = F("x", h), this.Y = F("y", u, !0), this.Z = F("z", x), Object.freeze(this);
3622
+ }
3623
+ static CURVE() {
3624
+ return o;
3625
+ }
3626
+ /** Does NOT validate if the point is valid. Use `.assertValidity()`. */
3627
+ static fromAffine(h) {
3628
+ const { x: u, y: x } = h || {};
3629
+ if (!h || !t.isValid(u) || !t.isValid(x))
3630
+ throw new Error("invalid affine point");
3631
+ if (h instanceof L)
3632
+ throw new Error("projective point not allowed");
3633
+ return t.is0(u) && t.is0(x) ? L.ZERO : new L(u, x, t.ONE);
3634
+ }
3635
+ static fromBytes(h) {
3636
+ const u = L.fromAffine(E(M(h, void 0, "point")));
3637
+ return u.assertValidity(), u;
3638
+ }
3639
+ static fromHex(h) {
3640
+ return L.fromBytes($e(h));
3641
+ }
3642
+ get x() {
3643
+ return this.toAffine().x;
3644
+ }
3645
+ get y() {
3646
+ return this.toAffine().y;
3647
+ }
3648
+ /**
3649
+ *
3650
+ * @param windowSize
3651
+ * @param isLazy true will defer table computation until the first multiplication
3652
+ * @returns
3653
+ */
3654
+ precompute(h = 8, u = !0) {
3655
+ return pe.createCache(this, h), u || this.multiply(Pe), this;
3656
+ }
3657
+ // TODO: return `this`
3658
+ /** A point on curve is valid if it conforms to equation. */
3659
+ assertValidity() {
3660
+ we(this);
3661
+ }
3662
+ hasEvenY() {
3663
+ const { y: h } = this.toAffine();
3664
+ if (!t.isOdd)
3665
+ throw new Error("Field doesn't support isOdd");
3666
+ return !t.isOdd(h);
3667
+ }
3668
+ /** Compare one point to another. */
3669
+ equals(h) {
3670
+ B(h);
3671
+ const { X: u, Y: x, Z: v } = this, { X: I, Y: T, Z: A } = h, b = t.eql(t.mul(u, A), t.mul(I, v)), R = t.eql(t.mul(x, A), t.mul(T, v));
3672
+ return b && R;
3673
+ }
3674
+ /** Flips point to one corresponding to (x, -y) in Affine coordinates. */
3675
+ negate() {
3676
+ return new L(this.X, t.neg(this.Y), this.Z);
3677
+ }
3678
+ // Renes-Costello-Batina exception-free doubling formula.
3679
+ // There is 30% faster Jacobian formula, but it is not complete.
3680
+ // https://eprint.iacr.org/2015/1060, algorithm 3
3681
+ // Cost: 8M + 3S + 3*a + 2*b3 + 15add.
3682
+ double() {
3683
+ const { a: h, b: u } = o, x = t.mul(u, Pe), { X: v, Y: I, Z: T } = this;
3684
+ let A = t.ZERO, b = t.ZERO, R = t.ZERO, k = t.mul(v, v), H = t.mul(I, I), $ = t.mul(T, T), N = t.mul(v, I);
3685
+ return N = t.add(N, N), R = t.mul(v, T), R = t.add(R, R), A = t.mul(h, R), b = t.mul(x, $), b = t.add(A, b), A = t.sub(H, b), b = t.add(H, b), b = t.mul(A, b), A = t.mul(N, A), R = t.mul(x, R), $ = t.mul(h, $), N = t.sub(k, $), N = t.mul(h, N), N = t.add(N, R), R = t.add(k, k), k = t.add(R, k), k = t.add(k, $), k = t.mul(k, N), b = t.add(b, k), $ = t.mul(I, T), $ = t.add($, $), k = t.mul($, N), A = t.sub(A, k), R = t.mul($, H), R = t.add(R, R), R = t.add(R, R), new L(A, b, R);
3686
+ }
3687
+ // Renes-Costello-Batina exception-free addition formula.
3688
+ // There is 30% faster Jacobian formula, but it is not complete.
3689
+ // https://eprint.iacr.org/2015/1060, algorithm 1
3690
+ // Cost: 12M + 0S + 3*a + 3*b3 + 23add.
3691
+ add(h) {
3692
+ B(h);
3693
+ const { X: u, Y: x, Z: v } = this, { X: I, Y: T, Z: A } = h;
3694
+ let b = t.ZERO, R = t.ZERO, k = t.ZERO;
3695
+ const H = o.a, $ = t.mul(o.b, Pe);
3696
+ let N = t.mul(u, I), G = t.mul(x, T), W = t.mul(v, A), Z = t.add(u, x), D = t.add(I, T);
3697
+ Z = t.mul(Z, D), D = t.add(N, G), Z = t.sub(Z, D), D = t.add(u, v);
3698
+ let V = t.add(I, A);
3699
+ return D = t.mul(D, V), V = t.add(N, W), D = t.sub(D, V), V = t.add(x, v), b = t.add(T, A), V = t.mul(V, b), b = t.add(G, W), V = t.sub(V, b), k = t.mul(H, D), b = t.mul($, W), k = t.add(b, k), b = t.sub(G, k), k = t.add(G, k), R = t.mul(b, k), G = t.add(N, N), G = t.add(G, N), W = t.mul(H, W), D = t.mul($, D), G = t.add(G, W), W = t.sub(N, W), W = t.mul(H, W), D = t.add(D, W), N = t.mul(G, D), R = t.add(R, N), N = t.mul(V, D), b = t.mul(Z, b), b = t.sub(b, N), N = t.mul(Z, G), k = t.mul(V, k), k = t.add(k, N), new L(b, R, k);
3700
+ }
3701
+ subtract(h) {
3702
+ return this.add(h.negate());
3703
+ }
3704
+ is0() {
3705
+ return this.equals(L.ZERO);
3706
+ }
3707
+ /**
3708
+ * Constant time multiplication.
3709
+ * Uses wNAF method. Windowed method may be 10% faster,
3710
+ * but takes 2x longer to generate and consumes 2x memory.
3711
+ * Uses precomputes when available.
3712
+ * Uses endomorphism for Koblitz curves.
3713
+ * @param scalar by which the point would be multiplied
3714
+ * @returns New point
3715
+ */
3716
+ multiply(h) {
3717
+ const { endo: u } = e;
3718
+ if (!n.isValidNot0(h))
3719
+ throw new Error("invalid scalar: out of range");
3720
+ let x, v;
3721
+ const I = (T) => pe.cached(this, T, (A) => Et(L, A));
3722
+ if (u) {
3723
+ const { k1neg: T, k1: A, k2neg: b, k2: R } = q(h), { p: k, f: H } = I(A), { p: $, f: N } = I(R);
3724
+ v = H.add(N), x = ae(u.beta, k, $, T, b);
3725
+ } else {
3726
+ const { p: T, f: A } = I(h);
3727
+ x = T, v = A;
3728
+ }
3729
+ return Et(L, [x, v])[0];
3730
+ }
3731
+ /**
3732
+ * Non-constant-time multiplication. Uses double-and-add algorithm.
3733
+ * It's faster, but should only be used when you don't care about
3734
+ * an exposed secret key e.g. sig verification, which works over *public* keys.
3735
+ */
3736
+ multiplyUnsafe(h) {
3737
+ const { endo: u } = e, x = this;
3738
+ if (!n.isValid(h))
3739
+ throw new Error("invalid scalar: out of range");
3740
+ if (h === ne || x.is0())
3741
+ return L.ZERO;
3742
+ if (h === ye)
3743
+ return x;
3744
+ if (pe.hasCache(this))
3745
+ return this.multiply(h);
3746
+ if (u) {
3747
+ const { k1neg: v, k1: I, k2neg: T, k2: A } = q(h), { p1: b, p2: R } = Ns(L, x, I, A);
3748
+ return ae(u.beta, b, R, v, T);
3749
+ } else
3750
+ return pe.unsafe(x, h);
3751
+ }
3752
+ /**
3753
+ * Converts Projective point to affine (x, y) coordinates.
3754
+ * @param invertedZ Z^-1 (inverted zero) - optional, precomputation is useful for invertBatch
3755
+ */
3756
+ toAffine(h) {
3757
+ return K(this, h);
3758
+ }
3759
+ /**
3760
+ * Checks whether Point is free of torsion elements (is in prime subgroup).
3761
+ * Always torsion-free for cofactor=1 curves.
3762
+ */
3763
+ isTorsionFree() {
3764
+ const { isTorsionFree: h } = e;
3765
+ return i === ye ? !0 : h ? h(L, this) : pe.unsafe(this, a).is0();
3766
+ }
3767
+ clearCofactor() {
3768
+ const { clearCofactor: h } = e;
3769
+ return i === ye ? this : h ? h(L, this) : this.multiplyUnsafe(i);
3770
+ }
3771
+ isSmallOrder() {
3772
+ return this.multiplyUnsafe(i).is0();
3773
+ }
3774
+ toBytes(h = !0) {
3775
+ return Me(h, "isCompressed"), this.assertValidity(), _(L, this, h);
3776
+ }
3777
+ toHex(h = !0) {
3778
+ return Ae(this.toBytes(h));
3779
+ }
3780
+ toString() {
3781
+ return `<Point ${this.is0() ? "ZERO" : this.toHex()}>`;
3782
+ }
3783
+ };
3784
+ // base / generator point
3785
+ w(L, "BASE", new L(o.Gx, o.Gy, t.ONE)), // zero / infinity / identity point
3786
+ w(L, "ZERO", new L(t.ZERO, t.ONE, t.ZERO)), // 0, 1, 0
3787
+ // math field
3788
+ w(L, "Fp", t), // scalar field
3789
+ w(L, "Fn", n);
3790
+ let j = L;
3791
+ const Re = n.BITS, pe = new Os(j, e.endo ? Math.ceil(Re / 2) : Re);
3792
+ return j.BASE.precompute(8), j;
3793
+ }
3794
+ function nr(s) {
3795
+ return Uint8Array.of(s ? 2 : 3);
3796
+ }
3797
+ function or(s, e) {
3798
+ return {
3799
+ secretKey: e.BYTES,
3800
+ publicKey: 1 + s.BYTES,
3801
+ publicKeyUncompressed: 1 + 2 * s.BYTES,
3802
+ publicKeyHasPrefix: !0,
3803
+ signature: 2 * e.BYTES
3804
+ };
3805
+ }
3806
+ function Ms(s, e = {}) {
3807
+ const { Fn: r } = s, t = e.randomBytes || Dt, n = Object.assign(or(s.Fp, r), { seed: Jt(r.ORDER) });
3808
+ function o(_) {
3809
+ try {
3810
+ const E = r.fromBytes(_);
3811
+ return r.isValidNot0(E);
3812
+ } catch {
3813
+ return !1;
3814
+ }
3815
+ }
3816
+ function i(_, E) {
3817
+ const { publicKey: O, publicKeyUncompressed: S } = n;
3818
+ try {
3819
+ const C = _.length;
3820
+ return E === !0 && C !== O || E === !1 && C !== S ? !1 : !!s.fromBytes(_);
3821
+ } catch {
3822
+ return !1;
3823
+ }
3824
+ }
3825
+ function a(_ = t(n.seed)) {
3826
+ return Rs(M(_, n.seed, "seed"), r.ORDER);
3827
+ }
3828
+ function c(_, E = !0) {
3829
+ return s.BASE.multiply(r.fromBytes(_)).toBytes(E);
3830
+ }
3831
+ function l(_) {
3832
+ const { secretKey: E, publicKey: O, publicKeyUncompressed: S } = n;
3833
+ if (!tt(_) || "_lengths" in r && r._lengths || E === O)
3834
+ return;
3835
+ const C = M(_, void 0, "key").length;
3836
+ return C === O || C === S;
3837
+ }
3838
+ function d(_, E, O = !0) {
3839
+ if (l(_) === !0)
3840
+ throw new Error("first arg must be private key");
3841
+ if (l(E) === !1)
3842
+ throw new Error("second arg must be public key");
3843
+ const S = r.fromBytes(_);
3844
+ return s.fromBytes(E).multiply(S).toBytes(O);
3845
+ }
3846
+ const f = {
3847
+ isValidSecretKey: o,
3848
+ isValidPublicKey: i,
3849
+ randomSecretKey: a
3850
+ }, y = Cs(a, c);
3851
+ return Object.freeze({ getPublicKey: c, getSharedSecret: d, keygen: y, Point: s, utils: f, lengths: n });
3852
+ }
3853
+ function Ds(s, e, r = {}) {
3854
+ Lt(e), ot(r, {}, {
3855
+ hmac: "function",
3856
+ lowS: "boolean",
3857
+ randomBytes: "function",
3858
+ bits2int: "function",
3859
+ bits2int_modN: "function"
3860
+ }), r = Object.assign({}, r);
3861
+ const t = r.randomBytes || Dt, n = r.hmac || ((h, u) => rr(e, h, u)), { Fp: o, Fn: i } = s, { ORDER: a, BITS: c } = i, { keygen: l, getPublicKey: d, getSharedSecret: f, utils: y, lengths: _ } = Ms(s, r), E = {
3862
+ prehash: !0,
3863
+ lowS: typeof r.lowS == "boolean" ? r.lowS : !0,
3864
+ format: "compact",
3865
+ extraEntropy: !1
3866
+ }, O = a * sr < o.ORDER;
3867
+ function S(h) {
3868
+ const u = a >> ye;
3869
+ return h > u;
3870
+ }
3871
+ function C(h, u) {
3872
+ if (!i.isValidNot0(u))
3873
+ throw new Error(`invalid signature ${h}: out of range 1..Point.Fn.ORDER`);
3874
+ return u;
3875
+ }
3876
+ function U() {
3877
+ if (O)
3878
+ throw new Error('"recovered" sig type is not supported for cofactor >2 curves');
3879
+ }
3880
+ function F(h, u) {
3881
+ Xe(u);
3882
+ const x = _.signature, v = u === "compact" ? x : u === "recovered" ? x + 1 : void 0;
3883
+ return M(h, v);
3884
+ }
3885
+ class B {
3886
+ constructor(u, x, v) {
3887
+ w(this, "r");
3888
+ w(this, "s");
3889
+ w(this, "recovery");
3890
+ if (this.r = C("r", u), this.s = C("s", x), v != null) {
3891
+ if (U(), ![0, 1, 2, 3].includes(v))
3892
+ throw new Error("invalid recovery id");
3893
+ this.recovery = v;
3894
+ }
3895
+ Object.freeze(this);
3896
+ }
3897
+ static fromBytes(u, x = E.format) {
3898
+ F(u, x);
3899
+ let v;
3900
+ if (x === "der") {
3901
+ const { r: b, s: R } = de.toSig(M(u));
3902
+ return new B(b, R);
3903
+ }
3904
+ x === "recovered" && (v = u[0], x = "compact", u = u.subarray(1));
3905
+ const I = _.signature / 2, T = u.subarray(0, I), A = u.subarray(I, I * 2);
3906
+ return new B(i.fromBytes(T), i.fromBytes(A), v);
3907
+ }
3908
+ static fromHex(u, x) {
3909
+ return this.fromBytes($e(u), x);
3910
+ }
3911
+ assertRecovery() {
3912
+ const { recovery: u } = this;
3913
+ if (u == null)
3914
+ throw new Error("invalid recovery id: must be present");
3915
+ return u;
3916
+ }
3917
+ addRecoveryBit(u) {
3918
+ return new B(this.r, this.s, u);
3919
+ }
3920
+ recoverPublicKey(u) {
3921
+ const { r: x, s: v } = this, I = this.assertRecovery(), T = I === 2 || I === 3 ? x + a : x;
3922
+ if (!o.isValid(T))
3923
+ throw new Error("invalid recovery id: sig.r+curve.n != R.x");
3924
+ const A = o.toBytes(T), b = s.fromBytes(ue(nr((I & 1) === 0), A)), R = i.inv(T), k = K(M(u, void 0, "msgHash")), H = i.create(-k * R), $ = i.create(v * R), N = s.BASE.multiplyUnsafe(H).add(b.multiplyUnsafe($));
3925
+ if (N.is0())
3926
+ throw new Error("invalid recovery: point at infinify");
3927
+ return N.assertValidity(), N;
3928
+ }
3929
+ // Signatures should be low-s, to prevent malleability.
3930
+ hasHighS() {
3931
+ return S(this.s);
3932
+ }
3933
+ toBytes(u = E.format) {
3934
+ if (Xe(u), u === "der")
3935
+ return $e(de.hexFromSig(this));
3936
+ const { r: x, s: v } = this, I = i.toBytes(x), T = i.toBytes(v);
3937
+ return u === "recovered" ? (U(), ue(Uint8Array.of(this.assertRecovery()), I, T)) : ue(I, T);
3938
+ }
3939
+ toHex(u) {
3940
+ return Ae(this.toBytes(u));
3941
+ }
3942
+ }
3943
+ const q = r.bits2int || function(u) {
3944
+ if (u.length > 8192)
3945
+ throw new Error("input is too large");
3946
+ const x = Fe(u), v = u.length * 8 - c;
3947
+ return v > 0 ? x >> BigInt(v) : x;
3948
+ }, K = r.bits2int_modN || function(u) {
3949
+ return i.create(q(u));
3950
+ }, we = nt(c);
3951
+ function ae(h) {
3952
+ return ps("num < 2^" + c, h, ne, we), i.toBytes(h);
3953
+ }
3954
+ function j(h, u) {
3955
+ return M(h, void 0, "message"), u ? M(e(h), void 0, "prehashed message") : h;
3956
+ }
3957
+ function Re(h, u, x) {
3958
+ const { lowS: v, prehash: I, extraEntropy: T } = je(x, E);
3959
+ h = j(h, I);
3960
+ const A = K(h), b = i.fromBytes(u);
3961
+ if (!i.isValidNot0(b))
3962
+ throw new Error("invalid private key");
3963
+ const R = [ae(b), ae(A)];
3964
+ if (T != null && T !== !1) {
3965
+ const N = T === !0 ? t(_.secretKey) : T;
3966
+ R.push(M(N, void 0, "extraEntropy"));
3967
+ }
3968
+ const k = ue(...R), H = A;
3969
+ function $(N) {
3970
+ const G = q(N);
3971
+ if (!i.isValidNot0(G))
3972
+ return;
3973
+ const W = i.inv(G), Z = s.BASE.multiply(G).toAffine(), D = i.create(Z.x);
3974
+ if (D === ne)
3975
+ return;
3976
+ const V = i.create(W * i.create(H + D * b));
3977
+ if (V === ne)
3978
+ return;
3979
+ let dt = (Z.x === D ? 0 : 2) | Number(Z.y & ye), ut = V;
3980
+ return v && S(V) && (ut = i.neg(V), dt ^= 1), new B(D, ut, O ? void 0 : dt);
3981
+ }
3982
+ return { seed: k, k2sig: $ };
3983
+ }
3984
+ function pe(h, u, x = {}) {
3985
+ const { seed: v, k2sig: I } = Re(h, u, x);
3986
+ return _s(e.outputLen, i.BYTES, n)(v, I).toBytes(x.format);
3987
+ }
3988
+ function L(h, u, x, v = {}) {
3989
+ const { lowS: I, prehash: T, format: A } = je(v, E);
3990
+ if (x = M(x, void 0, "publicKey"), u = j(u, T), !tt(h)) {
3991
+ const b = h instanceof B ? ", use sig.toBytes()" : "";
3992
+ throw new Error("verify expects Uint8Array signature" + b);
3993
+ }
3994
+ F(h, A);
3995
+ try {
3996
+ const b = B.fromBytes(h, A), R = s.fromBytes(x);
3997
+ if (I && b.hasHighS())
3998
+ return !1;
3999
+ const { r: k, s: H } = b, $ = K(u), N = i.inv(H), G = i.create($ * N), W = i.create(k * N), Z = s.BASE.multiplyUnsafe(G).add(R.multiplyUnsafe(W));
4000
+ return Z.is0() ? !1 : i.create(Z.x) === k;
4001
+ } catch {
4002
+ return !1;
4003
+ }
4004
+ }
4005
+ function P(h, u, x = {}) {
4006
+ const { prehash: v } = je(x, E);
4007
+ return u = j(u, v), B.fromBytes(h, "recovered").recoverPublicKey(u).toBytes();
4008
+ }
4009
+ return Object.freeze({
4010
+ keygen: l,
4011
+ getPublicKey: d,
4012
+ getSharedSecret: f,
4013
+ utils: y,
4014
+ lengths: _,
4015
+ Point: s,
4016
+ sign: pe,
4017
+ verify: L,
4018
+ recoverPublicKey: P,
4019
+ Signature: B,
4020
+ hash: e
4021
+ });
4022
+ }
4023
+ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
4024
+ const at = {
4025
+ p: BigInt("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"),
4026
+ n: BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"),
4027
+ h: BigInt(1),
4028
+ a: BigInt(0),
4029
+ b: BigInt(7),
4030
+ Gx: BigInt("0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"),
4031
+ Gy: BigInt("0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8")
4032
+ }, Us = {
4033
+ beta: BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"),
4034
+ basises: [
4035
+ [BigInt("0x3086d221a7d46bcde86c90e49284eb15"), -BigInt("0xe4437ed6010e88286f547fa90abfe4c3")],
4036
+ [BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"), BigInt("0x3086d221a7d46bcde86c90e49284eb15")]
4037
+ ]
4038
+ }, Rt = /* @__PURE__ */ BigInt(2);
4039
+ function Hs(s) {
4040
+ const e = at.p, r = BigInt(3), t = BigInt(6), n = BigInt(11), o = BigInt(22), i = BigInt(23), a = BigInt(44), c = BigInt(88), l = s * s * s % e, d = l * l * s % e, f = J(d, r, e) * d % e, y = J(f, r, e) * d % e, _ = J(y, Rt, e) * l % e, E = J(_, n, e) * _ % e, O = J(E, o, e) * E % e, S = J(O, a, e) * O % e, C = J(S, c, e) * S % e, U = J(C, a, e) * O % e, F = J(U, r, e) * d % e, B = J(F, i, e) * E % e, q = J(B, t, e) * l % e, K = J(q, Rt, e);
4041
+ if (!Je.eql(Je.sqr(K), s))
4042
+ throw new Error("Cannot find square root");
4043
+ return K;
4044
+ }
4045
+ const Je = qe(at.p, { sqrt: Hs }), Fs = /* @__PURE__ */ $s(at, {
4046
+ Fp: Je,
4047
+ endo: Us
4048
+ }), qs = /* @__PURE__ */ Ds(Fs, hs), Gs = BigInt(0), Te = BigInt(1), Ws = BigInt(2), Vs = BigInt(7), zs = BigInt(256), Ks = BigInt(113), ir = [], ar = [], cr = [];
4049
+ for (let s = 0, e = Te, r = 1, t = 0; s < 24; s++) {
4050
+ [r, t] = [t, (2 * r + 3 * t) % 5], ir.push(2 * (5 * t + r)), ar.push((s + 1) * (s + 2) / 2 % 64);
4051
+ let n = Gs;
4052
+ for (let o = 0; o < 7; o++)
4053
+ e = (e << Te ^ (e >> Vs) * Ks) % zs, e & Ws && (n ^= Te << (Te << BigInt(o)) - Te);
4054
+ cr.push(n);
4055
+ }
4056
+ const lr = ns(cr, !0), js = lr[0], Ys = lr[1], Ot = (s, e, r) => r > 32 ? as(s, e, r) : os(s, e, r), Nt = (s, e, r) => r > 32 ? cs(s, e, r) : is(s, e, r);
4057
+ function Zs(s, e = 24) {
4058
+ const r = new Uint32Array(10);
4059
+ for (let t = 24 - e; t < 24; t++) {
4060
+ for (let i = 0; i < 10; i++)
4061
+ r[i] = s[i] ^ s[i + 10] ^ s[i + 20] ^ s[i + 30] ^ s[i + 40];
4062
+ for (let i = 0; i < 10; i += 2) {
4063
+ const a = (i + 8) % 10, c = (i + 2) % 10, l = r[c], d = r[c + 1], f = Ot(l, d, 1) ^ r[a], y = Nt(l, d, 1) ^ r[a + 1];
4064
+ for (let _ = 0; _ < 50; _ += 10)
4065
+ s[i + _] ^= f, s[i + _ + 1] ^= y;
4066
+ }
4067
+ let n = s[2], o = s[3];
4068
+ for (let i = 0; i < 24; i++) {
4069
+ const a = ar[i], c = Ot(n, o, a), l = Nt(n, o, a), d = ir[i];
4070
+ n = s[d], o = s[d + 1], s[d] = c, s[d + 1] = l;
4071
+ }
4072
+ for (let i = 0; i < 50; i += 10) {
4073
+ for (let a = 0; a < 10; a++)
4074
+ r[a] = s[i + a];
4075
+ for (let a = 0; a < 10; a++)
4076
+ s[i + a] ^= ~r[(a + 2) % 10] & r[(a + 4) % 10];
4077
+ }
4078
+ s[0] ^= js[t], s[1] ^= Ys[t];
4079
+ }
4080
+ ve(r);
4081
+ }
4082
+ class ct {
4083
+ // NOTE: we accept arguments in bytes instead of bits here.
4084
+ constructor(e, r, t, n = !1, o = 24) {
4085
+ w(this, "state");
4086
+ w(this, "pos", 0);
4087
+ w(this, "posOut", 0);
4088
+ w(this, "finished", !1);
4089
+ w(this, "state32");
4090
+ w(this, "destroyed", !1);
4091
+ w(this, "blockLen");
4092
+ w(this, "suffix");
4093
+ w(this, "outputLen");
4094
+ w(this, "enableXOF", !1);
4095
+ w(this, "rounds");
4096
+ if (this.blockLen = e, this.suffix = r, this.outputLen = t, this.enableXOF = n, this.rounds = o, ie(t, "outputLen"), !(0 < e && e < 200))
4097
+ throw new Error("only keccak-f1600 function is supported");
4098
+ this.state = new Uint8Array(200), this.state32 = jr(this.state);
4099
+ }
4100
+ clone() {
4101
+ return this._cloneInto();
4102
+ }
4103
+ keccak() {
4104
+ _t(this.state32), Zs(this.state32, this.rounds), _t(this.state32), this.posOut = 0, this.pos = 0;
4105
+ }
4106
+ update(e) {
4107
+ be(this), M(e);
4108
+ const { blockLen: r, state: t } = this, n = e.length;
4109
+ for (let o = 0; o < n; ) {
4110
+ const i = Math.min(r - this.pos, n - o);
4111
+ for (let a = 0; a < i; a++)
4112
+ t[this.pos++] ^= e[o++];
4113
+ this.pos === r && this.keccak();
4114
+ }
4115
+ return this;
4116
+ }
4117
+ finish() {
4118
+ if (this.finished)
4119
+ return;
4120
+ this.finished = !0;
4121
+ const { state: e, suffix: r, pos: t, blockLen: n } = this;
4122
+ e[t] ^= r, r & 128 && t === n - 1 && this.keccak(), e[n - 1] ^= 128, this.keccak();
4123
+ }
4124
+ writeInto(e) {
4125
+ be(this, !1), M(e), this.finish();
4126
+ const r = this.state, { blockLen: t } = this;
4127
+ for (let n = 0, o = e.length; n < o; ) {
4128
+ this.posOut >= t && this.keccak();
4129
+ const i = Math.min(t - this.posOut, o - n);
4130
+ e.set(r.subarray(this.posOut, this.posOut + i), n), this.posOut += i, n += i;
4131
+ }
4132
+ return e;
4133
+ }
4134
+ xofInto(e) {
4135
+ if (!this.enableXOF)
4136
+ throw new Error("XOF is not possible for this instance");
4137
+ return this.writeInto(e);
4138
+ }
4139
+ xof(e) {
4140
+ return ie(e), this.xofInto(new Uint8Array(e));
4141
+ }
4142
+ digestInto(e) {
4143
+ if (Bt(e, this), this.finished)
4144
+ throw new Error("digest() was already called");
4145
+ return this.writeInto(e), this.destroy(), e;
4146
+ }
4147
+ digest() {
4148
+ return this.digestInto(new Uint8Array(this.outputLen));
4149
+ }
4150
+ destroy() {
4151
+ this.destroyed = !0, ve(this.state);
4152
+ }
4153
+ _cloneInto(e) {
4154
+ const { blockLen: r, suffix: t, outputLen: n, rounds: o, enableXOF: i } = this;
4155
+ return e || (e = new ct(r, t, n, i, o)), e.state32.set(this.state32), e.pos = this.pos, e.posOut = this.posOut, e.finished = this.finished, e.rounds = o, e.suffix = t, e.outputLen = n, e.enableXOF = i, e.destroyed = this.destroyed, e;
4156
+ }
4157
+ }
4158
+ const Xs = (s, e, r, t = {}) => Mt(() => new ct(e, s, r), t), kt = /* @__PURE__ */ Xs(1, 136, 32);
4159
+ class Js {
4160
+ async verifyJWT(e, r) {
4161
+ try {
4162
+ const t = this.decodeJWT(e);
4163
+ g.log("[CROSSx] JWT 디코딩 성공:", {
4164
+ sub: t.sub,
4165
+ exp: t.exp,
4166
+ iat: t.iat,
4167
+ "현재 시간": Math.floor(Date.now() / 1e3)
4168
+ });
4169
+ const n = Math.floor(Date.now() / 1e3);
4170
+ return t.exp && t.exp < n ? (g.warn("[CROSSx] 토큰 만료:", {
4171
+ exp: t.exp,
4172
+ now: n,
4173
+ 만료시간: new Date(t.exp * 1e3).toISOString()
4174
+ }), { payload: t, valid: !1, signatureVerified: !1 }) : t.sub ? (g.log("[CROSSx] JWT 검증 성공 (서명 미검증 — JWKS 미구현)"), { payload: t, valid: !0, signatureVerified: !1 }) : (g.warn("[CROSSx] JWT에 sub(사용자ID) 없음"), { payload: t, valid: !1, signatureVerified: !1 });
4175
+ } catch (t) {
4176
+ throw g.error("[CROSSx] JWT 검증 중 에러:", t), t;
4177
+ }
4178
+ }
4179
+ decodeJWT(e) {
4180
+ return hr(e);
4181
+ }
4182
+ /**
4183
+ * EIP-191 personal_sign 서명에서 서명자 Ethereum 주소를 복원합니다.
4184
+ *
4185
+ * hash = keccak256("\x19Ethereum Signed Message:\n" + len(msgBytes) + msgBytes)
4186
+ * publicKey = ecrecover(hash, v, r, s)
4187
+ * address = keccak256(publicKey)[12:]
4188
+ */
4189
+ recoverPersonalSignSigner(e, r) {
4190
+ const t = new TextEncoder().encode(e), n = new TextEncoder().encode(
4191
+ `Ethereum Signed Message:
4192
+ ${t.length}`
4193
+ ), o = new Uint8Array(n.length + t.length);
4194
+ o.set(n, 0), o.set(t, n.length);
4195
+ const i = kt(o), a = r.startsWith("0x") ? r.slice(2) : r;
4196
+ if (a.length !== 130)
4197
+ throw new Error(`Invalid signature length: expected 130 hex chars, got ${a.length}`);
4198
+ const c = Qs(a), l = c.slice(0, 32), d = c.slice(32, 64), f = c[64], y = f >= 27 ? f - 27 : f, O = new qs.Signature(
4199
+ Ct(l),
4200
+ Ct(d)
4201
+ ).addRecoveryBit(y).recoverPublicKey(i).toBytes(!1).slice(1), S = kt(O);
4202
+ return "0x" + Ae(S.slice(12));
4203
+ }
4204
+ }
4205
+ function Qs(s) {
4206
+ const e = new Uint8Array(s.length / 2);
4207
+ for (let r = 0; r < e.length; r++)
4208
+ e[r] = parseInt(s.substring(r * 2, r * 2 + 2), 16);
4209
+ return e;
4210
+ }
4211
+ function Ct(s) {
4212
+ let e = "0x";
4213
+ for (const r of s) e += r.toString(16).padStart(2, "0");
4214
+ return BigInt(e);
4215
+ }
4216
+ const en = 3e4;
4217
+ class tn {
4218
+ async request(e) {
4219
+ const r = new AbortController(), t = setTimeout(
4220
+ () => r.abort(),
4221
+ e.timeoutMs ?? en
4222
+ );
4223
+ try {
4224
+ const n = await fetch(e.url, {
4225
+ method: e.method,
4226
+ headers: e.headers,
4227
+ body: e.body ? JSON.stringify(e.body) : void 0,
4228
+ signal: r.signal
4229
+ }), o = await n.json();
4230
+ return {
4231
+ status: n.status,
4232
+ data: o,
4233
+ headers: Object.fromEntries(n.headers.entries())
4234
+ };
4235
+ } finally {
4236
+ clearTimeout(t);
4237
+ }
4238
+ }
4239
+ }
4240
+ class lt {
4241
+ static generateState() {
4242
+ const e = new Uint8Array(16);
4243
+ return crypto.getRandomValues(e), Array.from(e, (r) => r.toString(16).padStart(2, "0")).join("");
4244
+ }
4245
+ openAuth(e) {
4246
+ return new Promise((r, t) => {
4247
+ const n = e.width ?? 500, o = e.height ?? 600, i = window.screenX + (window.outerWidth - n) / 2, a = window.screenY + (window.outerHeight - o) / 2, c = lt.generateState(), l = e.authUrl.includes("?") ? "&" : "?", d = `${e.authUrl}${l}state=${c}`, f = window.open(
4248
+ d,
4249
+ "CROSSx OAuth",
4250
+ `width=${n},height=${o},left=${i},top=${a}`
4251
+ );
4252
+ if (!f) {
4253
+ t(new Error("팝업 창을 열 수 없습니다. 팝업 차단을 해제해 주세요."));
4254
+ return;
4255
+ }
4256
+ const y = setTimeout(() => {
4257
+ E(), t(new Error("Authentication timeout"));
4258
+ }, 5 * 60 * 1e3), _ = setInterval(() => {
4259
+ try {
4260
+ f.closed && (g.log("[CROSSx] 팝업이 닫혔습니다"), E(), t(new Error("로그인이 취소되었습니다")));
4261
+ } catch {
4262
+ }
4263
+ }, 1e3), E = () => {
4264
+ clearTimeout(y), clearInterval(_), window.removeEventListener("message", O);
4265
+ }, O = (S) => {
4266
+ var U, F, B, q, K, we, ae;
4267
+ if (S.origin !== e.expectedOrigin) return;
4268
+ E(), g.log("[CROSSx] OAuth postMessage 수신 — status:", S.data.status);
4269
+ const C = S.data.state ?? ((U = S.data.data) == null ? void 0 : U.state);
4270
+ if (C && C !== c) {
4271
+ t(new Error("OAuth state mismatch — possible CSRF attack"));
4272
+ return;
4273
+ }
4274
+ if (S.data.status === "success") {
4275
+ const j = ((F = S.data.data) == null ? void 0 : F.accessToken) || ((B = S.data.data) == null ? void 0 : B.idToken);
4276
+ g.log("[CROSSx] OAuth 토큰 수신:", {
4277
+ hasAccessToken: !!((q = S.data.data) != null && q.accessToken),
4278
+ hasIdToken: !!((K = S.data.data) != null && K.idToken)
4279
+ }), j ? r(j) : (g.error("[CROSSx] 토큰을 찾을 수 없음:", S.data), t(new Error("Token not found in response")));
4280
+ } else
4281
+ g.error("[CROSSx] OAuth 실패:", (we = S.data.data) == null ? void 0 : we.error), t(new Error(((ae = S.data.data) == null ? void 0 : ae.error) || "Authentication failed"));
4282
+ };
4283
+ window.addEventListener("message", O);
4284
+ });
4285
+ }
4286
+ }
4287
+ const Le = "crossx_wallet_data";
4288
+ class rn {
4289
+ constructor(e) {
4290
+ this.storage = e;
4291
+ }
4292
+ async getOrCreateWallet(e) {
4293
+ try {
4294
+ const r = await this.storage.get(Le);
4295
+ if (r) return r;
4296
+ const t = {
4297
+ id: e,
4298
+ address: this.generateMockEvmAddress(),
4299
+ derivationPath: "m/44'/60'/0'/0/0",
4300
+ createdAt: Date.now()
4301
+ };
4302
+ return await this.storage.set(Le, t), t;
4303
+ } catch (r) {
4304
+ throw new m(p.WALLET_CREATION_FAILED, "Wallet creation failed", r);
4305
+ }
4306
+ }
4307
+ async getAddress(e, r) {
4308
+ return {
4309
+ address: this.generateMockEvmAddress(),
4310
+ derivationPath: `m/44'/60'/0'/0/${r}`
4311
+ };
4312
+ }
4313
+ async getBalance(e, r) {
4314
+ return "0x0";
4315
+ }
4316
+ async getTransactionCount(e, r) {
4317
+ return 0;
4318
+ }
4319
+ async getTransactionReceipt(e, r) {
4320
+ return null;
4321
+ }
4322
+ async rpcRequest(e, r, t) {
4323
+ return g.log(`[Mock] rpcRequest: ${e}`), null;
4324
+ }
4325
+ async prepare(e, r) {
4326
+ const t = "mock-" + crypto.randomUUID();
4327
+ return g.log(`[Mock] prepare action=${e} → uuid=${t}`), { uuid: t, expiresAt: new Date(Date.now() + 5 * 6e4).toISOString() };
4328
+ }
4329
+ async signMessage(e, r, t, n = 0, o, i) {
4330
+ return g.log(`[Mock] signMessage chainId=${r} index=${n} uuid=${o} from=${i}: "${t}"`), { chainId: r, signature: this.generateMockSignature(), format: "hex" };
4331
+ }
4332
+ async signTypedData(e, r, t, n = 0, o, i) {
4333
+ return g.log(`[Mock] signTypedData chainId=${r} index=${n} uuid=${o} from=${i}`), { chainId: r, signature: this.generateMockSignature(), format: "hex" };
4334
+ }
4335
+ async signTransaction(e, r, t, n = 0, o) {
4336
+ g.log(`[Mock] signTransaction chainId=${r} index=${n} uuid=${o}:`, t);
4337
+ const i = "0x" + Array(64).fill(0).map(() => Math.floor(Math.random() * 16).toString(16)).join("");
4338
+ return { chainId: r, signature: this.generateMockSignature(), txHash: i, format: "hex" };
4339
+ }
4340
+ async sendTransaction(e, r, t, n) {
4341
+ return g.log(`[Mock] sendTransaction chainId=${r} uuid=${n}:`, t), { txHash: "0x" + Array(64).fill(0).map(() => Math.floor(Math.random() * 16).toString(16)).join("") };
4342
+ }
4343
+ async withdraw(e) {
4344
+ g.log("[Mock] withdraw confirmation:", e);
4345
+ }
4346
+ async recoverWallet(e, r) {
4347
+ g.log("[Mock] recoverWallet");
4348
+ const t = {
4349
+ id: e,
4350
+ address: this.generateMockEvmAddress(),
4351
+ derivationPath: "m/44'/60'/0'/0/0",
4352
+ createdAt: Date.now()
4353
+ };
4354
+ return await this.storage.set(Le, t), t;
4355
+ }
4356
+ async migrateWallet(e, r) {
4357
+ g.log(`[Mock] migrateWallet pin=${e} sub=${r}`);
4358
+ const t = {
4359
+ id: r,
4360
+ address: this.generateMockEvmAddress(),
4361
+ derivationPath: "m/44'/60'/0'/0/0",
4362
+ createdAt: Date.now()
4363
+ };
4364
+ return await this.storage.set(Le, t), t;
4365
+ }
4366
+ generateMockEvmAddress() {
4367
+ return "0x" + Array(40).fill(0).map(
4368
+ () => Math.floor(Math.random() * 16).toString(16)
4369
+ ).join("");
4370
+ }
4371
+ generateMockSignature() {
4372
+ return "0x" + Array(130).fill(0).map(
4373
+ () => Math.floor(Math.random() * 16).toString(16)
4374
+ ).join("");
4375
+ }
4376
+ }
4377
+ class Ue {
4378
+ constructor(e, r, t, n) {
4379
+ this.baseUrl = e.gatewayUrl, this.projectId = e.projectId, this.appId = e.appId, this.appType = e.appType, this.storage = r, this.transport = t, this.tokenStore = n;
4380
+ }
4381
+ getAuthToken() {
4382
+ const e = this.tokenStore.get();
4383
+ if (!e)
4384
+ throw new m(
4385
+ p.AUTH_NOT_AUTHENTICATED,
4386
+ "No auth token found. Please sign in first."
4387
+ );
4388
+ return e;
4389
+ }
4390
+ async request(e, r, t) {
4391
+ var a, c;
4392
+ const n = this.getAuthToken(), o = `${this.baseUrl}${r}`, i = {
4393
+ Authorization: `Bearer ${n}`,
4394
+ "Content-Type": "application/json",
4395
+ "X-Project-Id": this.projectId
4396
+ };
4397
+ this.appId && (i["X-App-Id"] = this.appId, i["X-App-Type"] = this.appType);
4398
+ try {
4399
+ const d = (await this.transport.request({
4400
+ url: o,
4401
+ method: e,
4402
+ headers: i,
4403
+ body: t ?? void 0
4404
+ })).data;
4405
+ if (d && typeof d.code == "number") {
4406
+ if (d.code < 0 || d.code >= 400) {
4407
+ const f = d.message || d.data || "API request failed";
4408
+ g.error("[CROSSx] Wallet Gateway API 에러 (HTTP 200):", {
4409
+ code: d.code,
4410
+ message: f,
4411
+ url: o,
4412
+ method: e,
4413
+ fullResponse: d
4414
+ });
4415
+ const y = Ue.mapGatewayError(d.code), _ = Ue.getGatewayErrorMessage(d.code, f), E = new m(y, _);
4416
+ throw E.gatewayCode = d.code, E.gatewayMessage = f, E;
4417
+ }
4418
+ return g.log("[CROSSx] Wallet Gateway API 성공:", { code: d.code, url: o, method: e }), d.data ?? d;
4419
+ }
4420
+ return d;
4421
+ } catch (l) {
4422
+ if (l instanceof m) throw l;
4423
+ if ((a = l.response) != null && a.data) {
4424
+ const d = l.response.data, f = d.message || d.data || "API request failed", y = d.code || "UNKNOWN";
4425
+ throw g.error("[CROSSx] Wallet Gateway API 에러 (HTTP 에러):", {
4426
+ code: y,
4427
+ message: f,
4428
+ url: o,
4429
+ method: e,
4430
+ status: (c = l.response) == null ? void 0 : c.status
4431
+ }), new m(
4432
+ p.UNKNOWN_ERROR,
4433
+ `Wallet Gateway error (${y}): ${f}`
4434
+ );
4435
+ }
4436
+ throw l;
4437
+ }
4438
+ }
4439
+ async getOrCreateWallet(e) {
4440
+ var r;
4441
+ g.log("[CROSSx][Migration Phase 2] GET /mnemonic/addresses — 기존 지갑 조회");
4442
+ try {
4443
+ const t = await this.request("GET", "/mnemonic/addresses");
4444
+ if (t.addresses && t.addresses.length > 0) {
4445
+ const { address: n } = t.addresses[0];
4446
+ return g.log("[CROSSx][Migration Phase 2] 기존 지갑 발견 — address:", n), {
4447
+ id: e,
4448
+ address: n,
4449
+ derivationPath: "m/44'/60'/0'/0/0",
4450
+ createdAt: Date.now()
4451
+ };
4452
+ }
4453
+ } catch {
4454
+ g.log("[CROSSx][Migration Phase 2] 기존 지갑 없음, POST /mnemonic/create 진행");
4455
+ }
4456
+ g.log("[CROSSx][Migration Phase 2] POST /mnemonic/create — ignoreBackup: false");
4457
+ try {
4458
+ const t = { ignoreBackup: !1 }, n = await this.request("POST", "/mnemonic/create", t);
4459
+ return g.log("[CROSSx][Migration Phase 2] /mnemonic/create 성공 — address:", n.address), {
4460
+ id: e,
4461
+ address: n.address,
4462
+ derivationPath: "m/44'/60'/0'/0/0",
4463
+ createdAt: Date.now()
4464
+ };
4465
+ } catch (t) {
4466
+ if ((t == null ? void 0 : t.gatewayCode) === -10004 || (r = t == null ? void 0 : t.message) != null && r.includes("-10004")) {
4467
+ g.log("[CROSSx][Migration Phase 2] 지갑 이미 존재 (-10004), 주소 재조회");
4468
+ const n = await this.request("GET", "/mnemonic/addresses");
4469
+ if (n.addresses && n.addresses.length > 0)
4470
+ return {
4471
+ id: e,
4472
+ address: n.addresses[0].address,
4473
+ derivationPath: "m/44'/60'/0'/0/0",
4474
+ createdAt: Date.now()
4475
+ };
4476
+ }
4477
+ throw (t == null ? void 0 : t.gatewayCode) === -10012 && g.log("[CROSSx][Migration Phase 2] Gateway -10012 수신 → MIGRATION_BACKUP_EXISTS throw"), t;
4478
+ }
4479
+ }
4480
+ async getAddress(e, r) {
4481
+ try {
4482
+ return { address: (await this.request(
4483
+ "GET",
4484
+ `/mnemonic/address?index=${r}`
4485
+ )).address, derivationPath: `m/44'/60'/0'/0/${r}` };
4486
+ } catch (t) {
4487
+ if (t instanceof m && this.isAddressNotFoundError(t))
4488
+ return g.log(`[CROSSx] index ${r} 주소 없음, 파생 중...`), { address: (await this.request(
4489
+ "GET",
4490
+ `/mnemonic/address?index=${r}&derive=true`
4491
+ )).address, derivationPath: `m/44'/60'/0'/0/${r}` };
4492
+ throw t;
4493
+ }
4494
+ }
4495
+ isAddressNotFoundError(e) {
4496
+ const r = e.message.toLowerCase();
4497
+ return r.includes("404") || r.includes("not found") || r.includes("찾을 수 없") || r.includes("does not exist") || r.includes("no address");
4498
+ }
4499
+ async rpcCall(e, r, t) {
4500
+ const n = {
4501
+ jsonrpc: "2.0",
4502
+ method: e,
4503
+ params: r,
4504
+ id: Date.now()
4505
+ }, o = await this.request(
4506
+ "POST",
4507
+ `/wallet/rpc/${encodeURIComponent(t)}`,
4508
+ n
4509
+ );
4510
+ if (o != null && o.error)
4511
+ throw new m(
4512
+ p.UNKNOWN_ERROR,
4513
+ `RPC call failed (${e}): ${o.error.message}`
4514
+ );
4515
+ return o == null ? void 0 : o.result;
4516
+ }
4517
+ async getBalance(e, r) {
4518
+ return await this.rpcCall("eth_getBalance", [e, "latest"], r) ?? "0x0";
4519
+ }
4520
+ async getTransactionCount(e, r) {
4521
+ const t = await this.rpcCall("eth_getTransactionCount", [e, "pending"], r);
4522
+ return parseInt(t ?? "0x0", 16);
4523
+ }
4524
+ async getTransactionReceipt(e, r) {
4525
+ return await this.rpcCall("eth_getTransactionReceipt", [e], r) ?? null;
4526
+ }
4527
+ async rpcRequest(e, r, t) {
4528
+ return this.rpcCall(e, r, t);
4529
+ }
4530
+ async prepare(e, r) {
4531
+ let t;
4532
+ switch (e) {
4533
+ case "sign":
4534
+ case "send":
4535
+ if (!r.tx) throw new m(p.TX_INVALID_PARAMS, "prepare: tx is required");
4536
+ t = { unsignedTx: this.buildUnsignedTx(r.tx) };
4537
+ break;
4538
+ case "sign-message":
4539
+ if (!r.message) throw new m(p.TX_INVALID_PARAMS, "prepare: message is required");
4540
+ t = { message: r.message }, r.from && (t.from = r.from);
4541
+ break;
4542
+ case "sign-typed-data":
4543
+ if (!r.typedData) throw new m(p.TX_INVALID_PARAMS, "prepare: typedData is required");
4544
+ t = { typedData: r.typedData }, r.from && (t.from = r.from);
4545
+ break;
4546
+ }
4547
+ const n = { action: e, params: t }, o = await this.request("POST", "/mnemonic/prepare", n);
4548
+ return { uuid: o.uuid, expiresAt: o.expiresAt };
4549
+ }
4550
+ async signMessage(e, r, t, n, o, i) {
4551
+ const a = { message: t };
4552
+ o && (a.uuid = o), i && (a.from = i);
4553
+ const c = await this.request("POST", "/mnemonic/sign-message", a);
4554
+ return { chainId: r, signature: c.signature, format: "hex" };
4555
+ }
4556
+ async signTypedData(e, r, t, n, o, i) {
4557
+ const a = { typedData: t };
4558
+ o && (a.uuid = o), i && (a.from = i);
4559
+ const c = await this.request("POST", "/mnemonic/sign-typed-data", a);
4560
+ return { chainId: r, signature: c.signature, format: "hex" };
4561
+ }
4562
+ buildUnsignedTx(e) {
4563
+ return {
4564
+ from: e.from,
4565
+ to: e.to,
4566
+ value: e.value,
4567
+ data: e.data,
4568
+ nonce: e.nonce !== void 0 ? `0x${e.nonce.toString(16)}` : void 0,
4569
+ gasLimit: e.gasLimit,
4570
+ gasPrice: e.gasPrice,
4571
+ maxFeePerGas: e.maxFeePerGas,
4572
+ maxPriorityFeePerGas: e.maxPriorityFeePerGas,
4573
+ chainId: e.chainId !== void 0 ? `0x${e.chainId.toString(16)}` : void 0
4574
+ };
4575
+ }
4576
+ async signTransaction(e, r, t, n, o) {
4577
+ const i = { unsignedTx: this.buildUnsignedTx(t) };
4578
+ o && (i.uuid = o);
4579
+ const a = await this.request(
4580
+ "POST",
4581
+ `/mnemonic/sign/${encodeURIComponent(r)}`,
4582
+ i
4583
+ );
4584
+ return { chainId: r, signature: a.signedTx, txHash: a.txHash, format: "hex" };
4585
+ }
4586
+ async sendTransaction(e, r, t, n) {
4587
+ const o = {
4588
+ unsignedTx: this.buildUnsignedTx(t)
4589
+ };
4590
+ return n && (o.uuid = n), { txHash: (await this.request(
4591
+ "POST",
4592
+ `/mnemonic/send/${encodeURIComponent(r)}`,
4593
+ o
4594
+ )).txHash };
4595
+ }
4596
+ async withdraw(e) {
4597
+ const r = { confirmation: e };
4598
+ if (!(await this.request("POST", "/mnemonic/withdraw", r)).success)
4599
+ throw new m(p.UNKNOWN_ERROR, "Wallet withdrawal failed");
4600
+ }
4601
+ async recoverWallet(e, r) {
4602
+ const t = { shareC: r }, n = await this.request(
4603
+ "POST",
4604
+ "/mnemonic/recover",
4605
+ t
4606
+ );
4607
+ return {
4608
+ id: e,
4609
+ address: n.address,
4610
+ newShareC: n.newShareC,
4611
+ derivationPath: "m/44'/60'/0'/0/0",
4612
+ createdAt: Date.now()
4613
+ };
4614
+ }
4615
+ async migrateWallet(e, r) {
4616
+ g.log("[CROSSx][Migration Phase 4] POST /mnemonic/migrate 호출 — sub:", r);
4617
+ const t = { pin: e, sub: r }, n = await this.request(
4618
+ "POST",
4619
+ "/mnemonic/migrate",
4620
+ t
4621
+ );
4622
+ return g.log("[CROSSx][Migration Phase 4] /mnemonic/migrate 완료 — address:", n.address), {
4623
+ id: r,
4624
+ address: n.address,
4625
+ derivationPath: "m/44'/60'/0'/0/0",
4626
+ createdAt: Date.now()
4627
+ };
4628
+ }
4629
+ static mapGatewayError(e) {
4630
+ switch (e) {
4631
+ case -10002:
4632
+ return p.AUTH_NOT_AUTHENTICATED;
4633
+ case -10001:
4634
+ case -10009:
4635
+ return p.UNKNOWN_ERROR;
4636
+ case -10006:
4637
+ return p.GATEWAY_INTERNAL_ERROR;
4638
+ case -10008:
4639
+ return p.GATEWAY_LOCK_CONFLICT;
4640
+ case -10010:
4641
+ return p.MIGRATION_FAILED;
4642
+ case -10012:
4643
+ return p.MIGRATION_BACKUP_EXISTS;
4644
+ case -10022:
4645
+ return p.PROJECT_NOT_REGISTERED;
4646
+ case -10023:
4647
+ return p.PROJECT_ID_MISSING;
4648
+ case -10024:
4649
+ return p.ORIGIN_OR_APP_ID_MISSING;
4650
+ case -10025:
4651
+ return p.INVALID_APP_TYPE;
4652
+ case -10014:
4653
+ case -10015:
4654
+ case -10019:
4655
+ return p.PREPARE_FAILED;
4656
+ case -10016:
4657
+ return p.PREPARE_EXPIRED;
4658
+ case -10017:
4659
+ case -10018:
4660
+ return p.PREPARE_MISMATCH;
4661
+ default:
4662
+ return p.UNKNOWN_ERROR;
4663
+ }
4664
+ }
4665
+ static getGatewayErrorMessage(e, r) {
4666
+ switch (e) {
4667
+ case -10002:
4668
+ return "Session expired. Please sign in again.";
4669
+ case -10006:
4670
+ return "Internal server error. Please try again later.";
4671
+ case -10008:
4672
+ return "Another operation is in progress. Please try again later.";
4673
+ case -10022:
4674
+ return "This project or origin is not registered. Check your projectId and allowed origins in the management console.";
4675
+ case -10023:
4676
+ return "Project ID is required. Set the projectId field in SDKConfig.";
4677
+ case -10024:
4678
+ return "Origin or App ID is required. Web requests need a valid Origin; native apps need appId and appType in SDKConfig.";
4679
+ case -10025:
4680
+ return 'Invalid app type. appType must be "ios" or "android".';
4681
+ default:
4682
+ return `Request failed (${e}): ${r}`;
4683
+ }
4684
+ }
4685
+ }
4686
+ class sn {
4687
+ constructor() {
4688
+ this._accessToken = null;
4689
+ }
4690
+ set(e) {
4691
+ this._accessToken = e;
4692
+ }
4693
+ get() {
4694
+ return this._accessToken;
4695
+ }
4696
+ clear() {
4697
+ this._accessToken = null;
4698
+ }
4699
+ has() {
4700
+ return this._accessToken !== null;
4701
+ }
4702
+ }
4703
+ const nn = "https://cross-wallet-oauth.crosstoken.io", on = "https://cross-auth.crosstoken.io", an = "https://embedded-wallet-gateway.crosstoken.io/api/v1";
4704
+ function cn() {
4705
+ return nn;
4706
+ }
4707
+ function ln() {
4708
+ return on;
4709
+ }
4710
+ function dn() {
4711
+ return an;
4712
+ }
4713
+ function fn(s) {
4714
+ s.debug;
4715
+ const e = cn(), r = ln(), t = dn(), n = {
4716
+ ...s,
4717
+ oauthServiceUrl: e,
4718
+ authApiUrl: r,
4719
+ walletGatewayUrl: t
4720
+ }, o = new Kr(), i = new Js(), a = new tn(), c = new lt(), l = new sn();
4721
+ let d;
4722
+ return s.useMockWallet ? (g.log("[CROSSx] Mock Wallet Provider 사용"), d = new rn(o)) : (g.log("[CROSSx] Remote Wallet Provider 사용"), d = new Ue(
4723
+ {
4724
+ gatewayUrl: t,
4725
+ projectId: s.projectId,
4726
+ appId: s.appId,
4727
+ appType: s.appType
4728
+ },
4729
+ o,
4730
+ a,
4731
+ l
4732
+ )), new Ye(
4733
+ n,
4734
+ o,
4735
+ i,
4736
+ a,
4737
+ c,
4738
+ d,
4739
+ l
4740
+ );
4741
+ }
4742
+ const gn = {
4743
+ // ─── CROSS ────────────────────────────────────────────
4744
+ CROSS_MAINNET: "eip155:612055",
4745
+ CROSS_TESTNET: "eip155:612044",
4746
+ // ─── Ethereum ─────────────────────────────────────────
4747
+ ETHEREUM_MAINNET: "eip155:1",
4748
+ ETHEREUM_SEPOLIA: "eip155:11155111",
4749
+ ETHEREUM_HOLESKY: "eip155:17000",
4750
+ // ─── Polygon ──────────────────────────────────────────
4751
+ POLYGON_MAINNET: "eip155:137",
4752
+ POLYGON_AMOY: "eip155:80002",
4753
+ // ─── BNB Smart Chain ──────────────────────────────────
4754
+ BSC_MAINNET: "eip155:56",
4755
+ BSC_TESTNET: "eip155:97",
4756
+ // ─── Arbitrum ─────────────────────────────────────────
4757
+ ARBITRUM_ONE: "eip155:42161",
4758
+ ARBITRUM_SEPOLIA: "eip155:421614",
4759
+ // ─── Optimism ─────────────────────────────────────────
4760
+ OPTIMISM_MAINNET: "eip155:10",
4761
+ OPTIMISM_SEPOLIA: "eip155:11155420",
4762
+ // ─── Base ─────────────────────────────────────────────
4763
+ BASE_MAINNET: "eip155:8453",
4764
+ BASE_SEPOLIA: "eip155:84532"
4765
+ };
4766
+ export {
4767
+ m as CROSSxError,
4768
+ fr as CROSSxEthereumProvider,
4769
+ Ye as CROSSxSDK,
4770
+ gn as ChainId,
4771
+ p as ErrorCode,
4772
+ fn as createCROSSxSDK
4773
+ };