@usdctofiat/offramp 2.0.4 → 3.0.1
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 +94 -0
- package/README.md +1 -1
- package/dist/{chunk-EVC54JGM.js → chunk-5KJ4DFWK.js} +28 -18
- package/dist/chunk-5KJ4DFWK.js.map +1 -0
- package/dist/index.cjs +27 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/react.cjs +27 -17
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +1 -1
- package/package.json +4 -4
- package/dist/chunk-EVC54JGM.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,98 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [3.0.1] - 2026-05-10
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Expand Zelle deposit creation into the three live Base payment-method variants
|
|
15
|
+
(`zelle-bofa`, `zelle-chase`, `zelle-citi`) while keeping maker registration
|
|
16
|
+
canonicalized to `processorName: "zelle"`.
|
|
17
|
+
|
|
18
|
+
## [3.0.0] - 2026-05-07
|
|
19
|
+
|
|
20
|
+
### ⚠ BREAKING CHANGES
|
|
21
|
+
|
|
22
|
+
The Peer browser extension upstream cut over to a prepared-calldata contract.
|
|
23
|
+
The host app now owns the fulfill broadcast instead of the extension. Anyone
|
|
24
|
+
driving `peerExtensionSdk` directly through the re-export must migrate.
|
|
25
|
+
|
|
26
|
+
- **`peerExtensionSdk.onramp(params)` is no longer fire-and-forget.** It now
|
|
27
|
+
takes a callback and yields prepared calldata for the host to broadcast:
|
|
28
|
+
`peerExtensionSdk.onramp(params, (prepared) => { /* sign & send */ })`. The
|
|
29
|
+
callback receives `{ status: "calldata_ready", intentHash, transaction: { to,
|
|
30
|
+
data, value, chainId } }` — broadcast it through your wallet client.
|
|
31
|
+
- **`peerExtensionSdk.onIntentFulfilled(callback)` was removed.** Subscriptions
|
|
32
|
+
no longer exist; the prepared-calldata callback above replaces them. Track
|
|
33
|
+
fulfillment off the `sendTransaction` resolution in your callback.
|
|
34
|
+
- **`intentHash` is required** in the `onramp` params (was optional). Pass the
|
|
35
|
+
hash returned by `signalIntent` upstream.
|
|
36
|
+
- **`PeerIntentFulfilledResult` / `PeerIntentFulfilledCallback` /
|
|
37
|
+
`PeerIntentFulfilledBridgeStatus` are gone** from `@zkp2p/sdk`. Anyone
|
|
38
|
+
importing them directly will hit a missing-name error. Switch to
|
|
39
|
+
`PeerOnrampPreparedTransactionResult` / `PeerOnrampPreparedTransactionCallback`
|
|
40
|
+
(now re-exported from this package).
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
|
|
44
|
+
- **`peerExtensionSdk.getOnrampTransaction(intentHash)`** pull-recovery path
|
|
45
|
+
for prepared calldata when the callback was missed (page reload, tab close,
|
|
46
|
+
extension restart). Returns the same `calldata_ready` shape or `null` if
|
|
47
|
+
nothing is pending. Wire it into your active-intent resume flow.
|
|
48
|
+
- **New type re-exports** from `@zkp2p/sdk`: `PeerOnrampPreparedTransactionCallback`,
|
|
49
|
+
`PeerOnrampPreparedTransactionResult`, `PeerExtensionOnrampParams`. Available
|
|
50
|
+
from both the core entry and via `extension.ts`.
|
|
51
|
+
|
|
52
|
+
### Migration
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
// Before (2.x)
|
|
56
|
+
peerExtensionSdk.onramp({
|
|
57
|
+
intentHash,
|
|
58
|
+
paymentPlatform: "wise",
|
|
59
|
+
inputAmount: "100",
|
|
60
|
+
amountUsdc: "100000000",
|
|
61
|
+
recipientAddress,
|
|
62
|
+
referrer: "myapp",
|
|
63
|
+
});
|
|
64
|
+
const unsubscribe = peerExtensionSdk.onIntentFulfilled((result) => {
|
|
65
|
+
if (result.status === "fulfilled") {
|
|
66
|
+
handleFulfilled(result.fulfillTxHash);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// After (3.x)
|
|
71
|
+
peerExtensionSdk.onramp(
|
|
72
|
+
{
|
|
73
|
+
intentHash, // now REQUIRED
|
|
74
|
+
paymentPlatform: "wise",
|
|
75
|
+
inputAmount: "100",
|
|
76
|
+
amountUsdc: "100000000",
|
|
77
|
+
recipientAddress,
|
|
78
|
+
referrer: "myapp",
|
|
79
|
+
},
|
|
80
|
+
async (prepared) => {
|
|
81
|
+
const fulfillTxHash = await walletClient.sendTransaction({
|
|
82
|
+
to: prepared.transaction.to,
|
|
83
|
+
data: prepared.transaction.data,
|
|
84
|
+
value: BigInt(prepared.transaction.value || "0"),
|
|
85
|
+
chainId: prepared.transaction.chainId,
|
|
86
|
+
});
|
|
87
|
+
handleFulfilled(fulfillTxHash);
|
|
88
|
+
},
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
// Optional: pull-recovery on page mount when an active intent exists
|
|
92
|
+
const prepared = await peerExtensionSdk.getOnrampTransaction(intentHash);
|
|
93
|
+
if (prepared?.status === "calldata_ready") {
|
|
94
|
+
// broadcast as above
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Changed
|
|
99
|
+
|
|
100
|
+
- Bump `@zkp2p/sdk` to `0.4.0-rc.4`.
|
|
101
|
+
|
|
10
102
|
## [2.0.4] - 2026-04-25
|
|
11
103
|
|
|
12
104
|
### Docs
|
|
@@ -279,6 +371,8 @@ If you were on `@usdctofiat/offramp@1.x`:
|
|
|
279
371
|
- Dual CJS/ESM build via tsup with type definitions for both entry points.
|
|
280
372
|
|
|
281
373
|
[Unreleased]: https://github.com/ADWilkinson/galleonlabs-zkp2p/compare/main...HEAD
|
|
374
|
+
[3.0.1]: https://github.com/ADWilkinson/galleonlabs-zkp2p/releases/tag/offramp-sdk-v3.0.1
|
|
375
|
+
[3.0.0]: https://github.com/ADWilkinson/galleonlabs-zkp2p/releases/tag/offramp-sdk-v3.0.0
|
|
282
376
|
[2.0.4]: https://github.com/ADWilkinson/galleonlabs-zkp2p/releases/tag/offramp-sdk-v2.0.4
|
|
283
377
|
[2.0.3]: https://github.com/ADWilkinson/galleonlabs-zkp2p/releases/tag/offramp-sdk-v2.0.3
|
|
284
378
|
[2.0.2]: https://github.com/ADWilkinson/galleonlabs-zkp2p/releases/tag/offramp-sdk-v2.0.2
|
package/README.md
CHANGED
|
@@ -217,7 +217,7 @@ Every deposit is automatically delegated to the Delegate vault for oracle-based
|
|
|
217
217
|
|
|
218
218
|
## Webhooks
|
|
219
219
|
|
|
220
|
-
Subscribe to `deposit.created`, `deposit.filled`, `deposit.partially_filled`, `deposit.closed`, `otc.
|
|
220
|
+
Subscribe to live `deposit.created`, `deposit.filled`, `deposit.partially_filled`, `deposit.closed`, and `otc.taken` events for your attributed deposits. `otc.enabled` and `otc.disabled` are reserved event names. Register endpoints at [usdctofiat.xyz/developers](https://usdctofiat.xyz/developers) with your Peerlytics API key. HMAC-SHA256 signed deliveries use the `X-Usdctofiat-Signature: t=<unix>,v1=<hex>` header. Reference HMAC receiver in the [starters repo](https://github.com/ADWilkinson/usdctofiat-peerlytics-starters).
|
|
221
221
|
|
|
222
222
|
## Links
|
|
223
223
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/config.ts
|
|
2
2
|
import { getContracts, getGatingServiceAddress } from "@zkp2p/sdk";
|
|
3
|
-
var SDK_VERSION = "
|
|
3
|
+
var SDK_VERSION = "3.0.1";
|
|
4
4
|
var BASE_CHAIN_ID = 8453;
|
|
5
5
|
var RUNTIME_ENV = "production";
|
|
6
6
|
var API_BASE_URL = "https://api.zkp2p.xyz";
|
|
@@ -322,6 +322,13 @@ function getPaymentMethodHashes(platform) {
|
|
|
322
322
|
}
|
|
323
323
|
return Array.from(hashes);
|
|
324
324
|
}
|
|
325
|
+
function getPaymentMethodCreateEntries(platform) {
|
|
326
|
+
if (platform !== "zelle") {
|
|
327
|
+
const hash = getPaymentMethodHash(platform);
|
|
328
|
+
return hash ? [{ name: platform, hash }] : [];
|
|
329
|
+
}
|
|
330
|
+
return Object.entries(PAYMENT_CATALOG).filter(([name, entry]) => name.startsWith("zelle") && Boolean(entry.paymentMethodHash)).sort(([a], [b]) => a.localeCompare(b)).map(([name, entry]) => ({ name, hash: entry.paymentMethodHash }));
|
|
331
|
+
}
|
|
325
332
|
function buildDepositData(platform, identifier, telegramUsername = "") {
|
|
326
333
|
const offchainId = platform === "chime" ? identifier.toLowerCase() : identifier;
|
|
327
334
|
return telegramUsername ? { offchainId, telegramUsername } : { offchainId };
|
|
@@ -1293,8 +1300,8 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
|
|
|
1293
1300
|
throw new OfframpError(validation.error || "Invalid identifier", "VALIDATION");
|
|
1294
1301
|
}
|
|
1295
1302
|
const normalizedIdentifier = validation.normalized;
|
|
1296
|
-
const
|
|
1297
|
-
if (
|
|
1303
|
+
const paymentMethodEntries = getPaymentMethodCreateEntries(platformId);
|
|
1304
|
+
if (paymentMethodEntries.length === 0) {
|
|
1298
1305
|
throw new OfframpError(`${platform.name} is not currently supported`, "UNSUPPORTED");
|
|
1299
1306
|
}
|
|
1300
1307
|
const existing = await findUndelegatedDeposit(walletAddress);
|
|
@@ -1410,11 +1417,16 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
|
|
|
1410
1417
|
);
|
|
1411
1418
|
}
|
|
1412
1419
|
emitProgress({ step: "depositing" });
|
|
1413
|
-
const conversionRates = [
|
|
1414
|
-
|
|
1415
|
-
];
|
|
1416
|
-
const baseCurrenciesOverride = mapConversionRatesToOnchainMinRate(
|
|
1420
|
+
const conversionRates = paymentMethodEntries.map(() => [
|
|
1421
|
+
{ currency: currencyCode, conversionRate: "1" }
|
|
1422
|
+
]);
|
|
1423
|
+
const baseCurrenciesOverride = mapConversionRatesToOnchainMinRate(
|
|
1424
|
+
conversionRates,
|
|
1425
|
+
paymentMethodEntries.length
|
|
1426
|
+
);
|
|
1417
1427
|
const currenciesOverride = attachOracleConfig(baseCurrenciesOverride, conversionRates);
|
|
1428
|
+
const paymentMethodHashes = paymentMethodEntries.map((entry) => entry.hash);
|
|
1429
|
+
const payeeDetailsHashes = paymentMethodEntries.map(() => hashedOnchainId);
|
|
1418
1430
|
let hash;
|
|
1419
1431
|
try {
|
|
1420
1432
|
const result2 = await client.createDeposit({
|
|
@@ -1422,17 +1434,15 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
|
|
|
1422
1434
|
amount: amountUnits,
|
|
1423
1435
|
retainOnEmpty: false,
|
|
1424
1436
|
intentAmountRange: { min: minUnits, max: maxUnits },
|
|
1425
|
-
processorNames:
|
|
1437
|
+
processorNames: paymentMethodEntries.map((entry) => entry.name),
|
|
1426
1438
|
conversionRates,
|
|
1427
|
-
payeeDetailsHashes
|
|
1428
|
-
paymentMethodsOverride:
|
|
1429
|
-
paymentMethodDataOverride:
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
}
|
|
1435
|
-
],
|
|
1439
|
+
payeeDetailsHashes,
|
|
1440
|
+
paymentMethodsOverride: paymentMethodHashes,
|
|
1441
|
+
paymentMethodDataOverride: payeeDetailsHashes.map((payeeDetails) => ({
|
|
1442
|
+
intentGatingService: GATING_SERVICE_ADDRESS,
|
|
1443
|
+
payeeDetails,
|
|
1444
|
+
data: "0x"
|
|
1445
|
+
})),
|
|
1436
1446
|
currenciesOverride,
|
|
1437
1447
|
escrowAddress: ESCROW_ADDRESS,
|
|
1438
1448
|
txOverrides
|
|
@@ -1774,4 +1784,4 @@ export {
|
|
|
1774
1784
|
openPeerExtensionInstallPage,
|
|
1775
1785
|
getPeerExtensionState
|
|
1776
1786
|
};
|
|
1777
|
-
//# sourceMappingURL=chunk-
|
|
1787
|
+
//# sourceMappingURL=chunk-5KJ4DFWK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/platforms.ts","../src/errors.ts","../src/otc.ts","../../../node_modules/@zkp2p/contracts-v2/abis/base/WhitelistPreIntentHook.json","../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 = \"3.0.1\";\nexport const BASE_CHAIN_ID = 8453;\nexport const RUNTIME_ENV = \"production\" as const;\nexport const API_BASE_URL = \"https://api.zkp2p.xyz\";\nexport const BASE_RPC_URL = \"https://mainnet.base.org\";\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\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 {\n currencyInfo,\n getCurrencyInfoFromHash,\n getPaymentMethodsCatalog,\n resolvePaymentMethodHash,\n} from \"@zkp2p/sdk\";\nimport { z } from \"zod\";\nimport { BASE_CHAIN_ID, RUNTIME_ENV } from \"./config\";\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\"\n | \"n26\";\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 in the Peer extension at `/verify/<providerId>`.\n */\nexport interface PeerExtensionRegistrationInfo {\n /** Peer extension provider id. Used to build `/verify/<providerId>`. */\n readonly providerId: string;\n /** Message shown to the user when curator rejects the maker. */\n readonly requiredPrompt: string;\n /** Label for the install / connect / verify CTA. */\n readonly ctaLabel: string;\n /** Optional subtext (e.g. PayPal Business disclaimer). */\n readonly ctaSubtext?: string;\n /** Minimum Peer extension version required. */\n readonly minExtensionVersion: 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 n26: [\"EUR\"],\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, \"\").replace(/^www\\./i, \"\");\n if (/^paypal\\.me(?:[?#].*)?$/i.test(withoutProtocol)) return \"\";\n const withoutDomain = withoutProtocol.replace(/^paypal\\.me\\//i, \"\");\n const [pathWithoutQuery] = withoutDomain.split(/[?#]/, 1);\n const sanitizedPath = pathWithoutQuery.replace(/^\\/+/, \"\");\n const [username] = sanitizedPath.split(\"/\", 1);\n return username.replace(/^@+/, \"\").trim().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 },\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 },\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. Verify it in the Peer extension, then refresh and retry with the same Wisetag.\",\n ctaLabel: \"Install Peer Extension\",\n minExtensionVersion: \"0.4.12\",\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 validation: z.string().email(),\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(/^[a-z0-9._-]+$/i, \"Use your PayPal.me username (letters, numbers, . _ -)\"),\n transform: normalizePaypalMeUsername,\n extensionRegistration: {\n providerId: \"paypal\",\n requiredPrompt:\n \"This PayPal username is not registered yet. Verify it in the Peer extension, then refresh and retry with the same PayPal username.\",\n ctaLabel: \"Install Peer Extension\",\n ctaSubtext: \"PayPal Business accounts are not supported at this time.\",\n minExtensionVersion: \"0.4.14\",\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 n26: {\n id: \"n26\",\n name: \"N26\",\n identifierLabel: \"IBAN\",\n placeholder: \"IBAN (e.g. DE89...)\",\n helperText: \"Your IBAN (spaces will be removed)\",\n validation: z\n .string()\n .min(15)\n .max(34)\n .regex(/^[A-Z]{2}[0-9]{2}[A-Z0-9]+$/i),\n transform: (v) => v.replace(/\\s/g, \"\").toUpperCase(),\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 N26: buildPlatformEntry(BLUEPRINTS.n26),\n} as const;\n\n/** Platform key type for PLATFORMS constant. */\nexport type PlatformKey = keyof typeof PLATFORMS;\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\nfunction resolveCanonicalZelleHash(): `0x${string}` | null {\n const direct = PAYMENT_CATALOG.zelle?.paymentMethodHash;\n if (direct) return direct;\n const variant = Object.entries(PAYMENT_CATALOG).find(\n ([name, entry]) => name.startsWith(\"zelle\") && Boolean(entry.paymentMethodHash),\n );\n return variant?.[1]?.paymentMethodHash ?? null;\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\" || name.startsWith(\"zelle-\")) return resolveCanonicalZelleHash();\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 = new Set<`0x${string}`>();\n const generic = resolvePaymentMethodHash(\"zelle\") as `0x${string}` | undefined;\n if (generic) hashes.add(generic);\n const canonical = resolveCanonicalZelleHash();\n if (canonical) hashes.add(canonical);\n for (const [name, entry] of Object.entries(PAYMENT_CATALOG)) {\n if (name.startsWith(\"zelle\") && entry.paymentMethodHash) {\n hashes.add(entry.paymentMethodHash);\n }\n }\n return Array.from(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\n return Object.entries(PAYMENT_CATALOG)\n .filter(([name, entry]) => name.startsWith(\"zelle\") && Boolean(entry.paymentMethodHash))\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, entry]) => ({ name, hash: entry.paymentMethodHash! }));\n}\n\n/** Flat payload accepted by `POST /v2/makers/create`. */\nexport interface PayeeDepositData {\n offchainId: string;\n telegramUsername?: string;\n metadata?: Record<string, string>;\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\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\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 const lower = normalized.toLowerCase();\n return EXTENSION_REGISTRATION_ERROR_PATTERNS.some((p) => lower.includes(p));\n}\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 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://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 * If the deposit already has a different taker whitelisted, replaces it.\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 // Remove any existing takers that aren't the desired one\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}/deposit/${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 {\n \"inputs\": [\n {\n \"internalType\": \"address\",\n \"name\": \"_orchestratorRegistry\",\n \"type\": \"address\"\n }\n ],\n \"stateMutability\": \"nonpayable\",\n \"type\": \"constructor\"\n },\n {\n \"inputs\": [],\n \"name\": \"EmptyArray\",\n \"type\": \"error\"\n },\n {\n \"inputs\": [\n {\n \"internalType\": \"address\",\n \"name\": \"taker\",\n \"type\": \"address\"\n },\n {\n \"internalType\": \"address\",\n \"name\": \"escrow\",\n \"type\": \"address\"\n },\n {\n \"internalType\": \"uint256\",\n \"name\": \"depositId\",\n \"type\": \"uint256\"\n }\n ],\n \"name\": \"TakerNotInWhitelist\",\n \"type\": \"error\"\n },\n {\n \"inputs\": [\n {\n \"internalType\": \"address\",\n \"name\": \"taker\",\n \"type\": \"address\"\n },\n {\n \"internalType\": \"address\",\n \"name\": \"escrow\",\n \"type\": \"address\"\n },\n {\n \"internalType\": \"uint256\",\n \"name\": \"depositId\",\n \"type\": \"uint256\"\n }\n ],\n \"name\": \"TakerNotWhitelisted\",\n \"type\": \"error\"\n },\n {\n \"inputs\": [\n {\n \"internalType\": \"address\",\n \"name\": \"caller\",\n \"type\": \"address\"\n },\n {\n \"internalType\": \"address\",\n \"name\": \"owner\",\n \"type\": \"address\"\n },\n {\n \"internalType\": \"address\",\n \"name\": \"delegate\",\n \"type\": \"address\"\n }\n ],\n \"name\": \"UnauthorizedCallerOrDelegate\",\n \"type\": \"error\"\n },\n {\n \"inputs\": [\n {\n \"internalType\": \"address\",\n \"name\": \"caller\",\n \"type\": \"address\"\n }\n ],\n \"name\": \"UnauthorizedOrchestratorCaller\",\n \"type\": \"error\"\n },\n {\n \"inputs\": [],\n \"name\": \"ZeroAddress\",\n \"type\": \"error\"\n },\n {\n \"anonymous\": false,\n \"inputs\": [\n {\n \"indexed\": true,\n \"internalType\": \"address\",\n \"name\": \"escrow\",\n \"type\": \"address\"\n },\n {\n \"indexed\": true,\n \"internalType\": \"uint256\",\n \"name\": \"depositId\",\n \"type\": \"uint256\"\n },\n {\n \"indexed\": true,\n \"internalType\": \"address\",\n \"name\": \"taker\",\n \"type\": \"address\"\n }\n ],\n \"name\": \"TakerRemovedFromWhitelist\",\n \"type\": \"event\"\n },\n {\n \"anonymous\": false,\n \"inputs\": [\n {\n \"indexed\": true,\n \"internalType\": \"address\",\n \"name\": \"escrow\",\n \"type\": \"address\"\n },\n {\n \"indexed\": true,\n \"internalType\": \"uint256\",\n \"name\": \"depositId\",\n \"type\": \"uint256\"\n },\n {\n \"indexed\": true,\n \"internalType\": \"address\",\n \"name\": \"taker\",\n \"type\": \"address\"\n }\n ],\n \"name\": \"TakerWhitelisted\",\n \"type\": \"event\"\n },\n {\n \"inputs\": [\n {\n \"internalType\": \"address\",\n \"name\": \"_escrow\",\n \"type\": \"address\"\n },\n {\n \"internalType\": \"uint256\",\n \"name\": \"_depositId\",\n \"type\": \"uint256\"\n },\n {\n \"internalType\": \"address[]\",\n \"name\": \"_takers\",\n \"type\": \"address[]\"\n }\n ],\n \"name\": \"addToWhitelist\",\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\",\n \"type\": \"function\"\n },\n {\n \"inputs\": [\n {\n \"internalType\": \"address\",\n \"name\": \"_escrow\",\n \"type\": \"address\"\n },\n {\n \"internalType\": \"uint256\",\n \"name\": \"_depositId\",\n \"type\": \"uint256\"\n },\n {\n \"internalType\": \"address\",\n \"name\": \"_taker\",\n \"type\": \"address\"\n }\n ],\n \"name\": \"isWhitelisted\",\n \"outputs\": [\n {\n \"internalType\": \"bool\",\n \"name\": \"\",\n \"type\": \"bool\"\n }\n ],\n \"stateMutability\": \"view\",\n \"type\": \"function\"\n },\n {\n \"inputs\": [],\n \"name\": \"orchestratorRegistry\",\n \"outputs\": [\n {\n \"internalType\": \"contract IOrchestratorRegistry\",\n \"name\": \"\",\n \"type\": \"address\"\n }\n ],\n \"stateMutability\": \"view\",\n \"type\": \"function\"\n },\n {\n \"inputs\": [\n {\n \"internalType\": \"address\",\n \"name\": \"_escrow\",\n \"type\": \"address\"\n },\n {\n \"internalType\": \"uint256\",\n \"name\": \"_depositId\",\n \"type\": \"uint256\"\n },\n {\n \"internalType\": \"address[]\",\n \"name\": \"_takers\",\n \"type\": \"address[]\"\n }\n ],\n \"name\": \"removeFromWhitelist\",\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\",\n \"type\": \"function\"\n },\n {\n \"inputs\": [\n {\n \"components\": [\n {\n \"internalType\": \"address\",\n \"name\": \"taker\",\n \"type\": \"address\"\n },\n {\n \"internalType\": \"address\",\n \"name\": \"escrow\",\n \"type\": \"address\"\n },\n {\n \"internalType\": \"uint256\",\n \"name\": \"depositId\",\n \"type\": \"uint256\"\n },\n {\n \"internalType\": \"uint256\",\n \"name\": \"amount\",\n \"type\": \"uint256\"\n },\n {\n \"internalType\": \"address\",\n \"name\": \"to\",\n \"type\": \"address\"\n },\n {\n \"internalType\": \"bytes32\",\n \"name\": \"paymentMethod\",\n \"type\": \"bytes32\"\n },\n {\n \"internalType\": \"bytes32\",\n \"name\": \"fiatCurrency\",\n \"type\": \"bytes32\"\n },\n {\n \"internalType\": \"uint256\",\n \"name\": \"conversionRate\",\n \"type\": \"uint256\"\n },\n {\n \"components\": [\n {\n \"internalType\": \"address\",\n \"name\": \"recipient\",\n \"type\": \"address\"\n },\n {\n \"internalType\": \"uint256\",\n \"name\": \"fee\",\n \"type\": \"uint256\"\n }\n ],\n \"internalType\": \"struct IReferralFee.ReferralFee[]\",\n \"name\": \"referralFees\",\n \"type\": \"tuple[]\"\n },\n {\n \"internalType\": \"bytes\",\n \"name\": \"preIntentHookData\",\n \"type\": \"bytes\"\n }\n ],\n \"internalType\": \"struct IPreIntentHook.PreIntentContext\",\n \"name\": \"_ctx\",\n \"type\": \"tuple\"\n }\n ],\n \"name\": \"validateSignalIntent\",\n \"outputs\": [],\n \"stateMutability\": \"view\",\n \"type\": \"function\"\n },\n {\n \"inputs\": [\n {\n \"internalType\": \"address\",\n \"name\": \"\",\n \"type\": \"address\"\n },\n {\n \"internalType\": \"uint256\",\n \"name\": \"\",\n \"type\": \"uint256\"\n },\n {\n \"internalType\": \"address\",\n \"name\": \"\",\n \"type\": \"address\"\n }\n ],\n \"name\": \"whitelist\",\n \"outputs\": [\n {\n \"internalType\": \"bool\",\n \"name\": \"\",\n \"type\": \"bool\"\n }\n ],\n \"stateMutability\": \"view\",\n \"type\": \"function\"\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(walletClient: WalletClient): 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: API_BASE_URL,\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 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 MIN_DEPOSIT_USDC,\n MIN_ORDER_USDC,\n PAYEE_REGISTRATION_TIMEOUT_MS,\n RATE_MANAGER_REGISTRY_ADDRESS,\n REFERRER,\n SDK_VERSION,\n USDC_ADDRESS,\n} from \"./config\";\nimport {\n buildDepositData,\n getPaymentMethodCreateEntries,\n isPeerExtensionRegistrationError,\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\nasync function registerPayeeDetails(\n processorName: string,\n payload: { offchainId: string; telegramUsername?: string; metadata?: Record<string, string> },\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(`${API_BASE_URL}/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\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): Promise<OfframpResult> {\n const { amount, platform, currency, identifier } = params;\n const platformId = platform.id;\n const currencyCode = currency.code;\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);\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, 2500)));\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 const client = createSdkClient(walletClient);\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 const canonicalName = platformId.startsWith(\"zelle\") ? \"zelle\" : platformId;\n try {\n const payeePayload = buildDepositData(canonicalName, normalizedIdentifier);\n hashedOnchainId = await registerPayeeDetails(canonicalName, payeePayload);\n } catch (err) {\n // Curator now requires PayPal + Wise makers to register their handle in\n // the Peer extension first (upstream #540, #610, #649). A 400 or\n // \"creating the maker\" message on those platforms means the integrator\n // needs to walk the user through the Peer extension verify flow before\n // retrying. Surface that via a dedicated error code so callers can\n // branch on recovery UI (see `usePeerExtensionRegistration` in the\n // React entry point).\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. Verify this handle in the extension, 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 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\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\n constructor(options: OfframpConstructorOptions) {\n this.walletClient = options.walletClient;\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 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 );\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 (PeerAuth) browser-extension surface for PayPal + Wise makers. Drive\n * the handshake via `usePeerExtensionRegistration` in\n * `@usdctofiat/offramp/react`, or manually:\n *\n * ```ts\n * import { peerExtensionSdk } from \"@usdctofiat/offramp\";\n *\n * const state = await peerExtensionSdk.getState();\n * if (state === \"needs_install\") peerExtensionSdk.openInstallPage();\n * else if (state === \"needs_connection\") await peerExtensionSdk.requestConnection();\n * else peerExtensionSdk.openSidebar(\"/verify/paypal\");\n * ```\n */\nexport {\n PEER_EXTENSION_CHROME_URL,\n peerExtensionSdk,\n createPeerExtensionSdk,\n isPeerExtensionAvailable,\n openPeerExtensionInstallPage,\n getPeerExtensionState,\n} from \"@zkp2p/sdk\";\nexport type {\n PeerExtensionOnrampParams,\n PeerExtensionApi,\n PeerExtensionSdk,\n PeerExtensionSdkOptions,\n PeerExtensionState,\n PeerExtensionWindow,\n PeerConnectionStatus,\n PeerOnrampPreparedTransactionCallback,\n PeerOnrampPreparedTransactionResult,\n} from \"@zkp2p/sdk\";\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"]}
|
package/dist/index.cjs
CHANGED
|
@@ -59,7 +59,7 @@ var import_sdk5 = require("@zkp2p/sdk");
|
|
|
59
59
|
|
|
60
60
|
// src/config.ts
|
|
61
61
|
var import_sdk = require("@zkp2p/sdk");
|
|
62
|
-
var SDK_VERSION = "
|
|
62
|
+
var SDK_VERSION = "3.0.1";
|
|
63
63
|
var BASE_CHAIN_ID = 8453;
|
|
64
64
|
var RUNTIME_ENV = "production";
|
|
65
65
|
var API_BASE_URL = "https://api.zkp2p.xyz";
|
|
@@ -376,6 +376,13 @@ function getPaymentMethodHashes(platform) {
|
|
|
376
376
|
}
|
|
377
377
|
return Array.from(hashes);
|
|
378
378
|
}
|
|
379
|
+
function getPaymentMethodCreateEntries(platform) {
|
|
380
|
+
if (platform !== "zelle") {
|
|
381
|
+
const hash = getPaymentMethodHash(platform);
|
|
382
|
+
return hash ? [{ name: platform, hash }] : [];
|
|
383
|
+
}
|
|
384
|
+
return Object.entries(PAYMENT_CATALOG).filter(([name, entry]) => name.startsWith("zelle") && Boolean(entry.paymentMethodHash)).sort(([a], [b]) => a.localeCompare(b)).map(([name, entry]) => ({ name, hash: entry.paymentMethodHash }));
|
|
385
|
+
}
|
|
379
386
|
function buildDepositData(platform, identifier, telegramUsername = "") {
|
|
380
387
|
const offchainId = platform === "chime" ? identifier.toLowerCase() : identifier;
|
|
381
388
|
return telegramUsername ? { offchainId, telegramUsername } : { offchainId };
|
|
@@ -1334,8 +1341,8 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
|
|
|
1334
1341
|
throw new OfframpError(validation.error || "Invalid identifier", "VALIDATION");
|
|
1335
1342
|
}
|
|
1336
1343
|
const normalizedIdentifier = validation.normalized;
|
|
1337
|
-
const
|
|
1338
|
-
if (
|
|
1344
|
+
const paymentMethodEntries = getPaymentMethodCreateEntries(platformId);
|
|
1345
|
+
if (paymentMethodEntries.length === 0) {
|
|
1339
1346
|
throw new OfframpError(`${platform.name} is not currently supported`, "UNSUPPORTED");
|
|
1340
1347
|
}
|
|
1341
1348
|
const existing = await findUndelegatedDeposit(walletAddress);
|
|
@@ -1451,11 +1458,16 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
|
|
|
1451
1458
|
);
|
|
1452
1459
|
}
|
|
1453
1460
|
emitProgress({ step: "depositing" });
|
|
1454
|
-
const conversionRates = [
|
|
1455
|
-
|
|
1456
|
-
];
|
|
1457
|
-
const baseCurrenciesOverride = (0, import_sdk5.mapConversionRatesToOnchainMinRate)(
|
|
1461
|
+
const conversionRates = paymentMethodEntries.map(() => [
|
|
1462
|
+
{ currency: currencyCode, conversionRate: "1" }
|
|
1463
|
+
]);
|
|
1464
|
+
const baseCurrenciesOverride = (0, import_sdk5.mapConversionRatesToOnchainMinRate)(
|
|
1465
|
+
conversionRates,
|
|
1466
|
+
paymentMethodEntries.length
|
|
1467
|
+
);
|
|
1458
1468
|
const currenciesOverride = attachOracleConfig(baseCurrenciesOverride, conversionRates);
|
|
1469
|
+
const paymentMethodHashes = paymentMethodEntries.map((entry) => entry.hash);
|
|
1470
|
+
const payeeDetailsHashes = paymentMethodEntries.map(() => hashedOnchainId);
|
|
1459
1471
|
let hash;
|
|
1460
1472
|
try {
|
|
1461
1473
|
const result2 = await client.createDeposit({
|
|
@@ -1463,17 +1475,15 @@ async function offramp(walletClient, params, onProgress, telemetryContext) {
|
|
|
1463
1475
|
amount: amountUnits,
|
|
1464
1476
|
retainOnEmpty: false,
|
|
1465
1477
|
intentAmountRange: { min: minUnits, max: maxUnits },
|
|
1466
|
-
processorNames:
|
|
1478
|
+
processorNames: paymentMethodEntries.map((entry) => entry.name),
|
|
1467
1479
|
conversionRates,
|
|
1468
|
-
payeeDetailsHashes
|
|
1469
|
-
paymentMethodsOverride:
|
|
1470
|
-
paymentMethodDataOverride:
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
}
|
|
1476
|
-
],
|
|
1480
|
+
payeeDetailsHashes,
|
|
1481
|
+
paymentMethodsOverride: paymentMethodHashes,
|
|
1482
|
+
paymentMethodDataOverride: payeeDetailsHashes.map((payeeDetails) => ({
|
|
1483
|
+
intentGatingService: GATING_SERVICE_ADDRESS,
|
|
1484
|
+
payeeDetails,
|
|
1485
|
+
data: "0x"
|
|
1486
|
+
})),
|
|
1477
1487
|
currenciesOverride,
|
|
1478
1488
|
escrowAddress: ESCROW_ADDRESS,
|
|
1479
1489
|
txOverrides
|