@usdctofiat/offramp 4.4.5 → 4.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -1
- package/README.md +7 -17
- package/dist/{chunk-4KM2I2HC.js → chunk-4DUIEYWQ.js} +8 -2
- package/dist/chunk-4DUIEYWQ.js.map +1 -0
- package/dist/{errors-B-Gaf0US.d.cts → errors-DyGBQpGY.d.cts} +2 -1
- package/dist/{errors-B-Gaf0US.d.ts → errors-DyGBQpGY.d.ts} +2 -1
- package/dist/index.cjs +14 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -5
- package/dist/index.d.ts +3 -5
- package/dist/index.js +8 -57
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +19 -8
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +5 -2
- package/dist/react.d.ts +5 -2
- package/dist/react.js +13 -8
- package/dist/react.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-4KM2I2HC.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,28 @@ All notable changes to `@usdctofiat/offramp` will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Align `@zkp2p/sdk` to `0.8.0` and pass `callerAddress` through Peer
|
|
13
|
+
extension seller-credential capture so the SDK follows upstream credential
|
|
14
|
+
bundle and Wise identity-attestation registration behavior.
|
|
15
|
+
|
|
16
|
+
### Removed
|
|
17
|
+
|
|
18
|
+
- Remove outbound webhook playbooks and docs from the developer resource bundle.
|
|
19
|
+
Lifecycle state is now reconciled with `deposits(address)` and Peerlytics
|
|
20
|
+
deposit/intent reads.
|
|
21
|
+
|
|
22
|
+
## [4.4.6] - 2026-07-03
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- Align the published package dependency and developer-resource metadata on
|
|
27
|
+
`@zkp2p/sdk` to `0.7.2`, matching the current USDCtoFiat app surface and
|
|
28
|
+
upstream ZKP2P SDK release line.
|
|
29
|
+
|
|
8
30
|
## [4.4.5] - 2026-07-01
|
|
9
31
|
|
|
10
32
|
### Fixed
|
|
@@ -263,7 +285,7 @@ if (prepared?.status === "calldata_ready") {
|
|
|
263
285
|
### Docs
|
|
264
286
|
|
|
265
287
|
- Lead the agent bundle with the developer portal (`https://usdctofiat.xyz/developers`) so human integrators landing on npm have a one-click path to the polished docs surface, then drop into skills and `llms-full.txt`.
|
|
266
|
-
- Call out the symmetric Peerlytics relationship: one Peerlytics API key authenticates
|
|
288
|
+
- Call out the symmetric Peerlytics relationship: one Peerlytics API key authenticates the paid Peerlytics v1 API for lifecycle reads and analytics.
|
|
267
289
|
- Bump `SDK_VERSION` to track package version (enforced by `scripts/check-version.mjs`).
|
|
268
290
|
|
|
269
291
|
## [2.0.3] - 2026-04-25
|
package/README.md
CHANGED
|
@@ -15,8 +15,8 @@ If you are integrating through an agent (Claude Code, Cursor, etc.), start here:
|
|
|
15
15
|
- Short machine reference: <https://usdctofiat.xyz/llms.txt>
|
|
16
16
|
- Full machine reference: <https://usdctofiat.xyz/llms-full.txt>
|
|
17
17
|
- Scaffold CLI: `npx create-offramp-app@latest my-app --template=next|vite|telegram-bot`
|
|
18
|
-
- Starters (Next.js / Vite / Telegram bot, plus runnable example scripts
|
|
19
|
-
- Companion SDK for analytics + explorer: [`@peerlytics/sdk`](https://www.npmjs.com/package/@peerlytics/sdk)
|
|
18
|
+
- Starters (Next.js / Vite / Telegram bot, plus runnable example scripts): <https://github.com/ADWilkinson/usdctofiat-peerlytics-starters>
|
|
19
|
+
- Companion SDK for analytics + explorer: [`@peerlytics/sdk`](https://www.npmjs.com/package/@peerlytics/sdk)
|
|
20
20
|
|
|
21
21
|
The SDK also exports a typed resource map for self-serve products and coding agents:
|
|
22
22
|
|
|
@@ -27,11 +27,11 @@ OFFRAMP_DEVELOPER_RESOURCES.delegation.required; // true
|
|
|
27
27
|
OFFRAMP_DEVELOPER_RESOURCES.delegation.feeRateBps; // 10
|
|
28
28
|
OFFRAMP_DEVELOPER_RESOURCES.links.agentSkill; // https://usdctofiat.xyz/skills/usdctofiat.md
|
|
29
29
|
OFFRAMP_DEVELOPER_RESOURCES.upstreamSourceTruths.map((source) => source.label);
|
|
30
|
-
// ["@zkp2p/sdk 0.
|
|
30
|
+
// ["@zkp2p/sdk 0.8.0", "Curator API", ...]
|
|
31
31
|
OFFRAMP_DEVELOPER_RESOURCES.checklist.map((item) => item.title); // integration doctor
|
|
32
32
|
|
|
33
33
|
const botPlaybook = getOfframpDeveloperResources("bot");
|
|
34
|
-
// profile-specific steps + canonical docs/starters
|
|
34
|
+
// profile-specific steps + canonical docs/starters resources
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
Use `upstreamSourceTruths` before generating protocol-sensitive code. It points
|
|
@@ -136,8 +136,7 @@ CURRENCIES.EUR.countryCode; // "eu"
|
|
|
136
136
|
- bot: server-wallet and automation flows
|
|
137
137
|
- agent: skill, `llms.txt`, and starter-template routing for coding agents
|
|
138
138
|
- private-otc: one-buyer deposits with whitelist enforcement
|
|
139
|
-
-
|
|
140
|
-
- peerlytics: paid protocol API, analytics, orderbook, credits, and webhooks
|
|
139
|
+
- peerlytics: paid protocol API, analytics, orderbook, credits, deposits, and intents
|
|
141
140
|
|
|
142
141
|
This is intentionally duplicated into the package so integrators can expose
|
|
143
142
|
docs, help menus, agent context, or onboarding checklists without scraping the
|
|
@@ -374,18 +373,9 @@ await sdk.createDeposit({
|
|
|
374
373
|
});
|
|
375
374
|
```
|
|
376
375
|
|
|
377
|
-
##
|
|
376
|
+
## Lifecycle State
|
|
378
377
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
There are **two separate webhook families** — different event vocabularies, different dispatchers, different registration surfaces. Pick the one for the product you integrate:
|
|
382
|
-
|
|
383
|
-
| Family | Events | Emitted by | Register at |
|
|
384
|
-
| ----------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ----------------------------- | -------------------------------------------------------------- |
|
|
385
|
-
| **Offramp** (this SDK) | `deposit.created`, `deposit.filled`, `deposit.partially_filled`, `deposit.closed`, `otc.taken` | usdctofiat offramp dispatcher | [usdctofiat.xyz/developers](https://usdctofiat.xyz/developers) |
|
|
386
|
-
| **Integrator** ([`@peerlytics/sdk`](https://www.npmjs.com/package/@peerlytics/sdk)) | `deposit.created`, `intent.signaled`, `intent.fulfilled` | Peerlytics cron dispatcher | [peerlytics.xyz/developers](https://peerlytics.xyz/developers) |
|
|
387
|
-
|
|
388
|
-
One Peerlytics API key authenticates both. The integrator family also accepts the legacy aliases `intent.created` and `intent.filled` on registration (normalized server-side). Rate updates are activity-feed events, not webhook fanout.
|
|
378
|
+
Use `deposits(address)` for seller-owned deposit reconciliation. Use [`@peerlytics/sdk`](https://www.npmjs.com/package/@peerlytics/sdk) when your product needs broader deposit, intent, orderbook, or explorer reads.
|
|
389
379
|
|
|
390
380
|
## Links
|
|
391
381
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/config.ts
|
|
2
2
|
import { getContracts, getGatingServiceAddress } from "@zkp2p/sdk";
|
|
3
|
-
var SDK_VERSION = "4.4.
|
|
3
|
+
var SDK_VERSION = "4.4.7";
|
|
4
4
|
var BASE_CHAIN_ID = 8453;
|
|
5
5
|
var RUNTIME_ENV = "production";
|
|
6
6
|
var API_BASE_URL = "https://api.zkp2p.xyz";
|
|
@@ -401,6 +401,7 @@ function getPeerExtensionRegistrationInfo(platform) {
|
|
|
401
401
|
function getPeerExtensionRegistrationAuthParams(platform, options = {}) {
|
|
402
402
|
const info = getPeerExtensionRegistrationInfo(platform);
|
|
403
403
|
if (!info) return null;
|
|
404
|
+
const callerAddress = options.callerAddress?.trim();
|
|
404
405
|
const params = {
|
|
405
406
|
actionType: `transfer_${info.providerId}`,
|
|
406
407
|
captureMode: "sellerCredential",
|
|
@@ -409,6 +410,9 @@ function getPeerExtensionRegistrationAuthParams(platform, options = {}) {
|
|
|
409
410
|
if (options.attestationServiceUrl) {
|
|
410
411
|
params.attestationServiceUrl = options.attestationServiceUrl;
|
|
411
412
|
}
|
|
413
|
+
if (callerAddress) {
|
|
414
|
+
params.callerAddress = callerAddress;
|
|
415
|
+
}
|
|
412
416
|
return params;
|
|
413
417
|
}
|
|
414
418
|
function resolveRegistrationProcessor(platform) {
|
|
@@ -510,12 +514,14 @@ async function completePeerExtensionRegistration(input) {
|
|
|
510
514
|
};
|
|
511
515
|
}
|
|
512
516
|
var EXTENSION_REGISTRATION_ERROR_PATTERNS = ["creating the maker", "create the maker"];
|
|
517
|
+
var isWiseIdentityAttestationRequiredError = (message) => message.toLowerCase().includes("identityattestation is required");
|
|
513
518
|
function isPeerExtensionRegistrationError(platform, message, statusCode) {
|
|
514
519
|
const info = getPeerExtensionRegistrationInfo(platform);
|
|
515
520
|
if (!info) return false;
|
|
516
521
|
if (statusCode === 400) return true;
|
|
517
522
|
const normalized = (message ?? "").trim();
|
|
518
523
|
if (!normalized) return false;
|
|
524
|
+
if (platform === "wise" && isWiseIdentityAttestationRequiredError(normalized)) return true;
|
|
519
525
|
const lower = normalized.toLowerCase();
|
|
520
526
|
return EXTENSION_REGISTRATION_ERROR_PATTERNS.some((p) => lower.includes(p));
|
|
521
527
|
}
|
|
@@ -1671,4 +1677,4 @@ export {
|
|
|
1671
1677
|
createPeerExtensionSdk,
|
|
1672
1678
|
peerExtensionSdk
|
|
1673
1679
|
};
|
|
1674
|
-
//# sourceMappingURL=chunk-
|
|
1680
|
+
//# sourceMappingURL=chunk-4DUIEYWQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/errors.ts","../src/platforms.ts","../src/otc.ts","../src/sdk-client.ts","../src/queries.ts","../src/telemetry.ts","../src/deposit.ts","../src/currencies.ts","../src/offramp.ts","../src/extension.ts"],"sourcesContent":["import { getContracts, getGatingServiceAddress } from \"@zkp2p/sdk\";\n\n// Keep in sync with package.json — enforced by scripts/check-version.mjs on prepublish.\nexport const SDK_VERSION = \"4.4.7\";\nexport const BASE_CHAIN_ID = 8453;\nexport const RUNTIME_ENV = \"production\" as const;\nexport const API_BASE_URL = \"https://api.zkp2p.xyz\";\nexport const ATTESTATION_SERVICE_URL = \"https://attestation-service.zkp2p.xyz\";\nexport const BASE_RPC_URL = \"https://mainnet.base.org\";\n\n/**\n * Resolve the curator REST base URL for maker registration/validation calls.\n *\n * Returns `API_BASE_URL` unchanged when no override is supplied, so default\n * behavior is byte-for-byte identical. A non-empty override is trimmed and has\n * any trailing slash stripped (mirrors `@peerlytics/sdk`). Only the curator\n * REST surface is overridable — the indexer and Base RPC always target mainnet.\n */\nexport function resolveApiBaseUrl(override?: string): string {\n const trimmed = override?.trim();\n return (trimmed && trimmed.length > 0 ? trimmed : API_BASE_URL).replace(/\\/$/, \"\");\n}\n\nconst contracts = getContracts(BASE_CHAIN_ID, RUNTIME_ENV);\nconst addresses = contracts.addresses;\n\nconst addrs = addresses as unknown as Record<string, string>;\nexport const USDC_ADDRESS = (addrs.token ||\n \"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913\") as `0x${string}`;\nexport const ESCROW_ADDRESS = (addrs.escrowV2 || addrs.escrow || \"\") as `0x${string}`;\nexport const GATING_SERVICE_ADDRESS = getGatingServiceAddress(\n BASE_CHAIN_ID,\n RUNTIME_ENV,\n) as `0x${string}`;\n\nexport const DELEGATE_RATE_MANAGER_ID =\n \"0x8666d6fb0f6797c56e95339fd7ca82fdd348b9db200e10a4c4aa0a0b879fc41c\" as `0x${string}`;\nexport const RATE_MANAGER_REGISTRY_ADDRESS =\n \"0xeed7db23e724ac4590d6db6f78fda6db203535f3\" as `0x${string}`;\nexport const DELEGATE_MANAGER_FEE_BPS = 10;\n\n// Mirrors `DEFAULT_INTENT_GUARDIAN_ADDRESS` from zkp2p-clients\n// (`packages/core/src/constants/index.ts`) so SDK-created deposits share the\n// canonical guardian instead of falling back to ZERO_ADDRESS at the contract.\nexport const DEFAULT_INTENT_GUARDIAN_ADDRESS =\n \"0xe29a5BD4D0CEbA6C125A0361E7D20ab4eA275C2f\" as `0x${string}`;\n\nexport const REFERRER = \"galleonlabs\";\n\nexport const MIN_DEPOSIT_USDC = 1;\nexport const MIN_ORDER_USDC = 1;\nexport const MAX_ORDER_USDC = 2500;\n\nexport const INDEXER_MAX_ATTEMPTS = 12;\nexport const INDEXER_INITIAL_DELAY_MS = 1000;\nexport const INDEXER_MAX_DELAY_MS = 10_000;\n\nexport const PAYEE_REGISTRATION_TIMEOUT_MS = 8000;\n","import type { OfframpErrorCode, OfframpStep } from \"./types\";\n\n/**\n * Error thrown when curator's `/v2/makers/create` returns a non-success\n * response. Preserves the HTTP status so callers can distinguish a\n * \"needs Peer-extension registration\" 400 from a transient server error.\n *\n * `offramp()` re-raises this as an {@link OfframpError} with code\n * `EXTENSION_REGISTRATION_REQUIRED` (for PayPal/Wise 400s) or\n * `REGISTRATION_FAILED` (for any other curator error); `MakersCreateError`\n * is attached as the `cause`.\n */\nexport class MakersCreateError extends Error {\n readonly status: number | null;\n readonly body: string;\n\n constructor(message: string, status: number | null, body: string) {\n super(message);\n this.name = \"MakersCreateError\";\n this.status = status;\n this.body = body;\n }\n}\n\nexport class OfframpError extends Error {\n readonly code: OfframpErrorCode;\n readonly step?: OfframpStep;\n readonly cause?: unknown;\n readonly txHash?: string;\n readonly depositId?: string;\n\n constructor(\n message: string,\n code: OfframpErrorCode,\n step?: OfframpStep,\n cause?: unknown,\n details?: { txHash?: string; depositId?: string },\n ) {\n super(message);\n this.name = \"OfframpError\";\n this.code = code;\n this.step = step;\n this.cause = cause;\n this.txHash = details?.txHash;\n this.depositId = details?.depositId;\n }\n}\n\nexport function isUserCancellation(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n const msg = error.message.toLowerCase();\n return (\n msg.includes(\"user rejected\") ||\n msg.includes(\"user denied\") ||\n msg.includes(\"user cancelled\") ||\n msg.includes(\"rejected the request\") ||\n msg.includes(\"action_rejected\")\n );\n}\n","import {\n apiUploadSellerCredentialBundle,\n type CuratorSellerCredentialUploadResponse,\n type UploadSellerCredentialBundleParams,\n currencyInfo,\n getCurrencyInfoFromHash,\n getPaymentMethodsCatalog,\n resolvePaymentMethodHash,\n} from \"@zkp2p/sdk\";\nimport { z } from \"zod\";\nimport { API_BASE_URL, BASE_CHAIN_ID, PAYEE_REGISTRATION_TIMEOUT_MS, RUNTIME_ENV } from \"./config\";\nimport { MakersCreateError } from \"./errors\";\nimport type {\n PeerAuthenticateParams,\n PeerMetadataMessage,\n PeerSarCredentialBundle,\n PeerSarCredentialCapture,\n} from \"./extension\";\n\n/* ── Internal types ───────────────────────────────────────────────── */\n\ntype CatalogEntry = { currencies?: string[]; paymentMethodHash?: `0x${string}` };\nconst PAYMENT_CATALOG = getPaymentMethodsCatalog(BASE_CHAIN_ID, RUNTIME_ENV) as Record<\n string,\n CatalogEntry\n>;\n\ntype CurrencyCode = keyof typeof currencyInfo;\n\nconst ZELLE_HASH_LOOKUP_NAMES = [\"zelle\", \"zelle-bofa\", \"zelle-chase\", \"zelle-citi\"] as const;\ntype PaymentMethodLookupName = PlatformId | (typeof ZELLE_HASH_LOOKUP_NAMES)[number];\n\ntype PlatformId =\n | \"venmo\"\n | \"cashapp\"\n | \"chime\"\n | \"revolut\"\n | \"wise\"\n | \"mercadopago\"\n | \"zelle\"\n | \"paypal\"\n | \"monzo\";\ntype SellerCredentialProcessor = \"paypal\" | \"wise\" | \"venmo\" | \"cashapp\";\n\n/* ── Platform entry type ──────────────────────────────────────────── */\n\n/**\n * Extension pre-registration requirement for a platform. When present,\n * curator's `/v2/makers/create` rejects the maker until the user has\n * registered their handle with PeerAuth.\n */\nexport interface PeerExtensionRegistrationInfo {\n /** Peer extension provider id. */\n readonly providerId: string;\n /** Message shown to the user when curator rejects the maker. */\n readonly requiredPrompt: string;\n /** Label for the registration CTA. */\n readonly ctaLabel: string;\n /** Optional subtext (e.g. PayPal Business disclaimer). */\n readonly ctaSubtext?: string;\n}\n\nexport interface PlatformEntry {\n readonly id: PlatformId;\n readonly name: string;\n readonly currencies: readonly string[];\n readonly identifier: {\n readonly label: string;\n readonly placeholder: string;\n readonly help: string;\n };\n /** Set for platforms that require Peer extension registration (PayPal, Wise). */\n readonly extensionRegistration?: PeerExtensionRegistrationInfo;\n validate(input: string): { valid: boolean; normalized: string; error?: string };\n}\n\n/* ── Currency resolution ──────────────────────────────────────────── */\n\nconst FALLBACK_CURRENCIES: Record<PlatformId, string[]> = {\n venmo: [\"USD\"],\n cashapp: [\"USD\"],\n chime: [\"USD\"],\n revolut: [\n \"USD\",\n \"EUR\",\n \"GBP\",\n \"SGD\",\n \"NZD\",\n \"AUD\",\n \"CAD\",\n \"HKD\",\n \"MXN\",\n \"SAR\",\n \"AED\",\n \"THB\",\n \"TRY\",\n \"PLN\",\n \"CHF\",\n \"ZAR\",\n \"CZK\",\n \"CNY\",\n \"DKK\",\n \"HUF\",\n \"NOK\",\n \"RON\",\n \"SEK\",\n ],\n wise: [\n \"USD\",\n \"CNY\",\n \"EUR\",\n \"GBP\",\n \"AUD\",\n \"NZD\",\n \"CAD\",\n \"AED\",\n \"CHF\",\n \"ZAR\",\n \"SGD\",\n \"ILS\",\n \"HKD\",\n \"JPY\",\n \"PLN\",\n \"TRY\",\n \"IDR\",\n \"KES\",\n \"MYR\",\n \"MXN\",\n \"THB\",\n \"VND\",\n \"UGX\",\n \"CZK\",\n \"DKK\",\n \"HUF\",\n \"INR\",\n \"NOK\",\n \"PHP\",\n \"RON\",\n \"SEK\",\n ],\n mercadopago: [\"ARS\"],\n zelle: [\"USD\"],\n paypal: [\"USD\", \"EUR\", \"GBP\", \"SGD\", \"NZD\", \"AUD\", \"CAD\"],\n monzo: [\"GBP\"],\n};\n\nfunction gatherCatalogHashes(platform: PlatformId): string[] {\n if (platform === \"zelle\") {\n return Object.entries(PAYMENT_CATALOG)\n .filter(([key]) => key.startsWith(\"zelle\"))\n .flatMap(([, entry]) => entry.currencies ?? []);\n }\n return PAYMENT_CATALOG[platform]?.currencies ?? [];\n}\n\nfunction resolveSupportedCurrencies(platform: PlatformId): string[] {\n const codes = new Set<string>();\n for (const hash of gatherCatalogHashes(platform)) {\n const info = getCurrencyInfoFromHash(hash);\n if (info?.currencyCode && currencyInfo[info.currencyCode as CurrencyCode]) {\n codes.add(info.currencyCode);\n }\n }\n if (!codes.size) {\n for (const code of FALLBACK_CURRENCIES[platform] ?? []) codes.add(code);\n }\n return Array.from(codes).sort();\n}\n\n/* ── PayPal.me username normalizer ────────────────────────────────── */\n\n/**\n * Extracts the bare PayPal.me username from any accepted input shape\n * (`paypal.me/user`, `https://paypal.me/user`, `@user`, `user`). Mirrors the\n * upstream zkp2p-clients normalizer so our offchainId hashes identically.\n */\nexport function normalizePaypalMeUsername(value: string): string {\n const trimmed = value.trim();\n if (!trimmed) return \"\";\n const withoutProtocol = trimmed.replace(/^https?:\\/\\//i, \"\");\n const [pathWithoutQuery] = withoutProtocol.split(/[?#]/, 1);\n const sanitizedPath = pathWithoutQuery.replace(/^\\/+/, \"\");\n const [host = \"\", ...pathSegments] = sanitizedPath.split(\"/\");\n const normalizedHost = host.toLowerCase().replace(/^www\\./i, \"\");\n\n if (normalizedHost === \"paypal.me\") {\n const [username = \"\"] = pathSegments;\n return username.replace(/^@+/, \"\").trim().toLowerCase();\n }\n\n if (normalizedHost === \"paypal.com\") {\n const [paypalMePath = \"\", username = \"\"] = pathSegments;\n if (paypalMePath.toLowerCase() !== \"paypalme\") return \"\";\n return username.replace(/^@+/, \"\").trim().toLowerCase();\n }\n\n if (/^https?:\\/\\//i.test(trimmed) || trimmed.includes(\"/\")) {\n return trimmed;\n }\n\n return trimmed.replace(/^@+/, \"\").toLowerCase();\n}\n\n/* ── Validation schemas ───────────────────────────────────────────── */\n\ninterface PlatformBlueprint {\n id: PlatformId;\n name: string;\n identifierLabel: string;\n placeholder: string;\n helperText: string;\n validation: z.ZodType<string>;\n transform?: (value: string) => string;\n extensionRegistration?: PeerExtensionRegistrationInfo;\n}\n\nconst BLUEPRINTS: Record<PlatformId, PlatformBlueprint> = {\n venmo: {\n id: \"venmo\",\n name: \"Venmo\",\n identifierLabel: \"Username\",\n placeholder: \"venmo username (no @)\",\n helperText: \"Username without @ (publicly discoverable)\",\n validation: z\n .string()\n .min(1)\n .regex(/^[a-zA-Z0-9_-]+$/),\n transform: (v) => v.replace(/^@+/, \"\"),\n extensionRegistration: {\n providerId: \"venmo\",\n requiredPrompt:\n \"This Venmo username is not registered yet. Register it with PeerAuth, then retry with the same Venmo username.\",\n ctaLabel: \"Register Venmo Username\",\n },\n },\n cashapp: {\n id: \"cashapp\",\n name: \"Cash App\",\n identifierLabel: \"Cashtag\",\n placeholder: \"cashtag (no $)\",\n helperText: \"Cashtag without $ (publicly discoverable)\",\n validation: z\n .string()\n .min(1)\n .regex(/^[a-zA-Z0-9]+$/),\n transform: (v) => v.replace(/^\\$+/, \"\"),\n extensionRegistration: {\n providerId: \"cashapp\",\n requiredPrompt:\n \"This Cash App cashtag is not registered yet. Register it with PeerAuth, then retry with the same cashtag.\",\n ctaLabel: \"Register Cash App Cashtag\",\n },\n },\n chime: {\n id: \"chime\",\n name: \"Chime\",\n identifierLabel: \"ChimeSign\",\n placeholder: \"$chimesign\",\n helperText: \"ChimeSign with $ (must be discoverable)\",\n validation: z\n .string()\n .min(2)\n .regex(/^\\$[a-zA-Z0-9]+$/),\n transform: (v) => {\n const t = v.trim().toLowerCase();\n return t.startsWith(\"$\") ? t : `$${t}`;\n },\n },\n revolut: {\n id: \"revolut\",\n name: \"Revolut\",\n identifierLabel: \"Revtag\",\n placeholder: \"revtag (no @)\",\n helperText: \"Revtag without @ (must be public)\",\n validation: z\n .string()\n .min(1)\n .regex(/^[a-zA-Z0-9]+$/),\n transform: (v) => v.replace(/^@+/, \"\").trim(),\n },\n wise: {\n id: \"wise\",\n name: \"Wise\",\n identifierLabel: \"Wisetag\",\n placeholder: \"wisetag (no @)\",\n helperText: \"Your Wise @wisetag (no @)\",\n validation: z\n .string()\n .min(1)\n .regex(/^[a-zA-Z0-9_-]+$/),\n transform: (v) => v.replace(/^@+/, \"\").trim(),\n extensionRegistration: {\n providerId: \"wise\",\n requiredPrompt:\n \"This Wisetag is not registered yet. Register it with PeerAuth, then retry with the same Wisetag.\",\n ctaLabel: \"Register Wisetag\",\n },\n },\n mercadopago: {\n id: \"mercadopago\",\n name: \"Mercado Pago\",\n identifierLabel: \"CVU\",\n placeholder: \"22-digit CVU\",\n helperText: \"CVU must be exactly 22 digits\",\n validation: z\n .string()\n .length(22)\n .regex(/^\\d{22}$/),\n },\n zelle: {\n id: \"zelle\",\n name: \"Zelle\",\n identifierLabel: \"Email\",\n placeholder: \"email\",\n helperText: \"Registered Zelle email\",\n // Curator's ZelleProcessor rejects any non-lowercase email outright, so\n // canonicalize to lowercase here rather than letting /v2/makers/create\n // reject after the maker has already approved USDC + paid gas.\n validation: z.string().email(),\n transform: (v) => v.trim().toLowerCase(),\n },\n paypal: {\n id: \"paypal\",\n name: \"PayPal\",\n identifierLabel: \"PayPal.me Username\",\n placeholder: \"paypal.me/your-username\",\n helperText: \"Your PayPal.me username, not your email\",\n validation: z\n .string()\n .min(1, \"PayPal.me username is required\")\n .regex(\n /^[a-z0-9._-]+$/i,\n \"Use your PayPal.me username or paypal.me link, not a shortened URL.\",\n ),\n transform: normalizePaypalMeUsername,\n extensionRegistration: {\n providerId: \"paypal\",\n requiredPrompt:\n \"This PayPal username is not registered yet. Register it with PeerAuth, then retry with the same PayPal username.\",\n ctaLabel: \"Register PayPal Username\",\n ctaSubtext: \"PayPal Business accounts are not supported at this time.\",\n },\n },\n monzo: {\n id: \"monzo\",\n name: \"Monzo\",\n identifierLabel: \"Username\",\n placeholder: \"monzo.me username\",\n helperText: \"Your Monzo.me username\",\n validation: z\n .string()\n .min(1)\n .regex(/^[a-zA-Z0-9_-]+$/),\n },\n};\n\n/* ── Build PLATFORMS const ────────────────────────────────────────── */\n\nfunction buildPlatformEntry(bp: PlatformBlueprint): PlatformEntry {\n const currencies = resolveSupportedCurrencies(bp.id);\n return {\n id: bp.id,\n name: bp.name,\n currencies,\n identifier: {\n label: bp.identifierLabel,\n placeholder: bp.placeholder,\n help: bp.helperText,\n },\n ...(bp.extensionRegistration ? { extensionRegistration: bp.extensionRegistration } : {}),\n validate(input: string) {\n const transformed = bp.transform ? bp.transform(input) : input;\n const result = bp.validation.safeParse(transformed);\n if (!result.success) {\n return {\n valid: false,\n normalized: transformed,\n error: result.error.issues[0]?.message || \"Invalid input\",\n };\n }\n return { valid: true, normalized: transformed };\n },\n };\n}\n\n/** All supported payment platforms. Access via `PLATFORMS.REVOLUT`, `PLATFORMS.WISE`, etc. */\nexport const PLATFORMS = {\n VENMO: buildPlatformEntry(BLUEPRINTS.venmo),\n CASHAPP: buildPlatformEntry(BLUEPRINTS.cashapp),\n CHIME: buildPlatformEntry(BLUEPRINTS.chime),\n REVOLUT: buildPlatformEntry(BLUEPRINTS.revolut),\n WISE: buildPlatformEntry(BLUEPRINTS.wise),\n MERCADO_PAGO: buildPlatformEntry(BLUEPRINTS.mercadopago),\n ZELLE: buildPlatformEntry(BLUEPRINTS.zelle),\n PAYPAL: buildPlatformEntry(BLUEPRINTS.paypal),\n MONZO: buildPlatformEntry(BLUEPRINTS.monzo),\n} as const;\n\n/** Platform key type for PLATFORMS constant. */\nexport type PlatformKey = keyof typeof PLATFORMS;\n\n/* ── Per-platform constraints (mirrored from curator) ─────────────── */\n\n/** Taker account tiers curator gates fills behind, lowest → highest. */\nexport type PlatformTier = \"PEASANT\" | \"PEER\" | \"PLUS\" | \"PRO\" | \"PLATINUM\";\n\nexport interface PlatformLimits {\n /**\n * Hard per-platform max fill (USD) curator enforces regardless of taker\n * tier. Omitted when a platform has no absolute cap — its effective limit is\n * `capMultiplier × tierCap`, which depends on the taker's tier and so can't\n * be known when a maker creates a deposit.\n */\n readonly platformCapUsd?: number;\n /**\n * Minimum taker account tier curator requires to fill on this platform.\n * Omitted when any tier may fill.\n */\n readonly minTier?: PlatformTier;\n}\n\n/**\n * Per-platform constraints mirrored from curator's `PLATFORM_RISK_CONFIG`\n * (curator `platformRisk.ts`). ONLY the absolute, tier-independent rules are\n * mirrored: PayPal's PLUS-tier gate and the hard Venmo cap. Per-tier\n * effective caps are intentionally excluded — they're `capMultiplier × tierCap`\n * and depend on the taker, not the maker. Curator exposes no public \"list\n * limits\" endpoint, so this static mirror can drift if a PeerHQ admin changes\n * a value; treat as an advisory hint, never as enforcement — curator remains\n * the source of truth at intent-signing time.\n */\nexport const PLATFORM_LIMITS: Partial<Record<PlatformId, PlatformLimits>> = {\n venmo: { platformCapUsd: 5_000 },\n paypal: { minTier: \"PLUS\" },\n};\n\n/** Returns curator's constraints for a platform id, or null if unconstrained. */\nexport function getPlatformLimits(platform: string): PlatformLimits | null {\n const id = platform.trim().toLowerCase() as PlatformId;\n return PLATFORM_LIMITS[id] ?? null;\n}\n\n/* ── Internal helpers (used by deposit.ts) ─────────────────────────── */\n\nexport function getPlatformById(id: string): PlatformEntry | null {\n return Object.values(PLATFORMS).find((p) => p.id === id) ?? null;\n}\n\nfunction normalizePaymentMethodLookupName(platform: string): PaymentMethodLookupName | null {\n const normalized = platform.trim().toLowerCase();\n if (!normalized) return null;\n if (ZELLE_HASH_LOOKUP_NAMES.includes(normalized as (typeof ZELLE_HASH_LOOKUP_NAMES)[number])) {\n return normalized as PaymentMethodLookupName;\n }\n const ids: readonly string[] = Object.values(PLATFORMS).map((p) => p.id);\n return ids.includes(normalized) ? (normalized as PlatformId) : null;\n}\n\nconst ZELLE_CREATE_LOOKUP_NAMES = [\"zelle-chase\", \"zelle-bofa\", \"zelle-citi\"] as const;\n\n/**\n * Generic Zelle payment-method hash, keccak256(\"zelle\"). Some upstream\n * surfaces can resolve it, but curator prod reverted generic-Zelle maker\n * creation on 2026-06-23. Keep recognizing it for reads/taker handoff while\n * registering new maker deposits with bank-specific variants.\n */\nexport const GENERIC_ZELLE_METHOD_HASH = (resolvePaymentMethodHash(\"zelle\") ?? null) as\n | `0x${string}`\n | null;\n\nfunction resolveGenericZelleHash(): `0x${string}` | null {\n return GENERIC_ZELLE_METHOD_HASH;\n}\n\nfunction getZelleCreateEntries(): Array<{ name: string; hash: `0x${string}` }> {\n const entries: Array<{ name: string; hash: `0x${string}` }> = [];\n for (const name of ZELLE_CREATE_LOOKUP_NAMES) {\n const hash = getPaymentMethodHash(name);\n if (hash) entries.push({ name, hash });\n }\n return entries;\n}\n\nexport function getPaymentMethodHash(platform: string): `0x${string}` | null {\n const name = normalizePaymentMethodLookupName(platform);\n if (!name) return null;\n const catalogEntry = PAYMENT_CATALOG[name];\n if (catalogEntry?.paymentMethodHash) return catalogEntry.paymentMethodHash;\n if (name === \"zelle\") return resolveGenericZelleHash();\n if (name.startsWith(\"zelle-\")) return resolvePaymentMethodHash(name) as `0x${string}` | null;\n const sdkHash = resolvePaymentMethodHash(name);\n return sdkHash ? (sdkHash as `0x${string}`) : null;\n}\n\nexport function getPaymentMethodHashes(platform: string): `0x${string}`[] {\n if (platform !== \"zelle\") {\n const hash = getPaymentMethodHash(platform);\n return hash ? [hash] : [];\n }\n const hashes = getZelleCreateEntries().map((entry) => entry.hash);\n const generic = resolveGenericZelleHash();\n return generic ? [...hashes, generic] : hashes;\n}\n\nexport function getPaymentMethodCreateEntries(\n platform: string,\n): Array<{ name: string; hash: `0x${string}` }> {\n if (platform !== \"zelle\") {\n const hash = getPaymentMethodHash(platform);\n return hash ? [{ name: platform, hash }] : [];\n }\n return getZelleCreateEntries();\n}\n\n/** Flat payload accepted by `POST /v2/makers/create`. */\nexport interface PayeeDepositData {\n offchainId: string;\n telegramUsername?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface CompletePeerExtensionRegistrationInput {\n readonly platform: PlatformEntry;\n readonly identifier: string;\n readonly capturedMetadata: PeerMetadataMessage;\n}\n\nexport interface CompletePeerExtensionRegistrationResult {\n readonly processorName: SellerCredentialProcessor;\n readonly offchainId: string;\n readonly hashedOnchainId: string;\n readonly sellerCredentialResponse: CuratorSellerCredentialUploadResponse;\n readonly sellerCredentialStatus: CuratorSellerCredentialUploadResponse[\"responseObject\"];\n}\n\ntype PayPalSellerCredentialBundleParams = {\n platform: \"paypal\";\n offchainId: string;\n bundle: PeerSarCredentialBundle;\n};\n\n/**\n * Build the payee payload for `/v2/makers/create`. Chime lowercases its\n * chimesign; PayPal identifiers should already be normalized via\n * `PLATFORMS.PAYPAL.validate()`.\n */\nexport function buildDepositData(\n platform: string,\n identifier: string,\n telegramUsername = \"\",\n): PayeeDepositData {\n const offchainId = platform === \"chime\" ? identifier.toLowerCase() : identifier;\n return telegramUsername ? { offchainId, telegramUsername } : { offchainId };\n}\n\n/* ── Peer extension helpers ──────────────────────────────────────── */\n\n/**\n * Returns the extension-registration metadata for a platform, or `null` if\n * the platform does not require Peer-extension pre-registration. Use this to\n * decide whether to surface an \"Install / Connect Peer Extension\" CTA in\n * your UI before calling `offramp()` for PayPal or Wise.\n */\nexport function getPeerExtensionRegistrationInfo(\n platform: string,\n): PeerExtensionRegistrationInfo | null {\n const entry = getPlatformById(platform);\n return entry?.extensionRegistration ?? null;\n}\n\nexport function getPeerExtensionRegistrationAuthParams(\n platform: string,\n options: { attestationServiceUrl?: string | null; callerAddress?: string | null } = {},\n): PeerAuthenticateParams | null {\n const info = getPeerExtensionRegistrationInfo(platform);\n if (!info) return null;\n const callerAddress = options.callerAddress?.trim();\n const params: PeerAuthenticateParams = {\n actionType: `transfer_${info.providerId}`,\n captureMode: \"sellerCredential\",\n platform: info.providerId,\n };\n if (options.attestationServiceUrl) {\n params.attestationServiceUrl = options.attestationServiceUrl;\n }\n if (callerAddress) {\n params.callerAddress = callerAddress;\n }\n return params;\n}\n\nfunction resolveRegistrationProcessor(platform: PlatformEntry): SellerCredentialProcessor {\n const info = getPeerExtensionRegistrationInfo(platform.id);\n if (\n info?.providerId === \"paypal\" ||\n info?.providerId === \"wise\" ||\n info?.providerId === \"venmo\" ||\n info?.providerId === \"cashapp\"\n ) {\n return info.providerId;\n }\n throw new Error(`${platform.name} does not require Peer extension registration.`);\n}\n\n/**\n * POST a maker to curator's `/v2/makers/create` and return the\n * `hashedOnchainId`. Shared by the deposit flow (standard processors) and the\n * Peer-extension registration flow (PayPal/Wise/Venmo/Cash App). Throws `MakersCreateError`\n * preserving curator's HTTP status so callers can apply the\n * extension-registration heuristic.\n */\nexport async function postMakerCreate(\n processorName: string,\n payload: PayeeDepositData,\n apiBaseUrl: string = API_BASE_URL,\n): Promise<string> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), PAYEE_REGISTRATION_TIMEOUT_MS);\n try {\n const res = await fetch(`${apiBaseUrl}/v2/makers/create`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ processorName, ...payload }),\n signal: controller.signal,\n });\n if (!res.ok) {\n const txt = await res.text().catch(() => \"\");\n // Prefer curator's JSON `message` so the extension-registration heuristic\n // can match on the \"creating the maker\" phrasing.\n let detail = txt || res.statusText;\n try {\n const parsed = JSON.parse(txt) as { message?: unknown };\n if (typeof parsed.message === \"string\" && parsed.message.trim()) {\n detail = parsed.message;\n }\n } catch {\n // fall through\n }\n throw new MakersCreateError(\n `makers/create failed (${res.status}): ${detail}`,\n res.status,\n txt,\n );\n }\n const json = (await res.json()) as {\n success: boolean;\n message: string;\n statusCode?: number;\n responseObject?: { hashedOnchainId: string };\n };\n if (!json.success || !json.responseObject?.hashedOnchainId) {\n throw new MakersCreateError(\n json.message || \"makers/create returned no hashedOnchainId\",\n json.statusCode ?? null,\n \"\",\n );\n }\n return json.responseObject.hashedOnchainId;\n } finally {\n clearTimeout(timeout);\n }\n}\n\nfunction requireSarCredentialCapture(\n capturedMetadata: PeerMetadataMessage,\n): PeerSarCredentialCapture {\n const capture = capturedMetadata.sarCredentialCapture;\n if (!capture?.credentialBundle) {\n throw new Error(\"Peer metadata did not include a seller credential bundle.\");\n }\n if (!capture.offchainId) {\n throw new Error(\"Peer metadata did not include seller credential offchainId.\");\n }\n return capture;\n}\n\nasync function uploadSellerCredentialBundle(\n processorName: SellerCredentialProcessor,\n offchainId: string,\n bundle: PeerSarCredentialBundle,\n): Promise<CuratorSellerCredentialUploadResponse> {\n const params: UploadSellerCredentialBundleParams | PayPalSellerCredentialBundleParams =\n processorName === \"wise\"\n ? { platform: \"wise\", bundle }\n : { platform: processorName, offchainId, bundle };\n // @zkp2p/sdk's public bundle-upload type covers venmo/cashapp/wise. PayPal\n // remains a curator-compatible runtime path, so keep the cast for that one\n // legacy route while letting the first-class SAR platforms pass through.\n //\n // Older @zkp2p/sdk releases narrowed the public type to venmo/cashapp/wise, but the\n // runtime helper still supports the curator's PayPal bundle route by\n // registering `{ processorName: \"paypal\", offchainId }` before upload. Keep\n // that path here so existing PayPal maker recovery keeps working.\n return apiUploadSellerCredentialBundle(\n params as unknown as UploadSellerCredentialBundleParams,\n API_BASE_URL,\n PAYEE_REGISTRATION_TIMEOUT_MS,\n );\n}\n\nexport async function completePeerExtensionRegistration(\n input: CompletePeerExtensionRegistrationInput,\n): Promise<CompletePeerExtensionRegistrationResult> {\n const processorName = resolveRegistrationProcessor(input.platform);\n if (input.capturedMetadata.platform !== processorName) {\n throw new Error(\n `Peer metadata is for ${input.capturedMetadata.platform}, not ${processorName}.`,\n );\n }\n\n const sarCredentialCapture = requireSarCredentialCapture(input.capturedMetadata);\n const bundle = sarCredentialCapture.credentialBundle;\n if (bundle.platform.toLowerCase() !== processorName) {\n throw new Error(\"Seller credential bundle platform does not match registration platform.\");\n }\n\n const validation = input.platform.validate(input.identifier);\n if (!validation.valid) {\n throw new Error(validation.error || \"Invalid identifier\");\n }\n\n const payload = buildDepositData(processorName, sarCredentialCapture.offchainId);\n if (payload.offchainId !== validation.normalized) {\n throw new Error(\"Seller credential offchainId does not match registration identifier.\");\n }\n const hashedOnchainId = bundle.payeeIdHash;\n\n const sellerCredentialResponse = await uploadSellerCredentialBundle(\n processorName,\n payload.offchainId,\n bundle,\n );\n\n return {\n processorName,\n offchainId: payload.offchainId,\n hashedOnchainId,\n sellerCredentialResponse,\n sellerCredentialStatus: sellerCredentialResponse.responseObject,\n };\n}\n\n// Phrases curator emits when the maker is not yet registered in the Peer\n// extension. Matched case-insensitively alongside the 400 heuristic.\nconst EXTENSION_REGISTRATION_ERROR_PATTERNS = [\"creating the maker\", \"create the maker\"] as const;\n\nconst isWiseIdentityAttestationRequiredError = (message: string): boolean =>\n message.toLowerCase().includes(\"identityattestation is required\");\n\n/**\n * True when a failed `/v2/makers/create` response should be treated as\n * \"maker needs to register in the Peer extension first\". Platforms without\n * an `extensionRegistration` config always return false. A 400 on a\n * registration-required platform is treated as registration required, and\n * so is any response whose message contains curator's phrasing.\n */\nexport function isPeerExtensionRegistrationError(\n platform: string,\n message?: string | null,\n statusCode?: number | null,\n): boolean {\n const info = getPeerExtensionRegistrationInfo(platform);\n if (!info) return false;\n if (statusCode === 400) return true;\n const normalized = (message ?? \"\").trim();\n if (!normalized) return false;\n if (platform === \"wise\" && isWiseIdentityAttestationRequiredError(normalized)) return true;\n const lower = normalized.toLowerCase();\n return EXTENSION_REGISTRATION_ERROR_PATTERNS.some((p) => lower.includes(p));\n}\n","import type { WalletClient } from \"viem\";\nimport { createPublicClient, http, isAddress, zeroAddress, type Address } from \"viem\";\nimport { base } from \"viem/chains\";\nimport WhitelistPreIntentHookABI from \"@zkp2p/contracts-v2/abis/base/WhitelistPreIntentHook.json\";\n\nimport { createSdkClient } from \"./sdk-client\";\nimport { BASE_RPC_URL, ESCROW_ADDRESS, REFERRER } from \"./config\";\nimport { OfframpError, isUserCancellation } from \"./errors\";\n\nconst WHITELIST_HOOK_ADDRESS = \"0xda023Ea0d789A41BcF5866F7B6BBd2CaDF9b79B8\" as const;\n\nconst OTC_BASE_URL = \"https://otc.usdctofiat.xyz\";\n\nexport interface EnableOtcResult {\n depositId: string;\n takerAddress: string;\n otcLink: string;\n}\n\n/**\n * Make a deposit private so only one taker wallet can trade against it.\n *\n * Sets the WhitelistPreIntentHook on the deposit and whitelists the taker.\n * The hook stores its whitelist as a membership-only mapping with no\n * enumeration, so a taker that was previously whitelisted is NOT removed when\n * a new one is added — both stay whitelisted. To switch to a single new taker,\n * remove the prior one explicitly (or `disableOtc` first) before calling this.\n *\n * @param walletClient - viem WalletClient with the deposit owner's account\n * @param depositId - The numeric deposit ID (from `OfframpResult.depositId`)\n * @param takerAddress - The Ethereum address allowed to take this order\n * @param escrowAddress - Optional escrow override (defaults to current V3 escrow)\n */\nexport async function enableOtc(\n walletClient: WalletClient,\n depositId: string,\n takerAddress: string,\n escrowAddress?: string,\n): Promise<EnableOtcResult> {\n if (!isAddress(takerAddress)) {\n throw new OfframpError(\"Invalid taker address\", \"VALIDATION\");\n }\n\n const escrow = (escrowAddress || ESCROW_ADDRESS) as Address;\n const taker = takerAddress as Address;\n const depositIdBig = BigInt(depositId);\n const client = createSdkClient(walletClient);\n const txOverrides = { referrer: [REFERRER] };\n\n try {\n // Check current hook state\n const currentHook = (await client.getDepositWhitelistHook(depositIdBig, {\n escrowAddress: escrow,\n })) as Address;\n\n // If the hook is already set and this taker is already whitelisted, no-op.\n if (currentHook !== zeroAddress) {\n const isAlready = (await readIsWhitelisted(escrow, depositIdBig, taker)) as boolean;\n\n if (isAlready) {\n return {\n depositId,\n takerAddress: taker,\n otcLink: getOtcLink(depositId, escrow),\n };\n }\n }\n\n // Add taker to whitelist\n await writeContract(walletClient, \"addToWhitelist\", [escrow, depositIdBig, [taker]]);\n\n // Set hook if not already set\n if (currentHook === zeroAddress) {\n await client.setDepositWhitelistHook({\n depositId: depositIdBig,\n whitelistHook: WHITELIST_HOOK_ADDRESS,\n escrowAddress: escrow,\n txOverrides,\n });\n }\n\n return {\n depositId,\n takerAddress: taker,\n otcLink: getOtcLink(depositId, escrow),\n };\n } catch (err) {\n if (err instanceof OfframpError) throw err;\n if (isUserCancellation(err)) {\n throw new OfframpError(\"User cancelled\", \"USER_CANCELLED\", undefined, err, { depositId });\n }\n const detail = err instanceof Error ? err.message : String(err);\n throw new OfframpError(`Failed to enable OTC: ${detail}`, \"DEPOSIT_FAILED\", undefined, err, {\n depositId,\n });\n }\n}\n\n/**\n * Remove the OTC restriction and make the deposit public again.\n *\n * @param walletClient - viem WalletClient with the deposit owner's account\n * @param depositId - The numeric deposit ID\n * @param escrowAddress - Optional escrow override (defaults to current V3 escrow)\n */\nexport async function disableOtc(\n walletClient: WalletClient,\n depositId: string,\n escrowAddress?: string,\n): Promise<void> {\n const escrow = (escrowAddress || ESCROW_ADDRESS) as Address;\n const client = createSdkClient(walletClient);\n const txOverrides = { referrer: [REFERRER] };\n\n try {\n await client.setDepositWhitelistHook({\n depositId: BigInt(depositId),\n whitelistHook: zeroAddress,\n escrowAddress: escrow,\n txOverrides,\n });\n } catch (err) {\n if (isUserCancellation(err)) {\n throw new OfframpError(\"User cancelled\", \"USER_CANCELLED\", undefined, err, { depositId });\n }\n const detail = err instanceof Error ? err.message : String(err);\n throw new OfframpError(`Failed to disable OTC: ${detail}`, \"DEPOSIT_FAILED\", undefined, err, {\n depositId,\n });\n }\n}\n\n/**\n * Get the OTC deposit link that a taker opens to fill the order.\n *\n * @param depositId - The numeric deposit ID\n * @param escrowAddress - Optional escrow override (defaults to current V3 escrow)\n */\nexport function getOtcLink(depositId: string, escrowAddress?: string): string {\n const escrow = escrowAddress || ESCROW_ADDRESS;\n return `${OTC_BASE_URL}/d/${escrow}/${depositId}`;\n}\n\n/* ── Internal helpers ──────────────────────────────────────────────── */\n\nasync function writeContract(\n walletClient: WalletClient,\n functionName: string,\n args: unknown[],\n): Promise<void> {\n const wc = walletClient as unknown as {\n writeContract: (req: {\n address: Address;\n abi: unknown;\n functionName: string;\n args: unknown[];\n }) => Promise<string>;\n };\n if (typeof wc.writeContract !== \"function\") {\n throw new OfframpError(\"Wallet client does not support writeContract\", \"VALIDATION\");\n }\n await wc.writeContract({\n address: WHITELIST_HOOK_ADDRESS,\n abi: WhitelistPreIntentHookABI,\n functionName,\n args,\n });\n}\n\nasync function readIsWhitelisted(\n escrow: Address,\n depositId: bigint,\n taker: Address,\n): Promise<unknown> {\n const publicClient = createPublicClient({ chain: base, transport: http(BASE_RPC_URL) });\n return publicClient.readContract({\n address: WHITELIST_HOOK_ADDRESS,\n abi: WhitelistPreIntentHookABI,\n functionName: \"isWhitelisted\",\n args: [escrow, depositId, taker],\n });\n}\n","/**\n * SDK client factory.\n *\n * Extracted from `./deposit.ts` so both `otc.ts` and `queries.ts` can import\n * `createSdkClient` without closing a cycle back through `deposit.ts`.\n */\n\nimport type { WalletClient } from \"viem\";\nimport { OfframpClient } from \"@zkp2p/sdk\";\n\nimport { API_BASE_URL, BASE_CHAIN_ID, BASE_RPC_URL, RUNTIME_ENV } from \"./config\";\n\nexport function createSdkClient(\n walletClient: WalletClient,\n apiBaseUrl: string = API_BASE_URL,\n): OfframpClient {\n return new OfframpClient({\n walletClient: walletClient as any,\n chainId: BASE_CHAIN_ID,\n runtimeEnv: RUNTIME_ENV,\n rpcUrl: BASE_RPC_URL,\n baseApiUrl: apiBaseUrl,\n });\n}\n","import type { Hex, WalletClient } from \"viem\";\nimport { concatHex, createPublicClient, encodeFunctionData, formatUnits, http } from \"viem\";\nimport { base } from \"viem/chains\";\nimport {\n classifyDelegationState,\n defaultIndexerEndpoint,\n getAttributionDataSuffix,\n getCurrencyInfoFromHash,\n IndexerClient,\n IndexerDepositService,\n} from \"@zkp2p/sdk\";\n\nimport type { DepositInfo, DepositStatus } from \"./types\";\nimport { createSdkClient } from \"./sdk-client\";\nimport { PLATFORMS, getPaymentMethodHashes } from \"./platforms\";\nimport {\n BASE_RPC_URL,\n DELEGATE_RATE_MANAGER_ID,\n ESCROW_ADDRESS,\n RATE_MANAGER_REGISTRY_ADDRESS,\n REFERRER,\n} from \"./config\";\n\n/* ── Indexer singleton ────────────────────────────────────────────── */\n\nlet indexerService: IndexerDepositService | null = null;\n\nexport function getIndexerService(): IndexerDepositService {\n if (!indexerService) {\n const endpoint = defaultIndexerEndpoint(\"PRODUCTION\");\n const client = new IndexerClient(endpoint);\n indexerService = new IndexerDepositService(client);\n }\n return indexerService;\n}\n\n/* ── Helpers ──────────────────────────────────────────────────────── */\n\ntype IndexerDeposit = {\n id: string;\n depositId: string;\n txHash?: string;\n status: string;\n remainingDeposits: string | null;\n outstandingIntentAmount: string | null;\n totalAmountTaken: string | null;\n fulfilledIntents: number | null;\n escrowAddress: string;\n rateManagerId?: string | null;\n rateManagerAddress?: string | null;\n paymentMethods: Array<{ paymentMethodHash: string }>;\n currencies: Array<{ currencyCode: string; rateSource?: string | null }>;\n};\n\nfunction toBigInt(value: string | null | undefined): bigint {\n try {\n return BigInt(value || \"0\");\n } catch {\n return 0n;\n }\n}\n\nfunction toUsdc(value: string | null | undefined): number {\n return Number(formatUnits(toBigInt(value), 6));\n}\n\nfunction resolveStatus(deposit: IndexerDeposit): DepositStatus {\n if (deposit.status === \"CLOSED\") return \"closed\";\n if (toBigInt(deposit.remainingDeposits) === 0n) return \"empty\";\n return \"active\";\n}\n\nfunction resolveMethodNames(hashes: Array<{ paymentMethodHash: string }>): string[] {\n const names = new Set<string>();\n for (const { paymentMethodHash } of hashes) {\n const normalized = paymentMethodHash.toLowerCase();\n for (const platform of Object.values(PLATFORMS)) {\n const platformHashes = getPaymentMethodHashes(platform.id);\n if (platformHashes.some((h) => h.toLowerCase() === normalized)) {\n names.add(platform.name);\n break;\n }\n }\n }\n return Array.from(names);\n}\n\nfunction mapDeposit(d: IndexerDeposit): DepositInfo {\n const delegationState = classifyDelegationState(\n d.rateManagerId ?? undefined,\n d.rateManagerAddress ?? undefined,\n DELEGATE_RATE_MANAGER_ID,\n RATE_MANAGER_REGISTRY_ADDRESS,\n );\n return {\n depositId: d.depositId,\n compositeId: d.id,\n txHash: d.txHash,\n status: resolveStatus(d),\n remainingUsdc: toUsdc(d.remainingDeposits),\n outstandingUsdc: toUsdc(d.outstandingIntentAmount),\n totalTakenUsdc: toUsdc(d.totalAmountTaken),\n fulfilledIntents: d.fulfilledIntents ?? 0,\n paymentMethods: resolveMethodNames(d.paymentMethods),\n currencies: d.currencies.map((c) => {\n const info = getCurrencyInfoFromHash(c.currencyCode);\n return info?.currencyCode ?? c.currencyCode;\n }),\n rateSource: d.currencies[0]?.rateSource || \"unknown\",\n delegated: delegationState === \"delegated_here\",\n escrowAddress: d.escrowAddress,\n };\n}\n\nfunction extractTxHash(result: unknown): string {\n if (typeof result === \"string\") return result;\n if (result && typeof result === \"object\" && \"hash\" in result)\n return (result as { hash: string }).hash;\n if (result && typeof result === \"object\" && \"transactionHash\" in result)\n return (result as { transactionHash: string }).transactionHash;\n throw new Error(\"Unexpected transaction result format\");\n}\n\nconst ESCROW_V2_ABI = [\n {\n name: \"clearRateManager\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"depositId\", type: \"uint256\" }],\n outputs: [],\n },\n] as const;\n\nfunction appendReferrerAttribution(calldata: Hex): Hex {\n return concatHex([calldata, getAttributionDataSuffix([REFERRER])]);\n}\n\n/* ── Public functions ─────────────────────────────────────────────── */\n\n/**\n * List all deposits for a wallet address. Read-only, no wallet needed.\n * Returns active deposits first, then empty, then closed.\n */\nexport async function deposits(walletAddress: string): Promise<DepositInfo[]> {\n const service = getIndexerService();\n const raw = (await service.fetchDepositsWithRelations(\n { depositor: walletAddress as `0x${string}` },\n { limit: 100 },\n )) as IndexerDeposit[];\n\n const statusOrder: Record<DepositStatus, number> = { active: 0, empty: 1, closed: 2 };\n\n return (raw || []).map(mapDeposit).sort((a, b) => {\n const diff = statusOrder[a.status] - statusOrder[b.status];\n if (diff !== 0) return diff;\n return Number(BigInt(b.depositId) - BigInt(a.depositId));\n });\n}\n\n/**\n * Withdraw remaining USDC and close a deposit.\n *\n * @param walletClient - viem WalletClient with the deposit owner's account\n * @param depositId - The numeric deposit ID (from `DepositInfo.depositId`)\n */\nexport async function close(\n walletClient: WalletClient,\n depositId: string,\n escrowAddress?: string,\n): Promise<string> {\n const client = createSdkClient(walletClient);\n const result = await client.withdrawDeposit({\n depositId: BigInt(depositId),\n escrowAddress: (escrowAddress || ESCROW_ADDRESS) as `0x${string}`,\n txOverrides: { referrer: [REFERRER] },\n });\n return extractTxHash(result);\n}\n\n/**\n * Delegate a deposit to the configured Delegate vault.\n *\n * @param walletClient - viem WalletClient with the deposit owner's account\n * @param depositId - The numeric deposit ID (from `DepositInfo.depositId`)\n */\nexport async function delegate(\n walletClient: WalletClient,\n depositId: string,\n escrowAddress?: string,\n): Promise<string> {\n const client = createSdkClient(walletClient);\n const result = await client.setRateManager({\n depositId: BigInt(depositId),\n rateManagerAddress: RATE_MANAGER_REGISTRY_ADDRESS,\n rateManagerId: DELEGATE_RATE_MANAGER_ID,\n escrowAddress: (escrowAddress || ESCROW_ADDRESS) as `0x${string}`,\n txOverrides: { referrer: [REFERRER] },\n });\n return extractTxHash(result);\n}\n\n/**\n * Remove Delegate rate management from a deposit.\n *\n * @param walletClient - viem WalletClient with the deposit owner's account\n * @param depositId - The numeric deposit ID (from `DepositInfo.depositId`)\n */\nexport async function undelegate(\n walletClient: WalletClient,\n depositId: string,\n escrowAddress?: string,\n): Promise<string> {\n const account = walletClient.account;\n if (!account) {\n throw new Error(\"Wallet client has no account. Connect a wallet first.\");\n }\n\n const data = appendReferrerAttribution(\n encodeFunctionData({\n abi: ESCROW_V2_ABI,\n functionName: \"clearRateManager\",\n args: [BigInt(depositId)],\n }),\n );\n\n const hash = await walletClient.sendTransaction({\n account,\n chain: base,\n data,\n to: (escrowAddress || ESCROW_ADDRESS) as `0x${string}`,\n });\n\n const publicClient = createPublicClient({\n chain: base,\n transport: http(BASE_RPC_URL),\n });\n\n try {\n const receipt = await publicClient.waitForTransactionReceipt({\n hash,\n confirmations: 1,\n timeout: 120_000,\n pollingInterval: 4_000,\n });\n\n if (receipt.status !== \"success\") {\n throw new Error(\"Undelegation transaction failed\");\n }\n } catch (err) {\n const isTimeout = err instanceof Error && err.message.toLowerCase().includes(\"timed out\");\n\n if (!isTimeout) {\n throw err;\n }\n }\n\n return hash;\n}\n","const SDK_EVENTS_ENDPOINT = \"https://usdctofiat.xyz/api/sdk-events\";\nconst MAX_BATCH_SIZE = 50;\nconst FLUSH_DELAY_MS = 180;\nconst TELEMETRY_TIMEOUT_MS = 2_000;\n\nexport type TelemetryEventName =\n | \"sdk.init\"\n | \"sdk.createDeposit.start\"\n | \"sdk.createDeposit.progress\"\n | \"sdk.createDeposit.success\"\n | \"sdk.createDeposit.error\";\n\nexport interface TelemetryEvent {\n name: TelemetryEventName;\n payload?: Record<string, unknown>;\n ts: number;\n}\n\nexport interface TelemetryContext {\n readonly enabled: boolean;\n readonly sdkVersion: string;\n readonly integratorId?: string;\n readonly referralId?: string;\n emit: (name: TelemetryEventName, payload?: Record<string, unknown>) => void;\n}\n\nexport interface CreateTelemetryContextOptions {\n sdkVersion: string;\n telemetry?: boolean;\n integratorId?: string;\n referralId?: string;\n}\n\nlet queuedEvents: TelemetryEvent[] = [];\nlet flushTimer: ReturnType<typeof setTimeout> | null = null;\nlet flushInFlight = false;\n\nexport function sanitizeAttributionId(raw: unknown): string | undefined {\n if (typeof raw !== \"string\") return undefined;\n const stripped = raw.trim().replace(/[^a-zA-Z0-9_-]/g, \"\");\n if (!stripped) return undefined;\n if (stripped.length > 64) return undefined;\n return stripped;\n}\n\nfunction scheduleFlush(): void {\n if (flushTimer != null) return;\n flushTimer = setTimeout(() => {\n flushTimer = null;\n void flushQueue();\n }, FLUSH_DELAY_MS);\n}\n\nasync function postBatch(batch: TelemetryEvent[]): Promise<void> {\n if (!batch.length) return;\n\n const body = JSON.stringify(batch);\n try {\n if (typeof navigator !== \"undefined\" && typeof navigator.sendBeacon === \"function\") {\n const blob = new Blob([body], { type: \"application/json\" });\n const accepted = navigator.sendBeacon(SDK_EVENTS_ENDPOINT, blob);\n if (accepted) return;\n }\n } catch {\n // noop: fall back to fetch\n }\n\n try {\n const controller =\n typeof AbortController !== \"undefined\"\n ? new AbortController()\n : (null as AbortController | null);\n const timeout = controller ? setTimeout(() => controller.abort(), TELEMETRY_TIMEOUT_MS) : null;\n await fetch(SDK_EVENTS_ENDPOINT, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body,\n keepalive: true,\n signal: controller?.signal,\n }).catch(() => {});\n if (timeout) clearTimeout(timeout);\n } catch {\n // noop: best effort\n }\n}\n\nasync function flushQueue(): Promise<void> {\n if (flushInFlight) return;\n if (!queuedEvents.length) return;\n flushInFlight = true;\n try {\n while (queuedEvents.length > 0) {\n const batch = queuedEvents.slice(0, MAX_BATCH_SIZE);\n queuedEvents = queuedEvents.slice(batch.length);\n await postBatch(batch);\n }\n } finally {\n flushInFlight = false;\n }\n}\n\nexport function emitEvent(name: TelemetryEventName, payload?: Record<string, unknown>): void {\n try {\n queuedEvents.push({\n name,\n payload,\n ts: Date.now(),\n });\n if (queuedEvents.length >= MAX_BATCH_SIZE) {\n void flushQueue();\n return;\n }\n scheduleFlush();\n } catch {\n // noop\n }\n}\n\nexport function sendTelemetryEvent(\n name: TelemetryEventName,\n payload?: Record<string, unknown>,\n): void {\n emitEvent(name, payload);\n}\n\nexport function createTelemetryContext(options: CreateTelemetryContextOptions): TelemetryContext {\n const integratorId = sanitizeAttributionId(options.integratorId);\n const referralId = sanitizeAttributionId(options.referralId);\n const enabled = options.telemetry !== false;\n const sdkVersion = options.sdkVersion;\n\n return {\n enabled,\n sdkVersion,\n integratorId,\n referralId,\n emit(name, payload = {}) {\n if (!enabled) return;\n emitEvent(name, {\n sdkVersion,\n integratorId,\n referralId,\n ...payload,\n });\n },\n };\n}\n","import type { WalletClient } from \"viem\";\nimport { createPublicClient, decodeEventLog, formatUnits, http, parseUnits, type Hex } from \"viem\";\nimport { base } from \"viem/chains\";\nimport {\n getSpreadOracleConfig,\n mapConversionRatesToOnchainMinRate,\n type CurrencyType,\n} from \"@zkp2p/sdk\";\n\nimport {\n API_BASE_URL,\n BASE_RPC_URL,\n DEFAULT_INTENT_GUARDIAN_ADDRESS,\n DELEGATE_RATE_MANAGER_ID,\n ESCROW_ADDRESS,\n GATING_SERVICE_ADDRESS,\n INDEXER_INITIAL_DELAY_MS,\n INDEXER_MAX_ATTEMPTS,\n INDEXER_MAX_DELAY_MS,\n MAX_ORDER_USDC,\n MIN_DEPOSIT_USDC,\n MIN_ORDER_USDC,\n PAYEE_REGISTRATION_TIMEOUT_MS,\n RATE_MANAGER_REGISTRY_ADDRESS,\n REFERRER,\n resolveApiBaseUrl,\n SDK_VERSION,\n USDC_ADDRESS,\n} from \"./config\";\nimport {\n buildDepositData,\n getPaymentMethodCreateEntries,\n getPeerExtensionRegistrationInfo,\n isPeerExtensionRegistrationError,\n postMakerCreate,\n} from \"./platforms\";\nimport { MakersCreateError, OfframpError, isUserCancellation } from \"./errors\";\nimport { enableOtc } from \"./otc\";\nimport { getIndexerService } from \"./queries\";\nimport { createSdkClient } from \"./sdk-client\";\nimport { createTelemetryContext, type TelemetryContext } from \"./telemetry\";\nimport type { OfframpParams, OfframpResult, OnProgress } from \"./types\";\n\nexport { createSdkClient };\n\n/* ── Helpers ──────────────────────────────────────────────────────── */\n\nfunction usdcToUnits(amount: string): bigint {\n return parseUnits(amount, 6);\n}\n\nconst DEPOSIT_RECEIVED_ABI = [\n {\n type: \"event\" as const,\n name: \"DepositReceived\" as const,\n inputs: [\n { indexed: true, name: \"depositId\", type: \"uint256\" },\n { indexed: true, name: \"depositor\", type: \"address\" },\n { indexed: true, name: \"token\", type: \"address\" },\n { indexed: false, name: \"amount\", type: \"uint256\" },\n {\n indexed: false,\n name: \"intentAmountRange\",\n type: \"tuple\",\n components: [\n { name: \"min\", type: \"uint256\" },\n { name: \"max\", type: \"uint256\" },\n ],\n },\n { indexed: false, name: \"delegate\", type: \"address\" },\n { indexed: false, name: \"intentGuardian\", type: \"address\" },\n ],\n },\n] as const;\n\nfunction extractDepositIdFromLogs(logs: Array<{ topics?: Hex[]; data?: Hex }>): string | null {\n for (const log of logs) {\n if (!log?.topics?.length || !log.data) continue;\n try {\n const decoded = decodeEventLog({\n abi: DEPOSIT_RECEIVED_ABI,\n data: log.data,\n topics: log.topics as [Hex, ...Hex[]],\n });\n if (decoded.eventName !== \"DepositReceived\") continue;\n const args = decoded.args as { depositId?: bigint };\n if (typeof args.depositId === \"bigint\") return args.depositId.toString();\n } catch {\n continue;\n }\n }\n return null;\n}\n\ntype ValidateOutcome = \"valid\" | \"invalid\" | \"unknown\";\n\n/**\n * Pre-checks a payee handle against curator's `/v2/makers/validate` before the\n * maker spends gas. Curator runs the same processor checks `/v2/makers/create`\n * does (format, live existence lookup for Venmo/Revolut, lowercase for Zelle)\n * with zero on-chain side effects, returning the verdict as a `responseObject`\n * boolean on an HTTP 200.\n *\n * Fails OPEN: only an explicit `false` verdict returns `\"invalid\"`. Curator\n * downtime, a non-200, a network error, or an unexpected body all return\n * `\"unknown\"` so the deposit still proceeds and `/v2/makers/create` stays the\n * authoritative gate — the pre-check can never be the reason a valid maker is\n * blocked.\n */\nasync function validatePayeeDetails(\n processorName: string,\n offchainId: string,\n apiBaseUrl: string = API_BASE_URL,\n): Promise<ValidateOutcome> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), PAYEE_REGISTRATION_TIMEOUT_MS);\n try {\n const res = await fetch(`${apiBaseUrl}/v2/makers/validate`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ processorName, offchainId }),\n signal: controller.signal,\n });\n if (!res.ok) return \"unknown\";\n const json = (await res.json()) as { responseObject?: unknown };\n if (typeof json.responseObject === \"boolean\") {\n return json.responseObject ? \"valid\" : \"invalid\";\n }\n return \"unknown\";\n } catch {\n return \"unknown\";\n } finally {\n clearTimeout(timeout);\n }\n}\n\ntype OnchainCurrencyEntry = {\n code: `0x${string}`;\n minConversionRate: bigint;\n oracleRateConfig?: {\n adapter: `0x${string}`;\n adapterConfig: `0x${string}`;\n spreadBps: number;\n maxStaleness: number;\n };\n};\n\nfunction attachOracleConfig(\n entries: Array<Array<{ code: `0x${string}`; minConversionRate: bigint }>>,\n conversionRates: Array<Array<{ currency: CurrencyType; conversionRate: string }>>,\n): OnchainCurrencyEntry[][] {\n return entries.map((group, gi) =>\n group.map((entry, ci) => {\n const currency = conversionRates[gi]?.[ci]?.currency;\n if (!currency) return entry;\n const oracleConfig = getSpreadOracleConfig(currency);\n if (!oracleConfig) return entry;\n return {\n ...entry,\n oracleRateConfig: {\n adapter: oracleConfig.adapter,\n adapterConfig: oracleConfig.adapterConfig,\n spreadBps: 0,\n maxStaleness: oracleConfig.maxStaleness,\n },\n };\n }),\n );\n}\n\nfunction extractTxHash(result: unknown): string {\n if (typeof result === \"string\") return result;\n if (result && typeof result === \"object\" && \"hash\" in result)\n return (result as { hash: string }).hash;\n if (result && typeof result === \"object\" && \"transactionHash\" in result)\n return (result as { transactionHash: string }).transactionHash;\n throw new Error(\"Unexpected transaction result format\");\n}\n\n/* ── Resume check ─────────────────────────────────────────────────── */\n\ntype IndexerDeposit = {\n depositId: string;\n txHash?: string;\n status: string;\n remainingDeposits: string | null;\n escrowAddress: string;\n rateManagerId?: string | null;\n rateManagerAddress?: string | null;\n};\n\nasync function findUndelegatedDeposit(walletAddress: string): Promise<IndexerDeposit | null> {\n try {\n const service = getIndexerService();\n const raw = (await service.fetchDepositsWithRelations(\n { depositor: walletAddress as `0x${string}` },\n { limit: 50 },\n )) as IndexerDeposit[];\n\n const escrowLower = ESCROW_ADDRESS.toLowerCase();\n const delegateIdLower = DELEGATE_RATE_MANAGER_ID.toLowerCase();\n const undelegated = (raw || []).filter((d) => {\n if (d.status === \"CLOSED\") return false;\n if (d.escrowAddress.toLowerCase() !== escrowLower) return false;\n const remaining = (() => {\n try {\n return BigInt(d.remainingDeposits || \"0\");\n } catch {\n return 0n;\n }\n })();\n if (remaining === 0n) return false;\n return (d.rateManagerId ?? \"\").toLowerCase() !== delegateIdLower;\n });\n // Most recent first\n undelegated.sort((a, b) => {\n const left = BigInt(a.depositId);\n const right = BigInt(b.depositId);\n if (left === right) return 0;\n return left > right ? -1 : 1;\n });\n return undelegated[0] ?? null;\n } catch {\n return null;\n }\n}\n\n/* ── Main offramp flow ────────────────────────────────────────────── */\n\n/**\n * Create a USDC-to-fiat offramp deposit and delegate it to the vault.\n *\n * **Resumable**: if an existing undelegated deposit is found for this wallet,\n * the flow skips directly to delegation instead of creating a new deposit.\n */\nexport async function offramp(\n walletClient: WalletClient,\n params: OfframpParams,\n onProgress?: OnProgress,\n telemetryContext?: TelemetryContext,\n apiBaseUrl?: string,\n): Promise<OfframpResult> {\n const { amount, platform, currency, identifier } = params;\n const platformId = platform.id;\n const currencyCode = currency.code;\n // Resolves to the production curator REST base unless an override is passed.\n // Only the curator REST surface is overridable (indexer + RPC stay mainnet).\n const resolvedApiBaseUrl = resolveApiBaseUrl(apiBaseUrl);\n const telemetry =\n telemetryContext ??\n createTelemetryContext({\n sdkVersion: SDK_VERSION,\n telemetry: true,\n integratorId: params.integratorId,\n referralId: params.referralId,\n });\n const flowStartMs = Date.now();\n const emitProgress = (progress: Parameters<NonNullable<typeof onProgress>>[0]) => {\n onProgress?.(progress);\n telemetry.emit(\"sdk.createDeposit.progress\", {\n step: progress.step,\n txHash: progress.txHash,\n });\n };\n\n try {\n // 1. Validate\n if (!walletClient.account?.address) {\n throw new OfframpError(\"Wallet client has no account. Connect a wallet first.\", \"VALIDATION\");\n }\n const walletAddress = walletClient.account.address.toLowerCase() as `0x${string}`;\n telemetry.emit(\"sdk.createDeposit.start\", {\n platform: platformId,\n currency: currencyCode,\n amount,\n wallet: walletAddress,\n });\n\n const amt = parseFloat(amount);\n if (!Number.isFinite(amt) || amt < MIN_DEPOSIT_USDC) {\n throw new OfframpError(`Minimum deposit is ${MIN_DEPOSIT_USDC} USDC`, \"VALIDATION\");\n }\n\n if (!platform.currencies.includes(currencyCode)) {\n throw new OfframpError(`${currencyCode} is not supported on ${platform.name}`, \"UNSUPPORTED\");\n }\n\n const validation = platform.validate(identifier);\n if (!validation.valid) {\n throw new OfframpError(validation.error || \"Invalid identifier\", \"VALIDATION\");\n }\n const normalizedIdentifier = validation.normalized;\n\n const paymentMethodEntries = getPaymentMethodCreateEntries(platformId);\n if (paymentMethodEntries.length === 0) {\n throw new OfframpError(`${platform.name} is not currently supported`, \"UNSUPPORTED\");\n }\n\n // 2. Check for existing undelegated deposit (resume path)\n const existing = await findUndelegatedDeposit(walletAddress);\n if (existing) {\n emitProgress({ step: \"resuming\", depositId: existing.depositId });\n\n const client = createSdkClient(walletClient, resolvedApiBaseUrl);\n const txOverrides = { referrer: [REFERRER] };\n\n try {\n const result = await client.setRateManager({\n depositId: BigInt(existing.depositId),\n rateManagerAddress: RATE_MANAGER_REGISTRY_ADDRESS,\n rateManagerId: DELEGATE_RATE_MANAGER_ID,\n escrowAddress: existing.escrowAddress as `0x${string}`,\n txOverrides,\n });\n const txHash = extractTxHash(result);\n emitProgress({ step: \"done\", txHash, depositId: existing.depositId });\n const resumedResult = { depositId: existing.depositId, txHash, resumed: true };\n telemetry.emit(\"sdk.createDeposit.success\", {\n depositId: resumedResult.depositId,\n txHash: resumedResult.txHash,\n wallet: walletAddress,\n resumed: true,\n wallDurationMs: Date.now() - flowStartMs,\n });\n return resumedResult;\n } catch (err) {\n if (isUserCancellation(err))\n throw new OfframpError(\"User cancelled\", \"USER_CANCELLED\", \"resuming\", err);\n throw new OfframpError(\n \"Found undelegated deposit but delegation failed. Try again.\",\n \"DELEGATION_FAILED\",\n \"resuming\",\n err,\n { depositId: existing.depositId, txHash: existing.txHash },\n );\n }\n }\n\n // 3. Full flow — no existing deposit to resume\n const truncatedAmount = amt.toFixed(6).replace(/\\.?0+$/, \"\");\n const amountUnits = usdcToUnits(truncatedAmount);\n const minUnits = usdcToUnits(String(MIN_ORDER_USDC));\n const maxUnits = usdcToUnits(String(Math.min(amt, MAX_ORDER_USDC)));\n\n // Pre-flight balance check\n try {\n const publicClient = createPublicClient({ chain: base, transport: http(BASE_RPC_URL) });\n const balance = await publicClient.readContract({\n address: USDC_ADDRESS,\n abi: [\n {\n name: \"balanceOf\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"account\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n ] as const,\n functionName: \"balanceOf\",\n args: [walletAddress],\n });\n if (balance < amountUnits) {\n const available = Number(formatUnits(balance, 6));\n throw new OfframpError(\n `Insufficient USDC balance. Have ${available.toFixed(2)}, need ${truncatedAmount}.`,\n \"VALIDATION\",\n );\n }\n } catch (err) {\n if (err instanceof OfframpError) throw err;\n }\n\n // All Zelle variants register under the base \"zelle\" processor.\n const canonicalName = platformId.startsWith(\"zelle\") ? \"zelle\" : platformId;\n\n // Fail fast on a bad/nonexistent handle BEFORE the maker approves USDC and\n // pays deposit gas. Skipped for extension-gated platforms (PayPal, Wise):\n // their validate path doesn't assert Peer-extension registration, and\n // `/v2/makers/create` already owns the EXTENSION_REGISTRATION_REQUIRED\n // recovery flow, so a pre-check there would add no signal and risk masking\n // it. For every other platform this catches typo'd IBANs, non-existent\n // Venmo/Revolut handles, etc. that curator would reject after gas is spent.\n if (!getPeerExtensionRegistrationInfo(platformId)) {\n const outcome = await validatePayeeDetails(\n canonicalName,\n normalizedIdentifier,\n resolvedApiBaseUrl,\n );\n if (outcome === \"invalid\") {\n throw new OfframpError(\n `Couldn't verify that ${platform.name} ${platform.identifier.label.toLowerCase()}. Double-check it and try again.`,\n \"VALIDATION\",\n \"registering\",\n );\n }\n }\n\n const client = createSdkClient(walletClient, resolvedApiBaseUrl);\n const txOverrides = { referrer: [REFERRER] };\n\n // Approve\n emitProgress({ step: \"approving\" });\n try {\n await client.ensureAllowance({\n token: USDC_ADDRESS,\n amount: amountUnits,\n escrowAddress: ESCROW_ADDRESS,\n maxApprove: false,\n txOverrides,\n });\n } catch (err) {\n if (isUserCancellation(err))\n throw new OfframpError(\"User cancelled\", \"USER_CANCELLED\", \"approving\", err);\n const detail = err instanceof Error ? err.message : String(err);\n throw new OfframpError(\n `USDC approval failed: ${detail}`,\n \"APPROVAL_FAILED\",\n \"approving\",\n err,\n );\n }\n\n // Register payee\n emitProgress({ step: \"registering\" });\n let hashedOnchainId: string;\n try {\n const payeePayload = buildDepositData(canonicalName, normalizedIdentifier);\n hashedOnchainId = await postMakerCreate(canonicalName, payeePayload, resolvedApiBaseUrl);\n } catch (err) {\n // Curator requires SAR-capable makers to register their handle in the\n // Peer extension first. A 400 or \"creating the maker\" message on those\n // platforms means the integrator needs to launch the headless Peer\n // metadata-capture flow before retrying.\n const status = err instanceof MakersCreateError ? err.status : null;\n const message = err instanceof Error ? err.message : String(err);\n if (isPeerExtensionRegistrationError(canonicalName, message, status)) {\n throw new OfframpError(\n `${platform.name} maker is not yet registered in the Peer extension. Register this handle with Peer, then retry.`,\n \"EXTENSION_REGISTRATION_REQUIRED\",\n \"registering\",\n err,\n );\n }\n throw new OfframpError(\n \"Payee registration failed\",\n \"REGISTRATION_FAILED\",\n \"registering\",\n err,\n );\n }\n\n // Create deposit\n emitProgress({ step: \"depositing\" });\n\n const conversionRates: Array<Array<{ currency: CurrencyType; conversionRate: string }>> =\n paymentMethodEntries.map(() => [\n { currency: currencyCode as CurrencyType, conversionRate: \"1\" },\n ]);\n\n const baseCurrenciesOverride = mapConversionRatesToOnchainMinRate(\n conversionRates,\n paymentMethodEntries.length,\n );\n const currenciesOverride = attachOracleConfig(baseCurrenciesOverride, conversionRates);\n const paymentMethodHashes = paymentMethodEntries.map((entry) => entry.hash);\n const payeeDetailsHashes = paymentMethodEntries.map(() => hashedOnchainId);\n\n let hash: `0x${string}`;\n try {\n const result = await client.createDeposit({\n token: USDC_ADDRESS,\n amount: amountUnits,\n retainOnEmpty: false,\n intentAmountRange: { min: minUnits, max: maxUnits },\n processorNames: paymentMethodEntries.map((entry) => entry.name),\n conversionRates,\n payeeDetailsHashes,\n paymentMethodsOverride: paymentMethodHashes,\n paymentMethodDataOverride: payeeDetailsHashes.map((payeeDetails) => ({\n intentGatingService: GATING_SERVICE_ADDRESS,\n payeeDetails: payeeDetails as `0x${string}`,\n data: \"0x\" as `0x${string}`,\n })),\n currenciesOverride,\n intentGuardian: DEFAULT_INTENT_GUARDIAN_ADDRESS,\n escrowAddress: ESCROW_ADDRESS,\n txOverrides,\n });\n if (!result?.hash) throw new Error(\"No transaction hash returned\");\n hash = result.hash;\n } catch (err) {\n if (isUserCancellation(err))\n throw new OfframpError(\"User cancelled\", \"USER_CANCELLED\", \"depositing\", err);\n const detail = err instanceof Error ? err.message : String(err);\n throw new OfframpError(\n `Deposit transaction failed: ${detail}`,\n \"DEPOSIT_FAILED\",\n \"depositing\",\n err,\n );\n }\n\n // Confirm\n emitProgress({ step: \"confirming\", txHash: hash });\n let depositId = \"\";\n\n const receiptClient = client as {\n waitForTransactionReceipt?: (p: {\n hash: `0x${string}`;\n confirmations?: number;\n }) => Promise<{ logs: Array<{ topics?: Hex[]; data?: Hex }> }>;\n };\n if (typeof receiptClient.waitForTransactionReceipt === \"function\") {\n try {\n const receipt = await receiptClient.waitForTransactionReceipt({ hash, confirmations: 1 });\n depositId = extractDepositIdFromLogs(receipt.logs) || \"\";\n } catch {\n /* fall through to indexer */\n }\n }\n\n if (!depositId) {\n let delay = INDEXER_INITIAL_DELAY_MS;\n for (let attempt = 0; attempt < INDEXER_MAX_ATTEMPTS && !depositId; attempt++) {\n try {\n const deps = (await client.indexer.getDepositsWithRelations(\n { depositor: walletAddress },\n { limit: 25 },\n )) as Array<{ txHash?: string; depositId: string }>;\n const hit = deps.find((d) => (d?.txHash || \"\").toLowerCase() === hash.toLowerCase());\n if (hit) {\n depositId = String(hit.depositId);\n break;\n }\n } catch {\n /* continue */\n }\n await new Promise((r) => setTimeout(r, delay));\n delay = Math.min(INDEXER_MAX_DELAY_MS, Math.floor(delay * 1.7));\n }\n }\n\n if (!depositId) {\n throw new OfframpError(\n \"Deposit created on-chain but could not confirm deposit ID. Your funds are safe. Call offramp() again to resume delegation.\",\n \"CONFIRMATION_FAILED\",\n \"confirming\",\n undefined,\n { txHash: hash },\n );\n }\n\n // Delegate\n emitProgress({ step: \"delegating\", txHash: hash, depositId });\n try {\n await client.setRateManager({\n depositId: BigInt(depositId),\n rateManagerAddress: RATE_MANAGER_REGISTRY_ADDRESS,\n rateManagerId: DELEGATE_RATE_MANAGER_ID,\n escrowAddress: ESCROW_ADDRESS,\n txOverrides,\n });\n } catch (delegationError) {\n if (isUserCancellation(delegationError)) {\n throw new OfframpError(\n \"User cancelled delegation\",\n \"USER_CANCELLED\",\n \"delegating\",\n delegationError,\n { txHash: hash, depositId },\n );\n }\n throw new OfframpError(\n \"Deposit created but delegation failed. Call offramp() again to resume delegation.\",\n \"DELEGATION_FAILED\",\n \"delegating\",\n delegationError,\n { txHash: hash, depositId },\n );\n }\n\n // OTC restriction (optional)\n let otcLink: string | undefined;\n if (params.otcTaker) {\n emitProgress({ step: \"restricting\", txHash: hash, depositId });\n try {\n const otcResult = await enableOtc(walletClient, depositId, params.otcTaker);\n otcLink = otcResult.otcLink;\n } catch (otcError) {\n if (isUserCancellation(otcError)) {\n throw new OfframpError(\n \"User cancelled OTC restriction\",\n \"USER_CANCELLED\",\n \"restricting\",\n otcError,\n {\n txHash: hash,\n depositId,\n },\n );\n }\n throw new OfframpError(\n \"Deposit created and delegated but OTC restriction failed. Use enableOtc() to retry.\",\n \"DEPOSIT_FAILED\",\n \"restricting\",\n otcError,\n { txHash: hash, depositId },\n );\n }\n }\n\n emitProgress({ step: \"done\", txHash: hash, depositId });\n const result = { depositId, txHash: hash, resumed: false, otcLink };\n telemetry.emit(\"sdk.createDeposit.success\", {\n depositId: result.depositId,\n txHash: result.txHash,\n wallet: walletAddress,\n resumed: false,\n wallDurationMs: Date.now() - flowStartMs,\n });\n return result;\n } catch (error) {\n const known = error instanceof OfframpError ? error : null;\n telemetry.emit(\"sdk.createDeposit.error\", {\n code: known?.code ?? \"DEPOSIT_FAILED\",\n step: known?.step ?? \"unknown\",\n });\n throw error;\n }\n}\n","import { currencyInfo } from \"@zkp2p/sdk\";\n\nexport interface CurrencyEntry {\n readonly code: string;\n readonly name: string;\n readonly symbol: string;\n readonly countryCode: string;\n}\n\ntype CurrencyMap = { readonly [K in keyof typeof currencyInfo]: CurrencyEntry };\n\nfunction buildCurrencies(): CurrencyMap {\n const entries: Record<string, CurrencyEntry> = {};\n for (const [code, info] of Object.entries(\n currencyInfo as Record<\n string,\n {\n currencyCode?: string;\n currencyName?: string;\n currencySymbol?: string;\n countryCode?: string;\n }\n >,\n )) {\n entries[code] = {\n code: info.currencyCode ?? code,\n name: info.currencyName ?? code,\n symbol: info.currencySymbol ?? code,\n countryCode: info.countryCode ?? \"\",\n };\n }\n return entries as CurrencyMap;\n}\n\n/** All supported currencies with metadata. Access via `CURRENCIES.EUR.symbol` etc. */\nexport const CURRENCIES = buildCurrencies();\n","import type { WalletClient } from \"viem\";\n\nimport {\n DELEGATE_RATE_MANAGER_ID,\n DELEGATE_MANAGER_FEE_BPS,\n ESCROW_ADDRESS,\n RATE_MANAGER_REGISTRY_ADDRESS,\n SDK_VERSION,\n} from \"./config\";\nimport { CURRENCIES, type CurrencyEntry } from \"./currencies\";\nimport { offramp as createDepositFlow } from \"./deposit\";\nimport { OfframpError } from \"./errors\";\nimport { PLATFORMS, type PlatformEntry } from \"./platforms\";\nimport { createTelemetryContext, sanitizeAttributionId, type TelemetryContext } from \"./telemetry\";\nimport type {\n OfframpCreateOptions,\n OfframpParams,\n OfframpQuote,\n OfframpQuoteInput,\n OfframpResult,\n OfframpVaultStatus,\n OnProgress,\n} from \"./types\";\n\nconst IDEMPOTENCY_TTL_MS = 10 * 60 * 1000;\nconst IDEMPOTENCY_STORAGE_PREFIX = \"offramp:idempotency:\";\n\ninterface IdempotencyRecord {\n result: OfframpResult;\n expiresAt: number;\n}\n\n// The idempotency cache is backed by `sessionStorage`, so it is a no-op in\n// Node/worker runtimes. Warn server-side integrators exactly once per process\n// the first time they pass an `idempotencyKey` without a backing store, so they\n// learn at runtime instead of via duplicate deposits.\nlet warnedIdempotencyUnavailable = false;\n\nfunction warnIdempotencyUnavailableOnce(): void {\n if (warnedIdempotencyUnavailable) return;\n warnedIdempotencyUnavailable = true;\n console.warn(\n \"[offramp] idempotencyKey was provided but sessionStorage is unavailable \" +\n \"(Node/worker runtime). The idempotency cache is browser-only and no-ops here, \" +\n \"so retries can create duplicate deposits. For server-side dedup, call \" +\n \"deposits(walletAddress) and reuse an existing open deposit before creating one.\",\n );\n}\n\nfunction getWalletAddress(walletClient: WalletClient): string {\n const address = walletClient.account?.address;\n if (!address) {\n throw new OfframpError(\"Wallet client has no account. Connect a wallet first.\", \"VALIDATION\");\n }\n return address.toLowerCase();\n}\n\nfunction getIdempotencyStorageKey(walletAddress: string, idempotencyKey: string): string {\n return `${IDEMPOTENCY_STORAGE_PREFIX}${walletAddress}:${idempotencyKey}`;\n}\n\nfunction readIdempotencyResult(storageKey: string): OfframpResult | null {\n if (typeof sessionStorage === \"undefined\") return null;\n try {\n const raw = sessionStorage.getItem(storageKey);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as Partial<IdempotencyRecord>;\n const expiresAt =\n typeof parsed.expiresAt === \"number\" && Number.isFinite(parsed.expiresAt)\n ? parsed.expiresAt\n : 0;\n if (expiresAt <= Date.now()) {\n sessionStorage.removeItem(storageKey);\n return null;\n }\n const result = parsed.result;\n if (!result?.depositId || !result.txHash) {\n sessionStorage.removeItem(storageKey);\n return null;\n }\n return result;\n } catch {\n return null;\n }\n}\n\nfunction writeIdempotencyResult(storageKey: string, result: OfframpResult): void {\n if (typeof sessionStorage === \"undefined\") return;\n try {\n const record: IdempotencyRecord = {\n result,\n expiresAt: Date.now() + IDEMPOTENCY_TTL_MS,\n };\n sessionStorage.setItem(storageKey, JSON.stringify(record));\n } catch {\n // noop\n }\n}\n\nfunction createPerFlowTelemetry(\n base: TelemetryContext,\n integratorId?: string,\n referralId?: string,\n): TelemetryContext {\n return createTelemetryContext({\n sdkVersion: base.sdkVersion,\n telemetry: base.enabled,\n integratorId: sanitizeAttributionId(integratorId) ?? base.integratorId,\n referralId: sanitizeAttributionId(referralId) ?? base.referralId,\n });\n}\n\nfunction normalizeCurrencyEntry(code: string): CurrencyEntry {\n const fromCatalog = CURRENCIES[code as keyof typeof CURRENCIES];\n if (fromCatalog) return fromCatalog;\n return {\n code,\n name: code,\n symbol: code,\n countryCode: \"\",\n };\n}\n\nfunction buildCurrencyGroups(): Record<PlatformEntry[\"id\"], CurrencyEntry[]> {\n const grouped = {} as Record<PlatformEntry[\"id\"], CurrencyEntry[]>;\n for (const platform of Object.values(PLATFORMS)) {\n grouped[platform.id] = platform.currencies.map(normalizeCurrencyEntry);\n }\n return grouped;\n}\n\nexport interface OfframpConstructorOptions extends OfframpCreateOptions {\n walletClient: WalletClient;\n}\n\nexport class Offramp {\n private readonly walletClient: WalletClient;\n private readonly telemetry: TelemetryContext;\n private readonly apiBaseUrl?: string;\n\n constructor(options: OfframpConstructorOptions) {\n this.walletClient = options.walletClient;\n this.apiBaseUrl = options.apiBaseUrl;\n this.telemetry = createTelemetryContext({\n sdkVersion: SDK_VERSION,\n telemetry: options.telemetry,\n integratorId: options.integratorId,\n referralId: options.referralId,\n });\n\n this.telemetry.emit(\"sdk.init\", {\n userAgent: typeof navigator !== \"undefined\" ? navigator.userAgent : \"unknown\",\n });\n }\n\n async createDeposit(params: OfframpParams, onProgress?: OnProgress): Promise<OfframpResult> {\n const flowTelemetry = createPerFlowTelemetry(\n this.telemetry,\n params.integratorId,\n params.referralId,\n );\n const sanitizedParams: OfframpParams = {\n ...params,\n integratorId: flowTelemetry.integratorId,\n referralId: flowTelemetry.referralId,\n };\n\n const sanitizedKey = sanitizeAttributionId(params.idempotencyKey);\n if (sanitizedKey && typeof sessionStorage === \"undefined\") {\n warnIdempotencyUnavailableOnce();\n }\n const walletAddress = sanitizedKey ? getWalletAddress(this.walletClient) : null;\n const storageKey =\n walletAddress && sanitizedKey ? getIdempotencyStorageKey(walletAddress, sanitizedKey) : null;\n\n if (storageKey) {\n const existing = readIdempotencyResult(storageKey);\n if (existing) return existing;\n }\n\n const result = await createDepositFlow(\n this.walletClient,\n sanitizedParams,\n onProgress,\n flowTelemetry,\n this.apiBaseUrl,\n );\n\n if (storageKey) {\n writeIdempotencyResult(storageKey, result);\n }\n return result;\n }\n\n getQuote(input: OfframpQuoteInput): OfframpQuote {\n const amountUsdc = Number(input.amount);\n if (!Number.isFinite(amountUsdc) || amountUsdc <= 0) {\n throw new OfframpError(\"Amount must be a positive number\", \"VALIDATION\");\n }\n if (!input.platform.currencies.includes(input.currency.code)) {\n throw new OfframpError(\n `${input.currency.code} is not supported on ${input.platform.name}`,\n \"UNSUPPORTED\",\n );\n }\n\n const vaultSpreadBps = 0;\n const spreadFactor = Math.max(0, 1 - vaultSpreadBps / 10_000);\n const expectedFiat = amountUsdc * spreadFactor;\n const effectiveRate = amountUsdc === 0 ? 0 : expectedFiat / amountUsdc;\n\n return {\n amountUsdc,\n expectedFiat,\n effectiveRate,\n vaultSpreadBps,\n };\n }\n\n getVaultStatus(): OfframpVaultStatus {\n return {\n rateManagerId: DELEGATE_RATE_MANAGER_ID,\n rateManagerAddress: RATE_MANAGER_REGISTRY_ADDRESS,\n feeRateBps: DELEGATE_MANAGER_FEE_BPS,\n escrow: ESCROW_ADDRESS,\n isActive: true,\n };\n }\n\n listCurrencies(): Record<PlatformEntry[\"id\"], CurrencyEntry[]> {\n return buildCurrencyGroups();\n }\n}\n\nexport function createOfframp(options: OfframpConstructorOptions): Offramp {\n return new Offramp(options);\n}\n","/**\n * Peer browser-extension surface for SAR-capable makers. Drive the\n * headless metadata bridge via `usePeerExtensionRegistration` in\n * `@usdctofiat/offramp/react`, or manually:\n *\n * ```ts\n * import {\n * completePeerExtensionRegistration,\n * isPeerExtensionMetadataBridgeAvailable,\n * peerExtensionSdk,\n * } from \"@usdctofiat/offramp\";\n *\n * const state = await peerExtensionSdk.getState();\n * if (state === \"needs_install\" || !isPeerExtensionMetadataBridgeAvailable()) {\n * peerExtensionSdk.openInstallPage();\n * } else if (state === \"needs_connection\") {\n * await peerExtensionSdk.requestConnection();\n * } else {\n * peerExtensionSdk.authenticate({\n * actionType: \"transfer_paypal\",\n * captureMode: \"sellerCredential\",\n * platform: \"paypal\",\n * });\n * // Pass the captured metadata to completePeerExtensionRegistration(...), then retry.\n * }\n * ```\n */\nimport { PEER_EXTENSION_CHROME_URL } from \"@zkp2p/sdk\";\nimport type {\n PeerAuthenticateParams,\n PeerBuyerTeePaymentCapture,\n PeerBuyerTeePaymentParams,\n PeerConnectionStatus,\n PeerMetadataCaptureMode,\n PeerMetadataMessage,\n PeerMetadataMessageCallback,\n PeerMetadataProviderConfig,\n PeerMetadataRow,\n PeerSarCredentialCapture,\n SellerCredentialBundle,\n} from \"@zkp2p/sdk\";\n\nexport { PEER_EXTENSION_CHROME_URL };\nexport type {\n PeerAuthenticateParams,\n PeerBuyerTeePaymentCapture,\n PeerBuyerTeePaymentParams,\n PeerConnectionStatus,\n PeerMetadataCaptureMode,\n PeerMetadataMessage,\n PeerMetadataMessageCallback,\n PeerMetadataProviderConfig,\n PeerMetadataRow,\n PeerSarCredentialCapture,\n};\n\nexport type PeerSarCredentialBundle = SellerCredentialBundle;\n\nexport type PeerExtensionApi = {\n requestConnection(): Promise<boolean>;\n checkConnectionStatus(): Promise<PeerConnectionStatus>;\n getVersion(): Promise<string>;\n authenticate?: (params: PeerAuthenticateParams) => void;\n onMetadataMessage?: (callback: PeerMetadataMessageCallback) => () => void;\n};\n\nexport type PeerExtensionWindow = Window & {\n peer?: PeerExtensionApi;\n usdctofiatVerify?: PeerExtensionApi;\n};\n\nexport type PeerExtensionSdkOptions = {\n window?: PeerExtensionWindow;\n /**\n * Chrome Web Store listing opened by `openInstallPage()`. Defaults to the\n * USDCtoFiat Verify listing; pass `PEER_EXTENSION_CHROME_URL` (re-exported\n * from `@zkp2p/sdk`) to target the legacy PeerAuth listing, or any custom\n * branded-extension listing.\n */\n installUrl?: string;\n};\n\n/**\n * Default install target: the USDCtoFiat Verify extension (branded fork of\n * PeerAuth implementing the same window.peer interface).\n */\nexport const DEFAULT_EXTENSION_INSTALL_URL =\n \"https://chromewebstore.google.com/detail/usdctofiat-verify/lfkmdfifolhcfjmhklmckigfngghmpdf\";\n\nexport type PeerExtensionSdk = {\n requestConnection(): Promise<boolean>;\n checkConnectionStatus(): Promise<PeerConnectionStatus>;\n getVersion(): Promise<string>;\n authenticate(params: PeerAuthenticateParams): void;\n onMetadataMessage(callback: PeerMetadataMessageCallback): () => void;\n isAvailable(): boolean;\n openInstallPage(): void;\n getState(): Promise<PeerExtensionState>;\n};\n\nexport type PeerExtensionState = \"needs_install\" | \"needs_connection\" | \"ready\";\n\nconst resolveWindow = (options?: PeerExtensionSdkOptions): PeerExtensionWindow | undefined => {\n if (options?.window) {\n return options.window;\n }\n\n if (typeof window === \"undefined\") {\n return undefined;\n }\n\n return window as PeerExtensionWindow;\n};\n\nconst requirePeer = (options?: PeerExtensionSdkOptions): PeerExtensionApi => {\n const resolvedWindow = resolveWindow(options);\n if (!resolvedWindow) {\n throw new Error(\"Peer extension SDK requires a browser window.\");\n }\n\n const peer = resolvedWindow.usdctofiatVerify ?? resolvedWindow.peer;\n if (!peer) {\n throw new Error(\"Peer extension not available. Install or enable the Peer extension.\");\n }\n\n return peer;\n};\n\nexport const isPeerExtensionAvailable = (options?: PeerExtensionSdkOptions): boolean => {\n const resolvedWindow = resolveWindow(options);\n return Boolean(resolvedWindow?.usdctofiatVerify ?? resolvedWindow?.peer);\n};\n\nconst hasHeadlessMetadataBridge = (peer: PeerExtensionApi): boolean =>\n typeof peer.authenticate === \"function\" && typeof peer.onMetadataMessage === \"function\";\n\nconst requirePeerMetadataBridge = (\n options?: PeerExtensionSdkOptions,\n): PeerExtensionApi & Required<Pick<PeerExtensionApi, \"authenticate\" | \"onMetadataMessage\">> => {\n const peer = requirePeer(options);\n if (!hasHeadlessMetadataBridge(peer)) {\n throw new Error(\"Peer extension metadata bridge unavailable. Install or update Peer.\");\n }\n return peer as PeerExtensionApi &\n Required<Pick<PeerExtensionApi, \"authenticate\" | \"onMetadataMessage\">>;\n};\n\nexport const isPeerExtensionMetadataBridgeAvailable = (\n options?: PeerExtensionSdkOptions,\n): boolean => {\n const resolvedWindow = resolveWindow(options);\n const peer = resolvedWindow?.usdctofiatVerify ?? resolvedWindow?.peer;\n return Boolean(peer && hasHeadlessMetadataBridge(peer));\n};\n\nexport const openPeerExtensionInstallPage = (options?: PeerExtensionSdkOptions): void => {\n const resolvedWindow = resolveWindow(options);\n if (!resolvedWindow) {\n throw new Error(\"Peer extension SDK requires a browser window.\");\n }\n\n const installUrl = options?.installUrl ?? DEFAULT_EXTENSION_INSTALL_URL;\n resolvedWindow.open(installUrl, \"_blank\", \"noopener,noreferrer\");\n};\n\nexport const getPeerExtensionState = async (\n options?: PeerExtensionSdkOptions,\n): Promise<PeerExtensionState> => {\n if (!isPeerExtensionAvailable(options)) {\n return \"needs_install\";\n }\n\n try {\n const status = await requirePeer(options).checkConnectionStatus();\n return status === \"connected\" ? \"ready\" : \"needs_connection\";\n } catch {\n return \"needs_connection\";\n }\n};\n\nexport const createPeerExtensionSdk = (options: PeerExtensionSdkOptions = {}): PeerExtensionSdk => {\n return {\n isAvailable: () => isPeerExtensionAvailable(options),\n requestConnection: () => requirePeer(options).requestConnection(),\n checkConnectionStatus: () => requirePeer(options).checkConnectionStatus(),\n getVersion: () => requirePeer(options).getVersion(),\n authenticate: (params: PeerAuthenticateParams) =>\n requirePeerMetadataBridge(options).authenticate(params),\n onMetadataMessage: (callback: PeerMetadataMessageCallback) =>\n requirePeerMetadataBridge(options).onMetadataMessage(callback),\n openInstallPage: () => openPeerExtensionInstallPage(options),\n getState: () => getPeerExtensionState(options),\n };\n};\n\nexport const peerExtensionSdk = createPeerExtensionSdk();\n"],"mappings":"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","names":["createPublicClient","http","base","getCurrencyInfoFromHash","getCurrencyInfoFromHash","base","createPublicClient","http","createPublicClient","formatUnits","http","base","extractTxHash","client","txOverrides","result","createPublicClient","base","http","formatUnits","currencyInfo","base"]}
|
|
@@ -110,6 +110,7 @@ interface CompletePeerExtensionRegistrationResult {
|
|
|
110
110
|
declare function getPeerExtensionRegistrationInfo(platform: string): PeerExtensionRegistrationInfo | null;
|
|
111
111
|
declare function getPeerExtensionRegistrationAuthParams(platform: string, options?: {
|
|
112
112
|
attestationServiceUrl?: string | null;
|
|
113
|
+
callerAddress?: string | null;
|
|
113
114
|
}): PeerAuthenticateParams | null;
|
|
114
115
|
declare function completePeerExtensionRegistration(input: CompletePeerExtensionRegistrationInput): Promise<CompletePeerExtensionRegistrationResult>;
|
|
115
116
|
/**
|
|
@@ -279,4 +280,4 @@ declare class OfframpError extends Error {
|
|
|
279
280
|
});
|
|
280
281
|
}
|
|
281
282
|
|
|
282
|
-
export { getPlatformLimits as A, isPeerExtensionRegistrationError as B,
|
|
283
|
+
export { getPlatformLimits as A, isPeerExtensionRegistrationError as B, type CurrencyEntry as C, type DepositInfo as D, normalizePaypalMeUsername as E, MakersCreateError as M, type OfframpParams as O, type PlatformEntry as P, type OnProgress as a, type OfframpResult as b, type OfframpCreateOptions as c, type OfframpQuoteInput as d, type OfframpQuote as e, type OfframpVaultStatus as f, CURRENCIES as g, type CompletePeerExtensionRegistrationInput as h, type CompletePeerExtensionRegistrationResult as i, type DepositStatus as j, OFFRAMP_ERROR_CODES as k, OfframpError as l, type OfframpErrorCode as m, type OfframpProgress as n, type OfframpState as o, type OfframpStep as p, PLATFORMS as q, PLATFORM_LIMITS as r, type PayeeDepositData as s, type PeerExtensionRegistrationInfo as t, type PlatformKey as u, type PlatformLimits as v, type PlatformTier as w, completePeerExtensionRegistration as x, getPeerExtensionRegistrationAuthParams as y, getPeerExtensionRegistrationInfo as z };
|
|
@@ -110,6 +110,7 @@ interface CompletePeerExtensionRegistrationResult {
|
|
|
110
110
|
declare function getPeerExtensionRegistrationInfo(platform: string): PeerExtensionRegistrationInfo | null;
|
|
111
111
|
declare function getPeerExtensionRegistrationAuthParams(platform: string, options?: {
|
|
112
112
|
attestationServiceUrl?: string | null;
|
|
113
|
+
callerAddress?: string | null;
|
|
113
114
|
}): PeerAuthenticateParams | null;
|
|
114
115
|
declare function completePeerExtensionRegistration(input: CompletePeerExtensionRegistrationInput): Promise<CompletePeerExtensionRegistrationResult>;
|
|
115
116
|
/**
|
|
@@ -279,4 +280,4 @@ declare class OfframpError extends Error {
|
|
|
279
280
|
});
|
|
280
281
|
}
|
|
281
282
|
|
|
282
|
-
export { getPlatformLimits as A, isPeerExtensionRegistrationError as B,
|
|
283
|
+
export { getPlatformLimits as A, isPeerExtensionRegistrationError as B, type CurrencyEntry as C, type DepositInfo as D, normalizePaypalMeUsername as E, MakersCreateError as M, type OfframpParams as O, type PlatformEntry as P, type OnProgress as a, type OfframpResult as b, type OfframpCreateOptions as c, type OfframpQuoteInput as d, type OfframpQuote as e, type OfframpVaultStatus as f, CURRENCIES as g, type CompletePeerExtensionRegistrationInput as h, type CompletePeerExtensionRegistrationResult as i, type DepositStatus as j, OFFRAMP_ERROR_CODES as k, OfframpError as l, type OfframpErrorCode as m, type OfframpProgress as n, type OfframpState as o, type OfframpStep as p, PLATFORMS as q, PLATFORM_LIMITS as r, type PayeeDepositData as s, type PeerExtensionRegistrationInfo as t, type PlatformKey as u, type PlatformLimits as v, type PlatformTier as w, completePeerExtensionRegistration as x, getPeerExtensionRegistrationAuthParams as y, getPeerExtensionRegistrationInfo as z };
|