@coinlist-co/react 0.6.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/{chunk-5C4TEVM7.js → chunk-7BJ2HAG7.js} +62 -92
  2. package/dist/chunk-7BJ2HAG7.js.map +1 -0
  3. package/dist/{chunk-5E3P7AMH.js → chunk-AAER5LOL.js} +3 -1
  4. package/dist/chunk-AAER5LOL.js.map +1 -0
  5. package/dist/chunk-GSSAB4K5.js +644 -0
  6. package/dist/chunk-GSSAB4K5.js.map +1 -0
  7. package/dist/chunk-TUZKKFNW.js +836 -0
  8. package/dist/chunk-TUZKKFNW.js.map +1 -0
  9. package/dist/client/index.cjs +3203 -412
  10. package/dist/client/index.cjs.map +1 -1
  11. package/dist/client/index.d.cts +996 -41
  12. package/dist/client/index.d.ts +996 -41
  13. package/dist/client/index.js +2069 -208
  14. package/dist/client/index.js.map +1 -1
  15. package/dist/collections-CJ24dOda.d.cts +28 -0
  16. package/dist/collections-ZYLKp8JB.d.ts +28 -0
  17. package/dist/requirement-CDi5NJI8.d.cts +1036 -0
  18. package/dist/requirement-CDi5NJI8.d.ts +1036 -0
  19. package/dist/server/index.cjs +588 -85
  20. package/dist/server/index.cjs.map +1 -1
  21. package/dist/server/index.d.cts +117 -17
  22. package/dist/server/index.d.ts +117 -17
  23. package/dist/server/index.js +92 -40
  24. package/dist/server/index.js.map +1 -1
  25. package/dist/shared/index.cjs +1334 -91
  26. package/dist/shared/index.cjs.map +1 -1
  27. package/dist/shared/index.d.cts +624 -3
  28. package/dist/shared/index.d.ts +624 -3
  29. package/dist/shared/index.js +220 -5
  30. package/dist/shared/index.js.map +1 -1
  31. package/package.json +7 -3
  32. package/dist/chunk-5C4TEVM7.js.map +0 -1
  33. package/dist/chunk-5E3P7AMH.js.map +0 -1
  34. package/dist/chunk-7SB2GKEU.js +0 -311
  35. package/dist/chunk-7SB2GKEU.js.map +0 -1
  36. package/dist/chunk-UEJVCU2J.js +0 -43
  37. package/dist/chunk-UEJVCU2J.js.map +0 -1
  38. package/dist/requirement-Dk6nYN1c.d.cts +0 -389
  39. package/dist/requirement-Dk6nYN1c.d.ts +0 -389
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  API_VERSION,
3
- Attributes,
4
3
  AuthenticatedApiClient,
5
4
  COINLIST_BASE_URL,
6
5
  HEADER_USER_AGENT,
@@ -13,25 +12,47 @@ import {
13
12
  VERIFY_IDENTITY_SOURCE_OF_FUNDS_PATH,
14
13
  VERIFY_IDENTITY_VERIFIED_PATH,
15
14
  WALLET_PATH,
16
- createParticipation,
15
+ createKycToken,
17
16
  fetchOfferDetails,
18
17
  fetchOfferRequirements,
19
18
  fetchOffers,
20
19
  fetchOffersPage,
21
- fetchParticipation,
22
- fetchParticipations,
23
- fetchParticipationsPage,
24
- fetchRequirementStatuses
25
- } from "../chunk-5C4TEVM7.js";
20
+ fetchPii,
21
+ fetchRequirementStatuses,
22
+ submitDocument
23
+ } from "../chunk-7BJ2HAG7.js";
26
24
  import {
27
25
  AuthorizationCode,
28
26
  CodeVerifier,
29
- generatePKCEParams
30
- } from "../chunk-UEJVCU2J.js";
27
+ ERC20_ABI,
28
+ SUPERSTATE_SWAP_ABI,
29
+ SWAP_POLL_INTERVAL_MS,
30
+ SwapQuote,
31
+ TOKEN_REGISTRY,
32
+ computePrice,
33
+ computeSlip,
34
+ decodeSwappedOutputAmount,
35
+ generatePKCEParams,
36
+ isStopped,
37
+ shortenAddress
38
+ } from "../chunk-GSSAB4K5.js";
31
39
  import {
40
+ Attributes,
41
+ Blockchain,
42
+ BlockchainAmount,
43
+ Erc20NamespaceImpl,
44
+ KycToken,
32
45
  NotAuthenticatedError,
33
- getUUIDv4
34
- } from "../chunk-7SB2GKEU.js";
46
+ OfferOptionAddressId,
47
+ SwapNamespaceImpl,
48
+ TokenSaleNamespaceImpl,
49
+ WalletAddress,
50
+ connectExternalWallet,
51
+ createWalletOwnershipChallenge,
52
+ getUUIDv4,
53
+ listOptionAddresses,
54
+ removeOptionAddress
55
+ } from "../chunk-TUZKKFNW.js";
35
56
 
36
57
  // src/client/CoinListProvider.tsx
37
58
  import {
@@ -41,36 +62,6 @@ import {
41
62
  useState
42
63
  } from "react";
43
64
 
44
- // src/client/generated/sdk-styles.gen.ts
45
- var sdkStyles = '/*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-ease:initial;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}@layer theme{:root,:host{--clcosdk-color-red-400:oklch(70.4% .191 22.216);--clcosdk-color-red-500:oklch(63.7% .237 25.331);--clcosdk-color-amber-500:oklch(76.9% .188 70.08);--clcosdk-color-gray-400:oklch(70.7% .022 261.325);--clcosdk-color-gray-500:oklch(55.1% .027 264.364);--clcosdk-spacing:.25rem;--clcosdk-container-md:28rem;--clcosdk-text-xs:.75rem;--clcosdk-text-xs--line-height:calc(1 / .75);--clcosdk-text-sm:.875rem;--clcosdk-text-sm--line-height:calc(1.25 / .875);--clcosdk-text-base:1rem;--clcosdk-text-base--line-height:calc(1.5 / 1);--clcosdk-font-weight-normal:400;--clcosdk-font-weight-medium:500;--clcosdk-font-weight-semibold:600;--clcosdk-radius-md:.375rem;--clcosdk-radius-lg:.5rem;--clcosdk-radius-2xl:1rem;--clcosdk-ease-in-out:cubic-bezier(.4, 0, .2, 1);--clcosdk-animate-spin:spin 1s linear infinite;--clcosdk-color-brand-primary:var(--color-brand-primary)}}@layer base{.clco-sdk-root{--color-brand-primary:#171717;--color-brand-primary-hover:#000;--color-brand-primary-active:#262626;--color-accent:#2b3a67;--color-accent-hover:#243057;--color-accent-active:#1d2647;--color-accent-focus:#c7d2fe;--color-accent-subtle:#eef1f8;--color-text-primary:#171717;--color-text-secondary:#8c8c8c;--color-text-disabled:#d1d1d1;--color-text-inverse:#fff;--color-background:#fff;--color-surface:#fafafa;--color-section:#f3f3f3;--color-border:#e5e5e5;--color-divider:#ececec;--color-overlay:#00000080;--color-positive:#15803d;--color-positive-subtle:#dcfce7;--color-negative:#dc2626;--color-negative-subtle:#fee2e2;--color-success:#2c8c5e;--color-success-subtle:#e6f4ec;--color-success-border:#cfe9db;--color-warning:#e08a1a;--color-warning-subtle:#fff7ed;--color-warning-border:#fdead7;--color-error:#b42318;--color-error-subtle:#feeceb;--color-error-border:#fbd5d2}@media (prefers-color-scheme:dark){.clco-sdk-root:not(:where(.light,.light *)){--color-brand-primary:#f4f4f5;--color-brand-primary-hover:#fff;--color-brand-primary-active:#e4e4e7;--color-accent:#6f82c9;--color-accent-hover:#8799e4;--color-accent-active:#5b6fcf;--color-accent-focus:#6f82c959;--color-accent-subtle:#6f82c91f;--color-text-primary:#f4f4f5;--color-text-secondary:#a1a1aa;--color-text-disabled:#71717a;--color-text-inverse:#171717;--color-background:#0f1115;--color-surface:#161a20;--color-section:#20242c;--color-border:#2a2e35;--color-divider:#323741;--color-overlay:#000000b3;--color-positive:#22c55e;--color-positive-subtle:#22c55e1f;--color-negative:#ef4444;--color-negative-subtle:#ef44441f;--color-success:#34d399;--color-success-subtle:#34d3991f;--color-success-border:#34d39940;--color-warning:#f59e0b;--color-warning-subtle:#f59e0b1f;--color-warning-border:#f59e0b40;--color-error:#f87171;--color-error-subtle:#f871711f;--color-error-border:#f8717140}}:where(.dark,.dark *) .clco-sdk-root{--color-brand-primary:#f4f4f5;--color-brand-primary-hover:#fff;--color-brand-primary-active:#e4e4e7;--color-accent:#6f82c9;--color-accent-hover:#8799e4;--color-accent-active:#5b6fcf;--color-accent-focus:#6f82c959;--color-accent-subtle:#6f82c91f;--color-text-primary:#f4f4f5;--color-text-secondary:#a1a1aa;--color-text-disabled:#71717a;--color-text-inverse:#171717;--color-background:#0f1115;--color-surface:#161a20;--color-section:#20242c;--color-border:#2a2e35;--color-divider:#323741;--color-overlay:#000000b3;--color-positive:#22c55e;--color-positive-subtle:#22c55e1f;--color-negative:#ef4444;--color-negative-subtle:#ef44441f;--color-success:#34d399;--color-success-subtle:#34d3991f;--color-success-border:#34d39940;--color-warning:#f59e0b;--color-warning-subtle:#f59e0b1f;--color-warning-border:#f59e0b40;--color-error:#f87171;--color-error-subtle:#f871711f;--color-error-border:#f8717140}.clco-sdk-root{color:var(--color-text-primary);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:Inter,sans-serif}.clco-sdk-root *,.clco-sdk-root :before,.clco-sdk-root :after{box-sizing:border-box}.clco-sdk-root button{appearance:none;cursor:pointer;font:inherit;color:inherit;background:0 0;border:none;padding:0}.clco-sdk-root a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}.clco-sdk-root ul,.clco-sdk-root ol{margin:0;padding:0;list-style:none}.clco-sdk-root img,.clco-sdk-root svg{max-width:100%;display:block}}@layer components;@layer utilities{.clcosdk\\:absolute{position:absolute}.clcosdk\\:relative{position:relative}.clcosdk\\:inset-0{inset:calc(var(--clcosdk-spacing) * 0)}.clcosdk\\:top-4{top:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:right-4{right:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:mt-4{margin-top:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:mb-6{margin-bottom:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:flex{display:flex}.clcosdk\\:grid{display:grid}.clcosdk\\:inline-flex{display:inline-flex}.clcosdk\\:h-3{height:calc(var(--clcosdk-spacing) * 3)}.clcosdk\\:h-4{height:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:h-5{height:calc(var(--clcosdk-spacing) * 5)}.clcosdk\\:h-6{height:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:h-9{height:calc(var(--clcosdk-spacing) * 9)}.clcosdk\\:h-11{height:calc(var(--clcosdk-spacing) * 11)}.clcosdk\\:h-12{height:calc(var(--clcosdk-spacing) * 12)}.clcosdk\\:h-14{height:calc(var(--clcosdk-spacing) * 14)}.clcosdk\\:h-28{height:calc(var(--clcosdk-spacing) * 28)}.clcosdk\\:h-52{height:calc(var(--clcosdk-spacing) * 52)}.clcosdk\\:h-\\[18px\\]{height:18px}.clcosdk\\:h-auto{height:auto}.clcosdk\\:h-full{height:100%}.clcosdk\\:min-h-0{min-height:calc(var(--clcosdk-spacing) * 0)}.clcosdk\\:min-h-40{min-height:calc(var(--clcosdk-spacing) * 40)}.clcosdk\\:min-h-\\[2\\.4rem\\]{min-height:2.4rem}.clcosdk\\:w-4{width:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:w-5{width:calc(var(--clcosdk-spacing) * 5)}.clcosdk\\:w-6{width:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:w-12{width:calc(var(--clcosdk-spacing) * 12)}.clcosdk\\:w-16{width:calc(var(--clcosdk-spacing) * 16)}.clcosdk\\:w-28{width:calc(var(--clcosdk-spacing) * 28)}.clcosdk\\:w-80{width:calc(var(--clcosdk-spacing) * 80)}.clcosdk\\:w-96{width:calc(var(--clcosdk-spacing) * 96)}.clcosdk\\:w-\\[16px\\]{width:16px}.clcosdk\\:w-\\[448px\\]{width:448px}.clcosdk\\:w-auto{width:auto}.clcosdk\\:w-full{width:100%}.clcosdk\\:max-w-\\[22rem\\]{max-width:22rem}.clcosdk\\:max-w-\\[28rem\\]{max-width:28rem}.clcosdk\\:max-w-\\[30rem\\]{max-width:30rem}.clcosdk\\:max-w-\\[1200px\\]{max-width:1200px}.clcosdk\\:max-w-md{max-width:var(--clcosdk-container-md)}.clcosdk\\:shrink-0{flex-shrink:0}.clcosdk\\:rotate-90{rotate:90deg}.clcosdk\\:animate-spin{animation:var(--clcosdk-animate-spin)}.clcosdk\\:cursor-pointer{cursor:pointer}.clcosdk\\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.clcosdk\\:grid-rows-\\[0fr\\]{grid-template-rows:0fr}.clcosdk\\:grid-rows-\\[1fr\\]{grid-template-rows:1fr}.clcosdk\\:flex-col{flex-direction:column}.clcosdk\\:flex-wrap{flex-wrap:wrap}.clcosdk\\:items-center{align-items:center}.clcosdk\\:items-start{align-items:flex-start}.clcosdk\\:justify-between{justify-content:space-between}.clcosdk\\:justify-center{justify-content:center}.clcosdk\\:gap-1{gap:calc(var(--clcosdk-spacing) * 1)}.clcosdk\\:gap-2{gap:calc(var(--clcosdk-spacing) * 2)}.clcosdk\\:gap-3{gap:calc(var(--clcosdk-spacing) * 3)}.clcosdk\\:gap-4{gap:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:gap-5{gap:calc(var(--clcosdk-spacing) * 5)}.clcosdk\\:gap-6{gap:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:gap-8{gap:calc(var(--clcosdk-spacing) * 8)}.clcosdk\\:gap-\\[5px\\]{gap:5px}:where(.clcosdk\\:space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--clcosdk-spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--clcosdk-spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.clcosdk\\:space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--clcosdk-spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--clcosdk-spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.clcosdk\\:divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.clcosdk\\:divide-border>:not(:last-child)){border-color:var(--color-border)}:where(.clcosdk\\:divide-divider>:not(:last-child)){border-color:var(--color-divider)}.clcosdk\\:overflow-hidden{overflow:hidden}.clcosdk\\:rounded-2xl{border-radius:var(--clcosdk-radius-2xl)}.clcosdk\\:rounded-btn{border-radius:12px}.clcosdk\\:rounded-card{border-radius:24px}.clcosdk\\:rounded-full{border-radius:3.40282e38px}.clcosdk\\:rounded-lg{border-radius:var(--clcosdk-radius-lg)}.clcosdk\\:rounded-md{border-radius:var(--clcosdk-radius-md)}.clcosdk\\:border{border-style:var(--tw-border-style);border-width:1px}.clcosdk\\:border-2{border-style:var(--tw-border-style);border-width:2px}.clcosdk\\:border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.clcosdk\\:border-dashed{--tw-border-style:dashed;border-style:dashed}.clcosdk\\:border-accent\\/50{border-color:var(--color-accent)}@supports (color:color-mix(in lab, red, red)){.clcosdk\\:border-accent\\/50{border-color:color-mix(in oklab, var(--color-accent) 50%, transparent)}}.clcosdk\\:border-accent\\/60{border-color:var(--color-accent)}@supports (color:color-mix(in lab, red, red)){.clcosdk\\:border-accent\\/60{border-color:color-mix(in oklab, var(--color-accent) 60%, transparent)}}.clcosdk\\:border-amber-500{border-color:var(--clcosdk-color-amber-500)}.clcosdk\\:border-border,.clcosdk\\:border-border\\/60{border-color:var(--color-border)}@supports (color:color-mix(in lab, red, red)){.clcosdk\\:border-border\\/60{border-color:color-mix(in oklab, var(--color-border) 60%, transparent)}}.clcosdk\\:border-current{border-color:currentColor}.clcosdk\\:border-divider{border-color:var(--color-divider)}.clcosdk\\:border-error-border{border-color:var(--color-error-border)}.clcosdk\\:border-success-border{border-color:var(--color-success-border)}.clcosdk\\:border-warning-border{border-color:var(--color-warning-border)}.clcosdk\\:border-t-transparent{border-top-color:#0000}.clcosdk\\:bg-accent\\/10{background-color:var(--color-accent)}@supports (color:color-mix(in lab, red, red)){.clcosdk\\:bg-accent\\/10{background-color:color-mix(in oklab, var(--color-accent) 10%, transparent)}}.clcosdk\\:bg-background{background-color:var(--color-background)}.clcosdk\\:bg-brand-primary{background-color:var(--color-brand-primary)}.clcosdk\\:bg-error-subtle{background-color:var(--color-error-subtle)}.clcosdk\\:bg-section{background-color:var(--color-section)}.clcosdk\\:bg-success-subtle{background-color:var(--color-success-subtle)}.clcosdk\\:bg-surface{background-color:var(--color-surface)}.clcosdk\\:bg-transparent{background-color:#0000}.clcosdk\\:bg-warning-subtle{background-color:var(--color-warning-subtle)}.clcosdk\\:bg-gradient-to-b{--tw-gradient-position:to bottom in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.clcosdk\\:bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.clcosdk\\:from-surface{--tw-gradient-from:var(--color-surface);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.clcosdk\\:from-transparent{--tw-gradient-from:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.clcosdk\\:via-section{--tw-gradient-via:var(--color-section);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.clcosdk\\:via-transparent{--tw-gradient-via:transparent;--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.clcosdk\\:to-background{--tw-gradient-to:var(--color-background);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.clcosdk\\:to-overlay\\/35{--tw-gradient-to:var(--color-overlay)}@supports (color:color-mix(in lab, red, red)){.clcosdk\\:to-overlay\\/35{--tw-gradient-to:color-mix(in oklab, var(--color-overlay) 35%, transparent)}}.clcosdk\\:to-overlay\\/35{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.clcosdk\\:object-cover{object-fit:cover}.clcosdk\\:p-0{padding:calc(var(--clcosdk-spacing) * 0)}.clcosdk\\:p-1\\.5{padding:calc(var(--clcosdk-spacing) * 1.5)}.clcosdk\\:p-3{padding:calc(var(--clcosdk-spacing) * 3)}.clcosdk\\:p-6{padding:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:p-8{padding:calc(var(--clcosdk-spacing) * 8)}.clcosdk\\:px-2{padding-inline:calc(var(--clcosdk-spacing) * 2)}.clcosdk\\:px-4{padding-inline:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:px-5{padding-inline:calc(var(--clcosdk-spacing) * 5)}.clcosdk\\:px-6{padding-inline:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:pt-4{padding-top:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:pb-4{padding-bottom:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:text-center{text-align:center}.clcosdk\\:text-left{text-align:left}.clcosdk\\:text-base{font-size:var(--clcosdk-text-base);line-height:var(--tw-leading,var(--clcosdk-text-base--line-height))}.clcosdk\\:text-sm{font-size:var(--clcosdk-text-sm);line-height:var(--tw-leading,var(--clcosdk-text-sm--line-height))}.clcosdk\\:text-xs{font-size:var(--clcosdk-text-xs);line-height:var(--tw-leading,var(--clcosdk-text-xs--line-height))}.clcosdk\\:text-\\[11px\\]{font-size:11px}.clcosdk\\:text-\\[12px\\]{font-size:12px}.clcosdk\\:text-\\[14px\\]{font-size:14px}.clcosdk\\:text-\\[16px\\]{font-size:16px}.clcosdk\\:text-\\[18px\\]{font-size:18px}.clcosdk\\:text-\\[22px\\]{font-size:22px}.clcosdk\\:text-\\[28px\\]{font-size:28px}.clcosdk\\:text-\\[36px\\]{font-size:36px}.clcosdk\\:text-\\[48px\\]{font-size:48px}.clcosdk\\:text-\\[64px\\]{font-size:64px}.clcosdk\\:leading-\\[110\\%\\]{--tw-leading:110%;line-height:110%}.clcosdk\\:leading-\\[120\\%\\]{--tw-leading:120%;line-height:120%}.clcosdk\\:leading-\\[125\\%\\]{--tw-leading:125%;line-height:125%}.clcosdk\\:leading-\\[130\\%\\]{--tw-leading:130%;line-height:130%}.clcosdk\\:leading-\\[135\\%\\]{--tw-leading:135%;line-height:135%}.clcosdk\\:leading-\\[140\\%\\]{--tw-leading:140%;line-height:140%}.clcosdk\\:leading-\\[150\\%\\]{--tw-leading:150%;line-height:150%}.clcosdk\\:font-medium{--tw-font-weight:var(--clcosdk-font-weight-medium);font-weight:var(--clcosdk-font-weight-medium)}.clcosdk\\:font-normal{--tw-font-weight:var(--clcosdk-font-weight-normal);font-weight:var(--clcosdk-font-weight-normal)}.clcosdk\\:font-semibold{--tw-font-weight:var(--clcosdk-font-weight-semibold);font-weight:var(--clcosdk-font-weight-semibold)}.clcosdk\\:tracking-\\[0\\.12px\\]{--tw-tracking:.12px;letter-spacing:.12px}.clcosdk\\:tracking-\\[0\\.28px\\]{--tw-tracking:.28px;letter-spacing:.28px}.clcosdk\\:whitespace-nowrap{white-space:nowrap}.clcosdk\\:text-error{color:var(--color-error)}.clcosdk\\:text-success{color:var(--color-success)}.clcosdk\\:text-text-inverse{color:var(--color-text-inverse)}.clcosdk\\:text-text-primary{color:var(--color-text-primary)}.clcosdk\\:text-text-secondary{color:var(--color-text-secondary)}.clcosdk\\:text-warning{color:var(--color-warning)}.clcosdk\\:capitalize{text-transform:capitalize}.clcosdk\\:underline{text-decoration-line:underline}.clcosdk\\:underline-offset-2{text-underline-offset:2px}.clcosdk\\:underline-offset-4{text-underline-offset:4px}.clcosdk\\:opacity-60{opacity:.6}.clcosdk\\:shadow-\\[0_0_0_3px_rgba\\(59\\,130\\,246\\,0\\.2\\)\\]{--tw-shadow:0 0 0 3px var(--tw-shadow-color,#3b82f633);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:shadow-\\[0_0_0_3px_rgba\\(59\\,130\\,246\\,0\\.18\\)\\]{--tw-shadow:0 0 0 3px var(--tw-shadow-color,#3b82f62e);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:shadow-\\[0_0_0_3px_rgba\\(59\\,130\\,246\\,0\\.25\\)\\]{--tw-shadow:0 0 0 3px var(--tw-shadow-color,#3b82f640);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:shadow-\\[0_10px_24px_rgba\\(0\\,0\\,0\\,0\\.18\\)\\]{--tw-shadow:0 10px 24px var(--tw-shadow-color,#0000002e);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:shadow-\\[0_10px_24px_rgba\\(0\\,0\\,0\\,0\\.25\\)\\]{--tw-shadow:0 10px 24px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:shadow-card{--tw-shadow:0px 4px 6px -2px var(--tw-shadow-color,#0000000d), 0px 12px 24px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:transition-\\[grid-template-rows\\]{transition-property:grid-template-rows;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.clcosdk\\:transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.clcosdk\\:transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.clcosdk\\:transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.clcosdk\\:duration-200{--tw-duration:.2s;transition-duration:.2s}.clcosdk\\:duration-300{--tw-duration:.3s;transition-duration:.3s}.clcosdk\\:ease-in-out{--tw-ease:var(--clcosdk-ease-in-out);transition-timing-function:var(--clcosdk-ease-in-out)}@media (hover:hover){.clcosdk\\:hover\\:-translate-y-0\\.5:hover{--tw-translate-y:calc(var(--clcosdk-spacing) * -.5);translate:var(--tw-translate-x) var(--tw-translate-y)}.clcosdk\\:hover\\:border-divider:hover{border-color:var(--color-divider)}.clcosdk\\:hover\\:bg-\\[\\#fcdcd8\\]:hover{background-color:#fcdcd8}.clcosdk\\:hover\\:bg-border:hover{background-color:var(--color-border)}.clcosdk\\:hover\\:bg-brand-primary:hover{background-color:var(--color-brand-primary)}.clcosdk\\:hover\\:bg-brand-primary-hover:hover{background-color:var(--color-brand-primary-hover)}.clcosdk\\:hover\\:bg-section:hover{background-color:var(--color-section)}.clcosdk\\:hover\\:bg-surface:hover{background-color:var(--color-surface)}.clcosdk\\:hover\\:text-\\[\\#8b1a13\\]:hover{color:#8b1a13}.clcosdk\\:hover\\:text-text-primary:hover{color:var(--color-text-primary)}.clcosdk\\:hover\\:underline:hover{text-decoration-line:underline}.clcosdk\\:hover\\:shadow-\\[0px_14px_32px_-10px_rgba\\(0\\,0\\,0\\,0\\.35\\)\\]:hover{--tw-shadow:0px 14px 32px -10px var(--tw-shadow-color,#00000059);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}}.clcosdk\\:focus-visible\\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:focus-visible\\:ring-accent-focus:focus-visible{--tw-ring-color:var(--color-accent-focus)}.clcosdk\\:focus-visible\\:ring-gray-400:focus-visible{--tw-ring-color:var(--clcosdk-color-gray-400)}.clcosdk\\:focus-visible\\:ring-gray-500:focus-visible{--tw-ring-color:var(--clcosdk-color-gray-500)}.clcosdk\\:focus-visible\\:ring-red-400:focus-visible{--tw-ring-color:var(--clcosdk-color-red-400)}.clcosdk\\:focus-visible\\:ring-red-500:focus-visible{--tw-ring-color:var(--clcosdk-color-red-500)}.clcosdk\\:focus-visible\\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.clcosdk\\:focus-visible\\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.clcosdk\\:active\\:bg-\\[\\#d9d9d9\\]:active{background-color:#d9d9d9}.clcosdk\\:active\\:bg-\\[\\#f9c9c4\\]:active{background-color:#f9c9c4}.clcosdk\\:active\\:bg-border:active{background-color:var(--color-border)}.clcosdk\\:active\\:bg-brand-primary-active:active{background-color:var(--color-brand-primary-active)}.clcosdk\\:active\\:text-\\[\\#6d1510\\]:active{color:#6d1510}.clcosdk\\:disabled\\:pointer-events-none:disabled{pointer-events:none}.clcosdk\\:disabled\\:opacity-40:disabled{opacity:.4}@media (prefers-color-scheme:dark){@media (hover:hover){.clcosdk\\:dark\\:hover\\:bg-\\[rgba\\(248\\,113\\,113\\,0\\.20\\)\\]:not(:where(.light,.light *)):hover{background-color:#f8717133}}}@media (hover:hover){.clcosdk\\:dark\\:hover\\:bg-\\[rgba\\(248\\,113\\,113\\,0\\.20\\)\\]:where(.dark,.dark *):hover{background-color:#f8717133}}@media (prefers-color-scheme:dark){@media (hover:hover){.clcosdk\\:dark\\:hover\\:text-\\[\\#fca5a5\\]:not(:where(.light,.light *)):hover{color:#fca5a5}}}@media (hover:hover){.clcosdk\\:dark\\:hover\\:text-\\[\\#fca5a5\\]:where(.dark,.dark *):hover{color:#fca5a5}}@media (prefers-color-scheme:dark){.clcosdk\\:dark\\:active\\:bg-\\[rgba\\(248\\,113\\,113\\,0\\.30\\)\\]:not(:where(.light,.light *)):active{background-color:#f871714d}}.clcosdk\\:dark\\:active\\:bg-\\[rgba\\(248\\,113\\,113\\,0\\.30\\)\\]:where(.dark,.dark *):active{background-color:#f871714d}@media (prefers-color-scheme:dark){.clcosdk\\:dark\\:active\\:bg-divider:not(:where(.light,.light *)):active{background-color:var(--color-divider)}}.clcosdk\\:dark\\:active\\:bg-divider:where(.dark,.dark *):active{background-color:var(--color-divider)}@media (prefers-color-scheme:dark){.clcosdk\\:dark\\:active\\:text-\\[\\#f87171\\]:not(:where(.light,.light *)):active{color:#f87171}}.clcosdk\\:dark\\:active\\:text-\\[\\#f87171\\]:where(.dark,.dark *):active{color:#f87171}.clcosdk\\:\\[\\&_circle\\]\\:fill-error-subtle circle{fill:var(--color-error-subtle)}.clcosdk\\:\\[\\&_circle\\]\\:fill-success-subtle circle{fill:var(--color-success-subtle)}.clcosdk\\:\\[\\&_circle\\]\\:fill-warning-subtle circle{fill:var(--color-warning-subtle)}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@keyframes spin{to{transform:rotate(360deg)}}';
46
-
47
- // src/client/CoinListStyleScope.tsx
48
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
49
- function CoinListStyleScope({ children }) {
50
- return /* @__PURE__ */ jsxs(Fragment, { children: [
51
- /* @__PURE__ */ jsx("link", { rel: "preconnect", href: "https://fonts.googleapis.com" }),
52
- /* @__PURE__ */ jsx(
53
- "link",
54
- {
55
- rel: "preconnect",
56
- href: "https://fonts.gstatic.com",
57
- crossOrigin: "anonymous"
58
- }
59
- ),
60
- /* @__PURE__ */ jsx(
61
- "link",
62
- {
63
- rel: "stylesheet",
64
- href: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap"
65
- }
66
- ),
67
- /* @__PURE__ */ jsxs("div", { className: "clco-sdk-root", children: [
68
- /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: sdkStyles } }),
69
- children
70
- ] })
71
- ] });
72
- }
73
-
74
65
  // src/client/core/api/middleware/device-id.ts
75
66
  var DEVICE_ID_KEY = "coinlist.device_id";
76
67
  function getDeviceId() {
@@ -118,6 +109,383 @@ var ApiClient = class {
118
109
  }
119
110
  };
120
111
 
112
+ // src/client/core/blockchain/wallet-error.ts
113
+ import {
114
+ ContractFunctionRevertedError,
115
+ InsufficientFundsError,
116
+ UserRejectedRequestError,
117
+ WaitForTransactionReceiptTimeoutError
118
+ } from "viem";
119
+ function classifyWalletError(error, ctx) {
120
+ if (error instanceof UserRejectedRequestError) {
121
+ return { type: "user_rejected" };
122
+ }
123
+ if (error instanceof InsufficientFundsError) {
124
+ return { type: "insufficient_funds" };
125
+ }
126
+ if (error instanceof ContractFunctionRevertedError) {
127
+ return { type: "contract_reverted", reason: error.reason ?? error.message };
128
+ }
129
+ if (error instanceof WaitForTransactionReceiptTimeoutError && ctx?.hash) {
130
+ return { type: "timeout", hash: ctx.hash };
131
+ }
132
+ return { type: "unknown", cause: error };
133
+ }
134
+
135
+ // src/client/core/blockchain/erc20-approval.ts
136
+ async function submitErc20Approval(args) {
137
+ const {
138
+ wallet,
139
+ tokenAddress,
140
+ spender,
141
+ chain,
142
+ value,
143
+ pending,
144
+ confirming,
145
+ emit
146
+ } = args;
147
+ emit(pending);
148
+ let hash;
149
+ try {
150
+ hash = await wallet.writeContract({
151
+ abi: ERC20_ABI,
152
+ address: tokenAddress,
153
+ functionName: "approve",
154
+ args: [spender, value],
155
+ chain
156
+ });
157
+ } catch (error) {
158
+ return {
159
+ type: "error",
160
+ error: { step: "approval", cause: classifyWalletError(error) }
161
+ };
162
+ }
163
+ emit(confirming);
164
+ let receipt;
165
+ try {
166
+ receipt = await wallet.awaitTx(hash, chain);
167
+ } catch (error) {
168
+ return {
169
+ type: "error",
170
+ error: { step: "approval", cause: classifyWalletError(error, { hash }) }
171
+ };
172
+ }
173
+ if (receipt.status !== "success") {
174
+ return { type: "error", error: { step: "approval-reverted" } };
175
+ }
176
+ return { type: "ok", txHash: hash };
177
+ }
178
+
179
+ // src/client/core/blockchain/swap-flows.ts
180
+ async function executeSwap(params) {
181
+ const {
182
+ swap,
183
+ erc20,
184
+ wallet,
185
+ contractAddress,
186
+ chain,
187
+ inputTokenAddress,
188
+ quote,
189
+ slippageBps,
190
+ onProgress
191
+ } = params;
192
+ const emit = (phase) => onProgress?.(phase);
193
+ const inputAmount = BlockchainAmount.add(
194
+ quote.inputTokenAmount,
195
+ quote.fee
196
+ ).raw;
197
+ const minOut = computeSlip(quote.outputTokenAmount, slippageBps).raw;
198
+ emit("checking-status");
199
+ let status;
200
+ try {
201
+ status = await swap.getStatus({ contractAddress, chain });
202
+ } catch {
203
+ return { type: "error", error: { step: "status-check" } };
204
+ }
205
+ if (isStopped(status)) {
206
+ return { type: "error", error: { step: "swap-stopped" } };
207
+ }
208
+ emit("checking-allowance");
209
+ let allowance;
210
+ try {
211
+ allowance = await erc20.getTokenAllowance({
212
+ tokenAddress: inputTokenAddress,
213
+ owner: wallet.address,
214
+ spender: contractAddress,
215
+ chain
216
+ });
217
+ } catch {
218
+ return { type: "error", error: { step: "allowance-check" } };
219
+ }
220
+ if (allowance.allowance < inputAmount) {
221
+ if (allowance.allowance > 0n) {
222
+ const reset = await submitErc20Approval({
223
+ wallet,
224
+ tokenAddress: inputTokenAddress,
225
+ spender: contractAddress,
226
+ chain,
227
+ value: 0n,
228
+ pending: "resetting-allowance",
229
+ confirming: "confirming-allowance-reset",
230
+ emit
231
+ });
232
+ if (reset.type === "error") return { type: "error", error: reset.error };
233
+ }
234
+ const approve = await submitErc20Approval({
235
+ wallet,
236
+ tokenAddress: inputTokenAddress,
237
+ spender: contractAddress,
238
+ chain,
239
+ value: inputAmount,
240
+ pending: "approving",
241
+ confirming: "confirming-approval",
242
+ emit
243
+ });
244
+ if (approve.type === "error")
245
+ return { type: "error", error: approve.error };
246
+ }
247
+ emit("swapping");
248
+ let swapTxHash;
249
+ try {
250
+ swapTxHash = await wallet.writeContract({
251
+ abi: SUPERSTATE_SWAP_ABI,
252
+ address: contractAddress,
253
+ functionName: "swap",
254
+ args: [inputTokenAddress, inputAmount, minOut],
255
+ chain
256
+ });
257
+ } catch (error) {
258
+ return {
259
+ type: "error",
260
+ error: { step: "swap", cause: classifyWalletError(error) }
261
+ };
262
+ }
263
+ emit("confirming-swap");
264
+ let receipt;
265
+ try {
266
+ receipt = await wallet.awaitTx(swapTxHash, chain);
267
+ } catch (error) {
268
+ return {
269
+ type: "error",
270
+ error: {
271
+ step: "swap",
272
+ cause: classifyWalletError(error, { hash: swapTxHash })
273
+ }
274
+ };
275
+ }
276
+ if (receipt.status !== "success") {
277
+ return { type: "error", error: { step: "swap-reverted" } };
278
+ }
279
+ const outputAmount = decodeSwappedOutputAmount(receipt, quote.outputTokenAmount.decimals) ?? quote.outputTokenAmount;
280
+ const finalQuote = { ...quote, outputTokenAmount: outputAmount };
281
+ return {
282
+ type: "success",
283
+ swapTxHash,
284
+ inputAmount: finalQuote.inputTokenAmount,
285
+ fee: finalQuote.fee,
286
+ outputAmount,
287
+ pricePerShare: computePrice(finalQuote),
288
+ recipientAddress: wallet.address
289
+ };
290
+ }
291
+ async function authorizeWallet(params) {
292
+ const { swap, wallet, offerId, contractAddress, chain, onProgress } = params;
293
+ const emit = (phase) => onProgress?.(phase);
294
+ const walletAddress = wallet.address;
295
+ emit("checking-authorization");
296
+ let auth;
297
+ try {
298
+ auth = await swap.getAuthorization({
299
+ walletAddress,
300
+ contractAddress,
301
+ chain
302
+ });
303
+ } catch {
304
+ return { type: "error", error: { step: "authorization-check" } };
305
+ }
306
+ if (auth.authorized) return { type: "success" };
307
+ emit("requesting-challenge");
308
+ let challenge;
309
+ try {
310
+ challenge = await swap.requestWalletOwnershipChallenge({
311
+ walletAddress,
312
+ chain,
313
+ challengeType: "plain"
314
+ });
315
+ } catch {
316
+ return { type: "error", error: { step: "challenge-request" } };
317
+ }
318
+ emit("signing-message");
319
+ let signature;
320
+ try {
321
+ signature = await wallet.signMessage(challenge.message);
322
+ } catch (error) {
323
+ return {
324
+ type: "error",
325
+ error: { step: "signing", cause: classifyWalletError(error) }
326
+ };
327
+ }
328
+ emit("submitting-signature");
329
+ let allow;
330
+ try {
331
+ allow = await swap.allowWallet({
332
+ offerId,
333
+ walletAddress,
334
+ chain,
335
+ signature
336
+ });
337
+ } catch {
338
+ return { type: "error", error: { step: "allow-wallet" } };
339
+ }
340
+ if (allow.action === "broadcast_transaction") {
341
+ emit("broadcasting-transaction");
342
+ let hash;
343
+ try {
344
+ hash = await wallet.broadcastRawTx({
345
+ to: allow.to,
346
+ data: allow.data,
347
+ chain
348
+ });
349
+ } catch (error) {
350
+ return {
351
+ type: "error",
352
+ error: { step: "broadcast", cause: classifyWalletError(error) }
353
+ };
354
+ }
355
+ emit("awaiting-confirmation");
356
+ try {
357
+ await wallet.awaitTx(hash, chain);
358
+ } catch (error) {
359
+ return {
360
+ type: "error",
361
+ error: {
362
+ step: "broadcast",
363
+ cause: classifyWalletError(error, { hash })
364
+ }
365
+ };
366
+ }
367
+ }
368
+ emit("verifying-authorization");
369
+ let reCheck;
370
+ try {
371
+ reCheck = await swap.getAuthorization({
372
+ walletAddress,
373
+ contractAddress,
374
+ chain
375
+ });
376
+ } catch {
377
+ return { type: "error", error: { step: "authorization-check" } };
378
+ }
379
+ if (!reCheck.authorized) {
380
+ return { type: "error", error: { step: "not-authorized" } };
381
+ }
382
+ return { type: "success" };
383
+ }
384
+
385
+ // src/client/core/client-swap-namespace.ts
386
+ var ClientSwapNamespaceImpl = class extends SwapNamespaceImpl {
387
+ constructor(ctx, erc20) {
388
+ super(ctx);
389
+ this.erc20 = erc20;
390
+ }
391
+ executeSwap(params) {
392
+ return executeSwap({ ...params, swap: this, erc20: this.erc20 });
393
+ }
394
+ authorizeWallet(params) {
395
+ return authorizeWallet({ ...params, swap: this });
396
+ }
397
+ };
398
+
399
+ // src/client/core/blockchain/token-sale-flow.ts
400
+ async function executeTokenSale(params) {
401
+ const {
402
+ erc20,
403
+ tokenSale,
404
+ wallet,
405
+ offerId,
406
+ offerOptionId,
407
+ assetId,
408
+ paymentTokenAddress,
409
+ fundingContractAddress,
410
+ chain,
411
+ amount,
412
+ onProgress
413
+ } = params;
414
+ const emit = (phase) => onProgress?.(phase);
415
+ emit("checking-allowance");
416
+ let currentAllowance;
417
+ try {
418
+ const allowance = await erc20.getTokenAllowance({
419
+ tokenAddress: paymentTokenAddress,
420
+ owner: wallet.address,
421
+ spender: fundingContractAddress,
422
+ chain
423
+ });
424
+ currentAllowance = allowance.allowance;
425
+ } catch {
426
+ return { type: "error", error: { step: "allowance-check" } };
427
+ }
428
+ if (currentAllowance > 0n) {
429
+ const reset = await submitErc20Approval({
430
+ wallet,
431
+ tokenAddress: paymentTokenAddress,
432
+ spender: fundingContractAddress,
433
+ chain,
434
+ value: 0n,
435
+ pending: "resetting-allowance",
436
+ confirming: "confirming-allowance-reset",
437
+ emit
438
+ });
439
+ if (reset.type === "error") {
440
+ return {
441
+ type: "error",
442
+ error: reset.error.step === "approval-reverted" ? { step: "allowance-reset-reverted" } : { step: "allowance-reset", cause: reset.error.cause }
443
+ };
444
+ }
445
+ }
446
+ const approve = await submitErc20Approval({
447
+ wallet,
448
+ tokenAddress: paymentTokenAddress,
449
+ spender: fundingContractAddress,
450
+ chain,
451
+ value: amount.raw,
452
+ pending: "approving",
453
+ confirming: "confirming-approval",
454
+ emit
455
+ });
456
+ if (approve.type === "error") {
457
+ return { type: "error", error: approve.error };
458
+ }
459
+ const approvalTxHash = approve.txHash;
460
+ emit("recording-participation");
461
+ let participation;
462
+ try {
463
+ participation = await tokenSale.createParticipation({
464
+ offerId,
465
+ offerOptionId,
466
+ chain: Blockchain(chain),
467
+ walletAddress: WalletAddress(wallet.address),
468
+ amount: amount.raw.toString(),
469
+ assetId,
470
+ approvalTransactionHash: approvalTxHash
471
+ });
472
+ } catch {
473
+ return { type: "error", error: { step: "participation", approvalTxHash } };
474
+ }
475
+ return { type: "success", participation, approvalTxHash };
476
+ }
477
+
478
+ // src/client/core/client-token-sale-namespace.ts
479
+ var ClientTokenSaleNamespaceImpl = class extends TokenSaleNamespaceImpl {
480
+ constructor(ctx, erc20) {
481
+ super(ctx);
482
+ this.erc20 = erc20;
483
+ }
484
+ executeTokenSale(params) {
485
+ return executeTokenSale({ ...params, erc20: this.erc20, tokenSale: this });
486
+ }
487
+ };
488
+
121
489
  // src/client/core/coinlist-client.ts
122
490
  var OAUTH_STATE_KEY = "coinlist.oauth_state";
123
491
  var OAUTH_CODE_VERIFIER_KEY = "coinlist.oauth_code_verifier";
@@ -133,6 +501,13 @@ var CoinListClientImpl = class {
133
501
  },
134
502
  this.fetchAccessToken.bind(this)
135
503
  );
504
+ const ctx = {
505
+ api: this.api,
506
+ ensureUserAuthenticated: async () => this.ensureAuthenticated()
507
+ };
508
+ this.erc20 = new Erc20NamespaceImpl(ctx);
509
+ this.tokenSale = new ClientTokenSaleNamespaceImpl(ctx, this.erc20);
510
+ this.swap = new ClientSwapNamespaceImpl(ctx, this.erc20);
136
511
  }
137
512
  async init() {
138
513
  await this.fetchAccessToken(true);
@@ -204,40 +579,56 @@ var CoinListClientImpl = class {
204
579
  }
205
580
  async fetchOffers() {
206
581
  this.ensureAuthenticated();
207
- return fetchOffers(this.api);
582
+ return fetchOffers(this.api, void 0);
208
583
  }
209
584
  async fetchOffersPage(params) {
210
585
  this.ensureAuthenticated();
211
- return fetchOffersPage(this.api, params);
586
+ return fetchOffersPage(this.api, params, void 0);
212
587
  }
213
588
  async fetchOfferDetails(id) {
214
589
  this.ensureAuthenticated();
215
- return fetchOfferDetails(this.api, id);
590
+ return fetchOfferDetails(this.api, id, void 0);
216
591
  }
217
- async fetchParticipations(offerId) {
592
+ async createWalletOwnershipChallenge(params) {
218
593
  this.ensureAuthenticated();
219
- return fetchParticipations(this.api, offerId);
594
+ return createWalletOwnershipChallenge(this.api, params);
220
595
  }
221
- async fetchParticipationsPage(params) {
596
+ async connectExternalWallet(offerId, params) {
222
597
  this.ensureAuthenticated();
223
- return fetchParticipationsPage(this.api, params);
598
+ return connectExternalWallet(this.api, offerId, params);
224
599
  }
225
- async fetchParticipation(id) {
600
+ async listOptionAddresses(offerId, offerOptionId) {
226
601
  this.ensureAuthenticated();
227
- return fetchParticipation(this.api, id);
602
+ return listOptionAddresses(
603
+ this.api,
604
+ offerId,
605
+ offerOptionId
606
+ );
228
607
  }
229
- async createParticipation(params) {
608
+ async removeOptionAddress(offerId, addressId) {
230
609
  this.ensureAuthenticated();
231
- return createParticipation(this.api, params);
610
+ return removeOptionAddress(this.api, offerId, addressId);
232
611
  }
233
612
  async fetchOfferRequirements(offerId) {
234
613
  this.ensureAuthenticated();
235
- return fetchOfferRequirements(this.api, offerId);
614
+ return fetchOfferRequirements(this.api, offerId, void 0);
236
615
  }
237
616
  async fetchRequirementStatuses(offerId) {
238
617
  this.ensureAuthenticated();
239
618
  return fetchRequirementStatuses(this.api, offerId);
240
619
  }
620
+ async fetchPii() {
621
+ this.ensureAuthenticated();
622
+ return fetchPii(this.api);
623
+ }
624
+ async submitDocument(documentType, fields) {
625
+ this.ensureAuthenticated();
626
+ return submitDocument(this.api, documentType, fields);
627
+ }
628
+ async createKycToken(levelName, reset) {
629
+ this.ensureAuthenticated();
630
+ return createKycToken(this.api, levelName, reset);
631
+ }
241
632
  handleRequirement(requirement) {
242
633
  const baseUrl = this._config.coinlistBaseUrl ?? COINLIST_BASE_URL;
243
634
  let path;
@@ -264,6 +655,9 @@ var CoinListClientImpl = class {
264
655
  case "jurisdiction":
265
656
  path = null;
266
657
  break;
658
+ case "document":
659
+ path = null;
660
+ break;
267
661
  default: {
268
662
  const _exhaustive = requirement.type;
269
663
  return;
@@ -289,7 +683,7 @@ function createCoinListClient(config) {
289
683
  }
290
684
 
291
685
  // src/client/CoinListProvider.tsx
292
- import { jsx as jsx2 } from "react/jsx-runtime";
686
+ import { jsx } from "react/jsx-runtime";
293
687
  var CoinListContext = createContext(null);
294
688
  function CoinListContextProvider({
295
689
  config,
@@ -317,10 +711,53 @@ function CoinListContextProvider({
317
711
  };
318
712
  }, [coinlist]);
319
713
  const value = useMemo(() => ({ coinlist, isReady }), [coinlist, isReady]);
320
- return /* @__PURE__ */ jsx2(CoinListContext.Provider, { value, children });
714
+ return /* @__PURE__ */ jsx(CoinListContext.Provider, { value, children });
321
715
  }
322
- function CoinListProvider({ config, children }) {
323
- return /* @__PURE__ */ jsx2(CoinListContextProvider, { config, children: /* @__PURE__ */ jsx2(CoinListStyleScope, { children }) });
716
+ var CoinListProvider = CoinListContextProvider;
717
+
718
+ // src/client/CoinListStyleScope.tsx
719
+ import { createContext as createContext2, useContext } from "react";
720
+
721
+ // src/client/generated/sdk-styles.gen.ts
722
+ var sdkStyles = '/*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-ease:initial;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}@layer theme{:root,:host{--clcosdk-font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--clcosdk-color-red-400:oklch(70.4% .191 22.216);--clcosdk-color-red-500:oklch(63.7% .237 25.331);--clcosdk-color-amber-500:oklch(76.9% .188 70.08);--clcosdk-color-gray-400:oklch(70.7% .022 261.325);--clcosdk-color-gray-500:oklch(55.1% .027 264.364);--clcosdk-color-black:#000;--clcosdk-spacing:.25rem;--clcosdk-container-md:28rem;--clcosdk-text-xs:.75rem;--clcosdk-text-xs--line-height:calc(1 / .75);--clcosdk-text-sm:.875rem;--clcosdk-text-sm--line-height:calc(1.25 / .875);--clcosdk-text-base:1rem;--clcosdk-text-base--line-height:calc(1.5 / 1);--clcosdk-font-weight-normal:400;--clcosdk-font-weight-medium:500;--clcosdk-font-weight-semibold:600;--clcosdk-radius-md:.375rem;--clcosdk-radius-lg:.5rem;--clcosdk-radius-2xl:1rem;--clcosdk-ease-in-out:cubic-bezier(.4, 0, .2, 1);--clcosdk-animate-spin:spin 1s linear infinite;--clcosdk-animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--clcosdk-color-brand-primary:var(--color-brand-primary)}}@layer base{.clco-sdk-root{--color-brand-primary:#171717;--color-brand-primary-hover:#000;--color-brand-primary-active:#262626;--color-accent:#2b3a67;--color-accent-hover:#243057;--color-accent-active:#1d2647;--color-accent-focus:#c7d2fe;--color-accent-subtle:#eef1f8;--color-text-primary:#171717;--color-text-secondary:#8c8c8c;--color-text-disabled:#d1d1d1;--color-text-inverse:#fff;--color-background:#fff;--color-surface:#fafafa;--color-section:#f3f3f3;--color-border:#e5e5e5;--color-divider:#ececec;--color-overlay:#00000080;--color-positive:#15803d;--color-positive-subtle:#dcfce7;--color-negative:#dc2626;--color-negative-subtle:#fee2e2;--color-success:#2c8c5e;--color-success-subtle:#e6f4ec;--color-success-border:#cfe9db;--color-warning:#e08a1a;--color-warning-subtle:#fff7ed;--color-warning-border:#fdead7;--color-error:#b42318;--color-error-subtle:#feeceb;--color-error-border:#fbd5d2}@media (prefers-color-scheme:dark){.clco-sdk-root:not(:where(.light,.light *)){--color-brand-primary:#f4f4f5;--color-brand-primary-hover:#fff;--color-brand-primary-active:#e4e4e7;--color-accent:#6f82c9;--color-accent-hover:#8799e4;--color-accent-active:#5b6fcf;--color-accent-focus:#6f82c959;--color-accent-subtle:#6f82c91f;--color-text-primary:#f4f4f5;--color-text-secondary:#a1a1aa;--color-text-disabled:#71717a;--color-text-inverse:#171717;--color-background:#0f1115;--color-surface:#161a20;--color-section:#20242c;--color-border:#2a2e35;--color-divider:#323741;--color-overlay:#000000b3;--color-positive:#22c55e;--color-positive-subtle:#22c55e1f;--color-negative:#ef4444;--color-negative-subtle:#ef44441f;--color-success:#34d399;--color-success-subtle:#34d3991f;--color-success-border:#34d39940;--color-warning:#f59e0b;--color-warning-subtle:#f59e0b1f;--color-warning-border:#f59e0b40;--color-error:#f87171;--color-error-subtle:#f871711f;--color-error-border:#f8717140}}:where(.dark,.dark *) .clco-sdk-root{--color-brand-primary:#f4f4f5;--color-brand-primary-hover:#fff;--color-brand-primary-active:#e4e4e7;--color-accent:#6f82c9;--color-accent-hover:#8799e4;--color-accent-active:#5b6fcf;--color-accent-focus:#6f82c959;--color-accent-subtle:#6f82c91f;--color-text-primary:#f4f4f5;--color-text-secondary:#a1a1aa;--color-text-disabled:#71717a;--color-text-inverse:#171717;--color-background:#0f1115;--color-surface:#161a20;--color-section:#20242c;--color-border:#2a2e35;--color-divider:#323741;--color-overlay:#000000b3;--color-positive:#22c55e;--color-positive-subtle:#22c55e1f;--color-negative:#ef4444;--color-negative-subtle:#ef44441f;--color-success:#34d399;--color-success-subtle:#34d3991f;--color-success-border:#34d39940;--color-warning:#f59e0b;--color-warning-subtle:#f59e0b1f;--color-warning-border:#f59e0b40;--color-error:#f87171;--color-error-subtle:#f871711f;--color-error-border:#f8717140}.clco-sdk-root{color:var(--color-text-primary);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:Inter,sans-serif}.clco-sdk-root *,.clco-sdk-root :before,.clco-sdk-root :after{box-sizing:border-box}.clco-sdk-root button{appearance:none;cursor:pointer;font:inherit;color:inherit;background:0 0;border:none;padding:0}.clco-sdk-root a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}.clco-sdk-root ul,.clco-sdk-root ol{margin:0;padding:0;list-style:none}.clco-sdk-root img,.clco-sdk-root svg{max-width:100%;display:block}}@layer components;@layer utilities{.clcosdk\\:absolute{position:absolute}.clcosdk\\:fixed{position:fixed}.clcosdk\\:relative{position:relative}.clcosdk\\:inset-0{inset:calc(var(--clcosdk-spacing) * 0)}.clcosdk\\:top-4{top:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:right-4{right:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:z-50{z-index:50}.clcosdk\\:mt-4{margin-top:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:mb-6{margin-bottom:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:flex{display:flex}.clcosdk\\:grid{display:grid}.clcosdk\\:inline-flex{display:inline-flex}.clcosdk\\:h-3{height:calc(var(--clcosdk-spacing) * 3)}.clcosdk\\:h-4{height:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:h-5{height:calc(var(--clcosdk-spacing) * 5)}.clcosdk\\:h-6{height:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:h-9{height:calc(var(--clcosdk-spacing) * 9)}.clcosdk\\:h-11{height:calc(var(--clcosdk-spacing) * 11)}.clcosdk\\:h-12{height:calc(var(--clcosdk-spacing) * 12)}.clcosdk\\:h-14{height:calc(var(--clcosdk-spacing) * 14)}.clcosdk\\:h-28{height:calc(var(--clcosdk-spacing) * 28)}.clcosdk\\:h-52{height:calc(var(--clcosdk-spacing) * 52)}.clcosdk\\:h-\\[18px\\]{height:18px}.clcosdk\\:h-auto{height:auto}.clcosdk\\:h-full{height:100%}.clcosdk\\:max-h-\\[92vh\\]{max-height:92vh}.clcosdk\\:min-h-0{min-height:calc(var(--clcosdk-spacing) * 0)}.clcosdk\\:min-h-9{min-height:calc(var(--clcosdk-spacing) * 9)}.clcosdk\\:min-h-40{min-height:calc(var(--clcosdk-spacing) * 40)}.clcosdk\\:min-h-\\[2\\.4rem\\]{min-height:2.4rem}.clcosdk\\:w-4{width:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:w-5{width:calc(var(--clcosdk-spacing) * 5)}.clcosdk\\:w-6{width:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:w-12{width:calc(var(--clcosdk-spacing) * 12)}.clcosdk\\:w-16{width:calc(var(--clcosdk-spacing) * 16)}.clcosdk\\:w-28{width:calc(var(--clcosdk-spacing) * 28)}.clcosdk\\:w-48{width:calc(var(--clcosdk-spacing) * 48)}.clcosdk\\:w-80{width:calc(var(--clcosdk-spacing) * 80)}.clcosdk\\:w-96{width:calc(var(--clcosdk-spacing) * 96)}.clcosdk\\:w-\\[16px\\]{width:16px}.clcosdk\\:w-\\[448px\\]{width:448px}.clcosdk\\:w-auto{width:auto}.clcosdk\\:w-full{width:100%}.clcosdk\\:max-w-\\[22rem\\]{max-width:22rem}.clcosdk\\:max-w-\\[28rem\\]{max-width:28rem}.clcosdk\\:max-w-\\[30rem\\]{max-width:30rem}.clcosdk\\:max-w-\\[760px\\]{max-width:760px}.clcosdk\\:max-w-\\[1200px\\]{max-width:1200px}.clcosdk\\:max-w-md{max-width:var(--clcosdk-container-md)}.clcosdk\\:shrink-0{flex-shrink:0}.clcosdk\\:rotate-90{rotate:90deg}.clcosdk\\:animate-pulse{animation:var(--clcosdk-animate-pulse)}.clcosdk\\:animate-spin{animation:var(--clcosdk-animate-spin)}.clcosdk\\:cursor-pointer{cursor:pointer}.clcosdk\\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.clcosdk\\:grid-rows-\\[0fr\\]{grid-template-rows:0fr}.clcosdk\\:grid-rows-\\[1fr\\]{grid-template-rows:1fr}.clcosdk\\:flex-col{flex-direction:column}.clcosdk\\:flex-wrap{flex-wrap:wrap}.clcosdk\\:items-center{align-items:center}.clcosdk\\:items-start{align-items:flex-start}.clcosdk\\:justify-between{justify-content:space-between}.clcosdk\\:justify-center{justify-content:center}.clcosdk\\:gap-1{gap:calc(var(--clcosdk-spacing) * 1)}.clcosdk\\:gap-2{gap:calc(var(--clcosdk-spacing) * 2)}.clcosdk\\:gap-3{gap:calc(var(--clcosdk-spacing) * 3)}.clcosdk\\:gap-4{gap:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:gap-5{gap:calc(var(--clcosdk-spacing) * 5)}.clcosdk\\:gap-6{gap:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:gap-8{gap:calc(var(--clcosdk-spacing) * 8)}.clcosdk\\:gap-\\[5px\\]{gap:5px}:where(.clcosdk\\:space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--clcosdk-spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--clcosdk-spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.clcosdk\\:space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--clcosdk-spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--clcosdk-spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.clcosdk\\:divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.clcosdk\\:divide-border>:not(:last-child)){border-color:var(--color-border)}:where(.clcosdk\\:divide-divider>:not(:last-child)){border-color:var(--color-divider)}.clcosdk\\:self-start{align-self:flex-start}.clcosdk\\:overflow-hidden{overflow:hidden}.clcosdk\\:overflow-y-auto{overflow-y:auto}.clcosdk\\:rounded{border-radius:.25rem}.clcosdk\\:rounded-2xl{border-radius:var(--clcosdk-radius-2xl)}.clcosdk\\:rounded-btn{border-radius:12px}.clcosdk\\:rounded-card{border-radius:24px}.clcosdk\\:rounded-full{border-radius:3.40282e38px}.clcosdk\\:rounded-lg{border-radius:var(--clcosdk-radius-lg)}.clcosdk\\:rounded-md{border-radius:var(--clcosdk-radius-md)}.clcosdk\\:border{border-style:var(--tw-border-style);border-width:1px}.clcosdk\\:border-2{border-style:var(--tw-border-style);border-width:2px}.clcosdk\\:border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.clcosdk\\:border-dashed{--tw-border-style:dashed;border-style:dashed}.clcosdk\\:border-accent\\/50{border-color:var(--color-accent)}@supports (color:color-mix(in lab, red, red)){.clcosdk\\:border-accent\\/50{border-color:color-mix(in oklab, var(--color-accent) 50%, transparent)}}.clcosdk\\:border-accent\\/60{border-color:var(--color-accent)}@supports (color:color-mix(in lab, red, red)){.clcosdk\\:border-accent\\/60{border-color:color-mix(in oklab, var(--color-accent) 60%, transparent)}}.clcosdk\\:border-amber-500{border-color:var(--clcosdk-color-amber-500)}.clcosdk\\:border-border,.clcosdk\\:border-border\\/60{border-color:var(--color-border)}@supports (color:color-mix(in lab, red, red)){.clcosdk\\:border-border\\/60{border-color:color-mix(in oklab, var(--color-border) 60%, transparent)}}.clcosdk\\:border-current{border-color:currentColor}.clcosdk\\:border-divider{border-color:var(--color-divider)}.clcosdk\\:border-error-border{border-color:var(--color-error-border)}.clcosdk\\:border-success-border{border-color:var(--color-success-border)}.clcosdk\\:border-warning-border{border-color:var(--color-warning-border)}.clcosdk\\:border-t-transparent{border-top-color:#0000}.clcosdk\\:bg-accent\\/10{background-color:var(--color-accent)}@supports (color:color-mix(in lab, red, red)){.clcosdk\\:bg-accent\\/10{background-color:color-mix(in oklab, var(--color-accent) 10%, transparent)}}.clcosdk\\:bg-background{background-color:var(--color-background)}.clcosdk\\:bg-black\\/50{background-color:var(--clcosdk-color-black)}@supports (color:color-mix(in lab, red, red)){.clcosdk\\:bg-black\\/50{background-color:color-mix(in oklab, var(--clcosdk-color-black) 50%, transparent)}}.clcosdk\\:bg-brand-primary{background-color:var(--color-brand-primary)}.clcosdk\\:bg-error-subtle{background-color:var(--color-error-subtle)}.clcosdk\\:bg-overlay{background-color:var(--color-overlay)}.clcosdk\\:bg-section{background-color:var(--color-section)}.clcosdk\\:bg-success-subtle{background-color:var(--color-success-subtle)}.clcosdk\\:bg-surface{background-color:var(--color-surface)}.clcosdk\\:bg-transparent{background-color:#0000}.clcosdk\\:bg-warning-subtle{background-color:var(--color-warning-subtle)}.clcosdk\\:bg-gradient-to-b{--tw-gradient-position:to bottom in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.clcosdk\\:bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.clcosdk\\:from-surface{--tw-gradient-from:var(--color-surface);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.clcosdk\\:from-transparent{--tw-gradient-from:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.clcosdk\\:via-section{--tw-gradient-via:var(--color-section);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.clcosdk\\:via-transparent{--tw-gradient-via:transparent;--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.clcosdk\\:to-background{--tw-gradient-to:var(--color-background);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.clcosdk\\:to-overlay\\/35{--tw-gradient-to:var(--color-overlay)}@supports (color:color-mix(in lab, red, red)){.clcosdk\\:to-overlay\\/35{--tw-gradient-to:color-mix(in oklab, var(--color-overlay) 35%, transparent)}}.clcosdk\\:to-overlay\\/35{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.clcosdk\\:object-cover{object-fit:cover}.clcosdk\\:p-0{padding:calc(var(--clcosdk-spacing) * 0)}.clcosdk\\:p-1\\.5{padding:calc(var(--clcosdk-spacing) * 1.5)}.clcosdk\\:p-3{padding:calc(var(--clcosdk-spacing) * 3)}.clcosdk\\:p-4{padding:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:p-6{padding:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:p-8{padding:calc(var(--clcosdk-spacing) * 8)}.clcosdk\\:px-2{padding-inline:calc(var(--clcosdk-spacing) * 2)}.clcosdk\\:px-3{padding-inline:calc(var(--clcosdk-spacing) * 3)}.clcosdk\\:px-4{padding-inline:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:px-5{padding-inline:calc(var(--clcosdk-spacing) * 5)}.clcosdk\\:px-6{padding-inline:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:py-2{padding-block:calc(var(--clcosdk-spacing) * 2)}.clcosdk\\:pt-4{padding-top:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:pt-14{padding-top:calc(var(--clcosdk-spacing) * 14)}.clcosdk\\:pb-4{padding-bottom:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:text-center{text-align:center}.clcosdk\\:text-left{text-align:left}.clcosdk\\:font-mono{font-family:var(--clcosdk-font-mono)}.clcosdk\\:text-base{font-size:var(--clcosdk-text-base);line-height:var(--tw-leading,var(--clcosdk-text-base--line-height))}.clcosdk\\:text-sm{font-size:var(--clcosdk-text-sm);line-height:var(--tw-leading,var(--clcosdk-text-sm--line-height))}.clcosdk\\:text-xs{font-size:var(--clcosdk-text-xs);line-height:var(--tw-leading,var(--clcosdk-text-xs--line-height))}.clcosdk\\:text-\\[11px\\]{font-size:11px}.clcosdk\\:text-\\[12px\\]{font-size:12px}.clcosdk\\:text-\\[14px\\]{font-size:14px}.clcosdk\\:text-\\[16px\\]{font-size:16px}.clcosdk\\:text-\\[18px\\]{font-size:18px}.clcosdk\\:text-\\[22px\\]{font-size:22px}.clcosdk\\:text-\\[28px\\]{font-size:28px}.clcosdk\\:text-\\[36px\\]{font-size:36px}.clcosdk\\:text-\\[48px\\]{font-size:48px}.clcosdk\\:text-\\[64px\\]{font-size:64px}.clcosdk\\:leading-\\[110\\%\\]{--tw-leading:110%;line-height:110%}.clcosdk\\:leading-\\[120\\%\\]{--tw-leading:120%;line-height:120%}.clcosdk\\:leading-\\[125\\%\\]{--tw-leading:125%;line-height:125%}.clcosdk\\:leading-\\[130\\%\\]{--tw-leading:130%;line-height:130%}.clcosdk\\:leading-\\[135\\%\\]{--tw-leading:135%;line-height:135%}.clcosdk\\:leading-\\[140\\%\\]{--tw-leading:140%;line-height:140%}.clcosdk\\:leading-\\[150\\%\\]{--tw-leading:150%;line-height:150%}.clcosdk\\:font-medium{--tw-font-weight:var(--clcosdk-font-weight-medium);font-weight:var(--clcosdk-font-weight-medium)}.clcosdk\\:font-normal{--tw-font-weight:var(--clcosdk-font-weight-normal);font-weight:var(--clcosdk-font-weight-normal)}.clcosdk\\:font-semibold{--tw-font-weight:var(--clcosdk-font-weight-semibold);font-weight:var(--clcosdk-font-weight-semibold)}.clcosdk\\:tracking-\\[0\\.12px\\]{--tw-tracking:.12px;letter-spacing:.12px}.clcosdk\\:tracking-\\[0\\.28px\\]{--tw-tracking:.28px;letter-spacing:.28px}.clcosdk\\:whitespace-nowrap{white-space:nowrap}.clcosdk\\:text-error{color:var(--color-error)}.clcosdk\\:text-success{color:var(--color-success)}.clcosdk\\:text-text-inverse{color:var(--color-text-inverse)}.clcosdk\\:text-text-primary{color:var(--color-text-primary)}.clcosdk\\:text-text-secondary{color:var(--color-text-secondary)}.clcosdk\\:text-warning{color:var(--color-warning)}.clcosdk\\:capitalize{text-transform:capitalize}.clcosdk\\:underline{text-decoration-line:underline}.clcosdk\\:underline-offset-2{text-underline-offset:2px}.clcosdk\\:underline-offset-4{text-underline-offset:4px}.clcosdk\\:opacity-60{opacity:.6}.clcosdk\\:shadow-\\[0_0_0_3px_rgba\\(59\\,130\\,246\\,0\\.2\\)\\]{--tw-shadow:0 0 0 3px var(--tw-shadow-color,#3b82f633);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:shadow-\\[0_0_0_3px_rgba\\(59\\,130\\,246\\,0\\.18\\)\\]{--tw-shadow:0 0 0 3px var(--tw-shadow-color,#3b82f62e);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:shadow-\\[0_0_0_3px_rgba\\(59\\,130\\,246\\,0\\.25\\)\\]{--tw-shadow:0 0 0 3px var(--tw-shadow-color,#3b82f640);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:shadow-\\[0_10px_24px_rgba\\(0\\,0\\,0\\,0\\.18\\)\\]{--tw-shadow:0 10px 24px var(--tw-shadow-color,#0000002e);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:shadow-\\[0_10px_24px_rgba\\(0\\,0\\,0\\,0\\.25\\)\\]{--tw-shadow:0 10px 24px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:shadow-card{--tw-shadow:0px 4px 6px -2px var(--tw-shadow-color,#0000000d), 0px 12px 24px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:transition-\\[grid-template-rows\\]{transition-property:grid-template-rows;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.clcosdk\\:transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.clcosdk\\:transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.clcosdk\\:transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.clcosdk\\:duration-200{--tw-duration:.2s;transition-duration:.2s}.clcosdk\\:duration-300{--tw-duration:.3s;transition-duration:.3s}.clcosdk\\:ease-in-out{--tw-ease:var(--clcosdk-ease-in-out);transition-timing-function:var(--clcosdk-ease-in-out)}@media (hover:hover){.clcosdk\\:hover\\:-translate-y-0\\.5:hover{--tw-translate-y:calc(var(--clcosdk-spacing) * -.5);translate:var(--tw-translate-x) var(--tw-translate-y)}.clcosdk\\:hover\\:border-divider:hover{border-color:var(--color-divider)}.clcosdk\\:hover\\:bg-\\[\\#fcdcd8\\]:hover{background-color:#fcdcd8}.clcosdk\\:hover\\:bg-border:hover{background-color:var(--color-border)}.clcosdk\\:hover\\:bg-brand-primary:hover{background-color:var(--color-brand-primary)}.clcosdk\\:hover\\:bg-brand-primary-hover:hover{background-color:var(--color-brand-primary-hover)}.clcosdk\\:hover\\:bg-section:hover{background-color:var(--color-section)}.clcosdk\\:hover\\:bg-surface:hover{background-color:var(--color-surface)}.clcosdk\\:hover\\:text-\\[\\#8b1a13\\]:hover{color:#8b1a13}.clcosdk\\:hover\\:text-text-primary:hover{color:var(--color-text-primary)}.clcosdk\\:hover\\:underline:hover{text-decoration-line:underline}.clcosdk\\:hover\\:shadow-\\[0px_14px_32px_-10px_rgba\\(0\\,0\\,0\\,0\\.35\\)\\]:hover{--tw-shadow:0px 14px 32px -10px var(--tw-shadow-color,#00000059);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}}.clcosdk\\:focus-visible\\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:focus-visible\\:ring-accent-focus:focus-visible{--tw-ring-color:var(--color-accent-focus)}.clcosdk\\:focus-visible\\:ring-gray-400:focus-visible{--tw-ring-color:var(--clcosdk-color-gray-400)}.clcosdk\\:focus-visible\\:ring-gray-500:focus-visible{--tw-ring-color:var(--clcosdk-color-gray-500)}.clcosdk\\:focus-visible\\:ring-red-400:focus-visible{--tw-ring-color:var(--clcosdk-color-red-400)}.clcosdk\\:focus-visible\\:ring-red-500:focus-visible{--tw-ring-color:var(--clcosdk-color-red-500)}.clcosdk\\:focus-visible\\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.clcosdk\\:focus-visible\\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.clcosdk\\:active\\:bg-\\[\\#d9d9d9\\]:active{background-color:#d9d9d9}.clcosdk\\:active\\:bg-\\[\\#f9c9c4\\]:active{background-color:#f9c9c4}.clcosdk\\:active\\:bg-border:active{background-color:var(--color-border)}.clcosdk\\:active\\:bg-brand-primary-active:active{background-color:var(--color-brand-primary-active)}.clcosdk\\:active\\:text-\\[\\#6d1510\\]:active{color:#6d1510}.clcosdk\\:disabled\\:pointer-events-none:disabled{pointer-events:none}.clcosdk\\:disabled\\:opacity-40:disabled{opacity:.4}@media (prefers-color-scheme:dark){@media (hover:hover){.clcosdk\\:dark\\:hover\\:bg-\\[rgba\\(248\\,113\\,113\\,0\\.20\\)\\]:not(:where(.light,.light *)):hover{background-color:#f8717133}}}@media (hover:hover){.clcosdk\\:dark\\:hover\\:bg-\\[rgba\\(248\\,113\\,113\\,0\\.20\\)\\]:where(.dark,.dark *):hover{background-color:#f8717133}}@media (prefers-color-scheme:dark){@media (hover:hover){.clcosdk\\:dark\\:hover\\:text-\\[\\#fca5a5\\]:not(:where(.light,.light *)):hover{color:#fca5a5}}}@media (hover:hover){.clcosdk\\:dark\\:hover\\:text-\\[\\#fca5a5\\]:where(.dark,.dark *):hover{color:#fca5a5}}@media (prefers-color-scheme:dark){.clcosdk\\:dark\\:active\\:bg-\\[rgba\\(248\\,113\\,113\\,0\\.30\\)\\]:not(:where(.light,.light *)):active{background-color:#f871714d}}.clcosdk\\:dark\\:active\\:bg-\\[rgba\\(248\\,113\\,113\\,0\\.30\\)\\]:where(.dark,.dark *):active{background-color:#f871714d}@media (prefers-color-scheme:dark){.clcosdk\\:dark\\:active\\:bg-divider:not(:where(.light,.light *)):active{background-color:var(--color-divider)}}.clcosdk\\:dark\\:active\\:bg-divider:where(.dark,.dark *):active{background-color:var(--color-divider)}@media (prefers-color-scheme:dark){.clcosdk\\:dark\\:active\\:text-\\[\\#f87171\\]:not(:where(.light,.light *)):active{color:#f87171}}.clcosdk\\:dark\\:active\\:text-\\[\\#f87171\\]:where(.dark,.dark *):active{color:#f87171}.clcosdk\\:\\[\\&_circle\\]\\:fill-error-subtle circle{fill:var(--color-error-subtle)}.clcosdk\\:\\[\\&_circle\\]\\:fill-success-subtle circle{fill:var(--color-success-subtle)}.clcosdk\\:\\[\\&_circle\\]\\:fill-warning-subtle circle{fill:var(--color-warning-subtle)}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}';
723
+
724
+ // src/client/CoinListStyleScope.tsx
725
+ import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
726
+ var ScopeContext = createContext2(false);
727
+ function CoinListStyleScope({ children }) {
728
+ const alreadyScoped = useContext(ScopeContext);
729
+ if (alreadyScoped) {
730
+ return /* @__PURE__ */ jsx2(Fragment, { children });
731
+ }
732
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
733
+ /* @__PURE__ */ jsx2("link", { rel: "preconnect", href: "https://fonts.googleapis.com" }),
734
+ /* @__PURE__ */ jsx2(
735
+ "link",
736
+ {
737
+ rel: "preconnect",
738
+ href: "https://fonts.gstatic.com",
739
+ crossOrigin: "anonymous"
740
+ }
741
+ ),
742
+ /* @__PURE__ */ jsx2(
743
+ "link",
744
+ {
745
+ rel: "stylesheet",
746
+ href: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap"
747
+ }
748
+ ),
749
+ /* @__PURE__ */ jsxs("div", { className: "clco-sdk-root", style: { display: "contents" }, children: [
750
+ /* @__PURE__ */ jsx2(
751
+ "style",
752
+ {
753
+ href: "clco-sdk-styles",
754
+ precedence: "default",
755
+ dangerouslySetInnerHTML: { __html: sdkStyles }
756
+ }
757
+ ),
758
+ /* @__PURE__ */ jsx2(ScopeContext.Provider, { value: true, children })
759
+ ] })
760
+ ] });
324
761
  }
325
762
 
326
763
  // src/client/components/design-system/AlertBanner.tsx
@@ -670,9 +1107,9 @@ function CoinListSignInButton({
670
1107
  }
671
1108
 
672
1109
  // src/client/hooks/useCoinList.ts
673
- import { useContext } from "react";
1110
+ import { useContext as useContext2 } from "react";
674
1111
  function useCoinList() {
675
- const context = useContext(CoinListContext);
1112
+ const context = useContext2(CoinListContext);
676
1113
  if (context === null) {
677
1114
  throw new CoinListClientInitializationError();
678
1115
  }
@@ -700,7 +1137,7 @@ function CoinListSignInCard({
700
1137
  const handleSignIn = onSignIn ?? (() => {
701
1138
  void coinlist.startOAuth();
702
1139
  });
703
- return /* @__PURE__ */ jsxs7(
1140
+ return /* @__PURE__ */ jsx10(CoinListStyleScope, { children: /* @__PURE__ */ jsxs7(
704
1141
  "div",
705
1142
  {
706
1143
  className: cn(
@@ -739,7 +1176,7 @@ function CoinListSignInCard({
739
1176
  /* @__PURE__ */ jsx10(PoweredByCoinList, { className: "clcosdk:mt-4" })
740
1177
  ]
741
1178
  }
742
- );
1179
+ ) });
743
1180
  }
744
1181
 
745
1182
  // src/client/components/offers/OfferCard.tsx
@@ -754,7 +1191,7 @@ var OfferCardUi = {
754
1191
  bannerUrl: offer.bannerUrl,
755
1192
  logoUrl: offer.logoUrl,
756
1193
  formattedStartsAt: monthYearFormatter.format(offer.startsAt),
757
- formattedEndsAt: monthYearFormatter.format(offer.endsAt)
1194
+ formattedEndsAt: offer.endsAt ? monthYearFormatter.format(offer.endsAt) : null
758
1195
  })
759
1196
  };
760
1197
  function OfferCard({
@@ -805,7 +1242,7 @@ function OfferCard({
805
1242
  ),
806
1243
  /* @__PURE__ */ jsx11("span", { className: cn(typeClasses.label, "clcosdk:text-text-primary"), children: offer.formattedStartsAt })
807
1244
  ] }),
808
- /* @__PURE__ */ jsxs8("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-1", children: [
1245
+ offer.formattedEndsAt && /* @__PURE__ */ jsxs8("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-1", children: [
809
1246
  /* @__PURE__ */ jsx11(
810
1247
  "span",
811
1248
  {
@@ -813,7 +1250,13 @@ function OfferCard({
813
1250
  children: "Ends"
814
1251
  }
815
1252
  ),
816
- /* @__PURE__ */ jsx11("span", { className: cn(typeClasses.label, "clcosdk:text-text-primary"), children: offer.formattedEndsAt })
1253
+ /* @__PURE__ */ jsx11(
1254
+ "span",
1255
+ {
1256
+ className: cn(typeClasses.label, "clcosdk:text-text-primary"),
1257
+ children: offer.formattedEndsAt
1258
+ }
1259
+ )
817
1260
  ] })
818
1261
  ] })
819
1262
  ] });
@@ -837,10 +1280,8 @@ function OfferCard({
837
1280
  } else {
838
1281
  cardNode = /* @__PURE__ */ jsx11("div", { className: baseClasses, children: cardContent });
839
1282
  }
840
- if (!containerClassName) {
841
- return cardNode;
842
- }
843
- return /* @__PURE__ */ jsx11("div", { className: containerClassName, children: cardNode });
1283
+ const card = containerClassName ? /* @__PURE__ */ jsx11("div", { className: containerClassName, children: cardNode }) : cardNode;
1284
+ return /* @__PURE__ */ jsx11(CoinListStyleScope, { children: card });
844
1285
  }
845
1286
 
846
1287
  // src/client/hooks/useOffers.ts
@@ -888,7 +1329,7 @@ function useOffers(options = {}) {
888
1329
  // src/client/components/offers/OffersGrid.tsx
889
1330
  import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
890
1331
  var DEFAULT_MAX_COLUMNS = 3;
891
- function OffersGrid({
1332
+ function OffersGridBody({
892
1333
  data,
893
1334
  maxColumns,
894
1335
  className,
@@ -982,66 +1423,611 @@ function OffersGrid({
982
1423
  }
983
1424
  );
984
1425
  }
1426
+ function OffersGrid(props = {}) {
1427
+ return /* @__PURE__ */ jsx12(CoinListStyleScope, { children: /* @__PURE__ */ jsx12(OffersGridBody, { ...props }) });
1428
+ }
985
1429
 
986
- // src/client/components/requirements/RequirementItem.tsx
987
- import { ChevronRight } from "lucide-react";
988
-
989
- // src/client/components/design-system/StepStatusIcon.tsx
990
- import { CircleCheck as CircleCheck2, CircleX, Info as Info2 } from "lucide-react";
991
- import { jsx as jsx13 } from "react/jsx-runtime";
992
- var statusConfig = {
993
- required: {
994
- Icon: Info2,
995
- colorClass: "clcosdk:text-warning",
996
- fillClass: "clcosdk:[&_circle]:fill-warning-subtle"
997
- },
998
- pending: {
999
- Icon: Info2,
1000
- colorClass: "clcosdk:text-warning",
1001
- fillClass: "clcosdk:[&_circle]:fill-warning-subtle"
1002
- },
1003
- completed: {
1004
- Icon: CircleCheck2,
1005
- colorClass: "clcosdk:text-success",
1006
- fillClass: "clcosdk:[&_circle]:fill-success-subtle"
1007
- },
1008
- rejected: {
1009
- Icon: CircleX,
1010
- colorClass: "clcosdk:text-error",
1011
- fillClass: "clcosdk:[&_circle]:fill-error-subtle"
1012
- }
1013
- };
1014
- function StepStatusIcon({ status, className }) {
1015
- const { Icon, colorClass, fillClass } = statusConfig[status];
1016
- return /* @__PURE__ */ jsx13(
1017
- Icon,
1018
- {
1019
- className: cn(
1020
- "clcosdk:h-6 clcosdk:w-6 clcosdk:shrink-0",
1021
- colorClass,
1022
- fillClass,
1023
- className
1430
+ // src/client/components/requirements/ConnectedWalletList.tsx
1431
+ import { useState as useState3 } from "react";
1432
+ import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
1433
+ function ConnectedWalletRow({
1434
+ wallet,
1435
+ onRemove
1436
+ }) {
1437
+ const [state, setState] = useState3("idle");
1438
+ const remove = async () => {
1439
+ if (!onRemove) return;
1440
+ setState("removing");
1441
+ try {
1442
+ await onRemove(wallet.id);
1443
+ setState("idle");
1444
+ } catch {
1445
+ setState("error");
1446
+ }
1447
+ };
1448
+ return /* @__PURE__ */ jsxs10("div", { className: "clcosdk:flex clcosdk:min-h-9 clcosdk:flex-wrap clcosdk:items-center clcosdk:justify-between clcosdk:gap-2", children: [
1449
+ /* @__PURE__ */ jsx13(
1450
+ "span",
1451
+ {
1452
+ title: wallet.address,
1453
+ className: cn(
1454
+ typeClasses.body,
1455
+ "clcosdk:font-mono clcosdk:text-text-primary"
1456
+ ),
1457
+ children: wallet.shortAddress
1458
+ }
1459
+ ),
1460
+ onRemove != null && (state === "confirming" ? /* @__PURE__ */ jsxs10("div", { className: "clcosdk:flex clcosdk:items-center clcosdk:gap-2", children: [
1461
+ /* @__PURE__ */ jsx13(
1462
+ "span",
1463
+ {
1464
+ className: cn(typeClasses.subhead, "clcosdk:text-text-secondary"),
1465
+ children: "Remove?"
1466
+ }
1024
1467
  ),
1025
- "aria-hidden": "true"
1468
+ /* @__PURE__ */ jsx13(ClButton, { size: "sm", variant: "destructive", onClick: remove, children: "Remove" }),
1469
+ /* @__PURE__ */ jsx13(
1470
+ ClButton,
1471
+ {
1472
+ size: "sm",
1473
+ variant: "ghost",
1474
+ onClick: () => setState("idle"),
1475
+ children: "Cancel"
1476
+ }
1477
+ )
1478
+ ] }) : state === "error" ? /* @__PURE__ */ jsxs10("div", { className: "clcosdk:flex clcosdk:items-center clcosdk:gap-2", children: [
1479
+ /* @__PURE__ */ jsx13("span", { className: cn(typeClasses.subhead, "clcosdk:text-error"), children: "Couldn't remove." }),
1480
+ /* @__PURE__ */ jsx13(
1481
+ ClButton,
1482
+ {
1483
+ size: "sm",
1484
+ variant: "destructiveLink",
1485
+ onClick: () => setState("confirming"),
1486
+ children: "Try again"
1487
+ }
1488
+ )
1489
+ ] }) : /* @__PURE__ */ jsx13(
1490
+ ClButton,
1491
+ {
1492
+ size: "sm",
1493
+ variant: "destructiveLink",
1494
+ disabled: state === "removing",
1495
+ onClick: () => setState("confirming"),
1496
+ children: state === "removing" ? "Removing\u2026" : "Remove"
1497
+ }
1498
+ ))
1499
+ ] });
1500
+ }
1501
+ function ConnectedWalletList({
1502
+ wallets,
1503
+ onRemove,
1504
+ onAdd,
1505
+ addLabel = "Add wallet",
1506
+ status = "ready",
1507
+ className
1508
+ }) {
1509
+ return /* @__PURE__ */ jsxs10(
1510
+ "div",
1511
+ {
1512
+ className: cn("clcosdk:flex clcosdk:flex-col clcosdk:gap-2", className),
1513
+ children: [
1514
+ status === "loading" ? /* @__PURE__ */ jsx13(AlertBanner, { variant: "info", content: "Loading your connected wallets\u2026" }) : status === "error" ? /* @__PURE__ */ jsx13(
1515
+ AlertBanner,
1516
+ {
1517
+ variant: "error",
1518
+ content: "Couldn't load your connected wallets."
1519
+ }
1520
+ ) : wallets.length === 0 ? /* @__PURE__ */ jsx13(AlertBanner, { variant: "info", content: "No wallets connected yet." }) : /* @__PURE__ */ jsx13("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:divide-y clcosdk:divide-divider", children: wallets.map((wallet) => /* @__PURE__ */ jsx13(
1521
+ ConnectedWalletRow,
1522
+ {
1523
+ wallet,
1524
+ onRemove
1525
+ },
1526
+ wallet.id
1527
+ )) }),
1528
+ onAdd != null && status !== "loading" && /* @__PURE__ */ jsx13(
1529
+ ClButton,
1530
+ {
1531
+ size: "sm",
1532
+ variant: "secondary",
1533
+ onClick: onAdd,
1534
+ className: "clcosdk:self-start",
1535
+ children: addLabel
1536
+ }
1537
+ )
1538
+ ]
1026
1539
  }
1027
1540
  );
1028
1541
  }
1029
1542
 
1030
- // src/client/components/requirements/RequirementItem.tsx
1031
- import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
1032
- var RequirementVariant = {
1033
- fromType(type) {
1034
- switch (type) {
1035
- case "external_wallet":
1036
- case "whitelisted_wallet":
1037
- return "wallet";
1038
- default:
1039
- return "verification";
1543
+ // src/client/components/requirements/ConnectWalletModal.tsx
1544
+ import { useEffect as useEffect4, useId } from "react";
1545
+
1546
+ // src/client/hooks/useConnectWallet.ts
1547
+ import { useCallback, useEffect as useEffect3, useRef, useState as useState4 } from "react";
1548
+
1549
+ // src/client/core/connect-external-wallet.ts
1550
+ var DEFAULT_STATEMENT = "Sign this message to prove you own this wallet. This does not cost gas or move funds.";
1551
+ var TERMINAL_CODES = /* @__PURE__ */ new Set([
1552
+ "not_authenticated",
1553
+ "wallet_not_whitelisted",
1554
+ "max_wallets_reached"
1555
+ ]);
1556
+ var API_ERROR_CODES = /* @__PURE__ */ new Set([
1557
+ "wallet_not_whitelisted",
1558
+ "max_wallets_reached"
1559
+ ]);
1560
+ function flowError(code) {
1561
+ return { code, retryable: !TERMINAL_CODES.has(code) };
1562
+ }
1563
+ function siweContext() {
1564
+ if (typeof window === "undefined") return { domain: "", uri: "" };
1565
+ return { domain: window.location.host, uri: window.location.origin };
1566
+ }
1567
+ function apiErrorCode(error) {
1568
+ if (typeof error !== "object" || error === null) return void 0;
1569
+ const body = error.response?.body;
1570
+ return typeof body?.code === "string" ? body.code : void 0;
1571
+ }
1572
+ function classifyApiError(error) {
1573
+ if (error instanceof NotAuthenticatedError) {
1574
+ return flowError("not_authenticated");
1575
+ }
1576
+ const code = apiErrorCode(error);
1577
+ if (code !== void 0 && API_ERROR_CODES.has(code)) {
1578
+ return flowError(code);
1579
+ }
1580
+ return flowError("unknown");
1581
+ }
1582
+ function challengeParams(wallet, challengeType, statement) {
1583
+ switch (challengeType) {
1584
+ case "siwe":
1585
+ return {
1586
+ walletAddress: wallet.address,
1587
+ chain: wallet.chain,
1588
+ challengeType: "siwe",
1589
+ ...siweContext(),
1590
+ statement: statement ?? DEFAULT_STATEMENT
1591
+ };
1592
+ case "plain":
1593
+ return {
1594
+ walletAddress: wallet.address,
1595
+ chain: wallet.chain,
1596
+ challengeType: "plain"
1597
+ };
1598
+ default: {
1599
+ const _exhaustive = challengeType;
1600
+ return _exhaustive;
1601
+ }
1602
+ }
1603
+ }
1604
+ async function connectExternalWalletFlow(params) {
1605
+ const {
1606
+ coinlist,
1607
+ wallet,
1608
+ offerId,
1609
+ offerOptionId,
1610
+ challengeType,
1611
+ statement,
1612
+ isCancelled,
1613
+ onProgress
1614
+ } = params;
1615
+ const emit = (phase) => onProgress?.(phase);
1616
+ const cancelled = () => isCancelled?.() ?? false;
1617
+ emit("requesting-challenge");
1618
+ let challenge;
1619
+ try {
1620
+ challenge = await coinlist.createWalletOwnershipChallenge(
1621
+ challengeParams(wallet, challengeType ?? "siwe", statement)
1622
+ );
1623
+ } catch (error) {
1624
+ return { type: "error", error: classifyApiError(error) };
1625
+ }
1626
+ if (cancelled()) return { type: "cancelled" };
1627
+ emit("signing-message");
1628
+ let signature;
1629
+ try {
1630
+ signature = await wallet.signMessage(challenge.message);
1631
+ } catch (error) {
1632
+ if (classifyWalletError(error).type === "user_rejected") {
1633
+ return { type: "error", error: flowError("user_rejected") };
1040
1634
  }
1635
+ return { type: "error", error: flowError("unknown") };
1636
+ }
1637
+ if (cancelled()) return { type: "cancelled" };
1638
+ emit("submitting-signature");
1639
+ try {
1640
+ const binding = await coinlist.connectExternalWallet(offerId, {
1641
+ offerOptionId,
1642
+ walletAddress: wallet.address,
1643
+ chain: wallet.chain,
1644
+ signature
1645
+ });
1646
+ return { type: "success", binding };
1647
+ } catch (error) {
1648
+ return { type: "error", error: classifyApiError(error) };
1041
1649
  }
1650
+ }
1651
+
1652
+ // src/client/hooks/useConnectWallet.ts
1653
+ var IDLE_SIGN = { type: "idle", error: null };
1654
+ var ERROR_COPY = {
1655
+ not_authenticated: "Sign in to connect your wallet.",
1656
+ user_rejected: "Signature request declined. Approve it in your wallet to continue.",
1657
+ wallet_not_whitelisted: "This wallet is not approved for this offer.",
1658
+ max_wallets_reached: "You've reached the maximum number of wallets for this option.",
1659
+ unknown: "Unable to connect your wallet. Please try again."
1042
1660
  };
1043
- var RequirementStatus = {
1044
- fromStatusValue(status) {
1661
+ function displayError(error) {
1662
+ return {
1663
+ code: error.code,
1664
+ message: ERROR_COPY[error.code],
1665
+ retryable: error.retryable
1666
+ };
1667
+ }
1668
+ function useConnectWallet({
1669
+ isOpen,
1670
+ offerId,
1671
+ offerOptionId,
1672
+ wallet,
1673
+ challengeType,
1674
+ statement
1675
+ }) {
1676
+ const { coinlist } = useCoinList();
1677
+ const [state, setState] = useState4(
1678
+ () => wallet ? { type: "READY", address: wallet.address, sign: IDLE_SIGN } : { type: "NEEDS_WALLET" }
1679
+ );
1680
+ const attempt = useRef(0);
1681
+ useEffect3(() => {
1682
+ attempt.current += 1;
1683
+ if (!isOpen) return;
1684
+ setState(
1685
+ wallet ? { type: "READY", address: wallet.address, sign: IDLE_SIGN } : { type: "NEEDS_WALLET" }
1686
+ );
1687
+ }, [isOpen, wallet?.address]);
1688
+ useEffect3(
1689
+ () => () => {
1690
+ attempt.current += 1;
1691
+ },
1692
+ []
1693
+ );
1694
+ const onSign = useCallback(() => {
1695
+ if (!wallet || state.type !== "READY") return;
1696
+ attempt.current += 1;
1697
+ const gen = attempt.current;
1698
+ setState({
1699
+ type: "READY",
1700
+ address: wallet.address,
1701
+ sign: { type: "signing" }
1702
+ });
1703
+ connectExternalWalletFlow({
1704
+ coinlist,
1705
+ wallet,
1706
+ offerId,
1707
+ offerOptionId,
1708
+ challengeType,
1709
+ statement,
1710
+ // Cancels the flow before signing / binding if this attempt is superseded.
1711
+ isCancelled: () => attempt.current !== gen
1712
+ }).then((result) => {
1713
+ if (attempt.current !== gen) return;
1714
+ if (result.type === "success") {
1715
+ setState({ type: "CONNECTED", binding: result.binding });
1716
+ } else if (result.type === "error") {
1717
+ setState({
1718
+ type: "READY",
1719
+ address: wallet.address,
1720
+ sign: { type: "idle", error: displayError(result.error) }
1721
+ });
1722
+ }
1723
+ });
1724
+ }, [
1725
+ wallet,
1726
+ state,
1727
+ coinlist,
1728
+ offerId,
1729
+ offerOptionId,
1730
+ challengeType,
1731
+ statement
1732
+ ]);
1733
+ return { state, onSign };
1734
+ }
1735
+
1736
+ // src/client/components/requirements/ConnectWalletModal.tsx
1737
+ import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
1738
+ function ConnectWalletModal({
1739
+ isOpen,
1740
+ onClose,
1741
+ offerId,
1742
+ optionId,
1743
+ wallet,
1744
+ onConnected,
1745
+ onRequestConnect,
1746
+ challengeType,
1747
+ statement,
1748
+ className
1749
+ }) {
1750
+ const { state, onSign } = useConnectWallet({
1751
+ isOpen,
1752
+ offerId,
1753
+ offerOptionId: optionId,
1754
+ wallet,
1755
+ challengeType,
1756
+ statement
1757
+ });
1758
+ const titleId = useId();
1759
+ useEffect4(() => {
1760
+ if (state.type === "CONNECTED") {
1761
+ onConnected?.(state.binding);
1762
+ onClose();
1763
+ }
1764
+ }, [state]);
1765
+ if (!isOpen || state.type === "CONNECTED") return null;
1766
+ return /* @__PURE__ */ jsx14("div", { className: "clcosdk:fixed clcosdk:inset-0 clcosdk:z-50 clcosdk:flex clcosdk:items-center clcosdk:justify-center clcosdk:bg-black/50 clcosdk:p-4", children: /* @__PURE__ */ jsxs11(
1767
+ "div",
1768
+ {
1769
+ role: "dialog",
1770
+ "aria-modal": "true",
1771
+ "aria-labelledby": titleId,
1772
+ className: cn(
1773
+ "clcosdk:flex clcosdk:w-full clcosdk:max-w-md clcosdk:flex-col clcosdk:gap-6 clcosdk:rounded-2xl clcosdk:bg-background clcosdk:p-6",
1774
+ className
1775
+ ),
1776
+ children: [
1777
+ /* @__PURE__ */ jsxs11("div", { className: "clcosdk:flex clcosdk:items-start clcosdk:justify-between clcosdk:gap-4", children: [
1778
+ /* @__PURE__ */ jsx14(
1779
+ "h3",
1780
+ {
1781
+ id: titleId,
1782
+ className: cn(typeClasses.h3, "clcosdk:text-text-primary"),
1783
+ children: "Connect your wallet"
1784
+ }
1785
+ ),
1786
+ /* @__PURE__ */ jsx14(CloseButton, { onClick: onClose })
1787
+ ] }),
1788
+ state.type === "NEEDS_WALLET" && /* @__PURE__ */ jsx14(NeedsWalletScreen, { onRequestConnect }),
1789
+ state.type === "READY" && /* @__PURE__ */ jsx14(
1790
+ ReadyScreen,
1791
+ {
1792
+ address: state.address,
1793
+ sign: state.sign,
1794
+ onSign,
1795
+ onRequestConnect
1796
+ }
1797
+ )
1798
+ ]
1799
+ }
1800
+ ) });
1801
+ }
1802
+ function NeedsWalletScreen({
1803
+ onRequestConnect
1804
+ }) {
1805
+ return /* @__PURE__ */ jsxs11("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-6", children: [
1806
+ /* @__PURE__ */ jsx14("p", { className: cn(typeClasses.body, "clcosdk:text-text-secondary"), children: "Connect an external wallet to prove ownership and bind it to this offer." }),
1807
+ onRequestConnect && /* @__PURE__ */ jsx14(ClButton, { fullWidth: true, onClick: onRequestConnect, children: "Connect wallet" })
1808
+ ] });
1809
+ }
1810
+ function ReadyScreen({
1811
+ address,
1812
+ sign,
1813
+ onSign,
1814
+ onRequestConnect
1815
+ }) {
1816
+ const hasTerminalError = sign.type === "idle" && sign.error !== null && !sign.error.retryable;
1817
+ return /* @__PURE__ */ jsxs11("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-6", children: [
1818
+ /* @__PURE__ */ jsx14("p", { className: cn(typeClasses.body, "clcosdk:text-text-secondary"), children: "Sign a message with your connected wallet to prove you own it. This does not cost gas or move any funds." }),
1819
+ /* @__PURE__ */ jsxs11("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-1 clcosdk:border-t clcosdk:border-divider clcosdk:pt-4", children: [
1820
+ /* @__PURE__ */ jsx14("span", { className: cn(typeClasses.label, "clcosdk:text-text-secondary"), children: "Wallet address" }),
1821
+ /* @__PURE__ */ jsx14("span", { className: cn(typeClasses.body, "clcosdk:text-text-primary"), children: shortenAddress(address) })
1822
+ ] }),
1823
+ sign.type === "idle" && sign.error && // Live region: the error is inserted async after a failed attempt, so
1824
+ // screen readers need it announced rather than silently rendered.
1825
+ /* @__PURE__ */ jsx14("div", { role: "alert", children: /* @__PURE__ */ jsx14(AlertBanner, { variant: "error", icon: true, content: sign.error.message }) }),
1826
+ /* @__PURE__ */ jsx14(
1827
+ ClButton,
1828
+ {
1829
+ fullWidth: true,
1830
+ onClick: onSign,
1831
+ isLoading: sign.type === "signing",
1832
+ loadingText: "Waiting for signature...",
1833
+ disabled: hasTerminalError,
1834
+ children: "Sign & connect"
1835
+ }
1836
+ ),
1837
+ onRequestConnect && /* @__PURE__ */ jsx14(
1838
+ ClButton,
1839
+ {
1840
+ fullWidth: true,
1841
+ variant: "secondary",
1842
+ onClick: onRequestConnect,
1843
+ disabled: sign.type === "signing",
1844
+ children: "Use a different wallet"
1845
+ }
1846
+ )
1847
+ ] });
1848
+ }
1849
+
1850
+ // src/client/components/requirements/IdentityVerification.tsx
1851
+ import SumsubWebSdk from "@sumsub/websdk-react";
1852
+ import { useEffect as useEffect6, useRef as useRef3 } from "react";
1853
+
1854
+ // src/client/hooks/useKycToken.ts
1855
+ import { useCallback as useCallback2, useEffect as useEffect5, useRef as useRef2, useState as useState5 } from "react";
1856
+ var IDLE_STATE = { type: "IDLE" };
1857
+ var LOADING_STATE2 = { type: "LOADING" };
1858
+ function useKycToken(levelName, reset) {
1859
+ const { coinlist } = useCoinList();
1860
+ const [kycTokenState, setKycTokenState] = useState5(IDLE_STATE);
1861
+ const resetPendingRef = useRef2(reset === true);
1862
+ const tokenIssuedRef = useRef2(false);
1863
+ useEffect5(() => {
1864
+ if (!tokenIssuedRef.current) {
1865
+ resetPendingRef.current = reset === true;
1866
+ }
1867
+ }, [reset]);
1868
+ const fetchToken = useCallback2(async () => {
1869
+ setKycTokenState(LOADING_STATE2);
1870
+ try {
1871
+ const kycToken = await coinlist.createKycToken(
1872
+ levelName,
1873
+ resetPendingRef.current
1874
+ );
1875
+ resetPendingRef.current = false;
1876
+ tokenIssuedRef.current = true;
1877
+ setKycTokenState({ type: "CONTENT", token: kycToken.token });
1878
+ return kycToken.token;
1879
+ } catch (error) {
1880
+ const reason = error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error";
1881
+ setKycTokenState({ type: "ERROR", reason });
1882
+ throw error;
1883
+ }
1884
+ }, [coinlist, levelName]);
1885
+ return { kycTokenState, fetchToken };
1886
+ }
1887
+
1888
+ // src/client/components/requirements/IdentityVerification.tsx
1889
+ import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
1890
+ function IdentityVerification({
1891
+ levelName,
1892
+ reset,
1893
+ locale,
1894
+ onSubmitted,
1895
+ onError,
1896
+ className
1897
+ }) {
1898
+ const { kycTokenState, fetchToken } = useKycToken(levelName, reset);
1899
+ const fetchedRef = useRef3(false);
1900
+ useEffect6(() => {
1901
+ if (fetchedRef.current) return;
1902
+ fetchedRef.current = true;
1903
+ fetchToken().catch(() => {
1904
+ });
1905
+ }, [fetchToken]);
1906
+ const handleMessage = (type, payload) => {
1907
+ switch (type) {
1908
+ case "idCheck.onApplicantSubmitted":
1909
+ onSubmitted?.();
1910
+ break;
1911
+ case "idCheck.onError": {
1912
+ const message = payload?.message ?? "Verification error";
1913
+ onError?.(new Error(message));
1914
+ break;
1915
+ }
1916
+ default:
1917
+ break;
1918
+ }
1919
+ };
1920
+ const handleError = (error) => {
1921
+ onError?.(error instanceof Error ? error : new Error("Verification error"));
1922
+ };
1923
+ if (kycTokenState.type === "IDLE" || kycTokenState.type === "LOADING") {
1924
+ return /* @__PURE__ */ jsx15(
1925
+ "output",
1926
+ {
1927
+ "aria-live": "polite",
1928
+ className: cn(
1929
+ "clcosdk:flex clcosdk:min-h-40 clcosdk:items-center clcosdk:justify-center",
1930
+ className
1931
+ ),
1932
+ children: /* @__PURE__ */ jsx15("p", { className: cn(typeClasses.body, "clcosdk:text-text-secondary"), children: "Loading identity verification..." })
1933
+ }
1934
+ );
1935
+ }
1936
+ if (kycTokenState.type === "ERROR") {
1937
+ const errorMessage = kycTokenState.reason === "not-authenticated" ? "Sign in to verify your identity." : "Unable to start identity verification right now. Please try again.";
1938
+ return /* @__PURE__ */ jsxs12(
1939
+ "div",
1940
+ {
1941
+ className: cn("clcosdk:flex clcosdk:flex-col clcosdk:gap-4", className),
1942
+ children: [
1943
+ /* @__PURE__ */ jsx15(AlertBanner, { variant: "error", icon: true, content: errorMessage }),
1944
+ kycTokenState.reason !== "not-authenticated" && /* @__PURE__ */ jsx15(
1945
+ ClButton,
1946
+ {
1947
+ size: "sm",
1948
+ onClick: () => {
1949
+ fetchToken().catch(() => {
1950
+ });
1951
+ },
1952
+ children: "Try again"
1953
+ }
1954
+ )
1955
+ ]
1956
+ }
1957
+ );
1958
+ }
1959
+ return /* @__PURE__ */ jsx15("div", { className: cn("clcosdk:w-full", className), children: /* @__PURE__ */ jsx15(
1960
+ SumsubWebSdk,
1961
+ {
1962
+ accessToken: kycTokenState.token,
1963
+ expirationHandler: fetchToken,
1964
+ config: locale === void 0 ? {} : { lang: locale },
1965
+ options: { addViewportTag: false, adaptIframeHeight: true },
1966
+ onMessage: handleMessage,
1967
+ onError: handleError
1968
+ }
1969
+ ) });
1970
+ }
1971
+
1972
+ // src/client/components/requirements/RequirementItem.tsx
1973
+ import { ChevronRight } from "lucide-react";
1974
+
1975
+ // src/client/components/design-system/StepStatusIcon.tsx
1976
+ import { CircleCheck as CircleCheck2, CircleX, Info as Info2 } from "lucide-react";
1977
+ import { jsx as jsx16 } from "react/jsx-runtime";
1978
+ var statusConfig = {
1979
+ required: {
1980
+ Icon: Info2,
1981
+ colorClass: "clcosdk:text-warning",
1982
+ fillClass: "clcosdk:[&_circle]:fill-warning-subtle"
1983
+ },
1984
+ pending: {
1985
+ Icon: Info2,
1986
+ colorClass: "clcosdk:text-warning",
1987
+ fillClass: "clcosdk:[&_circle]:fill-warning-subtle"
1988
+ },
1989
+ completed: {
1990
+ Icon: CircleCheck2,
1991
+ colorClass: "clcosdk:text-success",
1992
+ fillClass: "clcosdk:[&_circle]:fill-success-subtle"
1993
+ },
1994
+ rejected: {
1995
+ Icon: CircleX,
1996
+ colorClass: "clcosdk:text-error",
1997
+ fillClass: "clcosdk:[&_circle]:fill-error-subtle"
1998
+ }
1999
+ };
2000
+ function StepStatusIcon({ status, className }) {
2001
+ const { Icon, colorClass, fillClass } = statusConfig[status];
2002
+ return /* @__PURE__ */ jsx16(
2003
+ Icon,
2004
+ {
2005
+ className: cn(
2006
+ "clcosdk:h-6 clcosdk:w-6 clcosdk:shrink-0",
2007
+ colorClass,
2008
+ fillClass,
2009
+ className
2010
+ ),
2011
+ "aria-hidden": "true"
2012
+ }
2013
+ );
2014
+ }
2015
+
2016
+ // src/client/components/requirements/RequirementItem.tsx
2017
+ import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
2018
+ var RequirementVariant = {
2019
+ fromType(type) {
2020
+ switch (type) {
2021
+ case "external_wallet":
2022
+ case "whitelisted_wallet":
2023
+ return "wallet";
2024
+ default:
2025
+ return "verification";
2026
+ }
2027
+ }
2028
+ };
2029
+ var RequirementStatus = {
2030
+ fromStatusValue(status) {
1045
2031
  switch (status) {
1046
2032
  case "not_started":
1047
2033
  case "action_needed":
@@ -1063,13 +2049,18 @@ var ChecklistStatus = {
1063
2049
  }
1064
2050
  };
1065
2051
  var RequirementItemUi = {
1066
- fromDomain(req, statusInfo, label, description, walletAddress) {
2052
+ fromDomain(req, statusInfo, label, description, addresses = []) {
1067
2053
  return {
1068
2054
  variant: RequirementVariant.fromType(req.type),
1069
2055
  status: statusInfo ? RequirementStatus.fromStatusValue(statusInfo.status) : "required",
1070
2056
  label,
1071
2057
  description,
1072
- walletAddress
2058
+ multiWallet: req.type === "whitelisted_wallet",
2059
+ connectedWallets: addresses.map((address) => ({
2060
+ id: address.id,
2061
+ address: address.address,
2062
+ shortAddress: shortenAddress(address.address)
2063
+ }))
1073
2064
  };
1074
2065
  }
1075
2066
  };
@@ -1081,9 +2072,9 @@ function VerificationActionZone({
1081
2072
  switch (status) {
1082
2073
  case "required":
1083
2074
  if (onAction === null) return null;
1084
- return /* @__PURE__ */ jsx14(ClButton, { size: "sm", onClick: onAction, children: "Continue" });
2075
+ return /* @__PURE__ */ jsx17(ClButton, { size: "sm", onClick: onAction, children: "Continue" });
1085
2076
  case "pending":
1086
- return /* @__PURE__ */ jsx14(
2077
+ return /* @__PURE__ */ jsx17(
1087
2078
  AlertBanner,
1088
2079
  {
1089
2080
  variant: "warning",
@@ -1091,16 +2082,16 @@ function VerificationActionZone({
1091
2082
  }
1092
2083
  );
1093
2084
  case "completed":
1094
- return /* @__PURE__ */ jsx14(AlertBanner, { variant: "success", content: "Identity verified." });
2085
+ return /* @__PURE__ */ jsx17(AlertBanner, { variant: "success", content: "Identity verified." });
1095
2086
  case "rejected":
1096
- return /* @__PURE__ */ jsx14(
2087
+ return /* @__PURE__ */ jsx17(
1097
2088
  AlertBanner,
1098
2089
  {
1099
2090
  variant: "error",
1100
- content: onContactSupport === null ? "Verification rejected." : /* @__PURE__ */ jsxs10(Fragment3, { children: [
2091
+ content: onContactSupport === null ? "Verification rejected." : /* @__PURE__ */ jsxs13(Fragment3, { children: [
1101
2092
  "Verification rejected.",
1102
2093
  " ",
1103
- /* @__PURE__ */ jsx14(
2094
+ /* @__PURE__ */ jsx17(
1104
2095
  "button",
1105
2096
  {
1106
2097
  type: "button",
@@ -1117,25 +2108,61 @@ function VerificationActionZone({
1117
2108
  }
1118
2109
  function WalletActionZone({
1119
2110
  status,
1120
- walletAddress,
1121
- onAction
2111
+ multiWallet,
2112
+ connectedWallets,
2113
+ walletsStatus,
2114
+ onAction,
2115
+ onRemoveWallet
1122
2116
  }) {
2117
+ if (multiWallet) {
2118
+ return /* @__PURE__ */ jsxs13(Fragment3, { children: [
2119
+ /* @__PURE__ */ jsx17(
2120
+ ConnectedWalletList,
2121
+ {
2122
+ wallets: connectedWallets,
2123
+ onRemove: onRemoveWallet,
2124
+ onAdd: onAction ?? void 0,
2125
+ status: walletsStatus
2126
+ }
2127
+ ),
2128
+ status === "rejected" && /* @__PURE__ */ jsx17(
2129
+ AlertBanner,
2130
+ {
2131
+ variant: "error",
2132
+ content: "One of these wallets is not eligible for this sale."
2133
+ }
2134
+ )
2135
+ ] });
2136
+ }
1123
2137
  if (status === "completed") {
1124
- return /* @__PURE__ */ jsxs10(Fragment3, { children: [
1125
- onAction !== null && /* @__PURE__ */ jsx14(ClButton, { size: "sm", variant: "secondary", onClick: onAction, children: "Change wallet" }),
1126
- /* @__PURE__ */ jsx14(
2138
+ const connected = connectedWallets[0];
2139
+ return /* @__PURE__ */ jsxs13(Fragment3, { children: [
2140
+ onAction !== null && /* @__PURE__ */ jsx17(ClButton, { size: "sm", variant: "secondary", onClick: onAction, children: "Change wallet" }),
2141
+ walletsStatus === "loading" ? /* @__PURE__ */ jsx17(
2142
+ AlertBanner,
2143
+ {
2144
+ variant: "info",
2145
+ content: "Loading your connected wallet\u2026"
2146
+ }
2147
+ ) : walletsStatus === "error" ? /* @__PURE__ */ jsx17(
2148
+ AlertBanner,
2149
+ {
2150
+ variant: "error",
2151
+ content: "Couldn't load your connected wallet."
2152
+ }
2153
+ ) : /* @__PURE__ */ jsx17(
1127
2154
  AlertBanner,
1128
2155
  {
1129
2156
  variant: "success",
1130
- content: walletAddress ?? "Connected: 0xBa4b...9f2c"
2157
+ content: connected ? connected.shortAddress : "Wallet connected."
1131
2158
  }
1132
2159
  )
1133
2160
  ] });
1134
2161
  }
1135
2162
  if (status === "rejected") {
1136
- return /* @__PURE__ */ jsxs10(Fragment3, { children: [
1137
- onAction !== null && /* @__PURE__ */ jsx14(ClButton, { size: "sm", onClick: onAction, children: "Connect wallet" }),
1138
- /* @__PURE__ */ jsx14(
2163
+ return /* @__PURE__ */ jsxs13(Fragment3, { children: [
2164
+ onAction !== null && /* @__PURE__ */ jsx17(ClButton, { size: "sm", onClick: onAction, children: "Connect wallet" }),
2165
+ /* @__PURE__ */ jsx17(
1139
2166
  AlertBanner,
1140
2167
  {
1141
2168
  variant: "error",
@@ -1145,7 +2172,7 @@ function WalletActionZone({
1145
2172
  ] });
1146
2173
  }
1147
2174
  if (onAction === null) return null;
1148
- return /* @__PURE__ */ jsx14(ClButton, { size: "sm", onClick: onAction, children: "Connect wallet" });
2175
+ return /* @__PURE__ */ jsx17(ClButton, { size: "sm", onClick: onAction, children: "Connect wallet" });
1149
2176
  }
1150
2177
  function RequirementItem({
1151
2178
  ui,
@@ -1153,14 +2180,19 @@ function RequirementItem({
1153
2180
  onToggle,
1154
2181
  className,
1155
2182
  onAction,
2183
+ onRemoveWallet,
2184
+ walletsStatus,
1156
2185
  onContactSupport
1157
2186
  }) {
1158
- return /* @__PURE__ */ jsxs10(
2187
+ return /* @__PURE__ */ jsx17(CoinListStyleScope, { children: /* @__PURE__ */ jsxs13(
1159
2188
  "div",
1160
2189
  {
1161
- className: cn("clcosdk:flex clcosdk:w-full clcosdk:flex-col", className),
2190
+ className: cn(
2191
+ "clcosdk:flex clcosdk:w-full clcosdk:flex-col",
2192
+ className
2193
+ ),
1162
2194
  children: [
1163
- /* @__PURE__ */ jsxs10(
2195
+ /* @__PURE__ */ jsxs13(
1164
2196
  "button",
1165
2197
  {
1166
2198
  type: "button",
@@ -1168,9 +2200,9 @@ function RequirementItem({
1168
2200
  "aria-expanded": expanded,
1169
2201
  className: "clcosdk:flex clcosdk:h-14 clcosdk:w-full clcosdk:cursor-pointer clcosdk:items-center clcosdk:justify-between clcosdk:rounded-2xl clcosdk:px-2 clcosdk:transition-colors clcosdk:hover:bg-surface",
1170
2202
  children: [
1171
- /* @__PURE__ */ jsxs10("div", { className: "clcosdk:flex clcosdk:items-center clcosdk:gap-3", children: [
1172
- /* @__PURE__ */ jsx14(StepStatusIcon, { status: ui.status }),
1173
- /* @__PURE__ */ jsx14(
2203
+ /* @__PURE__ */ jsxs13("div", { className: "clcosdk:flex clcosdk:items-center clcosdk:gap-3", children: [
2204
+ /* @__PURE__ */ jsx17(StepStatusIcon, { status: ui.status }),
2205
+ /* @__PURE__ */ jsx17(
1174
2206
  "span",
1175
2207
  {
1176
2208
  className: cn(
@@ -1181,7 +2213,7 @@ function RequirementItem({
1181
2213
  }
1182
2214
  )
1183
2215
  ] }),
1184
- /* @__PURE__ */ jsx14(
2216
+ /* @__PURE__ */ jsx17(
1185
2217
  ChevronRight,
1186
2218
  {
1187
2219
  className: cn(
@@ -1194,34 +2226,40 @@ function RequirementItem({
1194
2226
  ]
1195
2227
  }
1196
2228
  ),
1197
- /* @__PURE__ */ jsx14(
2229
+ /* @__PURE__ */ jsx17(
1198
2230
  "div",
1199
2231
  {
1200
2232
  className: cn(
1201
2233
  "clcosdk:grid clcosdk:transition-[grid-template-rows] clcosdk:duration-300 clcosdk:ease-in-out",
1202
2234
  expanded ? "clcosdk:grid-rows-[1fr]" : "clcosdk:grid-rows-[0fr]"
1203
2235
  ),
1204
- children: /* @__PURE__ */ jsx14("div", { className: "clcosdk:min-h-0 clcosdk:overflow-hidden", children: /* @__PURE__ */ jsxs10("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-4 clcosdk:px-2 clcosdk:pb-4", children: [
1205
- /* @__PURE__ */ jsx14(
2236
+ children: /* @__PURE__ */ jsx17("div", { className: "clcosdk:min-h-0 clcosdk:overflow-hidden", children: /* @__PURE__ */ jsxs13("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-4 clcosdk:px-2 clcosdk:pb-4", children: [
2237
+ /* @__PURE__ */ jsx17(
1206
2238
  "p",
1207
2239
  {
1208
- className: cn(typeClasses.subhead, "clcosdk:text-text-secondary"),
2240
+ className: cn(
2241
+ typeClasses.subhead,
2242
+ "clcosdk:text-text-secondary"
2243
+ ),
1209
2244
  children: ui.description
1210
2245
  }
1211
2246
  ),
1212
- ui.variant === "verification" ? /* @__PURE__ */ jsx14(
2247
+ ui.variant === "verification" ? /* @__PURE__ */ jsx17(
1213
2248
  VerificationActionZone,
1214
2249
  {
1215
2250
  status: ui.status,
1216
2251
  onAction,
1217
2252
  onContactSupport
1218
2253
  }
1219
- ) : /* @__PURE__ */ jsx14(
2254
+ ) : /* @__PURE__ */ jsx17(
1220
2255
  WalletActionZone,
1221
2256
  {
1222
2257
  status: ui.status,
1223
- walletAddress: ui.walletAddress,
1224
- onAction
2258
+ multiWallet: ui.multiWallet,
2259
+ connectedWallets: ui.connectedWallets,
2260
+ walletsStatus,
2261
+ onAction,
2262
+ onRemoveWallet
1225
2263
  }
1226
2264
  )
1227
2265
  ] }) })
@@ -1229,28 +2267,501 @@ function RequirementItem({
1229
2267
  )
1230
2268
  ]
1231
2269
  }
1232
- );
2270
+ ) });
1233
2271
  }
1234
2272
 
1235
2273
  // src/client/components/requirements/RequirementsChecklist.tsx
1236
- import { useState as useState4 } from "react";
2274
+ import { useEffect as useEffect11, useRef as useRef4, useState as useState9 } from "react";
2275
+
2276
+ // src/client/components/requirements/TaxDocumentModal.tsx
2277
+ import { useEffect as useEffect8 } from "react";
2278
+
2279
+ // src/client/hooks/useTaxDocument.ts
2280
+ import { useCallback as useCallback3, useEffect as useEffect7, useState as useState6 } from "react";
2281
+ var IDLE_SIGN2 = { type: "idle", error: null };
2282
+ var LOADING_STATE3 = { type: "LOADING" };
2283
+ var SIGN_FAILED_MESSAGE = "Unable to sign document. Please try again.";
2284
+ var DOB_INVALID_MESSAGE = "Enter your date of birth as MM/DD/YYYY.";
2285
+ var FIELD_KEYS = {
2286
+ fullLegalName: "Full Name",
2287
+ dob: "DOB",
2288
+ countryOfCitizenship: "Country Of Citizenship",
2289
+ taxId: "Foreign Tax Number",
2290
+ permanentAddress: "Permanent Address"
2291
+ };
2292
+ function formatUsDate(date) {
2293
+ const month = String(date.getMonth() + 1).padStart(2, "0");
2294
+ const day = String(date.getDate()).padStart(2, "0");
2295
+ const year = String(date.getFullYear()).padStart(4, "0");
2296
+ return `${month}/${day}/${year}`;
2297
+ }
2298
+ function formatIsoDateOnly(isoDate) {
2299
+ const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(isoDate);
2300
+ if (!match) return "";
2301
+ const [, year, month, day] = match;
2302
+ return `${month}/${day}/${year}`;
2303
+ }
2304
+ function isValidUsDate(value) {
2305
+ const match = /^(\d{2})\/(\d{2})\/(\d{4})$/.exec(value);
2306
+ if (!match) return false;
2307
+ const [, mm, dd, yyyy] = match;
2308
+ const month = Number(mm);
2309
+ const day = Number(dd);
2310
+ const year = Number(yyyy);
2311
+ const date = new Date(year, month - 1, day);
2312
+ return date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day;
2313
+ }
2314
+ function mapPiiToFields(pii) {
2315
+ const { street, city, state, postalCode } = pii.permanentAddress;
2316
+ const cityLine = [postalCode, city].filter(Boolean).join(" ");
2317
+ const permanentAddress = [street, cityLine, state].filter(Boolean).join(", ");
2318
+ return {
2319
+ fullLegalName: pii.fullLegalName ?? "",
2320
+ // Date-only ISO from the backend, shown as MM/DD/YYYY. Blank until the
2321
+ // backend has a date of birth (the field is editable in the meantime).
2322
+ dob: formatIsoDateOnly(pii.dateOfBirth ?? ""),
2323
+ countryOfCitizenship: pii.jurisdiction?.name ?? "",
2324
+ taxId: pii.taxId ?? "",
2325
+ permanentAddress
2326
+ };
2327
+ }
2328
+ function addressPartsFromPii(pii) {
2329
+ return {
2330
+ city: pii.permanentAddress.city ?? "",
2331
+ country: pii.permanentAddress.country ?? ""
2332
+ };
2333
+ }
2334
+ function hasAnyFieldValue(fields) {
2335
+ return Object.values(fields).some((value) => value.trim() !== "");
2336
+ }
2337
+ function toSubmissionFields(fields, addressParts) {
2338
+ return {
2339
+ [FIELD_KEYS.fullLegalName]: fields.fullLegalName,
2340
+ [FIELD_KEYS.dob]: fields.dob,
2341
+ [FIELD_KEYS.countryOfCitizenship]: fields.countryOfCitizenship,
2342
+ [FIELD_KEYS.taxId]: fields.taxId,
2343
+ [FIELD_KEYS.permanentAddress]: fields.permanentAddress,
2344
+ City: addressParts.city,
2345
+ Country: addressParts.country,
2346
+ Signature: fields.fullLegalName,
2347
+ Date: formatUsDate(/* @__PURE__ */ new Date())
2348
+ };
2349
+ }
2350
+ function useTaxDocument({
2351
+ isOpen
2352
+ }) {
2353
+ const { coinlist, isReady } = useCoinList();
2354
+ const [state, setState] = useState6(LOADING_STATE3);
2355
+ useEffect7(() => {
2356
+ let isCancelled = false;
2357
+ if (!isOpen) {
2358
+ return () => {
2359
+ isCancelled = true;
2360
+ };
2361
+ }
2362
+ if (!isReady) {
2363
+ setState(LOADING_STATE3);
2364
+ return () => {
2365
+ isCancelled = true;
2366
+ };
2367
+ }
2368
+ setState(LOADING_STATE3);
2369
+ coinlist.fetchPii().then((pii) => {
2370
+ if (isCancelled) return;
2371
+ if (pii.kind === "company") {
2372
+ setState({ type: "SIGN_ONLY", sign: IDLE_SIGN2 });
2373
+ return;
2374
+ }
2375
+ const fields = mapPiiToFields(pii);
2376
+ setState({
2377
+ type: "REVIEW",
2378
+ fields,
2379
+ addressParts: addressPartsFromPii(pii),
2380
+ piiUnavailable: !hasAnyFieldValue(fields),
2381
+ sign: IDLE_SIGN2
2382
+ });
2383
+ }).catch((error) => {
2384
+ if (isCancelled) return;
2385
+ setState({
2386
+ type: "ERROR",
2387
+ reason: error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error"
2388
+ });
2389
+ });
2390
+ return () => {
2391
+ isCancelled = true;
2392
+ };
2393
+ }, [coinlist, isReady, isOpen]);
2394
+ const onEditField = useCallback3(
2395
+ (field, value) => {
2396
+ setState(
2397
+ (prev) => prev.type === "EDITING" ? { ...prev, fields: { ...prev.fields, [field]: value } } : prev
2398
+ );
2399
+ },
2400
+ []
2401
+ );
2402
+ const onStartEdit = useCallback3(() => {
2403
+ setState(
2404
+ (prev) => prev.type === "REVIEW" ? {
2405
+ type: "EDITING",
2406
+ fields: prev.fields,
2407
+ original: prev.fields,
2408
+ addressParts: prev.addressParts,
2409
+ piiUnavailable: prev.piiUnavailable
2410
+ } : prev
2411
+ );
2412
+ }, []);
2413
+ const onSaveEdit = useCallback3(() => {
2414
+ setState(
2415
+ (prev) => prev.type === "EDITING" ? {
2416
+ type: "REVIEW",
2417
+ fields: prev.fields,
2418
+ addressParts: prev.addressParts,
2419
+ piiUnavailable: prev.piiUnavailable,
2420
+ sign: IDLE_SIGN2
2421
+ } : prev
2422
+ );
2423
+ }, []);
2424
+ const onCancelEdit = useCallback3(() => {
2425
+ setState(
2426
+ (prev) => prev.type === "EDITING" ? {
2427
+ type: "REVIEW",
2428
+ fields: prev.original,
2429
+ addressParts: prev.addressParts,
2430
+ piiUnavailable: prev.piiUnavailable,
2431
+ sign: IDLE_SIGN2
2432
+ } : prev
2433
+ );
2434
+ }, []);
2435
+ const onSign = useCallback3(() => {
2436
+ if (state.type !== "REVIEW" && state.type !== "SIGN_ONLY") return;
2437
+ if (state.type === "REVIEW" && state.fields.dob.trim() !== "" && !isValidUsDate(state.fields.dob)) {
2438
+ setState({
2439
+ ...state,
2440
+ sign: { type: "idle", error: DOB_INVALID_MESSAGE }
2441
+ });
2442
+ return;
2443
+ }
2444
+ setState({ ...state, sign: { type: "signing" } });
2445
+ coinlist.submitDocument(
2446
+ "tax_certification",
2447
+ state.type === "REVIEW" ? toSubmissionFields(state.fields, state.addressParts) : {}
2448
+ ).then((submission) => {
2449
+ setState({ type: "SUBMITTED", submission });
2450
+ }).catch(() => {
2451
+ setState(
2452
+ (prev) => prev.type === "REVIEW" || prev.type === "SIGN_ONLY" ? { ...prev, sign: { type: "idle", error: SIGN_FAILED_MESSAGE } } : prev
2453
+ );
2454
+ });
2455
+ }, [state, coinlist]);
2456
+ return { state, onEditField, onStartEdit, onSaveEdit, onCancelEdit, onSign };
2457
+ }
2458
+
2459
+ // src/client/components/requirements/TaxDocumentModal.tsx
2460
+ import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
2461
+ var FIELD_ROWS = [
2462
+ { field: "fullLegalName", label: "Full legal name" },
2463
+ { field: "dob", label: "Date of birth", placeholder: "MM/DD/YYYY" },
2464
+ { field: "countryOfCitizenship", label: "Country of citizenship" },
2465
+ { field: "taxId", label: "Tax ID" },
2466
+ { field: "permanentAddress", label: "Permanent address" }
2467
+ ];
2468
+ function TaxDocumentModal({
2469
+ isOpen,
2470
+ onClose,
2471
+ onSubmitted,
2472
+ className
2473
+ }) {
2474
+ const { state, onEditField, onStartEdit, onSaveEdit, onCancelEdit, onSign } = useTaxDocument({ isOpen });
2475
+ useEffect8(() => {
2476
+ if (state.type === "SUBMITTED") {
2477
+ onSubmitted?.(state.submission);
2478
+ onClose();
2479
+ }
2480
+ }, [state]);
2481
+ if (!isOpen || state.type === "SUBMITTED") return null;
2482
+ return /* @__PURE__ */ jsx18("div", { className: "clcosdk:fixed clcosdk:inset-0 clcosdk:z-50 clcosdk:flex clcosdk:items-center clcosdk:justify-center clcosdk:bg-black/50 clcosdk:p-4", children: /* @__PURE__ */ jsxs14(
2483
+ "div",
2484
+ {
2485
+ className: cn(
2486
+ "clcosdk:flex clcosdk:w-full clcosdk:max-w-md clcosdk:flex-col clcosdk:gap-6 clcosdk:rounded-2xl clcosdk:bg-background clcosdk:p-6",
2487
+ className
2488
+ ),
2489
+ children: [
2490
+ /* @__PURE__ */ jsxs14("div", { className: "clcosdk:flex clcosdk:items-start clcosdk:justify-between clcosdk:gap-4", children: [
2491
+ /* @__PURE__ */ jsx18(TaxDocumentModalHeading, { state }),
2492
+ /* @__PURE__ */ jsx18(CloseButton, { onClick: onClose })
2493
+ ] }),
2494
+ state.type === "LOADING" && /* @__PURE__ */ jsx18(LoadingScreen, {}),
2495
+ state.type === "ERROR" && /* @__PURE__ */ jsx18(ErrorScreen, { reason: state.reason }),
2496
+ state.type === "REVIEW" && /* @__PURE__ */ jsx18(
2497
+ ReviewScreen,
2498
+ {
2499
+ fields: state.fields,
2500
+ piiUnavailable: state.piiUnavailable,
2501
+ sign: state.sign,
2502
+ onStartEdit,
2503
+ onSign
2504
+ }
2505
+ ),
2506
+ state.type === "EDITING" && /* @__PURE__ */ jsx18(
2507
+ EditScreen,
2508
+ {
2509
+ fields: state.fields,
2510
+ onEditField,
2511
+ onSaveEdit,
2512
+ onCancelEdit
2513
+ }
2514
+ ),
2515
+ state.type === "SIGN_ONLY" && /* @__PURE__ */ jsx18(SignOnlyScreen, { sign: state.sign, onSign })
2516
+ ]
2517
+ }
2518
+ ) });
2519
+ }
2520
+ function TaxDocumentModalHeading({
2521
+ state
2522
+ }) {
2523
+ const title = state.type === "EDITING" ? "Edit your W-8BEN" : state.type === "REVIEW" ? "Confirm your W-8BEN" : state.type === "SIGN_ONLY" ? "Confirm your W-8BEN-E" : "Tax document";
2524
+ return /* @__PURE__ */ jsx18("h3", { className: cn(typeClasses.h3, "clcosdk:text-text-primary"), children: title });
2525
+ }
2526
+ function LoadingScreen() {
2527
+ return /* @__PURE__ */ jsx18(
2528
+ "output",
2529
+ {
2530
+ "aria-live": "polite",
2531
+ className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-4",
2532
+ children: FIELD_ROWS.map(({ field }) => /* @__PURE__ */ jsxs14(
2533
+ "div",
2534
+ {
2535
+ className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-1",
2536
+ children: [
2537
+ /* @__PURE__ */ jsx18("div", { className: "clcosdk:h-3 clcosdk:w-28 clcosdk:animate-pulse clcosdk:rounded clcosdk:bg-surface" }),
2538
+ /* @__PURE__ */ jsx18("div", { className: "clcosdk:h-5 clcosdk:w-48 clcosdk:animate-pulse clcosdk:rounded clcosdk:bg-surface" })
2539
+ ]
2540
+ },
2541
+ field
2542
+ ))
2543
+ }
2544
+ );
2545
+ }
2546
+ function ErrorScreen({
2547
+ reason
2548
+ }) {
2549
+ return /* @__PURE__ */ jsx18(
2550
+ AlertBanner,
2551
+ {
2552
+ variant: "error",
2553
+ icon: true,
2554
+ content: reason === "not-authenticated" ? "Sign in to complete your tax document." : "Unable to load your tax information right now. Please try again."
2555
+ }
2556
+ );
2557
+ }
2558
+ function ReviewScreen({
2559
+ fields,
2560
+ piiUnavailable,
2561
+ sign,
2562
+ onStartEdit,
2563
+ onSign
2564
+ }) {
2565
+ return /* @__PURE__ */ jsxs14("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-6", children: [
2566
+ /* @__PURE__ */ jsx18("p", { className: cn(typeClasses.body, "clcosdk:text-text-secondary"), children: "Review your information below. If anything looks incorrect, edit before signing." }),
2567
+ piiUnavailable && /* @__PURE__ */ jsx18(
2568
+ AlertBanner,
2569
+ {
2570
+ variant: "info",
2571
+ icon: true,
2572
+ content: "We don't have this information on file yet \u2014 please fill it in below."
2573
+ }
2574
+ ),
2575
+ /* @__PURE__ */ jsx18("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-4 clcosdk:border-t clcosdk:border-divider clcosdk:pt-4", children: FIELD_ROWS.map(({ field, label }) => /* @__PURE__ */ jsxs14(
2576
+ "div",
2577
+ {
2578
+ className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-1",
2579
+ children: [
2580
+ /* @__PURE__ */ jsx18(
2581
+ "span",
2582
+ {
2583
+ className: cn(typeClasses.label, "clcosdk:text-text-secondary"),
2584
+ children: label
2585
+ }
2586
+ ),
2587
+ /* @__PURE__ */ jsx18("span", { className: cn(typeClasses.body, "clcosdk:text-text-primary"), children: fields[field] || "\u2014" })
2588
+ ]
2589
+ },
2590
+ field
2591
+ )) }),
2592
+ /* @__PURE__ */ jsx18("p", { className: cn(typeClasses.caption, "clcosdk:text-text-secondary"), children: "By signing, you certify that the information above is accurate and that you are the beneficial owner of the income this form relates to. This document cannot be edited once signed." }),
2593
+ sign.type === "idle" && sign.error && /* @__PURE__ */ jsx18(AlertBanner, { variant: "error", icon: true, content: sign.error }),
2594
+ /* @__PURE__ */ jsxs14("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-2", children: [
2595
+ /* @__PURE__ */ jsx18(
2596
+ ClButton,
2597
+ {
2598
+ fullWidth: true,
2599
+ onClick: onSign,
2600
+ isLoading: sign.type === "signing",
2601
+ loadingText: "Signing...",
2602
+ children: "Sign W-8BEN"
2603
+ }
2604
+ ),
2605
+ /* @__PURE__ */ jsx18(
2606
+ ClButton,
2607
+ {
2608
+ fullWidth: true,
2609
+ variant: "secondary",
2610
+ onClick: onStartEdit,
2611
+ disabled: sign.type === "signing",
2612
+ children: "Edit information"
2613
+ }
2614
+ )
2615
+ ] })
2616
+ ] });
2617
+ }
2618
+ function EditScreen({
2619
+ fields,
2620
+ onEditField,
2621
+ onSaveEdit,
2622
+ onCancelEdit
2623
+ }) {
2624
+ return /* @__PURE__ */ jsxs14("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-6", children: [
2625
+ /* @__PURE__ */ jsx18("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-4 clcosdk:border-t clcosdk:border-divider clcosdk:pt-4", children: FIELD_ROWS.map(({ field, label, placeholder }) => /* @__PURE__ */ jsxs14(
2626
+ "label",
2627
+ {
2628
+ className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-1",
2629
+ children: [
2630
+ /* @__PURE__ */ jsx18(
2631
+ "span",
2632
+ {
2633
+ className: cn(typeClasses.label, "clcosdk:text-text-secondary"),
2634
+ children: label
2635
+ }
2636
+ ),
2637
+ /* @__PURE__ */ jsx18(
2638
+ "input",
2639
+ {
2640
+ type: "text",
2641
+ value: fields[field],
2642
+ placeholder,
2643
+ onChange: (e) => onEditField(field, e.target.value),
2644
+ className: cn(
2645
+ typeClasses.body,
2646
+ "clcosdk:rounded-lg clcosdk:border clcosdk:border-border clcosdk:bg-background clcosdk:px-3 clcosdk:py-2 clcosdk:text-text-primary clcosdk:focus-visible:outline-none clcosdk:focus-visible:ring-2 clcosdk:focus-visible:ring-gray-400"
2647
+ )
2648
+ }
2649
+ )
2650
+ ]
2651
+ },
2652
+ field
2653
+ )) }),
2654
+ /* @__PURE__ */ jsxs14("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-2", children: [
2655
+ /* @__PURE__ */ jsx18(ClButton, { fullWidth: true, onClick: onSaveEdit, children: "Save & review" }),
2656
+ /* @__PURE__ */ jsx18(ClButton, { fullWidth: true, variant: "secondary", onClick: onCancelEdit, children: "Cancel" })
2657
+ ] })
2658
+ ] });
2659
+ }
2660
+ function SignOnlyScreen({
2661
+ sign,
2662
+ onSign
2663
+ }) {
2664
+ return /* @__PURE__ */ jsxs14("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-6", children: [
2665
+ /* @__PURE__ */ jsx18("p", { className: cn(typeClasses.body, "clcosdk:text-text-secondary"), children: "As an entity investor, you must complete a W-8BEN-E to confirm your foreign tax status and claim applicable treaty benefits. You'll receive an email to complete the signing." }),
2666
+ sign.type === "idle" && sign.error && /* @__PURE__ */ jsx18(AlertBanner, { variant: "error", icon: true, content: sign.error }),
2667
+ /* @__PURE__ */ jsx18(
2668
+ ClButton,
2669
+ {
2670
+ fullWidth: true,
2671
+ onClick: onSign,
2672
+ isLoading: sign.type === "signing",
2673
+ loadingText: "Signing...",
2674
+ children: "Sign W-8BEN-E"
2675
+ }
2676
+ )
2677
+ ] });
2678
+ }
2679
+
2680
+ // src/client/hooks/useOptionAddresses.ts
2681
+ import { useCallback as useCallback4, useEffect as useEffect9, useState as useState7 } from "react";
2682
+ var LOADING_STATE4 = { type: "LOADING" };
2683
+ var EMPTY_STATE = {
2684
+ type: "CONTENT",
2685
+ addresses: []
2686
+ };
2687
+ function useOptionAddresses(offerId, offerOptionId, options = {}) {
2688
+ const { coinlist, isReady } = useCoinList();
2689
+ const { data, enabled = true } = options;
2690
+ const [addressesState, setAddressesState] = useState7(
2691
+ data !== void 0 ? { type: "CONTENT", addresses: data } : LOADING_STATE4
2692
+ );
2693
+ const [fetchKey, setFetchKey] = useState7(0);
2694
+ const refetch = useCallback4(() => setFetchKey((k) => k + 1), []);
2695
+ const disconnect = useCallback4(
2696
+ async (addressId) => {
2697
+ await coinlist.removeOptionAddress(offerId, addressId);
2698
+ refetch();
2699
+ },
2700
+ [coinlist, offerId, refetch]
2701
+ );
2702
+ useEffect9(() => {
2703
+ let isCancelled = false;
2704
+ if (!enabled) {
2705
+ setAddressesState(
2706
+ data !== void 0 ? { type: "CONTENT", addresses: data } : EMPTY_STATE
2707
+ );
2708
+ return () => {
2709
+ isCancelled = true;
2710
+ };
2711
+ }
2712
+ if (!isReady) {
2713
+ if (data === void 0) {
2714
+ setAddressesState(LOADING_STATE4);
2715
+ }
2716
+ return () => {
2717
+ isCancelled = true;
2718
+ };
2719
+ }
2720
+ if (data !== void 0 && fetchKey === 0) {
2721
+ return () => {
2722
+ isCancelled = true;
2723
+ };
2724
+ }
2725
+ if (coinlist.getAuthState() === "logged-out") {
2726
+ setAddressesState({ type: "ERROR", reason: "not-authenticated" });
2727
+ return () => {
2728
+ isCancelled = true;
2729
+ };
2730
+ }
2731
+ setAddressesState(LOADING_STATE4);
2732
+ coinlist.listOptionAddresses(offerId, offerOptionId).then((addresses) => {
2733
+ if (!isCancelled) {
2734
+ setAddressesState({ type: "CONTENT", addresses });
2735
+ }
2736
+ }).catch((error) => {
2737
+ if (!isCancelled) {
2738
+ const reason = error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error";
2739
+ setAddressesState({ type: "ERROR", reason });
2740
+ }
2741
+ });
2742
+ return () => {
2743
+ isCancelled = true;
2744
+ };
2745
+ }, [coinlist, isReady, enabled, offerId, offerOptionId, fetchKey]);
2746
+ return { addressesState, refetch, disconnect };
2747
+ }
1237
2748
 
1238
2749
  // src/client/hooks/useRequirements.ts
1239
- import { useCallback, useEffect as useEffect3, useState as useState3 } from "react";
1240
- var LOADING_STATE2 = { type: "LOADING" };
2750
+ import { useCallback as useCallback5, useEffect as useEffect10, useState as useState8 } from "react";
2751
+ var LOADING_STATE5 = { type: "LOADING" };
1241
2752
  function useRequirements(offerId, options = {}) {
1242
2753
  const { coinlist, isReady } = useCoinList();
1243
2754
  const { data } = options;
1244
- const [requirementsState, setRequirementsState] = useState3(
1245
- data !== void 0 ? { type: "CONTENT", ...data } : LOADING_STATE2
2755
+ const [requirementsState, setRequirementsState] = useState8(
2756
+ data !== void 0 ? { type: "CONTENT", ...data } : LOADING_STATE5
1246
2757
  );
1247
- const [fetchKey, setFetchKey] = useState3(0);
1248
- const refetch = useCallback(() => setFetchKey((k) => k + 1), []);
1249
- useEffect3(() => {
2758
+ const [fetchKey, setFetchKey] = useState8(0);
2759
+ const refetch = useCallback5(() => setFetchKey((k) => k + 1), []);
2760
+ useEffect10(() => {
1250
2761
  let isCancelled = false;
1251
2762
  if (!isReady) {
1252
2763
  if (data === void 0) {
1253
- setRequirementsState(LOADING_STATE2);
2764
+ setRequirementsState(LOADING_STATE5);
1254
2765
  }
1255
2766
  return () => {
1256
2767
  isCancelled = true;
@@ -1261,7 +2772,13 @@ function useRequirements(offerId, options = {}) {
1261
2772
  isCancelled = true;
1262
2773
  };
1263
2774
  }
1264
- setRequirementsState(LOADING_STATE2);
2775
+ if (coinlist.getAuthState() === "logged-out") {
2776
+ setRequirementsState({ type: "ERROR", reason: "not-authenticated" });
2777
+ return () => {
2778
+ isCancelled = true;
2779
+ };
2780
+ }
2781
+ setRequirementsState(LOADING_STATE5);
1265
2782
  Promise.all([
1266
2783
  coinlist.fetchOfferRequirements(offerId),
1267
2784
  coinlist.fetchRequirementStatuses(offerId)
@@ -1287,7 +2804,8 @@ function useRequirements(offerId, options = {}) {
1287
2804
  }
1288
2805
 
1289
2806
  // src/client/components/requirements/RequirementsChecklist.tsx
1290
- import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
2807
+ import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
2808
+ var isWalletRequirement = (requirement) => RequirementVariant.fromType(requirement.type) === "wallet";
1291
2809
  var DEFAULT_LABELS = {
1292
2810
  kyc_approved: "KYC Verification",
1293
2811
  identity_verified: "Identity Verification",
@@ -1296,7 +2814,8 @@ var DEFAULT_LABELS = {
1296
2814
  external_wallet: "External Wallet",
1297
2815
  whitelisted_wallet: "Whitelisted Wallet",
1298
2816
  jurisdiction: "Jurisdiction Check",
1299
- accreditation: "Accreditation"
2817
+ accreditation: "Accreditation",
2818
+ document: "Document"
1300
2819
  };
1301
2820
  var DEFAULT_DESCRIPTIONS = {
1302
2821
  kyc_approved: "Complete Know Your Customer verification.",
@@ -1306,9 +2825,39 @@ var DEFAULT_DESCRIPTIONS = {
1306
2825
  external_wallet: "Connect an external wallet.",
1307
2826
  whitelisted_wallet: "Connect a whitelisted wallet.",
1308
2827
  jurisdiction: "Confirm your jurisdiction eligibility.",
1309
- accreditation: "Verify your accreditation status."
2828
+ accreditation: "Verify your accreditation status.",
2829
+ document: "Confirm your Tax Documents."
1310
2830
  };
1311
- function RequirementsChecklist({
2831
+ var VERIFICATION_POLL_INTERVAL_MS = 5e3;
2832
+ var VERIFICATION_POLL_TIMEOUT_MS = 12e4;
2833
+ function sleep(ms) {
2834
+ return new Promise((resolve) => setTimeout(resolve, ms));
2835
+ }
2836
+ function VerificationOverlay({
2837
+ onClose,
2838
+ children
2839
+ }) {
2840
+ return /* @__PURE__ */ jsx19(
2841
+ "div",
2842
+ {
2843
+ role: "dialog",
2844
+ "aria-modal": "true",
2845
+ "aria-label": "Identity verification",
2846
+ className: "clcosdk:fixed clcosdk:inset-0 clcosdk:z-50 clcosdk:flex clcosdk:items-center clcosdk:justify-center clcosdk:bg-overlay clcosdk:p-4",
2847
+ children: /* @__PURE__ */ jsxs15("div", { className: "clcosdk:relative clcosdk:flex clcosdk:max-h-[92vh] clcosdk:w-full clcosdk:max-w-[760px] clcosdk:flex-col clcosdk:overflow-y-auto clcosdk:rounded-2xl clcosdk:bg-background clcosdk:p-6 clcosdk:pt-14", children: [
2848
+ /* @__PURE__ */ jsx19(
2849
+ CloseButton,
2850
+ {
2851
+ onClick: onClose,
2852
+ className: "clcosdk:absolute clcosdk:top-4 clcosdk:right-4"
2853
+ }
2854
+ ),
2855
+ children
2856
+ ] })
2857
+ }
2858
+ );
2859
+ }
2860
+ function RequirementsChecklistBody({
1312
2861
  offerId,
1313
2862
  optionId,
1314
2863
  title,
@@ -1316,38 +2865,106 @@ function RequirementsChecklist({
1316
2865
  onContinue,
1317
2866
  onRequirementActionOverride,
1318
2867
  onContactSupportOverride,
2868
+ wallet,
2869
+ onRequestConnect,
1319
2870
  getLabel,
1320
2871
  getDescription,
1321
2872
  loading,
2873
+ unauthenticatedState,
1322
2874
  error,
1323
2875
  className,
1324
- data
2876
+ data,
2877
+ identityVerificationOptions
1325
2878
  }) {
1326
2879
  const { coinlist } = useCoinList();
1327
- const { requirementsState } = useRequirements(offerId, { data });
1328
- const [expandedIndex, setExpandedIndex] = useState4(null);
1329
- const onRequirementAction = onRequirementActionOverride !== void 0 ? onRequirementActionOverride : (requirement) => coinlist.handleRequirement(requirement);
2880
+ const { requirementsState, refetch } = useRequirements(offerId, { data });
2881
+ const [expandedIndex, setExpandedIndex] = useState9(null);
2882
+ const [taxDocumentOpen, setTaxDocumentOpen] = useState9(false);
2883
+ const [walletConnectOpen, setConnectWalletOpen] = useState9(false);
2884
+ const [verifyingRequirementId, setVerifyingRequirementId] = useState9(null);
2885
+ const isMountedRef = useRef4(true);
2886
+ useEffect11(() => {
2887
+ isMountedRef.current = true;
2888
+ return () => {
2889
+ isMountedRef.current = false;
2890
+ };
2891
+ }, []);
2892
+ const [hasWalletRequirement, setHasWalletRequirement] = useState9(false);
2893
+ useEffect11(() => {
2894
+ if (requirementsState.type === "CONTENT") {
2895
+ setHasWalletRequirement(
2896
+ (requirementsState.requirements[optionId] ?? []).some(
2897
+ isWalletRequirement
2898
+ )
2899
+ );
2900
+ }
2901
+ }, [requirementsState, optionId]);
2902
+ const {
2903
+ addressesState,
2904
+ refetch: refetchAddresses,
2905
+ disconnect
2906
+ } = useOptionAddresses(offerId, optionId, {
2907
+ enabled: hasWalletRequirement
2908
+ });
2909
+ const optionAddresses = addressesState.type === "CONTENT" ? addressesState.addresses : [];
2910
+ const walletsStatus = addressesState.type === "ERROR" ? "error" : addressesState.type === "LOADING" ? "loading" : "ready";
2911
+ const onRemoveWallet = async (id) => {
2912
+ await disconnect(OfferOptionAddressId(id));
2913
+ refetch();
2914
+ };
2915
+ const onRequirementAction = onRequirementActionOverride !== void 0 ? onRequirementActionOverride : (requirement) => {
2916
+ if (requirement.type === "document") {
2917
+ setTaxDocumentOpen(true);
2918
+ return;
2919
+ }
2920
+ if ((requirement.type === "external_wallet" || requirement.type === "whitelisted_wallet") && wallet !== void 0 && (wallet !== null || onRequestConnect !== void 0)) {
2921
+ setConnectWalletOpen(true);
2922
+ return;
2923
+ }
2924
+ coinlist.handleRequirement(requirement);
2925
+ };
1330
2926
  const onContactSupport = onContactSupportOverride !== void 0 ? onContactSupportOverride : () => coinlist.contactSupport();
2927
+ const awaitVerificationResult = (requirementId, statusBeforeSubmit) => {
2928
+ void (async () => {
2929
+ const deadline = Date.now() + VERIFICATION_POLL_TIMEOUT_MS;
2930
+ while (Date.now() < deadline) {
2931
+ await sleep(VERIFICATION_POLL_INTERVAL_MS);
2932
+ if (!isMountedRef.current) return;
2933
+ try {
2934
+ const statuses2 = await coinlist.fetchRequirementStatuses(offerId);
2935
+ const current = statuses2.find((s) => s.id === requirementId)?.status;
2936
+ if (current !== void 0 && current !== statusBeforeSubmit) break;
2937
+ } catch (_) {
2938
+ }
2939
+ }
2940
+ if (isMountedRef.current) {
2941
+ setVerifyingRequirementId(null);
2942
+ refetch();
2943
+ }
2944
+ })();
2945
+ };
1331
2946
  if (requirementsState.type === "LOADING") {
1332
2947
  if (loading) return loading;
1333
- return /* @__PURE__ */ jsx15(
2948
+ return /* @__PURE__ */ jsx19(
1334
2949
  "output",
1335
2950
  {
1336
2951
  "aria-live": "polite",
1337
2952
  className: "clcosdk:flex clcosdk:min-h-40 clcosdk:items-center clcosdk:justify-center clcosdk:rounded-2xl clcosdk:border clcosdk:border-border clcosdk:bg-background clcosdk:p-6",
1338
- children: /* @__PURE__ */ jsx15("p", { className: cn(typeClasses.body, "clcosdk:text-text-secondary"), children: "Loading requirements..." })
2953
+ children: /* @__PURE__ */ jsx19("p", { className: cn(typeClasses.body, "clcosdk:text-text-secondary"), children: "Loading requirements..." })
1339
2954
  }
1340
2955
  );
1341
2956
  }
1342
2957
  if (requirementsState.type === "ERROR") {
2958
+ if (requirementsState.reason === "not-authenticated") {
2959
+ return unauthenticatedState !== void 0 ? unauthenticatedState : /* @__PURE__ */ jsx19(CoinListSignInCard, {});
2960
+ }
1343
2961
  if (error) return error;
1344
- const errorMessage = requirementsState.reason === "not-authenticated" ? "Sign in to view requirements." : "Unable to load requirements right now. Please try again.";
1345
- return /* @__PURE__ */ jsx15(
2962
+ return /* @__PURE__ */ jsx19(
1346
2963
  AlertBanner,
1347
2964
  {
1348
2965
  variant: "error",
1349
2966
  icon: true,
1350
- content: errorMessage,
2967
+ content: "Unable to load requirements right now. Please try again.",
1351
2968
  className: "clcosdk:w-full clcosdk:max-w-[28rem]"
1352
2969
  }
1353
2970
  );
@@ -1358,7 +2975,7 @@ function RequirementsChecklist({
1358
2975
  const optionStatuses = statuses.filter((s) => requirementIds.has(s.id));
1359
2976
  const statusByRequirementId = new Map(optionStatuses.map((s) => [s.id, s]));
1360
2977
  const checklistStatus = ChecklistStatus.derive(optionStatuses);
1361
- return /* @__PURE__ */ jsxs11(
2978
+ return /* @__PURE__ */ jsxs15(
1362
2979
  "div",
1363
2980
  {
1364
2981
  className: cn(
@@ -1366,17 +2983,20 @@ function RequirementsChecklist({
1366
2983
  className
1367
2984
  ),
1368
2985
  children: [
1369
- /* @__PURE__ */ jsxs11("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-2", children: [
1370
- /* @__PURE__ */ jsx15("h3", { className: cn(typeClasses.h3, "clcosdk:text-text-primary"), children: title }),
1371
- /* @__PURE__ */ jsx15("p", { className: cn(typeClasses.body, "clcosdk:text-text-secondary"), children: description })
2986
+ /* @__PURE__ */ jsxs15("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-2", children: [
2987
+ /* @__PURE__ */ jsx19("h3", { className: cn(typeClasses.h3, "clcosdk:text-text-primary"), children: title }),
2988
+ /* @__PURE__ */ jsx19("p", { className: cn(typeClasses.body, "clcosdk:text-text-secondary"), children: description })
1372
2989
  ] }),
1373
- /* @__PURE__ */ jsx15("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:divide-y clcosdk:divide-divider", children: requirements.map((req, index) => {
2990
+ /* @__PURE__ */ jsx19("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:divide-y clcosdk:divide-divider", children: requirements.map((req, index) => {
1374
2991
  const statusInfo = statusByRequirementId.get(req.id);
1375
2992
  const label = getLabel ? getLabel(req) : DEFAULT_LABELS[req.type];
1376
2993
  const itemDescription = (getDescription ? getDescription(req) : null) ?? DEFAULT_DESCRIPTIONS[req.type];
2994
+ const inlineVerification = statusInfo?.kycLevel !== void 0 && onRequirementActionOverride === void 0;
1377
2995
  let onActionBound;
1378
2996
  if (onRequirementAction === null) {
1379
2997
  onActionBound = null;
2998
+ } else if (inlineVerification) {
2999
+ onActionBound = () => setVerifyingRequirementId(req.id);
1380
3000
  } else if (onRequirementAction) {
1381
3001
  onActionBound = () => onRequirementAction(req);
1382
3002
  }
@@ -1386,24 +3006,28 @@ function RequirementsChecklist({
1386
3006
  } else if (onContactSupport) {
1387
3007
  onContactSupportBound = () => onContactSupport(req);
1388
3008
  }
1389
- return /* @__PURE__ */ jsx15(
3009
+ const walletRequirement = isWalletRequirement(req);
3010
+ return /* @__PURE__ */ jsx19(
1390
3011
  RequirementItem,
1391
3012
  {
1392
3013
  ui: RequirementItemUi.fromDomain(
1393
3014
  req,
1394
3015
  statusInfo,
1395
3016
  label,
1396
- itemDescription
3017
+ itemDescription,
3018
+ walletRequirement ? optionAddresses : []
1397
3019
  ),
1398
3020
  expanded: expandedIndex === index,
1399
3021
  onToggle: () => setExpandedIndex((prev) => prev === index ? null : index),
1400
3022
  onAction: onActionBound,
3023
+ onRemoveWallet: walletRequirement ? onRemoveWallet : void 0,
3024
+ walletsStatus: walletRequirement ? walletsStatus : void 0,
1401
3025
  onContactSupport: onContactSupportBound
1402
3026
  },
1403
3027
  req.id
1404
3028
  );
1405
3029
  }) }),
1406
- checklistStatus === "ineligible" && /* @__PURE__ */ jsx15(
3030
+ checklistStatus === "ineligible" && /* @__PURE__ */ jsx19(
1407
3031
  AlertBanner,
1408
3032
  {
1409
3033
  variant: "error",
@@ -1411,7 +3035,7 @@ function RequirementsChecklist({
1411
3035
  content: "You are not eligible to participate."
1412
3036
  }
1413
3037
  ),
1414
- onContinue && /* @__PURE__ */ jsx15(
3038
+ onContinue && /* @__PURE__ */ jsx19(
1415
3039
  ClButton,
1416
3040
  {
1417
3041
  fullWidth: true,
@@ -1419,24 +3043,242 @@ function RequirementsChecklist({
1419
3043
  onClick: onContinue,
1420
3044
  children: "Continue"
1421
3045
  }
3046
+ ),
3047
+ /* @__PURE__ */ jsx19(
3048
+ TaxDocumentModal,
3049
+ {
3050
+ isOpen: taxDocumentOpen,
3051
+ onClose: () => setTaxDocumentOpen(false),
3052
+ onSubmitted: () => refetch()
3053
+ }
3054
+ ),
3055
+ verifyingRequirementId !== null && /* @__PURE__ */ jsx19(VerificationOverlay, { onClose: () => setVerifyingRequirementId(null), children: /* @__PURE__ */ jsx19(
3056
+ IdentityVerification,
3057
+ {
3058
+ levelName: identityVerificationOptions?.levelName ?? statusByRequirementId.get(verifyingRequirementId)?.kycLevel,
3059
+ reset: statusByRequirementId.get(verifyingRequirementId)?.kycReset ?? false,
3060
+ locale: identityVerificationOptions?.locale,
3061
+ onSubmitted: () => awaitVerificationResult(
3062
+ verifyingRequirementId,
3063
+ statusByRequirementId.get(verifyingRequirementId)?.status ?? "not_started"
3064
+ )
3065
+ }
3066
+ ) }),
3067
+ /* @__PURE__ */ jsx19(
3068
+ ConnectWalletModal,
3069
+ {
3070
+ isOpen: walletConnectOpen,
3071
+ onClose: () => setConnectWalletOpen(false),
3072
+ offerId,
3073
+ optionId,
3074
+ wallet: wallet ?? null,
3075
+ onRequestConnect,
3076
+ onConnected: () => {
3077
+ refetch();
3078
+ refetchAddresses();
3079
+ }
3080
+ }
1422
3081
  )
1423
3082
  ]
1424
3083
  }
1425
3084
  );
1426
3085
  }
3086
+ function RequirementsChecklist(props) {
3087
+ return /* @__PURE__ */ jsx19(CoinListStyleScope, { children: /* @__PURE__ */ jsx19(RequirementsChecklistBody, { ...props }) });
3088
+ }
3089
+
3090
+ // src/client/hooks/swap/useSwapOutputToken.ts
3091
+ import { useEffect as useEffect12, useRef as useRef5, useState as useState10 } from "react";
3092
+ var LOADING_STATE6 = { type: "LOADING" };
3093
+ function useSwapOutputToken(options) {
3094
+ const { contractAddress, chain, enabled } = options;
3095
+ const { coinlist, isReady } = useCoinList();
3096
+ const [outputTokenState, setOutputTokenState] = useState10(LOADING_STATE6);
3097
+ const fetchIdRef = useRef5(0);
3098
+ useEffect12(() => {
3099
+ if (!enabled || !isReady) return;
3100
+ const currentFetchId = ++fetchIdRef.current;
3101
+ const load = async () => {
3102
+ try {
3103
+ const outputToken = await coinlist.swap.getOutputToken({
3104
+ contractAddress,
3105
+ chain
3106
+ });
3107
+ if (currentFetchId !== fetchIdRef.current) return;
3108
+ setOutputTokenState({ type: "CONTENT", outputToken });
3109
+ } catch {
3110
+ if (currentFetchId !== fetchIdRef.current) return;
3111
+ setOutputTokenState({ type: "ERROR" });
3112
+ }
3113
+ };
3114
+ load();
3115
+ return () => {
3116
+ ++fetchIdRef.current;
3117
+ };
3118
+ }, [coinlist, isReady, contractAddress, chain, enabled]);
3119
+ return { outputTokenState };
3120
+ }
3121
+
3122
+ // src/client/hooks/swap/useSwapQuote.ts
3123
+ import { useEffect as useEffect13, useRef as useRef6, useState as useState11 } from "react";
3124
+ function useSwapQuote(options) {
3125
+ const {
3126
+ contractAddress,
3127
+ chain,
3128
+ inputAmount,
3129
+ inputTokenAddress,
3130
+ outputTokenDecimals,
3131
+ pollIntervalMs = SWAP_POLL_INTERVAL_MS,
3132
+ enabled
3133
+ } = options;
3134
+ const { coinlist, isReady } = useCoinList();
3135
+ const [quote, setQuote] = useState11(null);
3136
+ const [isLoading, setIsLoading] = useState11(true);
3137
+ const [isRefreshing, setIsRefreshing] = useState11(false);
3138
+ const isFetchingRef = useRef6(false);
3139
+ const hasQuoteRef = useRef6(false);
3140
+ const fetchIdRef = useRef6(0);
3141
+ useEffect13(() => {
3142
+ if (!isReady) return;
3143
+ if (!enabled) {
3144
+ setIsLoading(false);
3145
+ return;
3146
+ }
3147
+ const currentFetchId = ++fetchIdRef.current;
3148
+ isFetchingRef.current = false;
3149
+ const loadQuote = async () => {
3150
+ if (outputTokenDecimals === null) return;
3151
+ if (isFetchingRef.current) return;
3152
+ isFetchingRef.current = true;
3153
+ if (hasQuoteRef.current) {
3154
+ setIsRefreshing(true);
3155
+ }
3156
+ try {
3157
+ const preview = await coinlist.swap.getPreview({
3158
+ contractAddress,
3159
+ chain,
3160
+ inputToken: inputTokenAddress,
3161
+ amount: inputAmount.raw
3162
+ });
3163
+ if (currentFetchId !== fetchIdRef.current) return;
3164
+ setQuote(
3165
+ SwapQuote.fromPreview(
3166
+ preview,
3167
+ inputAmount.decimals,
3168
+ outputTokenDecimals
3169
+ )
3170
+ );
3171
+ if (!hasQuoteRef.current) {
3172
+ hasQuoteRef.current = true;
3173
+ setIsLoading(false);
3174
+ }
3175
+ } catch {
3176
+ } finally {
3177
+ if (currentFetchId === fetchIdRef.current) {
3178
+ isFetchingRef.current = false;
3179
+ setIsRefreshing(false);
3180
+ }
3181
+ }
3182
+ };
3183
+ loadQuote();
3184
+ const interval = setInterval(loadQuote, pollIntervalMs);
3185
+ return () => {
3186
+ clearInterval(interval);
3187
+ ++fetchIdRef.current;
3188
+ setIsRefreshing(false);
3189
+ };
3190
+ }, [
3191
+ coinlist,
3192
+ isReady,
3193
+ contractAddress,
3194
+ chain,
3195
+ inputAmount.raw,
3196
+ inputAmount.decimals,
3197
+ inputTokenAddress,
3198
+ outputTokenDecimals,
3199
+ pollIntervalMs,
3200
+ enabled
3201
+ ]);
3202
+ return { quote, isLoading, isRefreshing };
3203
+ }
3204
+
3205
+ // src/client/hooks/swap/useSwapTokenBalances.ts
3206
+ import { useEffect as useEffect14, useRef as useRef7, useState as useState12 } from "react";
3207
+ function useSwapTokenBalances(options) {
3208
+ const {
3209
+ address,
3210
+ chain,
3211
+ assets,
3212
+ pollIntervalMs = SWAP_POLL_INTERVAL_MS,
3213
+ enabled
3214
+ } = options;
3215
+ const { coinlist, isReady } = useCoinList();
3216
+ const [balances, setBalances] = useState12(/* @__PURE__ */ new Map());
3217
+ const [isLoading, setIsLoading] = useState12(true);
3218
+ const fetchIdRef = useRef7(0);
3219
+ const isFetchingRef = useRef7(false);
3220
+ const assetsKey = assets.join(",");
3221
+ useEffect14(() => {
3222
+ if (!isReady) return;
3223
+ if (!enabled) {
3224
+ setIsLoading(false);
3225
+ return;
3226
+ }
3227
+ const symbols = assetsKey.split(",");
3228
+ const currentFetchId = ++fetchIdRef.current;
3229
+ isFetchingRef.current = false;
3230
+ let isFirstFetch = true;
3231
+ async function fetchBalances() {
3232
+ if (isFetchingRef.current) return;
3233
+ isFetchingRef.current = true;
3234
+ if (isFirstFetch) {
3235
+ setIsLoading(true);
3236
+ }
3237
+ const results = await Promise.allSettled(
3238
+ symbols.map(
3239
+ (symbol) => coinlist.erc20.getTokenBalance({
3240
+ tokenAddress: TOKEN_REGISTRY.contractAddress(symbol, chain),
3241
+ owner: address,
3242
+ chain
3243
+ })
3244
+ )
3245
+ );
3246
+ if (currentFetchId !== fetchIdRef.current) return;
3247
+ isFetchingRef.current = false;
3248
+ const next = /* @__PURE__ */ new Map();
3249
+ symbols.forEach((symbol, i) => {
3250
+ const result = results[i];
3251
+ next.set(
3252
+ symbol,
3253
+ result.status === "fulfilled" ? result.value.balance : null
3254
+ );
3255
+ });
3256
+ setBalances(next);
3257
+ setIsLoading(false);
3258
+ isFirstFetch = false;
3259
+ }
3260
+ fetchBalances();
3261
+ const interval = setInterval(fetchBalances, pollIntervalMs);
3262
+ return () => {
3263
+ clearInterval(interval);
3264
+ ++fetchIdRef.current;
3265
+ };
3266
+ }, [coinlist, isReady, address, chain, assetsKey, pollIntervalMs, enabled]);
3267
+ return { balances, isLoading };
3268
+ }
1427
3269
 
1428
3270
  // src/client/hooks/useCompleteOAuth.ts
1429
- import { useEffect as useEffect4, useRef } from "react";
3271
+ import { useEffect as useEffect15, useRef as useRef8 } from "react";
1430
3272
  function useCompleteOAuth(options) {
1431
3273
  const { coinlist } = useCoinList();
1432
- const postOAuthCompleteRef = useRef(options.postOAuthComplete);
1433
- const onFailureRef = useRef(options.onFailure);
1434
- const onSuccessRef = useRef(options.onSuccess);
3274
+ const postOAuthCompleteRef = useRef8(options.postOAuthComplete);
3275
+ const onFailureRef = useRef8(options.onFailure);
3276
+ const onSuccessRef = useRef8(options.onSuccess);
1435
3277
  postOAuthCompleteRef.current = options.postOAuthComplete;
1436
3278
  onFailureRef.current = options.onFailure;
1437
3279
  onSuccessRef.current = options.onSuccess;
1438
- const hasStartedExchangeRef = useRef(false);
1439
- useEffect4(() => {
3280
+ const hasStartedExchangeRef = useRef8(false);
3281
+ useEffect15(() => {
1440
3282
  if (typeof window === "undefined") return;
1441
3283
  const params = new URLSearchParams(window.location.search);
1442
3284
  if (!params.has("code") && !params.has("error")) return;
@@ -1480,19 +3322,19 @@ function useCompleteOAuth(options) {
1480
3322
  }
1481
3323
 
1482
3324
  // src/client/hooks/useOfferDetails.ts
1483
- import { useEffect as useEffect5, useState as useState5 } from "react";
1484
- var LOADING_STATE3 = { type: "LOADING" };
3325
+ import { useEffect as useEffect16, useState as useState13 } from "react";
3326
+ var LOADING_STATE7 = { type: "LOADING" };
1485
3327
  function useOfferDetails(offerId, options = {}) {
1486
3328
  const { coinlist, isReady } = useCoinList();
1487
3329
  const { data } = options;
1488
- const [offerDetailsState, setOfferDetailsState] = useState5(
1489
- data !== void 0 ? { type: "CONTENT", offerDetail: data } : LOADING_STATE3
3330
+ const [offerDetailsState, setOfferDetailsState] = useState13(
3331
+ data !== void 0 ? { type: "CONTENT", offerDetail: data } : LOADING_STATE7
1490
3332
  );
1491
- useEffect5(() => {
3333
+ useEffect16(() => {
1492
3334
  let isCancelled = false;
1493
3335
  if (!isReady) {
1494
3336
  if (data === void 0) {
1495
- setOfferDetailsState(LOADING_STATE3);
3337
+ setOfferDetailsState(LOADING_STATE7);
1496
3338
  }
1497
3339
  return () => {
1498
3340
  isCancelled = true;
@@ -1503,7 +3345,7 @@ function useOfferDetails(offerId, options = {}) {
1503
3345
  isCancelled = true;
1504
3346
  };
1505
3347
  }
1506
- setOfferDetailsState(LOADING_STATE3);
3348
+ setOfferDetailsState(LOADING_STATE7);
1507
3349
  coinlist.fetchOfferDetails(offerId).then((offerDetail) => {
1508
3350
  if (!isCancelled) {
1509
3351
  setOfferDetailsState({ type: "CONTENT", offerDetail });
@@ -1522,19 +3364,19 @@ function useOfferDetails(offerId, options = {}) {
1522
3364
  }
1523
3365
 
1524
3366
  // src/client/hooks/useParticipations.ts
1525
- import { useEffect as useEffect6, useState as useState6 } from "react";
1526
- var LOADING_STATE4 = { type: "LOADING" };
3367
+ import { useEffect as useEffect17, useState as useState14 } from "react";
3368
+ var LOADING_STATE8 = { type: "LOADING" };
1527
3369
  function useParticipations(offerId, options = {}) {
1528
3370
  const { coinlist, isReady } = useCoinList();
1529
3371
  const { data } = options;
1530
- const [participationsState, setParticipationsState] = useState6(
1531
- data !== void 0 ? { type: "CONTENT", participations: data } : LOADING_STATE4
3372
+ const [participationsState, setParticipationsState] = useState14(
3373
+ data !== void 0 ? { type: "CONTENT", participations: data } : LOADING_STATE8
1532
3374
  );
1533
- useEffect6(() => {
3375
+ useEffect17(() => {
1534
3376
  let isCancelled = false;
1535
3377
  if (!isReady) {
1536
3378
  if (data === void 0) {
1537
- setParticipationsState(LOADING_STATE4);
3379
+ setParticipationsState(LOADING_STATE8);
1538
3380
  }
1539
3381
  return () => {
1540
3382
  isCancelled = true;
@@ -1545,8 +3387,8 @@ function useParticipations(offerId, options = {}) {
1545
3387
  isCancelled = true;
1546
3388
  };
1547
3389
  }
1548
- setParticipationsState(LOADING_STATE4);
1549
- coinlist.fetchParticipations(offerId).then((participations) => {
3390
+ setParticipationsState(LOADING_STATE8);
3391
+ coinlist.tokenSale.fetchParticipations(offerId).then((participations) => {
1550
3392
  if (!isCancelled) {
1551
3393
  setParticipationsState({ type: "CONTENT", participations });
1552
3394
  }
@@ -1564,12 +3406,18 @@ function useParticipations(offerId, options = {}) {
1564
3406
  }
1565
3407
  export {
1566
3408
  ChecklistStatus,
3409
+ ClientSwapNamespaceImpl,
3410
+ ClientTokenSaleNamespaceImpl,
1567
3411
  CoinListClientInitializationError,
1568
3412
  CoinListContext,
1569
3413
  CoinListContextProvider,
1570
3414
  CoinListProvider,
1571
3415
  CoinListSignInCard,
1572
3416
  CoinListStyleScope,
3417
+ ConnectWalletModal,
3418
+ ConnectedWalletList,
3419
+ IdentityVerification,
3420
+ KycToken,
1573
3421
  OAUTH_CODE_VERIFIER_KEY,
1574
3422
  OAUTH_STATE_KEY,
1575
3423
  OfferCard,
@@ -1580,12 +3428,25 @@ export {
1580
3428
  RequirementStatus,
1581
3429
  RequirementVariant,
1582
3430
  RequirementsChecklist,
3431
+ TaxDocumentModal,
3432
+ authorizeWallet,
3433
+ classifyWalletError,
3434
+ connectExternalWalletFlow,
1583
3435
  createCoinListClient,
3436
+ executeSwap,
3437
+ executeTokenSale,
1584
3438
  useCoinList,
1585
3439
  useCompleteOAuth,
3440
+ useConnectWallet,
3441
+ useKycToken,
1586
3442
  useOfferDetails,
1587
3443
  useOffers,
3444
+ useOptionAddresses,
1588
3445
  useParticipations,
1589
- useRequirements
3446
+ useRequirements,
3447
+ useSwapOutputToken,
3448
+ useSwapQuote,
3449
+ useSwapTokenBalances,
3450
+ useTaxDocument
1590
3451
  };
1591
3452
  //# sourceMappingURL=index.js.map