@coinlist-co/react 0.9.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.
@@ -2,8 +2,8 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
3
  import { ReactNode } from 'react';
4
4
  import { Hex, Abi, Hash, TransactionReceipt } from 'viem';
5
- import { E as EvmWalletAddress, a as EthereumChain, C as CoinListSwapNamespace, O as OfferId, b as EvmContractAddress, B as Bps, c as BlockchainAmount, S as SwapNamespaceImpl, A as AuthorizationCode, d as CodeVerifier, e as Config, f as OAuthAccessToken, g as Offer, P as PaginationParams, h as PaginatedResponse, i as OfferDetail, j as Participation, k as ParticipationsPaginationParams, l as ParticipationId, m as CreateParticipationParams, n as CreateWalletOwnershipChallengeParams, W as WalletOwnershipChallenge, o as ConnectExternalWalletParams, p as OfferOptionAddress, q as OfferOptionId, r as OfferOptionAddressId, R as Requirement, s as RequirementStatusInfo, t as Pii, D as DocumentType, u as DocumentSubmission, K as KycLevelName, v as KycToken, w as WalletChallengeType, x as RequirementType, y as RequirementStatusValue, z as Erc20Asset, F as AssetDecimals, G as StablecoinSymbol } from '../requirement-C2w45Q11.cjs';
6
- import { S as SwapQuote, N as NonEmptyArray } from '../collections-B84Vw55t.cjs';
5
+ import { E as EvmWalletAddress, a as EthereumChain, C as CoinListSwapNamespace, O as OfferId, b as EvmContractAddress, c as CoinListErc20Namespace, B as Bps, d as BlockchainAmount, S as SwapNamespaceImpl, e as SharedNamespaceContext, f as CoinListTokenSaleNamespace, g as OfferOptionId, A as AssetId, P as Participation, T as TokenSaleNamespaceImpl, h as AuthorizationCode, i as CodeVerifier, j as Config, k as OAuthAccessToken, l as Offer, m as PaginationParams, n as PaginatedResponse, o as OfferDetail, p as CreateWalletOwnershipChallengeParams, W as WalletOwnershipChallenge, q as ConnectExternalWalletParams, r as OfferOptionAddress, s as OfferOptionAddressId, R as Requirement, t as RequirementStatusInfo, u as Pii, D as DocumentType, v as DocumentSubmission, K as KycLevelName, w as KycToken, x as WalletChallengeType, y as RequirementType, z as RequirementStatusValue, F as Erc20Asset, G as AssetDecimals, H as StablecoinSymbol } from '../requirement-CDi5NJI8.cjs';
6
+ import { S as SwapQuote, N as NonEmptyArray } from '../collections-CJ24dOda.cjs';
7
7
 
8
8
  type WriteContractParams = {
9
9
  abi: Abi;
@@ -76,6 +76,14 @@ declare function classifyWalletError(error: unknown, ctx?: {
76
76
  hash?: Hash;
77
77
  }): WalletError;
78
78
 
79
+ /** A step-tagged reason {@link submitErc20Approval} failed. */
80
+ type Erc20ApprovalError = {
81
+ step: 'approval';
82
+ cause: WalletError;
83
+ } | {
84
+ step: 'approval-reverted';
85
+ };
86
+
79
87
  /**
80
88
  * Progress phases emitted by {@link executeSwap}, in the order they occur. An
81
89
  * allowance that already covers the swap skips the approval phases.
@@ -88,12 +96,7 @@ type SwapExecutionError = {
88
96
  step: 'swap-stopped';
89
97
  } | {
90
98
  step: 'allowance-check';
91
- } | {
92
- step: 'approval';
93
- cause: WalletError;
94
- } | {
95
- step: 'approval-reverted';
96
- } | {
99
+ } | Erc20ApprovalError | {
97
100
  step: 'swap';
98
101
  cause: WalletError;
99
102
  } | {
@@ -113,6 +116,7 @@ type SwapExecutionResult = {
113
116
  };
114
117
  type ExecuteSwapParams = {
115
118
  swap: CoinListSwapNamespace;
119
+ erc20: CoinListErc20Namespace;
116
120
  wallet: EvmWallet;
117
121
  contractAddress: EvmContractAddress;
118
122
  chain: EthereumChain;
@@ -188,7 +192,7 @@ interface CoinListClientSwapNamespace extends CoinListSwapNamespace {
188
192
  * Runs an on-chain swap end-to-end against the given wallet: status check,
189
193
  * ERC-20 allowance/approval, swap submission, and receipt confirmation.
190
194
  */
191
- executeSwap(params: Omit<ExecuteSwapParams, 'swap'>): Promise<SwapExecutionResult>;
195
+ executeSwap(params: Omit<ExecuteSwapParams, 'swap' | 'erc20'>): Promise<SwapExecutionResult>;
192
196
  /**
193
197
  * Proves ownership of a wallet and allow-lists it for an offer's swap,
194
198
  * broadcasting any required allow-list transaction.
@@ -196,10 +200,98 @@ interface CoinListClientSwapNamespace extends CoinListSwapNamespace {
196
200
  authorizeWallet(params: Omit<AuthorizeWalletParams, 'swap'>): Promise<WalletAuthorizationResult>;
197
201
  }
198
202
  declare class ClientSwapNamespaceImpl extends SwapNamespaceImpl implements CoinListClientSwapNamespace {
199
- executeSwap(params: Omit<ExecuteSwapParams, 'swap'>): Promise<SwapExecutionResult>;
203
+ private readonly erc20;
204
+ constructor(ctx: SharedNamespaceContext, erc20: CoinListErc20Namespace);
205
+ executeSwap(params: Omit<ExecuteSwapParams, 'swap' | 'erc20'>): Promise<SwapExecutionResult>;
200
206
  authorizeWallet(params: Omit<AuthorizeWalletParams, 'swap'>): Promise<WalletAuthorizationResult>;
201
207
  }
202
208
 
209
+ /**
210
+ * Progress phases emitted by {@link executeTokenSale}, in the order they occur.
211
+ * The `resetting-allowance`/`confirming-allowance-reset` phases only occur when
212
+ * the wallet holds a non-zero allowance that must be reset to 0 first
213
+ * (USDT-style tokens reject non-zero -> non-zero `approve()`).
214
+ */
215
+ type TokenSaleExecutionPhase = 'checking-allowance' | 'resetting-allowance' | 'confirming-allowance-reset' | 'approving' | 'confirming-approval' | 'recording-participation';
216
+ /**
217
+ * A step-tagged reason {@link executeTokenSale} failed.
218
+ *
219
+ * The reset-to-zero step (`allowance-reset` / `allowance-reset-reverted`) is
220
+ * reported distinctly from the main approval (`approval` /
221
+ * `approval-reverted`, reused from {@link Erc20ApprovalError}) so consumers can
222
+ * tell which of the two wallet prompts the user rejected or which approval
223
+ * reverted on-chain.
224
+ */
225
+ type TokenSaleExecutionError = {
226
+ step: 'allowance-check';
227
+ } | {
228
+ step: 'allowance-reset';
229
+ cause: WalletError;
230
+ } | {
231
+ step: 'allowance-reset-reverted';
232
+ } | Erc20ApprovalError | {
233
+ step: 'participation';
234
+ approvalTxHash: Hash;
235
+ };
236
+ type TokenSaleExecutionResult = {
237
+ type: 'success';
238
+ participation: Participation;
239
+ approvalTxHash: Hash;
240
+ } | {
241
+ type: 'error';
242
+ error: TokenSaleExecutionError;
243
+ };
244
+ type ExecuteTokenSaleParams = {
245
+ erc20: CoinListErc20Namespace;
246
+ tokenSale: CoinListTokenSaleNamespace;
247
+ wallet: EvmWallet;
248
+ offerId: OfferId;
249
+ offerOptionId: OfferOptionId;
250
+ assetId: AssetId;
251
+ /** ERC-20 the user pays with (e.g. USDC/USDT). */
252
+ paymentTokenAddress: EvmContractAddress;
253
+ /** Contract that pulls the payment — the `approve()` spender. */
254
+ fundingContractAddress: EvmContractAddress;
255
+ chain: EthereumChain;
256
+ amount: BlockchainAmount;
257
+ onProgress?: (phase: TokenSaleExecutionPhase) => void;
258
+ };
259
+ /**
260
+ * Executes a token sale end-to-end: submits an ERC-20 `approve()` for the sale
261
+ * amount to the funding contract (resetting a stale non-zero allowance to 0
262
+ * first for USDT-style tokens), waits for it to mine, and records the
263
+ * participation with CoinList. An approval is submitted even when the existing
264
+ * allowance already covers the amount — the backend requires a fresh approval
265
+ * transaction hash for every participation and verifies it on-chain before
266
+ * confirming.
267
+ *
268
+ * Wallet selection/connection and chain switching are the app's responsibility —
269
+ * this operates on an already-connected {@link EvmWallet}. Progress is reported
270
+ * via `onProgress` for consumers rendering loading states.
271
+ */
272
+ declare function executeTokenSale(params: ExecuteTokenSaleParams): Promise<TokenSaleExecutionResult>;
273
+
274
+ /**
275
+ * The client-side token-sale namespace: everything the shared
276
+ * {@link CoinListTokenSaleNamespace} reads/writes over the API, plus the
277
+ * on-chain flow that drives a wallet (`executeTokenSale`). The flow takes the
278
+ * wallet and addresses per call; the namespace supplies the participation
279
+ * writes and (via the ERC-20 namespace) the allowance read it depends on.
280
+ */
281
+ interface CoinListClientTokenSaleNamespace extends CoinListTokenSaleNamespace {
282
+ /**
283
+ * Runs a token sale end-to-end against the given wallet: ERC-20
284
+ * allowance/approval (resetting a stale non-zero allowance first for
285
+ * USDT-style tokens), approval confirmation, and participation recording.
286
+ */
287
+ executeTokenSale(params: Omit<ExecuteTokenSaleParams, 'erc20' | 'tokenSale'>): Promise<TokenSaleExecutionResult>;
288
+ }
289
+ declare class ClientTokenSaleNamespaceImpl extends TokenSaleNamespaceImpl implements CoinListClientTokenSaleNamespace {
290
+ private readonly erc20;
291
+ constructor(ctx: SharedNamespaceContext, erc20: CoinListErc20Namespace);
292
+ executeTokenSale(params: Omit<ExecuteTokenSaleParams, 'erc20' | 'tokenSale'>): Promise<TokenSaleExecutionResult>;
293
+ }
294
+
203
295
  type AuthState = 'unknown' | 'logged-in' | 'logged-out';
204
296
  /** Discriminated error reasons from {@link CoinListClient.completeOAuth}. */
205
297
  type OauthClientErrorReason = 'user_canceled' | 'missing_state' | 'invalid_state' | 'missing_code' | 'missing_code_verifier';
@@ -297,38 +389,6 @@ interface CoinListClient {
297
389
  * {@link NotAuthenticatedError}.
298
390
  */
299
391
  fetchOfferDetails(id: OfferId): Promise<OfferDetail>;
300
- /**
301
- * Fetches all participations by iterating through every paginated response.
302
- *
303
- * This method must be called only when the user's {@link AuthState} is
304
- * `'logged-in'`. If the user is not authenticated, it throws
305
- * {@link NotAuthenticatedError}.
306
- */
307
- fetchParticipations(offerId?: OfferId): Promise<Participation[]>;
308
- /**
309
- * Fetches a single page of participations, optionally filtered by offer.
310
- *
311
- * This method must be called only when the user's {@link AuthState} is
312
- * `'logged-in'`. If the user is not authenticated, it throws
313
- * {@link NotAuthenticatedError}.
314
- */
315
- fetchParticipationsPage(params: ParticipationsPaginationParams): Promise<PaginatedResponse<Participation>>;
316
- /**
317
- * Fetches a participation by id.
318
- *
319
- * This method must be called only when the user's {@link AuthState} is
320
- * `'logged-in'`. If the user is not authenticated, it throws
321
- * {@link NotAuthenticatedError}.
322
- */
323
- fetchParticipation(id: ParticipationId): Promise<Participation>;
324
- /**
325
- * Creates a participation.
326
- *
327
- * This method must be called only when the user's {@link AuthState} is
328
- * `'logged-in'`. If the user is not authenticated, it throws
329
- * {@link NotAuthenticatedError}.
330
- */
331
- createParticipation(params: CreateParticipationParams): Promise<Participation>;
332
392
  /**
333
393
  * Creates a single-use wallet-ownership challenge for the given wallet and
334
394
  * chain. The user signs the returned {@link WalletOwnershipChallenge.message}
@@ -430,8 +490,30 @@ interface CoinListClient {
430
490
  */
431
491
  contactSupport(): void;
432
492
  /**
433
- * On-chain swap operations: quoting a swap, reading swap-contract state and
434
- * token allowances, and proving/allow-listing wallet ownership — e.g.
493
+ * Generic ERC-20 reads (token allowance and balance) shared across the
494
+ * on-chain flows — e.g. `coinlist.erc20.getTokenBalance({ ... })`.
495
+ *
496
+ * These reads must be called only when the user's {@link AuthState} is
497
+ * `'logged-in'`; if the user is not authenticated, they throw
498
+ * {@link NotAuthenticatedError}.
499
+ */
500
+ readonly erc20: CoinListErc20Namespace;
501
+ /**
502
+ * Token-sale operations: listing/reading/recording participations, plus the
503
+ * on-chain `executeTokenSale` flow that submits the ERC-20 approval and
504
+ * records the participation over a caller-supplied {@link EvmWallet} —
505
+ * e.g. `coinlist.tokenSale.executeTokenSale({ ... })`.
506
+ *
507
+ * The API-backed reads/writes must be called only when the user's
508
+ * {@link AuthState} is `'logged-in'`; if the user is not authenticated, they
509
+ * throw {@link NotAuthenticatedError}. `executeTokenSale` additionally drives
510
+ * a caller-supplied wallet and returns a step-tagged result rather than
511
+ * throwing.
512
+ */
513
+ readonly tokenSale: CoinListClientTokenSaleNamespace;
514
+ /**
515
+ * On-chain swap operations: quoting a swap, reading swap-contract state, and
516
+ * proving/allow-listing wallet ownership — e.g.
435
517
  * `coinlist.swap.getOutputToken({ contractAddress, chain })`.
436
518
  *
437
519
  * The API-backed reads must be called only when the user's {@link AuthState}
@@ -520,11 +602,11 @@ interface CoinListSignInCardProps {
520
602
  declare function CoinListSignInCard({ state, onSignIn, onClose, className, }?: CoinListSignInCardProps): ReactNode;
521
603
 
522
604
  type OfferCardUi = {
523
- tagline: string | null;
524
- bannerUrl: string | null;
525
- logoUrl: string | null;
605
+ tagline: string;
606
+ bannerUrl: string;
607
+ logoUrl: string;
526
608
  formattedStartsAt: string;
527
- formattedEndsAt: string;
609
+ formattedEndsAt: string | null;
528
610
  };
529
611
  declare const OfferCardUi: {
530
612
  fromDomain: (offer: Offer) => OfferCardUi;
@@ -1438,4 +1520,4 @@ interface UseTaxDocumentResult {
1438
1520
  */
1439
1521
  declare function useTaxDocument({ isOpen, }: UseTaxDocumentOptions): UseTaxDocumentResult;
1440
1522
 
1441
- export { type AuthState, type AuthorizeWalletParams, type BroadcastTxParams, ChecklistStatus, type ClientConfig, ClientSwapNamespaceImpl, type CoinListClient, CoinListClientInitializationError, type CoinListClientSwapNamespace, CoinListContext, CoinListContextProvider, type CoinListContextValue, CoinListProvider, type CoinListProviderProps, CoinListSignInCard, type CoinListSignInCardProps, CoinListStyleScope, type CoinListStyleScopeProps, type CompleteOAuthFailureReason, type ConnectWallet, type ConnectWalletError, type ConnectWalletErrorCode, type ConnectWalletFlowError, type ConnectWalletFlowParams, type ConnectWalletFlowResult, ConnectWalletModal, type ConnectWalletModalProps, type ConnectWalletPhase, type ConnectWalletSignState, type ConnectWalletState, ConnectedWalletList, type ConnectedWalletListProps, type ConnectedWalletUi, type EvmSigner, type EvmWallet, type ExecuteSwapParams, IdentityVerification, type IdentityVerificationProps, KycLevelName, KycToken, type KycTokenErrorReason, type KycTokenState, type LoadOfferDetailsReason, type LoadOfferDetailsState, type LoadOffersReason, type LoadOffersState, type LoadOptionAddressesReason, type LoadOptionAddressesState, type LoadParticipationsReason, type LoadParticipationsState, type LoadRequirementsReason, type LoadRequirementsState, OAUTH_CODE_VERIFIER_KEY, OAUTH_STATE_KEY, type OauthClientErrorReason, type OauthClientResult, OfferCard, type Props as OfferCardProps, OfferCardUi, OffersGrid, type OffersGridProps, RequirementItem, type RequirementItemProps, RequirementItemUi, RequirementStatus, RequirementVariant, RequirementsChecklist, type RequirementsChecklistProps, type RequirementsData, type SignState, type SwapExecutionError, type SwapExecutionPhase, type SwapExecutionResult, type SwapOutputTokenState, type TaxDocumentAddressParts, type TaxDocumentFields, TaxDocumentModal, type TaxDocumentModalProps, type TaxDocumentState, type UseCoinListResult, type UseCompleteOAuthOptions, type UseConnectWalletOptions, type UseConnectWalletResult, type UseKycTokenResult, type UseOfferDetailsOptions, type UseOfferDetailsResult, type UseOffersOptions, type UseOffersResult, type UseOptionAddressesOptions, type UseOptionAddressesResult, type UseParticipationsOptions, type UseParticipationsResult, type UseRequirementsOptions, type UseRequirementsResult, type UseSwapOutputTokenOptions, type UseSwapOutputTokenResult, type UseSwapQuoteOptions, type UseSwapQuoteResult, type UseSwapTokenBalancesOptions, type UseSwapTokenBalancesResult, type UseTaxDocumentOptions, type UseTaxDocumentResult, type WalletAuthorizationError, type WalletAuthorizationPhase, type WalletAuthorizationResult, type WalletError, type WalletsStatus, type WriteContractParams, authorizeWallet, classifyWalletError, connectExternalWalletFlow, createCoinListClient, executeSwap, useCoinList, useCompleteOAuth, useConnectWallet, useKycToken, useOfferDetails, useOffers, useOptionAddresses, useParticipations, useRequirements, useSwapOutputToken, useSwapQuote, useSwapTokenBalances, useTaxDocument };
1523
+ export { type AuthState, type AuthorizeWalletParams, type BroadcastTxParams, ChecklistStatus, type ClientConfig, ClientSwapNamespaceImpl, ClientTokenSaleNamespaceImpl, type CoinListClient, CoinListClientInitializationError, type CoinListClientSwapNamespace, type CoinListClientTokenSaleNamespace, CoinListContext, CoinListContextProvider, type CoinListContextValue, CoinListProvider, type CoinListProviderProps, CoinListSignInCard, type CoinListSignInCardProps, CoinListStyleScope, type CoinListStyleScopeProps, type CompleteOAuthFailureReason, type ConnectWallet, type ConnectWalletError, type ConnectWalletErrorCode, type ConnectWalletFlowError, type ConnectWalletFlowParams, type ConnectWalletFlowResult, ConnectWalletModal, type ConnectWalletModalProps, type ConnectWalletPhase, type ConnectWalletSignState, type ConnectWalletState, ConnectedWalletList, type ConnectedWalletListProps, type ConnectedWalletUi, type EvmSigner, type EvmWallet, type ExecuteSwapParams, type ExecuteTokenSaleParams, IdentityVerification, type IdentityVerificationProps, KycLevelName, KycToken, type KycTokenErrorReason, type KycTokenState, type LoadOfferDetailsReason, type LoadOfferDetailsState, type LoadOffersReason, type LoadOffersState, type LoadOptionAddressesReason, type LoadOptionAddressesState, type LoadParticipationsReason, type LoadParticipationsState, type LoadRequirementsReason, type LoadRequirementsState, OAUTH_CODE_VERIFIER_KEY, OAUTH_STATE_KEY, type OauthClientErrorReason, type OauthClientResult, OfferCard, type Props as OfferCardProps, OfferCardUi, OffersGrid, type OffersGridProps, RequirementItem, type RequirementItemProps, RequirementItemUi, RequirementStatus, RequirementVariant, RequirementsChecklist, type RequirementsChecklistProps, type RequirementsData, type SignState, type SwapExecutionError, type SwapExecutionPhase, type SwapExecutionResult, type SwapOutputTokenState, type TaxDocumentAddressParts, type TaxDocumentFields, TaxDocumentModal, type TaxDocumentModalProps, type TaxDocumentState, type TokenSaleExecutionError, type TokenSaleExecutionPhase, type TokenSaleExecutionResult, type UseCoinListResult, type UseCompleteOAuthOptions, type UseConnectWalletOptions, type UseConnectWalletResult, type UseKycTokenResult, type UseOfferDetailsOptions, type UseOfferDetailsResult, type UseOffersOptions, type UseOffersResult, type UseOptionAddressesOptions, type UseOptionAddressesResult, type UseParticipationsOptions, type UseParticipationsResult, type UseRequirementsOptions, type UseRequirementsResult, type UseSwapOutputTokenOptions, type UseSwapOutputTokenResult, type UseSwapQuoteOptions, type UseSwapQuoteResult, type UseSwapTokenBalancesOptions, type UseSwapTokenBalancesResult, type UseTaxDocumentOptions, type UseTaxDocumentResult, type WalletAuthorizationError, type WalletAuthorizationPhase, type WalletAuthorizationResult, type WalletError, type WalletsStatus, type WriteContractParams, authorizeWallet, classifyWalletError, connectExternalWalletFlow, createCoinListClient, executeSwap, executeTokenSale, useCoinList, useCompleteOAuth, useConnectWallet, useKycToken, useOfferDetails, useOffers, useOptionAddresses, useParticipations, useRequirements, useSwapOutputToken, useSwapQuote, useSwapTokenBalances, useTaxDocument };
@@ -2,8 +2,8 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
3
  import { ReactNode } from 'react';
4
4
  import { Hex, Abi, Hash, TransactionReceipt } from 'viem';
5
- import { E as EvmWalletAddress, a as EthereumChain, C as CoinListSwapNamespace, O as OfferId, b as EvmContractAddress, B as Bps, c as BlockchainAmount, S as SwapNamespaceImpl, A as AuthorizationCode, d as CodeVerifier, e as Config, f as OAuthAccessToken, g as Offer, P as PaginationParams, h as PaginatedResponse, i as OfferDetail, j as Participation, k as ParticipationsPaginationParams, l as ParticipationId, m as CreateParticipationParams, n as CreateWalletOwnershipChallengeParams, W as WalletOwnershipChallenge, o as ConnectExternalWalletParams, p as OfferOptionAddress, q as OfferOptionId, r as OfferOptionAddressId, R as Requirement, s as RequirementStatusInfo, t as Pii, D as DocumentType, u as DocumentSubmission, K as KycLevelName, v as KycToken, w as WalletChallengeType, x as RequirementType, y as RequirementStatusValue, z as Erc20Asset, F as AssetDecimals, G as StablecoinSymbol } from '../requirement-C2w45Q11.js';
6
- import { S as SwapQuote, N as NonEmptyArray } from '../collections-BQbFJS3g.js';
5
+ import { E as EvmWalletAddress, a as EthereumChain, C as CoinListSwapNamespace, O as OfferId, b as EvmContractAddress, c as CoinListErc20Namespace, B as Bps, d as BlockchainAmount, S as SwapNamespaceImpl, e as SharedNamespaceContext, f as CoinListTokenSaleNamespace, g as OfferOptionId, A as AssetId, P as Participation, T as TokenSaleNamespaceImpl, h as AuthorizationCode, i as CodeVerifier, j as Config, k as OAuthAccessToken, l as Offer, m as PaginationParams, n as PaginatedResponse, o as OfferDetail, p as CreateWalletOwnershipChallengeParams, W as WalletOwnershipChallenge, q as ConnectExternalWalletParams, r as OfferOptionAddress, s as OfferOptionAddressId, R as Requirement, t as RequirementStatusInfo, u as Pii, D as DocumentType, v as DocumentSubmission, K as KycLevelName, w as KycToken, x as WalletChallengeType, y as RequirementType, z as RequirementStatusValue, F as Erc20Asset, G as AssetDecimals, H as StablecoinSymbol } from '../requirement-CDi5NJI8.js';
6
+ import { S as SwapQuote, N as NonEmptyArray } from '../collections-ZYLKp8JB.js';
7
7
 
8
8
  type WriteContractParams = {
9
9
  abi: Abi;
@@ -76,6 +76,14 @@ declare function classifyWalletError(error: unknown, ctx?: {
76
76
  hash?: Hash;
77
77
  }): WalletError;
78
78
 
79
+ /** A step-tagged reason {@link submitErc20Approval} failed. */
80
+ type Erc20ApprovalError = {
81
+ step: 'approval';
82
+ cause: WalletError;
83
+ } | {
84
+ step: 'approval-reverted';
85
+ };
86
+
79
87
  /**
80
88
  * Progress phases emitted by {@link executeSwap}, in the order they occur. An
81
89
  * allowance that already covers the swap skips the approval phases.
@@ -88,12 +96,7 @@ type SwapExecutionError = {
88
96
  step: 'swap-stopped';
89
97
  } | {
90
98
  step: 'allowance-check';
91
- } | {
92
- step: 'approval';
93
- cause: WalletError;
94
- } | {
95
- step: 'approval-reverted';
96
- } | {
99
+ } | Erc20ApprovalError | {
97
100
  step: 'swap';
98
101
  cause: WalletError;
99
102
  } | {
@@ -113,6 +116,7 @@ type SwapExecutionResult = {
113
116
  };
114
117
  type ExecuteSwapParams = {
115
118
  swap: CoinListSwapNamespace;
119
+ erc20: CoinListErc20Namespace;
116
120
  wallet: EvmWallet;
117
121
  contractAddress: EvmContractAddress;
118
122
  chain: EthereumChain;
@@ -188,7 +192,7 @@ interface CoinListClientSwapNamespace extends CoinListSwapNamespace {
188
192
  * Runs an on-chain swap end-to-end against the given wallet: status check,
189
193
  * ERC-20 allowance/approval, swap submission, and receipt confirmation.
190
194
  */
191
- executeSwap(params: Omit<ExecuteSwapParams, 'swap'>): Promise<SwapExecutionResult>;
195
+ executeSwap(params: Omit<ExecuteSwapParams, 'swap' | 'erc20'>): Promise<SwapExecutionResult>;
192
196
  /**
193
197
  * Proves ownership of a wallet and allow-lists it for an offer's swap,
194
198
  * broadcasting any required allow-list transaction.
@@ -196,10 +200,98 @@ interface CoinListClientSwapNamespace extends CoinListSwapNamespace {
196
200
  authorizeWallet(params: Omit<AuthorizeWalletParams, 'swap'>): Promise<WalletAuthorizationResult>;
197
201
  }
198
202
  declare class ClientSwapNamespaceImpl extends SwapNamespaceImpl implements CoinListClientSwapNamespace {
199
- executeSwap(params: Omit<ExecuteSwapParams, 'swap'>): Promise<SwapExecutionResult>;
203
+ private readonly erc20;
204
+ constructor(ctx: SharedNamespaceContext, erc20: CoinListErc20Namespace);
205
+ executeSwap(params: Omit<ExecuteSwapParams, 'swap' | 'erc20'>): Promise<SwapExecutionResult>;
200
206
  authorizeWallet(params: Omit<AuthorizeWalletParams, 'swap'>): Promise<WalletAuthorizationResult>;
201
207
  }
202
208
 
209
+ /**
210
+ * Progress phases emitted by {@link executeTokenSale}, in the order they occur.
211
+ * The `resetting-allowance`/`confirming-allowance-reset` phases only occur when
212
+ * the wallet holds a non-zero allowance that must be reset to 0 first
213
+ * (USDT-style tokens reject non-zero -> non-zero `approve()`).
214
+ */
215
+ type TokenSaleExecutionPhase = 'checking-allowance' | 'resetting-allowance' | 'confirming-allowance-reset' | 'approving' | 'confirming-approval' | 'recording-participation';
216
+ /**
217
+ * A step-tagged reason {@link executeTokenSale} failed.
218
+ *
219
+ * The reset-to-zero step (`allowance-reset` / `allowance-reset-reverted`) is
220
+ * reported distinctly from the main approval (`approval` /
221
+ * `approval-reverted`, reused from {@link Erc20ApprovalError}) so consumers can
222
+ * tell which of the two wallet prompts the user rejected or which approval
223
+ * reverted on-chain.
224
+ */
225
+ type TokenSaleExecutionError = {
226
+ step: 'allowance-check';
227
+ } | {
228
+ step: 'allowance-reset';
229
+ cause: WalletError;
230
+ } | {
231
+ step: 'allowance-reset-reverted';
232
+ } | Erc20ApprovalError | {
233
+ step: 'participation';
234
+ approvalTxHash: Hash;
235
+ };
236
+ type TokenSaleExecutionResult = {
237
+ type: 'success';
238
+ participation: Participation;
239
+ approvalTxHash: Hash;
240
+ } | {
241
+ type: 'error';
242
+ error: TokenSaleExecutionError;
243
+ };
244
+ type ExecuteTokenSaleParams = {
245
+ erc20: CoinListErc20Namespace;
246
+ tokenSale: CoinListTokenSaleNamespace;
247
+ wallet: EvmWallet;
248
+ offerId: OfferId;
249
+ offerOptionId: OfferOptionId;
250
+ assetId: AssetId;
251
+ /** ERC-20 the user pays with (e.g. USDC/USDT). */
252
+ paymentTokenAddress: EvmContractAddress;
253
+ /** Contract that pulls the payment — the `approve()` spender. */
254
+ fundingContractAddress: EvmContractAddress;
255
+ chain: EthereumChain;
256
+ amount: BlockchainAmount;
257
+ onProgress?: (phase: TokenSaleExecutionPhase) => void;
258
+ };
259
+ /**
260
+ * Executes a token sale end-to-end: submits an ERC-20 `approve()` for the sale
261
+ * amount to the funding contract (resetting a stale non-zero allowance to 0
262
+ * first for USDT-style tokens), waits for it to mine, and records the
263
+ * participation with CoinList. An approval is submitted even when the existing
264
+ * allowance already covers the amount — the backend requires a fresh approval
265
+ * transaction hash for every participation and verifies it on-chain before
266
+ * confirming.
267
+ *
268
+ * Wallet selection/connection and chain switching are the app's responsibility —
269
+ * this operates on an already-connected {@link EvmWallet}. Progress is reported
270
+ * via `onProgress` for consumers rendering loading states.
271
+ */
272
+ declare function executeTokenSale(params: ExecuteTokenSaleParams): Promise<TokenSaleExecutionResult>;
273
+
274
+ /**
275
+ * The client-side token-sale namespace: everything the shared
276
+ * {@link CoinListTokenSaleNamespace} reads/writes over the API, plus the
277
+ * on-chain flow that drives a wallet (`executeTokenSale`). The flow takes the
278
+ * wallet and addresses per call; the namespace supplies the participation
279
+ * writes and (via the ERC-20 namespace) the allowance read it depends on.
280
+ */
281
+ interface CoinListClientTokenSaleNamespace extends CoinListTokenSaleNamespace {
282
+ /**
283
+ * Runs a token sale end-to-end against the given wallet: ERC-20
284
+ * allowance/approval (resetting a stale non-zero allowance first for
285
+ * USDT-style tokens), approval confirmation, and participation recording.
286
+ */
287
+ executeTokenSale(params: Omit<ExecuteTokenSaleParams, 'erc20' | 'tokenSale'>): Promise<TokenSaleExecutionResult>;
288
+ }
289
+ declare class ClientTokenSaleNamespaceImpl extends TokenSaleNamespaceImpl implements CoinListClientTokenSaleNamespace {
290
+ private readonly erc20;
291
+ constructor(ctx: SharedNamespaceContext, erc20: CoinListErc20Namespace);
292
+ executeTokenSale(params: Omit<ExecuteTokenSaleParams, 'erc20' | 'tokenSale'>): Promise<TokenSaleExecutionResult>;
293
+ }
294
+
203
295
  type AuthState = 'unknown' | 'logged-in' | 'logged-out';
204
296
  /** Discriminated error reasons from {@link CoinListClient.completeOAuth}. */
205
297
  type OauthClientErrorReason = 'user_canceled' | 'missing_state' | 'invalid_state' | 'missing_code' | 'missing_code_verifier';
@@ -297,38 +389,6 @@ interface CoinListClient {
297
389
  * {@link NotAuthenticatedError}.
298
390
  */
299
391
  fetchOfferDetails(id: OfferId): Promise<OfferDetail>;
300
- /**
301
- * Fetches all participations by iterating through every paginated response.
302
- *
303
- * This method must be called only when the user's {@link AuthState} is
304
- * `'logged-in'`. If the user is not authenticated, it throws
305
- * {@link NotAuthenticatedError}.
306
- */
307
- fetchParticipations(offerId?: OfferId): Promise<Participation[]>;
308
- /**
309
- * Fetches a single page of participations, optionally filtered by offer.
310
- *
311
- * This method must be called only when the user's {@link AuthState} is
312
- * `'logged-in'`. If the user is not authenticated, it throws
313
- * {@link NotAuthenticatedError}.
314
- */
315
- fetchParticipationsPage(params: ParticipationsPaginationParams): Promise<PaginatedResponse<Participation>>;
316
- /**
317
- * Fetches a participation by id.
318
- *
319
- * This method must be called only when the user's {@link AuthState} is
320
- * `'logged-in'`. If the user is not authenticated, it throws
321
- * {@link NotAuthenticatedError}.
322
- */
323
- fetchParticipation(id: ParticipationId): Promise<Participation>;
324
- /**
325
- * Creates a participation.
326
- *
327
- * This method must be called only when the user's {@link AuthState} is
328
- * `'logged-in'`. If the user is not authenticated, it throws
329
- * {@link NotAuthenticatedError}.
330
- */
331
- createParticipation(params: CreateParticipationParams): Promise<Participation>;
332
392
  /**
333
393
  * Creates a single-use wallet-ownership challenge for the given wallet and
334
394
  * chain. The user signs the returned {@link WalletOwnershipChallenge.message}
@@ -430,8 +490,30 @@ interface CoinListClient {
430
490
  */
431
491
  contactSupport(): void;
432
492
  /**
433
- * On-chain swap operations: quoting a swap, reading swap-contract state and
434
- * token allowances, and proving/allow-listing wallet ownership — e.g.
493
+ * Generic ERC-20 reads (token allowance and balance) shared across the
494
+ * on-chain flows — e.g. `coinlist.erc20.getTokenBalance({ ... })`.
495
+ *
496
+ * These reads must be called only when the user's {@link AuthState} is
497
+ * `'logged-in'`; if the user is not authenticated, they throw
498
+ * {@link NotAuthenticatedError}.
499
+ */
500
+ readonly erc20: CoinListErc20Namespace;
501
+ /**
502
+ * Token-sale operations: listing/reading/recording participations, plus the
503
+ * on-chain `executeTokenSale` flow that submits the ERC-20 approval and
504
+ * records the participation over a caller-supplied {@link EvmWallet} —
505
+ * e.g. `coinlist.tokenSale.executeTokenSale({ ... })`.
506
+ *
507
+ * The API-backed reads/writes must be called only when the user's
508
+ * {@link AuthState} is `'logged-in'`; if the user is not authenticated, they
509
+ * throw {@link NotAuthenticatedError}. `executeTokenSale` additionally drives
510
+ * a caller-supplied wallet and returns a step-tagged result rather than
511
+ * throwing.
512
+ */
513
+ readonly tokenSale: CoinListClientTokenSaleNamespace;
514
+ /**
515
+ * On-chain swap operations: quoting a swap, reading swap-contract state, and
516
+ * proving/allow-listing wallet ownership — e.g.
435
517
  * `coinlist.swap.getOutputToken({ contractAddress, chain })`.
436
518
  *
437
519
  * The API-backed reads must be called only when the user's {@link AuthState}
@@ -520,11 +602,11 @@ interface CoinListSignInCardProps {
520
602
  declare function CoinListSignInCard({ state, onSignIn, onClose, className, }?: CoinListSignInCardProps): ReactNode;
521
603
 
522
604
  type OfferCardUi = {
523
- tagline: string | null;
524
- bannerUrl: string | null;
525
- logoUrl: string | null;
605
+ tagline: string;
606
+ bannerUrl: string;
607
+ logoUrl: string;
526
608
  formattedStartsAt: string;
527
- formattedEndsAt: string;
609
+ formattedEndsAt: string | null;
528
610
  };
529
611
  declare const OfferCardUi: {
530
612
  fromDomain: (offer: Offer) => OfferCardUi;
@@ -1438,4 +1520,4 @@ interface UseTaxDocumentResult {
1438
1520
  */
1439
1521
  declare function useTaxDocument({ isOpen, }: UseTaxDocumentOptions): UseTaxDocumentResult;
1440
1522
 
1441
- export { type AuthState, type AuthorizeWalletParams, type BroadcastTxParams, ChecklistStatus, type ClientConfig, ClientSwapNamespaceImpl, type CoinListClient, CoinListClientInitializationError, type CoinListClientSwapNamespace, CoinListContext, CoinListContextProvider, type CoinListContextValue, CoinListProvider, type CoinListProviderProps, CoinListSignInCard, type CoinListSignInCardProps, CoinListStyleScope, type CoinListStyleScopeProps, type CompleteOAuthFailureReason, type ConnectWallet, type ConnectWalletError, type ConnectWalletErrorCode, type ConnectWalletFlowError, type ConnectWalletFlowParams, type ConnectWalletFlowResult, ConnectWalletModal, type ConnectWalletModalProps, type ConnectWalletPhase, type ConnectWalletSignState, type ConnectWalletState, ConnectedWalletList, type ConnectedWalletListProps, type ConnectedWalletUi, type EvmSigner, type EvmWallet, type ExecuteSwapParams, IdentityVerification, type IdentityVerificationProps, KycLevelName, KycToken, type KycTokenErrorReason, type KycTokenState, type LoadOfferDetailsReason, type LoadOfferDetailsState, type LoadOffersReason, type LoadOffersState, type LoadOptionAddressesReason, type LoadOptionAddressesState, type LoadParticipationsReason, type LoadParticipationsState, type LoadRequirementsReason, type LoadRequirementsState, OAUTH_CODE_VERIFIER_KEY, OAUTH_STATE_KEY, type OauthClientErrorReason, type OauthClientResult, OfferCard, type Props as OfferCardProps, OfferCardUi, OffersGrid, type OffersGridProps, RequirementItem, type RequirementItemProps, RequirementItemUi, RequirementStatus, RequirementVariant, RequirementsChecklist, type RequirementsChecklistProps, type RequirementsData, type SignState, type SwapExecutionError, type SwapExecutionPhase, type SwapExecutionResult, type SwapOutputTokenState, type TaxDocumentAddressParts, type TaxDocumentFields, TaxDocumentModal, type TaxDocumentModalProps, type TaxDocumentState, type UseCoinListResult, type UseCompleteOAuthOptions, type UseConnectWalletOptions, type UseConnectWalletResult, type UseKycTokenResult, type UseOfferDetailsOptions, type UseOfferDetailsResult, type UseOffersOptions, type UseOffersResult, type UseOptionAddressesOptions, type UseOptionAddressesResult, type UseParticipationsOptions, type UseParticipationsResult, type UseRequirementsOptions, type UseRequirementsResult, type UseSwapOutputTokenOptions, type UseSwapOutputTokenResult, type UseSwapQuoteOptions, type UseSwapQuoteResult, type UseSwapTokenBalancesOptions, type UseSwapTokenBalancesResult, type UseTaxDocumentOptions, type UseTaxDocumentResult, type WalletAuthorizationError, type WalletAuthorizationPhase, type WalletAuthorizationResult, type WalletError, type WalletsStatus, type WriteContractParams, authorizeWallet, classifyWalletError, connectExternalWalletFlow, createCoinListClient, executeSwap, useCoinList, useCompleteOAuth, useConnectWallet, useKycToken, useOfferDetails, useOffers, useOptionAddresses, useParticipations, useRequirements, useSwapOutputToken, useSwapQuote, useSwapTokenBalances, useTaxDocument };
1523
+ export { type AuthState, type AuthorizeWalletParams, type BroadcastTxParams, ChecklistStatus, type ClientConfig, ClientSwapNamespaceImpl, ClientTokenSaleNamespaceImpl, type CoinListClient, CoinListClientInitializationError, type CoinListClientSwapNamespace, type CoinListClientTokenSaleNamespace, CoinListContext, CoinListContextProvider, type CoinListContextValue, CoinListProvider, type CoinListProviderProps, CoinListSignInCard, type CoinListSignInCardProps, CoinListStyleScope, type CoinListStyleScopeProps, type CompleteOAuthFailureReason, type ConnectWallet, type ConnectWalletError, type ConnectWalletErrorCode, type ConnectWalletFlowError, type ConnectWalletFlowParams, type ConnectWalletFlowResult, ConnectWalletModal, type ConnectWalletModalProps, type ConnectWalletPhase, type ConnectWalletSignState, type ConnectWalletState, ConnectedWalletList, type ConnectedWalletListProps, type ConnectedWalletUi, type EvmSigner, type EvmWallet, type ExecuteSwapParams, type ExecuteTokenSaleParams, IdentityVerification, type IdentityVerificationProps, KycLevelName, KycToken, type KycTokenErrorReason, type KycTokenState, type LoadOfferDetailsReason, type LoadOfferDetailsState, type LoadOffersReason, type LoadOffersState, type LoadOptionAddressesReason, type LoadOptionAddressesState, type LoadParticipationsReason, type LoadParticipationsState, type LoadRequirementsReason, type LoadRequirementsState, OAUTH_CODE_VERIFIER_KEY, OAUTH_STATE_KEY, type OauthClientErrorReason, type OauthClientResult, OfferCard, type Props as OfferCardProps, OfferCardUi, OffersGrid, type OffersGridProps, RequirementItem, type RequirementItemProps, RequirementItemUi, RequirementStatus, RequirementVariant, RequirementsChecklist, type RequirementsChecklistProps, type RequirementsData, type SignState, type SwapExecutionError, type SwapExecutionPhase, type SwapExecutionResult, type SwapOutputTokenState, type TaxDocumentAddressParts, type TaxDocumentFields, TaxDocumentModal, type TaxDocumentModalProps, type TaxDocumentState, type TokenSaleExecutionError, type TokenSaleExecutionPhase, type TokenSaleExecutionResult, type UseCoinListResult, type UseCompleteOAuthOptions, type UseConnectWalletOptions, type UseConnectWalletResult, type UseKycTokenResult, type UseOfferDetailsOptions, type UseOfferDetailsResult, type UseOffersOptions, type UseOffersResult, type UseOptionAddressesOptions, type UseOptionAddressesResult, type UseParticipationsOptions, type UseParticipationsResult, type UseRequirementsOptions, type UseRequirementsResult, type UseSwapOutputTokenOptions, type UseSwapOutputTokenResult, type UseSwapQuoteOptions, type UseSwapQuoteResult, type UseSwapTokenBalancesOptions, type UseSwapTokenBalancesResult, type UseTaxDocumentOptions, type UseTaxDocumentResult, type WalletAuthorizationError, type WalletAuthorizationPhase, type WalletAuthorizationResult, type WalletError, type WalletsStatus, type WriteContractParams, authorizeWallet, classifyWalletError, connectExternalWalletFlow, createCoinListClient, executeSwap, executeTokenSale, useCoinList, useCompleteOAuth, useConnectWallet, useKycToken, useOfferDetails, useOffers, useOptionAddresses, useParticipations, useRequirements, useSwapOutputToken, useSwapQuote, useSwapTokenBalances, useTaxDocument };