@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.
- package/dist/{chunk-5C4TEVM7.js → chunk-7BJ2HAG7.js} +62 -92
- package/dist/chunk-7BJ2HAG7.js.map +1 -0
- package/dist/{chunk-5E3P7AMH.js → chunk-AAER5LOL.js} +3 -1
- package/dist/chunk-AAER5LOL.js.map +1 -0
- package/dist/chunk-GSSAB4K5.js +644 -0
- package/dist/chunk-GSSAB4K5.js.map +1 -0
- package/dist/chunk-TUZKKFNW.js +836 -0
- package/dist/chunk-TUZKKFNW.js.map +1 -0
- package/dist/client/index.cjs +3203 -412
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +996 -41
- package/dist/client/index.d.ts +996 -41
- package/dist/client/index.js +2069 -208
- package/dist/client/index.js.map +1 -1
- package/dist/collections-CJ24dOda.d.cts +28 -0
- package/dist/collections-ZYLKp8JB.d.ts +28 -0
- package/dist/requirement-CDi5NJI8.d.cts +1036 -0
- package/dist/requirement-CDi5NJI8.d.ts +1036 -0
- package/dist/server/index.cjs +588 -85
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +117 -17
- package/dist/server/index.d.ts +117 -17
- package/dist/server/index.js +92 -40
- package/dist/server/index.js.map +1 -1
- package/dist/shared/index.cjs +1334 -91
- package/dist/shared/index.cjs.map +1 -1
- package/dist/shared/index.d.cts +624 -3
- package/dist/shared/index.d.ts +624 -3
- package/dist/shared/index.js +220 -5
- package/dist/shared/index.js.map +1 -1
- package/package.json +7 -3
- package/dist/chunk-5C4TEVM7.js.map +0 -1
- package/dist/chunk-5E3P7AMH.js.map +0 -1
- package/dist/chunk-7SB2GKEU.js +0 -311
- package/dist/chunk-7SB2GKEU.js.map +0 -1
- package/dist/chunk-UEJVCU2J.js +0 -43
- package/dist/chunk-UEJVCU2J.js.map +0 -1
- package/dist/requirement-Dk6nYN1c.d.cts +0 -389
- package/dist/requirement-Dk6nYN1c.d.ts +0 -389
package/dist/client/index.js
CHANGED
|
@@ -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
|
-
|
|
15
|
+
createKycToken,
|
|
17
16
|
fetchOfferDetails,
|
|
18
17
|
fetchOfferRequirements,
|
|
19
18
|
fetchOffers,
|
|
20
19
|
fetchOffersPage,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
30
|
-
|
|
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
|
-
|
|
34
|
-
|
|
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
|
|
592
|
+
async createWalletOwnershipChallenge(params) {
|
|
218
593
|
this.ensureAuthenticated();
|
|
219
|
-
return
|
|
594
|
+
return createWalletOwnershipChallenge(this.api, params);
|
|
220
595
|
}
|
|
221
|
-
async
|
|
596
|
+
async connectExternalWallet(offerId, params) {
|
|
222
597
|
this.ensureAuthenticated();
|
|
223
|
-
return
|
|
598
|
+
return connectExternalWallet(this.api, offerId, params);
|
|
224
599
|
}
|
|
225
|
-
async
|
|
600
|
+
async listOptionAddresses(offerId, offerOptionId) {
|
|
226
601
|
this.ensureAuthenticated();
|
|
227
|
-
return
|
|
602
|
+
return listOptionAddresses(
|
|
603
|
+
this.api,
|
|
604
|
+
offerId,
|
|
605
|
+
offerOptionId
|
|
606
|
+
);
|
|
228
607
|
}
|
|
229
|
-
async
|
|
608
|
+
async removeOptionAddress(offerId, addressId) {
|
|
230
609
|
this.ensureAuthenticated();
|
|
231
|
-
return
|
|
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
|
|
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__ */
|
|
714
|
+
return /* @__PURE__ */ jsx(CoinListContext.Provider, { value, children });
|
|
321
715
|
}
|
|
322
|
-
|
|
323
|
-
|
|
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 =
|
|
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(
|
|
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
|
-
|
|
841
|
-
|
|
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
|
|
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/
|
|
987
|
-
import {
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
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
|
-
"
|
|
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/
|
|
1031
|
-
import {
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
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
|
-
|
|
1044
|
-
|
|
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,
|
|
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
|
-
|
|
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__ */
|
|
2075
|
+
return /* @__PURE__ */ jsx17(ClButton, { size: "sm", onClick: onAction, children: "Continue" });
|
|
1085
2076
|
case "pending":
|
|
1086
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
2085
|
+
return /* @__PURE__ */ jsx17(AlertBanner, { variant: "success", content: "Identity verified." });
|
|
1095
2086
|
case "rejected":
|
|
1096
|
-
return /* @__PURE__ */
|
|
2087
|
+
return /* @__PURE__ */ jsx17(
|
|
1097
2088
|
AlertBanner,
|
|
1098
2089
|
{
|
|
1099
2090
|
variant: "error",
|
|
1100
|
-
content: onContactSupport === null ? "Verification rejected." : /* @__PURE__ */
|
|
2091
|
+
content: onContactSupport === null ? "Verification rejected." : /* @__PURE__ */ jsxs13(Fragment3, { children: [
|
|
1101
2092
|
"Verification rejected.",
|
|
1102
2093
|
" ",
|
|
1103
|
-
/* @__PURE__ */
|
|
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
|
-
|
|
1121
|
-
|
|
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
|
-
|
|
1125
|
-
|
|
1126
|
-
/* @__PURE__ */
|
|
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:
|
|
2157
|
+
content: connected ? connected.shortAddress : "Wallet connected."
|
|
1131
2158
|
}
|
|
1132
2159
|
)
|
|
1133
2160
|
] });
|
|
1134
2161
|
}
|
|
1135
2162
|
if (status === "rejected") {
|
|
1136
|
-
return /* @__PURE__ */
|
|
1137
|
-
onAction !== null && /* @__PURE__ */
|
|
1138
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
2187
|
+
return /* @__PURE__ */ jsx17(CoinListStyleScope, { children: /* @__PURE__ */ jsxs13(
|
|
1159
2188
|
"div",
|
|
1160
2189
|
{
|
|
1161
|
-
className: cn(
|
|
2190
|
+
className: cn(
|
|
2191
|
+
"clcosdk:flex clcosdk:w-full clcosdk:flex-col",
|
|
2192
|
+
className
|
|
2193
|
+
),
|
|
1162
2194
|
children: [
|
|
1163
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1172
|
-
/* @__PURE__ */
|
|
1173
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
1205
|
-
/* @__PURE__ */
|
|
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(
|
|
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__ */
|
|
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__ */
|
|
2254
|
+
) : /* @__PURE__ */ jsx17(
|
|
1220
2255
|
WalletActionZone,
|
|
1221
2256
|
{
|
|
1222
2257
|
status: ui.status,
|
|
1223
|
-
|
|
1224
|
-
|
|
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
|
|
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
|
|
1240
|
-
var
|
|
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] =
|
|
1245
|
-
data !== void 0 ? { type: "CONTENT", ...data } :
|
|
2755
|
+
const [requirementsState, setRequirementsState] = useState8(
|
|
2756
|
+
data !== void 0 ? { type: "CONTENT", ...data } : LOADING_STATE5
|
|
1246
2757
|
);
|
|
1247
|
-
const [fetchKey, setFetchKey] =
|
|
1248
|
-
const refetch =
|
|
1249
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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] =
|
|
1329
|
-
const
|
|
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__ */
|
|
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__ */
|
|
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
|
-
|
|
1345
|
-
return /* @__PURE__ */ jsx15(
|
|
2962
|
+
return /* @__PURE__ */ jsx19(
|
|
1346
2963
|
AlertBanner,
|
|
1347
2964
|
{
|
|
1348
2965
|
variant: "error",
|
|
1349
2966
|
icon: true,
|
|
1350
|
-
content:
|
|
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__ */
|
|
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__ */
|
|
1370
|
-
/* @__PURE__ */
|
|
1371
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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
|
-
|
|
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__ */
|
|
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__ */
|
|
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
|
|
3271
|
+
import { useEffect as useEffect15, useRef as useRef8 } from "react";
|
|
1430
3272
|
function useCompleteOAuth(options) {
|
|
1431
3273
|
const { coinlist } = useCoinList();
|
|
1432
|
-
const postOAuthCompleteRef =
|
|
1433
|
-
const onFailureRef =
|
|
1434
|
-
const onSuccessRef =
|
|
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 =
|
|
1439
|
-
|
|
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
|
|
1484
|
-
var
|
|
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] =
|
|
1489
|
-
data !== void 0 ? { type: "CONTENT", offerDetail: data } :
|
|
3330
|
+
const [offerDetailsState, setOfferDetailsState] = useState13(
|
|
3331
|
+
data !== void 0 ? { type: "CONTENT", offerDetail: data } : LOADING_STATE7
|
|
1490
3332
|
);
|
|
1491
|
-
|
|
3333
|
+
useEffect16(() => {
|
|
1492
3334
|
let isCancelled = false;
|
|
1493
3335
|
if (!isReady) {
|
|
1494
3336
|
if (data === void 0) {
|
|
1495
|
-
setOfferDetailsState(
|
|
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(
|
|
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
|
|
1526
|
-
var
|
|
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] =
|
|
1531
|
-
data !== void 0 ? { type: "CONTENT", participations: data } :
|
|
3372
|
+
const [participationsState, setParticipationsState] = useState14(
|
|
3373
|
+
data !== void 0 ? { type: "CONTENT", participations: data } : LOADING_STATE8
|
|
1532
3374
|
);
|
|
1533
|
-
|
|
3375
|
+
useEffect17(() => {
|
|
1534
3376
|
let isCancelled = false;
|
|
1535
3377
|
if (!isReady) {
|
|
1536
3378
|
if (data === void 0) {
|
|
1537
|
-
setParticipationsState(
|
|
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(
|
|
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
|