@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.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,18 +17,32 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/client/index.ts
|
|
21
31
|
var client_exports = {};
|
|
22
32
|
__export(client_exports, {
|
|
23
33
|
ChecklistStatus: () => ChecklistStatus,
|
|
34
|
+
ClientSwapNamespaceImpl: () => ClientSwapNamespaceImpl,
|
|
35
|
+
ClientTokenSaleNamespaceImpl: () => ClientTokenSaleNamespaceImpl,
|
|
24
36
|
CoinListClientInitializationError: () => CoinListClientInitializationError,
|
|
25
37
|
CoinListContext: () => CoinListContext,
|
|
26
38
|
CoinListContextProvider: () => CoinListContextProvider,
|
|
27
39
|
CoinListProvider: () => CoinListProvider,
|
|
28
40
|
CoinListSignInCard: () => CoinListSignInCard,
|
|
29
41
|
CoinListStyleScope: () => CoinListStyleScope,
|
|
42
|
+
ConnectWalletModal: () => ConnectWalletModal,
|
|
43
|
+
ConnectedWalletList: () => ConnectedWalletList,
|
|
44
|
+
IdentityVerification: () => IdentityVerification,
|
|
45
|
+
KycToken: () => KycToken,
|
|
30
46
|
OAUTH_CODE_VERIFIER_KEY: () => OAUTH_CODE_VERIFIER_KEY,
|
|
31
47
|
OAUTH_STATE_KEY: () => OAUTH_STATE_KEY,
|
|
32
48
|
OfferCard: () => OfferCard,
|
|
@@ -37,49 +53,32 @@ __export(client_exports, {
|
|
|
37
53
|
RequirementStatus: () => RequirementStatus,
|
|
38
54
|
RequirementVariant: () => RequirementVariant,
|
|
39
55
|
RequirementsChecklist: () => RequirementsChecklist,
|
|
56
|
+
TaxDocumentModal: () => TaxDocumentModal,
|
|
57
|
+
authorizeWallet: () => authorizeWallet,
|
|
58
|
+
classifyWalletError: () => classifyWalletError,
|
|
59
|
+
connectExternalWalletFlow: () => connectExternalWalletFlow,
|
|
40
60
|
createCoinListClient: () => createCoinListClient,
|
|
61
|
+
executeSwap: () => executeSwap,
|
|
62
|
+
executeTokenSale: () => executeTokenSale,
|
|
41
63
|
useCoinList: () => useCoinList,
|
|
42
64
|
useCompleteOAuth: () => useCompleteOAuth,
|
|
65
|
+
useConnectWallet: () => useConnectWallet,
|
|
66
|
+
useKycToken: () => useKycToken,
|
|
43
67
|
useOfferDetails: () => useOfferDetails,
|
|
44
68
|
useOffers: () => useOffers,
|
|
69
|
+
useOptionAddresses: () => useOptionAddresses,
|
|
45
70
|
useParticipations: () => useParticipations,
|
|
46
|
-
useRequirements: () => useRequirements
|
|
71
|
+
useRequirements: () => useRequirements,
|
|
72
|
+
useSwapOutputToken: () => useSwapOutputToken,
|
|
73
|
+
useSwapQuote: () => useSwapQuote,
|
|
74
|
+
useSwapTokenBalances: () => useSwapTokenBalances,
|
|
75
|
+
useTaxDocument: () => useTaxDocument
|
|
47
76
|
});
|
|
48
77
|
module.exports = __toCommonJS(client_exports);
|
|
49
78
|
|
|
50
79
|
// src/client/CoinListProvider.tsx
|
|
51
80
|
var import_react = require("react");
|
|
52
81
|
|
|
53
|
-
// src/client/generated/sdk-styles.gen.ts
|
|
54
|
-
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)}}';
|
|
55
|
-
|
|
56
|
-
// src/client/CoinListStyleScope.tsx
|
|
57
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
58
|
-
function CoinListStyleScope({ children }) {
|
|
59
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
60
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("link", { rel: "preconnect", href: "https://fonts.googleapis.com" }),
|
|
61
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
62
|
-
"link",
|
|
63
|
-
{
|
|
64
|
-
rel: "preconnect",
|
|
65
|
-
href: "https://fonts.gstatic.com",
|
|
66
|
-
crossOrigin: "anonymous"
|
|
67
|
-
}
|
|
68
|
-
),
|
|
69
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
70
|
-
"link",
|
|
71
|
-
{
|
|
72
|
-
rel: "stylesheet",
|
|
73
|
-
href: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap"
|
|
74
|
-
}
|
|
75
|
-
),
|
|
76
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "clco-sdk-root", children: [
|
|
77
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { dangerouslySetInnerHTML: { __html: sdkStyles } }),
|
|
78
|
-
children
|
|
79
|
-
] })
|
|
80
|
-
] });
|
|
81
|
-
}
|
|
82
|
-
|
|
83
82
|
// src/shared/utils.ts
|
|
84
83
|
async function sha256(data) {
|
|
85
84
|
const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
|
|
@@ -175,6 +174,9 @@ var userAgent = () => ({ userAgent: true });
|
|
|
175
174
|
var idempotencyKey = () => ({
|
|
176
175
|
idempotencyKey: true
|
|
177
176
|
});
|
|
177
|
+
var clientCredentials = (credentials) => ({
|
|
178
|
+
clientCredentials: credentials
|
|
179
|
+
});
|
|
178
180
|
var retryAttempt = (attempt) => ({
|
|
179
181
|
retryAttempt: attempt
|
|
180
182
|
});
|
|
@@ -186,6 +188,7 @@ var needUserAgent = (attrs) => attrs?.userAgent === true;
|
|
|
186
188
|
var isIdempotent = (attrs) => attrs?.idempotencyKey === true;
|
|
187
189
|
var getRetryAttempt = (attrs) => attrs?.retryAttempt ?? 0;
|
|
188
190
|
var wasRenewAttempted = (attrs) => attrs?.renewAttempted === true;
|
|
191
|
+
var getClientCredentials = (attrs) => attrs?.clientCredentials;
|
|
189
192
|
var Attributes = {
|
|
190
193
|
empty,
|
|
191
194
|
concat,
|
|
@@ -199,7 +202,9 @@ var Attributes = {
|
|
|
199
202
|
retryAttempt,
|
|
200
203
|
getRetryAttempt,
|
|
201
204
|
renewAttempted,
|
|
202
|
-
wasRenewAttempted
|
|
205
|
+
wasRenewAttempted,
|
|
206
|
+
clientCredentials,
|
|
207
|
+
getClientCredentials
|
|
203
208
|
};
|
|
204
209
|
|
|
205
210
|
// src/client/core/api/middleware/user-agent.ts
|
|
@@ -399,7 +404,13 @@ function attachSessionMiddleware(fetchAccessToken) {
|
|
|
399
404
|
if (!Attributes.isProtected(request.attributes)) {
|
|
400
405
|
return request;
|
|
401
406
|
}
|
|
402
|
-
|
|
407
|
+
let accessToken = await fetchAccessToken(false);
|
|
408
|
+
if (!accessToken) {
|
|
409
|
+
const clientCreds = Attributes.getClientCredentials(request.attributes);
|
|
410
|
+
if (clientCreds) {
|
|
411
|
+
accessToken = clientCreds;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
403
414
|
if (accessToken === null) {
|
|
404
415
|
return request;
|
|
405
416
|
}
|
|
@@ -528,81 +539,866 @@ var ApiClient = class {
|
|
|
528
539
|
}
|
|
529
540
|
};
|
|
530
541
|
|
|
531
|
-
// src/
|
|
532
|
-
var
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
542
|
+
// src/client/core/blockchain/wallet-error.ts
|
|
543
|
+
var import_viem = require("viem");
|
|
544
|
+
function classifyWalletError(error, ctx) {
|
|
545
|
+
if (error instanceof import_viem.UserRejectedRequestError) {
|
|
546
|
+
return { type: "user_rejected" };
|
|
547
|
+
}
|
|
548
|
+
if (error instanceof import_viem.InsufficientFundsError) {
|
|
549
|
+
return { type: "insufficient_funds" };
|
|
550
|
+
}
|
|
551
|
+
if (error instanceof import_viem.ContractFunctionRevertedError) {
|
|
552
|
+
return { type: "contract_reverted", reason: error.reason ?? error.message };
|
|
553
|
+
}
|
|
554
|
+
if (error instanceof import_viem.WaitForTransactionReceiptTimeoutError && ctx?.hash) {
|
|
555
|
+
return { type: "timeout", hash: ctx.hash };
|
|
556
|
+
}
|
|
557
|
+
return { type: "unknown", cause: error };
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// src/shared/core/blockchain/abis/erc20.ts
|
|
561
|
+
var ERC20_ABI = [
|
|
562
|
+
{
|
|
563
|
+
type: "function",
|
|
564
|
+
name: "allowance",
|
|
565
|
+
inputs: [
|
|
566
|
+
{ name: "owner", type: "address" },
|
|
567
|
+
{ name: "spender", type: "address" }
|
|
568
|
+
],
|
|
569
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
570
|
+
stateMutability: "view"
|
|
571
|
+
},
|
|
572
|
+
{
|
|
573
|
+
type: "function",
|
|
574
|
+
name: "approve",
|
|
575
|
+
inputs: [
|
|
576
|
+
{ name: "spender", type: "address" },
|
|
577
|
+
{ name: "amount", type: "uint256" }
|
|
578
|
+
],
|
|
579
|
+
outputs: [{ name: "", type: "bool" }],
|
|
580
|
+
stateMutability: "nonpayable"
|
|
581
|
+
},
|
|
582
|
+
{
|
|
583
|
+
type: "function",
|
|
584
|
+
name: "balanceOf",
|
|
585
|
+
inputs: [{ name: "account", type: "address" }],
|
|
586
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
587
|
+
stateMutability: "view"
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
type: "function",
|
|
591
|
+
name: "decimals",
|
|
592
|
+
inputs: [],
|
|
593
|
+
outputs: [{ name: "", type: "uint8" }],
|
|
594
|
+
stateMutability: "view"
|
|
595
|
+
},
|
|
596
|
+
{
|
|
597
|
+
type: "function",
|
|
598
|
+
name: "name",
|
|
599
|
+
inputs: [],
|
|
600
|
+
outputs: [{ name: "", type: "string" }],
|
|
601
|
+
stateMutability: "view"
|
|
602
|
+
},
|
|
603
|
+
{
|
|
604
|
+
type: "function",
|
|
605
|
+
name: "symbol",
|
|
606
|
+
inputs: [],
|
|
607
|
+
outputs: [{ name: "", type: "string" }],
|
|
608
|
+
stateMutability: "view"
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
type: "function",
|
|
612
|
+
name: "totalSupply",
|
|
613
|
+
inputs: [],
|
|
614
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
615
|
+
stateMutability: "view"
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
type: "function",
|
|
619
|
+
name: "transfer",
|
|
620
|
+
inputs: [
|
|
621
|
+
{ name: "recipient", type: "address" },
|
|
622
|
+
{ name: "amount", type: "uint256" }
|
|
623
|
+
],
|
|
624
|
+
outputs: [{ name: "", type: "bool" }],
|
|
625
|
+
stateMutability: "nonpayable"
|
|
626
|
+
},
|
|
627
|
+
{
|
|
628
|
+
type: "function",
|
|
629
|
+
name: "transferFrom",
|
|
630
|
+
inputs: [
|
|
631
|
+
{ name: "sender", type: "address" },
|
|
632
|
+
{ name: "recipient", type: "address" },
|
|
633
|
+
{ name: "amount", type: "uint256" }
|
|
634
|
+
],
|
|
635
|
+
outputs: [{ name: "", type: "bool" }],
|
|
636
|
+
stateMutability: "nonpayable"
|
|
637
|
+
},
|
|
638
|
+
{
|
|
639
|
+
type: "event",
|
|
640
|
+
name: "Approval",
|
|
641
|
+
inputs: [
|
|
642
|
+
{ name: "owner", type: "address", indexed: true },
|
|
643
|
+
{ name: "spender", type: "address", indexed: true },
|
|
644
|
+
{ name: "value", type: "uint256", indexed: false }
|
|
645
|
+
],
|
|
646
|
+
anonymous: false
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
type: "event",
|
|
650
|
+
name: "Transfer",
|
|
651
|
+
inputs: [
|
|
652
|
+
{ name: "from", type: "address", indexed: true },
|
|
653
|
+
{ name: "to", type: "address", indexed: true },
|
|
654
|
+
{ name: "value", type: "uint256", indexed: false }
|
|
655
|
+
],
|
|
656
|
+
anonymous: false
|
|
657
|
+
}
|
|
658
|
+
];
|
|
659
|
+
|
|
660
|
+
// src/client/core/blockchain/erc20-approval.ts
|
|
661
|
+
async function submitErc20Approval(args) {
|
|
662
|
+
const {
|
|
663
|
+
wallet,
|
|
664
|
+
tokenAddress,
|
|
665
|
+
spender,
|
|
666
|
+
chain,
|
|
667
|
+
value,
|
|
668
|
+
pending,
|
|
669
|
+
confirming,
|
|
670
|
+
emit
|
|
671
|
+
} = args;
|
|
672
|
+
emit(pending);
|
|
673
|
+
let hash;
|
|
674
|
+
try {
|
|
675
|
+
hash = await wallet.writeContract({
|
|
676
|
+
abi: ERC20_ABI,
|
|
677
|
+
address: tokenAddress,
|
|
678
|
+
functionName: "approve",
|
|
679
|
+
args: [spender, value],
|
|
680
|
+
chain
|
|
681
|
+
});
|
|
682
|
+
} catch (error) {
|
|
683
|
+
return {
|
|
684
|
+
type: "error",
|
|
685
|
+
error: { step: "approval", cause: classifyWalletError(error) }
|
|
540
686
|
};
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
687
|
+
}
|
|
688
|
+
emit(confirming);
|
|
689
|
+
let receipt;
|
|
690
|
+
try {
|
|
691
|
+
receipt = await wallet.awaitTx(hash, chain);
|
|
692
|
+
} catch (error) {
|
|
693
|
+
return {
|
|
694
|
+
type: "error",
|
|
695
|
+
error: { step: "approval", cause: classifyWalletError(error, { hash }) }
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
if (receipt.status !== "success") {
|
|
699
|
+
return { type: "error", error: { step: "approval-reverted" } };
|
|
700
|
+
}
|
|
701
|
+
return { type: "ok", txHash: hash };
|
|
546
702
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
703
|
+
|
|
704
|
+
// src/shared/core/blockchain/abis/superstate-swap.ts
|
|
705
|
+
var SUPERSTATE_SWAP_ABI = [
|
|
706
|
+
{
|
|
707
|
+
type: "function",
|
|
708
|
+
name: "authorized",
|
|
709
|
+
inputs: [{ name: "user", type: "address", internalType: "address" }],
|
|
710
|
+
outputs: [{ name: "", type: "bool", internalType: "bool" }],
|
|
711
|
+
stateMutability: "view"
|
|
712
|
+
},
|
|
713
|
+
{
|
|
714
|
+
type: "function",
|
|
715
|
+
name: "stopped",
|
|
716
|
+
inputs: [],
|
|
717
|
+
outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
|
|
718
|
+
stateMutability: "view"
|
|
719
|
+
},
|
|
720
|
+
{
|
|
721
|
+
type: "function",
|
|
722
|
+
name: "SWAP_LEVEL",
|
|
723
|
+
inputs: [],
|
|
724
|
+
outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
|
|
725
|
+
stateMutability: "view"
|
|
726
|
+
},
|
|
727
|
+
{
|
|
728
|
+
type: "function",
|
|
729
|
+
name: "preview",
|
|
730
|
+
inputs: [
|
|
731
|
+
{ name: "token", type: "address", internalType: "address" },
|
|
732
|
+
{ name: "amount", type: "uint256", internalType: "uint256" }
|
|
733
|
+
],
|
|
734
|
+
outputs: [
|
|
735
|
+
{
|
|
736
|
+
name: "",
|
|
737
|
+
type: "tuple",
|
|
738
|
+
internalType: "struct Preview",
|
|
739
|
+
components: [
|
|
740
|
+
{ name: "input", type: "uint256", internalType: "uint256" },
|
|
741
|
+
{ name: "fee", type: "uint256", internalType: "uint256" },
|
|
742
|
+
{ name: "output", type: "uint256", internalType: "uint256" }
|
|
743
|
+
]
|
|
744
|
+
}
|
|
745
|
+
],
|
|
746
|
+
stateMutability: "view"
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
type: "function",
|
|
750
|
+
name: "swap",
|
|
751
|
+
inputs: [
|
|
752
|
+
{ name: "token", type: "address", internalType: "address" },
|
|
753
|
+
{ name: "amount", type: "uint256", internalType: "uint256" },
|
|
754
|
+
{ name: "slip", type: "uint256", internalType: "uint256" }
|
|
755
|
+
],
|
|
756
|
+
outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
|
|
757
|
+
stateMutability: "nonpayable"
|
|
758
|
+
},
|
|
759
|
+
{
|
|
760
|
+
type: "function",
|
|
761
|
+
name: "tokenBalance",
|
|
762
|
+
inputs: [{ name: "token", type: "address", internalType: "address" }],
|
|
763
|
+
outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
|
|
764
|
+
stateMutability: "view"
|
|
765
|
+
},
|
|
766
|
+
{
|
|
767
|
+
type: "function",
|
|
768
|
+
name: "outputToken",
|
|
769
|
+
inputs: [],
|
|
770
|
+
outputs: [{ name: "", type: "address", internalType: "address" }],
|
|
771
|
+
stateMutability: "view"
|
|
772
|
+
},
|
|
773
|
+
{
|
|
774
|
+
type: "function",
|
|
775
|
+
name: "outputTokenBalance",
|
|
776
|
+
inputs: [],
|
|
777
|
+
outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
|
|
778
|
+
stateMutability: "view"
|
|
779
|
+
},
|
|
780
|
+
{
|
|
781
|
+
type: "function",
|
|
782
|
+
name: "totals",
|
|
783
|
+
inputs: [{ name: "token", type: "address", internalType: "address" }],
|
|
784
|
+
outputs: [
|
|
785
|
+
{
|
|
786
|
+
name: "",
|
|
787
|
+
type: "tuple",
|
|
788
|
+
internalType: "struct SwapTotal",
|
|
789
|
+
components: [
|
|
790
|
+
{ name: "inputSum", type: "uint256", internalType: "uint256" },
|
|
791
|
+
{ name: "feeSum", type: "uint256", internalType: "uint256" },
|
|
792
|
+
{ name: "outputSum", type: "uint256", internalType: "uint256" },
|
|
793
|
+
{ name: "count", type: "uint256", internalType: "uint256" }
|
|
794
|
+
]
|
|
795
|
+
}
|
|
796
|
+
],
|
|
797
|
+
stateMutability: "view"
|
|
798
|
+
},
|
|
799
|
+
{
|
|
800
|
+
type: "function",
|
|
801
|
+
name: "totals",
|
|
802
|
+
inputs: [
|
|
803
|
+
{ name: "user", type: "address", internalType: "address" },
|
|
804
|
+
{ name: "token", type: "address", internalType: "address" }
|
|
805
|
+
],
|
|
806
|
+
outputs: [
|
|
807
|
+
{
|
|
808
|
+
name: "",
|
|
809
|
+
type: "tuple",
|
|
810
|
+
internalType: "struct SwapTotal",
|
|
811
|
+
components: [
|
|
812
|
+
{ name: "inputSum", type: "uint256", internalType: "uint256" },
|
|
813
|
+
{ name: "feeSum", type: "uint256", internalType: "uint256" },
|
|
814
|
+
{ name: "outputSum", type: "uint256", internalType: "uint256" },
|
|
815
|
+
{ name: "count", type: "uint256", internalType: "uint256" }
|
|
816
|
+
]
|
|
817
|
+
}
|
|
818
|
+
],
|
|
819
|
+
stateMutability: "view"
|
|
820
|
+
},
|
|
821
|
+
{
|
|
822
|
+
type: "function",
|
|
823
|
+
name: "transfer",
|
|
824
|
+
inputs: [
|
|
825
|
+
{ name: "to", type: "address", internalType: "address" },
|
|
826
|
+
{ name: "amount", type: "uint256", internalType: "uint256" }
|
|
827
|
+
],
|
|
828
|
+
outputs: [{ name: "", type: "bool", internalType: "bool" }],
|
|
829
|
+
stateMutability: "nonpayable"
|
|
830
|
+
},
|
|
831
|
+
{
|
|
832
|
+
type: "function",
|
|
833
|
+
name: "transfer",
|
|
834
|
+
inputs: [
|
|
835
|
+
{ name: "to", type: "address", internalType: "address" },
|
|
836
|
+
{ name: "token", type: "address", internalType: "address" },
|
|
837
|
+
{ name: "amount", type: "uint256", internalType: "uint256" }
|
|
838
|
+
],
|
|
839
|
+
outputs: [{ name: "", type: "bool", internalType: "bool" }],
|
|
840
|
+
stateMutability: "nonpayable"
|
|
841
|
+
},
|
|
842
|
+
{
|
|
843
|
+
type: "function",
|
|
844
|
+
name: "setBps",
|
|
845
|
+
inputs: [{ name: "points", type: "uint256", internalType: "uint256" }],
|
|
846
|
+
outputs: [{ name: "", type: "bool", internalType: "bool" }],
|
|
847
|
+
stateMutability: "nonpayable"
|
|
848
|
+
},
|
|
849
|
+
{
|
|
850
|
+
type: "event",
|
|
851
|
+
name: "Swapped",
|
|
852
|
+
inputs: [
|
|
853
|
+
{ name: "user", type: "address", indexed: true, internalType: "address" },
|
|
854
|
+
{
|
|
855
|
+
name: "inputToken",
|
|
856
|
+
type: "address",
|
|
857
|
+
indexed: true,
|
|
858
|
+
internalType: "address"
|
|
859
|
+
},
|
|
860
|
+
{
|
|
861
|
+
name: "outputToken",
|
|
862
|
+
type: "address",
|
|
863
|
+
indexed: true,
|
|
864
|
+
internalType: "address"
|
|
865
|
+
},
|
|
866
|
+
{
|
|
867
|
+
name: "inputAmount",
|
|
868
|
+
type: "uint256",
|
|
869
|
+
indexed: false,
|
|
870
|
+
internalType: "uint256"
|
|
871
|
+
},
|
|
872
|
+
{
|
|
873
|
+
name: "outputAmount",
|
|
874
|
+
type: "uint256",
|
|
875
|
+
indexed: false,
|
|
876
|
+
internalType: "uint256"
|
|
877
|
+
}
|
|
878
|
+
],
|
|
879
|
+
anonymous: false
|
|
880
|
+
},
|
|
881
|
+
{
|
|
882
|
+
type: "event",
|
|
883
|
+
name: "Transferred",
|
|
884
|
+
inputs: [
|
|
885
|
+
{ name: "to", type: "address", indexed: true, internalType: "address" },
|
|
886
|
+
{
|
|
887
|
+
name: "token",
|
|
888
|
+
type: "address",
|
|
889
|
+
indexed: true,
|
|
890
|
+
internalType: "address"
|
|
891
|
+
},
|
|
892
|
+
{
|
|
893
|
+
name: "amount",
|
|
894
|
+
type: "uint256",
|
|
895
|
+
indexed: false,
|
|
896
|
+
internalType: "uint256"
|
|
897
|
+
}
|
|
898
|
+
],
|
|
899
|
+
anonymous: false
|
|
900
|
+
},
|
|
901
|
+
{
|
|
902
|
+
type: "error",
|
|
903
|
+
name: "InvalidAddress",
|
|
904
|
+
inputs: []
|
|
905
|
+
},
|
|
906
|
+
{
|
|
907
|
+
type: "error",
|
|
908
|
+
name: "InsufficientAmount",
|
|
909
|
+
inputs: []
|
|
910
|
+
},
|
|
911
|
+
{
|
|
912
|
+
type: "error",
|
|
913
|
+
name: "InvalidAmount",
|
|
914
|
+
inputs: []
|
|
915
|
+
},
|
|
916
|
+
{
|
|
917
|
+
type: "error",
|
|
918
|
+
name: "SwapFailed",
|
|
919
|
+
inputs: [
|
|
920
|
+
{ name: "user", type: "address", internalType: "address" },
|
|
921
|
+
{ name: "token", type: "address", internalType: "address" }
|
|
922
|
+
]
|
|
923
|
+
}
|
|
924
|
+
];
|
|
925
|
+
|
|
926
|
+
// src/shared/types/blockchain/core.ts
|
|
927
|
+
var EvmWalletAddress = (value) => value;
|
|
928
|
+
var EvmContractAddress = (value) => value;
|
|
929
|
+
var HexEncodedTransactionData = (value) => value;
|
|
930
|
+
var AssetDecimals = (value) => value;
|
|
931
|
+
var MAX_UINT_256 = 2n ** 256n - 1n;
|
|
932
|
+
var assertUint256 = (value) => {
|
|
933
|
+
if (value < 0n || value > MAX_UINT_256) {
|
|
934
|
+
throw new Error(`Value out of uint256 bounds: ${value}`);
|
|
935
|
+
}
|
|
936
|
+
return value;
|
|
553
937
|
};
|
|
554
|
-
var
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
938
|
+
var BlockchainAmount = Object.assign(
|
|
939
|
+
(value) => value,
|
|
940
|
+
{
|
|
941
|
+
add: (a, b) => combineAmounts(a, b, (x, y) => x + y),
|
|
942
|
+
sub: (a, b) => combineAmounts(a, b, (x, y) => x - y)
|
|
943
|
+
}
|
|
944
|
+
);
|
|
945
|
+
function combineAmounts(a, b, op) {
|
|
946
|
+
if (a.decimals !== b.decimals) {
|
|
947
|
+
throw new Error(
|
|
948
|
+
`Cannot combine BlockchainAmounts with different decimals: ${a.decimals} vs ${b.decimals}`
|
|
949
|
+
);
|
|
950
|
+
}
|
|
951
|
+
const raw = op(a.raw, b.raw);
|
|
952
|
+
if (raw < 0n || raw > MAX_UINT_256) {
|
|
953
|
+
throw new Error(`BlockchainAmount out of uint256 bounds: ${raw}`);
|
|
954
|
+
}
|
|
955
|
+
return BlockchainAmount({ raw, decimals: a.decimals });
|
|
956
|
+
}
|
|
957
|
+
var AssetSymbol = (value) => value;
|
|
958
|
+
var StablecoinSymbol = (value) => value;
|
|
959
|
+
var Bps = (value) => value;
|
|
960
|
+
|
|
961
|
+
// src/shared/core/blockchain/bps.ts
|
|
962
|
+
var BPS_DENOM = Bps(10000n);
|
|
963
|
+
function applyBps(amount, bps) {
|
|
964
|
+
return assertUint256(amount * bps / BPS_DENOM);
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
// src/shared/core/blockchain/swap/math.ts
|
|
968
|
+
function computePrice({
|
|
969
|
+
inputTokenAmount,
|
|
970
|
+
outputTokenAmount
|
|
971
|
+
}) {
|
|
972
|
+
if (outputTokenAmount.raw === 0n) return null;
|
|
973
|
+
const scale = 10n ** BigInt(outputTokenAmount.decimals);
|
|
974
|
+
const raw = assertUint256(
|
|
975
|
+
inputTokenAmount.raw * scale / outputTokenAmount.raw
|
|
976
|
+
);
|
|
977
|
+
return BlockchainAmount({ raw, decimals: inputTokenAmount.decimals });
|
|
978
|
+
}
|
|
979
|
+
function computeSlip(amount, slippage) {
|
|
980
|
+
const retained = Bps(assertUint256(BPS_DENOM - slippage));
|
|
981
|
+
const slipRaw = applyBps(amount.raw, retained);
|
|
982
|
+
return BlockchainAmount({ raw: slipRaw, decimals: amount.decimals });
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
// src/shared/core/blockchain/swap/status.ts
|
|
986
|
+
function isStopped(status) {
|
|
987
|
+
return (status.stopped & status.swapLevel) !== 0n;
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
// src/shared/core/blockchain/swap/swapped-event.ts
|
|
991
|
+
var import_viem2 = require("viem");
|
|
992
|
+
function decodeSwappedOutputAmount(receipt, outputDecimals) {
|
|
993
|
+
try {
|
|
994
|
+
const [swapped] = (0, import_viem2.parseEventLogs)({
|
|
995
|
+
abi: SUPERSTATE_SWAP_ABI,
|
|
996
|
+
eventName: "Swapped",
|
|
997
|
+
logs: receipt.logs
|
|
998
|
+
});
|
|
999
|
+
if (!swapped) return null;
|
|
1000
|
+
const raw = swapped.args.outputAmount;
|
|
1001
|
+
if (raw < 0n || raw > MAX_UINT_256) return null;
|
|
1002
|
+
return BlockchainAmount({ raw, decimals: outputDecimals });
|
|
1003
|
+
} catch {
|
|
1004
|
+
return null;
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
// src/client/core/blockchain/swap-flows.ts
|
|
1009
|
+
async function executeSwap(params) {
|
|
1010
|
+
const {
|
|
1011
|
+
swap,
|
|
1012
|
+
erc20,
|
|
1013
|
+
wallet,
|
|
1014
|
+
contractAddress,
|
|
1015
|
+
chain,
|
|
1016
|
+
inputTokenAddress,
|
|
1017
|
+
quote,
|
|
1018
|
+
slippageBps,
|
|
1019
|
+
onProgress
|
|
1020
|
+
} = params;
|
|
1021
|
+
const emit = (phase) => onProgress?.(phase);
|
|
1022
|
+
const inputAmount = BlockchainAmount.add(
|
|
1023
|
+
quote.inputTokenAmount,
|
|
1024
|
+
quote.fee
|
|
1025
|
+
).raw;
|
|
1026
|
+
const minOut = computeSlip(quote.outputTokenAmount, slippageBps).raw;
|
|
1027
|
+
emit("checking-status");
|
|
1028
|
+
let status;
|
|
1029
|
+
try {
|
|
1030
|
+
status = await swap.getStatus({ contractAddress, chain });
|
|
1031
|
+
} catch {
|
|
1032
|
+
return { type: "error", error: { step: "status-check" } };
|
|
1033
|
+
}
|
|
1034
|
+
if (isStopped(status)) {
|
|
1035
|
+
return { type: "error", error: { step: "swap-stopped" } };
|
|
1036
|
+
}
|
|
1037
|
+
emit("checking-allowance");
|
|
1038
|
+
let allowance;
|
|
1039
|
+
try {
|
|
1040
|
+
allowance = await erc20.getTokenAllowance({
|
|
1041
|
+
tokenAddress: inputTokenAddress,
|
|
1042
|
+
owner: wallet.address,
|
|
1043
|
+
spender: contractAddress,
|
|
1044
|
+
chain
|
|
1045
|
+
});
|
|
1046
|
+
} catch {
|
|
1047
|
+
return { type: "error", error: { step: "allowance-check" } };
|
|
1048
|
+
}
|
|
1049
|
+
if (allowance.allowance < inputAmount) {
|
|
1050
|
+
if (allowance.allowance > 0n) {
|
|
1051
|
+
const reset = await submitErc20Approval({
|
|
1052
|
+
wallet,
|
|
1053
|
+
tokenAddress: inputTokenAddress,
|
|
1054
|
+
spender: contractAddress,
|
|
1055
|
+
chain,
|
|
1056
|
+
value: 0n,
|
|
1057
|
+
pending: "resetting-allowance",
|
|
1058
|
+
confirming: "confirming-allowance-reset",
|
|
1059
|
+
emit
|
|
1060
|
+
});
|
|
1061
|
+
if (reset.type === "error") return { type: "error", error: reset.error };
|
|
559
1062
|
}
|
|
560
|
-
|
|
561
|
-
|
|
1063
|
+
const approve = await submitErc20Approval({
|
|
1064
|
+
wallet,
|
|
1065
|
+
tokenAddress: inputTokenAddress,
|
|
1066
|
+
spender: contractAddress,
|
|
1067
|
+
chain,
|
|
1068
|
+
value: inputAmount,
|
|
1069
|
+
pending: "approving",
|
|
1070
|
+
confirming: "confirming-approval",
|
|
1071
|
+
emit
|
|
1072
|
+
});
|
|
1073
|
+
if (approve.type === "error")
|
|
1074
|
+
return { type: "error", error: approve.error };
|
|
1075
|
+
}
|
|
1076
|
+
emit("swapping");
|
|
1077
|
+
let swapTxHash;
|
|
1078
|
+
try {
|
|
1079
|
+
swapTxHash = await wallet.writeContract({
|
|
1080
|
+
abi: SUPERSTATE_SWAP_ABI,
|
|
1081
|
+
address: contractAddress,
|
|
1082
|
+
functionName: "swap",
|
|
1083
|
+
args: [inputTokenAddress, inputAmount, minOut],
|
|
1084
|
+
chain
|
|
1085
|
+
});
|
|
1086
|
+
} catch (error) {
|
|
1087
|
+
return {
|
|
1088
|
+
type: "error",
|
|
1089
|
+
error: { step: "swap", cause: classifyWalletError(error) }
|
|
1090
|
+
};
|
|
1091
|
+
}
|
|
1092
|
+
emit("confirming-swap");
|
|
1093
|
+
let receipt;
|
|
1094
|
+
try {
|
|
1095
|
+
receipt = await wallet.awaitTx(swapTxHash, chain);
|
|
1096
|
+
} catch (error) {
|
|
1097
|
+
return {
|
|
1098
|
+
type: "error",
|
|
1099
|
+
error: {
|
|
1100
|
+
step: "swap",
|
|
1101
|
+
cause: classifyWalletError(error, { hash: swapTxHash })
|
|
1102
|
+
}
|
|
1103
|
+
};
|
|
1104
|
+
}
|
|
1105
|
+
if (receipt.status !== "success") {
|
|
1106
|
+
return { type: "error", error: { step: "swap-reverted" } };
|
|
1107
|
+
}
|
|
1108
|
+
const outputAmount = decodeSwappedOutputAmount(receipt, quote.outputTokenAmount.decimals) ?? quote.outputTokenAmount;
|
|
1109
|
+
const finalQuote = { ...quote, outputTokenAmount: outputAmount };
|
|
1110
|
+
return {
|
|
1111
|
+
type: "success",
|
|
1112
|
+
swapTxHash,
|
|
1113
|
+
inputAmount: finalQuote.inputTokenAmount,
|
|
1114
|
+
fee: finalQuote.fee,
|
|
1115
|
+
outputAmount,
|
|
1116
|
+
pricePerShare: computePrice(finalQuote),
|
|
1117
|
+
recipientAddress: wallet.address
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
async function authorizeWallet(params) {
|
|
1121
|
+
const { swap, wallet, offerId, contractAddress, chain, onProgress } = params;
|
|
1122
|
+
const emit = (phase) => onProgress?.(phase);
|
|
1123
|
+
const walletAddress = wallet.address;
|
|
1124
|
+
emit("checking-authorization");
|
|
1125
|
+
let auth;
|
|
1126
|
+
try {
|
|
1127
|
+
auth = await swap.getAuthorization({
|
|
1128
|
+
walletAddress,
|
|
1129
|
+
contractAddress,
|
|
1130
|
+
chain
|
|
1131
|
+
});
|
|
1132
|
+
} catch {
|
|
1133
|
+
return { type: "error", error: { step: "authorization-check" } };
|
|
1134
|
+
}
|
|
1135
|
+
if (auth.authorized) return { type: "success" };
|
|
1136
|
+
emit("requesting-challenge");
|
|
1137
|
+
let challenge;
|
|
1138
|
+
try {
|
|
1139
|
+
challenge = await swap.requestWalletOwnershipChallenge({
|
|
1140
|
+
walletAddress,
|
|
1141
|
+
chain,
|
|
1142
|
+
challengeType: "plain"
|
|
1143
|
+
});
|
|
1144
|
+
} catch {
|
|
1145
|
+
return { type: "error", error: { step: "challenge-request" } };
|
|
1146
|
+
}
|
|
1147
|
+
emit("signing-message");
|
|
1148
|
+
let signature;
|
|
1149
|
+
try {
|
|
1150
|
+
signature = await wallet.signMessage(challenge.message);
|
|
1151
|
+
} catch (error) {
|
|
1152
|
+
return {
|
|
1153
|
+
type: "error",
|
|
1154
|
+
error: { step: "signing", cause: classifyWalletError(error) }
|
|
1155
|
+
};
|
|
1156
|
+
}
|
|
1157
|
+
emit("submitting-signature");
|
|
1158
|
+
let allow;
|
|
1159
|
+
try {
|
|
1160
|
+
allow = await swap.allowWallet({
|
|
1161
|
+
offerId,
|
|
1162
|
+
walletAddress,
|
|
1163
|
+
chain,
|
|
1164
|
+
signature
|
|
1165
|
+
});
|
|
1166
|
+
} catch {
|
|
1167
|
+
return { type: "error", error: { step: "allow-wallet" } };
|
|
1168
|
+
}
|
|
1169
|
+
if (allow.action === "broadcast_transaction") {
|
|
1170
|
+
emit("broadcasting-transaction");
|
|
1171
|
+
let hash;
|
|
1172
|
+
try {
|
|
1173
|
+
hash = await wallet.broadcastRawTx({
|
|
1174
|
+
to: allow.to,
|
|
1175
|
+
data: allow.data,
|
|
1176
|
+
chain
|
|
1177
|
+
});
|
|
1178
|
+
} catch (error) {
|
|
1179
|
+
return {
|
|
1180
|
+
type: "error",
|
|
1181
|
+
error: { step: "broadcast", cause: classifyWalletError(error) }
|
|
1182
|
+
};
|
|
562
1183
|
}
|
|
563
|
-
|
|
564
|
-
|
|
1184
|
+
emit("awaiting-confirmation");
|
|
1185
|
+
try {
|
|
1186
|
+
await wallet.awaitTx(hash, chain);
|
|
1187
|
+
} catch (error) {
|
|
1188
|
+
return {
|
|
1189
|
+
type: "error",
|
|
1190
|
+
error: {
|
|
1191
|
+
step: "broadcast",
|
|
1192
|
+
cause: classifyWalletError(error, { hash })
|
|
1193
|
+
}
|
|
1194
|
+
};
|
|
565
1195
|
}
|
|
566
|
-
return queryParams;
|
|
567
1196
|
}
|
|
568
|
-
|
|
1197
|
+
emit("verifying-authorization");
|
|
1198
|
+
let reCheck;
|
|
1199
|
+
try {
|
|
1200
|
+
reCheck = await swap.getAuthorization({
|
|
1201
|
+
walletAddress,
|
|
1202
|
+
contractAddress,
|
|
1203
|
+
chain
|
|
1204
|
+
});
|
|
1205
|
+
} catch {
|
|
1206
|
+
return { type: "error", error: { step: "authorization-check" } };
|
|
1207
|
+
}
|
|
1208
|
+
if (!reCheck.authorized) {
|
|
1209
|
+
return { type: "error", error: { step: "not-authorized" } };
|
|
1210
|
+
}
|
|
1211
|
+
return { type: "success" };
|
|
1212
|
+
}
|
|
569
1213
|
|
|
570
|
-
// src/shared/types/
|
|
571
|
-
var
|
|
572
|
-
var OfferSlug = (value) => value;
|
|
573
|
-
var Offer = {
|
|
1214
|
+
// src/shared/types/swap.ts
|
|
1215
|
+
var SwapAuthorization = {
|
|
574
1216
|
fromDto: (dto) => ({
|
|
575
|
-
|
|
576
|
-
slug: OfferSlug(dto.slug),
|
|
577
|
-
tagline: notBlankStringOrNull(dto.tagline),
|
|
578
|
-
bannerUrl: notBlankStringOrNull(dto.banner_url),
|
|
579
|
-
logoUrl: notBlankStringOrNull(dto.logo_url),
|
|
580
|
-
startsAt: new Date(dto.starts_at),
|
|
581
|
-
endsAt: new Date(dto.ends_at)
|
|
1217
|
+
authorized: dto.authorized
|
|
582
1218
|
})
|
|
583
1219
|
};
|
|
584
|
-
|
|
585
|
-
// src/shared/types/asset.ts
|
|
586
|
-
var AssetId = (value) => value;
|
|
587
|
-
var AssetCode = (value) => value;
|
|
588
|
-
var Asset = {
|
|
1220
|
+
var SwapPreview = {
|
|
589
1221
|
fromDto: (dto) => ({
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
fractionalDigits: dto.fractional_digits
|
|
1222
|
+
inputAmount: assertUint256(BigInt(dto.pay_input_amount)),
|
|
1223
|
+
fee: assertUint256(BigInt(dto.fee)),
|
|
1224
|
+
outputAmount: assertUint256(BigInt(dto.receive_output_amount))
|
|
594
1225
|
})
|
|
595
1226
|
};
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
1227
|
+
var SwapStatus = {
|
|
1228
|
+
fromDto: (dto) => ({
|
|
1229
|
+
stopped: assertUint256(BigInt(dto.stopped)),
|
|
1230
|
+
swapLevel: assertUint256(BigInt(dto.swap_level))
|
|
1231
|
+
})
|
|
1232
|
+
};
|
|
1233
|
+
var TokenAllowance = {
|
|
1234
|
+
fromDto: (dto) => ({
|
|
1235
|
+
allowance: assertUint256(BigInt(dto.allowance))
|
|
1236
|
+
})
|
|
1237
|
+
};
|
|
1238
|
+
var TokenBalance = {
|
|
1239
|
+
fromDto: (dto) => ({
|
|
1240
|
+
balance: assertUint256(BigInt(dto.balance))
|
|
1241
|
+
})
|
|
1242
|
+
};
|
|
1243
|
+
var AllowWalletResponse = {
|
|
1244
|
+
fromDto: (dto) => {
|
|
1245
|
+
switch (dto.action) {
|
|
1246
|
+
case "broadcast_transaction":
|
|
1247
|
+
return {
|
|
1248
|
+
action: "broadcast_transaction",
|
|
1249
|
+
to: EvmContractAddress(dto.to),
|
|
1250
|
+
data: HexEncodedTransactionData(dto.data)
|
|
1251
|
+
};
|
|
1252
|
+
case "none":
|
|
1253
|
+
return {
|
|
1254
|
+
action: "none",
|
|
1255
|
+
alreadyAllowed: dto.already_allowed
|
|
1256
|
+
};
|
|
1257
|
+
default: {
|
|
1258
|
+
const _exhaustive = dto;
|
|
1259
|
+
return _exhaustive;
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
};
|
|
1264
|
+
|
|
1265
|
+
// src/shared/api/frontline/swap.ts
|
|
1266
|
+
async function getSwapAuthorization(api, params) {
|
|
1267
|
+
const dto = await api.send({
|
|
1268
|
+
method: "GET",
|
|
1269
|
+
url: "/v1/wallet/authorized",
|
|
1270
|
+
queryParams: {
|
|
1271
|
+
chain: params.chain,
|
|
1272
|
+
contract_address: params.contractAddress,
|
|
1273
|
+
wallet_address: params.walletAddress
|
|
1274
|
+
},
|
|
1275
|
+
attributes: Attributes.protected()
|
|
1276
|
+
});
|
|
1277
|
+
return SwapAuthorization.fromDto(dto);
|
|
1278
|
+
}
|
|
1279
|
+
async function getSwapOutputToken(api, params) {
|
|
1280
|
+
const dto = await api.send({
|
|
1281
|
+
method: "GET",
|
|
1282
|
+
url: "/v1/swap/output-token",
|
|
1283
|
+
queryParams: {
|
|
1284
|
+
chain: params.chain,
|
|
1285
|
+
contract_address: params.contractAddress
|
|
1286
|
+
},
|
|
1287
|
+
attributes: Attributes.protected()
|
|
1288
|
+
});
|
|
1289
|
+
return toErc20Asset(dto);
|
|
1290
|
+
}
|
|
1291
|
+
async function getSwapPreview(api, params) {
|
|
1292
|
+
const dto = await api.send({
|
|
1293
|
+
method: "GET",
|
|
1294
|
+
url: "/v1/swap/preview",
|
|
1295
|
+
queryParams: {
|
|
1296
|
+
chain: params.chain,
|
|
1297
|
+
contract_address: params.contractAddress,
|
|
1298
|
+
input_token: params.inputToken,
|
|
1299
|
+
amount: params.amount.toString()
|
|
1300
|
+
},
|
|
1301
|
+
attributes: Attributes.protected()
|
|
1302
|
+
});
|
|
1303
|
+
return SwapPreview.fromDto(dto);
|
|
1304
|
+
}
|
|
1305
|
+
async function getSwapStatus(api, params) {
|
|
1306
|
+
const dto = await api.send({
|
|
1307
|
+
method: "GET",
|
|
1308
|
+
url: "/v1/swap/status",
|
|
1309
|
+
queryParams: {
|
|
1310
|
+
chain: params.chain,
|
|
1311
|
+
contract_address: params.contractAddress
|
|
1312
|
+
},
|
|
1313
|
+
attributes: Attributes.protected()
|
|
1314
|
+
});
|
|
1315
|
+
return SwapStatus.fromDto(dto);
|
|
1316
|
+
}
|
|
1317
|
+
async function getTokenAllowance(api, params) {
|
|
1318
|
+
const dto = await api.send({
|
|
1319
|
+
method: "GET",
|
|
1320
|
+
url: "/v1/token/allowance",
|
|
1321
|
+
queryParams: {
|
|
1322
|
+
chain: params.chain,
|
|
1323
|
+
token_address: params.tokenAddress,
|
|
1324
|
+
owner: params.owner,
|
|
1325
|
+
spender: params.spender
|
|
1326
|
+
},
|
|
1327
|
+
attributes: Attributes.protected()
|
|
1328
|
+
});
|
|
1329
|
+
return TokenAllowance.fromDto(dto);
|
|
1330
|
+
}
|
|
1331
|
+
async function getTokenBalance(api, params) {
|
|
1332
|
+
const dto = await api.send({
|
|
1333
|
+
method: "GET",
|
|
1334
|
+
url: "/v1/token/balance",
|
|
1335
|
+
queryParams: {
|
|
1336
|
+
chain: params.chain,
|
|
1337
|
+
token_address: params.tokenAddress,
|
|
1338
|
+
owner: params.owner
|
|
1339
|
+
},
|
|
1340
|
+
attributes: Attributes.protected()
|
|
1341
|
+
});
|
|
1342
|
+
return TokenBalance.fromDto(dto);
|
|
1343
|
+
}
|
|
1344
|
+
async function allowWallet(api, params) {
|
|
1345
|
+
const dto = await api.send({
|
|
1346
|
+
method: "POST",
|
|
1347
|
+
url: `/v1/offers/${encodeURIComponent(params.offerId)}/allow-wallet`,
|
|
1348
|
+
body: {
|
|
1349
|
+
wallet_address: params.walletAddress,
|
|
1350
|
+
chain: params.chain,
|
|
1351
|
+
signature: params.signature
|
|
1352
|
+
},
|
|
1353
|
+
attributes: Attributes.protected()
|
|
1354
|
+
});
|
|
1355
|
+
return AllowWalletResponse.fromDto(dto);
|
|
1356
|
+
}
|
|
1357
|
+
function toErc20Asset(dto) {
|
|
1358
|
+
return {
|
|
1359
|
+
name: dto.name,
|
|
1360
|
+
symbol: AssetSymbol(dto.symbol),
|
|
1361
|
+
decimals: AssetDecimals(dto.decimals)
|
|
1362
|
+
};
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
// src/shared/types/asset.ts
|
|
1366
|
+
var AssetId = (value) => value;
|
|
1367
|
+
var AssetCode = (value) => value;
|
|
1368
|
+
var Asset = {
|
|
1369
|
+
fromDto: (dto) => ({
|
|
1370
|
+
id: AssetId(dto.id),
|
|
1371
|
+
code: AssetCode(dto.code),
|
|
1372
|
+
name: dto.name,
|
|
1373
|
+
fractionalDigits: dto.fractional_digits
|
|
1374
|
+
})
|
|
1375
|
+
};
|
|
1376
|
+
|
|
1377
|
+
// src/shared/types/offer.ts
|
|
1378
|
+
var OfferId = (value) => value;
|
|
1379
|
+
var OfferSlug = (value) => value;
|
|
1380
|
+
var Offer = {
|
|
1381
|
+
fromDto: (dto) => ({
|
|
1382
|
+
id: OfferId(dto.id),
|
|
1383
|
+
slug: OfferSlug(dto.slug),
|
|
1384
|
+
type: dto.type,
|
|
1385
|
+
tagline: dto.tagline,
|
|
1386
|
+
bannerUrl: dto.banner_url,
|
|
1387
|
+
logoUrl: dto.logo_url,
|
|
1388
|
+
startsAt: new Date(dto.starts_at),
|
|
1389
|
+
endsAt: dto.ends_at ? new Date(dto.ends_at) : null
|
|
1390
|
+
})
|
|
1391
|
+
};
|
|
1392
|
+
|
|
1393
|
+
// src/shared/types/offer-detail.ts
|
|
1394
|
+
var OfferOptionId = (value) => value;
|
|
1395
|
+
var OfferOptionSlug = (value) => value;
|
|
1396
|
+
var OfferDetail = {
|
|
1397
|
+
fromDto: (dto) => {
|
|
1398
|
+
if (!Array.isArray(dto.funding_assets)) {
|
|
1399
|
+
throw new Error(`funding_assets must be an array`);
|
|
1400
|
+
}
|
|
1401
|
+
if (!Array.isArray(dto.options)) {
|
|
606
1402
|
throw new Error(`options must be an array`);
|
|
607
1403
|
}
|
|
608
1404
|
if (!Array.isArray(dto.terms)) {
|
|
@@ -620,16 +1416,17 @@ var OfferDetail = {
|
|
|
620
1416
|
return {
|
|
621
1417
|
id: OfferId(dto.id),
|
|
622
1418
|
slug: OfferSlug(dto.slug),
|
|
1419
|
+
type: dto.type,
|
|
623
1420
|
name: dto.name,
|
|
624
1421
|
asset: Asset.fromDto(dto.asset),
|
|
625
1422
|
fundingAssets: dto.funding_assets.map(Asset.fromDto),
|
|
626
1423
|
about: notBlankStringOrNull(dto.about),
|
|
627
|
-
tagline:
|
|
628
|
-
bannerUrl:
|
|
629
|
-
logoUrl:
|
|
630
|
-
category:
|
|
1424
|
+
tagline: dto.tagline,
|
|
1425
|
+
bannerUrl: dto.banner_url,
|
|
1426
|
+
logoUrl: dto.logo_url,
|
|
1427
|
+
category: dto.category,
|
|
631
1428
|
startsAt: new Date(dto.starts_at),
|
|
632
|
-
endsAt: new Date(dto.ends_at),
|
|
1429
|
+
endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
|
|
633
1430
|
faqs: dto.faqs.map(FaqItem.fromDto),
|
|
634
1431
|
links: dto.links.map(Link.fromDto),
|
|
635
1432
|
milestones: dto.milestones.map(Milestone.fromDto),
|
|
@@ -676,28 +1473,187 @@ var Milestone = {
|
|
|
676
1473
|
})
|
|
677
1474
|
};
|
|
678
1475
|
|
|
679
|
-
// src/shared/
|
|
680
|
-
|
|
681
|
-
|
|
1476
|
+
// src/shared/types/offer-option-address.ts
|
|
1477
|
+
var OfferOptionAddressId = (value) => value;
|
|
1478
|
+
var OfferOptionAddress = {
|
|
1479
|
+
/** Maps the API DTO into the SDK offer-option-address domain model. */
|
|
1480
|
+
fromDto: (dto) => ({
|
|
1481
|
+
id: OfferOptionAddressId(dto.id),
|
|
1482
|
+
offerOptionId: OfferOptionId(dto.offer_option_id),
|
|
1483
|
+
address: EvmWalletAddress(dto.address),
|
|
1484
|
+
protocol: dto.protocol,
|
|
1485
|
+
createdAt: new Date(dto.created_at)
|
|
1486
|
+
})
|
|
1487
|
+
};
|
|
1488
|
+
var ConnectExternalWalletParams = {
|
|
1489
|
+
/** Maps connect-wallet params into the API DTO payload. */
|
|
1490
|
+
toDto: (params) => ({
|
|
1491
|
+
offer_option_id: params.offerOptionId,
|
|
1492
|
+
wallet_address: params.walletAddress,
|
|
1493
|
+
chain: params.chain,
|
|
1494
|
+
signature: params.signature
|
|
1495
|
+
})
|
|
1496
|
+
};
|
|
1497
|
+
|
|
1498
|
+
// src/shared/types/wallet-ownership-challenge.ts
|
|
1499
|
+
var WalletOwnershipChallenge = {
|
|
1500
|
+
/** Maps the API DTO into the SDK wallet-ownership-challenge domain model. */
|
|
1501
|
+
fromDto: (dto) => ({
|
|
1502
|
+
message: dto.message,
|
|
1503
|
+
expiresAt: new Date(dto.expires_at)
|
|
1504
|
+
})
|
|
1505
|
+
};
|
|
1506
|
+
var CreateWalletOwnershipChallengeParams = {
|
|
1507
|
+
/**
|
|
1508
|
+
* Maps challenge-request params into the API DTO payload. The discriminated
|
|
1509
|
+
* union guarantees SIWE fields are present exactly when `challengeType` is
|
|
1510
|
+
* `siwe`, so the mapping narrows on the discriminant.
|
|
1511
|
+
*/
|
|
1512
|
+
toDto: (params) => {
|
|
1513
|
+
switch (params.challengeType) {
|
|
1514
|
+
case "plain":
|
|
1515
|
+
return {
|
|
1516
|
+
wallet_address: params.walletAddress,
|
|
1517
|
+
chain: params.chain,
|
|
1518
|
+
challenge_type: "plain"
|
|
1519
|
+
};
|
|
1520
|
+
case "siwe":
|
|
1521
|
+
return {
|
|
1522
|
+
wallet_address: params.walletAddress,
|
|
1523
|
+
chain: params.chain,
|
|
1524
|
+
challenge_type: "siwe",
|
|
1525
|
+
domain: params.domain,
|
|
1526
|
+
uri: params.uri,
|
|
1527
|
+
statement: params.statement
|
|
1528
|
+
};
|
|
1529
|
+
default: {
|
|
1530
|
+
const _exhaustive = params;
|
|
1531
|
+
return _exhaustive;
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
};
|
|
1536
|
+
|
|
1537
|
+
// src/shared/api/frontline/wallet-connect.ts
|
|
1538
|
+
async function createWalletOwnershipChallenge(api, params) {
|
|
1539
|
+
const dto = await api.send({
|
|
1540
|
+
method: "POST",
|
|
1541
|
+
url: "/v1/wallet-ownership",
|
|
1542
|
+
body: CreateWalletOwnershipChallengeParams.toDto(params),
|
|
1543
|
+
attributes: Attributes.protected()
|
|
1544
|
+
});
|
|
1545
|
+
return WalletOwnershipChallenge.fromDto(dto);
|
|
682
1546
|
}
|
|
683
|
-
async function
|
|
684
|
-
const
|
|
685
|
-
|
|
1547
|
+
async function connectExternalWallet(api, offerId, params) {
|
|
1548
|
+
const dto = await api.send({
|
|
1549
|
+
method: "POST",
|
|
1550
|
+
url: `/v1/offers/${offerId}/addresses`,
|
|
1551
|
+
body: ConnectExternalWalletParams.toDto(params),
|
|
1552
|
+
attributes: Attributes.protected()
|
|
1553
|
+
});
|
|
1554
|
+
return OfferOptionAddress.fromDto(dto);
|
|
1555
|
+
}
|
|
1556
|
+
async function listOptionAddresses(api, offerId, offerOptionId) {
|
|
1557
|
+
const { data } = await api.send({
|
|
686
1558
|
method: "GET",
|
|
687
|
-
url:
|
|
688
|
-
queryParams,
|
|
1559
|
+
url: `/v1/offers/${offerId}/addresses`,
|
|
1560
|
+
queryParams: { offer_option_id: offerOptionId },
|
|
689
1561
|
attributes: Attributes.protected()
|
|
690
1562
|
});
|
|
691
|
-
return
|
|
1563
|
+
return data.map(OfferOptionAddress.fromDto);
|
|
692
1564
|
}
|
|
693
|
-
async function
|
|
1565
|
+
async function removeOptionAddress(api, offerId, addressId) {
|
|
694
1566
|
const dto = await api.send({
|
|
695
|
-
method: "
|
|
696
|
-
url: `/v1/offers/${
|
|
1567
|
+
method: "DELETE",
|
|
1568
|
+
url: `/v1/offers/${offerId}/addresses/${addressId}`,
|
|
697
1569
|
attributes: Attributes.protected()
|
|
698
1570
|
});
|
|
699
|
-
return
|
|
1571
|
+
return OfferOptionAddress.fromDto(dto);
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
// src/shared/core/swap-namespace.ts
|
|
1575
|
+
var SwapNamespaceImpl = class {
|
|
1576
|
+
constructor(ctx) {
|
|
1577
|
+
this.ctx = ctx;
|
|
1578
|
+
}
|
|
1579
|
+
async getAuthorization(params) {
|
|
1580
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1581
|
+
return getSwapAuthorization(this.ctx.api, params);
|
|
1582
|
+
}
|
|
1583
|
+
async getPreview(params) {
|
|
1584
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1585
|
+
return getSwapPreview(this.ctx.api, params);
|
|
1586
|
+
}
|
|
1587
|
+
async getStatus(params) {
|
|
1588
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1589
|
+
return getSwapStatus(this.ctx.api, params);
|
|
1590
|
+
}
|
|
1591
|
+
async getOutputToken(params) {
|
|
1592
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1593
|
+
return getSwapOutputToken(this.ctx.api, params);
|
|
1594
|
+
}
|
|
1595
|
+
async requestWalletOwnershipChallenge(params) {
|
|
1596
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1597
|
+
return createWalletOwnershipChallenge(this.ctx.api, params);
|
|
1598
|
+
}
|
|
1599
|
+
async allowWallet(params) {
|
|
1600
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1601
|
+
return allowWallet(this.ctx.api, params);
|
|
1602
|
+
}
|
|
1603
|
+
};
|
|
1604
|
+
|
|
1605
|
+
// src/client/core/client-swap-namespace.ts
|
|
1606
|
+
var ClientSwapNamespaceImpl = class extends SwapNamespaceImpl {
|
|
1607
|
+
constructor(ctx, erc20) {
|
|
1608
|
+
super(ctx);
|
|
1609
|
+
this.erc20 = erc20;
|
|
1610
|
+
}
|
|
1611
|
+
executeSwap(params) {
|
|
1612
|
+
return executeSwap({ ...params, swap: this, erc20: this.erc20 });
|
|
1613
|
+
}
|
|
1614
|
+
authorizeWallet(params) {
|
|
1615
|
+
return authorizeWallet({ ...params, swap: this });
|
|
1616
|
+
}
|
|
1617
|
+
};
|
|
1618
|
+
|
|
1619
|
+
// src/shared/api/pagination.ts
|
|
1620
|
+
var Cursor = (value) => value;
|
|
1621
|
+
async function fetchAllPages(fetchPage, baseParams) {
|
|
1622
|
+
const items = [];
|
|
1623
|
+
let cursor = null;
|
|
1624
|
+
do {
|
|
1625
|
+
const params = {
|
|
1626
|
+
...baseParams ?? {},
|
|
1627
|
+
after: cursor ?? void 0
|
|
1628
|
+
};
|
|
1629
|
+
const page = await fetchPage(params);
|
|
1630
|
+
items.push(...page.data);
|
|
1631
|
+
cursor = page.startingAfter;
|
|
1632
|
+
} while (cursor);
|
|
1633
|
+
return items;
|
|
700
1634
|
}
|
|
1635
|
+
var PaginatedResponse = {
|
|
1636
|
+
fromDto: (dto, itemMapper) => ({
|
|
1637
|
+
data: dto.data.map(itemMapper),
|
|
1638
|
+
startingAfter: dto.starting_after ? Cursor(dto.starting_after) : null,
|
|
1639
|
+
startingBefore: dto.starting_before ? Cursor(dto.starting_before) : null
|
|
1640
|
+
})
|
|
1641
|
+
};
|
|
1642
|
+
var PaginationParams = {
|
|
1643
|
+
toQueryParams: (params) => {
|
|
1644
|
+
const queryParams = {};
|
|
1645
|
+
if (params.after) {
|
|
1646
|
+
queryParams.starting_after = params.after;
|
|
1647
|
+
}
|
|
1648
|
+
if (params.before) {
|
|
1649
|
+
queryParams.starting_before = params.before;
|
|
1650
|
+
}
|
|
1651
|
+
if (params.limit) {
|
|
1652
|
+
queryParams.limit = params.limit;
|
|
1653
|
+
}
|
|
1654
|
+
return queryParams;
|
|
1655
|
+
}
|
|
1656
|
+
};
|
|
701
1657
|
|
|
702
1658
|
// src/shared/types/participation.ts
|
|
703
1659
|
var ParticipationId = (value) => value;
|
|
@@ -746,6 +1702,85 @@ var CreateParticipationParams = {
|
|
|
746
1702
|
})
|
|
747
1703
|
};
|
|
748
1704
|
|
|
1705
|
+
// src/client/core/blockchain/token-sale-flow.ts
|
|
1706
|
+
async function executeTokenSale(params) {
|
|
1707
|
+
const {
|
|
1708
|
+
erc20,
|
|
1709
|
+
tokenSale,
|
|
1710
|
+
wallet,
|
|
1711
|
+
offerId,
|
|
1712
|
+
offerOptionId,
|
|
1713
|
+
assetId,
|
|
1714
|
+
paymentTokenAddress,
|
|
1715
|
+
fundingContractAddress,
|
|
1716
|
+
chain,
|
|
1717
|
+
amount,
|
|
1718
|
+
onProgress
|
|
1719
|
+
} = params;
|
|
1720
|
+
const emit = (phase) => onProgress?.(phase);
|
|
1721
|
+
emit("checking-allowance");
|
|
1722
|
+
let currentAllowance;
|
|
1723
|
+
try {
|
|
1724
|
+
const allowance = await erc20.getTokenAllowance({
|
|
1725
|
+
tokenAddress: paymentTokenAddress,
|
|
1726
|
+
owner: wallet.address,
|
|
1727
|
+
spender: fundingContractAddress,
|
|
1728
|
+
chain
|
|
1729
|
+
});
|
|
1730
|
+
currentAllowance = allowance.allowance;
|
|
1731
|
+
} catch {
|
|
1732
|
+
return { type: "error", error: { step: "allowance-check" } };
|
|
1733
|
+
}
|
|
1734
|
+
if (currentAllowance > 0n) {
|
|
1735
|
+
const reset = await submitErc20Approval({
|
|
1736
|
+
wallet,
|
|
1737
|
+
tokenAddress: paymentTokenAddress,
|
|
1738
|
+
spender: fundingContractAddress,
|
|
1739
|
+
chain,
|
|
1740
|
+
value: 0n,
|
|
1741
|
+
pending: "resetting-allowance",
|
|
1742
|
+
confirming: "confirming-allowance-reset",
|
|
1743
|
+
emit
|
|
1744
|
+
});
|
|
1745
|
+
if (reset.type === "error") {
|
|
1746
|
+
return {
|
|
1747
|
+
type: "error",
|
|
1748
|
+
error: reset.error.step === "approval-reverted" ? { step: "allowance-reset-reverted" } : { step: "allowance-reset", cause: reset.error.cause }
|
|
1749
|
+
};
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
const approve = await submitErc20Approval({
|
|
1753
|
+
wallet,
|
|
1754
|
+
tokenAddress: paymentTokenAddress,
|
|
1755
|
+
spender: fundingContractAddress,
|
|
1756
|
+
chain,
|
|
1757
|
+
value: amount.raw,
|
|
1758
|
+
pending: "approving",
|
|
1759
|
+
confirming: "confirming-approval",
|
|
1760
|
+
emit
|
|
1761
|
+
});
|
|
1762
|
+
if (approve.type === "error") {
|
|
1763
|
+
return { type: "error", error: approve.error };
|
|
1764
|
+
}
|
|
1765
|
+
const approvalTxHash = approve.txHash;
|
|
1766
|
+
emit("recording-participation");
|
|
1767
|
+
let participation;
|
|
1768
|
+
try {
|
|
1769
|
+
participation = await tokenSale.createParticipation({
|
|
1770
|
+
offerId,
|
|
1771
|
+
offerOptionId,
|
|
1772
|
+
chain: Blockchain(chain),
|
|
1773
|
+
walletAddress: WalletAddress(wallet.address),
|
|
1774
|
+
amount: amount.raw.toString(),
|
|
1775
|
+
assetId,
|
|
1776
|
+
approvalTransactionHash: approvalTxHash
|
|
1777
|
+
});
|
|
1778
|
+
} catch {
|
|
1779
|
+
return { type: "error", error: { step: "participation", approvalTxHash } };
|
|
1780
|
+
}
|
|
1781
|
+
return { type: "success", participation, approvalTxHash };
|
|
1782
|
+
}
|
|
1783
|
+
|
|
749
1784
|
// src/shared/api/frontline/participations.ts
|
|
750
1785
|
async function fetchParticipations(api, offerId) {
|
|
751
1786
|
return fetchAllPages(
|
|
@@ -780,53 +1815,217 @@ async function createParticipation(api, params) {
|
|
|
780
1815
|
return Participation.fromDto(dto);
|
|
781
1816
|
}
|
|
782
1817
|
|
|
783
|
-
// src/shared/
|
|
784
|
-
var
|
|
785
|
-
|
|
1818
|
+
// src/shared/core/token-sale-namespace.ts
|
|
1819
|
+
var TokenSaleNamespaceImpl = class {
|
|
1820
|
+
constructor(ctx) {
|
|
1821
|
+
this.ctx = ctx;
|
|
1822
|
+
}
|
|
1823
|
+
async fetchParticipations(offerId) {
|
|
1824
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1825
|
+
return fetchParticipations(this.ctx.api, offerId);
|
|
1826
|
+
}
|
|
1827
|
+
async fetchParticipationsPage(params) {
|
|
1828
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1829
|
+
return fetchParticipationsPage(this.ctx.api, params);
|
|
1830
|
+
}
|
|
1831
|
+
async fetchParticipation(id) {
|
|
1832
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1833
|
+
return fetchParticipation(this.ctx.api, id);
|
|
1834
|
+
}
|
|
1835
|
+
async createParticipation(params) {
|
|
1836
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1837
|
+
return createParticipation(this.ctx.api, params);
|
|
1838
|
+
}
|
|
1839
|
+
};
|
|
1840
|
+
|
|
1841
|
+
// src/client/core/client-token-sale-namespace.ts
|
|
1842
|
+
var ClientTokenSaleNamespaceImpl = class extends TokenSaleNamespaceImpl {
|
|
1843
|
+
constructor(ctx, erc20) {
|
|
1844
|
+
super(ctx);
|
|
1845
|
+
this.erc20 = erc20;
|
|
1846
|
+
}
|
|
1847
|
+
executeTokenSale(params) {
|
|
1848
|
+
return executeTokenSale({ ...params, erc20: this.erc20, tokenSale: this });
|
|
1849
|
+
}
|
|
1850
|
+
};
|
|
1851
|
+
|
|
1852
|
+
// src/shared/types/document-submission.ts
|
|
1853
|
+
var DocumentSubmission = {
|
|
786
1854
|
fromDto: (dto) => ({
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
details: dto.details
|
|
1855
|
+
status: dto.status,
|
|
1856
|
+
formType: dto.form_type
|
|
790
1857
|
})
|
|
791
1858
|
};
|
|
792
|
-
var RequirementStatusInfo = {
|
|
793
|
-
fromStatusesDto: (dto) => Object.entries(dto.statuses).map(([id, status]) => ({
|
|
794
|
-
id: RequirementId(id),
|
|
795
|
-
status
|
|
796
|
-
}))
|
|
797
|
-
};
|
|
798
1859
|
|
|
799
|
-
// src/shared/api/frontline/
|
|
800
|
-
async function
|
|
801
|
-
const
|
|
802
|
-
method: "
|
|
803
|
-
url: `/v1/
|
|
1860
|
+
// src/shared/api/frontline/documents.ts
|
|
1861
|
+
async function submitDocument(api, documentType, fields) {
|
|
1862
|
+
const dto = await api.send({
|
|
1863
|
+
method: "POST",
|
|
1864
|
+
url: `/v1/documents/${documentType}/submission`,
|
|
1865
|
+
body: fields,
|
|
804
1866
|
attributes: Attributes.protected()
|
|
805
1867
|
});
|
|
806
|
-
return
|
|
807
|
-
Object.entries(response.options).map(([optionId, list]) => [
|
|
808
|
-
optionId,
|
|
809
|
-
list.data.map(Requirement.fromDto)
|
|
810
|
-
])
|
|
811
|
-
);
|
|
1868
|
+
return DocumentSubmission.fromDto(dto);
|
|
812
1869
|
}
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
1870
|
+
|
|
1871
|
+
// src/shared/types/kyc.ts
|
|
1872
|
+
var KycToken = {
|
|
1873
|
+
fromDto: (dto) => ({
|
|
1874
|
+
token: dto.token
|
|
1875
|
+
})
|
|
1876
|
+
};
|
|
1877
|
+
|
|
1878
|
+
// src/shared/api/frontline/kyc.ts
|
|
1879
|
+
async function createKycToken(api, levelName, reset) {
|
|
1880
|
+
const dto = await api.send({
|
|
1881
|
+
method: "POST",
|
|
1882
|
+
url: "/v1/kyc-token",
|
|
1883
|
+
body: {
|
|
1884
|
+
...levelName === void 0 ? {} : { level_name: levelName },
|
|
1885
|
+
...reset === void 0 ? {} : { reset }
|
|
1886
|
+
},
|
|
817
1887
|
attributes: Attributes.protected()
|
|
818
1888
|
});
|
|
819
|
-
return
|
|
1889
|
+
return KycToken.fromDto(dto);
|
|
820
1890
|
}
|
|
821
1891
|
|
|
822
|
-
// src/shared/
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
1892
|
+
// src/shared/api/frontline/offers.ts
|
|
1893
|
+
async function fetchOffers(api, clientCreds) {
|
|
1894
|
+
return fetchAllPages((params) => fetchOffersPage(api, params, clientCreds));
|
|
1895
|
+
}
|
|
1896
|
+
async function fetchOffersPage(api, params, clientCreds) {
|
|
1897
|
+
const queryParams = PaginationParams.toQueryParams(params);
|
|
1898
|
+
const pageDto = await api.send({
|
|
1899
|
+
method: "GET",
|
|
1900
|
+
url: "/v1/offers",
|
|
1901
|
+
queryParams,
|
|
1902
|
+
attributes: Attributes.concat(
|
|
1903
|
+
Attributes.protected(),
|
|
1904
|
+
Attributes.clientCredentials(clientCreds)
|
|
1905
|
+
)
|
|
1906
|
+
});
|
|
1907
|
+
return PaginatedResponse.fromDto(pageDto, Offer.fromDto);
|
|
1908
|
+
}
|
|
1909
|
+
async function fetchOfferDetails(api, id, clientCreds) {
|
|
1910
|
+
const dto = await api.send({
|
|
1911
|
+
method: "GET",
|
|
1912
|
+
url: `/v1/offers/${id}`,
|
|
1913
|
+
attributes: Attributes.concat(
|
|
1914
|
+
Attributes.protected(),
|
|
1915
|
+
Attributes.clientCredentials(clientCreds)
|
|
1916
|
+
)
|
|
1917
|
+
});
|
|
1918
|
+
return OfferDetail.fromDto(dto);
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
// src/shared/types/pii.ts
|
|
1922
|
+
var Iso2CountryCode = (value) => value;
|
|
1923
|
+
var PiiJurisdiction = {
|
|
1924
|
+
fromDto: (dto) => ({
|
|
1925
|
+
iso2: Iso2CountryCode(dto.iso_2),
|
|
1926
|
+
name: dto.name
|
|
1927
|
+
})
|
|
1928
|
+
};
|
|
1929
|
+
var PiiAddress = {
|
|
1930
|
+
fromDto: (dto) => ({
|
|
1931
|
+
street: dto.street,
|
|
1932
|
+
city: dto.city,
|
|
1933
|
+
state: dto.state,
|
|
1934
|
+
postalCode: dto.postal_code,
|
|
1935
|
+
country: dto.country
|
|
1936
|
+
})
|
|
1937
|
+
};
|
|
1938
|
+
var Pii = {
|
|
1939
|
+
fromDto: (dto) => ({
|
|
1940
|
+
kind: dto.kind,
|
|
1941
|
+
fullLegalName: dto.full_legal_name,
|
|
1942
|
+
dateOfBirth: dto.date_of_birth,
|
|
1943
|
+
jurisdiction: dto.jurisdiction ? PiiJurisdiction.fromDto(dto.jurisdiction) : null,
|
|
1944
|
+
taxId: dto.tax_id,
|
|
1945
|
+
permanentAddress: PiiAddress.fromDto(dto.permanent_address)
|
|
1946
|
+
})
|
|
1947
|
+
};
|
|
1948
|
+
|
|
1949
|
+
// src/shared/api/frontline/pii.ts
|
|
1950
|
+
async function fetchPii(api) {
|
|
1951
|
+
const dto = await api.send({
|
|
1952
|
+
method: "GET",
|
|
1953
|
+
url: "/v1/pii",
|
|
1954
|
+
attributes: Attributes.protected()
|
|
1955
|
+
});
|
|
1956
|
+
return Pii.fromDto(dto);
|
|
1957
|
+
}
|
|
1958
|
+
|
|
1959
|
+
// src/shared/types/requirement.ts
|
|
1960
|
+
var RequirementId = (value) => value;
|
|
1961
|
+
var Requirement = {
|
|
1962
|
+
fromDto: (dto) => ({
|
|
1963
|
+
id: RequirementId(dto.id),
|
|
1964
|
+
type: dto.type,
|
|
1965
|
+
details: dto.details
|
|
1966
|
+
})
|
|
1967
|
+
};
|
|
1968
|
+
var RequirementStatusInfo = {
|
|
1969
|
+
fromStatusesDto: (dto) => Object.entries(dto.statuses).map(
|
|
1970
|
+
([id, value]) => typeof value === "string" ? { id: RequirementId(id), status: value, action: null } : {
|
|
1971
|
+
id: RequirementId(id),
|
|
1972
|
+
status: value.status,
|
|
1973
|
+
action: value.action ?? null,
|
|
1974
|
+
kycLevel: value.kyc_level,
|
|
1975
|
+
kycReset: value.kyc_reset
|
|
1976
|
+
}
|
|
1977
|
+
)
|
|
1978
|
+
};
|
|
1979
|
+
|
|
1980
|
+
// src/shared/api/frontline/requirements.ts
|
|
1981
|
+
async function fetchOfferRequirements(api, offerId, clientCreds) {
|
|
1982
|
+
const response = await api.send({
|
|
1983
|
+
method: "GET",
|
|
1984
|
+
url: `/v1/offers/${offerId}/requirements`,
|
|
1985
|
+
attributes: Attributes.concat(
|
|
1986
|
+
Attributes.protected(),
|
|
1987
|
+
Attributes.clientCredentials(clientCreds)
|
|
1988
|
+
)
|
|
1989
|
+
});
|
|
1990
|
+
return Object.fromEntries(
|
|
1991
|
+
Object.entries(response.options).map(([optionId, list]) => [
|
|
1992
|
+
optionId,
|
|
1993
|
+
list.data.map(Requirement.fromDto)
|
|
1994
|
+
])
|
|
1995
|
+
);
|
|
1996
|
+
}
|
|
1997
|
+
async function fetchRequirementStatuses(api, offerId) {
|
|
1998
|
+
const response = await api.send({
|
|
1999
|
+
method: "GET",
|
|
2000
|
+
url: `/v1/offers/${offerId}/requirements/statuses`,
|
|
2001
|
+
attributes: Attributes.protected()
|
|
2002
|
+
});
|
|
2003
|
+
return RequirementStatusInfo.fromStatusesDto(response);
|
|
2004
|
+
}
|
|
2005
|
+
|
|
2006
|
+
// src/shared/core/erc20-namespace.ts
|
|
2007
|
+
var Erc20NamespaceImpl = class {
|
|
2008
|
+
constructor(ctx) {
|
|
2009
|
+
this.ctx = ctx;
|
|
2010
|
+
}
|
|
2011
|
+
async getTokenAllowance(params) {
|
|
2012
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2013
|
+
return getTokenAllowance(this.ctx.api, params);
|
|
2014
|
+
}
|
|
2015
|
+
async getTokenBalance(params) {
|
|
2016
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2017
|
+
return getTokenBalance(this.ctx.api, params);
|
|
2018
|
+
}
|
|
2019
|
+
};
|
|
2020
|
+
|
|
2021
|
+
// src/shared/types/oauth.ts
|
|
2022
|
+
var AuthorizationCode = (value) => value;
|
|
2023
|
+
var CodeVerifier = (value) => value;
|
|
2024
|
+
var CodeChallenge = (value) => value;
|
|
2025
|
+
var PKCEState = (value) => value;
|
|
2026
|
+
|
|
2027
|
+
// src/shared/pkce.ts
|
|
2028
|
+
async function generatePKCEParams(config) {
|
|
830
2029
|
const state = generateSecureRandomBase64Url(32);
|
|
831
2030
|
const codeVerifier = generateSecureRandomBase64Url(32);
|
|
832
2031
|
const codeChallengeRaw = await sha256(codeVerifier);
|
|
@@ -865,6 +2064,13 @@ var CoinListClientImpl = class {
|
|
|
865
2064
|
},
|
|
866
2065
|
this.fetchAccessToken.bind(this)
|
|
867
2066
|
);
|
|
2067
|
+
const ctx = {
|
|
2068
|
+
api: this.api,
|
|
2069
|
+
ensureUserAuthenticated: async () => this.ensureAuthenticated()
|
|
2070
|
+
};
|
|
2071
|
+
this.erc20 = new Erc20NamespaceImpl(ctx);
|
|
2072
|
+
this.tokenSale = new ClientTokenSaleNamespaceImpl(ctx, this.erc20);
|
|
2073
|
+
this.swap = new ClientSwapNamespaceImpl(ctx, this.erc20);
|
|
868
2074
|
}
|
|
869
2075
|
async init() {
|
|
870
2076
|
await this.fetchAccessToken(true);
|
|
@@ -936,40 +2142,56 @@ var CoinListClientImpl = class {
|
|
|
936
2142
|
}
|
|
937
2143
|
async fetchOffers() {
|
|
938
2144
|
this.ensureAuthenticated();
|
|
939
|
-
return fetchOffers(this.api);
|
|
2145
|
+
return fetchOffers(this.api, void 0);
|
|
940
2146
|
}
|
|
941
2147
|
async fetchOffersPage(params) {
|
|
942
2148
|
this.ensureAuthenticated();
|
|
943
|
-
return fetchOffersPage(this.api, params);
|
|
2149
|
+
return fetchOffersPage(this.api, params, void 0);
|
|
944
2150
|
}
|
|
945
2151
|
async fetchOfferDetails(id) {
|
|
946
2152
|
this.ensureAuthenticated();
|
|
947
|
-
return fetchOfferDetails(this.api, id);
|
|
2153
|
+
return fetchOfferDetails(this.api, id, void 0);
|
|
948
2154
|
}
|
|
949
|
-
async
|
|
2155
|
+
async createWalletOwnershipChallenge(params) {
|
|
950
2156
|
this.ensureAuthenticated();
|
|
951
|
-
return
|
|
2157
|
+
return createWalletOwnershipChallenge(this.api, params);
|
|
952
2158
|
}
|
|
953
|
-
async
|
|
2159
|
+
async connectExternalWallet(offerId, params) {
|
|
954
2160
|
this.ensureAuthenticated();
|
|
955
|
-
return
|
|
2161
|
+
return connectExternalWallet(this.api, offerId, params);
|
|
956
2162
|
}
|
|
957
|
-
async
|
|
2163
|
+
async listOptionAddresses(offerId, offerOptionId) {
|
|
958
2164
|
this.ensureAuthenticated();
|
|
959
|
-
return
|
|
2165
|
+
return listOptionAddresses(
|
|
2166
|
+
this.api,
|
|
2167
|
+
offerId,
|
|
2168
|
+
offerOptionId
|
|
2169
|
+
);
|
|
960
2170
|
}
|
|
961
|
-
async
|
|
2171
|
+
async removeOptionAddress(offerId, addressId) {
|
|
962
2172
|
this.ensureAuthenticated();
|
|
963
|
-
return
|
|
2173
|
+
return removeOptionAddress(this.api, offerId, addressId);
|
|
964
2174
|
}
|
|
965
2175
|
async fetchOfferRequirements(offerId) {
|
|
966
2176
|
this.ensureAuthenticated();
|
|
967
|
-
return fetchOfferRequirements(this.api, offerId);
|
|
2177
|
+
return fetchOfferRequirements(this.api, offerId, void 0);
|
|
968
2178
|
}
|
|
969
2179
|
async fetchRequirementStatuses(offerId) {
|
|
970
2180
|
this.ensureAuthenticated();
|
|
971
2181
|
return fetchRequirementStatuses(this.api, offerId);
|
|
972
2182
|
}
|
|
2183
|
+
async fetchPii() {
|
|
2184
|
+
this.ensureAuthenticated();
|
|
2185
|
+
return fetchPii(this.api);
|
|
2186
|
+
}
|
|
2187
|
+
async submitDocument(documentType, fields) {
|
|
2188
|
+
this.ensureAuthenticated();
|
|
2189
|
+
return submitDocument(this.api, documentType, fields);
|
|
2190
|
+
}
|
|
2191
|
+
async createKycToken(levelName, reset) {
|
|
2192
|
+
this.ensureAuthenticated();
|
|
2193
|
+
return createKycToken(this.api, levelName, reset);
|
|
2194
|
+
}
|
|
973
2195
|
handleRequirement(requirement) {
|
|
974
2196
|
const baseUrl = this._config.coinlistBaseUrl ?? COINLIST_BASE_URL;
|
|
975
2197
|
let path;
|
|
@@ -996,6 +2218,9 @@ var CoinListClientImpl = class {
|
|
|
996
2218
|
case "jurisdiction":
|
|
997
2219
|
path = null;
|
|
998
2220
|
break;
|
|
2221
|
+
case "document":
|
|
2222
|
+
path = null;
|
|
2223
|
+
break;
|
|
999
2224
|
default: {
|
|
1000
2225
|
const _exhaustive = requirement.type;
|
|
1001
2226
|
return;
|
|
@@ -1021,7 +2246,7 @@ function createCoinListClient(config) {
|
|
|
1021
2246
|
}
|
|
1022
2247
|
|
|
1023
2248
|
// src/client/CoinListProvider.tsx
|
|
1024
|
-
var
|
|
2249
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
1025
2250
|
var CoinListContext = (0, import_react.createContext)(null);
|
|
1026
2251
|
function CoinListContextProvider({
|
|
1027
2252
|
config,
|
|
@@ -1049,10 +2274,53 @@ function CoinListContextProvider({
|
|
|
1049
2274
|
};
|
|
1050
2275
|
}, [coinlist]);
|
|
1051
2276
|
const value = (0, import_react.useMemo)(() => ({ coinlist, isReady }), [coinlist, isReady]);
|
|
1052
|
-
return /* @__PURE__ */ (0,
|
|
2277
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CoinListContext.Provider, { value, children });
|
|
1053
2278
|
}
|
|
1054
|
-
|
|
1055
|
-
|
|
2279
|
+
var CoinListProvider = CoinListContextProvider;
|
|
2280
|
+
|
|
2281
|
+
// src/client/CoinListStyleScope.tsx
|
|
2282
|
+
var import_react2 = require("react");
|
|
2283
|
+
|
|
2284
|
+
// src/client/generated/sdk-styles.gen.ts
|
|
2285
|
+
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}}';
|
|
2286
|
+
|
|
2287
|
+
// src/client/CoinListStyleScope.tsx
|
|
2288
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
2289
|
+
var ScopeContext = (0, import_react2.createContext)(false);
|
|
2290
|
+
function CoinListStyleScope({ children }) {
|
|
2291
|
+
const alreadyScoped = (0, import_react2.useContext)(ScopeContext);
|
|
2292
|
+
if (alreadyScoped) {
|
|
2293
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
|
|
2294
|
+
}
|
|
2295
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
2296
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "preconnect", href: "https://fonts.googleapis.com" }),
|
|
2297
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2298
|
+
"link",
|
|
2299
|
+
{
|
|
2300
|
+
rel: "preconnect",
|
|
2301
|
+
href: "https://fonts.gstatic.com",
|
|
2302
|
+
crossOrigin: "anonymous"
|
|
2303
|
+
}
|
|
2304
|
+
),
|
|
2305
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2306
|
+
"link",
|
|
2307
|
+
{
|
|
2308
|
+
rel: "stylesheet",
|
|
2309
|
+
href: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap"
|
|
2310
|
+
}
|
|
2311
|
+
),
|
|
2312
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "clco-sdk-root", style: { display: "contents" }, children: [
|
|
2313
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2314
|
+
"style",
|
|
2315
|
+
{
|
|
2316
|
+
href: "clco-sdk-styles",
|
|
2317
|
+
precedence: "default",
|
|
2318
|
+
dangerouslySetInnerHTML: { __html: sdkStyles }
|
|
2319
|
+
}
|
|
2320
|
+
),
|
|
2321
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ScopeContext.Provider, { value: true, children })
|
|
2322
|
+
] })
|
|
2323
|
+
] });
|
|
1056
2324
|
}
|
|
1057
2325
|
|
|
1058
2326
|
// src/client/components/design-system/AlertBanner.tsx
|
|
@@ -1232,7 +2500,7 @@ function PoweredByCoinList({ className }) {
|
|
|
1232
2500
|
|
|
1233
2501
|
// src/client/components/design-system/ClButton.tsx
|
|
1234
2502
|
var import_class_variance_authority = require("class-variance-authority");
|
|
1235
|
-
var
|
|
2503
|
+
var import_react3 = require("react");
|
|
1236
2504
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1237
2505
|
var buttonVariants = (0, import_class_variance_authority.cva)(
|
|
1238
2506
|
"clcosdk:inline-flex clcosdk:items-center clcosdk:justify-center clcosdk:gap-3 clcosdk:whitespace-nowrap clcosdk:transition-colors clcosdk:focus-visible:outline-none clcosdk:focus-visible:ring-2 clcosdk:focus-visible:ring-offset-2 clcosdk:disabled:pointer-events-none clcosdk:disabled:opacity-40 clcosdk:cursor-pointer",
|
|
@@ -1284,7 +2552,7 @@ var buttonVariants = (0, import_class_variance_authority.cva)(
|
|
|
1284
2552
|
}
|
|
1285
2553
|
}
|
|
1286
2554
|
);
|
|
1287
|
-
var ClButton = (0,
|
|
2555
|
+
var ClButton = (0, import_react3.forwardRef)(
|
|
1288
2556
|
({
|
|
1289
2557
|
className,
|
|
1290
2558
|
variant,
|
|
@@ -1402,9 +2670,9 @@ function CoinListSignInButton({
|
|
|
1402
2670
|
}
|
|
1403
2671
|
|
|
1404
2672
|
// src/client/hooks/useCoinList.ts
|
|
1405
|
-
var
|
|
2673
|
+
var import_react4 = require("react");
|
|
1406
2674
|
function useCoinList() {
|
|
1407
|
-
const context = (0,
|
|
2675
|
+
const context = (0, import_react4.useContext)(CoinListContext);
|
|
1408
2676
|
if (context === null) {
|
|
1409
2677
|
throw new CoinListClientInitializationError();
|
|
1410
2678
|
}
|
|
@@ -1432,7 +2700,7 @@ function CoinListSignInCard({
|
|
|
1432
2700
|
const handleSignIn = onSignIn ?? (() => {
|
|
1433
2701
|
void coinlist.startOAuth();
|
|
1434
2702
|
});
|
|
1435
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2703
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CoinListStyleScope, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1436
2704
|
"div",
|
|
1437
2705
|
{
|
|
1438
2706
|
className: cn(
|
|
@@ -1471,7 +2739,7 @@ function CoinListSignInCard({
|
|
|
1471
2739
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PoweredByCoinList, { className: "clcosdk:mt-4" })
|
|
1472
2740
|
]
|
|
1473
2741
|
}
|
|
1474
|
-
);
|
|
2742
|
+
) });
|
|
1475
2743
|
}
|
|
1476
2744
|
|
|
1477
2745
|
// src/client/components/offers/OfferCard.tsx
|
|
@@ -1486,7 +2754,7 @@ var OfferCardUi = {
|
|
|
1486
2754
|
bannerUrl: offer.bannerUrl,
|
|
1487
2755
|
logoUrl: offer.logoUrl,
|
|
1488
2756
|
formattedStartsAt: monthYearFormatter.format(offer.startsAt),
|
|
1489
|
-
formattedEndsAt: monthYearFormatter.format(offer.endsAt)
|
|
2757
|
+
formattedEndsAt: offer.endsAt ? monthYearFormatter.format(offer.endsAt) : null
|
|
1490
2758
|
})
|
|
1491
2759
|
};
|
|
1492
2760
|
function OfferCard({
|
|
@@ -1537,7 +2805,7 @@ function OfferCard({
|
|
|
1537
2805
|
),
|
|
1538
2806
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: cn(typeClasses.label, "clcosdk:text-text-primary"), children: offer.formattedStartsAt })
|
|
1539
2807
|
] }),
|
|
1540
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-1", children: [
|
|
2808
|
+
offer.formattedEndsAt && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-1", children: [
|
|
1541
2809
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1542
2810
|
"span",
|
|
1543
2811
|
{
|
|
@@ -1545,7 +2813,13 @@ function OfferCard({
|
|
|
1545
2813
|
children: "Ends"
|
|
1546
2814
|
}
|
|
1547
2815
|
),
|
|
1548
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2816
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2817
|
+
"span",
|
|
2818
|
+
{
|
|
2819
|
+
className: cn(typeClasses.label, "clcosdk:text-text-primary"),
|
|
2820
|
+
children: offer.formattedEndsAt
|
|
2821
|
+
}
|
|
2822
|
+
)
|
|
1549
2823
|
] })
|
|
1550
2824
|
] })
|
|
1551
2825
|
] });
|
|
@@ -1565,154 +2839,712 @@ function OfferCard({
|
|
|
1565
2839
|
onClick,
|
|
1566
2840
|
children: cardContent
|
|
1567
2841
|
}
|
|
1568
|
-
);
|
|
1569
|
-
} else {
|
|
1570
|
-
cardNode = /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: baseClasses, children: cardContent });
|
|
1571
|
-
}
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
2842
|
+
);
|
|
2843
|
+
} else {
|
|
2844
|
+
cardNode = /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: baseClasses, children: cardContent });
|
|
2845
|
+
}
|
|
2846
|
+
const card = containerClassName ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: containerClassName, children: cardNode }) : cardNode;
|
|
2847
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CoinListStyleScope, { children: card });
|
|
2848
|
+
}
|
|
2849
|
+
|
|
2850
|
+
// src/client/hooks/useOffers.ts
|
|
2851
|
+
var import_react5 = require("react");
|
|
2852
|
+
var LOADING_STATE = { type: "LOADING" };
|
|
2853
|
+
function useOffers(options = {}) {
|
|
2854
|
+
const { coinlist, isReady } = useCoinList();
|
|
2855
|
+
const { data: serverOffers } = options;
|
|
2856
|
+
const [offersState, setOffersState] = (0, import_react5.useState)(
|
|
2857
|
+
serverOffers !== void 0 ? { type: "CONTENT", offers: serverOffers } : LOADING_STATE
|
|
2858
|
+
);
|
|
2859
|
+
(0, import_react5.useEffect)(() => {
|
|
2860
|
+
let isCancelled = false;
|
|
2861
|
+
if (!isReady) {
|
|
2862
|
+
if (serverOffers === void 0) {
|
|
2863
|
+
setOffersState(LOADING_STATE);
|
|
2864
|
+
}
|
|
2865
|
+
return () => {
|
|
2866
|
+
isCancelled = true;
|
|
2867
|
+
};
|
|
2868
|
+
}
|
|
2869
|
+
if (serverOffers !== void 0) {
|
|
2870
|
+
return () => {
|
|
2871
|
+
isCancelled = true;
|
|
2872
|
+
};
|
|
2873
|
+
}
|
|
2874
|
+
setOffersState(LOADING_STATE);
|
|
2875
|
+
coinlist.fetchOffers().then((offers) => {
|
|
2876
|
+
if (!isCancelled) {
|
|
2877
|
+
setOffersState({ type: "CONTENT", offers });
|
|
2878
|
+
}
|
|
2879
|
+
}).catch((error) => {
|
|
2880
|
+
if (!isCancelled) {
|
|
2881
|
+
const reason = error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error";
|
|
2882
|
+
setOffersState({ type: "ERROR", reason });
|
|
2883
|
+
}
|
|
2884
|
+
});
|
|
2885
|
+
return () => {
|
|
2886
|
+
isCancelled = true;
|
|
2887
|
+
};
|
|
2888
|
+
}, [coinlist, isReady, serverOffers]);
|
|
2889
|
+
return { offersState };
|
|
2890
|
+
}
|
|
2891
|
+
|
|
2892
|
+
// src/client/components/offers/OffersGrid.tsx
|
|
2893
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2894
|
+
var DEFAULT_MAX_COLUMNS = 3;
|
|
2895
|
+
function OffersGridBody({
|
|
2896
|
+
data,
|
|
2897
|
+
maxColumns,
|
|
2898
|
+
className,
|
|
2899
|
+
containerClassName,
|
|
2900
|
+
loading,
|
|
2901
|
+
error,
|
|
2902
|
+
emptyState,
|
|
2903
|
+
onOfferClick
|
|
2904
|
+
} = {}) {
|
|
2905
|
+
const { offersState } = useOffers({ data });
|
|
2906
|
+
const cols = Math.max(1, maxColumns ?? DEFAULT_MAX_COLUMNS);
|
|
2907
|
+
if (offersState.type === "LOADING") {
|
|
2908
|
+
if (loading) {
|
|
2909
|
+
return loading;
|
|
2910
|
+
}
|
|
2911
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2912
|
+
"output",
|
|
2913
|
+
{
|
|
2914
|
+
"aria-live": "polite",
|
|
2915
|
+
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",
|
|
2916
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: cn(typeClasses.body, "clcosdk:text-text-secondary"), children: "Loading offers..." })
|
|
2917
|
+
}
|
|
2918
|
+
);
|
|
2919
|
+
}
|
|
2920
|
+
if (offersState.type === "ERROR") {
|
|
2921
|
+
if (error) {
|
|
2922
|
+
return error;
|
|
2923
|
+
}
|
|
2924
|
+
const errorMessage = offersState.reason === "not-authenticated" ? "Sign in to view available offers." : "Unable to load offers right now. Please try again.";
|
|
2925
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2926
|
+
AlertBanner,
|
|
2927
|
+
{
|
|
2928
|
+
variant: "error",
|
|
2929
|
+
icon: true,
|
|
2930
|
+
content: errorMessage,
|
|
2931
|
+
className: "clcosdk:w-full clcosdk:max-w-[28rem]"
|
|
2932
|
+
}
|
|
2933
|
+
);
|
|
2934
|
+
}
|
|
2935
|
+
if (offersState.offers.length === 0) {
|
|
2936
|
+
if (emptyState) {
|
|
2937
|
+
return emptyState;
|
|
2938
|
+
}
|
|
2939
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2940
|
+
"output",
|
|
2941
|
+
{
|
|
2942
|
+
"aria-live": "polite",
|
|
2943
|
+
className: "clcosdk:flex clcosdk:min-h-40 clcosdk:flex-col clcosdk:items-center clcosdk:justify-center clcosdk:rounded-2xl clcosdk:border clcosdk:border-border clcosdk:bg-background clcosdk:p-6 clcosdk:text-center",
|
|
2944
|
+
children: [
|
|
2945
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2946
|
+
"p",
|
|
2947
|
+
{
|
|
2948
|
+
className: cn(
|
|
2949
|
+
typeClasses.body,
|
|
2950
|
+
"clcosdk:font-medium clcosdk:text-text-primary"
|
|
2951
|
+
),
|
|
2952
|
+
children: "No offers available"
|
|
2953
|
+
}
|
|
2954
|
+
),
|
|
2955
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: cn(typeClasses.subhead, "clcosdk:text-text-secondary"), children: "Check back soon for upcoming opportunities." })
|
|
2956
|
+
]
|
|
2957
|
+
}
|
|
2958
|
+
);
|
|
2959
|
+
}
|
|
2960
|
+
const maxGridWidth = `calc(${cols} * 28rem + ${Math.max(cols - 1, 0)} * 1.5rem)`;
|
|
2961
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2962
|
+
"div",
|
|
2963
|
+
{
|
|
2964
|
+
className: cn(
|
|
2965
|
+
"clcosdk:flex clcosdk:w-full clcosdk:justify-center",
|
|
2966
|
+
containerClassName
|
|
2967
|
+
),
|
|
2968
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2969
|
+
"div",
|
|
2970
|
+
{
|
|
2971
|
+
className: cn("clcosdk:grid clcosdk:w-full clcosdk:gap-6", className),
|
|
2972
|
+
style: {
|
|
2973
|
+
gridTemplateColumns: "repeat(auto-fit, minmax(min(100%, 20rem), 1fr))",
|
|
2974
|
+
maxWidth: maxGridWidth
|
|
2975
|
+
},
|
|
2976
|
+
children: offersState.offers.map((offer) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2977
|
+
OfferCard,
|
|
2978
|
+
{
|
|
2979
|
+
offer: OfferCardUi.fromDomain(offer),
|
|
2980
|
+
onClick: onOfferClick ? () => onOfferClick(offer) : void 0
|
|
2981
|
+
},
|
|
2982
|
+
offer.id
|
|
2983
|
+
))
|
|
2984
|
+
}
|
|
2985
|
+
)
|
|
2986
|
+
}
|
|
2987
|
+
);
|
|
2988
|
+
}
|
|
2989
|
+
function OffersGrid(props = {}) {
|
|
2990
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CoinListStyleScope, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(OffersGridBody, { ...props }) });
|
|
2991
|
+
}
|
|
2992
|
+
|
|
2993
|
+
// src/client/components/requirements/ConnectedWalletList.tsx
|
|
2994
|
+
var import_react6 = require("react");
|
|
2995
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2996
|
+
function ConnectedWalletRow({
|
|
2997
|
+
wallet,
|
|
2998
|
+
onRemove
|
|
2999
|
+
}) {
|
|
3000
|
+
const [state, setState] = (0, import_react6.useState)("idle");
|
|
3001
|
+
const remove = async () => {
|
|
3002
|
+
if (!onRemove) return;
|
|
3003
|
+
setState("removing");
|
|
3004
|
+
try {
|
|
3005
|
+
await onRemove(wallet.id);
|
|
3006
|
+
setState("idle");
|
|
3007
|
+
} catch {
|
|
3008
|
+
setState("error");
|
|
3009
|
+
}
|
|
3010
|
+
};
|
|
3011
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "clcosdk:flex clcosdk:min-h-9 clcosdk:flex-wrap clcosdk:items-center clcosdk:justify-between clcosdk:gap-2", children: [
|
|
3012
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3013
|
+
"span",
|
|
3014
|
+
{
|
|
3015
|
+
title: wallet.address,
|
|
3016
|
+
className: cn(
|
|
3017
|
+
typeClasses.body,
|
|
3018
|
+
"clcosdk:font-mono clcosdk:text-text-primary"
|
|
3019
|
+
),
|
|
3020
|
+
children: wallet.shortAddress
|
|
3021
|
+
}
|
|
3022
|
+
),
|
|
3023
|
+
onRemove != null && (state === "confirming" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "clcosdk:flex clcosdk:items-center clcosdk:gap-2", children: [
|
|
3024
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3025
|
+
"span",
|
|
3026
|
+
{
|
|
3027
|
+
className: cn(typeClasses.subhead, "clcosdk:text-text-secondary"),
|
|
3028
|
+
children: "Remove?"
|
|
3029
|
+
}
|
|
3030
|
+
),
|
|
3031
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ClButton, { size: "sm", variant: "destructive", onClick: remove, children: "Remove" }),
|
|
3032
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3033
|
+
ClButton,
|
|
3034
|
+
{
|
|
3035
|
+
size: "sm",
|
|
3036
|
+
variant: "ghost",
|
|
3037
|
+
onClick: () => setState("idle"),
|
|
3038
|
+
children: "Cancel"
|
|
3039
|
+
}
|
|
3040
|
+
)
|
|
3041
|
+
] }) : state === "error" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "clcosdk:flex clcosdk:items-center clcosdk:gap-2", children: [
|
|
3042
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: cn(typeClasses.subhead, "clcosdk:text-error"), children: "Couldn't remove." }),
|
|
3043
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3044
|
+
ClButton,
|
|
3045
|
+
{
|
|
3046
|
+
size: "sm",
|
|
3047
|
+
variant: "destructiveLink",
|
|
3048
|
+
onClick: () => setState("confirming"),
|
|
3049
|
+
children: "Try again"
|
|
3050
|
+
}
|
|
3051
|
+
)
|
|
3052
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3053
|
+
ClButton,
|
|
3054
|
+
{
|
|
3055
|
+
size: "sm",
|
|
3056
|
+
variant: "destructiveLink",
|
|
3057
|
+
disabled: state === "removing",
|
|
3058
|
+
onClick: () => setState("confirming"),
|
|
3059
|
+
children: state === "removing" ? "Removing\u2026" : "Remove"
|
|
3060
|
+
}
|
|
3061
|
+
))
|
|
3062
|
+
] });
|
|
3063
|
+
}
|
|
3064
|
+
function ConnectedWalletList({
|
|
3065
|
+
wallets,
|
|
3066
|
+
onRemove,
|
|
3067
|
+
onAdd,
|
|
3068
|
+
addLabel = "Add wallet",
|
|
3069
|
+
status = "ready",
|
|
3070
|
+
className
|
|
3071
|
+
}) {
|
|
3072
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3073
|
+
"div",
|
|
3074
|
+
{
|
|
3075
|
+
className: cn("clcosdk:flex clcosdk:flex-col clcosdk:gap-2", className),
|
|
3076
|
+
children: [
|
|
3077
|
+
status === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(AlertBanner, { variant: "info", content: "Loading your connected wallets\u2026" }) : status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3078
|
+
AlertBanner,
|
|
3079
|
+
{
|
|
3080
|
+
variant: "error",
|
|
3081
|
+
content: "Couldn't load your connected wallets."
|
|
3082
|
+
}
|
|
3083
|
+
) : wallets.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(AlertBanner, { variant: "info", content: "No wallets connected yet." }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:divide-y clcosdk:divide-divider", children: wallets.map((wallet) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3084
|
+
ConnectedWalletRow,
|
|
3085
|
+
{
|
|
3086
|
+
wallet,
|
|
3087
|
+
onRemove
|
|
3088
|
+
},
|
|
3089
|
+
wallet.id
|
|
3090
|
+
)) }),
|
|
3091
|
+
onAdd != null && status !== "loading" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3092
|
+
ClButton,
|
|
3093
|
+
{
|
|
3094
|
+
size: "sm",
|
|
3095
|
+
variant: "secondary",
|
|
3096
|
+
onClick: onAdd,
|
|
3097
|
+
className: "clcosdk:self-start",
|
|
3098
|
+
children: addLabel
|
|
3099
|
+
}
|
|
3100
|
+
)
|
|
3101
|
+
]
|
|
3102
|
+
}
|
|
3103
|
+
);
|
|
3104
|
+
}
|
|
3105
|
+
|
|
3106
|
+
// src/client/components/requirements/ConnectWalletModal.tsx
|
|
3107
|
+
var import_react8 = require("react");
|
|
3108
|
+
|
|
3109
|
+
// src/client/hooks/useConnectWallet.ts
|
|
3110
|
+
var import_react7 = require("react");
|
|
3111
|
+
|
|
3112
|
+
// src/client/core/connect-external-wallet.ts
|
|
3113
|
+
var DEFAULT_STATEMENT = "Sign this message to prove you own this wallet. This does not cost gas or move funds.";
|
|
3114
|
+
var TERMINAL_CODES = /* @__PURE__ */ new Set([
|
|
3115
|
+
"not_authenticated",
|
|
3116
|
+
"wallet_not_whitelisted",
|
|
3117
|
+
"max_wallets_reached"
|
|
3118
|
+
]);
|
|
3119
|
+
var API_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
3120
|
+
"wallet_not_whitelisted",
|
|
3121
|
+
"max_wallets_reached"
|
|
3122
|
+
]);
|
|
3123
|
+
function flowError(code) {
|
|
3124
|
+
return { code, retryable: !TERMINAL_CODES.has(code) };
|
|
3125
|
+
}
|
|
3126
|
+
function siweContext() {
|
|
3127
|
+
if (typeof window === "undefined") return { domain: "", uri: "" };
|
|
3128
|
+
return { domain: window.location.host, uri: window.location.origin };
|
|
3129
|
+
}
|
|
3130
|
+
function apiErrorCode(error) {
|
|
3131
|
+
if (typeof error !== "object" || error === null) return void 0;
|
|
3132
|
+
const body = error.response?.body;
|
|
3133
|
+
return typeof body?.code === "string" ? body.code : void 0;
|
|
3134
|
+
}
|
|
3135
|
+
function classifyApiError(error) {
|
|
3136
|
+
if (error instanceof NotAuthenticatedError) {
|
|
3137
|
+
return flowError("not_authenticated");
|
|
3138
|
+
}
|
|
3139
|
+
const code = apiErrorCode(error);
|
|
3140
|
+
if (code !== void 0 && API_ERROR_CODES.has(code)) {
|
|
3141
|
+
return flowError(code);
|
|
3142
|
+
}
|
|
3143
|
+
return flowError("unknown");
|
|
3144
|
+
}
|
|
3145
|
+
function challengeParams(wallet, challengeType, statement) {
|
|
3146
|
+
switch (challengeType) {
|
|
3147
|
+
case "siwe":
|
|
3148
|
+
return {
|
|
3149
|
+
walletAddress: wallet.address,
|
|
3150
|
+
chain: wallet.chain,
|
|
3151
|
+
challengeType: "siwe",
|
|
3152
|
+
...siweContext(),
|
|
3153
|
+
statement: statement ?? DEFAULT_STATEMENT
|
|
3154
|
+
};
|
|
3155
|
+
case "plain":
|
|
3156
|
+
return {
|
|
3157
|
+
walletAddress: wallet.address,
|
|
3158
|
+
chain: wallet.chain,
|
|
3159
|
+
challengeType: "plain"
|
|
3160
|
+
};
|
|
3161
|
+
default: {
|
|
3162
|
+
const _exhaustive = challengeType;
|
|
3163
|
+
return _exhaustive;
|
|
3164
|
+
}
|
|
3165
|
+
}
|
|
3166
|
+
}
|
|
3167
|
+
async function connectExternalWalletFlow(params) {
|
|
3168
|
+
const {
|
|
3169
|
+
coinlist,
|
|
3170
|
+
wallet,
|
|
3171
|
+
offerId,
|
|
3172
|
+
offerOptionId,
|
|
3173
|
+
challengeType,
|
|
3174
|
+
statement,
|
|
3175
|
+
isCancelled,
|
|
3176
|
+
onProgress
|
|
3177
|
+
} = params;
|
|
3178
|
+
const emit = (phase) => onProgress?.(phase);
|
|
3179
|
+
const cancelled = () => isCancelled?.() ?? false;
|
|
3180
|
+
emit("requesting-challenge");
|
|
3181
|
+
let challenge;
|
|
3182
|
+
try {
|
|
3183
|
+
challenge = await coinlist.createWalletOwnershipChallenge(
|
|
3184
|
+
challengeParams(wallet, challengeType ?? "siwe", statement)
|
|
3185
|
+
);
|
|
3186
|
+
} catch (error) {
|
|
3187
|
+
return { type: "error", error: classifyApiError(error) };
|
|
3188
|
+
}
|
|
3189
|
+
if (cancelled()) return { type: "cancelled" };
|
|
3190
|
+
emit("signing-message");
|
|
3191
|
+
let signature;
|
|
3192
|
+
try {
|
|
3193
|
+
signature = await wallet.signMessage(challenge.message);
|
|
3194
|
+
} catch (error) {
|
|
3195
|
+
if (classifyWalletError(error).type === "user_rejected") {
|
|
3196
|
+
return { type: "error", error: flowError("user_rejected") };
|
|
3197
|
+
}
|
|
3198
|
+
return { type: "error", error: flowError("unknown") };
|
|
3199
|
+
}
|
|
3200
|
+
if (cancelled()) return { type: "cancelled" };
|
|
3201
|
+
emit("submitting-signature");
|
|
3202
|
+
try {
|
|
3203
|
+
const binding = await coinlist.connectExternalWallet(offerId, {
|
|
3204
|
+
offerOptionId,
|
|
3205
|
+
walletAddress: wallet.address,
|
|
3206
|
+
chain: wallet.chain,
|
|
3207
|
+
signature
|
|
3208
|
+
});
|
|
3209
|
+
return { type: "success", binding };
|
|
3210
|
+
} catch (error) {
|
|
3211
|
+
return { type: "error", error: classifyApiError(error) };
|
|
3212
|
+
}
|
|
3213
|
+
}
|
|
3214
|
+
|
|
3215
|
+
// src/client/hooks/useConnectWallet.ts
|
|
3216
|
+
var IDLE_SIGN = { type: "idle", error: null };
|
|
3217
|
+
var ERROR_COPY = {
|
|
3218
|
+
not_authenticated: "Sign in to connect your wallet.",
|
|
3219
|
+
user_rejected: "Signature request declined. Approve it in your wallet to continue.",
|
|
3220
|
+
wallet_not_whitelisted: "This wallet is not approved for this offer.",
|
|
3221
|
+
max_wallets_reached: "You've reached the maximum number of wallets for this option.",
|
|
3222
|
+
unknown: "Unable to connect your wallet. Please try again."
|
|
3223
|
+
};
|
|
3224
|
+
function displayError(error) {
|
|
3225
|
+
return {
|
|
3226
|
+
code: error.code,
|
|
3227
|
+
message: ERROR_COPY[error.code],
|
|
3228
|
+
retryable: error.retryable
|
|
3229
|
+
};
|
|
3230
|
+
}
|
|
3231
|
+
function useConnectWallet({
|
|
3232
|
+
isOpen,
|
|
3233
|
+
offerId,
|
|
3234
|
+
offerOptionId,
|
|
3235
|
+
wallet,
|
|
3236
|
+
challengeType,
|
|
3237
|
+
statement
|
|
3238
|
+
}) {
|
|
3239
|
+
const { coinlist } = useCoinList();
|
|
3240
|
+
const [state, setState] = (0, import_react7.useState)(
|
|
3241
|
+
() => wallet ? { type: "READY", address: wallet.address, sign: IDLE_SIGN } : { type: "NEEDS_WALLET" }
|
|
3242
|
+
);
|
|
3243
|
+
const attempt = (0, import_react7.useRef)(0);
|
|
3244
|
+
(0, import_react7.useEffect)(() => {
|
|
3245
|
+
attempt.current += 1;
|
|
3246
|
+
if (!isOpen) return;
|
|
3247
|
+
setState(
|
|
3248
|
+
wallet ? { type: "READY", address: wallet.address, sign: IDLE_SIGN } : { type: "NEEDS_WALLET" }
|
|
3249
|
+
);
|
|
3250
|
+
}, [isOpen, wallet?.address]);
|
|
3251
|
+
(0, import_react7.useEffect)(
|
|
3252
|
+
() => () => {
|
|
3253
|
+
attempt.current += 1;
|
|
3254
|
+
},
|
|
3255
|
+
[]
|
|
3256
|
+
);
|
|
3257
|
+
const onSign = (0, import_react7.useCallback)(() => {
|
|
3258
|
+
if (!wallet || state.type !== "READY") return;
|
|
3259
|
+
attempt.current += 1;
|
|
3260
|
+
const gen = attempt.current;
|
|
3261
|
+
setState({
|
|
3262
|
+
type: "READY",
|
|
3263
|
+
address: wallet.address,
|
|
3264
|
+
sign: { type: "signing" }
|
|
3265
|
+
});
|
|
3266
|
+
connectExternalWalletFlow({
|
|
3267
|
+
coinlist,
|
|
3268
|
+
wallet,
|
|
3269
|
+
offerId,
|
|
3270
|
+
offerOptionId,
|
|
3271
|
+
challengeType,
|
|
3272
|
+
statement,
|
|
3273
|
+
// Cancels the flow before signing / binding if this attempt is superseded.
|
|
3274
|
+
isCancelled: () => attempt.current !== gen
|
|
3275
|
+
}).then((result) => {
|
|
3276
|
+
if (attempt.current !== gen) return;
|
|
3277
|
+
if (result.type === "success") {
|
|
3278
|
+
setState({ type: "CONNECTED", binding: result.binding });
|
|
3279
|
+
} else if (result.type === "error") {
|
|
3280
|
+
setState({
|
|
3281
|
+
type: "READY",
|
|
3282
|
+
address: wallet.address,
|
|
3283
|
+
sign: { type: "idle", error: displayError(result.error) }
|
|
3284
|
+
});
|
|
3285
|
+
}
|
|
3286
|
+
});
|
|
3287
|
+
}, [
|
|
3288
|
+
wallet,
|
|
3289
|
+
state,
|
|
3290
|
+
coinlist,
|
|
3291
|
+
offerId,
|
|
3292
|
+
offerOptionId,
|
|
3293
|
+
challengeType,
|
|
3294
|
+
statement
|
|
3295
|
+
]);
|
|
3296
|
+
return { state, onSign };
|
|
3297
|
+
}
|
|
3298
|
+
|
|
3299
|
+
// src/shared/core/blockchain/formatters.ts
|
|
3300
|
+
var import_viem3 = require("viem");
|
|
3301
|
+
|
|
3302
|
+
// src/shared/types/blockchain/ui.ts
|
|
3303
|
+
var ShortenedWalletAddress = (value) => value;
|
|
3304
|
+
var FormattedAmountAssetUi = (value) => value;
|
|
3305
|
+
|
|
3306
|
+
// src/shared/core/blockchain/formatters.ts
|
|
3307
|
+
function shortenAddress(address) {
|
|
3308
|
+
const short = address.length > 10 ? `${address.slice(0, 6)}\u2026${address.slice(-4)}` : address;
|
|
3309
|
+
return ShortenedWalletAddress(short);
|
|
3310
|
+
}
|
|
3311
|
+
var NA_AMOUNT_ASSET_UI = FormattedAmountAssetUi("-");
|
|
3312
|
+
var USD_FRACTION_DIGITS = AssetDecimals(2);
|
|
3313
|
+
|
|
3314
|
+
// src/client/components/requirements/ConnectWalletModal.tsx
|
|
3315
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
3316
|
+
function ConnectWalletModal({
|
|
3317
|
+
isOpen,
|
|
3318
|
+
onClose,
|
|
3319
|
+
offerId,
|
|
3320
|
+
optionId,
|
|
3321
|
+
wallet,
|
|
3322
|
+
onConnected,
|
|
3323
|
+
onRequestConnect,
|
|
3324
|
+
challengeType,
|
|
3325
|
+
statement,
|
|
3326
|
+
className
|
|
3327
|
+
}) {
|
|
3328
|
+
const { state, onSign } = useConnectWallet({
|
|
3329
|
+
isOpen,
|
|
3330
|
+
offerId,
|
|
3331
|
+
offerOptionId: optionId,
|
|
3332
|
+
wallet,
|
|
3333
|
+
challengeType,
|
|
3334
|
+
statement
|
|
3335
|
+
});
|
|
3336
|
+
const titleId = (0, import_react8.useId)();
|
|
3337
|
+
(0, import_react8.useEffect)(() => {
|
|
3338
|
+
if (state.type === "CONNECTED") {
|
|
3339
|
+
onConnected?.(state.binding);
|
|
3340
|
+
onClose();
|
|
3341
|
+
}
|
|
3342
|
+
}, [state]);
|
|
3343
|
+
if (!isOpen || state.type === "CONNECTED") return null;
|
|
3344
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("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__ */ (0, import_jsx_runtime14.jsxs)(
|
|
3345
|
+
"div",
|
|
3346
|
+
{
|
|
3347
|
+
role: "dialog",
|
|
3348
|
+
"aria-modal": "true",
|
|
3349
|
+
"aria-labelledby": titleId,
|
|
3350
|
+
className: cn(
|
|
3351
|
+
"clcosdk:flex clcosdk:w-full clcosdk:max-w-md clcosdk:flex-col clcosdk:gap-6 clcosdk:rounded-2xl clcosdk:bg-background clcosdk:p-6",
|
|
3352
|
+
className
|
|
3353
|
+
),
|
|
3354
|
+
children: [
|
|
3355
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "clcosdk:flex clcosdk:items-start clcosdk:justify-between clcosdk:gap-4", children: [
|
|
3356
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3357
|
+
"h3",
|
|
3358
|
+
{
|
|
3359
|
+
id: titleId,
|
|
3360
|
+
className: cn(typeClasses.h3, "clcosdk:text-text-primary"),
|
|
3361
|
+
children: "Connect your wallet"
|
|
3362
|
+
}
|
|
3363
|
+
),
|
|
3364
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CloseButton, { onClick: onClose })
|
|
3365
|
+
] }),
|
|
3366
|
+
state.type === "NEEDS_WALLET" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(NeedsWalletScreen, { onRequestConnect }),
|
|
3367
|
+
state.type === "READY" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3368
|
+
ReadyScreen,
|
|
3369
|
+
{
|
|
3370
|
+
address: state.address,
|
|
3371
|
+
sign: state.sign,
|
|
3372
|
+
onSign,
|
|
3373
|
+
onRequestConnect
|
|
3374
|
+
}
|
|
3375
|
+
)
|
|
3376
|
+
]
|
|
3377
|
+
}
|
|
3378
|
+
) });
|
|
3379
|
+
}
|
|
3380
|
+
function NeedsWalletScreen({
|
|
3381
|
+
onRequestConnect
|
|
3382
|
+
}) {
|
|
3383
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-6", children: [
|
|
3384
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: cn(typeClasses.body, "clcosdk:text-text-secondary"), children: "Connect an external wallet to prove ownership and bind it to this offer." }),
|
|
3385
|
+
onRequestConnect && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ClButton, { fullWidth: true, onClick: onRequestConnect, children: "Connect wallet" })
|
|
3386
|
+
] });
|
|
3387
|
+
}
|
|
3388
|
+
function ReadyScreen({
|
|
3389
|
+
address,
|
|
3390
|
+
sign,
|
|
3391
|
+
onSign,
|
|
3392
|
+
onRequestConnect
|
|
3393
|
+
}) {
|
|
3394
|
+
const hasTerminalError = sign.type === "idle" && sign.error !== null && !sign.error.retryable;
|
|
3395
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-6", children: [
|
|
3396
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("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." }),
|
|
3397
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-1 clcosdk:border-t clcosdk:border-divider clcosdk:pt-4", children: [
|
|
3398
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: cn(typeClasses.label, "clcosdk:text-text-secondary"), children: "Wallet address" }),
|
|
3399
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: cn(typeClasses.body, "clcosdk:text-text-primary"), children: shortenAddress(address) })
|
|
3400
|
+
] }),
|
|
3401
|
+
sign.type === "idle" && sign.error && // Live region: the error is inserted async after a failed attempt, so
|
|
3402
|
+
// screen readers need it announced rather than silently rendered.
|
|
3403
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { role: "alert", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AlertBanner, { variant: "error", icon: true, content: sign.error.message }) }),
|
|
3404
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3405
|
+
ClButton,
|
|
3406
|
+
{
|
|
3407
|
+
fullWidth: true,
|
|
3408
|
+
onClick: onSign,
|
|
3409
|
+
isLoading: sign.type === "signing",
|
|
3410
|
+
loadingText: "Waiting for signature...",
|
|
3411
|
+
disabled: hasTerminalError,
|
|
3412
|
+
children: "Sign & connect"
|
|
3413
|
+
}
|
|
3414
|
+
),
|
|
3415
|
+
onRequestConnect && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3416
|
+
ClButton,
|
|
3417
|
+
{
|
|
3418
|
+
fullWidth: true,
|
|
3419
|
+
variant: "secondary",
|
|
3420
|
+
onClick: onRequestConnect,
|
|
3421
|
+
disabled: sign.type === "signing",
|
|
3422
|
+
children: "Use a different wallet"
|
|
3423
|
+
}
|
|
3424
|
+
)
|
|
3425
|
+
] });
|
|
1576
3426
|
}
|
|
1577
3427
|
|
|
1578
|
-
// src/client/
|
|
1579
|
-
var
|
|
1580
|
-
var
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
isCancelled = true;
|
|
1595
|
-
};
|
|
3428
|
+
// src/client/components/requirements/IdentityVerification.tsx
|
|
3429
|
+
var import_websdk_react = __toESM(require("@sumsub/websdk-react"), 1);
|
|
3430
|
+
var import_react10 = require("react");
|
|
3431
|
+
|
|
3432
|
+
// src/client/hooks/useKycToken.ts
|
|
3433
|
+
var import_react9 = require("react");
|
|
3434
|
+
var IDLE_STATE = { type: "IDLE" };
|
|
3435
|
+
var LOADING_STATE2 = { type: "LOADING" };
|
|
3436
|
+
function useKycToken(levelName, reset) {
|
|
3437
|
+
const { coinlist } = useCoinList();
|
|
3438
|
+
const [kycTokenState, setKycTokenState] = (0, import_react9.useState)(IDLE_STATE);
|
|
3439
|
+
const resetPendingRef = (0, import_react9.useRef)(reset === true);
|
|
3440
|
+
const tokenIssuedRef = (0, import_react9.useRef)(false);
|
|
3441
|
+
(0, import_react9.useEffect)(() => {
|
|
3442
|
+
if (!tokenIssuedRef.current) {
|
|
3443
|
+
resetPendingRef.current = reset === true;
|
|
1596
3444
|
}
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
3445
|
+
}, [reset]);
|
|
3446
|
+
const fetchToken = (0, import_react9.useCallback)(async () => {
|
|
3447
|
+
setKycTokenState(LOADING_STATE2);
|
|
3448
|
+
try {
|
|
3449
|
+
const kycToken = await coinlist.createKycToken(
|
|
3450
|
+
levelName,
|
|
3451
|
+
resetPendingRef.current
|
|
3452
|
+
);
|
|
3453
|
+
resetPendingRef.current = false;
|
|
3454
|
+
tokenIssuedRef.current = true;
|
|
3455
|
+
setKycTokenState({ type: "CONTENT", token: kycToken.token });
|
|
3456
|
+
return kycToken.token;
|
|
3457
|
+
} catch (error) {
|
|
3458
|
+
const reason = error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error";
|
|
3459
|
+
setKycTokenState({ type: "ERROR", reason });
|
|
3460
|
+
throw error;
|
|
1601
3461
|
}
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
if (!isCancelled) {
|
|
1605
|
-
setOffersState({ type: "CONTENT", offers });
|
|
1606
|
-
}
|
|
1607
|
-
}).catch((error) => {
|
|
1608
|
-
if (!isCancelled) {
|
|
1609
|
-
const reason = error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error";
|
|
1610
|
-
setOffersState({ type: "ERROR", reason });
|
|
1611
|
-
}
|
|
1612
|
-
});
|
|
1613
|
-
return () => {
|
|
1614
|
-
isCancelled = true;
|
|
1615
|
-
};
|
|
1616
|
-
}, [coinlist, isReady, serverOffers]);
|
|
1617
|
-
return { offersState };
|
|
3462
|
+
}, [coinlist, levelName]);
|
|
3463
|
+
return { kycTokenState, fetchToken };
|
|
1618
3464
|
}
|
|
1619
3465
|
|
|
1620
|
-
// src/client/components/
|
|
1621
|
-
var
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
3466
|
+
// src/client/components/requirements/IdentityVerification.tsx
|
|
3467
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
3468
|
+
function IdentityVerification({
|
|
3469
|
+
levelName,
|
|
3470
|
+
reset,
|
|
3471
|
+
locale,
|
|
3472
|
+
onSubmitted,
|
|
3473
|
+
onError,
|
|
3474
|
+
className
|
|
3475
|
+
}) {
|
|
3476
|
+
const { kycTokenState, fetchToken } = useKycToken(levelName, reset);
|
|
3477
|
+
const fetchedRef = (0, import_react10.useRef)(false);
|
|
3478
|
+
(0, import_react10.useEffect)(() => {
|
|
3479
|
+
if (fetchedRef.current) return;
|
|
3480
|
+
fetchedRef.current = true;
|
|
3481
|
+
fetchToken().catch(() => {
|
|
3482
|
+
});
|
|
3483
|
+
}, [fetchToken]);
|
|
3484
|
+
const handleMessage = (type, payload) => {
|
|
3485
|
+
switch (type) {
|
|
3486
|
+
case "idCheck.onApplicantSubmitted":
|
|
3487
|
+
onSubmitted?.();
|
|
3488
|
+
break;
|
|
3489
|
+
case "idCheck.onError": {
|
|
3490
|
+
const message = payload?.message ?? "Verification error";
|
|
3491
|
+
onError?.(new Error(message));
|
|
3492
|
+
break;
|
|
3493
|
+
}
|
|
3494
|
+
default:
|
|
3495
|
+
break;
|
|
1638
3496
|
}
|
|
1639
|
-
|
|
3497
|
+
};
|
|
3498
|
+
const handleError = (error) => {
|
|
3499
|
+
onError?.(error instanceof Error ? error : new Error("Verification error"));
|
|
3500
|
+
};
|
|
3501
|
+
if (kycTokenState.type === "IDLE" || kycTokenState.type === "LOADING") {
|
|
3502
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1640
3503
|
"output",
|
|
1641
3504
|
{
|
|
1642
3505
|
"aria-live": "polite",
|
|
1643
|
-
className:
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
if (offersState.type === "ERROR") {
|
|
1649
|
-
if (error) {
|
|
1650
|
-
return error;
|
|
1651
|
-
}
|
|
1652
|
-
const errorMessage = offersState.reason === "not-authenticated" ? "Sign in to view available offers." : "Unable to load offers right now. Please try again.";
|
|
1653
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1654
|
-
AlertBanner,
|
|
1655
|
-
{
|
|
1656
|
-
variant: "error",
|
|
1657
|
-
icon: true,
|
|
1658
|
-
content: errorMessage,
|
|
1659
|
-
className: "clcosdk:w-full clcosdk:max-w-[28rem]"
|
|
3506
|
+
className: cn(
|
|
3507
|
+
"clcosdk:flex clcosdk:min-h-40 clcosdk:items-center clcosdk:justify-center",
|
|
3508
|
+
className
|
|
3509
|
+
),
|
|
3510
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: cn(typeClasses.body, "clcosdk:text-text-secondary"), children: "Loading identity verification..." })
|
|
1660
3511
|
}
|
|
1661
3512
|
);
|
|
1662
3513
|
}
|
|
1663
|
-
if (
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
1668
|
-
"output",
|
|
3514
|
+
if (kycTokenState.type === "ERROR") {
|
|
3515
|
+
const errorMessage = kycTokenState.reason === "not-authenticated" ? "Sign in to verify your identity." : "Unable to start identity verification right now. Please try again.";
|
|
3516
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
3517
|
+
"div",
|
|
1669
3518
|
{
|
|
1670
|
-
"
|
|
1671
|
-
className: "clcosdk:flex clcosdk:min-h-40 clcosdk:flex-col clcosdk:items-center clcosdk:justify-center clcosdk:rounded-2xl clcosdk:border clcosdk:border-border clcosdk:bg-background clcosdk:p-6 clcosdk:text-center",
|
|
3519
|
+
className: cn("clcosdk:flex clcosdk:flex-col clcosdk:gap-4", className),
|
|
1672
3520
|
children: [
|
|
1673
|
-
/* @__PURE__ */ (0,
|
|
1674
|
-
|
|
3521
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AlertBanner, { variant: "error", icon: true, content: errorMessage }),
|
|
3522
|
+
kycTokenState.reason !== "not-authenticated" && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3523
|
+
ClButton,
|
|
1675
3524
|
{
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
3525
|
+
size: "sm",
|
|
3526
|
+
onClick: () => {
|
|
3527
|
+
fetchToken().catch(() => {
|
|
3528
|
+
});
|
|
3529
|
+
},
|
|
3530
|
+
children: "Try again"
|
|
1681
3531
|
}
|
|
1682
|
-
)
|
|
1683
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: cn(typeClasses.subhead, "clcosdk:text-text-secondary"), children: "Check back soon for upcoming opportunities." })
|
|
3532
|
+
)
|
|
1684
3533
|
]
|
|
1685
3534
|
}
|
|
1686
3535
|
);
|
|
1687
3536
|
}
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
"div",
|
|
3537
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cn("clcosdk:w-full", className), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3538
|
+
import_websdk_react.default,
|
|
1691
3539
|
{
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
{
|
|
1699
|
-
className: cn("clcosdk:grid clcosdk:w-full clcosdk:gap-6", className),
|
|
1700
|
-
style: {
|
|
1701
|
-
gridTemplateColumns: "repeat(auto-fit, minmax(min(100%, 20rem), 1fr))",
|
|
1702
|
-
maxWidth: maxGridWidth
|
|
1703
|
-
},
|
|
1704
|
-
children: offersState.offers.map((offer) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1705
|
-
OfferCard,
|
|
1706
|
-
{
|
|
1707
|
-
offer: OfferCardUi.fromDomain(offer),
|
|
1708
|
-
onClick: onOfferClick ? () => onOfferClick(offer) : void 0
|
|
1709
|
-
},
|
|
1710
|
-
offer.id
|
|
1711
|
-
))
|
|
1712
|
-
}
|
|
1713
|
-
)
|
|
3540
|
+
accessToken: kycTokenState.token,
|
|
3541
|
+
expirationHandler: fetchToken,
|
|
3542
|
+
config: locale === void 0 ? {} : { lang: locale },
|
|
3543
|
+
options: { addViewportTag: false, adaptIframeHeight: true },
|
|
3544
|
+
onMessage: handleMessage,
|
|
3545
|
+
onError: handleError
|
|
1714
3546
|
}
|
|
1715
|
-
);
|
|
3547
|
+
) });
|
|
1716
3548
|
}
|
|
1717
3549
|
|
|
1718
3550
|
// src/client/components/requirements/RequirementItem.tsx
|
|
@@ -1720,7 +3552,7 @@ var import_lucide_react4 = require("lucide-react");
|
|
|
1720
3552
|
|
|
1721
3553
|
// src/client/components/design-system/StepStatusIcon.tsx
|
|
1722
3554
|
var import_lucide_react3 = require("lucide-react");
|
|
1723
|
-
var
|
|
3555
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1724
3556
|
var statusConfig = {
|
|
1725
3557
|
required: {
|
|
1726
3558
|
Icon: import_lucide_react3.Info,
|
|
@@ -1745,7 +3577,7 @@ var statusConfig = {
|
|
|
1745
3577
|
};
|
|
1746
3578
|
function StepStatusIcon({ status, className }) {
|
|
1747
3579
|
const { Icon, colorClass, fillClass } = statusConfig[status];
|
|
1748
|
-
return /* @__PURE__ */ (0,
|
|
3580
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1749
3581
|
Icon,
|
|
1750
3582
|
{
|
|
1751
3583
|
className: cn(
|
|
@@ -1760,7 +3592,7 @@ function StepStatusIcon({ status, className }) {
|
|
|
1760
3592
|
}
|
|
1761
3593
|
|
|
1762
3594
|
// src/client/components/requirements/RequirementItem.tsx
|
|
1763
|
-
var
|
|
3595
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1764
3596
|
var RequirementVariant = {
|
|
1765
3597
|
fromType(type) {
|
|
1766
3598
|
switch (type) {
|
|
@@ -1795,13 +3627,18 @@ var ChecklistStatus = {
|
|
|
1795
3627
|
}
|
|
1796
3628
|
};
|
|
1797
3629
|
var RequirementItemUi = {
|
|
1798
|
-
fromDomain(req, statusInfo, label, description,
|
|
3630
|
+
fromDomain(req, statusInfo, label, description, addresses = []) {
|
|
1799
3631
|
return {
|
|
1800
3632
|
variant: RequirementVariant.fromType(req.type),
|
|
1801
3633
|
status: statusInfo ? RequirementStatus.fromStatusValue(statusInfo.status) : "required",
|
|
1802
3634
|
label,
|
|
1803
3635
|
description,
|
|
1804
|
-
|
|
3636
|
+
multiWallet: req.type === "whitelisted_wallet",
|
|
3637
|
+
connectedWallets: addresses.map((address) => ({
|
|
3638
|
+
id: address.id,
|
|
3639
|
+
address: address.address,
|
|
3640
|
+
shortAddress: shortenAddress(address.address)
|
|
3641
|
+
}))
|
|
1805
3642
|
};
|
|
1806
3643
|
}
|
|
1807
3644
|
};
|
|
@@ -1813,9 +3650,9 @@ function VerificationActionZone({
|
|
|
1813
3650
|
switch (status) {
|
|
1814
3651
|
case "required":
|
|
1815
3652
|
if (onAction === null) return null;
|
|
1816
|
-
return /* @__PURE__ */ (0,
|
|
3653
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ClButton, { size: "sm", onClick: onAction, children: "Continue" });
|
|
1817
3654
|
case "pending":
|
|
1818
|
-
return /* @__PURE__ */ (0,
|
|
3655
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1819
3656
|
AlertBanner,
|
|
1820
3657
|
{
|
|
1821
3658
|
variant: "warning",
|
|
@@ -1823,16 +3660,16 @@ function VerificationActionZone({
|
|
|
1823
3660
|
}
|
|
1824
3661
|
);
|
|
1825
3662
|
case "completed":
|
|
1826
|
-
return /* @__PURE__ */ (0,
|
|
3663
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(AlertBanner, { variant: "success", content: "Identity verified." });
|
|
1827
3664
|
case "rejected":
|
|
1828
|
-
return /* @__PURE__ */ (0,
|
|
3665
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1829
3666
|
AlertBanner,
|
|
1830
3667
|
{
|
|
1831
3668
|
variant: "error",
|
|
1832
|
-
content: onContactSupport === null ? "Verification rejected." : /* @__PURE__ */ (0,
|
|
3669
|
+
content: onContactSupport === null ? "Verification rejected." : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
1833
3670
|
"Verification rejected.",
|
|
1834
3671
|
" ",
|
|
1835
|
-
/* @__PURE__ */ (0,
|
|
3672
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1836
3673
|
"button",
|
|
1837
3674
|
{
|
|
1838
3675
|
type: "button",
|
|
@@ -1849,25 +3686,61 @@ function VerificationActionZone({
|
|
|
1849
3686
|
}
|
|
1850
3687
|
function WalletActionZone({
|
|
1851
3688
|
status,
|
|
1852
|
-
|
|
1853
|
-
|
|
3689
|
+
multiWallet,
|
|
3690
|
+
connectedWallets,
|
|
3691
|
+
walletsStatus,
|
|
3692
|
+
onAction,
|
|
3693
|
+
onRemoveWallet
|
|
1854
3694
|
}) {
|
|
3695
|
+
if (multiWallet) {
|
|
3696
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
3697
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3698
|
+
ConnectedWalletList,
|
|
3699
|
+
{
|
|
3700
|
+
wallets: connectedWallets,
|
|
3701
|
+
onRemove: onRemoveWallet,
|
|
3702
|
+
onAdd: onAction ?? void 0,
|
|
3703
|
+
status: walletsStatus
|
|
3704
|
+
}
|
|
3705
|
+
),
|
|
3706
|
+
status === "rejected" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3707
|
+
AlertBanner,
|
|
3708
|
+
{
|
|
3709
|
+
variant: "error",
|
|
3710
|
+
content: "One of these wallets is not eligible for this sale."
|
|
3711
|
+
}
|
|
3712
|
+
)
|
|
3713
|
+
] });
|
|
3714
|
+
}
|
|
1855
3715
|
if (status === "completed") {
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
/* @__PURE__ */ (0,
|
|
3716
|
+
const connected = connectedWallets[0];
|
|
3717
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
3718
|
+
onAction !== null && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ClButton, { size: "sm", variant: "secondary", onClick: onAction, children: "Change wallet" }),
|
|
3719
|
+
walletsStatus === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3720
|
+
AlertBanner,
|
|
3721
|
+
{
|
|
3722
|
+
variant: "info",
|
|
3723
|
+
content: "Loading your connected wallet\u2026"
|
|
3724
|
+
}
|
|
3725
|
+
) : walletsStatus === "error" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3726
|
+
AlertBanner,
|
|
3727
|
+
{
|
|
3728
|
+
variant: "error",
|
|
3729
|
+
content: "Couldn't load your connected wallet."
|
|
3730
|
+
}
|
|
3731
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1859
3732
|
AlertBanner,
|
|
1860
3733
|
{
|
|
1861
3734
|
variant: "success",
|
|
1862
|
-
content:
|
|
3735
|
+
content: connected ? connected.shortAddress : "Wallet connected."
|
|
1863
3736
|
}
|
|
1864
3737
|
)
|
|
1865
3738
|
] });
|
|
1866
3739
|
}
|
|
1867
3740
|
if (status === "rejected") {
|
|
1868
|
-
return /* @__PURE__ */ (0,
|
|
1869
|
-
onAction !== null && /* @__PURE__ */ (0,
|
|
1870
|
-
/* @__PURE__ */ (0,
|
|
3741
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
3742
|
+
onAction !== null && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ClButton, { size: "sm", onClick: onAction, children: "Connect wallet" }),
|
|
3743
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1871
3744
|
AlertBanner,
|
|
1872
3745
|
{
|
|
1873
3746
|
variant: "error",
|
|
@@ -1877,7 +3750,7 @@ function WalletActionZone({
|
|
|
1877
3750
|
] });
|
|
1878
3751
|
}
|
|
1879
3752
|
if (onAction === null) return null;
|
|
1880
|
-
return /* @__PURE__ */ (0,
|
|
3753
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ClButton, { size: "sm", onClick: onAction, children: "Connect wallet" });
|
|
1881
3754
|
}
|
|
1882
3755
|
function RequirementItem({
|
|
1883
3756
|
ui,
|
|
@@ -1885,14 +3758,19 @@ function RequirementItem({
|
|
|
1885
3758
|
onToggle,
|
|
1886
3759
|
className,
|
|
1887
3760
|
onAction,
|
|
3761
|
+
onRemoveWallet,
|
|
3762
|
+
walletsStatus,
|
|
1888
3763
|
onContactSupport
|
|
1889
3764
|
}) {
|
|
1890
|
-
return /* @__PURE__ */ (0,
|
|
3765
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(CoinListStyleScope, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
1891
3766
|
"div",
|
|
1892
3767
|
{
|
|
1893
|
-
className: cn(
|
|
3768
|
+
className: cn(
|
|
3769
|
+
"clcosdk:flex clcosdk:w-full clcosdk:flex-col",
|
|
3770
|
+
className
|
|
3771
|
+
),
|
|
1894
3772
|
children: [
|
|
1895
|
-
/* @__PURE__ */ (0,
|
|
3773
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
1896
3774
|
"button",
|
|
1897
3775
|
{
|
|
1898
3776
|
type: "button",
|
|
@@ -1900,9 +3778,9 @@ function RequirementItem({
|
|
|
1900
3778
|
"aria-expanded": expanded,
|
|
1901
3779
|
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",
|
|
1902
3780
|
children: [
|
|
1903
|
-
/* @__PURE__ */ (0,
|
|
1904
|
-
/* @__PURE__ */ (0,
|
|
1905
|
-
/* @__PURE__ */ (0,
|
|
3781
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "clcosdk:flex clcosdk:items-center clcosdk:gap-3", children: [
|
|
3782
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(StepStatusIcon, { status: ui.status }),
|
|
3783
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1906
3784
|
"span",
|
|
1907
3785
|
{
|
|
1908
3786
|
className: cn(
|
|
@@ -1913,7 +3791,7 @@ function RequirementItem({
|
|
|
1913
3791
|
}
|
|
1914
3792
|
)
|
|
1915
3793
|
] }),
|
|
1916
|
-
/* @__PURE__ */ (0,
|
|
3794
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1917
3795
|
import_lucide_react4.ChevronRight,
|
|
1918
3796
|
{
|
|
1919
3797
|
className: cn(
|
|
@@ -1926,63 +3804,542 @@ function RequirementItem({
|
|
|
1926
3804
|
]
|
|
1927
3805
|
}
|
|
1928
3806
|
),
|
|
1929
|
-
/* @__PURE__ */ (0,
|
|
1930
|
-
"div",
|
|
3807
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3808
|
+
"div",
|
|
3809
|
+
{
|
|
3810
|
+
className: cn(
|
|
3811
|
+
"clcosdk:grid clcosdk:transition-[grid-template-rows] clcosdk:duration-300 clcosdk:ease-in-out",
|
|
3812
|
+
expanded ? "clcosdk:grid-rows-[1fr]" : "clcosdk:grid-rows-[0fr]"
|
|
3813
|
+
),
|
|
3814
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "clcosdk:min-h-0 clcosdk:overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-4 clcosdk:px-2 clcosdk:pb-4", children: [
|
|
3815
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3816
|
+
"p",
|
|
3817
|
+
{
|
|
3818
|
+
className: cn(
|
|
3819
|
+
typeClasses.subhead,
|
|
3820
|
+
"clcosdk:text-text-secondary"
|
|
3821
|
+
),
|
|
3822
|
+
children: ui.description
|
|
3823
|
+
}
|
|
3824
|
+
),
|
|
3825
|
+
ui.variant === "verification" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3826
|
+
VerificationActionZone,
|
|
3827
|
+
{
|
|
3828
|
+
status: ui.status,
|
|
3829
|
+
onAction,
|
|
3830
|
+
onContactSupport
|
|
3831
|
+
}
|
|
3832
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3833
|
+
WalletActionZone,
|
|
3834
|
+
{
|
|
3835
|
+
status: ui.status,
|
|
3836
|
+
multiWallet: ui.multiWallet,
|
|
3837
|
+
connectedWallets: ui.connectedWallets,
|
|
3838
|
+
walletsStatus,
|
|
3839
|
+
onAction,
|
|
3840
|
+
onRemoveWallet
|
|
3841
|
+
}
|
|
3842
|
+
)
|
|
3843
|
+
] }) })
|
|
3844
|
+
}
|
|
3845
|
+
)
|
|
3846
|
+
]
|
|
3847
|
+
}
|
|
3848
|
+
) });
|
|
3849
|
+
}
|
|
3850
|
+
|
|
3851
|
+
// src/client/components/requirements/RequirementsChecklist.tsx
|
|
3852
|
+
var import_react15 = require("react");
|
|
3853
|
+
|
|
3854
|
+
// src/client/components/requirements/TaxDocumentModal.tsx
|
|
3855
|
+
var import_react12 = require("react");
|
|
3856
|
+
|
|
3857
|
+
// src/client/hooks/useTaxDocument.ts
|
|
3858
|
+
var import_react11 = require("react");
|
|
3859
|
+
var IDLE_SIGN2 = { type: "idle", error: null };
|
|
3860
|
+
var LOADING_STATE3 = { type: "LOADING" };
|
|
3861
|
+
var SIGN_FAILED_MESSAGE = "Unable to sign document. Please try again.";
|
|
3862
|
+
var DOB_INVALID_MESSAGE = "Enter your date of birth as MM/DD/YYYY.";
|
|
3863
|
+
var FIELD_KEYS = {
|
|
3864
|
+
fullLegalName: "Full Name",
|
|
3865
|
+
dob: "DOB",
|
|
3866
|
+
countryOfCitizenship: "Country Of Citizenship",
|
|
3867
|
+
taxId: "Foreign Tax Number",
|
|
3868
|
+
permanentAddress: "Permanent Address"
|
|
3869
|
+
};
|
|
3870
|
+
function formatUsDate(date) {
|
|
3871
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
3872
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
3873
|
+
const year = String(date.getFullYear()).padStart(4, "0");
|
|
3874
|
+
return `${month}/${day}/${year}`;
|
|
3875
|
+
}
|
|
3876
|
+
function formatIsoDateOnly(isoDate) {
|
|
3877
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(isoDate);
|
|
3878
|
+
if (!match) return "";
|
|
3879
|
+
const [, year, month, day] = match;
|
|
3880
|
+
return `${month}/${day}/${year}`;
|
|
3881
|
+
}
|
|
3882
|
+
function isValidUsDate(value) {
|
|
3883
|
+
const match = /^(\d{2})\/(\d{2})\/(\d{4})$/.exec(value);
|
|
3884
|
+
if (!match) return false;
|
|
3885
|
+
const [, mm, dd, yyyy] = match;
|
|
3886
|
+
const month = Number(mm);
|
|
3887
|
+
const day = Number(dd);
|
|
3888
|
+
const year = Number(yyyy);
|
|
3889
|
+
const date = new Date(year, month - 1, day);
|
|
3890
|
+
return date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day;
|
|
3891
|
+
}
|
|
3892
|
+
function mapPiiToFields(pii) {
|
|
3893
|
+
const { street, city, state, postalCode } = pii.permanentAddress;
|
|
3894
|
+
const cityLine = [postalCode, city].filter(Boolean).join(" ");
|
|
3895
|
+
const permanentAddress = [street, cityLine, state].filter(Boolean).join(", ");
|
|
3896
|
+
return {
|
|
3897
|
+
fullLegalName: pii.fullLegalName ?? "",
|
|
3898
|
+
// Date-only ISO from the backend, shown as MM/DD/YYYY. Blank until the
|
|
3899
|
+
// backend has a date of birth (the field is editable in the meantime).
|
|
3900
|
+
dob: formatIsoDateOnly(pii.dateOfBirth ?? ""),
|
|
3901
|
+
countryOfCitizenship: pii.jurisdiction?.name ?? "",
|
|
3902
|
+
taxId: pii.taxId ?? "",
|
|
3903
|
+
permanentAddress
|
|
3904
|
+
};
|
|
3905
|
+
}
|
|
3906
|
+
function addressPartsFromPii(pii) {
|
|
3907
|
+
return {
|
|
3908
|
+
city: pii.permanentAddress.city ?? "",
|
|
3909
|
+
country: pii.permanentAddress.country ?? ""
|
|
3910
|
+
};
|
|
3911
|
+
}
|
|
3912
|
+
function hasAnyFieldValue(fields) {
|
|
3913
|
+
return Object.values(fields).some((value) => value.trim() !== "");
|
|
3914
|
+
}
|
|
3915
|
+
function toSubmissionFields(fields, addressParts) {
|
|
3916
|
+
return {
|
|
3917
|
+
[FIELD_KEYS.fullLegalName]: fields.fullLegalName,
|
|
3918
|
+
[FIELD_KEYS.dob]: fields.dob,
|
|
3919
|
+
[FIELD_KEYS.countryOfCitizenship]: fields.countryOfCitizenship,
|
|
3920
|
+
[FIELD_KEYS.taxId]: fields.taxId,
|
|
3921
|
+
[FIELD_KEYS.permanentAddress]: fields.permanentAddress,
|
|
3922
|
+
City: addressParts.city,
|
|
3923
|
+
Country: addressParts.country,
|
|
3924
|
+
Signature: fields.fullLegalName,
|
|
3925
|
+
Date: formatUsDate(/* @__PURE__ */ new Date())
|
|
3926
|
+
};
|
|
3927
|
+
}
|
|
3928
|
+
function useTaxDocument({
|
|
3929
|
+
isOpen
|
|
3930
|
+
}) {
|
|
3931
|
+
const { coinlist, isReady } = useCoinList();
|
|
3932
|
+
const [state, setState] = (0, import_react11.useState)(LOADING_STATE3);
|
|
3933
|
+
(0, import_react11.useEffect)(() => {
|
|
3934
|
+
let isCancelled = false;
|
|
3935
|
+
if (!isOpen) {
|
|
3936
|
+
return () => {
|
|
3937
|
+
isCancelled = true;
|
|
3938
|
+
};
|
|
3939
|
+
}
|
|
3940
|
+
if (!isReady) {
|
|
3941
|
+
setState(LOADING_STATE3);
|
|
3942
|
+
return () => {
|
|
3943
|
+
isCancelled = true;
|
|
3944
|
+
};
|
|
3945
|
+
}
|
|
3946
|
+
setState(LOADING_STATE3);
|
|
3947
|
+
coinlist.fetchPii().then((pii) => {
|
|
3948
|
+
if (isCancelled) return;
|
|
3949
|
+
if (pii.kind === "company") {
|
|
3950
|
+
setState({ type: "SIGN_ONLY", sign: IDLE_SIGN2 });
|
|
3951
|
+
return;
|
|
3952
|
+
}
|
|
3953
|
+
const fields = mapPiiToFields(pii);
|
|
3954
|
+
setState({
|
|
3955
|
+
type: "REVIEW",
|
|
3956
|
+
fields,
|
|
3957
|
+
addressParts: addressPartsFromPii(pii),
|
|
3958
|
+
piiUnavailable: !hasAnyFieldValue(fields),
|
|
3959
|
+
sign: IDLE_SIGN2
|
|
3960
|
+
});
|
|
3961
|
+
}).catch((error) => {
|
|
3962
|
+
if (isCancelled) return;
|
|
3963
|
+
setState({
|
|
3964
|
+
type: "ERROR",
|
|
3965
|
+
reason: error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error"
|
|
3966
|
+
});
|
|
3967
|
+
});
|
|
3968
|
+
return () => {
|
|
3969
|
+
isCancelled = true;
|
|
3970
|
+
};
|
|
3971
|
+
}, [coinlist, isReady, isOpen]);
|
|
3972
|
+
const onEditField = (0, import_react11.useCallback)(
|
|
3973
|
+
(field, value) => {
|
|
3974
|
+
setState(
|
|
3975
|
+
(prev) => prev.type === "EDITING" ? { ...prev, fields: { ...prev.fields, [field]: value } } : prev
|
|
3976
|
+
);
|
|
3977
|
+
},
|
|
3978
|
+
[]
|
|
3979
|
+
);
|
|
3980
|
+
const onStartEdit = (0, import_react11.useCallback)(() => {
|
|
3981
|
+
setState(
|
|
3982
|
+
(prev) => prev.type === "REVIEW" ? {
|
|
3983
|
+
type: "EDITING",
|
|
3984
|
+
fields: prev.fields,
|
|
3985
|
+
original: prev.fields,
|
|
3986
|
+
addressParts: prev.addressParts,
|
|
3987
|
+
piiUnavailable: prev.piiUnavailable
|
|
3988
|
+
} : prev
|
|
3989
|
+
);
|
|
3990
|
+
}, []);
|
|
3991
|
+
const onSaveEdit = (0, import_react11.useCallback)(() => {
|
|
3992
|
+
setState(
|
|
3993
|
+
(prev) => prev.type === "EDITING" ? {
|
|
3994
|
+
type: "REVIEW",
|
|
3995
|
+
fields: prev.fields,
|
|
3996
|
+
addressParts: prev.addressParts,
|
|
3997
|
+
piiUnavailable: prev.piiUnavailable,
|
|
3998
|
+
sign: IDLE_SIGN2
|
|
3999
|
+
} : prev
|
|
4000
|
+
);
|
|
4001
|
+
}, []);
|
|
4002
|
+
const onCancelEdit = (0, import_react11.useCallback)(() => {
|
|
4003
|
+
setState(
|
|
4004
|
+
(prev) => prev.type === "EDITING" ? {
|
|
4005
|
+
type: "REVIEW",
|
|
4006
|
+
fields: prev.original,
|
|
4007
|
+
addressParts: prev.addressParts,
|
|
4008
|
+
piiUnavailable: prev.piiUnavailable,
|
|
4009
|
+
sign: IDLE_SIGN2
|
|
4010
|
+
} : prev
|
|
4011
|
+
);
|
|
4012
|
+
}, []);
|
|
4013
|
+
const onSign = (0, import_react11.useCallback)(() => {
|
|
4014
|
+
if (state.type !== "REVIEW" && state.type !== "SIGN_ONLY") return;
|
|
4015
|
+
if (state.type === "REVIEW" && state.fields.dob.trim() !== "" && !isValidUsDate(state.fields.dob)) {
|
|
4016
|
+
setState({
|
|
4017
|
+
...state,
|
|
4018
|
+
sign: { type: "idle", error: DOB_INVALID_MESSAGE }
|
|
4019
|
+
});
|
|
4020
|
+
return;
|
|
4021
|
+
}
|
|
4022
|
+
setState({ ...state, sign: { type: "signing" } });
|
|
4023
|
+
coinlist.submitDocument(
|
|
4024
|
+
"tax_certification",
|
|
4025
|
+
state.type === "REVIEW" ? toSubmissionFields(state.fields, state.addressParts) : {}
|
|
4026
|
+
).then((submission) => {
|
|
4027
|
+
setState({ type: "SUBMITTED", submission });
|
|
4028
|
+
}).catch(() => {
|
|
4029
|
+
setState(
|
|
4030
|
+
(prev) => prev.type === "REVIEW" || prev.type === "SIGN_ONLY" ? { ...prev, sign: { type: "idle", error: SIGN_FAILED_MESSAGE } } : prev
|
|
4031
|
+
);
|
|
4032
|
+
});
|
|
4033
|
+
}, [state, coinlist]);
|
|
4034
|
+
return { state, onEditField, onStartEdit, onSaveEdit, onCancelEdit, onSign };
|
|
4035
|
+
}
|
|
4036
|
+
|
|
4037
|
+
// src/client/components/requirements/TaxDocumentModal.tsx
|
|
4038
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
4039
|
+
var FIELD_ROWS = [
|
|
4040
|
+
{ field: "fullLegalName", label: "Full legal name" },
|
|
4041
|
+
{ field: "dob", label: "Date of birth", placeholder: "MM/DD/YYYY" },
|
|
4042
|
+
{ field: "countryOfCitizenship", label: "Country of citizenship" },
|
|
4043
|
+
{ field: "taxId", label: "Tax ID" },
|
|
4044
|
+
{ field: "permanentAddress", label: "Permanent address" }
|
|
4045
|
+
];
|
|
4046
|
+
function TaxDocumentModal({
|
|
4047
|
+
isOpen,
|
|
4048
|
+
onClose,
|
|
4049
|
+
onSubmitted,
|
|
4050
|
+
className
|
|
4051
|
+
}) {
|
|
4052
|
+
const { state, onEditField, onStartEdit, onSaveEdit, onCancelEdit, onSign } = useTaxDocument({ isOpen });
|
|
4053
|
+
(0, import_react12.useEffect)(() => {
|
|
4054
|
+
if (state.type === "SUBMITTED") {
|
|
4055
|
+
onSubmitted?.(state.submission);
|
|
4056
|
+
onClose();
|
|
4057
|
+
}
|
|
4058
|
+
}, [state]);
|
|
4059
|
+
if (!isOpen || state.type === "SUBMITTED") return null;
|
|
4060
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("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__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4061
|
+
"div",
|
|
4062
|
+
{
|
|
4063
|
+
className: cn(
|
|
4064
|
+
"clcosdk:flex clcosdk:w-full clcosdk:max-w-md clcosdk:flex-col clcosdk:gap-6 clcosdk:rounded-2xl clcosdk:bg-background clcosdk:p-6",
|
|
4065
|
+
className
|
|
4066
|
+
),
|
|
4067
|
+
children: [
|
|
4068
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "clcosdk:flex clcosdk:items-start clcosdk:justify-between clcosdk:gap-4", children: [
|
|
4069
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TaxDocumentModalHeading, { state }),
|
|
4070
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(CloseButton, { onClick: onClose })
|
|
4071
|
+
] }),
|
|
4072
|
+
state.type === "LOADING" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(LoadingScreen, {}),
|
|
4073
|
+
state.type === "ERROR" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ErrorScreen, { reason: state.reason }),
|
|
4074
|
+
state.type === "REVIEW" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4075
|
+
ReviewScreen,
|
|
4076
|
+
{
|
|
4077
|
+
fields: state.fields,
|
|
4078
|
+
piiUnavailable: state.piiUnavailable,
|
|
4079
|
+
sign: state.sign,
|
|
4080
|
+
onStartEdit,
|
|
4081
|
+
onSign
|
|
4082
|
+
}
|
|
4083
|
+
),
|
|
4084
|
+
state.type === "EDITING" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4085
|
+
EditScreen,
|
|
1931
4086
|
{
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "clcosdk:min-h-0 clcosdk:overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-4 clcosdk:px-2 clcosdk:pb-4", children: [
|
|
1937
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1938
|
-
"p",
|
|
1939
|
-
{
|
|
1940
|
-
className: cn(typeClasses.subhead, "clcosdk:text-text-secondary"),
|
|
1941
|
-
children: ui.description
|
|
1942
|
-
}
|
|
1943
|
-
),
|
|
1944
|
-
ui.variant === "verification" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1945
|
-
VerificationActionZone,
|
|
1946
|
-
{
|
|
1947
|
-
status: ui.status,
|
|
1948
|
-
onAction,
|
|
1949
|
-
onContactSupport
|
|
1950
|
-
}
|
|
1951
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1952
|
-
WalletActionZone,
|
|
1953
|
-
{
|
|
1954
|
-
status: ui.status,
|
|
1955
|
-
walletAddress: ui.walletAddress,
|
|
1956
|
-
onAction
|
|
1957
|
-
}
|
|
1958
|
-
)
|
|
1959
|
-
] }) })
|
|
4087
|
+
fields: state.fields,
|
|
4088
|
+
onEditField,
|
|
4089
|
+
onSaveEdit,
|
|
4090
|
+
onCancelEdit
|
|
1960
4091
|
}
|
|
1961
|
-
)
|
|
4092
|
+
),
|
|
4093
|
+
state.type === "SIGN_ONLY" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SignOnlyScreen, { sign: state.sign, onSign })
|
|
1962
4094
|
]
|
|
1963
4095
|
}
|
|
4096
|
+
) });
|
|
4097
|
+
}
|
|
4098
|
+
function TaxDocumentModalHeading({
|
|
4099
|
+
state
|
|
4100
|
+
}) {
|
|
4101
|
+
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";
|
|
4102
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h3", { className: cn(typeClasses.h3, "clcosdk:text-text-primary"), children: title });
|
|
4103
|
+
}
|
|
4104
|
+
function LoadingScreen() {
|
|
4105
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4106
|
+
"output",
|
|
4107
|
+
{
|
|
4108
|
+
"aria-live": "polite",
|
|
4109
|
+
className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-4",
|
|
4110
|
+
children: FIELD_ROWS.map(({ field }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4111
|
+
"div",
|
|
4112
|
+
{
|
|
4113
|
+
className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-1",
|
|
4114
|
+
children: [
|
|
4115
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "clcosdk:h-3 clcosdk:w-28 clcosdk:animate-pulse clcosdk:rounded clcosdk:bg-surface" }),
|
|
4116
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "clcosdk:h-5 clcosdk:w-48 clcosdk:animate-pulse clcosdk:rounded clcosdk:bg-surface" })
|
|
4117
|
+
]
|
|
4118
|
+
},
|
|
4119
|
+
field
|
|
4120
|
+
))
|
|
4121
|
+
}
|
|
4122
|
+
);
|
|
4123
|
+
}
|
|
4124
|
+
function ErrorScreen({
|
|
4125
|
+
reason
|
|
4126
|
+
}) {
|
|
4127
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4128
|
+
AlertBanner,
|
|
4129
|
+
{
|
|
4130
|
+
variant: "error",
|
|
4131
|
+
icon: true,
|
|
4132
|
+
content: reason === "not-authenticated" ? "Sign in to complete your tax document." : "Unable to load your tax information right now. Please try again."
|
|
4133
|
+
}
|
|
1964
4134
|
);
|
|
1965
4135
|
}
|
|
4136
|
+
function ReviewScreen({
|
|
4137
|
+
fields,
|
|
4138
|
+
piiUnavailable,
|
|
4139
|
+
sign,
|
|
4140
|
+
onStartEdit,
|
|
4141
|
+
onSign
|
|
4142
|
+
}) {
|
|
4143
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-6", children: [
|
|
4144
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: cn(typeClasses.body, "clcosdk:text-text-secondary"), children: "Review your information below. If anything looks incorrect, edit before signing." }),
|
|
4145
|
+
piiUnavailable && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4146
|
+
AlertBanner,
|
|
4147
|
+
{
|
|
4148
|
+
variant: "info",
|
|
4149
|
+
icon: true,
|
|
4150
|
+
content: "We don't have this information on file yet \u2014 please fill it in below."
|
|
4151
|
+
}
|
|
4152
|
+
),
|
|
4153
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("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__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4154
|
+
"div",
|
|
4155
|
+
{
|
|
4156
|
+
className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-1",
|
|
4157
|
+
children: [
|
|
4158
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4159
|
+
"span",
|
|
4160
|
+
{
|
|
4161
|
+
className: cn(typeClasses.label, "clcosdk:text-text-secondary"),
|
|
4162
|
+
children: label
|
|
4163
|
+
}
|
|
4164
|
+
),
|
|
4165
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: cn(typeClasses.body, "clcosdk:text-text-primary"), children: fields[field] || "\u2014" })
|
|
4166
|
+
]
|
|
4167
|
+
},
|
|
4168
|
+
field
|
|
4169
|
+
)) }),
|
|
4170
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("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." }),
|
|
4171
|
+
sign.type === "idle" && sign.error && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AlertBanner, { variant: "error", icon: true, content: sign.error }),
|
|
4172
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-2", children: [
|
|
4173
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4174
|
+
ClButton,
|
|
4175
|
+
{
|
|
4176
|
+
fullWidth: true,
|
|
4177
|
+
onClick: onSign,
|
|
4178
|
+
isLoading: sign.type === "signing",
|
|
4179
|
+
loadingText: "Signing...",
|
|
4180
|
+
children: "Sign W-8BEN"
|
|
4181
|
+
}
|
|
4182
|
+
),
|
|
4183
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4184
|
+
ClButton,
|
|
4185
|
+
{
|
|
4186
|
+
fullWidth: true,
|
|
4187
|
+
variant: "secondary",
|
|
4188
|
+
onClick: onStartEdit,
|
|
4189
|
+
disabled: sign.type === "signing",
|
|
4190
|
+
children: "Edit information"
|
|
4191
|
+
}
|
|
4192
|
+
)
|
|
4193
|
+
] })
|
|
4194
|
+
] });
|
|
4195
|
+
}
|
|
4196
|
+
function EditScreen({
|
|
4197
|
+
fields,
|
|
4198
|
+
onEditField,
|
|
4199
|
+
onSaveEdit,
|
|
4200
|
+
onCancelEdit
|
|
4201
|
+
}) {
|
|
4202
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-6", children: [
|
|
4203
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("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__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4204
|
+
"label",
|
|
4205
|
+
{
|
|
4206
|
+
className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-1",
|
|
4207
|
+
children: [
|
|
4208
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4209
|
+
"span",
|
|
4210
|
+
{
|
|
4211
|
+
className: cn(typeClasses.label, "clcosdk:text-text-secondary"),
|
|
4212
|
+
children: label
|
|
4213
|
+
}
|
|
4214
|
+
),
|
|
4215
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4216
|
+
"input",
|
|
4217
|
+
{
|
|
4218
|
+
type: "text",
|
|
4219
|
+
value: fields[field],
|
|
4220
|
+
placeholder,
|
|
4221
|
+
onChange: (e) => onEditField(field, e.target.value),
|
|
4222
|
+
className: cn(
|
|
4223
|
+
typeClasses.body,
|
|
4224
|
+
"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"
|
|
4225
|
+
)
|
|
4226
|
+
}
|
|
4227
|
+
)
|
|
4228
|
+
]
|
|
4229
|
+
},
|
|
4230
|
+
field
|
|
4231
|
+
)) }),
|
|
4232
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-2", children: [
|
|
4233
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ClButton, { fullWidth: true, onClick: onSaveEdit, children: "Save & review" }),
|
|
4234
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ClButton, { fullWidth: true, variant: "secondary", onClick: onCancelEdit, children: "Cancel" })
|
|
4235
|
+
] })
|
|
4236
|
+
] });
|
|
4237
|
+
}
|
|
4238
|
+
function SignOnlyScreen({
|
|
4239
|
+
sign,
|
|
4240
|
+
onSign
|
|
4241
|
+
}) {
|
|
4242
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-6", children: [
|
|
4243
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("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." }),
|
|
4244
|
+
sign.type === "idle" && sign.error && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AlertBanner, { variant: "error", icon: true, content: sign.error }),
|
|
4245
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4246
|
+
ClButton,
|
|
4247
|
+
{
|
|
4248
|
+
fullWidth: true,
|
|
4249
|
+
onClick: onSign,
|
|
4250
|
+
isLoading: sign.type === "signing",
|
|
4251
|
+
loadingText: "Signing...",
|
|
4252
|
+
children: "Sign W-8BEN-E"
|
|
4253
|
+
}
|
|
4254
|
+
)
|
|
4255
|
+
] });
|
|
4256
|
+
}
|
|
1966
4257
|
|
|
1967
|
-
// src/client/
|
|
1968
|
-
var
|
|
4258
|
+
// src/client/hooks/useOptionAddresses.ts
|
|
4259
|
+
var import_react13 = require("react");
|
|
4260
|
+
var LOADING_STATE4 = { type: "LOADING" };
|
|
4261
|
+
var EMPTY_STATE = {
|
|
4262
|
+
type: "CONTENT",
|
|
4263
|
+
addresses: []
|
|
4264
|
+
};
|
|
4265
|
+
function useOptionAddresses(offerId, offerOptionId, options = {}) {
|
|
4266
|
+
const { coinlist, isReady } = useCoinList();
|
|
4267
|
+
const { data, enabled = true } = options;
|
|
4268
|
+
const [addressesState, setAddressesState] = (0, import_react13.useState)(
|
|
4269
|
+
data !== void 0 ? { type: "CONTENT", addresses: data } : LOADING_STATE4
|
|
4270
|
+
);
|
|
4271
|
+
const [fetchKey, setFetchKey] = (0, import_react13.useState)(0);
|
|
4272
|
+
const refetch = (0, import_react13.useCallback)(() => setFetchKey((k) => k + 1), []);
|
|
4273
|
+
const disconnect = (0, import_react13.useCallback)(
|
|
4274
|
+
async (addressId) => {
|
|
4275
|
+
await coinlist.removeOptionAddress(offerId, addressId);
|
|
4276
|
+
refetch();
|
|
4277
|
+
},
|
|
4278
|
+
[coinlist, offerId, refetch]
|
|
4279
|
+
);
|
|
4280
|
+
(0, import_react13.useEffect)(() => {
|
|
4281
|
+
let isCancelled = false;
|
|
4282
|
+
if (!enabled) {
|
|
4283
|
+
setAddressesState(
|
|
4284
|
+
data !== void 0 ? { type: "CONTENT", addresses: data } : EMPTY_STATE
|
|
4285
|
+
);
|
|
4286
|
+
return () => {
|
|
4287
|
+
isCancelled = true;
|
|
4288
|
+
};
|
|
4289
|
+
}
|
|
4290
|
+
if (!isReady) {
|
|
4291
|
+
if (data === void 0) {
|
|
4292
|
+
setAddressesState(LOADING_STATE4);
|
|
4293
|
+
}
|
|
4294
|
+
return () => {
|
|
4295
|
+
isCancelled = true;
|
|
4296
|
+
};
|
|
4297
|
+
}
|
|
4298
|
+
if (data !== void 0 && fetchKey === 0) {
|
|
4299
|
+
return () => {
|
|
4300
|
+
isCancelled = true;
|
|
4301
|
+
};
|
|
4302
|
+
}
|
|
4303
|
+
if (coinlist.getAuthState() === "logged-out") {
|
|
4304
|
+
setAddressesState({ type: "ERROR", reason: "not-authenticated" });
|
|
4305
|
+
return () => {
|
|
4306
|
+
isCancelled = true;
|
|
4307
|
+
};
|
|
4308
|
+
}
|
|
4309
|
+
setAddressesState(LOADING_STATE4);
|
|
4310
|
+
coinlist.listOptionAddresses(offerId, offerOptionId).then((addresses) => {
|
|
4311
|
+
if (!isCancelled) {
|
|
4312
|
+
setAddressesState({ type: "CONTENT", addresses });
|
|
4313
|
+
}
|
|
4314
|
+
}).catch((error) => {
|
|
4315
|
+
if (!isCancelled) {
|
|
4316
|
+
const reason = error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error";
|
|
4317
|
+
setAddressesState({ type: "ERROR", reason });
|
|
4318
|
+
}
|
|
4319
|
+
});
|
|
4320
|
+
return () => {
|
|
4321
|
+
isCancelled = true;
|
|
4322
|
+
};
|
|
4323
|
+
}, [coinlist, isReady, enabled, offerId, offerOptionId, fetchKey]);
|
|
4324
|
+
return { addressesState, refetch, disconnect };
|
|
4325
|
+
}
|
|
1969
4326
|
|
|
1970
4327
|
// src/client/hooks/useRequirements.ts
|
|
1971
|
-
var
|
|
1972
|
-
var
|
|
4328
|
+
var import_react14 = require("react");
|
|
4329
|
+
var LOADING_STATE5 = { type: "LOADING" };
|
|
1973
4330
|
function useRequirements(offerId, options = {}) {
|
|
1974
4331
|
const { coinlist, isReady } = useCoinList();
|
|
1975
4332
|
const { data } = options;
|
|
1976
|
-
const [requirementsState, setRequirementsState] = (0,
|
|
1977
|
-
data !== void 0 ? { type: "CONTENT", ...data } :
|
|
4333
|
+
const [requirementsState, setRequirementsState] = (0, import_react14.useState)(
|
|
4334
|
+
data !== void 0 ? { type: "CONTENT", ...data } : LOADING_STATE5
|
|
1978
4335
|
);
|
|
1979
|
-
const [fetchKey, setFetchKey] = (0,
|
|
1980
|
-
const refetch = (0,
|
|
1981
|
-
(0,
|
|
4336
|
+
const [fetchKey, setFetchKey] = (0, import_react14.useState)(0);
|
|
4337
|
+
const refetch = (0, import_react14.useCallback)(() => setFetchKey((k) => k + 1), []);
|
|
4338
|
+
(0, import_react14.useEffect)(() => {
|
|
1982
4339
|
let isCancelled = false;
|
|
1983
4340
|
if (!isReady) {
|
|
1984
4341
|
if (data === void 0) {
|
|
1985
|
-
setRequirementsState(
|
|
4342
|
+
setRequirementsState(LOADING_STATE5);
|
|
1986
4343
|
}
|
|
1987
4344
|
return () => {
|
|
1988
4345
|
isCancelled = true;
|
|
@@ -1993,7 +4350,13 @@ function useRequirements(offerId, options = {}) {
|
|
|
1993
4350
|
isCancelled = true;
|
|
1994
4351
|
};
|
|
1995
4352
|
}
|
|
1996
|
-
|
|
4353
|
+
if (coinlist.getAuthState() === "logged-out") {
|
|
4354
|
+
setRequirementsState({ type: "ERROR", reason: "not-authenticated" });
|
|
4355
|
+
return () => {
|
|
4356
|
+
isCancelled = true;
|
|
4357
|
+
};
|
|
4358
|
+
}
|
|
4359
|
+
setRequirementsState(LOADING_STATE5);
|
|
1997
4360
|
Promise.all([
|
|
1998
4361
|
coinlist.fetchOfferRequirements(offerId),
|
|
1999
4362
|
coinlist.fetchRequirementStatuses(offerId)
|
|
@@ -2019,7 +4382,8 @@ function useRequirements(offerId, options = {}) {
|
|
|
2019
4382
|
}
|
|
2020
4383
|
|
|
2021
4384
|
// src/client/components/requirements/RequirementsChecklist.tsx
|
|
2022
|
-
var
|
|
4385
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
4386
|
+
var isWalletRequirement = (requirement) => RequirementVariant.fromType(requirement.type) === "wallet";
|
|
2023
4387
|
var DEFAULT_LABELS = {
|
|
2024
4388
|
kyc_approved: "KYC Verification",
|
|
2025
4389
|
identity_verified: "Identity Verification",
|
|
@@ -2028,7 +4392,8 @@ var DEFAULT_LABELS = {
|
|
|
2028
4392
|
external_wallet: "External Wallet",
|
|
2029
4393
|
whitelisted_wallet: "Whitelisted Wallet",
|
|
2030
4394
|
jurisdiction: "Jurisdiction Check",
|
|
2031
|
-
accreditation: "Accreditation"
|
|
4395
|
+
accreditation: "Accreditation",
|
|
4396
|
+
document: "Document"
|
|
2032
4397
|
};
|
|
2033
4398
|
var DEFAULT_DESCRIPTIONS = {
|
|
2034
4399
|
kyc_approved: "Complete Know Your Customer verification.",
|
|
@@ -2038,9 +4403,39 @@ var DEFAULT_DESCRIPTIONS = {
|
|
|
2038
4403
|
external_wallet: "Connect an external wallet.",
|
|
2039
4404
|
whitelisted_wallet: "Connect a whitelisted wallet.",
|
|
2040
4405
|
jurisdiction: "Confirm your jurisdiction eligibility.",
|
|
2041
|
-
accreditation: "Verify your accreditation status."
|
|
4406
|
+
accreditation: "Verify your accreditation status.",
|
|
4407
|
+
document: "Confirm your Tax Documents."
|
|
2042
4408
|
};
|
|
2043
|
-
|
|
4409
|
+
var VERIFICATION_POLL_INTERVAL_MS = 5e3;
|
|
4410
|
+
var VERIFICATION_POLL_TIMEOUT_MS = 12e4;
|
|
4411
|
+
function sleep(ms) {
|
|
4412
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
4413
|
+
}
|
|
4414
|
+
function VerificationOverlay({
|
|
4415
|
+
onClose,
|
|
4416
|
+
children
|
|
4417
|
+
}) {
|
|
4418
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4419
|
+
"div",
|
|
4420
|
+
{
|
|
4421
|
+
role: "dialog",
|
|
4422
|
+
"aria-modal": "true",
|
|
4423
|
+
"aria-label": "Identity verification",
|
|
4424
|
+
className: "clcosdk:fixed clcosdk:inset-0 clcosdk:z-50 clcosdk:flex clcosdk:items-center clcosdk:justify-center clcosdk:bg-overlay clcosdk:p-4",
|
|
4425
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("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: [
|
|
4426
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4427
|
+
CloseButton,
|
|
4428
|
+
{
|
|
4429
|
+
onClick: onClose,
|
|
4430
|
+
className: "clcosdk:absolute clcosdk:top-4 clcosdk:right-4"
|
|
4431
|
+
}
|
|
4432
|
+
),
|
|
4433
|
+
children
|
|
4434
|
+
] })
|
|
4435
|
+
}
|
|
4436
|
+
);
|
|
4437
|
+
}
|
|
4438
|
+
function RequirementsChecklistBody({
|
|
2044
4439
|
offerId,
|
|
2045
4440
|
optionId,
|
|
2046
4441
|
title,
|
|
@@ -2048,38 +4443,106 @@ function RequirementsChecklist({
|
|
|
2048
4443
|
onContinue,
|
|
2049
4444
|
onRequirementActionOverride,
|
|
2050
4445
|
onContactSupportOverride,
|
|
4446
|
+
wallet,
|
|
4447
|
+
onRequestConnect,
|
|
2051
4448
|
getLabel,
|
|
2052
4449
|
getDescription,
|
|
2053
4450
|
loading,
|
|
4451
|
+
unauthenticatedState,
|
|
2054
4452
|
error,
|
|
2055
4453
|
className,
|
|
2056
|
-
data
|
|
4454
|
+
data,
|
|
4455
|
+
identityVerificationOptions
|
|
2057
4456
|
}) {
|
|
2058
4457
|
const { coinlist } = useCoinList();
|
|
2059
|
-
const { requirementsState } = useRequirements(offerId, { data });
|
|
2060
|
-
const [expandedIndex, setExpandedIndex] = (0,
|
|
2061
|
-
const
|
|
4458
|
+
const { requirementsState, refetch } = useRequirements(offerId, { data });
|
|
4459
|
+
const [expandedIndex, setExpandedIndex] = (0, import_react15.useState)(null);
|
|
4460
|
+
const [taxDocumentOpen, setTaxDocumentOpen] = (0, import_react15.useState)(false);
|
|
4461
|
+
const [walletConnectOpen, setConnectWalletOpen] = (0, import_react15.useState)(false);
|
|
4462
|
+
const [verifyingRequirementId, setVerifyingRequirementId] = (0, import_react15.useState)(null);
|
|
4463
|
+
const isMountedRef = (0, import_react15.useRef)(true);
|
|
4464
|
+
(0, import_react15.useEffect)(() => {
|
|
4465
|
+
isMountedRef.current = true;
|
|
4466
|
+
return () => {
|
|
4467
|
+
isMountedRef.current = false;
|
|
4468
|
+
};
|
|
4469
|
+
}, []);
|
|
4470
|
+
const [hasWalletRequirement, setHasWalletRequirement] = (0, import_react15.useState)(false);
|
|
4471
|
+
(0, import_react15.useEffect)(() => {
|
|
4472
|
+
if (requirementsState.type === "CONTENT") {
|
|
4473
|
+
setHasWalletRequirement(
|
|
4474
|
+
(requirementsState.requirements[optionId] ?? []).some(
|
|
4475
|
+
isWalletRequirement
|
|
4476
|
+
)
|
|
4477
|
+
);
|
|
4478
|
+
}
|
|
4479
|
+
}, [requirementsState, optionId]);
|
|
4480
|
+
const {
|
|
4481
|
+
addressesState,
|
|
4482
|
+
refetch: refetchAddresses,
|
|
4483
|
+
disconnect
|
|
4484
|
+
} = useOptionAddresses(offerId, optionId, {
|
|
4485
|
+
enabled: hasWalletRequirement
|
|
4486
|
+
});
|
|
4487
|
+
const optionAddresses = addressesState.type === "CONTENT" ? addressesState.addresses : [];
|
|
4488
|
+
const walletsStatus = addressesState.type === "ERROR" ? "error" : addressesState.type === "LOADING" ? "loading" : "ready";
|
|
4489
|
+
const onRemoveWallet = async (id) => {
|
|
4490
|
+
await disconnect(OfferOptionAddressId(id));
|
|
4491
|
+
refetch();
|
|
4492
|
+
};
|
|
4493
|
+
const onRequirementAction = onRequirementActionOverride !== void 0 ? onRequirementActionOverride : (requirement) => {
|
|
4494
|
+
if (requirement.type === "document") {
|
|
4495
|
+
setTaxDocumentOpen(true);
|
|
4496
|
+
return;
|
|
4497
|
+
}
|
|
4498
|
+
if ((requirement.type === "external_wallet" || requirement.type === "whitelisted_wallet") && wallet !== void 0 && (wallet !== null || onRequestConnect !== void 0)) {
|
|
4499
|
+
setConnectWalletOpen(true);
|
|
4500
|
+
return;
|
|
4501
|
+
}
|
|
4502
|
+
coinlist.handleRequirement(requirement);
|
|
4503
|
+
};
|
|
2062
4504
|
const onContactSupport = onContactSupportOverride !== void 0 ? onContactSupportOverride : () => coinlist.contactSupport();
|
|
4505
|
+
const awaitVerificationResult = (requirementId, statusBeforeSubmit) => {
|
|
4506
|
+
void (async () => {
|
|
4507
|
+
const deadline = Date.now() + VERIFICATION_POLL_TIMEOUT_MS;
|
|
4508
|
+
while (Date.now() < deadline) {
|
|
4509
|
+
await sleep(VERIFICATION_POLL_INTERVAL_MS);
|
|
4510
|
+
if (!isMountedRef.current) return;
|
|
4511
|
+
try {
|
|
4512
|
+
const statuses2 = await coinlist.fetchRequirementStatuses(offerId);
|
|
4513
|
+
const current = statuses2.find((s) => s.id === requirementId)?.status;
|
|
4514
|
+
if (current !== void 0 && current !== statusBeforeSubmit) break;
|
|
4515
|
+
} catch (_) {
|
|
4516
|
+
}
|
|
4517
|
+
}
|
|
4518
|
+
if (isMountedRef.current) {
|
|
4519
|
+
setVerifyingRequirementId(null);
|
|
4520
|
+
refetch();
|
|
4521
|
+
}
|
|
4522
|
+
})();
|
|
4523
|
+
};
|
|
2063
4524
|
if (requirementsState.type === "LOADING") {
|
|
2064
4525
|
if (loading) return loading;
|
|
2065
|
-
return /* @__PURE__ */ (0,
|
|
4526
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2066
4527
|
"output",
|
|
2067
4528
|
{
|
|
2068
4529
|
"aria-live": "polite",
|
|
2069
4530
|
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",
|
|
2070
|
-
children: /* @__PURE__ */ (0,
|
|
4531
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: cn(typeClasses.body, "clcosdk:text-text-secondary"), children: "Loading requirements..." })
|
|
2071
4532
|
}
|
|
2072
4533
|
);
|
|
2073
4534
|
}
|
|
2074
4535
|
if (requirementsState.type === "ERROR") {
|
|
4536
|
+
if (requirementsState.reason === "not-authenticated") {
|
|
4537
|
+
return unauthenticatedState !== void 0 ? unauthenticatedState : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(CoinListSignInCard, {});
|
|
4538
|
+
}
|
|
2075
4539
|
if (error) return error;
|
|
2076
|
-
|
|
2077
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
4540
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2078
4541
|
AlertBanner,
|
|
2079
4542
|
{
|
|
2080
4543
|
variant: "error",
|
|
2081
4544
|
icon: true,
|
|
2082
|
-
content:
|
|
4545
|
+
content: "Unable to load requirements right now. Please try again.",
|
|
2083
4546
|
className: "clcosdk:w-full clcosdk:max-w-[28rem]"
|
|
2084
4547
|
}
|
|
2085
4548
|
);
|
|
@@ -2090,7 +4553,7 @@ function RequirementsChecklist({
|
|
|
2090
4553
|
const optionStatuses = statuses.filter((s) => requirementIds.has(s.id));
|
|
2091
4554
|
const statusByRequirementId = new Map(optionStatuses.map((s) => [s.id, s]));
|
|
2092
4555
|
const checklistStatus = ChecklistStatus.derive(optionStatuses);
|
|
2093
|
-
return /* @__PURE__ */ (0,
|
|
4556
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
2094
4557
|
"div",
|
|
2095
4558
|
{
|
|
2096
4559
|
className: cn(
|
|
@@ -2098,17 +4561,20 @@ function RequirementsChecklist({
|
|
|
2098
4561
|
className
|
|
2099
4562
|
),
|
|
2100
4563
|
children: [
|
|
2101
|
-
/* @__PURE__ */ (0,
|
|
2102
|
-
/* @__PURE__ */ (0,
|
|
2103
|
-
/* @__PURE__ */ (0,
|
|
4564
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-2", children: [
|
|
4565
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: cn(typeClasses.h3, "clcosdk:text-text-primary"), children: title }),
|
|
4566
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: cn(typeClasses.body, "clcosdk:text-text-secondary"), children: description })
|
|
2104
4567
|
] }),
|
|
2105
|
-
/* @__PURE__ */ (0,
|
|
4568
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:divide-y clcosdk:divide-divider", children: requirements.map((req, index) => {
|
|
2106
4569
|
const statusInfo = statusByRequirementId.get(req.id);
|
|
2107
4570
|
const label = getLabel ? getLabel(req) : DEFAULT_LABELS[req.type];
|
|
2108
4571
|
const itemDescription = (getDescription ? getDescription(req) : null) ?? DEFAULT_DESCRIPTIONS[req.type];
|
|
4572
|
+
const inlineVerification = statusInfo?.kycLevel !== void 0 && onRequirementActionOverride === void 0;
|
|
2109
4573
|
let onActionBound;
|
|
2110
4574
|
if (onRequirementAction === null) {
|
|
2111
4575
|
onActionBound = null;
|
|
4576
|
+
} else if (inlineVerification) {
|
|
4577
|
+
onActionBound = () => setVerifyingRequirementId(req.id);
|
|
2112
4578
|
} else if (onRequirementAction) {
|
|
2113
4579
|
onActionBound = () => onRequirementAction(req);
|
|
2114
4580
|
}
|
|
@@ -2118,24 +4584,28 @@ function RequirementsChecklist({
|
|
|
2118
4584
|
} else if (onContactSupport) {
|
|
2119
4585
|
onContactSupportBound = () => onContactSupport(req);
|
|
2120
4586
|
}
|
|
2121
|
-
|
|
4587
|
+
const walletRequirement = isWalletRequirement(req);
|
|
4588
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2122
4589
|
RequirementItem,
|
|
2123
4590
|
{
|
|
2124
4591
|
ui: RequirementItemUi.fromDomain(
|
|
2125
4592
|
req,
|
|
2126
4593
|
statusInfo,
|
|
2127
4594
|
label,
|
|
2128
|
-
itemDescription
|
|
4595
|
+
itemDescription,
|
|
4596
|
+
walletRequirement ? optionAddresses : []
|
|
2129
4597
|
),
|
|
2130
4598
|
expanded: expandedIndex === index,
|
|
2131
4599
|
onToggle: () => setExpandedIndex((prev) => prev === index ? null : index),
|
|
2132
4600
|
onAction: onActionBound,
|
|
4601
|
+
onRemoveWallet: walletRequirement ? onRemoveWallet : void 0,
|
|
4602
|
+
walletsStatus: walletRequirement ? walletsStatus : void 0,
|
|
2133
4603
|
onContactSupport: onContactSupportBound
|
|
2134
4604
|
},
|
|
2135
4605
|
req.id
|
|
2136
4606
|
);
|
|
2137
4607
|
}) }),
|
|
2138
|
-
checklistStatus === "ineligible" && /* @__PURE__ */ (0,
|
|
4608
|
+
checklistStatus === "ineligible" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2139
4609
|
AlertBanner,
|
|
2140
4610
|
{
|
|
2141
4611
|
variant: "error",
|
|
@@ -2143,7 +4613,7 @@ function RequirementsChecklist({
|
|
|
2143
4613
|
content: "You are not eligible to participate."
|
|
2144
4614
|
}
|
|
2145
4615
|
),
|
|
2146
|
-
onContinue && /* @__PURE__ */ (0,
|
|
4616
|
+
onContinue && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2147
4617
|
ClButton,
|
|
2148
4618
|
{
|
|
2149
4619
|
fullWidth: true,
|
|
@@ -2151,24 +4621,326 @@ function RequirementsChecklist({
|
|
|
2151
4621
|
onClick: onContinue,
|
|
2152
4622
|
children: "Continue"
|
|
2153
4623
|
}
|
|
4624
|
+
),
|
|
4625
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4626
|
+
TaxDocumentModal,
|
|
4627
|
+
{
|
|
4628
|
+
isOpen: taxDocumentOpen,
|
|
4629
|
+
onClose: () => setTaxDocumentOpen(false),
|
|
4630
|
+
onSubmitted: () => refetch()
|
|
4631
|
+
}
|
|
4632
|
+
),
|
|
4633
|
+
verifyingRequirementId !== null && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(VerificationOverlay, { onClose: () => setVerifyingRequirementId(null), children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4634
|
+
IdentityVerification,
|
|
4635
|
+
{
|
|
4636
|
+
levelName: identityVerificationOptions?.levelName ?? statusByRequirementId.get(verifyingRequirementId)?.kycLevel,
|
|
4637
|
+
reset: statusByRequirementId.get(verifyingRequirementId)?.kycReset ?? false,
|
|
4638
|
+
locale: identityVerificationOptions?.locale,
|
|
4639
|
+
onSubmitted: () => awaitVerificationResult(
|
|
4640
|
+
verifyingRequirementId,
|
|
4641
|
+
statusByRequirementId.get(verifyingRequirementId)?.status ?? "not_started"
|
|
4642
|
+
)
|
|
4643
|
+
}
|
|
4644
|
+
) }),
|
|
4645
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4646
|
+
ConnectWalletModal,
|
|
4647
|
+
{
|
|
4648
|
+
isOpen: walletConnectOpen,
|
|
4649
|
+
onClose: () => setConnectWalletOpen(false),
|
|
4650
|
+
offerId,
|
|
4651
|
+
optionId,
|
|
4652
|
+
wallet: wallet ?? null,
|
|
4653
|
+
onRequestConnect,
|
|
4654
|
+
onConnected: () => {
|
|
4655
|
+
refetch();
|
|
4656
|
+
refetchAddresses();
|
|
4657
|
+
}
|
|
4658
|
+
}
|
|
2154
4659
|
)
|
|
2155
4660
|
]
|
|
2156
4661
|
}
|
|
2157
4662
|
);
|
|
2158
4663
|
}
|
|
4664
|
+
function RequirementsChecklist(props) {
|
|
4665
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(CoinListStyleScope, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RequirementsChecklistBody, { ...props }) });
|
|
4666
|
+
}
|
|
4667
|
+
|
|
4668
|
+
// src/client/hooks/swap/useSwapOutputToken.ts
|
|
4669
|
+
var import_react16 = require("react");
|
|
4670
|
+
var LOADING_STATE6 = { type: "LOADING" };
|
|
4671
|
+
function useSwapOutputToken(options) {
|
|
4672
|
+
const { contractAddress, chain, enabled } = options;
|
|
4673
|
+
const { coinlist, isReady } = useCoinList();
|
|
4674
|
+
const [outputTokenState, setOutputTokenState] = (0, import_react16.useState)(LOADING_STATE6);
|
|
4675
|
+
const fetchIdRef = (0, import_react16.useRef)(0);
|
|
4676
|
+
(0, import_react16.useEffect)(() => {
|
|
4677
|
+
if (!enabled || !isReady) return;
|
|
4678
|
+
const currentFetchId = ++fetchIdRef.current;
|
|
4679
|
+
const load = async () => {
|
|
4680
|
+
try {
|
|
4681
|
+
const outputToken = await coinlist.swap.getOutputToken({
|
|
4682
|
+
contractAddress,
|
|
4683
|
+
chain
|
|
4684
|
+
});
|
|
4685
|
+
if (currentFetchId !== fetchIdRef.current) return;
|
|
4686
|
+
setOutputTokenState({ type: "CONTENT", outputToken });
|
|
4687
|
+
} catch {
|
|
4688
|
+
if (currentFetchId !== fetchIdRef.current) return;
|
|
4689
|
+
setOutputTokenState({ type: "ERROR" });
|
|
4690
|
+
}
|
|
4691
|
+
};
|
|
4692
|
+
load();
|
|
4693
|
+
return () => {
|
|
4694
|
+
++fetchIdRef.current;
|
|
4695
|
+
};
|
|
4696
|
+
}, [coinlist, isReady, contractAddress, chain, enabled]);
|
|
4697
|
+
return { outputTokenState };
|
|
4698
|
+
}
|
|
4699
|
+
|
|
4700
|
+
// src/client/hooks/swap/useSwapQuote.ts
|
|
4701
|
+
var import_react17 = require("react");
|
|
4702
|
+
|
|
4703
|
+
// src/shared/core/blockchain/swap/constants.ts
|
|
4704
|
+
var SWAP_POLL_INTERVAL_MS = 15e3;
|
|
4705
|
+
var SLIPPAGE_OPTIONS_BPS = [25n, 50n, 100n, 200n, 500n].map(
|
|
4706
|
+
(n) => Bps(n)
|
|
4707
|
+
);
|
|
4708
|
+
var DEFAULT_SLIPPAGE_BPS = Bps(50n);
|
|
4709
|
+
var SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA = EvmContractAddress("0x84f8e9a6C9Cc12fe911259372EfCa5582C4ae557");
|
|
4710
|
+
|
|
4711
|
+
// src/shared/core/blockchain/swap/quote.ts
|
|
4712
|
+
var SwapQuote = {
|
|
4713
|
+
/**
|
|
4714
|
+
* Assembles a {@link SwapQuote} from a raw contract {@link SwapPreview}. The
|
|
4715
|
+
* input and fee are denominated in the input token; the output in the output
|
|
4716
|
+
* token.
|
|
4717
|
+
*/
|
|
4718
|
+
fromPreview: (preview, inputDecimals, outputDecimals) => ({
|
|
4719
|
+
inputTokenAmount: BlockchainAmount({
|
|
4720
|
+
raw: preview.inputAmount,
|
|
4721
|
+
decimals: inputDecimals
|
|
4722
|
+
}),
|
|
4723
|
+
fee: BlockchainAmount({ raw: preview.fee, decimals: inputDecimals }),
|
|
4724
|
+
outputTokenAmount: BlockchainAmount({
|
|
4725
|
+
raw: preview.outputAmount,
|
|
4726
|
+
decimals: outputDecimals
|
|
4727
|
+
})
|
|
4728
|
+
})
|
|
4729
|
+
};
|
|
4730
|
+
|
|
4731
|
+
// src/client/hooks/swap/useSwapQuote.ts
|
|
4732
|
+
function useSwapQuote(options) {
|
|
4733
|
+
const {
|
|
4734
|
+
contractAddress,
|
|
4735
|
+
chain,
|
|
4736
|
+
inputAmount,
|
|
4737
|
+
inputTokenAddress,
|
|
4738
|
+
outputTokenDecimals,
|
|
4739
|
+
pollIntervalMs = SWAP_POLL_INTERVAL_MS,
|
|
4740
|
+
enabled
|
|
4741
|
+
} = options;
|
|
4742
|
+
const { coinlist, isReady } = useCoinList();
|
|
4743
|
+
const [quote, setQuote] = (0, import_react17.useState)(null);
|
|
4744
|
+
const [isLoading, setIsLoading] = (0, import_react17.useState)(true);
|
|
4745
|
+
const [isRefreshing, setIsRefreshing] = (0, import_react17.useState)(false);
|
|
4746
|
+
const isFetchingRef = (0, import_react17.useRef)(false);
|
|
4747
|
+
const hasQuoteRef = (0, import_react17.useRef)(false);
|
|
4748
|
+
const fetchIdRef = (0, import_react17.useRef)(0);
|
|
4749
|
+
(0, import_react17.useEffect)(() => {
|
|
4750
|
+
if (!isReady) return;
|
|
4751
|
+
if (!enabled) {
|
|
4752
|
+
setIsLoading(false);
|
|
4753
|
+
return;
|
|
4754
|
+
}
|
|
4755
|
+
const currentFetchId = ++fetchIdRef.current;
|
|
4756
|
+
isFetchingRef.current = false;
|
|
4757
|
+
const loadQuote = async () => {
|
|
4758
|
+
if (outputTokenDecimals === null) return;
|
|
4759
|
+
if (isFetchingRef.current) return;
|
|
4760
|
+
isFetchingRef.current = true;
|
|
4761
|
+
if (hasQuoteRef.current) {
|
|
4762
|
+
setIsRefreshing(true);
|
|
4763
|
+
}
|
|
4764
|
+
try {
|
|
4765
|
+
const preview = await coinlist.swap.getPreview({
|
|
4766
|
+
contractAddress,
|
|
4767
|
+
chain,
|
|
4768
|
+
inputToken: inputTokenAddress,
|
|
4769
|
+
amount: inputAmount.raw
|
|
4770
|
+
});
|
|
4771
|
+
if (currentFetchId !== fetchIdRef.current) return;
|
|
4772
|
+
setQuote(
|
|
4773
|
+
SwapQuote.fromPreview(
|
|
4774
|
+
preview,
|
|
4775
|
+
inputAmount.decimals,
|
|
4776
|
+
outputTokenDecimals
|
|
4777
|
+
)
|
|
4778
|
+
);
|
|
4779
|
+
if (!hasQuoteRef.current) {
|
|
4780
|
+
hasQuoteRef.current = true;
|
|
4781
|
+
setIsLoading(false);
|
|
4782
|
+
}
|
|
4783
|
+
} catch {
|
|
4784
|
+
} finally {
|
|
4785
|
+
if (currentFetchId === fetchIdRef.current) {
|
|
4786
|
+
isFetchingRef.current = false;
|
|
4787
|
+
setIsRefreshing(false);
|
|
4788
|
+
}
|
|
4789
|
+
}
|
|
4790
|
+
};
|
|
4791
|
+
loadQuote();
|
|
4792
|
+
const interval = setInterval(loadQuote, pollIntervalMs);
|
|
4793
|
+
return () => {
|
|
4794
|
+
clearInterval(interval);
|
|
4795
|
+
++fetchIdRef.current;
|
|
4796
|
+
setIsRefreshing(false);
|
|
4797
|
+
};
|
|
4798
|
+
}, [
|
|
4799
|
+
coinlist,
|
|
4800
|
+
isReady,
|
|
4801
|
+
contractAddress,
|
|
4802
|
+
chain,
|
|
4803
|
+
inputAmount.raw,
|
|
4804
|
+
inputAmount.decimals,
|
|
4805
|
+
inputTokenAddress,
|
|
4806
|
+
outputTokenDecimals,
|
|
4807
|
+
pollIntervalMs,
|
|
4808
|
+
enabled
|
|
4809
|
+
]);
|
|
4810
|
+
return { quote, isLoading, isRefreshing };
|
|
4811
|
+
}
|
|
4812
|
+
|
|
4813
|
+
// src/client/hooks/swap/useSwapTokenBalances.ts
|
|
4814
|
+
var import_react18 = require("react");
|
|
4815
|
+
|
|
4816
|
+
// src/shared/core/blockchain/token-registry.ts
|
|
4817
|
+
var USDC_SYMBOL = StablecoinSymbol("USDC");
|
|
4818
|
+
var USDC = {
|
|
4819
|
+
name: "USD Coin",
|
|
4820
|
+
symbol: USDC_SYMBOL,
|
|
4821
|
+
decimals: AssetDecimals(6)
|
|
4822
|
+
};
|
|
4823
|
+
var USDT_SYMBOL = StablecoinSymbol("USDT");
|
|
4824
|
+
var USDT = {
|
|
4825
|
+
name: "Tether USD",
|
|
4826
|
+
symbol: USDT_SYMBOL,
|
|
4827
|
+
decimals: AssetDecimals(6)
|
|
4828
|
+
};
|
|
4829
|
+
var USDC_ADDRESSES = {
|
|
4830
|
+
ethereum_mainnet: EvmContractAddress(
|
|
4831
|
+
"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
|
|
4832
|
+
),
|
|
4833
|
+
ethereum_sepolia: EvmContractAddress(
|
|
4834
|
+
"0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"
|
|
4835
|
+
)
|
|
4836
|
+
};
|
|
4837
|
+
var USDT_ADDRESSES = {
|
|
4838
|
+
ethereum_mainnet: EvmContractAddress(
|
|
4839
|
+
"0xdac17f958d2ee523a2206206994597c13d831ec7"
|
|
4840
|
+
),
|
|
4841
|
+
ethereum_sepolia: EvmContractAddress(
|
|
4842
|
+
"0x7169D38820dfd117C3FA1f22a697dBA58d90BA06"
|
|
4843
|
+
)
|
|
4844
|
+
};
|
|
4845
|
+
var TOKEN_REGISTRY = {
|
|
4846
|
+
erc20: (symbol) => {
|
|
4847
|
+
switch (symbol) {
|
|
4848
|
+
case "USDC":
|
|
4849
|
+
return USDC;
|
|
4850
|
+
case "USDT":
|
|
4851
|
+
return USDT;
|
|
4852
|
+
default:
|
|
4853
|
+
throw new Error(`Unknown asset symbol: ${symbol}`);
|
|
4854
|
+
}
|
|
4855
|
+
},
|
|
4856
|
+
contractAddress: (symbol, chain) => {
|
|
4857
|
+
switch (symbol) {
|
|
4858
|
+
case "USDC":
|
|
4859
|
+
return USDC_ADDRESSES[chain];
|
|
4860
|
+
case "USDT":
|
|
4861
|
+
return USDT_ADDRESSES[chain];
|
|
4862
|
+
default:
|
|
4863
|
+
throw new Error(`Unknown asset symbol: ${symbol}`);
|
|
4864
|
+
}
|
|
4865
|
+
}
|
|
4866
|
+
};
|
|
4867
|
+
|
|
4868
|
+
// src/client/hooks/swap/useSwapTokenBalances.ts
|
|
4869
|
+
function useSwapTokenBalances(options) {
|
|
4870
|
+
const {
|
|
4871
|
+
address,
|
|
4872
|
+
chain,
|
|
4873
|
+
assets,
|
|
4874
|
+
pollIntervalMs = SWAP_POLL_INTERVAL_MS,
|
|
4875
|
+
enabled
|
|
4876
|
+
} = options;
|
|
4877
|
+
const { coinlist, isReady } = useCoinList();
|
|
4878
|
+
const [balances, setBalances] = (0, import_react18.useState)(/* @__PURE__ */ new Map());
|
|
4879
|
+
const [isLoading, setIsLoading] = (0, import_react18.useState)(true);
|
|
4880
|
+
const fetchIdRef = (0, import_react18.useRef)(0);
|
|
4881
|
+
const isFetchingRef = (0, import_react18.useRef)(false);
|
|
4882
|
+
const assetsKey = assets.join(",");
|
|
4883
|
+
(0, import_react18.useEffect)(() => {
|
|
4884
|
+
if (!isReady) return;
|
|
4885
|
+
if (!enabled) {
|
|
4886
|
+
setIsLoading(false);
|
|
4887
|
+
return;
|
|
4888
|
+
}
|
|
4889
|
+
const symbols = assetsKey.split(",");
|
|
4890
|
+
const currentFetchId = ++fetchIdRef.current;
|
|
4891
|
+
isFetchingRef.current = false;
|
|
4892
|
+
let isFirstFetch = true;
|
|
4893
|
+
async function fetchBalances() {
|
|
4894
|
+
if (isFetchingRef.current) return;
|
|
4895
|
+
isFetchingRef.current = true;
|
|
4896
|
+
if (isFirstFetch) {
|
|
4897
|
+
setIsLoading(true);
|
|
4898
|
+
}
|
|
4899
|
+
const results = await Promise.allSettled(
|
|
4900
|
+
symbols.map(
|
|
4901
|
+
(symbol) => coinlist.erc20.getTokenBalance({
|
|
4902
|
+
tokenAddress: TOKEN_REGISTRY.contractAddress(symbol, chain),
|
|
4903
|
+
owner: address,
|
|
4904
|
+
chain
|
|
4905
|
+
})
|
|
4906
|
+
)
|
|
4907
|
+
);
|
|
4908
|
+
if (currentFetchId !== fetchIdRef.current) return;
|
|
4909
|
+
isFetchingRef.current = false;
|
|
4910
|
+
const next = /* @__PURE__ */ new Map();
|
|
4911
|
+
symbols.forEach((symbol, i) => {
|
|
4912
|
+
const result = results[i];
|
|
4913
|
+
next.set(
|
|
4914
|
+
symbol,
|
|
4915
|
+
result.status === "fulfilled" ? result.value.balance : null
|
|
4916
|
+
);
|
|
4917
|
+
});
|
|
4918
|
+
setBalances(next);
|
|
4919
|
+
setIsLoading(false);
|
|
4920
|
+
isFirstFetch = false;
|
|
4921
|
+
}
|
|
4922
|
+
fetchBalances();
|
|
4923
|
+
const interval = setInterval(fetchBalances, pollIntervalMs);
|
|
4924
|
+
return () => {
|
|
4925
|
+
clearInterval(interval);
|
|
4926
|
+
++fetchIdRef.current;
|
|
4927
|
+
};
|
|
4928
|
+
}, [coinlist, isReady, address, chain, assetsKey, pollIntervalMs, enabled]);
|
|
4929
|
+
return { balances, isLoading };
|
|
4930
|
+
}
|
|
2159
4931
|
|
|
2160
4932
|
// src/client/hooks/useCompleteOAuth.ts
|
|
2161
|
-
var
|
|
4933
|
+
var import_react19 = require("react");
|
|
2162
4934
|
function useCompleteOAuth(options) {
|
|
2163
4935
|
const { coinlist } = useCoinList();
|
|
2164
|
-
const postOAuthCompleteRef = (0,
|
|
2165
|
-
const onFailureRef = (0,
|
|
2166
|
-
const onSuccessRef = (0,
|
|
4936
|
+
const postOAuthCompleteRef = (0, import_react19.useRef)(options.postOAuthComplete);
|
|
4937
|
+
const onFailureRef = (0, import_react19.useRef)(options.onFailure);
|
|
4938
|
+
const onSuccessRef = (0, import_react19.useRef)(options.onSuccess);
|
|
2167
4939
|
postOAuthCompleteRef.current = options.postOAuthComplete;
|
|
2168
4940
|
onFailureRef.current = options.onFailure;
|
|
2169
4941
|
onSuccessRef.current = options.onSuccess;
|
|
2170
|
-
const hasStartedExchangeRef = (0,
|
|
2171
|
-
(0,
|
|
4942
|
+
const hasStartedExchangeRef = (0, import_react19.useRef)(false);
|
|
4943
|
+
(0, import_react19.useEffect)(() => {
|
|
2172
4944
|
if (typeof window === "undefined") return;
|
|
2173
4945
|
const params = new URLSearchParams(window.location.search);
|
|
2174
4946
|
if (!params.has("code") && !params.has("error")) return;
|
|
@@ -2212,19 +4984,19 @@ function useCompleteOAuth(options) {
|
|
|
2212
4984
|
}
|
|
2213
4985
|
|
|
2214
4986
|
// src/client/hooks/useOfferDetails.ts
|
|
2215
|
-
var
|
|
2216
|
-
var
|
|
4987
|
+
var import_react20 = require("react");
|
|
4988
|
+
var LOADING_STATE7 = { type: "LOADING" };
|
|
2217
4989
|
function useOfferDetails(offerId, options = {}) {
|
|
2218
4990
|
const { coinlist, isReady } = useCoinList();
|
|
2219
4991
|
const { data } = options;
|
|
2220
|
-
const [offerDetailsState, setOfferDetailsState] = (0,
|
|
2221
|
-
data !== void 0 ? { type: "CONTENT", offerDetail: data } :
|
|
4992
|
+
const [offerDetailsState, setOfferDetailsState] = (0, import_react20.useState)(
|
|
4993
|
+
data !== void 0 ? { type: "CONTENT", offerDetail: data } : LOADING_STATE7
|
|
2222
4994
|
);
|
|
2223
|
-
(0,
|
|
4995
|
+
(0, import_react20.useEffect)(() => {
|
|
2224
4996
|
let isCancelled = false;
|
|
2225
4997
|
if (!isReady) {
|
|
2226
4998
|
if (data === void 0) {
|
|
2227
|
-
setOfferDetailsState(
|
|
4999
|
+
setOfferDetailsState(LOADING_STATE7);
|
|
2228
5000
|
}
|
|
2229
5001
|
return () => {
|
|
2230
5002
|
isCancelled = true;
|
|
@@ -2235,7 +5007,7 @@ function useOfferDetails(offerId, options = {}) {
|
|
|
2235
5007
|
isCancelled = true;
|
|
2236
5008
|
};
|
|
2237
5009
|
}
|
|
2238
|
-
setOfferDetailsState(
|
|
5010
|
+
setOfferDetailsState(LOADING_STATE7);
|
|
2239
5011
|
coinlist.fetchOfferDetails(offerId).then((offerDetail) => {
|
|
2240
5012
|
if (!isCancelled) {
|
|
2241
5013
|
setOfferDetailsState({ type: "CONTENT", offerDetail });
|
|
@@ -2254,19 +5026,19 @@ function useOfferDetails(offerId, options = {}) {
|
|
|
2254
5026
|
}
|
|
2255
5027
|
|
|
2256
5028
|
// src/client/hooks/useParticipations.ts
|
|
2257
|
-
var
|
|
2258
|
-
var
|
|
5029
|
+
var import_react21 = require("react");
|
|
5030
|
+
var LOADING_STATE8 = { type: "LOADING" };
|
|
2259
5031
|
function useParticipations(offerId, options = {}) {
|
|
2260
5032
|
const { coinlist, isReady } = useCoinList();
|
|
2261
5033
|
const { data } = options;
|
|
2262
|
-
const [participationsState, setParticipationsState] = (0,
|
|
2263
|
-
data !== void 0 ? { type: "CONTENT", participations: data } :
|
|
5034
|
+
const [participationsState, setParticipationsState] = (0, import_react21.useState)(
|
|
5035
|
+
data !== void 0 ? { type: "CONTENT", participations: data } : LOADING_STATE8
|
|
2264
5036
|
);
|
|
2265
|
-
(0,
|
|
5037
|
+
(0, import_react21.useEffect)(() => {
|
|
2266
5038
|
let isCancelled = false;
|
|
2267
5039
|
if (!isReady) {
|
|
2268
5040
|
if (data === void 0) {
|
|
2269
|
-
setParticipationsState(
|
|
5041
|
+
setParticipationsState(LOADING_STATE8);
|
|
2270
5042
|
}
|
|
2271
5043
|
return () => {
|
|
2272
5044
|
isCancelled = true;
|
|
@@ -2277,8 +5049,8 @@ function useParticipations(offerId, options = {}) {
|
|
|
2277
5049
|
isCancelled = true;
|
|
2278
5050
|
};
|
|
2279
5051
|
}
|
|
2280
|
-
setParticipationsState(
|
|
2281
|
-
coinlist.fetchParticipations(offerId).then((participations) => {
|
|
5052
|
+
setParticipationsState(LOADING_STATE8);
|
|
5053
|
+
coinlist.tokenSale.fetchParticipations(offerId).then((participations) => {
|
|
2282
5054
|
if (!isCancelled) {
|
|
2283
5055
|
setParticipationsState({ type: "CONTENT", participations });
|
|
2284
5056
|
}
|
|
@@ -2297,12 +5069,18 @@ function useParticipations(offerId, options = {}) {
|
|
|
2297
5069
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2298
5070
|
0 && (module.exports = {
|
|
2299
5071
|
ChecklistStatus,
|
|
5072
|
+
ClientSwapNamespaceImpl,
|
|
5073
|
+
ClientTokenSaleNamespaceImpl,
|
|
2300
5074
|
CoinListClientInitializationError,
|
|
2301
5075
|
CoinListContext,
|
|
2302
5076
|
CoinListContextProvider,
|
|
2303
5077
|
CoinListProvider,
|
|
2304
5078
|
CoinListSignInCard,
|
|
2305
5079
|
CoinListStyleScope,
|
|
5080
|
+
ConnectWalletModal,
|
|
5081
|
+
ConnectedWalletList,
|
|
5082
|
+
IdentityVerification,
|
|
5083
|
+
KycToken,
|
|
2306
5084
|
OAUTH_CODE_VERIFIER_KEY,
|
|
2307
5085
|
OAUTH_STATE_KEY,
|
|
2308
5086
|
OfferCard,
|
|
@@ -2313,12 +5091,25 @@ function useParticipations(offerId, options = {}) {
|
|
|
2313
5091
|
RequirementStatus,
|
|
2314
5092
|
RequirementVariant,
|
|
2315
5093
|
RequirementsChecklist,
|
|
5094
|
+
TaxDocumentModal,
|
|
5095
|
+
authorizeWallet,
|
|
5096
|
+
classifyWalletError,
|
|
5097
|
+
connectExternalWalletFlow,
|
|
2316
5098
|
createCoinListClient,
|
|
5099
|
+
executeSwap,
|
|
5100
|
+
executeTokenSale,
|
|
2317
5101
|
useCoinList,
|
|
2318
5102
|
useCompleteOAuth,
|
|
5103
|
+
useConnectWallet,
|
|
5104
|
+
useKycToken,
|
|
2319
5105
|
useOfferDetails,
|
|
2320
5106
|
useOffers,
|
|
5107
|
+
useOptionAddresses,
|
|
2321
5108
|
useParticipations,
|
|
2322
|
-
useRequirements
|
|
5109
|
+
useRequirements,
|
|
5110
|
+
useSwapOutputToken,
|
|
5111
|
+
useSwapQuote,
|
|
5112
|
+
useSwapTokenBalances,
|
|
5113
|
+
useTaxDocument
|
|
2323
5114
|
});
|
|
2324
5115
|
//# sourceMappingURL=index.cjs.map
|