@coinlist-co/react 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/chunk-CRACFEJ4.js +17 -0
  2. package/dist/chunk-CRACFEJ4.js.map +1 -0
  3. package/dist/{chunk-GRVV7NLV.js → chunk-N3WBC2VS.js} +218 -28
  4. package/dist/chunk-N3WBC2VS.js.map +1 -0
  5. package/dist/chunk-V6WO67RO.js +311 -0
  6. package/dist/chunk-V6WO67RO.js.map +1 -0
  7. package/dist/client/index.cjs +1393 -372
  8. package/dist/client/index.cjs.map +1 -1
  9. package/dist/client/index.d.cts +526 -10
  10. package/dist/client/index.d.ts +526 -10
  11. package/dist/client/index.js +1464 -88
  12. package/dist/client/index.js.map +1 -1
  13. package/dist/requirement-BEO42QOr.d.cts +387 -0
  14. package/dist/requirement-BEO42QOr.d.ts +387 -0
  15. package/dist/server/index.cjs +459 -36
  16. package/dist/server/index.cjs.map +1 -1
  17. package/dist/server/index.d.cts +56 -4
  18. package/dist/server/index.d.ts +56 -4
  19. package/dist/server/index.js +69 -37
  20. package/dist/server/index.js.map +1 -1
  21. package/dist/shared/index.cjs +375 -0
  22. package/dist/shared/index.cjs.map +1 -0
  23. package/dist/shared/index.d.cts +35 -0
  24. package/dist/shared/index.d.ts +35 -0
  25. package/dist/{client/core → shared}/index.js +38 -19
  26. package/dist/shared/index.js.map +1 -0
  27. package/package.json +7 -22
  28. package/dist/RequirementItem-BpkJQep8.d.ts +0 -37
  29. package/dist/RequirementItem-BvwsFu9e.d.cts +0 -37
  30. package/dist/chunk-GRVV7NLV.js.map +0 -1
  31. package/dist/chunk-IADBIDY6.js +0 -76
  32. package/dist/chunk-IADBIDY6.js.map +0 -1
  33. package/dist/chunk-IDCROXPS.js +0 -412
  34. package/dist/chunk-IDCROXPS.js.map +0 -1
  35. package/dist/chunk-P4DTIPEX.js +0 -623
  36. package/dist/chunk-P4DTIPEX.js.map +0 -1
  37. package/dist/chunk-V5M7SA3C.js +0 -161
  38. package/dist/chunk-V5M7SA3C.js.map +0 -1
  39. package/dist/chunk-YJQMJFA7.js +0 -16
  40. package/dist/chunk-YJQMJFA7.js.map +0 -1
  41. package/dist/client/components/index.cjs +0 -1107
  42. package/dist/client/components/index.cjs.map +0 -1
  43. package/dist/client/components/index.d.cts +0 -121
  44. package/dist/client/components/index.d.ts +0 -121
  45. package/dist/client/components/index.js +0 -586
  46. package/dist/client/components/index.js.map +0 -1
  47. package/dist/client/core/index.cjs +0 -961
  48. package/dist/client/core/index.cjs.map +0 -1
  49. package/dist/client/core/index.d.cts +0 -23
  50. package/dist/client/core/index.d.ts +0 -23
  51. package/dist/client/core/index.js.map +0 -1
  52. package/dist/client/hooks/index.cjs +0 -233
  53. package/dist/client/hooks/index.cjs.map +0 -1
  54. package/dist/client/hooks/index.d.cts +0 -33
  55. package/dist/client/hooks/index.d.ts +0 -33
  56. package/dist/client/hooks/index.js +0 -19
  57. package/dist/client/hooks/index.js.map +0 -1
  58. package/dist/coinlist-client-B_dJkbwB.d.ts +0 -283
  59. package/dist/coinlist-client-DBKa6j3f.d.cts +0 -283
  60. package/dist/newtype-yKTvFdg_.d.cts +0 -6
  61. package/dist/newtype-yKTvFdg_.d.ts +0 -6
  62. package/dist/oauth-session-DgItaMKN.d.cts +0 -56
  63. package/dist/oauth-session-DnKDI5ou.d.ts +0 -56
  64. package/dist/requirement-CxbdY8l4.d.cts +0 -202
  65. package/dist/requirement-fJsQ3f9_.d.ts +0 -202
  66. package/dist/useCoinListOffers-C5lBlzcC.d.ts +0 -27
  67. package/dist/useCoinListOffers-CguwXaCX.d.cts +0 -27
  68. package/dist/useCoinListRequirements-BECx1cIw.d.ts +0 -31
  69. package/dist/useCoinListRequirements-CX2gV9gJ.d.cts +0 -31
  70. package/dist/useCompleteCoinListOAuth-BRhAqD4_.d.cts +0 -55
  71. package/dist/useCompleteCoinListOAuth-DEZpHjd6.d.ts +0 -55
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"sources":["../../src/client/index.ts","../../src/client/CoinListProvider.tsx","../../src/client/core/api/middleware/device-id.ts","../../src/client/core/api/middleware/user-agent.ts","../../src/client/core/api/api-client.ts","../../src/client/core/coinlist-client.ts","../../src/client/components/design-system/AlertBanner.tsx","../../src/client/components/design-system/tokens/typography.ts","../../src/client/components/design-system/utils.ts","../../src/client/components/design-system/CloseButton.tsx","../../src/client/components/design-system/logos/CoinListWordmark.tsx","../../src/client/components/design-system/PoweredByCoinList.tsx","../../src/client/components/design-system/ClButton.tsx","../../src/client/components/design-system/logos/CoinListLogomark.tsx","../../src/client/components/oauth/CoinListSignInButton.tsx","../../src/client/hooks/useCoinList.ts","../../src/client/components/oauth/CoinListSignInCard.tsx","../../src/client/components/offers/OfferCard.tsx","../../src/client/hooks/useOffers.ts","../../src/client/components/offers/OffersGrid.tsx","../../src/client/components/requirements/RequirementItem.tsx","../../src/client/components/design-system/StepStatusIcon.tsx","../../src/client/components/requirements/RequirementsChecklist.tsx","../../src/client/hooks/useRequirements.ts","../../src/client/hooks/useCompleteOAuth.ts","../../src/client/hooks/useOfferDetails.ts","../../src/client/hooks/useParticipations.ts"],"sourcesContent":["import '@/client/styles.css';\n\n// Provider\nexport * from '@/client/CoinListProvider';\n// Components\nexport * from '@/client/components/oauth/CoinListSignInCard';\nexport {\n OfferCard,\n OfferCardUi,\n type Props as OfferCardProps,\n} from '@/client/components/offers/OfferCard';\nexport * from '@/client/components/offers/OffersGrid';\nexport * from '@/client/components/requirements/RequirementItem';\nexport * from '@/client/components/requirements/RequirementsChecklist';\n// Core client\nexport * from '@/client/core/coinlist-client';\nexport * from '@/client/core/types/client-types';\n// Hooks\nexport * from '@/client/hooks/useCoinList';\nexport * from '@/client/hooks/useCompleteOAuth';\nexport * from '@/client/hooks/useOfferDetails';\nexport * from '@/client/hooks/useOffers';\nexport * from '@/client/hooks/useParticipations';\nexport * from '@/client/hooks/useRequirements';\n","/**\n * Global CoinList initialization for React apps.\n * Wrap your app once at the root; use useCoinList() anywhere below.\n */\n\nimport {\n createContext,\n type ReactNode,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n type ClientConfig,\n type CoinListClient,\n createCoinListClient,\n} from '@/client/core/coinlist-client';\n\nexport type CoinListContextValue = {\n coinlist: CoinListClient;\n isReady: boolean;\n};\n\nexport const CoinListContext = createContext<CoinListContextValue | null>(null);\n\nexport type CoinListProviderProps = {\n config: ClientConfig;\n children: ReactNode;\n};\n\n/**\n * Provide CoinList (api + config) to the tree. Initialize once at app root with your config.\n */\nexport function CoinListProvider({ config, children }: CoinListProviderProps) {\n const [isReady, setIsReady] = useState(false);\n const coinlist = useMemo(() => createCoinListClient(config), [config]);\n\n useEffect(() => {\n let isCancelled = false;\n if (coinlist.getAuthState() === 'unknown') {\n coinlist\n .init()\n .then(() => {\n if (!isCancelled) {\n setIsReady(true);\n }\n })\n .catch(() => {\n if (!isCancelled) {\n setIsReady(true);\n }\n });\n } else {\n setIsReady(true);\n }\n\n return () => {\n isCancelled = true;\n };\n }, [coinlist]);\n\n const value = useMemo(() => ({ coinlist, isReady }), [coinlist, isReady]);\n\n return (\n <CoinListContext.Provider value={value}>\n {children}\n </CoinListContext.Provider>\n );\n}\n","'use client';\n\nimport { getUUIDv4 } from '@/shared/utils';\n\nconst DEVICE_ID_KEY = 'coinlist.device_id';\n\n/**\n * Get or create a device ID stored in localStorage.\n * Uses a crypto UUID that persists across sessions.\n */\nexport function getDeviceId(): string {\n let deviceId = localStorage.getItem(DEVICE_ID_KEY);\n\n if (!deviceId) {\n deviceId = getUUIDv4();\n localStorage.setItem(DEVICE_ID_KEY, deviceId);\n }\n\n return deviceId;\n}\n\n/**\n * Clear the stored device ID (useful for testing or logout).\n */\nexport function clearDeviceId(): void {\n localStorage.removeItem(DEVICE_ID_KEY);\n}\n","'use client';\n\nimport { getDeviceId } from '@/client/core/api/middleware/device-id';\nimport { HEADER_USER_AGENT } from '@/shared/api/frontline/config';\nimport type { HttpRequest } from '@/shared/api/http';\nimport { Attributes } from '@/shared/api/http-attributes';\nimport type { BeforeRequestMiddleware } from '@/shared/api/http-client';\n\nexport const userAgentMiddleware: BeforeRequestMiddleware = async (\n request: HttpRequest\n): Promise<HttpRequest> => {\n if (!Attributes.needUserAgent(request.attributes)) {\n return request;\n }\n\n const userAgent = generateUserAgent();\n return {\n ...request,\n headers: {\n ...(request.headers ?? {}),\n [HEADER_USER_AGENT]: userAgent,\n },\n };\n};\n\n// Generate User-Agent in the required format for Frontline API\n// Format: <app-info> (<device-info>; DevicePlatform <device-platform>; DeviceAppID <device-app-id>; DeviceID <device-id>)\nfunction generateUserAgent(): string {\n const appInfo = `CoinList/1.0`;\n const deviceInfo = 'Web Browser';\n const devicePlatform = 'DevicePlatform web'; // Must be 'web' for validation\n\n const deviceAppId = 'DeviceAppID co.coinlist.sdk'; // SDK app ID\n\n const deviceId = getDeviceId();\n const finalDeviceId = `DeviceID ${deviceId}`;\n\n return `${appInfo} (${deviceInfo}; ${devicePlatform}; ${deviceAppId}; ${finalDeviceId})`;\n}\n","'use client';\n\nimport { userAgentMiddleware } from '@/client/core/api/middleware/user-agent';\nimport { AuthenticatedApiClient } from '@/shared/api/authenticated-api-client';\nimport type { HttpClientConfig, HttpRequest } from '@/shared/api/http';\nimport type { OAuthAccessToken } from '@/shared/types/oauth-session';\n\nexport class ApiClient {\n private readonly client: AuthenticatedApiClient;\n\n constructor(\n config: HttpClientConfig,\n fetchAccessToken: (refresh: boolean) => Promise<OAuthAccessToken | null>\n ) {\n this.client = new AuthenticatedApiClient(config, fetchAccessToken, [\n userAgentMiddleware,\n ]);\n }\n\n async send<TResponse>(request: HttpRequest): Promise<TResponse> {\n return this.client.send<TResponse>(request);\n }\n}\n","'use client';\n\nimport { ApiClient } from '@/client/core/api/api-client';\nimport type {\n AuthState,\n OauthClientResult,\n} from '@/client/core/types/client-types';\nimport {\n API_VERSION,\n COINLIST_BASE_URL,\n OAUTH_PAGE_PATH,\n PUBLIC_API_BASE_URL,\n SUPPORT_NEW_TICKET_URL,\n VERIFY_IDENTITY_ACCREDITATION_PATH,\n VERIFY_IDENTITY_PATH,\n VERIFY_IDENTITY_PROOF_OF_ADDRESS_PATH,\n VERIFY_IDENTITY_SOURCE_OF_FUNDS_PATH,\n VERIFY_IDENTITY_VERIFIED_PATH,\n WALLET_PATH,\n} from '@/shared/api/frontline/config';\nimport * as offersApi from '@/shared/api/frontline/offers';\nimport * as participationsApi from '@/shared/api/frontline/participations';\nimport * as requirementsApi from '@/shared/api/frontline/requirements';\nimport type {\n PaginatedResponse,\n PaginationParams,\n} from '@/shared/api/pagination';\nimport type { Config } from '@/shared/types/config';\nimport { NotAuthenticatedError } from '@/shared/types/errors';\nimport { AuthorizationCode, CodeVerifier } from '@/shared/types/oauth';\nimport type { OAuthAccessToken } from '@/shared/types/oauth-session';\nimport type { Offer, OfferId } from '@/shared/types/offer';\nimport type { OfferDetail, OfferOptionId } from '@/shared/types/offer-detail';\nimport type {\n CreateParticipationParams,\n Participation,\n ParticipationId,\n ParticipationsPaginationParams,\n} from '@/shared/types/participation';\nimport type {\n Requirement,\n RequirementStatusInfo,\n} from '@/shared/types/requirement';\nimport {\n arrayBufferToBase64Url,\n generateSecureRandomBase64Url,\n sha256,\n} from '@/shared/utils';\n\n/** Session storage keys for OAuth PKCE (used by startOauth and completeOauth). */\nexport const OAUTH_STATE_KEY = 'coinlist.oauth_state';\nexport const OAUTH_CODE_VERIFIER_KEY = 'coinlist.oauth_code_verifier';\n\nexport interface ClientConfig extends Config {\n /**\n * The SDK user must provide this function. It is responsible for fetching a\n * valid {@link OAuthAccessToken}, or **null** for logged-out users. If your\n * backend is in TypeScript, it is recommended to use\n * {@link CoinListServer#accessToken} from `@/server/coinlist.server`.\n */\n getAccessToken: () => Promise<OAuthAccessToken | null>;\n /**\n * Recommended to leave undefined. Used to change the CoinList environment;\n * default is production.\n */\n coinlistBaseUrl?: string;\n}\n\nexport interface CoinListClient {\n /**\n * Calls the provided {@link ClientConfig.getAccessToken} lambda to determine\n * the user's {@link AuthState}. This is called automatically by {@link CoinListProvider};\n * you typically do not need to call it yourself unless you are using the client\n * outside of the provider.\n */\n init(): Promise<AuthState>;\n /**\n * Returns the current auth state: `'logged-in'`, `'logged-out'`, or `'unknown'`.\n * Returns **unknown** until {@link CoinListClient.init} has completed. It is\n * recommended to use the `const { isReady, coinlist } = useCoinList()` hook to know when\n * the SDK has initialized, or to manually await {@link CoinListClient.init}\n * before relying on this value.\n */\n getAuthState(): AuthState;\n /**\n * Starts the OAuth flow with PKCE. Generates a random `state` and `code_verifier`,\n * stores them in sessionStorage (for validation in {@link CoinListClient.completeOAuth}\n * on redirect), then redirects the user to the CoinList authorization page. After\n * the user authorizes, they are sent back to your application's redirect URI; call\n * {@link CoinListClient.completeOAuth} on that page to finish the flow.\n */\n startOAuth(): Promise<void>;\n /**\n * Completes the OAuth flow on the FE with PKCE and state validation. Parses the\n * redirect URL (state, code) and validates them against sessionStorage\n * (state, code_verifier). The state check protects against CSRF (cross-site\n * request forgery). Call this on the frontend page the user is redirected\n * to after authorizing.\n *\n * On `ok`: Call your backend to exchange the short-lived `authorizationCode`\n * (and the returned `codeVerifier`) for a long-lived session. If your backend\n * is in TypeScript, you can use {@link CoinListServer#completeOAuth} from\n * `@/server/coinlist.server` (CoinListServer) to perform that exchange.\n *\n * On `error`: `reason` is an {@link OauthClientErrorReason} (e.g. `'missing_state'`, `'invalid_state'`) so you can switch on it and surface a message to the user.\n */\n completeOAuth(): OauthClientResult;\n /**\n * Clears the in-memory access token. Note: you need to manually\n * also logout on the backend via CoinListServer#logout to clear the session cookie.\n */\n logout(): void;\n\n /**\n * Fetches all offers by iterating through every paginated response.\n *\n * This method must be called only when the user's {@link AuthState} is\n * `'logged-in'`. If the user is not authenticated, it throws\n * {@link NotAuthenticatedError}.\n */\n fetchOffers(): Promise<Offer[]>;\n /**\n * Fetches a single page of offers.\n *\n * This method must be called only when the user's {@link AuthState} is\n * `'logged-in'`. If the user is not authenticated, it throws\n * {@link NotAuthenticatedError}.\n */\n fetchOffersPage(params: PaginationParams): Promise<PaginatedResponse<Offer>>;\n /**\n * Fetches details for a given offer by its id.\n *\n * This method must be called only when the user's {@link AuthState} is\n * `'logged-in'`. If the user is not authenticated, it throws\n * {@link NotAuthenticatedError}.\n */\n fetchOfferDetails(id: OfferId): Promise<OfferDetail>;\n /**\n * Fetches all participations by iterating through every paginated response.\n *\n * This method must be called only when the user's {@link AuthState} is\n * `'logged-in'`. If the user is not authenticated, it throws\n * {@link NotAuthenticatedError}.\n */\n fetchParticipations(offerId?: OfferId): Promise<Participation[]>;\n /**\n * Fetches a single page of participations, optionally filtered by offer.\n *\n * This method must be called only when the user's {@link AuthState} is\n * `'logged-in'`. If the user is not authenticated, it throws\n * {@link NotAuthenticatedError}.\n */\n fetchParticipationsPage(\n params: ParticipationsPaginationParams\n ): Promise<PaginatedResponse<Participation>>;\n /**\n * Fetches a participation by id.\n *\n * This method must be called only when the user's {@link AuthState} is\n * `'logged-in'`. If the user is not authenticated, it throws\n * {@link NotAuthenticatedError}.\n */\n fetchParticipation(id: ParticipationId): Promise<Participation>;\n /**\n * Creates a participation.\n *\n * This method must be called only when the user's {@link AuthState} is\n * `'logged-in'`. If the user is not authenticated, it throws\n * {@link NotAuthenticatedError}.\n */\n createParticipation(\n params: CreateParticipationParams\n ): Promise<Participation>;\n /**\n * Fetches the requirements for all options of a given offer, grouped by option ID.\n *\n * This method must be called only when the user's {@link AuthState} is\n * `'logged-in'`. If the user is not authenticated, it throws\n * {@link NotAuthenticatedError}.\n */\n fetchOfferRequirements(\n offerId: OfferId\n ): Promise<Record<OfferOptionId, Requirement[]>>;\n /**\n * Fetches the user's requirement statuses for a given offer.\n *\n * This method must be called only when the user's {@link AuthState} is\n * `'logged-in'`. If the user is not authenticated, it throws\n * {@link NotAuthenticatedError}.\n */\n fetchRequirementStatuses(offerId: OfferId): Promise<RequirementStatusInfo[]>;\n /**\n * Opens the CoinList page for completing a given requirement in a new tab.\n * For `jurisdiction` requirements there is no CTA, so this is a no-op.\n */\n handleRequirement(requirement: Requirement): void;\n /**\n * Opens the CoinList support ticket page in a new tab.\n */\n contactSupport(): void;\n}\n\nclass CoinListClientImpl implements CoinListClient {\n /** Cached access token: undefined = loading, null = no token, AccessToken = logged in */\n private _accessToken: OAuthAccessToken | null | undefined = undefined;\n private readonly api: ApiClient;\n\n constructor(readonly _config: ClientConfig) {\n this.api = new ApiClient(\n {\n baseUrl: _config.baseUrl || PUBLIC_API_BASE_URL,\n xApiVersion: API_VERSION,\n },\n this.fetchAccessToken.bind(this)\n );\n }\n\n async init(): Promise<AuthState> {\n await this.fetchAccessToken(true);\n return this.getAuthState();\n }\n\n async fetchAccessToken(refresh: boolean): Promise<OAuthAccessToken | null> {\n if (!refresh && this._accessToken !== undefined) return this._accessToken;\n\n try {\n const accessToken = await this._config.getAccessToken();\n this._accessToken = accessToken;\n return accessToken;\n } catch (_) {\n this._accessToken = null;\n return null;\n }\n }\n\n getAuthState(): AuthState {\n if (this._accessToken === undefined) {\n return 'unknown';\n }\n return this._accessToken !== null ? 'logged-in' : 'logged-out';\n }\n\n async startOAuth(): Promise<void> {\n const state = generateSecureRandomBase64Url(32);\n const codeVerifier = generateSecureRandomBase64Url(32);\n\n const codeChallengeRaw = await sha256(codeVerifier);\n const codeChallenge = arrayBufferToBase64Url(codeChallengeRaw, false);\n\n sessionStorage.setItem(OAUTH_STATE_KEY, state);\n sessionStorage.setItem(OAUTH_CODE_VERIFIER_KEY, codeVerifier);\n\n const params = new URLSearchParams({\n client_id: this._config.clientId,\n response_type: 'code',\n redirect_uri: this._config.redirectUri,\n code_challenge: codeChallenge,\n code_challenge_method: 'S256',\n state,\n });\n const baseUrl = this._config.coinlistBaseUrl ?? COINLIST_BASE_URL;\n const url = `${baseUrl}${OAUTH_PAGE_PATH}?${params.toString()}`;\n window.location.href = url;\n }\n\n completeOAuth(): OauthClientResult {\n const params = new URLSearchParams(window.location.search);\n\n const coinlistError = params.get('error');\n if (coinlistError) {\n return { type: 'error', reason: 'user_canceled' };\n }\n\n const stateParam = params.get('state');\n if (!stateParam) {\n return { type: 'error', reason: 'missing_state' };\n }\n const storedState = sessionStorage.getItem(OAUTH_STATE_KEY);\n if (storedState === null || storedState !== stateParam) {\n return { type: 'error', reason: 'invalid_state' };\n }\n\n const codeParam = params.get('code');\n if (!codeParam) {\n return { type: 'error', reason: 'missing_code' };\n }\n\n const codeVerifierValue = sessionStorage.getItem(OAUTH_CODE_VERIFIER_KEY);\n if (!codeVerifierValue) {\n return { type: 'error', reason: 'missing_code_verifier' };\n }\n\n return {\n type: 'ok',\n code: AuthorizationCode(codeParam),\n codeVerifier: CodeVerifier(codeVerifierValue),\n };\n }\n\n logout(): void {\n this._accessToken = null;\n }\n\n async fetchOffers(): Promise<Offer[]> {\n this.ensureAuthenticated();\n return offersApi.fetchOffers(this.api);\n }\n\n async fetchOffersPage(\n params: PaginationParams\n ): Promise<PaginatedResponse<Offer>> {\n this.ensureAuthenticated();\n return offersApi.fetchOffersPage(this.api, params);\n }\n\n async fetchOfferDetails(id: OfferId): Promise<OfferDetail> {\n this.ensureAuthenticated();\n return offersApi.fetchOfferDetails(this.api, id);\n }\n\n async fetchParticipations(offerId?: OfferId): Promise<Participation[]> {\n this.ensureAuthenticated();\n return participationsApi.fetchParticipations(this.api, offerId);\n }\n\n async fetchParticipationsPage(\n params: ParticipationsPaginationParams\n ): Promise<PaginatedResponse<Participation>> {\n this.ensureAuthenticated();\n return participationsApi.fetchParticipationsPage(this.api, params);\n }\n\n async fetchParticipation(id: ParticipationId): Promise<Participation> {\n this.ensureAuthenticated();\n return participationsApi.fetchParticipation(this.api, id);\n }\n\n async createParticipation(\n params: CreateParticipationParams\n ): Promise<Participation> {\n this.ensureAuthenticated();\n return participationsApi.createParticipation(this.api, params);\n }\n\n async fetchOfferRequirements(\n offerId: OfferId\n ): Promise<Record<OfferOptionId, Requirement[]>> {\n this.ensureAuthenticated();\n return requirementsApi.fetchOfferRequirements(this.api, offerId);\n }\n\n async fetchRequirementStatuses(\n offerId: OfferId\n ): Promise<RequirementStatusInfo[]> {\n this.ensureAuthenticated();\n return requirementsApi.fetchRequirementStatuses(this.api, offerId);\n }\n\n handleRequirement(requirement: Requirement): void {\n const baseUrl = this._config.coinlistBaseUrl ?? COINLIST_BASE_URL;\n let path: string | null;\n switch (requirement.type) {\n case 'kyc_approved':\n path = VERIFY_IDENTITY_PATH;\n break;\n case 'identity_verified':\n path = VERIFY_IDENTITY_VERIFIED_PATH;\n break;\n case 'proof_of_address':\n path = VERIFY_IDENTITY_PROOF_OF_ADDRESS_PATH;\n break;\n case 'source_of_funds':\n path = VERIFY_IDENTITY_SOURCE_OF_FUNDS_PATH;\n break;\n case 'accreditation':\n path = VERIFY_IDENTITY_ACCREDITATION_PATH;\n break;\n case 'external_wallet':\n case 'whitelisted_wallet':\n path = WALLET_PATH;\n break;\n case 'jurisdiction':\n path = null;\n break;\n default: {\n const _exhaustive: never = requirement.type;\n return;\n }\n }\n if (path === null) return;\n openInNewTab(new URL(path, baseUrl).toString());\n }\n\n contactSupport(): void {\n openInNewTab(SUPPORT_NEW_TICKET_URL);\n }\n\n private ensureAuthenticated() {\n if (this.getAuthState() !== 'logged-in') {\n throw new NotAuthenticatedError();\n }\n }\n}\n\nfunction openInNewTab(url: string): void {\n window.open(url, '_blank', 'noopener,noreferrer');\n}\n\nexport function createCoinListClient(config: ClientConfig): CoinListClient {\n return new CoinListClientImpl(config);\n}\n","import type { LucideIcon } from 'lucide-react';\nimport { CircleCheck, Info } from 'lucide-react';\nimport type { ReactNode } from 'react';\nimport { typeClasses } from '@/client/components/design-system/tokens/typography';\nimport { cn } from '@/client/components/design-system/utils';\n\nexport type AlertBannerVariant = 'info' | 'success' | 'warning' | 'error';\n\ninterface AlertBannerProps {\n variant: AlertBannerVariant;\n content: ReactNode;\n icon?: boolean;\n className?: string;\n}\n\nconst variantConfig: Record<\n AlertBannerVariant,\n { container: string; text: string; Icon: LucideIcon }\n> = {\n info: {\n container: 'bg-surface border-border',\n text: 'text-text-secondary',\n Icon: Info,\n },\n success: {\n container: 'bg-success-subtle border-success-border',\n text: 'text-success',\n Icon: CircleCheck,\n },\n warning: {\n container: 'bg-warning-subtle border-warning-border',\n text: 'text-warning',\n Icon: Info,\n },\n error: {\n container: 'bg-error-subtle border-error-border',\n text: 'text-error',\n Icon: Info,\n },\n};\n\nexport function AlertBanner({\n variant,\n content,\n icon = false,\n className,\n}: AlertBannerProps) {\n const { container, text, Icon } = variantConfig[variant];\n\n return (\n <div\n className={cn(\n 'flex items-center rounded-btn border p-3',\n icon && 'gap-2',\n container,\n className\n )}\n >\n {icon && (\n <Icon className={cn('h-4 w-4 shrink-0', text)} aria-hidden=\"true\" />\n )}\n <p className={cn(typeClasses.subhead, text)}>{content}</p>\n </div>\n );\n}\n","/**\n * CoinList Sale SDK — Typography Tokens\n *\n * Scale based on design system.\n * fontSize in px, lineHeight as percentage string, fontWeight as number.\n * Use the cn() Tailwind classes where possible, these values\n * are for programmatic access or non-Tailwind contexts.\n */\n\nexport const typeScale = {\n hero: {\n fontSize: 64,\n lineHeight: '110%',\n fontWeight: 600,\n },\n display: {\n fontSize: 48,\n lineHeight: '110%',\n fontWeight: 600,\n },\n h1: {\n fontSize: 36,\n lineHeight: '120%',\n fontWeight: 600,\n },\n h2: {\n fontSize: 28,\n lineHeight: '125%',\n fontWeight: 600,\n },\n h3: {\n fontSize: 22,\n lineHeight: '130%',\n fontWeight: 600,\n },\n h4: {\n fontSize: 18,\n lineHeight: '135%',\n fontWeight: 500,\n },\n body: {\n fontSize: 16,\n lineHeight: '150%',\n fontWeight: 400,\n },\n subhead: {\n fontSize: 14,\n lineHeight: '150%',\n fontWeight: 400,\n },\n caption: {\n fontSize: 12,\n lineHeight: '140%',\n fontWeight: 400,\n },\n label: {\n fontSize: 14,\n lineHeight: '140%',\n fontWeight: 500,\n },\n data: {\n fontSize: 14,\n lineHeight: '140%',\n fontWeight: 400,\n },\n} as const;\n\n/**\n * Tailwind class mappings for each type style.\n * Use these className strings directly in components.\n *\n * e.g. <h1 className={typeClasses.h1}>Hello</h1>\n */\nexport const typeClasses = {\n hero: 'text-[64px] leading-[110%] font-semibold',\n display: 'text-[48px] leading-[110%] font-semibold',\n h1: 'text-[36px] leading-[120%] font-semibold',\n h2: 'text-[28px] leading-[125%] font-semibold',\n h3: 'text-[22px] leading-[130%] font-semibold',\n h4: 'text-[18px] leading-[135%] font-medium',\n body: 'text-[16px] leading-[150%] font-normal',\n subhead: 'text-[14px] leading-[150%] font-normal',\n caption: 'text-[12px] leading-[140%] font-normal',\n label: 'text-[14px] leading-[140%] font-medium',\n data: 'text-[14px] leading-[140%] font-normal',\n} as const;\n\nexport type TypeScale = keyof typeof typeScale;\n","import { type ClassValue, clsx } from 'clsx';\n\n/**\n * Utility function to merge class names using clsx.\n */\nexport function cn(...inputs: ClassValue[]) {\n return clsx(inputs);\n}\n","'use client';\n\nimport { X } from 'lucide-react';\nimport { cn } from '@/client/components/design-system/utils';\n\ninterface CloseButtonProps {\n onClick: () => void;\n 'aria-label'?: string;\n className?: string;\n}\n\nexport function CloseButton({\n onClick,\n 'aria-label': ariaLabel = 'Close',\n className,\n}: CloseButtonProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n aria-label={ariaLabel}\n className={cn(\n 'cursor-pointer rounded-full p-1.5 text-text-secondary transition-colors hover:bg-surface hover:text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-gray-400 focus-visible:ring-offset-2',\n className\n )}\n >\n <X className=\"h-5 w-5\" />\n </button>\n );\n}\n","import type { SVGProps } from 'react';\n\nexport function CoinListWordmark(props: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width=\"638\"\n height=\"125\"\n viewBox=\"0 0 638 125\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n {...props}\n >\n <path\n d=\"M68.7724 123.966C74.8226 124.172 80.7696 123.519 86.5104 121.799C97.4076 118.531 106.551 112.58 113.942 103.947C113.942 103.947 113.942 103.947 113.908 103.912C111.879 102.193 109.851 100.507 107.857 98.8218L105.829 97.1363C105.451 96.8268 105.107 96.5172 104.729 96.2076C103.939 95.5197 103.148 94.8662 102.323 94.2126C95.3107 98.8562 87.6104 101.539 79.1196 101.883C74.8569 102.055 70.6287 101.642 66.5036 100.507C59.5252 98.6154 53.2688 95.1757 48.2499 89.7755C39.1059 79.938 35.8745 68.1743 38.2465 55.0348C39.7246 46.9172 43.4373 40.0723 49.1093 34.5C47.9061 34.7408 46.703 35.016 45.5342 35.3943C36.5277 38.2148 29.6181 43.6839 24.6336 51.6639C20.6803 58.0273 18.5834 64.9411 18.3428 72.4739C18.2053 76.7047 18.4803 80.7979 19.4428 84.7879C22.5023 97.2395 29.3087 107.043 39.6903 114.335H39.7934V114.403C40.1372 114.644 40.4809 114.919 40.8247 115.16C49.2812 120.801 58.5971 123.691 68.7724 124.035V123.966Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M72.2101 89.052C68.1881 90.8406 64.0286 91.8725 59.6973 92.2165C64.9912 95.209 70.8007 96.688 77.1259 96.8256C79.1885 96.86 81.251 96.6536 83.4167 96.3097C88.745 95.4841 93.6951 93.5579 98.3015 90.7374C93.9358 87.057 89.6044 83.4109 85.2386 79.7305C81.526 83.6861 77.1946 86.8506 72.2101 89.052Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M66.9848 0.241609C66.4348 0.276006 65.8848 0.344799 65.3691 0.413592C70.663 1.4111 75.7851 3.13093 80.6321 5.71068C90.0511 10.7326 97.3732 17.9215 102.289 27.4494L104.936 25.1448C107.652 22.7714 110.368 20.3981 113.084 18.0247C106.655 11.1797 99.092 6.15784 90.223 3.06214C84.3103 0.998336 78.2601 -0.0335643 72.0381 0.000832319C70.388 0.000832319 68.7036 0.138419 66.9848 0.241609Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M25.4242 107.871C17.4833 97.9988 13.1519 86.7167 13.2207 73.818C13.2207 67.317 14.5614 61.0568 17.1396 55.1062C20.9553 46.2662 26.9711 39.1805 35.4276 34.2962C43.3685 29.687 51.9968 27.8984 61.1752 29.2743C70.5943 30.7189 78.3976 35.2249 84.6541 42.2762C84.6541 42.2762 84.8603 42.5514 84.9634 42.6546C85.8916 41.8291 86.8541 41.0035 87.7823 40.178L88.9167 39.1805C89.8792 38.355 90.8417 37.4951 91.8043 36.6696C94.0043 34.7434 96.17 32.8515 98.3357 30.9253C94.1075 22.223 87.7479 15.55 79.3258 10.8377C69.3911 5.26541 58.7002 3.54557 47.3904 5.02463C41.7528 5.78136 36.3557 7.50119 31.1993 10.0465C13.702 18.7145 1.08597 36.532 0.0546833 58.4771C-0.117196 62.0887 0.123436 65.7348 0.673452 69.3464C2.04849 78.3239 5.34859 86.4759 10.6425 93.8368C14.7676 99.5123 19.6834 104.19 25.3898 107.871H25.4242Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M366.034 58.1654C366.034 46.8145 375.178 37.665 386.419 37.665C397.66 37.665 406.804 46.8145 406.804 58.1654V99.3727H420.727V58.1654C420.727 39.1785 405.395 23.7344 386.419 23.7344C367.444 23.7344 352.112 39.1785 352.112 58.1654V99.3727H366.034V58.1654ZM278.616 38.1466C265.141 38.1466 254.244 49.0503 254.244 62.5338C254.244 76.0173 265.141 86.9211 278.616 86.9211C292.092 86.9211 302.989 76.0173 302.989 62.5338C302.989 49.0503 292.092 38.1466 278.616 38.1466ZM240.321 62.5338C240.321 41.3799 257.475 24.2159 278.616 24.2159C299.757 24.2159 316.911 41.3799 316.911 62.5338C316.911 83.6878 299.757 100.852 278.616 100.852C257.475 100.852 240.321 83.6878 240.321 62.5338ZM208.386 38.2154C195.082 37.9402 184.048 48.5 183.738 61.8115C183.463 75.123 194.017 86.1643 207.32 86.4739C215.192 86.6459 222.274 82.9998 226.812 77.2212L237.777 85.8204C230.662 94.9011 219.455 100.645 207.011 100.37C186.007 99.923 169.335 82.5183 169.782 61.5019C170.229 40.4856 187.623 23.8032 208.627 24.2503C219.524 24.4911 229.287 29.3066 236.059 36.8051L225.712 46.1266C221.415 41.3455 215.227 38.3186 208.317 38.1466L208.386 38.2154ZM340.527 25.2134V99.3727H326.605V25.2134H340.527ZM508.282 25.2134H494.36V99.8542H508.282V25.2134ZM483.154 99.8542H448.846C439.221 99.8542 431.452 92.0462 431.452 82.4495V25.2134H445.374V82.4495C445.374 84.3757 446.921 85.9236 448.846 85.9236H483.154V99.8542ZM583.772 25.2134H567.856H542.83C530.661 25.2134 520.933 35.1885 520.933 47.2273C520.933 59.2661 530.661 69.2412 542.83 69.2412H552.421C556.821 69.2412 560.396 72.8184 560.396 77.1868V77.9435C560.396 82.3463 556.821 85.8892 552.421 85.8892H520.451V99.8198H552.421C564.522 99.8198 574.319 90.0168 574.319 77.9091V77.1524C574.319 65.0448 564.522 55.2417 552.421 55.2417H542.83C538.499 55.2417 534.855 51.6301 534.855 47.1585C534.855 42.6869 538.499 39.0753 542.83 39.0753H574.319H583.772C591.472 39.0753 597.694 45.3011 597.694 53.0059V99.3039H611.617V53.0059C611.617 37.6306 599.138 25.1446 583.772 25.1446V25.2134ZM637.021 39.1441H609.038V25.2134H637.021V39.1441Z\"\n fill=\"currentColor\"\n />\n </svg>\n );\n}\n","import { CoinListWordmark } from '@/client/components/design-system/logos/CoinListWordmark';\nimport { typeClasses } from '@/client/components/design-system/tokens/typography';\nimport { cn } from '@/client/components/design-system/utils';\n\ninterface PoweredByCoinListProps {\n className?: string;\n}\n\nexport function PoweredByCoinList({ className }: PoweredByCoinListProps) {\n return (\n <div\n className={cn(\n 'flex items-center justify-center gap-[5px] text-text-secondary',\n className\n )}\n >\n <span className={cn(typeClasses.caption, 'tracking-[0.12px]')}>\n Powered by\n </span>\n <CoinListWordmark className=\"h-3 w-auto\" />\n </div>\n );\n}\n","'use client';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { type ButtonHTMLAttributes, forwardRef, type ReactNode } from 'react';\nimport { cn } from '@/client/components/design-system/utils';\n\n// Button variants using class-variance-authority for consistent styling\nconst buttonVariants = cva(\n 'inline-flex items-center justify-center gap-3 whitespace-nowrap transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-40 cursor-pointer',\n {\n variants: {\n variant: {\n // Primary — tokens auto-switch: dark bg (#171717) → light bg (#f4f4f5) in dark mode\n primary:\n 'bg-brand-primary text-text-inverse font-semibold hover:bg-brand-primary-hover active:bg-brand-primary-active focus-visible:ring-gray-500',\n // Secondary — bg-section, border-border, text-text-primary all auto-switch\n // hover maps to border token value; active has no token so uses dark: override\n secondary:\n 'bg-section border border-border text-text-primary font-medium hover:bg-border active:bg-[#d9d9d9] dark:active:bg-divider focus-visible:ring-gray-400',\n // Destructive — error tokens auto-switch to translucent dark equivalents\n // hover/active have no tokens so use dark: overrides\n destructive:\n 'bg-error-subtle border border-error-border text-error font-semibold hover:bg-[#fcdcd8] active:bg-[#f9c9c4] dark:hover:bg-[rgba(248,113,113,0.20)] dark:active:bg-[rgba(248,113,113,0.30)] focus-visible:ring-red-400',\n // Ghost — transparent base; hover/active use section/border tokens (auto-switch)\n ghost:\n 'bg-transparent text-text-primary font-medium hover:bg-section active:bg-border focus-visible:ring-gray-400',\n // Link — text-text-primary auto-switches light/dark\n link: 'h-auto p-0 text-text-primary font-medium underline-offset-4 hover:underline focus-visible:ring-gray-500',\n // Destructive link — text-error auto-switches (#b42318 → #f87171 in dark)\n destructiveLink:\n 'h-auto p-0 text-error font-medium hover:text-[#8b1a13] active:text-[#6d1510] dark:hover:text-[#fca5a5] dark:active:text-[#f87171] focus-visible:ring-red-500',\n },\n size: {\n sm: 'h-9 px-4 text-sm tracking-[0.28px]',\n default: 'h-11 px-5 text-sm tracking-[0.28px]',\n lg: 'h-14 px-6 text-base',\n icon: 'h-12 w-12',\n },\n radius: {\n pill: 'rounded-full',\n // compound variants below handle size-specific radii\n rounded: '',\n },\n fullWidth: {\n true: 'w-full',\n false: '',\n },\n },\n compoundVariants: [\n { size: 'sm', radius: 'rounded', className: 'rounded-lg' },\n { size: 'default', radius: 'rounded', className: 'rounded-2xl' },\n { size: 'lg', radius: 'rounded', className: 'rounded-2xl' },\n { size: 'icon', radius: 'rounded', className: 'rounded-md' },\n ],\n defaultVariants: {\n variant: 'primary',\n size: 'default',\n radius: 'pill',\n fullWidth: false,\n },\n }\n);\n\ninterface ClButtonProps\n extends ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n children?: ReactNode;\n isLoading?: boolean;\n loadingText?: string;\n startIcon?: ReactNode;\n endIcon?: ReactNode;\n}\n\nconst ClButton = forwardRef<HTMLButtonElement, ClButtonProps>(\n (\n {\n className,\n variant,\n size,\n radius,\n fullWidth,\n children,\n isLoading = false,\n loadingText,\n startIcon,\n endIcon,\n disabled,\n ...props\n },\n ref\n ) => {\n const isDisabled = disabled || isLoading;\n\n return (\n <button\n className={cn(\n buttonVariants({ variant, size, radius, fullWidth }),\n className\n )}\n ref={ref}\n disabled={isDisabled}\n {...props}\n >\n {isLoading && (\n <span\n className=\"h-4 w-4 shrink-0 animate-spin rounded-full border-2 border-current border-t-transparent opacity-60\"\n aria-hidden=\"true\"\n />\n )}\n\n {startIcon && !isLoading && (\n <span className=\"shrink-0\">{startIcon}</span>\n )}\n\n <span className={cn(isLoading && 'opacity-60')}>\n {isLoading && loadingText ? loadingText : children}\n </span>\n\n {endIcon && !isLoading && <span className=\"shrink-0\">{endIcon}</span>}\n </button>\n );\n }\n);\n\nClButton.displayName = 'ClButton';\n\nexport { ClButton, buttonVariants };\nexport type { ClButtonProps };\n","import type { SVGProps } from 'react';\n\nexport function CoinListLogomark(props: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width=\"115\"\n height=\"125\"\n viewBox=\"0 0 115 125\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n {...props}\n >\n <path\n d=\"M69.7519 123.966C75.8021 124.172 81.7491 123.519 87.4899 121.799C98.3871 118.531 107.531 112.58 114.922 103.947C114.922 103.947 114.922 103.947 114.888 103.912C112.859 102.193 110.831 100.507 108.837 98.8218L106.809 97.1363C106.431 96.8268 106.087 96.5172 105.709 96.2076C104.919 95.5197 104.128 94.8662 103.303 94.2126C96.2902 98.8562 88.5899 101.539 80.0991 101.883C75.8364 102.055 71.6082 101.642 67.4831 100.507C60.5047 98.6154 54.2483 95.1757 49.2294 89.7755C40.0854 79.938 36.854 68.1743 39.226 55.0348C40.7041 46.9172 44.4168 40.0723 50.0888 34.5C48.8856 34.7408 47.6825 35.016 46.5137 35.3943C37.5072 38.2148 30.5976 43.6839 25.6131 51.6639C21.6598 58.0273 19.5629 64.9411 19.3223 72.4739C19.1848 76.7047 19.4598 80.7979 20.4223 84.7879C23.4818 97.2395 30.2882 107.043 40.6698 114.335H40.7729V114.403C41.1167 114.644 41.4604 114.919 41.8042 115.16C50.2607 120.801 59.5766 123.691 69.7519 124.035V123.966Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M73.1896 89.052C69.1676 90.8406 65.0081 91.8725 60.6768 92.2165C65.9707 95.209 71.7802 96.688 78.1054 96.8256C80.168 96.86 82.2305 96.6536 84.3962 96.3097C89.7245 95.4841 94.6746 93.5579 99.281 90.7374C94.9153 87.057 90.5839 83.4109 86.2181 79.7305C82.5055 83.6861 78.1741 86.8506 73.1896 89.052Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M67.9643 0.241609C67.4143 0.276006 66.8643 0.344799 66.3486 0.413592C71.6425 1.4111 76.7646 3.13093 81.6116 5.71068C91.0306 10.7326 98.3527 17.9215 103.268 27.4494L105.915 25.1448C108.631 22.7714 111.347 20.3981 114.063 18.0247C107.634 11.1797 100.072 6.15784 91.2025 3.06214C85.2898 0.998336 79.2396 -0.0335643 73.0176 0.000832322C71.3675 0.000832322 69.6831 0.138419 67.9643 0.241609Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M26.4037 107.871C18.4628 97.9988 14.1314 86.7167 14.2002 73.818C14.2002 67.317 15.5409 61.0568 18.1191 55.1062C21.9348 46.2662 27.9506 39.1805 36.4071 34.2962C44.348 29.687 52.9763 27.8984 62.1547 29.2743C71.5738 30.7189 79.3771 35.2249 85.6336 42.2762C85.6336 42.2762 85.8398 42.5514 85.9429 42.6546C86.8711 41.8291 87.8336 41.0035 88.7618 40.178L89.8962 39.1805C90.8587 38.355 91.8212 37.4951 92.7838 36.6696C94.9838 34.7434 97.1495 32.8515 99.3152 30.9253C95.087 22.223 88.7274 15.55 80.3053 10.8377C70.3706 5.26541 59.6797 3.54557 48.37 5.02463C42.7323 5.78136 37.3352 7.50119 32.1788 10.0465C14.6815 18.7145 2.06546 36.532 1.03418 58.4771C0.862296 62.0887 1.10293 65.7348 1.65294 69.3464C3.02798 78.3239 6.32808 86.4759 11.622 93.8368C15.7471 99.5123 20.6629 104.19 26.3693 107.871H26.4037Z\"\n fill=\"currentColor\"\n />\n </svg>\n );\n}\n","'use client';\n\nimport {\n ClButton,\n type ClButtonProps,\n} from '@/client/components/design-system/ClButton';\nimport { CoinListLogomark } from '@/client/components/design-system/logos/CoinListLogomark';\n\ninterface CoinListSignInButtonProps\n extends Pick<\n ClButtonProps,\n 'onClick' | 'disabled' | 'fullWidth' | 'isLoading' | 'className'\n > {}\n\nexport function CoinListSignInButton({\n onClick,\n disabled = false,\n fullWidth = false,\n isLoading = false,\n className,\n}: CoinListSignInButtonProps) {\n return (\n <ClButton\n variant=\"primary\"\n size=\"lg\"\n fullWidth={fullWidth}\n onClick={onClick}\n disabled={disabled}\n isLoading={isLoading}\n loadingText=\"Signing in...\"\n startIcon={<CoinListLogomark className=\"h-[18px] w-[16px] shrink-0\" />}\n className={className}\n >\n Continue with CoinList\n </ClButton>\n );\n}\n","import { useContext } from 'react';\nimport { CoinListContext } from '@/client/CoinListProvider';\nimport type { CoinListClient } from '@/client/core/coinlist-client';\n\nexport interface UseCoinListResult {\n /**\n * Indicates whether the CoinList client has been initialized and ready to use.\n * While isReady is false, then the current user state will be `unknown`.\n */\n isReady: boolean;\n coinlist: CoinListClient;\n}\n\nexport function useCoinList(): UseCoinListResult {\n const context = useContext(CoinListContext);\n if (context === null) {\n throw new CoinListClientInitializationError();\n }\n\n return {\n isReady: context.isReady,\n coinlist: context.coinlist,\n };\n}\n\nexport class CoinListClientInitializationError extends Error {\n constructor(\n message = 'useCoinList() must be used within CoinListProvider. Wrap your app with <CoinListProvider config={...}>.'\n ) {\n super(message);\n this.name = 'CoinListClientInitializationError';\n }\n}\n","'use client';\n\nimport type { ReactNode } from 'react';\nimport { AlertBanner } from '@/client/components/design-system/AlertBanner';\nimport { CloseButton } from '@/client/components/design-system/CloseButton';\nimport { PoweredByCoinList } from '@/client/components/design-system/PoweredByCoinList';\nimport { typeClasses } from '@/client/components/design-system/tokens/typography';\nimport { cn } from '@/client/components/design-system/utils';\nimport { CoinListSignInButton } from '@/client/components/oauth/CoinListSignInButton';\nimport { useCoinList } from '@/client/hooks/useCoinList';\n\nexport interface CoinListSignInCardProps {\n state?: 'idle' | 'error';\n /**\n * Called when the user clicks the sign-in button. Defaults to\n * {@link CoinListClient#startOAuth}, which redirects to the CoinList\n * authorization page. Pass your own handler to override this behavior.\n */\n onSignIn?: () => void;\n /** Called when the user clicks the close button. When omitted, no close button is rendered. */\n onClose?: () => void;\n className?: string;\n}\n\n/**\n * Sign-in card that prompts the user to authenticate with CoinList.\n *\n * Use this component only inside a tree wrapped by {@link CoinListProvider}.\n * By default, clicking the sign-in button starts the CoinList OAuth flow via\n * {@link CoinListClient#startOAuth}; pass `onSignIn` to override.\n */\nexport function CoinListSignInCard({\n state = 'idle',\n onSignIn,\n onClose,\n className,\n}: CoinListSignInCardProps = {}): ReactNode {\n const { coinlist } = useCoinList();\n const handleSignIn =\n onSignIn ??\n (() => {\n void coinlist.startOAuth();\n });\n\n return (\n <div\n className={cn(\n 'relative flex w-full max-w-md flex-col rounded-card border border-border bg-background p-6 shadow-card',\n className\n )}\n >\n {onClose && (\n <CloseButton onClick={onClose} className=\"absolute right-4 top-4\" />\n )}\n\n <div className=\"flex flex-col gap-2\">\n <h3 className={cn(typeClasses.h3, 'text-text-primary')}>\n Sign in to participate\n </h3>\n <p className={cn(typeClasses.body, 'text-text-secondary')}>\n A CoinList account is required to participate in this sale.\n </p>\n </div>\n\n <CoinListSignInButton onClick={handleSignIn} fullWidth className=\"mt-4\" />\n\n {state === 'error' && (\n <AlertBanner\n variant=\"error\"\n icon\n content=\"Error signing in. Please try again.\"\n className=\"mt-4\"\n />\n )}\n\n <PoweredByCoinList className=\"mt-4\" />\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport { typeClasses } from '@/client/components/design-system/tokens/typography';\nimport { cn } from '@/client/components/design-system/utils';\nimport type { Offer } from '@/shared/types/offer';\n\nexport type OfferCardUi = {\n tagline: string | null;\n bannerUrl: string | null;\n logoUrl: string | null;\n formattedStartsAt: string;\n formattedEndsAt: string;\n};\n\nconst monthYearFormatter = new Intl.DateTimeFormat('en-US', {\n month: 'short',\n year: 'numeric',\n});\n\nexport const OfferCardUi = {\n fromDomain: (offer: Offer): OfferCardUi => ({\n tagline: offer.tagline,\n bannerUrl: offer.bannerUrl,\n logoUrl: offer.logoUrl,\n formattedStartsAt: monthYearFormatter.format(offer.startsAt),\n formattedEndsAt: monthYearFormatter.format(offer.endsAt),\n }),\n};\n\nexport interface Props {\n offer: OfferCardUi;\n /** Optional click handler. When provided, the card renders as interactive. */\n onClick?: () => void;\n /** Optional className applied to the card root element. */\n className?: string;\n /** Optional className applied to an outer wrapper element. */\n containerClassName?: string;\n}\n\nexport function OfferCard({\n offer,\n onClick,\n className,\n containerClassName,\n}: Props): ReactNode {\n const cardLabel = 'Open offer details';\n\n const cardContent = (\n <>\n <div className=\"relative mb-6 h-52 w-full overflow-hidden rounded-2xl border border-border/60 bg-section\">\n {offer.bannerUrl ? (\n <img\n src={offer.bannerUrl}\n alt=\"Offer banner\"\n className=\"h-full w-full object-cover\"\n />\n ) : (\n <div className=\"h-full w-full bg-gradient-to-br from-surface via-section to-background\" />\n )}\n <div className=\"absolute inset-0 bg-gradient-to-b from-transparent via-transparent to-overlay/35\" />\n\n <div className=\"absolute inset-0 flex items-center justify-center p-6\">\n {offer.logoUrl ? (\n <img\n src={offer.logoUrl}\n alt=\"Offer logo\"\n className=\"h-28 w-28 rounded-full border border-border bg-surface object-cover shadow-[0_10px_24px_rgba(0,0,0,0.25)]\"\n />\n ) : (\n <div className=\"h-28 w-28 rounded-full border border-border bg-surface shadow-[0_10px_24px_rgba(0,0,0,0.18)]\" />\n )}\n </div>\n </div>\n\n {offer.tagline && (\n <p className={cn(typeClasses.h3, 'min-h-[2.4rem] text-text-primary')}>\n {offer.tagline}\n </p>\n )}\n\n <div className=\"mt-4 grid grid-cols-2 gap-5 border-t border-divider pt-4\">\n <div className=\"flex flex-col gap-1\">\n <span className={cn(typeClasses.subhead, 'text-text-secondary')}>\n Starts\n </span>\n <span className={cn(typeClasses.label, 'text-text-primary')}>\n {offer.formattedStartsAt}\n </span>\n </div>\n\n <div className=\"flex flex-col gap-1\">\n <span className={cn(typeClasses.subhead, 'text-text-secondary')}>\n Ends\n </span>\n <span className={cn(typeClasses.label, 'text-text-primary')}>\n {offer.formattedEndsAt}\n </span>\n </div>\n </div>\n </>\n );\n\n const baseClasses = cn(\n 'relative flex w-full max-w-[28rem] flex-col rounded-card border border-border bg-background p-6 text-left shadow-card transition-all duration-200',\n className,\n onClick &&\n 'cursor-pointer hover:-translate-y-0.5 hover:border-divider hover:shadow-[0px_14px_32px_-10px_rgba(0,0,0,0.35)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-focus focus-visible:ring-offset-2'\n );\n\n let cardNode: ReactNode;\n if (onClick) {\n cardNode = (\n <button\n type=\"button\"\n aria-label={cardLabel}\n className={baseClasses}\n onClick={onClick}\n >\n {cardContent}\n </button>\n );\n } else {\n cardNode = <div className={baseClasses}>{cardContent}</div>;\n }\n\n if (!containerClassName) {\n return cardNode;\n }\n\n return <div className={containerClassName}>{cardNode}</div>;\n}\n","import { useEffect, useState } from 'react';\nimport { useCoinList } from '@/client/hooks/useCoinList';\nimport { NotAuthenticatedError } from '@/shared/types/errors';\nimport type { Offer } from '@/shared/types/offer';\n\nexport type LoadOffersReason = 'not-authenticated' | 'generic-error';\n\nexport type LoadOffersState =\n | {\n type: 'LOADING';\n }\n | {\n type: 'ERROR';\n reason: LoadOffersReason;\n }\n | {\n type: 'CONTENT';\n offers: Offer[];\n };\n\nexport interface UseOffersOptions {\n /**\n * Offers pre-fetched on the server (e.g. via `CoinListServer.fetchOffers()`).\n * When provided, the hook uses this data as-is and skips the client-side fetch entirely.\n */\n data?: Offer[];\n}\n\nexport interface UseOffersResult {\n offersState: LoadOffersState;\n}\n\nconst LOADING_STATE: LoadOffersState = { type: 'LOADING' };\n\n/**\n * Loads all CoinList offers for the current user and exposes a UI-friendly state.\n *\n * Pass `data` (pre-fetched server-side) to use that data as-is and skip\n * the client-side fetch entirely.\n *\n * Returns `LOADING` while CoinList is initializing or while offers are being fetched.\n * Returns `CONTENT` with all offers when `fetchOffers()` succeeds.\n * Returns `ERROR` with:\n * - `not-authenticated` when fetching fails with {@link NotAuthenticatedError}\n * - `generic-error` for any other failure\n */\nexport function useOffers(options: UseOffersOptions = {}): UseOffersResult {\n const { coinlist, isReady } = useCoinList();\n const { data: serverOffers } = options;\n const [offersState, setOffersState] = useState<LoadOffersState>(\n serverOffers !== undefined\n ? { type: 'CONTENT', offers: serverOffers }\n : LOADING_STATE\n );\n\n useEffect(() => {\n let isCancelled = false;\n\n // Wait until CoinListProvider finishes auth initialization.\n if (!isReady) {\n if (serverOffers === undefined) {\n setOffersState(LOADING_STATE);\n }\n return () => {\n isCancelled = true;\n };\n }\n\n if (serverOffers !== undefined) {\n return () => {\n isCancelled = true;\n };\n }\n\n setOffersState(LOADING_STATE);\n coinlist\n .fetchOffers()\n .then((offers) => {\n if (!isCancelled) {\n setOffersState({ type: 'CONTENT', offers });\n }\n })\n .catch((error: unknown) => {\n if (!isCancelled) {\n const reason: LoadOffersReason =\n error instanceof NotAuthenticatedError\n ? 'not-authenticated'\n : 'generic-error';\n setOffersState({ type: 'ERROR', reason });\n }\n });\n\n return () => {\n isCancelled = true;\n };\n }, [coinlist, isReady, serverOffers]);\n\n return { offersState };\n}\n","'use client';\n\nimport type { ReactNode } from 'react';\nimport { AlertBanner } from '@/client/components/design-system/AlertBanner';\nimport { typeClasses } from '@/client/components/design-system/tokens/typography';\nimport { cn } from '@/client/components/design-system/utils';\nimport { OfferCard, OfferCardUi } from '@/client/components/offers/OfferCard';\nimport { useOffers } from '@/client/hooks/useOffers';\nimport type { Offer } from '@/shared/types/offer';\n\nconst DEFAULT_MAX_COLUMNS = 3;\n\nexport interface OffersGridProps {\n /** Maximum number of columns to render when horizontal space allows. */\n maxColumns?: number;\n /** Optional className applied to the grid element. */\n className?: string;\n /** Optional className applied to the outer wrapper element. */\n containerClassName?: string;\n /** Optional loading slot shown while offers are being fetched. */\n loading?: ReactNode;\n /** Optional error slot shown when loading offers fails. */\n error?: ReactNode;\n /** Optional empty state slot shown when there are no available offers. */\n emptyState?: ReactNode;\n /** Optional per-offer click handler; when omitted, cards are not clickable. */\n onOfferClick?: (offer: Offer) => void;\n /**\n * Offers pre-fetched on the server (e.g. via `CoinListServer.fetchOffers()`).\n * When provided, the component uses this data as-is and skips the client-side fetch entirely.\n */\n data?: Offer[];\n}\n\n/**\n * Displays a responsive grid of offers backed by {@link useOffers}.\n *\n * Pass `data` (pre-fetched server-side) to use that data as-is and skip\n * the client-side fetch entirely.\n *\n * Uses `loading` / `error` slots when provided; otherwise renders standard\n * fallback loading and error states. Offer cards are interactive only when\n * `onOfferClick` is provided.\n */\nexport function OffersGrid({\n data,\n maxColumns,\n className,\n containerClassName,\n loading,\n error,\n emptyState,\n onOfferClick,\n}: OffersGridProps = {}): ReactNode {\n const { offersState } = useOffers({ data });\n const cols = Math.max(1, maxColumns ?? DEFAULT_MAX_COLUMNS);\n\n if (offersState.type === 'LOADING') {\n if (loading) {\n return loading;\n }\n\n return (\n <output\n aria-live=\"polite\"\n className=\"flex min-h-40 items-center justify-center rounded-2xl border border-border bg-background p-6\"\n >\n <p className={cn(typeClasses.body, 'text-text-secondary')}>\n Loading offers...\n </p>\n </output>\n );\n }\n\n if (offersState.type === 'ERROR') {\n if (error) {\n return error;\n }\n\n const errorMessage =\n offersState.reason === 'not-authenticated'\n ? 'Sign in to view available offers.'\n : 'Unable to load offers right now. Please try again.';\n\n return (\n <AlertBanner\n variant=\"error\"\n icon\n content={errorMessage}\n className=\"w-full max-w-[28rem]\"\n />\n );\n }\n\n if (offersState.offers.length === 0) {\n if (emptyState) {\n return emptyState;\n }\n\n return (\n <output\n aria-live=\"polite\"\n className=\"flex min-h-40 flex-col items-center justify-center rounded-2xl border border-border bg-background p-6 text-center\"\n >\n <p className={cn(typeClasses.body, 'font-medium text-text-primary')}>\n No offers available\n </p>\n <p className={cn(typeClasses.subhead, 'text-text-secondary')}>\n Check back soon for upcoming opportunities.\n </p>\n </output>\n );\n }\n\n const maxGridWidth = `calc(${cols} * 28rem + ${Math.max(cols - 1, 0)} * 1.5rem)`;\n\n return (\n <div className={cn('flex w-full justify-center', containerClassName)}>\n <div\n className={cn('grid w-full gap-6', className)}\n style={{\n gridTemplateColumns:\n 'repeat(auto-fit, minmax(min(100%, 20rem), 1fr))',\n maxWidth: maxGridWidth,\n }}\n >\n {offersState.offers.map((offer) => (\n <OfferCard\n key={offer.id}\n offer={OfferCardUi.fromDomain(offer)}\n onClick={onOfferClick ? () => onOfferClick(offer) : undefined}\n />\n ))}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { ChevronRight } from 'lucide-react';\nimport type { ReactNode } from 'react';\nimport { AlertBanner } from '@/client/components/design-system/AlertBanner';\nimport { ClButton } from '@/client/components/design-system/ClButton';\nimport { StepStatusIcon } from '@/client/components/design-system/StepStatusIcon';\nimport { typeClasses } from '@/client/components/design-system/tokens/typography';\nimport { cn } from '@/client/components/design-system/utils';\nimport type {\n Requirement,\n RequirementStatusInfo,\n RequirementStatusValue,\n RequirementType,\n} from '@/shared/types/requirement';\n\nexport type RequirementVariant = 'verification' | 'wallet';\nexport const RequirementVariant = {\n fromType(type: RequirementType): RequirementVariant {\n switch (type) {\n case 'external_wallet':\n case 'whitelisted_wallet':\n return 'wallet';\n default:\n return 'verification';\n }\n },\n};\n\nexport type RequirementStatus =\n | 'required'\n | 'pending'\n | 'completed'\n | 'rejected';\nexport const RequirementStatus = {\n fromStatusValue(status: RequirementStatusValue): RequirementStatus {\n switch (status) {\n case 'not_started':\n case 'action_needed':\n return 'required';\n case 'in_progress':\n return 'pending';\n case 'completed':\n return 'completed';\n case 'rejected':\n return 'rejected';\n }\n },\n};\n\nexport type ChecklistStatus = 'inProgress' | 'eligible' | 'ineligible';\nexport const ChecklistStatus = {\n derive(statuses: RequirementStatusInfo[]): ChecklistStatus {\n if (statuses.some((s) => s.status === 'rejected')) return 'ineligible';\n if (statuses.every((s) => s.status === 'completed')) return 'eligible';\n return 'inProgress';\n },\n};\n\nexport type RequirementItemUi = {\n variant: RequirementVariant;\n status: RequirementStatus;\n label: string;\n description: string;\n walletAddress?: string;\n};\n\nexport const RequirementItemUi = {\n fromDomain(\n req: Requirement,\n statusInfo: RequirementStatusInfo | undefined,\n label: string,\n description: string,\n walletAddress?: string\n ): RequirementItemUi {\n return {\n variant: RequirementVariant.fromType(req.type),\n status: statusInfo\n ? RequirementStatus.fromStatusValue(statusInfo.status)\n : 'required',\n label,\n description,\n walletAddress,\n };\n },\n};\n\nexport interface RequirementItemProps {\n ui: RequirementItemUi;\n expanded?: boolean;\n onToggle?: () => void;\n walletAddress?: string;\n className?: string;\n onAction?: (() => void) | null;\n onContactSupport?: (() => void) | null;\n}\n\nfunction VerificationActionZone({\n status,\n onAction,\n onContactSupport,\n}: {\n status: RequirementStatus;\n onAction?: (() => void) | null;\n onContactSupport?: (() => void) | null;\n}): ReactNode {\n switch (status) {\n case 'required':\n if (onAction === null) return null;\n return (\n <ClButton size=\"sm\" onClick={onAction}>\n Continue\n </ClButton>\n );\n case 'pending':\n return (\n <AlertBanner\n variant=\"warning\"\n content=\"Under review. We'll notify you when complete.\"\n />\n );\n case 'completed':\n return <AlertBanner variant=\"success\" content=\"Identity verified.\" />;\n case 'rejected':\n return (\n <AlertBanner\n variant=\"error\"\n content={\n onContactSupport === null ? (\n 'Verification rejected.'\n ) : (\n <>\n Verification rejected.{' '}\n <button\n type=\"button\"\n onClick={onContactSupport}\n className=\"underline\"\n >\n Contact support\n </button>\n .\n </>\n )\n }\n />\n );\n }\n}\n\nfunction WalletActionZone({\n status,\n walletAddress,\n onAction,\n}: {\n status: RequirementStatus;\n walletAddress?: string;\n onAction?: (() => void) | null;\n}): ReactNode {\n if (status === 'completed') {\n return (\n <>\n {onAction !== null && (\n <ClButton size=\"sm\" variant=\"secondary\" onClick={onAction}>\n Change wallet\n </ClButton>\n )}\n <AlertBanner\n variant=\"success\"\n content={walletAddress ?? 'Connected: 0xBa4b...9f2c'}\n />\n </>\n );\n }\n\n if (status === 'rejected') {\n return (\n <>\n {onAction !== null && (\n <ClButton size=\"sm\" onClick={onAction}>\n Connect wallet\n </ClButton>\n )}\n <AlertBanner\n variant=\"error\"\n content=\"This wallet is not eligible for this sale.\"\n />\n </>\n );\n }\n\n if (onAction === null) return null;\n return (\n <ClButton size=\"sm\" onClick={onAction}>\n Connect wallet\n </ClButton>\n );\n}\n\nexport function RequirementItem({\n ui,\n expanded = false,\n onToggle,\n className,\n onAction,\n onContactSupport,\n}: RequirementItemProps) {\n return (\n <div className={cn('flex w-full flex-col', className)}>\n <button\n type=\"button\"\n onClick={onToggle}\n aria-expanded={expanded}\n className=\"flex h-14 w-full cursor-pointer items-center justify-between rounded-2xl px-2 transition-colors hover:bg-surface\"\n >\n <div className=\"flex items-center gap-3\">\n <StepStatusIcon status={ui.status} />\n <span\n className={cn(\n typeClasses.body,\n 'whitespace-nowrap font-medium text-text-primary'\n )}\n >\n {ui.label}\n </span>\n </div>\n <ChevronRight\n className={cn(\n 'h-6 w-6 shrink-0 text-text-secondary transition-transform duration-300',\n expanded && 'rotate-90'\n )}\n aria-hidden=\"true\"\n />\n </button>\n\n <div\n className={cn(\n 'grid transition-[grid-template-rows] duration-300 ease-in-out',\n expanded ? 'grid-rows-[1fr]' : 'grid-rows-[0fr]'\n )}\n >\n {/* min-h-0 lets the grid item collapse to 0 when grid-rows is 0fr */}\n <div className=\"min-h-0 overflow-hidden\">\n <div className=\"flex flex-col gap-4 px-2 pb-4\">\n <p className={cn(typeClasses.subhead, 'text-text-secondary')}>\n {ui.description}\n </p>\n {ui.variant === 'verification' ? (\n <VerificationActionZone\n status={ui.status}\n onAction={onAction}\n onContactSupport={onContactSupport}\n />\n ) : (\n <WalletActionZone\n status={ui.status}\n walletAddress={ui.walletAddress}\n onAction={onAction}\n />\n )}\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import type { LucideIcon } from 'lucide-react';\nimport { CircleCheck, CircleX, Info } from 'lucide-react';\nimport { cn } from '@/client/components/design-system/utils';\n\nexport type StepStatus = 'required' | 'pending' | 'completed' | 'rejected';\n\ninterface StepStatusIconProps {\n status: StepStatus;\n className?: string;\n}\n\nconst statusConfig: Record<\n StepStatus,\n { Icon: LucideIcon; colorClass: string; fillClass: string }\n> = {\n required: {\n Icon: Info,\n colorClass: 'text-warning',\n fillClass: '[&_circle]:fill-warning-subtle',\n },\n pending: {\n Icon: Info,\n colorClass: 'text-warning',\n fillClass: '[&_circle]:fill-warning-subtle',\n },\n completed: {\n Icon: CircleCheck,\n colorClass: 'text-success',\n fillClass: '[&_circle]:fill-success-subtle',\n },\n rejected: {\n Icon: CircleX,\n colorClass: 'text-error',\n fillClass: '[&_circle]:fill-error-subtle',\n },\n};\n\nexport function StepStatusIcon({ status, className }: StepStatusIconProps) {\n const { Icon, colorClass, fillClass } = statusConfig[status];\n return (\n <Icon\n className={cn('h-6 w-6 shrink-0', colorClass, fillClass, className)}\n aria-hidden=\"true\"\n />\n );\n}\n","'use client';\n\nimport { type ReactNode, useState } from 'react';\nimport { AlertBanner } from '@/client/components/design-system/AlertBanner';\nimport { ClButton } from '@/client/components/design-system/ClButton';\nimport { typeClasses } from '@/client/components/design-system/tokens/typography';\nimport { cn } from '@/client/components/design-system/utils';\nimport {\n ChecklistStatus,\n RequirementItem,\n RequirementItemUi,\n} from '@/client/components/requirements/RequirementItem';\nimport { useCoinList } from '@/client/hooks/useCoinList';\nimport type { RequirementsData } from '@/client/hooks/useRequirements';\nimport { useRequirements } from '@/client/hooks/useRequirements';\nimport type { OfferId } from '@/shared/types/offer';\nimport type { OfferOptionId } from '@/shared/types/offer-detail';\nimport type { Requirement, RequirementType } from '@/shared/types/requirement';\n\nconst DEFAULT_LABELS: Record<RequirementType, string> = {\n kyc_approved: 'KYC Verification',\n identity_verified: 'Identity Verification',\n proof_of_address: 'Proof of Address',\n source_of_funds: 'Source of Funds',\n external_wallet: 'External Wallet',\n whitelisted_wallet: 'Whitelisted Wallet',\n jurisdiction: 'Jurisdiction Check',\n accreditation: 'Accreditation',\n};\n\nconst DEFAULT_DESCRIPTIONS: Record<RequirementType, string> = {\n kyc_approved: 'Complete Know Your Customer verification.',\n identity_verified: 'Verify your identity.',\n proof_of_address: 'Provide proof of your residential address.',\n source_of_funds: 'Provide documentation for your source of funds.',\n external_wallet: 'Connect an external wallet.',\n whitelisted_wallet: 'Connect a whitelisted wallet.',\n jurisdiction: 'Confirm your jurisdiction eligibility.',\n accreditation: 'Verify your accreditation status.',\n};\n\nexport interface RequirementsChecklistProps {\n offerId: OfferId;\n optionId: OfferOptionId;\n title: string;\n description: string;\n onContinue?: () => void;\n /**\n * Called when the user clicks a requirement's action button (e.g. \"Continue\", \"Connect wallet\").\n * Defaults to {@link CoinListClient#handleRequirement}, which opens the corresponding CoinList\n * page in a new tab. Pass your own handler to override this behavior, or pass `null` to disable\n * the action button entirely.\n */\n onRequirementActionOverride?: ((requirement: Requirement) => void) | null;\n /**\n * Called when the user clicks \"Contact support\" on a rejected requirement.\n * Defaults to {@link CoinListClient#contactSupport}, which opens the CoinList support ticket\n * page in a new tab. Pass your own handler to override this behavior, or pass `null` to disable\n * the contact support button entirely.\n */\n onContactSupportOverride?: ((requirement: Requirement) => void) | null;\n /** Override the default label for a requirement type. */\n getLabel?: (requirement: Requirement) => string;\n /** Override the default description for a requirement type. */\n getDescription?: (requirement: Requirement) => string | null;\n /** Optional loading slot. */\n loading?: ReactNode;\n /** Optional error slot. */\n error?: ReactNode;\n className?: string;\n /**\n * Requirements data pre-fetched on the server (e.g. via\n * `CoinListServer.fetchOfferRequirements()` + `fetchRequirementStatuses()`).\n * When provided, the component uses this data as-is and skips the client-side fetch entirely.\n */\n data?: RequirementsData;\n}\n\n/**\n * Connected requirements checklist that fetches requirements and statuses\n * via {@link useRequirements} and renders requirement items for the\n * specified option.\n *\n * Pass `data` (pre-fetched server-side) to use that data as-is and skip\n * the initial client-side fetch.\n *\n * By default, clicking a requirement's action button opens the corresponding\n * CoinList page in a new tab via {@link CoinListClient#handleRequirement}. It is\n * recommended to omit `onRequirementActionOverride` and rely on this default.\n * Pass your own handler only if you need custom navigation behavior, or `null`\n * to disable the action button entirely.\n */\nexport function RequirementsChecklist({\n offerId,\n optionId,\n title,\n description,\n onContinue,\n onRequirementActionOverride,\n onContactSupportOverride,\n getLabel,\n getDescription,\n loading,\n error,\n className,\n data,\n}: RequirementsChecklistProps): ReactNode {\n const { coinlist } = useCoinList();\n const { requirementsState } = useRequirements(offerId, { data });\n const [expandedIndex, setExpandedIndex] = useState<number | null>(null);\n\n const onRequirementAction =\n onRequirementActionOverride !== undefined\n ? onRequirementActionOverride\n : (requirement: Requirement) => coinlist.handleRequirement(requirement);\n const onContactSupport =\n onContactSupportOverride !== undefined\n ? onContactSupportOverride\n : () => coinlist.contactSupport();\n\n if (requirementsState.type === 'LOADING') {\n if (loading) return loading;\n return (\n <output\n aria-live=\"polite\"\n className=\"flex min-h-40 items-center justify-center rounded-2xl border border-border bg-background p-6\"\n >\n <p className={cn(typeClasses.body, 'text-text-secondary')}>\n Loading requirements...\n </p>\n </output>\n );\n }\n\n if (requirementsState.type === 'ERROR') {\n if (error) return error;\n const errorMessage =\n requirementsState.reason === 'not-authenticated'\n ? 'Sign in to view requirements.'\n : 'Unable to load requirements right now. Please try again.';\n return (\n <AlertBanner\n variant=\"error\"\n icon\n content={errorMessage}\n className=\"w-full max-w-[28rem]\"\n />\n );\n }\n\n const { requirements: requirementsByOptionId, statuses } = requirementsState;\n const requirements = requirementsByOptionId[optionId] ?? [];\n const requirementIds = new Set(requirements.map((r) => r.id));\n const optionStatuses = statuses.filter((s) => requirementIds.has(s.id));\n const statusByRequirementId = new Map(optionStatuses.map((s) => [s.id, s]));\n const checklistStatus: ChecklistStatus =\n ChecklistStatus.derive(optionStatuses);\n\n return (\n <div className={cn('flex w-full flex-col gap-4', className)}>\n <div className=\"flex flex-col gap-2\">\n <h3 className={cn(typeClasses.h3, 'text-text-primary')}>{title}</h3>\n <p className={cn(typeClasses.body, 'text-text-secondary')}>\n {description}\n </p>\n </div>\n\n <div className=\"flex flex-col divide-y divide-divider\">\n {requirements.map((req, index) => {\n const statusInfo = statusByRequirementId.get(req.id);\n const label = getLabel ? getLabel(req) : DEFAULT_LABELS[req.type];\n const itemDescription =\n (getDescription ? getDescription(req) : null) ??\n DEFAULT_DESCRIPTIONS[req.type];\n\n let onActionBound: (() => void) | null | undefined;\n if (onRequirementAction === null) {\n onActionBound = null;\n } else if (onRequirementAction) {\n onActionBound = () => onRequirementAction(req);\n }\n\n let onContactSupportBound: (() => void) | null | undefined;\n if (onContactSupport === null) {\n onContactSupportBound = null;\n } else if (onContactSupport) {\n onContactSupportBound = () => onContactSupport(req);\n }\n\n return (\n <RequirementItem\n key={req.id}\n ui={RequirementItemUi.fromDomain(\n req,\n statusInfo,\n label,\n itemDescription\n )}\n expanded={expandedIndex === index}\n onToggle={() =>\n setExpandedIndex((prev) => (prev === index ? null : index))\n }\n onAction={onActionBound}\n onContactSupport={onContactSupportBound}\n />\n );\n })}\n </div>\n\n {checklistStatus === 'ineligible' && (\n <AlertBanner\n variant=\"error\"\n icon\n content=\"You are not eligible to participate.\"\n />\n )}\n\n {onContinue && (\n <ClButton\n fullWidth\n disabled={checklistStatus !== 'eligible'}\n onClick={onContinue}\n >\n Continue\n </ClButton>\n )}\n </div>\n );\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { useCoinList } from '@/client/hooks/useCoinList';\nimport { NotAuthenticatedError } from '@/shared/types/errors';\nimport type { OfferId } from '@/shared/types/offer';\nimport type { OfferOptionId } from '@/shared/types/offer-detail';\nimport type {\n Requirement,\n RequirementStatusInfo,\n} from '@/shared/types/requirement';\n\nexport type LoadRequirementsReason = 'not-authenticated' | 'generic-error';\n\nexport type LoadRequirementsState =\n | {\n type: 'LOADING';\n }\n | {\n type: 'ERROR';\n reason: LoadRequirementsReason;\n }\n | {\n type: 'CONTENT';\n requirements: Record<OfferOptionId, Requirement[]>;\n statuses: RequirementStatusInfo[];\n };\n\nexport type RequirementsData = {\n requirements: Record<OfferOptionId, Requirement[]>;\n statuses: RequirementStatusInfo[];\n};\n\nexport interface UseRequirementsOptions {\n /**\n * Requirements data pre-fetched on the server (e.g. via\n * `CoinListServer.fetchOfferRequirements()` + `fetchRequirementStatuses()`).\n * When provided, the hook uses this data as-is and skips the initial client-side fetch.\n * Calling `refetch()` will still trigger a fresh fetch.\n */\n data?: RequirementsData;\n}\n\nexport interface UseRequirementsResult {\n requirementsState: LoadRequirementsState;\n /** Triggers a re-fetch of requirements and statuses. */\n refetch: () => void;\n}\n\nconst LOADING_STATE: LoadRequirementsState = { type: 'LOADING' };\n\n/**\n * Loads requirements (grouped by option ID) and requirement statuses for a\n * given offer, then exposes them via a state machine.\n *\n * Pass `data` (pre-fetched server-side) to use that data as-is and skip\n * the initial client-side fetch. Calling `refetch()` will still trigger a fresh fetch.\n *\n * Returns `LOADING` while CoinList is initializing or while data is being fetched.\n * Returns `CONTENT` with requirements and statuses on success.\n * Returns `ERROR` with:\n * - `not-authenticated` when fetching fails with {@link NotAuthenticatedError}\n * - `generic-error` for any other failure\n */\nexport function useRequirements(\n offerId: OfferId,\n options: UseRequirementsOptions = {}\n): UseRequirementsResult {\n const { coinlist, isReady } = useCoinList();\n const { data } = options;\n const [requirementsState, setRequirementsState] =\n useState<LoadRequirementsState>(\n data !== undefined ? { type: 'CONTENT', ...data } : LOADING_STATE\n );\n const [fetchKey, setFetchKey] = useState(0);\n const refetch = useCallback(() => setFetchKey((k) => k + 1), []);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: fetchKey is an intentional refetch trigger\n useEffect(() => {\n let isCancelled = false;\n\n if (!isReady) {\n if (data === undefined) {\n setRequirementsState(LOADING_STATE);\n }\n return () => {\n isCancelled = true;\n };\n }\n\n if (data !== undefined && fetchKey === 0) {\n return () => {\n isCancelled = true;\n };\n }\n\n setRequirementsState(LOADING_STATE);\n Promise.all([\n coinlist.fetchOfferRequirements(offerId),\n coinlist.fetchRequirementStatuses(offerId),\n ])\n .then(([requirementsByOptionId, statuses]) => {\n if (!isCancelled) {\n setRequirementsState({\n type: 'CONTENT',\n requirements: requirementsByOptionId,\n statuses,\n });\n }\n })\n .catch((error: unknown) => {\n if (!isCancelled) {\n const reason: LoadRequirementsReason =\n error instanceof NotAuthenticatedError\n ? 'not-authenticated'\n : 'generic-error';\n setRequirementsState({ type: 'ERROR', reason });\n }\n });\n\n return () => {\n isCancelled = true;\n };\n }, [coinlist, isReady, offerId, fetchKey]);\n\n return { requirementsState, refetch };\n}\n","import { useEffect, useRef } from 'react';\nimport type { OauthClientErrorReason } from '@/client/core/types/client-types';\nimport { useCoinList } from '@/client/hooks/useCoinList';\nimport type { AuthorizationCode, CodeVerifier } from '@/shared/types/oauth';\n\n/**\n * Reasons passed to {@link UseCompleteOAuthOptions.onFailure} when the\n * OAuth callback cannot be completed. Includes PKCE / redirect validation\n * errors from {@link CoinListClient.completeOAuth} and a dedicated value when\n * {@link UseCompleteOAuthOptions.postOAuthComplete} fails or rejects.\n */\nexport type CompleteOAuthFailureReason =\n | OauthClientErrorReason\n | 'complete_request_failed';\n\nexport interface UseCompleteOAuthOptions {\n /**\n * Exchange the authorization code on your backend (e.g. POST to your API).\n * Return `true` when the session was established successfully, `false` when\n * the request completed but signing in failed. Rejections are treated like\n * `false` and reported as {@link CompleteOAuthFailureReason}\n * `\"complete_request_failed\"`.\n */\n postOAuthComplete: (payload: {\n code: AuthorizationCode;\n codeVerifier: CodeVerifier;\n }) => Promise<boolean>;\n /**\n * Called when the user denied access (`error` query parameter), when\n * {@link CoinListClient.completeOAuth} fails PKCE/state validation, or when\n * {@link UseCompleteOAuthOptions.postOAuthComplete} fails.\n */\n onFailure: (reason: CompleteOAuthFailureReason) => void | Promise<void>;\n /** Invoked after {@link UseCompleteOAuthOptions.postOAuthComplete} succeeds and {@link CoinListClient.init} has refreshed the client session. */\n onSuccess: () => void | Promise<void>;\n}\n\n/**\n * Runs the CoinList OAuth callback once on mount: validates the redirect URL via\n * {@link CoinListClient.completeOAuth}, exchanges the code via {@link UseCompleteOAuthOptions.postOAuthComplete},\n * refreshes tokens with {@link CoinListClient.init}, then calls {@link UseCompleteOAuthOptions.onSuccess}.\n *\n * Framework-agnostic: reads `window.location` like {@link CoinListClient.completeOAuth}. Supply\n * {@link UseCompleteOAuthOptions.postOAuthComplete}, {@link UseCompleteOAuthOptions.onFailure},\n * and {@link UseCompleteOAuthOptions.onSuccess} to perform redirects or routing in your app.\n *\n * Must be used within {@link CoinListProvider}.\n */\nexport function useCompleteOAuth(options: UseCompleteOAuthOptions): void {\n const { coinlist } = useCoinList();\n\n const postOAuthCompleteRef = useRef(options.postOAuthComplete);\n const onFailureRef = useRef(options.onFailure);\n const onSuccessRef = useRef(options.onSuccess);\n\n postOAuthCompleteRef.current = options.postOAuthComplete;\n onFailureRef.current = options.onFailure;\n onSuccessRef.current = options.onSuccess;\n\n const hasStartedExchangeRef = useRef(false);\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const params = new URLSearchParams(window.location.search);\n if (!params.has('code') && !params.has('error')) return;\n\n if (hasStartedExchangeRef.current) return;\n\n const oauthResult = coinlist.completeOAuth();\n if (oauthResult.type === 'error') {\n void Promise.resolve(onFailureRef.current(oauthResult.reason)).catch(\n () => {}\n );\n return;\n }\n\n hasStartedExchangeRef.current = true;\n let cancelled = false;\n\n void (async () => {\n try {\n const ok = await postOAuthCompleteRef.current({\n code: oauthResult.code,\n codeVerifier: oauthResult.codeVerifier,\n });\n\n if (cancelled) return;\n\n if (!ok) {\n hasStartedExchangeRef.current = false;\n await onFailureRef.current('complete_request_failed');\n return;\n }\n\n await coinlist.init();\n\n if (cancelled) return;\n\n await onSuccessRef.current();\n } catch {\n if (cancelled) return;\n hasStartedExchangeRef.current = false;\n await onFailureRef.current('complete_request_failed');\n }\n })();\n\n return () => {\n cancelled = true;\n hasStartedExchangeRef.current = false;\n };\n }, [coinlist]);\n}\n","import { useEffect, useState } from 'react';\nimport { useCoinList } from '@/client/hooks/useCoinList';\nimport { NotAuthenticatedError } from '@/shared/types/errors';\nimport type { OfferId } from '@/shared/types/offer';\nimport type { OfferDetail } from '@/shared/types/offer-detail';\n\nexport type LoadOfferDetailsReason = 'not-authenticated' | 'generic-error';\n\nexport type LoadOfferDetailsState =\n | {\n type: 'LOADING';\n }\n | {\n type: 'ERROR';\n reason: LoadOfferDetailsReason;\n }\n | {\n type: 'CONTENT';\n offerDetail: OfferDetail;\n };\n\nexport interface UseOfferDetailsOptions {\n /**\n * Offer detail pre-fetched on the server (e.g. via `CoinListServer.fetchOfferDetails()`).\n * When provided, the hook uses this data as-is and skips the client-side fetch entirely.\n */\n data?: OfferDetail;\n}\n\nexport interface UseOfferDetailsResult {\n offerDetailsState: LoadOfferDetailsState;\n}\n\nconst LOADING_STATE: LoadOfferDetailsState = { type: 'LOADING' };\n\n/**\n * Loads CoinList offer details for a given offer id and exposes a UI-friendly state.\n *\n * Pass `data` (pre-fetched server-side) to use that data as-is and skip\n * the client-side fetch entirely.\n *\n * Returns `LOADING` while CoinList is initializing or while details are being fetched.\n * Returns `CONTENT` with the offer when `fetchOfferDetails()` succeeds.\n * Returns `ERROR` with:\n * - `not-authenticated` when fetching fails with {@link NotAuthenticatedError}\n * - `generic-error` for any other failure\n */\nexport function useOfferDetails(\n offerId: OfferId,\n options: UseOfferDetailsOptions = {}\n): UseOfferDetailsResult {\n const { coinlist, isReady } = useCoinList();\n const { data } = options;\n const [offerDetailsState, setOfferDetailsState] =\n useState<LoadOfferDetailsState>(\n data !== undefined\n ? { type: 'CONTENT', offerDetail: data }\n : LOADING_STATE\n );\n\n useEffect(() => {\n let isCancelled = false;\n\n if (!isReady) {\n if (data === undefined) {\n setOfferDetailsState(LOADING_STATE);\n }\n return () => {\n isCancelled = true;\n };\n }\n\n if (data !== undefined) {\n return () => {\n isCancelled = true;\n };\n }\n\n setOfferDetailsState(LOADING_STATE);\n coinlist\n .fetchOfferDetails(offerId)\n .then((offerDetail) => {\n if (!isCancelled) {\n setOfferDetailsState({ type: 'CONTENT', offerDetail });\n }\n })\n .catch((error: unknown) => {\n if (!isCancelled) {\n const reason: LoadOfferDetailsReason =\n error instanceof NotAuthenticatedError\n ? 'not-authenticated'\n : 'generic-error';\n setOfferDetailsState({ type: 'ERROR', reason });\n }\n });\n\n return () => {\n isCancelled = true;\n };\n }, [coinlist, isReady, offerId, data]);\n\n return { offerDetailsState };\n}\n","import { useEffect, useState } from 'react';\nimport { useCoinList } from '@/client/hooks/useCoinList';\nimport { NotAuthenticatedError } from '@/shared/types/errors';\nimport type { OfferId } from '@/shared/types/offer';\nimport type { Participation } from '@/shared/types/participation';\n\nexport type LoadParticipationsReason = 'not-authenticated' | 'generic-error';\n\nexport type LoadParticipationsState =\n | {\n type: 'LOADING';\n }\n | {\n type: 'ERROR';\n reason: LoadParticipationsReason;\n }\n | {\n type: 'CONTENT';\n participations: Participation[];\n };\n\nexport interface UseParticipationsOptions {\n /**\n * Participations pre-fetched on the server (e.g. via `CoinListServer.fetchParticipations()`).\n * When provided, the hook uses this data as-is and skips the client-side fetch entirely.\n */\n data?: Participation[];\n}\n\nexport interface UseParticipationsResult {\n participationsState: LoadParticipationsState;\n}\n\nconst LOADING_STATE: LoadParticipationsState = { type: 'LOADING' };\n\n/**\n * Loads all CoinList participations for the current user and exposes a UI-friendly state.\n * Optionally filters by offer when `offerId` is provided.\n *\n * Pass `data` (pre-fetched server-side) to use that data as-is and skip\n * the client-side fetch entirely.\n *\n * Returns `LOADING` while CoinList is initializing or while participations are being fetched.\n * Returns `CONTENT` with all participations when `fetchParticipations()` succeeds.\n * Returns `ERROR` with:\n * - `not-authenticated` when fetching fails with {@link NotAuthenticatedError}\n * - `generic-error` for any other failure\n */\nexport function useParticipations(\n offerId?: OfferId,\n options: UseParticipationsOptions = {}\n): UseParticipationsResult {\n const { coinlist, isReady } = useCoinList();\n const { data } = options;\n const [participationsState, setParticipationsState] =\n useState<LoadParticipationsState>(\n data !== undefined\n ? { type: 'CONTENT', participations: data }\n : LOADING_STATE\n );\n\n useEffect(() => {\n let isCancelled = false;\n\n // Wait until CoinListProvider finishes auth initialization.\n if (!isReady) {\n if (data === undefined) {\n setParticipationsState(LOADING_STATE);\n }\n return () => {\n isCancelled = true;\n };\n }\n\n if (data !== undefined) {\n return () => {\n isCancelled = true;\n };\n }\n\n setParticipationsState(LOADING_STATE);\n coinlist\n .fetchParticipations(offerId)\n .then((participations) => {\n if (!isCancelled) {\n setParticipationsState({ type: 'CONTENT', participations });\n }\n })\n .catch((error: unknown) => {\n if (!isCancelled) {\n const reason: LoadParticipationsReason =\n error instanceof NotAuthenticatedError\n ? 'not-authenticated'\n : 'generic-error';\n setParticipationsState({ type: 'ERROR', reason });\n }\n });\n\n return () => {\n isCancelled = true;\n };\n }, [coinlist, isReady, offerId, data]);\n\n return { participationsState };\n}\n"],"mappings":"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","names":["jsx","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsx","jsxs","jsx","jsxs","useEffect","useState","useState","useEffect","jsx","jsxs","CircleCheck","Info","jsx","Info","CircleCheck","Fragment","jsx","jsxs","useState","useEffect","useState","LOADING_STATE","useState","useEffect","jsx","jsxs","useState","useEffect","useEffect","useEffect","useState","LOADING_STATE","useState","useEffect","useEffect","useState","LOADING_STATE","useState","useEffect"]}