@p2pdotme/sdk 1.2.3 → 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/country.cjs +88 -4
- package/dist/country.cjs.map +1 -1
- package/dist/country.d.cts +14 -1
- package/dist/country.d.ts +14 -1
- package/dist/country.mjs +86 -4
- package/dist/country.mjs.map +1 -1
- package/dist/fraud-engine.cjs +2 -1
- package/dist/fraud-engine.cjs.map +1 -1
- package/dist/fraud-engine.mjs +2 -1
- package/dist/fraud-engine.mjs.map +1 -1
- package/dist/index.cjs +3 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +3 -2
- package/dist/index.mjs.map +1 -1
- package/dist/orders.cjs +2 -1
- package/dist/orders.cjs.map +1 -1
- package/dist/orders.d.cts +2 -0
- package/dist/orders.d.ts +2 -0
- package/dist/orders.mjs +2 -1
- package/dist/orders.mjs.map +1 -1
- package/dist/prices.cjs +2 -1
- package/dist/prices.cjs.map +1 -1
- package/dist/prices.d.cts +1 -0
- package/dist/prices.d.ts +1 -0
- package/dist/prices.mjs +2 -1
- package/dist/prices.mjs.map +1 -1
- package/dist/profile.cjs +2 -1
- package/dist/profile.cjs.map +1 -1
- package/dist/profile.d.cts +2 -0
- package/dist/profile.d.ts +2 -0
- package/dist/profile.mjs +2 -1
- package/dist/profile.mjs.map +1 -1
- package/dist/qr-parsers.cjs +52 -3
- package/dist/qr-parsers.cjs.map +1 -1
- package/dist/qr-parsers.d.cts +1 -0
- package/dist/qr-parsers.d.ts +1 -0
- package/dist/qr-parsers.mjs +52 -3
- package/dist/qr-parsers.mjs.map +1 -1
- package/dist/react.cjs +2 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +6 -0
- package/dist/react.d.ts +6 -0
- package/dist/react.mjs +2 -1
- package/dist/react.mjs.map +1 -1
- package/dist/stake.cjs +2 -1
- package/dist/stake.cjs.map +1 -1
- package/dist/stake.d.cts +1 -0
- package/dist/stake.d.ts +1 -0
- package/dist/stake.mjs +2 -1
- package/dist/stake.mjs.map +1 -1
- package/dist/zkkyc.cjs +2 -1
- package/dist/zkkyc.cjs.map +1 -1
- package/dist/zkkyc.mjs +2 -1
- package/dist/zkkyc.mjs.map +1 -1
- package/package.json +1 -1
package/dist/country.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/country/currency.ts","../src/country/currencies/ars.ts","../src/country/currencies/brl.ts","../src/country/currencies/cop.ts","../src/country/currencies/ecu.ts","../src/country/currencies/eur.ts","../src/country/currencies/idr.ts","../src/country/currencies/inr.ts","../src/country/currencies/mex.ts","../src/country/currencies/ngn.ts","../src/country/currencies/usd.ts","../src/country/currencies/ven.ts","../src/country/countries.ts","../src/country/payment-fields.ts","../src/country/validators.ts"],"sourcesContent":["/**\n * All supported currency symbols. Single source of truth for the SDK.\n *\n * Lives alongside the country metadata so that adding a currency is a\n * single-folder operation: drop a new file in `currencies/<code>.ts`, add it\n * to this map, and both `COUNTRY_OPTIONS` and `ZodCurrencySchema` pick it up.\n */\nexport const CURRENCY = {\n\tIDR: \"IDR\",\n\tINR: \"INR\",\n\tBRL: \"BRL\",\n\tARS: \"ARS\",\n\tMEX: \"MEX\",\n\tVEN: \"VEN\",\n\tEUR: \"EUR\",\n\tNGN: \"NGN\",\n\tUSD: \"USD\",\n\tCOP: \"COP\",\n\tECU: \"ECU\",\n} as const;\n\n/** Union of supported currency codes. */\nexport type CurrencyCode = (typeof CURRENCY)[keyof typeof CURRENCY];\n\n/**\n * Tuple form of the currency codes — used by `z.enum(...)` in the shared\n * validation layer. Narrow tuple type required by Zod.\n */\nexport const CURRENCY_CODES = Object.values(CURRENCY) as [CurrencyCode, ...CurrencyCode[]];\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const ARS_PLACEHOLDER = \"juan.perez\";\nexport const ARS_VALIDATION_ERROR =\n\t\"Please enter a valid CBU/CVU (22 digits) or Alias (6-20 characters)\";\n\n/** Validates CBU (Clave Bancaria Uniforme) — Argentine banking key, 22 digits with checksums. */\nfunction validateCBU(cbu: string): boolean {\n\tif (cbu.length !== 22) return false;\n\tif (/^(\\d)\\1{21}$/.test(cbu)) return false;\n\n\tconst bankCode = cbu.substring(0, 7);\n\tconst bankCheckDigit = parseInt(cbu[7], 10);\n\tlet sum = 0;\n\tconst weights = [7, 1, 3, 9, 7, 1, 3];\n\tfor (let i = 0; i < 7; i++) {\n\t\tsum += parseInt(bankCode[i], 10) * weights[i];\n\t}\n\tconst calculatedBankCheck = (10 - (sum % 10)) % 10;\n\tif (bankCheckDigit !== calculatedBankCheck) return false;\n\n\tconst accountNumber = cbu.substring(8, 21);\n\tconst accountCheckDigit = parseInt(cbu[21], 10);\n\tsum = 0;\n\tconst accountWeights = [3, 9, 7, 1, 3, 9, 7, 1, 3, 9, 7, 1, 3];\n\tfor (let i = 0; i < 13; i++) {\n\t\tsum += parseInt(accountNumber[i], 10) * accountWeights[i];\n\t}\n\tconst calculatedAccountCheck = (10 - (sum % 10)) % 10;\n\tif (accountCheckDigit !== calculatedAccountCheck) return false;\n\n\treturn true;\n}\n\n/**\n * Validates Argentine payment IDs (CBU, CVU, or Alias).\n * CBU/CVU: 22 digits with checksum. Alias: 6-20 alphanumeric characters.\n */\nexport function validateArgentinePaymentId(paymentId: string): boolean {\n\tif (!paymentId || paymentId.trim().length === 0) return false;\n\n\tconst trimmedPaymentId = paymentId.trim();\n\n\tif (/^\\d{22}$/.test(trimmedPaymentId)) return validateCBU(trimmedPaymentId);\n\tif (/^[a-zA-Z0-9.\\-_]{6,20}$/.test(trimmedPaymentId)) return true;\n\n\treturn false;\n}\n\n/** Payment ID field configuration for ARS (Argentina, ALIAS). */\nexport const ARS_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"alias\",\n\t\tlabel: \"ALIAS_ID\",\n\t\tplaceholder: ARS_PLACEHOLDER,\n\t\tdisplayLabel: \"Alias\",\n\t\tvalidate: validateArgentinePaymentId,\n\t\tvalidationErrorMessage: ARS_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for Argentina (ARS). */\nexport const ARS_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Argentina\",\n\tcurrency: CURRENCY.ARS,\n\tsymbolNative: \"$\",\n\tlocale: \"es-AR\",\n\tpaymentMethod: \"ALIAS\",\n\tpaymentAddressName: \"ALIAS_ID\",\n\ttimezone: \"America/Argentina/Buenos_Aires\",\n\ttimezone_name: \"ART\",\n\tflag: \"🇦🇷\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1e6-1f1f7.png\",\n\tphoneCode: \"+54\",\n\ttelegramSupportChannel: \"https://t.me/p2pmeargentina\",\n\ttwitterUsername: \"p2pmeargentina\",\n\tsmsCountryCodes: [\"AR\"],\n\tprecision: 2,\n\tisAlpha: false,\n\tdisabled: false,\n\tdisabledPaymentTypes: [],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const BRL_PLACEHOLDER = \"Chave pix ou pix copia e cola\";\nexport const BRL_VALIDATION_ERROR = \"Please enter a valid PIX ID\";\n\n/** Validates CPF (Brazilian tax ID for individuals). */\nfunction validateCPF(cpf: string): boolean {\n\tif (cpf.length !== 11) return false;\n\tif (/^(\\d)\\1{10}$/.test(cpf)) return false;\n\n\tlet sum = 0;\n\tfor (let i = 0; i < 9; i++) {\n\t\tsum += parseInt(cpf[i], 10) * (10 - i);\n\t}\n\tlet remainder = sum % 11;\n\tconst firstDigit = remainder < 2 ? 0 : 11 - remainder;\n\tif (parseInt(cpf[9], 10) !== firstDigit) return false;\n\n\tsum = 0;\n\tfor (let i = 0; i < 10; i++) {\n\t\tsum += parseInt(cpf[i], 10) * (11 - i);\n\t}\n\tremainder = sum % 11;\n\tconst secondDigit = remainder < 2 ? 0 : 11 - remainder;\n\treturn parseInt(cpf[10], 10) === secondDigit;\n}\n\n/** Validates CNPJ (Brazilian tax ID for companies). */\nfunction validateCNPJ(cnpj: string): boolean {\n\tif (cnpj.length !== 14) return false;\n\tif (/^(\\d)\\1{13}$/.test(cnpj)) return false;\n\n\tlet sum = 0;\n\tconst weights1 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];\n\tfor (let i = 0; i < 12; i++) {\n\t\tsum += parseInt(cnpj[i], 10) * weights1[i];\n\t}\n\tlet remainder = sum % 11;\n\tconst firstDigit = remainder < 2 ? 0 : 11 - remainder;\n\tif (parseInt(cnpj[12], 10) !== firstDigit) return false;\n\n\tsum = 0;\n\tconst weights2 = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];\n\tfor (let i = 0; i < 13; i++) {\n\t\tsum += parseInt(cnpj[i], 10) * weights2[i];\n\t}\n\tremainder = sum % 11;\n\tconst secondDigit = remainder < 2 ? 0 : 11 - remainder;\n\treturn parseInt(cnpj[13], 10) === secondDigit;\n}\n\n/**\n * Validates PIX ID format.\n * PIX can be: CPF (11 digits), CNPJ (14 digits), email, phone (10–11 digits or E.164),\n * random key (UUID), or a PIX \"copia e cola\" EMV QR payload (starts with 000201).\n */\nexport function validatePIXId(pixId: string): boolean {\n\tif (!pixId || pixId.trim().length === 0) return false;\n\n\tconst trimmedPixId = pixId.trim();\n\n\t// PIX \"copia e cola\" — EMV QR code payload\n\tif (/^000201/.test(trimmedPixId)) return true;\n\n\t// 11 digits: valid CPF or Brazilian mobile phone key (DDD 11–99 + digit 9 + 8 digits)\n\tif (/^\\d{11}$/.test(trimmedPixId))\n\t\treturn validateCPF(trimmedPixId) || /^[1-9][1-9]9\\d{8}$/.test(trimmedPixId);\n\tif (/^\\d{14}$/.test(trimmedPixId)) return validateCNPJ(trimmedPixId);\n\tif (/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(trimmedPixId)) return true;\n\t// Phone key: 10–11 digits (with or without country code prefix)\n\tif (/^\\d{10,11}$/.test(trimmedPixId)) return true;\n\tif (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(trimmedPixId))\n\t\treturn true;\n\n\treturn false;\n}\n\n/** Payment ID field configuration for BRL (Brazil, PIX). */\nexport const BRL_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"pix\",\n\t\tlabel: \"PIX_ID\",\n\t\tplaceholder: BRL_PLACEHOLDER,\n\t\tdisplayLabel: \"PIX ID\",\n\t\tvalidate: validatePIXId,\n\t\tvalidationErrorMessage: BRL_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for Brazil (BRL). */\nexport const BRL_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Brazil\",\n\tcurrency: CURRENCY.BRL,\n\tsymbolNative: \"R$\",\n\tlocale: \"pt-BR\",\n\tpaymentMethod: \"PIX\",\n\tpaymentAddressName: \"PIX_ID\",\n\ttimezone: \"America/Sao_Paulo\",\n\ttimezone_name: \"BRT\",\n\tflag: \"🇧🇷\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1e7-1f1f7.png\",\n\tphoneCode: \"+55\",\n\ttelegramSupportChannel: \"https://t.me/p2pmebrasil\",\n\ttwitterUsername: \"p2pmebrasil\",\n\tsmsCountryCodes: [\"BR\"],\n\tprecision: 2,\n\tisAlpha: false,\n\tdisabled: false,\n\tdisabledPaymentTypes: [],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const COP_PLACEHOLDER = \"3001234567 / juan.perez@nequi.com.co / @alias\";\nexport const COP_VALIDATION_ERROR =\n\t\"Please enter a valid Colombian payment ID (e.g., 3001234567, email, or @alias)\";\n\n/**\n * Validates Colombian payment ID for Nequi, Daviplata, or Bre-B.\n * Accepts a 10-digit phone number starting with 3, a valid email address,\n * or a Bre-B alias starting with @ (e.g. @juanperez).\n */\nexport function validateColombianPaymentId(paymentId: string): boolean {\n\tif (!paymentId || paymentId.trim().length === 0) return false;\n\tconst trimmed = paymentId.trim();\n\tif (/^3\\d{9}$/.test(trimmed)) return true;\n\tif (/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(trimmed)) return true;\n\tif (/^@\\S+$/.test(trimmed)) return true;\n\treturn false;\n}\n\n/** Payment ID field configuration for COP (Colombia, Transferencia). */\nexport const COP_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"alias\",\n\t\tlabel: \"ALIAS_TRANSFERENCIA\",\n\t\tplaceholder: COP_PLACEHOLDER,\n\t\tdisplayLabel: \"Nequi / Daviplata / Bre-B\",\n\t\tvalidate: validateColombianPaymentId,\n\t\tvalidationErrorMessage: COP_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for Colombia (COP). */\nexport const COP_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Colombia\",\n\tcurrency: CURRENCY.COP,\n\tsymbolNative: \"$\",\n\tlocale: \"es-CO\",\n\tpaymentMethod: \"TRANSFERENCIA\",\n\tpaymentAddressName: \"ALIAS_TRANSFERENCIA\",\n\ttimezone: \"America/Bogota\",\n\ttimezone_name: \"COT\",\n\tflag: \"🇨🇴\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1e8-1f1f4.png\",\n\tphoneCode: \"+57\",\n\ttelegramSupportChannel: \"https://t.me/p2pmecolombiaclientes\",\n\ttwitterUsername: \"p2pmeColombia\",\n\tsmsCountryCodes: [\"CO\"],\n\tprecision: 2,\n\tisAlpha: true,\n\tdisabled: false,\n\tdisabledPaymentTypes: [],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\n// ── Placeholders & error messages ────────────────────────────────────────────\n\nexport const ECU_PLACEHOLDER_BANK = \"Banco Pichincha\";\nexport const ECU_PLACEHOLDER_ACCOUNT_TYPE = \"Savings / Checking\";\nexport const ECU_PLACEHOLDER_ACCOUNT_NUMBER = \"2100123456\";\nexport const ECU_PLACEHOLDER_NAME = \"Juan Pérez\";\nexport const ECU_PLACEHOLDER_CEDULA = \"1710034065\";\n\nexport const ECU_BANK_VALIDATION_ERROR = \"Please enter the bank name\";\nexport const ECU_ACCOUNT_TYPE_VALIDATION_ERROR = \"Please enter the account type\";\nexport const ECU_ACCOUNT_NUMBER_VALIDATION_ERROR =\n\t\"Please enter a valid account number (4-20 digits)\";\nexport const ECU_NAME_VALIDATION_ERROR = \"Please enter the account holder name\";\nexport const ECU_CEDULA_VALIDATION_ERROR = \"Please enter a valid Ecuadorian cédula or RUC\";\n\n// ── Validators ───────────────────────────────────────────────────────────────\n\nfunction isValidCedulaCore(cedula: string): boolean {\n\tif (!/^\\d{10}$/.test(cedula)) return false;\n\tconst province = Number(cedula.slice(0, 2));\n\tif (province < 1 || province > 24) return false;\n\tif (Number(cedula[2]) >= 6) return false;\n\n\tconst coefficients = [2, 1, 2, 1, 2, 1, 2, 1, 2];\n\tlet sum = 0;\n\tfor (let i = 0; i < 9; i++) {\n\t\tlet product = Number(cedula[i]) * coefficients[i];\n\t\tif (product > 9) product -= 9;\n\t\tsum += product;\n\t}\n\tconst checkDigit = sum % 10 === 0 ? 0 : 10 - (sum % 10);\n\treturn checkDigit === Number(cedula[9]);\n}\n\n/**\n * Validates an Ecuadorian cédula (10-digit, módulo-10 checksum) or a 13-digit RUC\n * whose first 10 digits form a valid cédula. Province must be 01–24 and the third\n * digit < 6 (natural person).\n */\nexport function validateEcuadorianCedula(value: string): boolean {\n\tif (!value || value.trim().length === 0) return false;\n\tconst cleaned = value.trim().replace(/\\D/g, \"\");\n\tif (cleaned.length === 13) return isValidCedulaCore(cleaned.slice(0, 10));\n\tif (cleaned.length !== 10) return false;\n\treturn isValidCedulaCore(cleaned);\n}\n\n/** Validates an Ecuadorian bank account number — 4–20 digits after stripping separators. */\nexport function validateEcuadorianAccountNumber(value: string): boolean {\n\tif (!value || value.trim().length === 0) return false;\n\tconst cleaned = value.trim().replace(/\\D/g, \"\");\n\treturn /^\\d{4,20}$/.test(cleaned);\n}\n\n/** Validates an account holder name — non-empty, letters/spaces/apostrophe/period/hyphen only. */\nexport function validateEcuadorianAccountName(value: string): boolean {\n\tif (!value || value.trim().length === 0) return false;\n\treturn /^[A-Za-zÀ-ÿ][A-Za-zÀ-ÿ .'-]{1,}$/.test(value.trim());\n}\n\n// ── Payment fields ───────────────────────────────────────────────────────────\n\n/** Payment ID field configuration for ECU (Ecuador, bank transfer — all free text). */\nexport const ECU_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"bank-name\",\n\t\tlabel: \"BANK_NAME\",\n\t\tplaceholder: ECU_PLACEHOLDER_BANK,\n\t\tdisplayLabel: \"Bank\",\n\t\tvalidate: (v: string) => v.trim().length > 0,\n\t\tvalidationErrorMessage: ECU_BANK_VALIDATION_ERROR,\n\t},\n\t{\n\t\tkey: \"account-type\",\n\t\tlabel: \"ACCOUNT_TYPE\",\n\t\tplaceholder: ECU_PLACEHOLDER_ACCOUNT_TYPE,\n\t\tdisplayLabel: \"Account Type\",\n\t\tvalidate: (v: string) => v.trim().length > 0,\n\t\tvalidationErrorMessage: ECU_ACCOUNT_TYPE_VALIDATION_ERROR,\n\t},\n\t{\n\t\tkey: \"account-number\",\n\t\tlabel: \"ACCOUNT_NUMBER\",\n\t\tplaceholder: ECU_PLACEHOLDER_ACCOUNT_NUMBER,\n\t\tdisplayLabel: \"Account Number\",\n\t\tvalidate: validateEcuadorianAccountNumber,\n\t\tvalidationErrorMessage: ECU_ACCOUNT_NUMBER_VALIDATION_ERROR,\n\t},\n\t{\n\t\tkey: \"account-name\",\n\t\tlabel: \"NAME\",\n\t\tplaceholder: ECU_PLACEHOLDER_NAME,\n\t\tdisplayLabel: \"Name\",\n\t\tvalidate: validateEcuadorianAccountName,\n\t\tvalidationErrorMessage: ECU_NAME_VALIDATION_ERROR,\n\t},\n\t{\n\t\tkey: \"cedula\",\n\t\tlabel: \"CEDULA\",\n\t\tplaceholder: ECU_PLACEHOLDER_CEDULA,\n\t\tdisplayLabel: \"Cédula\",\n\t\tvalidate: validateEcuadorianCedula,\n\t\tvalidationErrorMessage: ECU_CEDULA_VALIDATION_ERROR,\n\t},\n];\n\n// ── Country option ───────────────────────────────────────────────────────────\n\n/** Country option for Ecuador (ECU — USD-denominated, bank transfer + DeUna QR). */\nexport const ECU_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Ecuador\",\n\tcurrency: CURRENCY.ECU,\n\tinternationalFormat: \"USD\",\n\tsymbolNative: \"$\",\n\tlocale: \"es-EC\",\n\tpaymentMethod: \"TRANSFERENCIA\",\n\tpaymentAddressName: \"ECU_BANK_DETAILS\",\n\ttimezone: \"America/Guayaquil\",\n\ttimezone_name: \"ECT\",\n\tflag: \"🇪🇨\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1ea-1f1e8.png\",\n\tphoneCode: \"+593\",\n\ttelegramSupportChannel: \"https://t.me/Ecuador_P2P\",\n\ttwitterUsername: \"P2Pdotme_Ecu\",\n\tsmsCountryCodes: [\"EC\"],\n\tprecision: 2,\n\tisAlpha: true,\n\tdisabled: false,\n\tdisabledPaymentTypes: [],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const EUR_PLACEHOLDER = \"@username or email\";\nexport const EUR_VALIDATION_ERROR = \"Please enter a valid Revolut ID (username, email, or phone)\";\n\n/**\n * Validates Revolut ID (username, email, or phone number).\n */\nexport function validateRevolutId(revolutId: string): boolean {\n\tif (!revolutId || revolutId.trim().length === 0) return false;\n\n\tconst trimmed = revolutId.trim();\n\n\tif (/^@?[a-zA-Z0-9._-]{3,30}$/.test(trimmed)) return true;\n\tif (/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(trimmed)) return true;\n\tif (/^\\+?\\d{7,15}$/.test(trimmed)) return true;\n\n\treturn false;\n}\n\n/** Payment ID field configuration for EUR (Revolut EUR). */\nexport const EUR_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"revolut\",\n\t\tlabel: \"REVOLUT_ID\",\n\t\tplaceholder: EUR_PLACEHOLDER,\n\t\tdisplayLabel: \"Revolut ID\",\n\t\tvalidate: validateRevolutId,\n\t\tvalidationErrorMessage: EUR_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for Revolut EUR. */\nexport const EUR_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Revolut EUR\",\n\tcurrency: CURRENCY.EUR,\n\tsymbolNative: \"€\",\n\tlocale: \"de-DE\",\n\tpaymentMethod: \"REVOLUT\",\n\tpaymentAddressName: \"REVOLUT_ID\",\n\ttimezone: \"Europe/Berlin\",\n\ttimezone_name: \"CET\",\n\tflag: \"\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f310.png\",\n\tphoneCode: \"\",\n\ttelegramSupportChannel: \"https://t.me/P2Pdotme\",\n\ttwitterUsername: \"P2Pdotme\",\n\tsmsCountryCodes: [],\n\tprecision: 2,\n\tisAlpha: true,\n\tdisabled: true,\n\tdisabledPaymentTypes: [\"PAY\"],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const IDR_PLACEHOLDER = \"8123456789\";\nexport const IDR_VALIDATION_ERROR =\n\t\"Please enter a valid Indonesian phone number (e.g., 8123456789)\";\n\n/**\n * Validates Indonesian phone number.\n * Validates just the number part (9-12 digits).\n */\nexport function validateIndonesianPhoneNumber(phoneNumber: string): boolean {\n\tif (!phoneNumber || phoneNumber.trim().length === 0) return false;\n\tif (/[a-zA-Z]/.test(phoneNumber)) return false;\n\tconst cleaned = phoneNumber.replace(/\\D/g, \"\");\n\treturn /^\\d{9,12}$/.test(cleaned);\n}\n\n/** Payment ID field configuration for IDR (Indonesia, QRIS). */\nexport const IDR_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"phone\",\n\t\tlabel: \"PHONE_NUMBER\",\n\t\tplaceholder: IDR_PLACEHOLDER,\n\t\tdisplayLabel: \"Phone Number\",\n\t\tvalidate: validateIndonesianPhoneNumber,\n\t\tvalidationErrorMessage: IDR_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for Indonesia (IDR). */\nexport const IDR_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Indonesia\",\n\tcurrency: CURRENCY.IDR,\n\tsymbolNative: \"Rp\",\n\tlocale: \"id-ID\",\n\tpaymentMethod: \"QRIS\",\n\tpaymentAddressName: \"PHONE_NUMBER\",\n\ttimezone: \"Asia/Jakarta\",\n\ttimezone_name: \"WIB\",\n\tflag: \"🇮🇩\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1ee-1f1e9.png\",\n\tphoneCode: \"+62\",\n\ttelegramSupportChannel: \"https://t.me/p2pmeindonesia\",\n\ttwitterUsername: \"p2pdotmeID\",\n\tsmsCountryCodes: [],\n\tprecision: 0,\n\tisAlpha: false,\n\tdisabled: false,\n\tdisabledPaymentTypes: [],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const INR_PLACEHOLDER = \"merchant@upi\";\nexport const INR_VALIDATION_ERROR = \"Please enter a valid UPI ID (e.g., username@bankname)\";\n\n/**\n * Validates UPI ID format.\n * UPI ID format: username@bankname (e.g., john@paytm, user@ybl, 8658404239@kotak811)\n */\nexport function validateUPIId(upiId: string): boolean {\n\tif (!upiId || upiId.trim().length === 0) return false;\n\tconst upiRegex = /^[a-zA-Z0-9.\\-_]{2,256}@[a-zA-Z0-9]{2,64}$/;\n\treturn upiRegex.test(upiId.trim());\n}\n\n/** Payment ID field configuration for INR (India, UPI). */\nexport const INR_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"upi\",\n\t\tlabel: \"UPI_ID\",\n\t\tplaceholder: INR_PLACEHOLDER,\n\t\tdisplayLabel: \"UPI ID\",\n\t\tvalidate: validateUPIId,\n\t\tvalidationErrorMessage: INR_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for India (INR). */\nexport const INR_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"India\",\n\tcurrency: CURRENCY.INR,\n\tsymbolNative: \"₹\",\n\tlocale: \"en-IN\",\n\tpaymentMethod: \"UPI\",\n\tpaymentAddressName: \"UPI_ID\",\n\ttimezone: \"Asia/Kolkata\",\n\ttimezone_name: \"IST\",\n\tflag: \"🇮🇳\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1ee-1f1f3.png\",\n\tphoneCode: \"+91\",\n\ttelegramSupportChannel: \"https://t.me/P2Pdotme\",\n\ttwitterUsername: \"P2Pdotme\",\n\tsmsCountryCodes: [\"IN\"],\n\tprecision: 2,\n\tisAlpha: false,\n\tdisabled: false,\n\tdisabledPaymentTypes: [],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const MEX_PLACEHOLDER = \"012345678901234567\";\nexport const MEX_VALIDATION_ERROR =\n\t\"Please enter a valid CLABE (18 digits), card number, or phone number\";\n\n/**\n * Validates Mexican payment IDs (CLABE, card number, or phone number).\n * CLABE: 18 digits. Card: 16 digits. Phone: 10 digits.\n */\nexport function validateMexicanPaymentId(paymentId: string): boolean {\n\tif (!paymentId || paymentId.trim().length === 0) return false;\n\n\tconst trimmed = paymentId.trim().replace(/\\D/g, \"\");\n\n\tif (/^\\d{18}$/.test(trimmed)) return true;\n\tif (/^\\d{16}$/.test(trimmed)) return true;\n\tif (/^\\d{10}$/.test(trimmed)) return true;\n\n\treturn false;\n}\n\n/** Payment ID field configuration for MEX (Mexico, SPEI). */\nexport const MEX_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"clabe\",\n\t\tlabel: \"CLABE_ID\",\n\t\tplaceholder: MEX_PLACEHOLDER,\n\t\tdisplayLabel: \"CLABE\",\n\t\tvalidate: validateMexicanPaymentId,\n\t\tvalidationErrorMessage: MEX_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for Mexico (MEX). */\nexport const MEX_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Mexico\",\n\tcurrency: CURRENCY.MEX,\n\tinternationalFormat: \"MXN\",\n\tsymbolNative: \"Mx\",\n\tlocale: \"es-MX\",\n\tpaymentMethod: \"SPEI\",\n\tpaymentAddressName: \"CLABE_ID\",\n\ttimezone: \"America/Mexico_City\",\n\ttimezone_name: \"CST\",\n\tflag: \"🇲🇽\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1f2-1f1fd.png\",\n\tphoneCode: \"+52\",\n\ttelegramSupportChannel: \"https://t.me/p2pdotmex\",\n\ttwitterUsername: \"p2pmemexico\",\n\tsmsCountryCodes: [\"MX\"],\n\tprecision: 2,\n\tisAlpha: true,\n\tdisabled: false,\n\tdisabledPaymentTypes: [\"PAY\"],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const NGN_PLACEHOLDER = \"0123456789\";\nexport const NGN_PLACEHOLDER_BANK = \"Bank Name\";\nexport const NGN_PLACEHOLDER_ACCOUNT_NAME = \"Account Name\";\nexport const NGN_VALIDATION_ERROR = \"Please enter a valid 10-digit account number\";\nexport const NGN_BANK_NAME_VALIDATION_ERROR = \"Please enter a valid bank name\";\nexport const NGN_ACCOUNT_NAME_VALIDATION_ERROR = \"Please enter a valid account name\";\n\n/**\n * Validates Nigerian bank account number (NUBAN format, 10 digits).\n */\nexport function validateNigerianAccountNumber(accountNumber: string): boolean {\n\tif (!accountNumber || accountNumber.trim().length === 0) return false;\n\tconst cleaned = accountNumber.trim().replace(/\\D/g, \"\");\n\treturn /^\\d{10}$/.test(cleaned);\n}\n\n/**\n * Validates a Nigerian bank account holder name (non-empty, letters/spaces/.'- only).\n */\nexport function validateNigerianAccountName(accountName: string): boolean {\n\tif (!accountName || accountName.trim().length === 0) return false;\n\treturn /^[A-Za-z][A-Za-z .'-]{1,}$/.test(accountName.trim());\n}\n\n/** Payment ID field configuration for NGN (Nigeria, NIP). */\nexport const NGN_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"account\",\n\t\tlabel: \"ACCOUNT_NUMBER\",\n\t\tplaceholder: NGN_PLACEHOLDER,\n\t\tdisplayLabel: \"Account Number\",\n\t\tvalidate: validateNigerianAccountNumber,\n\t\tvalidationErrorMessage: NGN_VALIDATION_ERROR,\n\t},\n\t{\n\t\tkey: \"bank-name\",\n\t\tlabel: \"BANK_NAME\",\n\t\tplaceholder: NGN_PLACEHOLDER_BANK,\n\t\tdisplayLabel: \"Bank Name\",\n\t\tvalidate: (v: string) => v.trim().length > 0,\n\t\tvalidationErrorMessage: NGN_BANK_NAME_VALIDATION_ERROR,\n\t},\n\t{\n\t\tkey: \"account-name\",\n\t\tlabel: \"ACCOUNT_NAME\",\n\t\tplaceholder: NGN_PLACEHOLDER_ACCOUNT_NAME,\n\t\tdisplayLabel: \"Account Name\",\n\t\tvalidate: validateNigerianAccountName,\n\t\tvalidationErrorMessage: NGN_ACCOUNT_NAME_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for Nigeria (NGN). */\nexport const NGN_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Nigeria\",\n\tcurrency: CURRENCY.NGN,\n\tsymbolNative: \"₦\",\n\tlocale: \"en-NG\",\n\tpaymentMethod: \"NIP\",\n\tpaymentAddressName: \"ACCOUNT_NUMBER\",\n\ttimezone: \"Africa/Lagos\",\n\ttimezone_name: \"WAT\",\n\tflag: \"🇳🇬\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1f3-1f1ec.png\",\n\tphoneCode: \"+234\",\n\ttelegramSupportChannel: \"https://t.me/p2pmengn\",\n\ttwitterUsername: \"p2pmeNigeria\",\n\tsmsCountryCodes: [\"NG\"],\n\tprecision: 2,\n\tisAlpha: true,\n\tdisabled: false,\n\tdisabledPaymentTypes: [],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\nimport { EUR_PLACEHOLDER, EUR_VALIDATION_ERROR, validateRevolutId } from \"./eur\";\n\nexport const USD_PLACEHOLDER = EUR_PLACEHOLDER;\nexport const USD_VALIDATION_ERROR = EUR_VALIDATION_ERROR;\n\n/** Payment ID field configuration for USD (Revolut USD). */\nexport const USD_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"revolut\",\n\t\tlabel: \"REVOLUT_ID\",\n\t\tplaceholder: USD_PLACEHOLDER,\n\t\tdisplayLabel: \"Revolut ID\",\n\t\tvalidate: validateRevolutId,\n\t\tvalidationErrorMessage: USD_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for Revolut USD. */\nexport const USD_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Revolut USD\",\n\tcurrency: CURRENCY.USD,\n\tsymbolNative: \"$\",\n\tlocale: \"en-US\",\n\tpaymentMethod: \"REVOLUT\",\n\tpaymentAddressName: \"REVOLUT_ID\",\n\ttimezone: \"America/New_York\",\n\ttimezone_name: \"EST\",\n\tflag: \"\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f310.png\",\n\tphoneCode: \"+1\",\n\ttelegramSupportChannel: \"https://t.me/P2Pdotme\",\n\ttwitterUsername: \"P2Pdotme\",\n\tsmsCountryCodes: [\"US\"],\n\tprecision: 2,\n\tisAlpha: true,\n\tdisabled: true,\n\tdisabledPaymentTypes: [\"PAY\"],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const VEN_PLACEHOLDER = \"04121234567\";\nexport const VEN_PLACEHOLDER_RIF = \"V12345678\";\nexport const VEN_PLACEHOLDER_BANK = \"Banesco\";\n\nexport const VEN_VALIDATION_ERROR = \"Please enter a valid phone number (e.g., 04121234567)\";\nexport const VEN_VALIDATION_ERROR_RIF = \"Please enter a valid Cédula (e.g., V12345678)\";\nexport const VEN_VALIDATION_ERROR_BANK = \"Please enter a bank name\";\n\n/**\n * Validates Venezuelan phone number for Pago Movil.\n * Format: 04XX-XXXXXXX (11 digits starting with 04).\n */\nexport function validateVenezuelanPhoneNumber(phoneNumber: string): boolean {\n\tif (!phoneNumber || phoneNumber.trim().length === 0) return false;\n\n\tconst cleaned = phoneNumber.trim().replace(/\\D/g, \"\");\n\n\tif (/^04\\d{9}$/.test(cleaned)) return true;\n\tif (/^4\\d{9}$/.test(cleaned)) return true;\n\n\treturn false;\n}\n\n/**\n * Validates Venezuelan Cédula. Format: \"V\" followed by digits.\n * Only natural-person cédulas (V) are accepted; legal-entity RIFs are not.\n */\nexport function validateVenezuelanRif(rif: string): boolean {\n\tif (!rif || rif.trim().length === 0) return false;\n\tconst trimmed = rif.trim().toUpperCase();\n\treturn /^V\\d+$/.test(trimmed);\n}\n\n/** Payment ID field configuration for VEN (Venezuela, Pago Móvil). */\nexport const VEN_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"phone\",\n\t\tlabel: \"PHONE_NUMBER\",\n\t\tplaceholder: VEN_PLACEHOLDER,\n\t\tdisplayLabel: \"Phone\",\n\t\tvalidate: validateVenezuelanPhoneNumber,\n\t\tvalidationErrorMessage: VEN_VALIDATION_ERROR,\n\t},\n\t{\n\t\tkey: \"rif\",\n\t\tlabel: \"RIF_LABEL\",\n\t\tplaceholder: VEN_PLACEHOLDER_RIF,\n\t\tdisplayLabel: \"Cedula con V\",\n\t\tvalidate: validateVenezuelanRif,\n\t\tvalidationErrorMessage: VEN_VALIDATION_ERROR_RIF,\n\t},\n\t{\n\t\tkey: \"bank\",\n\t\tlabel: \"BANK_LABEL\",\n\t\tplaceholder: VEN_PLACEHOLDER_BANK,\n\t\tdisplayLabel: \"Banco\",\n\t\tvalidate: (v: string) => v.trim().length > 0,\n\t\tvalidationErrorMessage: VEN_VALIDATION_ERROR_BANK,\n\t},\n];\n\n/** Country option for Venezuela (VEN). */\nexport const VEN_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Venezuela\",\n\tcurrency: CURRENCY.VEN,\n\tinternationalFormat: \"VES\",\n\tsymbolNative: \"Bs\",\n\tlocale: \"es-VE\",\n\tpaymentMethod: \"PAGO_MOVIL\",\n\tpaymentAddressName: \"PAGO_MOVIL_DETAILS\",\n\ttimezone: \"America/Caracas\",\n\ttimezone_name: \"VET\",\n\tflag: \"🇻🇪\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1fb-1f1ea.png\",\n\tphoneCode: \"+58\",\n\ttelegramSupportChannel: \"https://t.me/p2pmevenezuela\",\n\ttwitterUsername: \"p2pmevenezuela\",\n\tsmsCountryCodes: [\"VE\"],\n\tprecision: 2,\n\tisAlpha: true,\n\tdisabled: false,\n\tdisabledPaymentTypes: [],\n};\n","import {\n\tARS_COUNTRY_OPTION,\n\tBRL_COUNTRY_OPTION,\n\tCOP_COUNTRY_OPTION,\n\tECU_COUNTRY_OPTION,\n\tEUR_COUNTRY_OPTION,\n\tIDR_COUNTRY_OPTION,\n\tINR_COUNTRY_OPTION,\n\tMEX_COUNTRY_OPTION,\n\tNGN_COUNTRY_OPTION,\n\tUSD_COUNTRY_OPTION,\n\tVEN_COUNTRY_OPTION,\n} from \"./currencies\";\nimport type { CountryOption } from \"./types\";\n\n/** All supported countries with their currency metadata, payment methods, and display config. */\nexport const COUNTRY_OPTIONS: readonly CountryOption[] = [\n\tINR_COUNTRY_OPTION,\n\tIDR_COUNTRY_OPTION,\n\tBRL_COUNTRY_OPTION,\n\tARS_COUNTRY_OPTION,\n\tMEX_COUNTRY_OPTION,\n\tVEN_COUNTRY_OPTION,\n\tNGN_COUNTRY_OPTION,\n\tCOP_COUNTRY_OPTION,\n\tECU_COUNTRY_OPTION,\n\tEUR_COUNTRY_OPTION,\n\tUSD_COUNTRY_OPTION,\n];\n","import type { CurrencyCode } from \"../types\";\nimport {\n\tARS_PAYMENT_FIELDS,\n\tBRL_PAYMENT_FIELDS,\n\tCOP_PAYMENT_FIELDS,\n\tECU_PAYMENT_FIELDS,\n\tEUR_PAYMENT_FIELDS,\n\tIDR_PAYMENT_FIELDS,\n\tINR_PAYMENT_FIELDS,\n\tMEX_PAYMENT_FIELDS,\n\tNGN_PAYMENT_FIELDS,\n\tUSD_PAYMENT_FIELDS,\n\tVEN_PAYMENT_FIELDS,\n} from \"./currencies\";\nimport type { PaymentIdFieldConfig } from \"./types\";\n\n/** Payment ID field configuration for each supported currency. */\nexport const PAYMENT_ID_FIELDS: Record<CurrencyCode, PaymentIdFieldConfig[]> = {\n\tINR: INR_PAYMENT_FIELDS,\n\tIDR: IDR_PAYMENT_FIELDS,\n\tBRL: BRL_PAYMENT_FIELDS,\n\tARS: ARS_PAYMENT_FIELDS,\n\tMEX: MEX_PAYMENT_FIELDS,\n\tVEN: VEN_PAYMENT_FIELDS,\n\tNGN: NGN_PAYMENT_FIELDS,\n\tEUR: EUR_PAYMENT_FIELDS,\n\tUSD: USD_PAYMENT_FIELDS,\n\tCOP: COP_PAYMENT_FIELDS,\n\tECU: ECU_PAYMENT_FIELDS,\n};\n","export {\n\tvalidateArgentinePaymentId,\n\tvalidateColombianPaymentId,\n\tvalidateEcuadorianAccountName,\n\tvalidateEcuadorianAccountNumber,\n\tvalidateEcuadorianCedula,\n\tvalidateIndonesianPhoneNumber,\n\tvalidateMexicanPaymentId,\n\tvalidateNigerianAccountName,\n\tvalidateNigerianAccountNumber,\n\tvalidatePIXId,\n\tvalidateRevolutId,\n\tvalidateUPIId,\n\tvalidateVenezuelanPhoneNumber,\n\tvalidateVenezuelanRif,\n} from \"./currencies\";\n\n/** Serializes multiple fields into a pipe-separated string. */\nexport function serializeCompoundPaymentId(...fields: string[]): string {\n\treturn fields.join(\"|\");\n}\n\n/** Deserializes a pipe-separated payment ID into its component fields. */\nexport function deserializeCompoundPaymentId(paymentId: string): string[] {\n\treturn paymentId.split(\"|\");\n}\n\n/**\n * Formats a compound payment ID for display using optional labels.\n * Fields without a label are shown as-is, fields with a label are shown as \"Label: value\".\n */\nexport function formatCompoundPaymentIdForDisplay(\n\tpaymentId: string,\n\tlabels: (string | null)[],\n): string {\n\tconst parts = deserializeCompoundPaymentId(paymentId);\n\treturn parts.map((part, i) => (labels[i] ? `${labels[i]}: ${part}` : part)).join(\" | \");\n}\n"],"mappings":";AAOO,IAAM,WAAW;AAAA,EACvB,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACN;AASO,IAAM,iBAAiB,OAAO,OAAO,QAAQ;;;ACzB7C,IAAM,kBAAkB;AACxB,IAAM,uBACZ;AAGD,SAAS,YAAY,KAAsB;AAC1C,MAAI,IAAI,WAAW,GAAI,QAAO;AAC9B,MAAI,eAAe,KAAK,GAAG,EAAG,QAAO;AAErC,QAAM,WAAW,IAAI,UAAU,GAAG,CAAC;AACnC,QAAM,iBAAiB,SAAS,IAAI,CAAC,GAAG,EAAE;AAC1C,MAAI,MAAM;AACV,QAAM,UAAU,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AACpC,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC3B,WAAO,SAAS,SAAS,CAAC,GAAG,EAAE,IAAI,QAAQ,CAAC;AAAA,EAC7C;AACA,QAAM,uBAAuB,KAAM,MAAM,MAAO;AAChD,MAAI,mBAAmB,oBAAqB,QAAO;AAEnD,QAAM,gBAAgB,IAAI,UAAU,GAAG,EAAE;AACzC,QAAM,oBAAoB,SAAS,IAAI,EAAE,GAAG,EAAE;AAC9C,QAAM;AACN,QAAM,iBAAiB,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAC7D,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC5B,WAAO,SAAS,cAAc,CAAC,GAAG,EAAE,IAAI,eAAe,CAAC;AAAA,EACzD;AACA,QAAM,0BAA0B,KAAM,MAAM,MAAO;AACnD,MAAI,sBAAsB,uBAAwB,QAAO;AAEzD,SAAO;AACR;AAMO,SAAS,2BAA2B,WAA4B;AACtE,MAAI,CAAC,aAAa,UAAU,KAAK,EAAE,WAAW,EAAG,QAAO;AAExD,QAAM,mBAAmB,UAAU,KAAK;AAExC,MAAI,WAAW,KAAK,gBAAgB,EAAG,QAAO,YAAY,gBAAgB;AAC1E,MAAI,0BAA0B,KAAK,gBAAgB,EAAG,QAAO;AAE7D,SAAO;AACR;AAGO,IAAM,qBAA6C;AAAA,EACzD;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,wBAAwB;AAAA,EACzB;AACD;AAGO,IAAM,qBAAoC;AAAA,EAChD,SAAS;AAAA,EACT,UAAU,SAAS;AAAA,EACnB,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,UAAU;AAAA,EACV,eAAe;AAAA,EACf,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,EACX,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,iBAAiB,CAAC,IAAI;AAAA,EACtB,WAAW;AAAA,EACX,SAAS;AAAA,EACT,UAAU;AAAA,EACV,sBAAsB,CAAC;AACxB;;;AC/EO,IAAM,kBAAkB;AACxB,IAAM,uBAAuB;AAGpC,SAAS,YAAY,KAAsB;AAC1C,MAAI,IAAI,WAAW,GAAI,QAAO;AAC9B,MAAI,eAAe,KAAK,GAAG,EAAG,QAAO;AAErC,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC3B,WAAO,SAAS,IAAI,CAAC,GAAG,EAAE,KAAK,KAAK;AAAA,EACrC;AACA,MAAI,YAAY,MAAM;AACtB,QAAM,aAAa,YAAY,IAAI,IAAI,KAAK;AAC5C,MAAI,SAAS,IAAI,CAAC,GAAG,EAAE,MAAM,WAAY,QAAO;AAEhD,QAAM;AACN,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC5B,WAAO,SAAS,IAAI,CAAC,GAAG,EAAE,KAAK,KAAK;AAAA,EACrC;AACA,cAAY,MAAM;AAClB,QAAM,cAAc,YAAY,IAAI,IAAI,KAAK;AAC7C,SAAO,SAAS,IAAI,EAAE,GAAG,EAAE,MAAM;AAClC;AAGA,SAAS,aAAa,MAAuB;AAC5C,MAAI,KAAK,WAAW,GAAI,QAAO;AAC/B,MAAI,eAAe,KAAK,IAAI,EAAG,QAAO;AAEtC,MAAI,MAAM;AACV,QAAM,WAAW,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AACpD,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC5B,WAAO,SAAS,KAAK,CAAC,GAAG,EAAE,IAAI,SAAS,CAAC;AAAA,EAC1C;AACA,MAAI,YAAY,MAAM;AACtB,QAAM,aAAa,YAAY,IAAI,IAAI,KAAK;AAC5C,MAAI,SAAS,KAAK,EAAE,GAAG,EAAE,MAAM,WAAY,QAAO;AAElD,QAAM;AACN,QAAM,WAAW,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AACvD,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC5B,WAAO,SAAS,KAAK,CAAC,GAAG,EAAE,IAAI,SAAS,CAAC;AAAA,EAC1C;AACA,cAAY,MAAM;AAClB,QAAM,cAAc,YAAY,IAAI,IAAI,KAAK;AAC7C,SAAO,SAAS,KAAK,EAAE,GAAG,EAAE,MAAM;AACnC;AAOO,SAAS,cAAc,OAAwB;AACrD,MAAI,CAAC,SAAS,MAAM,KAAK,EAAE,WAAW,EAAG,QAAO;AAEhD,QAAM,eAAe,MAAM,KAAK;AAGhC,MAAI,UAAU,KAAK,YAAY,EAAG,QAAO;AAGzC,MAAI,WAAW,KAAK,YAAY;AAC/B,WAAO,YAAY,YAAY,KAAK,qBAAqB,KAAK,YAAY;AAC3E,MAAI,WAAW,KAAK,YAAY,EAAG,QAAO,aAAa,YAAY;AACnE,MAAI,6BAA6B,KAAK,YAAY,EAAG,QAAO;AAE5D,MAAI,cAAc,KAAK,YAAY,EAAG,QAAO;AAC7C,MAAI,kEAAkE,KAAK,YAAY;AACtF,WAAO;AAER,SAAO;AACR;AAGO,IAAM,qBAA6C;AAAA,EACzD;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,wBAAwB;AAAA,EACzB;AACD;AAGO,IAAM,qBAAoC;AAAA,EAChD,SAAS;AAAA,EACT,UAAU,SAAS;AAAA,EACnB,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,UAAU;AAAA,EACV,eAAe;AAAA,EACf,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,EACX,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,iBAAiB,CAAC,IAAI;AAAA,EACtB,WAAW;AAAA,EACX,SAAS;AAAA,EACT,UAAU;AAAA,EACV,sBAAsB,CAAC;AACxB;;;AC3GO,IAAM,kBAAkB;AACxB,IAAM,uBACZ;AAOM,SAAS,2BAA2B,WAA4B;AACtE,MAAI,CAAC,aAAa,UAAU,KAAK,EAAE,WAAW,EAAG,QAAO;AACxD,QAAM,UAAU,UAAU,KAAK;AAC/B,MAAI,WAAW,KAAK,OAAO,EAAG,QAAO;AACrC,MAAI,6BAA6B,KAAK,OAAO,EAAG,QAAO;AACvD,MAAI,SAAS,KAAK,OAAO,EAAG,QAAO;AACnC,SAAO;AACR;AAGO,IAAM,qBAA6C;AAAA,EACzD;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,wBAAwB;AAAA,EACzB;AACD;AAGO,IAAM,qBAAoC;AAAA,EAChD,SAAS;AAAA,EACT,UAAU,SAAS;AAAA,EACnB,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,UAAU;AAAA,EACV,eAAe;AAAA,EACf,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,EACX,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,iBAAiB,CAAC,IAAI;AAAA,EACtB,WAAW;AAAA,EACX,SAAS;AAAA,EACT,UAAU;AAAA,EACV,sBAAsB,CAAC;AACxB;;;AChDO,IAAM,uBAAuB;AAC7B,IAAM,+BAA+B;AACrC,IAAM,iCAAiC;AACvC,IAAM,uBAAuB;AAC7B,IAAM,yBAAyB;AAE/B,IAAM,4BAA4B;AAClC,IAAM,oCAAoC;AAC1C,IAAM,sCACZ;AACM,IAAM,4BAA4B;AAClC,IAAM,8BAA8B;AAI3C,SAAS,kBAAkB,QAAyB;AACnD,MAAI,CAAC,WAAW,KAAK,MAAM,EAAG,QAAO;AACrC,QAAM,WAAW,OAAO,OAAO,MAAM,GAAG,CAAC,CAAC;AAC1C,MAAI,WAAW,KAAK,WAAW,GAAI,QAAO;AAC1C,MAAI,OAAO,OAAO,CAAC,CAAC,KAAK,EAAG,QAAO;AAEnC,QAAM,eAAe,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAC/C,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC3B,QAAI,UAAU,OAAO,OAAO,CAAC,CAAC,IAAI,aAAa,CAAC;AAChD,QAAI,UAAU,EAAG,YAAW;AAC5B,WAAO;AAAA,EACR;AACA,QAAM,aAAa,MAAM,OAAO,IAAI,IAAI,KAAM,MAAM;AACpD,SAAO,eAAe,OAAO,OAAO,CAAC,CAAC;AACvC;AAOO,SAAS,yBAAyB,OAAwB;AAChE,MAAI,CAAC,SAAS,MAAM,KAAK,EAAE,WAAW,EAAG,QAAO;AAChD,QAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,OAAO,EAAE;AAC9C,MAAI,QAAQ,WAAW,GAAI,QAAO,kBAAkB,QAAQ,MAAM,GAAG,EAAE,CAAC;AACxE,MAAI,QAAQ,WAAW,GAAI,QAAO;AAClC,SAAO,kBAAkB,OAAO;AACjC;AAGO,SAAS,gCAAgC,OAAwB;AACvE,MAAI,CAAC,SAAS,MAAM,KAAK,EAAE,WAAW,EAAG,QAAO;AAChD,QAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,OAAO,EAAE;AAC9C,SAAO,aAAa,KAAK,OAAO;AACjC;AAGO,SAAS,8BAA8B,OAAwB;AACrE,MAAI,CAAC,SAAS,MAAM,KAAK,EAAE,WAAW,EAAG,QAAO;AAChD,SAAO,mCAAmC,KAAK,MAAM,KAAK,CAAC;AAC5D;AAKO,IAAM,qBAA6C;AAAA,EACzD;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU,CAAC,MAAc,EAAE,KAAK,EAAE,SAAS;AAAA,IAC3C,wBAAwB;AAAA,EACzB;AAAA,EACA;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU,CAAC,MAAc,EAAE,KAAK,EAAE,SAAS;AAAA,IAC3C,wBAAwB;AAAA,EACzB;AAAA,EACA;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,wBAAwB;AAAA,EACzB;AAAA,EACA;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,wBAAwB;AAAA,EACzB;AAAA,EACA;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,wBAAwB;AAAA,EACzB;AACD;AAKO,IAAM,qBAAoC;AAAA,EAChD,SAAS;AAAA,EACT,UAAU,SAAS;AAAA,EACnB,qBAAqB;AAAA,EACrB,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,UAAU;AAAA,EACV,eAAe;AAAA,EACf,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,EACX,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,iBAAiB,CAAC,IAAI;AAAA,EACtB,WAAW;AAAA,EACX,SAAS;AAAA,EACT,UAAU;AAAA,EACV,sBAAsB,CAAC;AACxB;;;ACjIO,IAAM,kBAAkB;AACxB,IAAM,uBAAuB;AAK7B,SAAS,kBAAkB,WAA4B;AAC7D,MAAI,CAAC,aAAa,UAAU,KAAK,EAAE,WAAW,EAAG,QAAO;AAExD,QAAM,UAAU,UAAU,KAAK;AAE/B,MAAI,2BAA2B,KAAK,OAAO,EAAG,QAAO;AACrD,MAAI,6BAA6B,KAAK,OAAO,EAAG,QAAO;AACvD,MAAI,gBAAgB,KAAK,OAAO,EAAG,QAAO;AAE1C,SAAO;AACR;AAGO,IAAM,qBAA6C;AAAA,EACzD;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,wBAAwB;AAAA,EACzB;AACD;AAGO,IAAM,qBAAoC;AAAA,EAChD,SAAS;AAAA,EACT,UAAU,SAAS;AAAA,EACnB,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,UAAU;AAAA,EACV,eAAe;AAAA,EACf,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,EACX,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,iBAAiB,CAAC;AAAA,EAClB,WAAW;AAAA,EACX,SAAS;AAAA,EACT,UAAU;AAAA,EACV,sBAAsB,CAAC,KAAK;AAC7B;;;AClDO,IAAM,kBAAkB;AACxB,IAAM,uBACZ;AAMM,SAAS,8BAA8B,aAA8B;AAC3E,MAAI,CAAC,eAAe,YAAY,KAAK,EAAE,WAAW,EAAG,QAAO;AAC5D,MAAI,WAAW,KAAK,WAAW,EAAG,QAAO;AACzC,QAAM,UAAU,YAAY,QAAQ,OAAO,EAAE;AAC7C,SAAO,aAAa,KAAK,OAAO;AACjC;AAGO,IAAM,qBAA6C;AAAA,EACzD;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,wBAAwB;AAAA,EACzB;AACD;AAGO,IAAM,qBAAoC;AAAA,EAChD,SAAS;AAAA,EACT,UAAU,SAAS;AAAA,EACnB,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,UAAU;AAAA,EACV,eAAe;AAAA,EACf,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,EACX,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,iBAAiB,CAAC;AAAA,EAClB,WAAW;AAAA,EACX,SAAS;AAAA,EACT,UAAU;AAAA,EACV,sBAAsB,CAAC;AACxB;;;AC/CO,IAAM,kBAAkB;AACxB,IAAM,uBAAuB;AAM7B,SAAS,cAAc,OAAwB;AACrD,MAAI,CAAC,SAAS,MAAM,KAAK,EAAE,WAAW,EAAG,QAAO;AAChD,QAAM,WAAW;AACjB,SAAO,SAAS,KAAK,MAAM,KAAK,CAAC;AAClC;AAGO,IAAM,qBAA6C;AAAA,EACzD;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,wBAAwB;AAAA,EACzB;AACD;AAGO,IAAM,qBAAoC;AAAA,EAChD,SAAS;AAAA,EACT,UAAU,SAAS;AAAA,EACnB,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,UAAU;AAAA,EACV,eAAe;AAAA,EACf,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,EACX,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,iBAAiB,CAAC,IAAI;AAAA,EACtB,WAAW;AAAA,EACX,SAAS;AAAA,EACT,UAAU;AAAA,EACV,sBAAsB,CAAC;AACxB;;;AC7CO,IAAM,kBAAkB;AACxB,IAAM,uBACZ;AAMM,SAAS,yBAAyB,WAA4B;AACpE,MAAI,CAAC,aAAa,UAAU,KAAK,EAAE,WAAW,EAAG,QAAO;AAExD,QAAM,UAAU,UAAU,KAAK,EAAE,QAAQ,OAAO,EAAE;AAElD,MAAI,WAAW,KAAK,OAAO,EAAG,QAAO;AACrC,MAAI,WAAW,KAAK,OAAO,EAAG,QAAO;AACrC,MAAI,WAAW,KAAK,OAAO,EAAG,QAAO;AAErC,SAAO;AACR;AAGO,IAAM,qBAA6C;AAAA,EACzD;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,wBAAwB;AAAA,EACzB;AACD;AAGO,IAAM,qBAAoC;AAAA,EAChD,SAAS;AAAA,EACT,UAAU,SAAS;AAAA,EACnB,qBAAqB;AAAA,EACrB,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,UAAU;AAAA,EACV,eAAe;AAAA,EACf,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,EACX,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,iBAAiB,CAAC,IAAI;AAAA,EACtB,WAAW;AAAA,EACX,SAAS;AAAA,EACT,UAAU;AAAA,EACV,sBAAsB,CAAC,KAAK;AAC7B;;;ACrDO,IAAM,kBAAkB;AACxB,IAAM,uBAAuB;AAC7B,IAAM,+BAA+B;AACrC,IAAM,uBAAuB;AAC7B,IAAM,iCAAiC;AACvC,IAAM,oCAAoC;AAK1C,SAAS,8BAA8B,eAAgC;AAC7E,MAAI,CAAC,iBAAiB,cAAc,KAAK,EAAE,WAAW,EAAG,QAAO;AAChE,QAAM,UAAU,cAAc,KAAK,EAAE,QAAQ,OAAO,EAAE;AACtD,SAAO,WAAW,KAAK,OAAO;AAC/B;AAKO,SAAS,4BAA4B,aAA8B;AACzE,MAAI,CAAC,eAAe,YAAY,KAAK,EAAE,WAAW,EAAG,QAAO;AAC5D,SAAO,6BAA6B,KAAK,YAAY,KAAK,CAAC;AAC5D;AAGO,IAAM,qBAA6C;AAAA,EACzD;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,wBAAwB;AAAA,EACzB;AAAA,EACA;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU,CAAC,MAAc,EAAE,KAAK,EAAE,SAAS;AAAA,IAC3C,wBAAwB;AAAA,EACzB;AAAA,EACA;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,wBAAwB;AAAA,EACzB;AACD;AAGO,IAAM,qBAAoC;AAAA,EAChD,SAAS;AAAA,EACT,UAAU,SAAS;AAAA,EACnB,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,UAAU;AAAA,EACV,eAAe;AAAA,EACf,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,EACX,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,iBAAiB,CAAC,IAAI;AAAA,EACtB,WAAW;AAAA,EACX,SAAS;AAAA,EACT,UAAU;AAAA,EACV,sBAAsB,CAAC;AACxB;;;ACvEO,IAAM,kBAAkB;AACxB,IAAM,uBAAuB;AAG7B,IAAM,qBAA6C;AAAA,EACzD;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,wBAAwB;AAAA,EACzB;AACD;AAGO,IAAM,qBAAoC;AAAA,EAChD,SAAS;AAAA,EACT,UAAU,SAAS;AAAA,EACnB,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,UAAU;AAAA,EACV,eAAe;AAAA,EACf,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,EACX,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,iBAAiB,CAAC,IAAI;AAAA,EACtB,WAAW;AAAA,EACX,SAAS;AAAA,EACT,UAAU;AAAA,EACV,sBAAsB,CAAC,KAAK;AAC7B;;;ACpCO,IAAM,kBAAkB;AACxB,IAAM,sBAAsB;AAC5B,IAAM,uBAAuB;AAE7B,IAAM,uBAAuB;AAC7B,IAAM,2BAA2B;AACjC,IAAM,4BAA4B;AAMlC,SAAS,8BAA8B,aAA8B;AAC3E,MAAI,CAAC,eAAe,YAAY,KAAK,EAAE,WAAW,EAAG,QAAO;AAE5D,QAAM,UAAU,YAAY,KAAK,EAAE,QAAQ,OAAO,EAAE;AAEpD,MAAI,YAAY,KAAK,OAAO,EAAG,QAAO;AACtC,MAAI,WAAW,KAAK,OAAO,EAAG,QAAO;AAErC,SAAO;AACR;AAMO,SAAS,sBAAsB,KAAsB;AAC3D,MAAI,CAAC,OAAO,IAAI,KAAK,EAAE,WAAW,EAAG,QAAO;AAC5C,QAAM,UAAU,IAAI,KAAK,EAAE,YAAY;AACvC,SAAO,SAAS,KAAK,OAAO;AAC7B;AAGO,IAAM,qBAA6C;AAAA,EACzD;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,wBAAwB;AAAA,EACzB;AAAA,EACA;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,wBAAwB;AAAA,EACzB;AAAA,EACA;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU,CAAC,MAAc,EAAE,KAAK,EAAE,SAAS;AAAA,IAC3C,wBAAwB;AAAA,EACzB;AACD;AAGO,IAAM,qBAAoC;AAAA,EAChD,SAAS;AAAA,EACT,UAAU,SAAS;AAAA,EACnB,qBAAqB;AAAA,EACrB,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,UAAU;AAAA,EACV,eAAe;AAAA,EACf,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,EACX,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,iBAAiB,CAAC,IAAI;AAAA,EACtB,WAAW;AAAA,EACX,SAAS;AAAA,EACT,UAAU;AAAA,EACV,sBAAsB,CAAC;AACxB;;;ACrEO,IAAM,kBAA4C;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;;;ACXO,IAAM,oBAAkE;AAAA,EAC9E,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACN;;;ACXO,SAAS,8BAA8B,QAA0B;AACvE,SAAO,OAAO,KAAK,GAAG;AACvB;AAGO,SAAS,6BAA6B,WAA6B;AACzE,SAAO,UAAU,MAAM,GAAG;AAC3B;AAMO,SAAS,kCACf,WACA,QACS;AACT,QAAM,QAAQ,6BAA6B,SAAS;AACpD,SAAO,MAAM,IAAI,CAAC,MAAM,MAAO,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,KAAK,IAAI,KAAK,IAAK,EAAE,KAAK,KAAK;AACvF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/country/currency.ts","../src/country/currencies/ars.ts","../src/country/currencies/brl.ts","../src/country/currencies/cop.ts","../src/country/currencies/ecu.ts","../src/country/currencies/eur.ts","../src/country/currencies/idr.ts","../src/country/currencies/inr.ts","../src/country/currencies/mex.ts","../src/country/currencies/ngn.ts","../src/country/currencies/pen.ts","../src/country/currencies/usd.ts","../src/country/currencies/ven.ts","../src/country/countries.ts","../src/country/payment-fields.ts","../src/country/validators.ts"],"sourcesContent":["/**\n * All supported currency symbols. Single source of truth for the SDK.\n *\n * Lives alongside the country metadata so that adding a currency is a\n * single-folder operation: drop a new file in `currencies/<code>.ts`, add it\n * to this map, and both `COUNTRY_OPTIONS` and `ZodCurrencySchema` pick it up.\n */\nexport const CURRENCY = {\n\tIDR: \"IDR\",\n\tINR: \"INR\",\n\tBRL: \"BRL\",\n\tARS: \"ARS\",\n\tMEX: \"MEX\",\n\tVEN: \"VEN\",\n\tEUR: \"EUR\",\n\tNGN: \"NGN\",\n\tUSD: \"USD\",\n\tCOP: \"COP\",\n\tECU: \"ECU\",\n\tPEN: \"PEN\",\n} as const;\n\n/** Union of supported currency codes. */\nexport type CurrencyCode = (typeof CURRENCY)[keyof typeof CURRENCY];\n\n/**\n * Tuple form of the currency codes — used by `z.enum(...)` in the shared\n * validation layer. Narrow tuple type required by Zod.\n */\nexport const CURRENCY_CODES = Object.values(CURRENCY) as [CurrencyCode, ...CurrencyCode[]];\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const ARS_PLACEHOLDER = \"juan.perez\";\nexport const ARS_VALIDATION_ERROR =\n\t\"Please enter a valid CBU/CVU (22 digits) or Alias (6-20 characters)\";\n\n/** Validates CBU (Clave Bancaria Uniforme) — Argentine banking key, 22 digits with checksums. */\nfunction validateCBU(cbu: string): boolean {\n\tif (cbu.length !== 22) return false;\n\tif (/^(\\d)\\1{21}$/.test(cbu)) return false;\n\n\tconst bankCode = cbu.substring(0, 7);\n\tconst bankCheckDigit = parseInt(cbu[7], 10);\n\tlet sum = 0;\n\tconst weights = [7, 1, 3, 9, 7, 1, 3];\n\tfor (let i = 0; i < 7; i++) {\n\t\tsum += parseInt(bankCode[i], 10) * weights[i];\n\t}\n\tconst calculatedBankCheck = (10 - (sum % 10)) % 10;\n\tif (bankCheckDigit !== calculatedBankCheck) return false;\n\n\tconst accountNumber = cbu.substring(8, 21);\n\tconst accountCheckDigit = parseInt(cbu[21], 10);\n\tsum = 0;\n\tconst accountWeights = [3, 9, 7, 1, 3, 9, 7, 1, 3, 9, 7, 1, 3];\n\tfor (let i = 0; i < 13; i++) {\n\t\tsum += parseInt(accountNumber[i], 10) * accountWeights[i];\n\t}\n\tconst calculatedAccountCheck = (10 - (sum % 10)) % 10;\n\tif (accountCheckDigit !== calculatedAccountCheck) return false;\n\n\treturn true;\n}\n\n/**\n * Validates Argentine payment IDs (CBU, CVU, or Alias).\n * CBU/CVU: 22 digits with checksum. Alias: 6-20 alphanumeric characters.\n */\nexport function validateArgentinePaymentId(paymentId: string): boolean {\n\tif (!paymentId || paymentId.trim().length === 0) return false;\n\n\tconst trimmedPaymentId = paymentId.trim();\n\n\tif (/^\\d{22}$/.test(trimmedPaymentId)) return validateCBU(trimmedPaymentId);\n\tif (/^[a-zA-Z0-9.\\-_]{6,20}$/.test(trimmedPaymentId)) return true;\n\n\treturn false;\n}\n\n/** Payment ID field configuration for ARS (Argentina, ALIAS). */\nexport const ARS_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"alias\",\n\t\tlabel: \"ALIAS_ID\",\n\t\tplaceholder: ARS_PLACEHOLDER,\n\t\tdisplayLabel: \"Alias\",\n\t\tvalidate: validateArgentinePaymentId,\n\t\tvalidationErrorMessage: ARS_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for Argentina (ARS). */\nexport const ARS_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Argentina\",\n\tcurrency: CURRENCY.ARS,\n\tsymbolNative: \"$\",\n\tlocale: \"es-AR\",\n\tpaymentMethod: \"ALIAS\",\n\tpaymentAddressName: \"ALIAS_ID\",\n\ttimezone: \"America/Argentina/Buenos_Aires\",\n\ttimezone_name: \"ART\",\n\tflag: \"🇦🇷\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1e6-1f1f7.png\",\n\tphoneCode: \"+54\",\n\ttelegramSupportChannel: \"https://t.me/p2pmeargentina\",\n\ttwitterUsername: \"p2pmeargentina\",\n\tsmsCountryCodes: [\"AR\"],\n\tprecision: 2,\n\tisAlpha: false,\n\tdisabled: false,\n\tdisabledPaymentTypes: [],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const BRL_PLACEHOLDER = \"Chave pix ou pix copia e cola\";\nexport const BRL_VALIDATION_ERROR = \"Please enter a valid PIX ID\";\n\n/** Validates CPF (Brazilian tax ID for individuals). */\nfunction validateCPF(cpf: string): boolean {\n\tif (cpf.length !== 11) return false;\n\tif (/^(\\d)\\1{10}$/.test(cpf)) return false;\n\n\tlet sum = 0;\n\tfor (let i = 0; i < 9; i++) {\n\t\tsum += parseInt(cpf[i], 10) * (10 - i);\n\t}\n\tlet remainder = sum % 11;\n\tconst firstDigit = remainder < 2 ? 0 : 11 - remainder;\n\tif (parseInt(cpf[9], 10) !== firstDigit) return false;\n\n\tsum = 0;\n\tfor (let i = 0; i < 10; i++) {\n\t\tsum += parseInt(cpf[i], 10) * (11 - i);\n\t}\n\tremainder = sum % 11;\n\tconst secondDigit = remainder < 2 ? 0 : 11 - remainder;\n\treturn parseInt(cpf[10], 10) === secondDigit;\n}\n\n/** Validates CNPJ (Brazilian tax ID for companies). */\nfunction validateCNPJ(cnpj: string): boolean {\n\tif (cnpj.length !== 14) return false;\n\tif (/^(\\d)\\1{13}$/.test(cnpj)) return false;\n\n\tlet sum = 0;\n\tconst weights1 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];\n\tfor (let i = 0; i < 12; i++) {\n\t\tsum += parseInt(cnpj[i], 10) * weights1[i];\n\t}\n\tlet remainder = sum % 11;\n\tconst firstDigit = remainder < 2 ? 0 : 11 - remainder;\n\tif (parseInt(cnpj[12], 10) !== firstDigit) return false;\n\n\tsum = 0;\n\tconst weights2 = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];\n\tfor (let i = 0; i < 13; i++) {\n\t\tsum += parseInt(cnpj[i], 10) * weights2[i];\n\t}\n\tremainder = sum % 11;\n\tconst secondDigit = remainder < 2 ? 0 : 11 - remainder;\n\treturn parseInt(cnpj[13], 10) === secondDigit;\n}\n\n/**\n * Validates PIX ID format.\n * PIX can be: CPF (11 digits), CNPJ (14 digits), email, phone (10–11 digits or E.164),\n * random key (UUID), or a PIX \"copia e cola\" EMV QR payload (starts with 000201).\n */\nexport function validatePIXId(pixId: string): boolean {\n\tif (!pixId || pixId.trim().length === 0) return false;\n\n\tconst trimmedPixId = pixId.trim();\n\n\t// PIX \"copia e cola\" — EMV QR code payload\n\tif (/^000201/.test(trimmedPixId)) return true;\n\n\t// 11 digits: valid CPF or Brazilian mobile phone key (DDD 11–99 + digit 9 + 8 digits)\n\tif (/^\\d{11}$/.test(trimmedPixId))\n\t\treturn validateCPF(trimmedPixId) || /^[1-9][1-9]9\\d{8}$/.test(trimmedPixId);\n\tif (/^\\d{14}$/.test(trimmedPixId)) return validateCNPJ(trimmedPixId);\n\tif (/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(trimmedPixId)) return true;\n\t// Phone key: 10–11 digits (with or without country code prefix)\n\tif (/^\\d{10,11}$/.test(trimmedPixId)) return true;\n\tif (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(trimmedPixId))\n\t\treturn true;\n\n\treturn false;\n}\n\n/** Payment ID field configuration for BRL (Brazil, PIX). */\nexport const BRL_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"pix\",\n\t\tlabel: \"PIX_ID\",\n\t\tplaceholder: BRL_PLACEHOLDER,\n\t\tdisplayLabel: \"PIX ID\",\n\t\tvalidate: validatePIXId,\n\t\tvalidationErrorMessage: BRL_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for Brazil (BRL). */\nexport const BRL_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Brazil\",\n\tcurrency: CURRENCY.BRL,\n\tsymbolNative: \"R$\",\n\tlocale: \"pt-BR\",\n\tpaymentMethod: \"PIX\",\n\tpaymentAddressName: \"PIX_ID\",\n\ttimezone: \"America/Sao_Paulo\",\n\ttimezone_name: \"BRT\",\n\tflag: \"🇧🇷\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1e7-1f1f7.png\",\n\tphoneCode: \"+55\",\n\ttelegramSupportChannel: \"https://t.me/p2pmebrasil\",\n\ttwitterUsername: \"p2pmebrasil\",\n\tsmsCountryCodes: [\"BR\"],\n\tprecision: 2,\n\tisAlpha: false,\n\tdisabled: false,\n\tdisabledPaymentTypes: [],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const COP_PLACEHOLDER = \"3001234567 / juan.perez@nequi.com.co / @alias\";\nexport const COP_VALIDATION_ERROR =\n\t\"Please enter a valid Colombian payment ID (e.g., 3001234567, email, or @alias)\";\n\n/**\n * Validates Colombian payment ID for Nequi, Daviplata, or Bre-B.\n * Accepts a 10-digit phone number starting with 3, a valid email address,\n * or a Bre-B alias starting with @ (e.g. @juanperez).\n */\nexport function validateColombianPaymentId(paymentId: string): boolean {\n\tif (!paymentId || paymentId.trim().length === 0) return false;\n\tconst trimmed = paymentId.trim();\n\tif (/^3\\d{9}$/.test(trimmed)) return true;\n\tif (/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(trimmed)) return true;\n\tif (/^@\\S+$/.test(trimmed)) return true;\n\treturn false;\n}\n\n/** Payment ID field configuration for COP (Colombia, Transferencia). */\nexport const COP_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"alias\",\n\t\tlabel: \"ALIAS_TRANSFERENCIA\",\n\t\tplaceholder: COP_PLACEHOLDER,\n\t\tdisplayLabel: \"Nequi / Daviplata / Bre-B\",\n\t\tvalidate: validateColombianPaymentId,\n\t\tvalidationErrorMessage: COP_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for Colombia (COP). */\nexport const COP_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Colombia\",\n\tcurrency: CURRENCY.COP,\n\tsymbolNative: \"$\",\n\tlocale: \"es-CO\",\n\tpaymentMethod: \"TRANSFERENCIA\",\n\tpaymentAddressName: \"ALIAS_TRANSFERENCIA\",\n\ttimezone: \"America/Bogota\",\n\ttimezone_name: \"COT\",\n\tflag: \"🇨🇴\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1e8-1f1f4.png\",\n\tphoneCode: \"+57\",\n\ttelegramSupportChannel: \"https://t.me/p2pmecolombiaclientes\",\n\ttwitterUsername: \"p2pmeColombia\",\n\tsmsCountryCodes: [\"CO\"],\n\tprecision: 2,\n\tisAlpha: true,\n\tdisabled: false,\n\tdisabledPaymentTypes: [],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\n// ── Placeholders & error messages ────────────────────────────────────────────\n\nexport const ECU_PLACEHOLDER_BANK = \"Banco Pichincha\";\nexport const ECU_PLACEHOLDER_ACCOUNT_TYPE = \"Savings / Checking\";\nexport const ECU_PLACEHOLDER_ACCOUNT_NUMBER = \"2100123456\";\nexport const ECU_PLACEHOLDER_NAME = \"Juan Pérez\";\nexport const ECU_PLACEHOLDER_CEDULA = \"1710034065\";\n\nexport const ECU_BANK_VALIDATION_ERROR = \"Please enter the bank name\";\nexport const ECU_ACCOUNT_TYPE_VALIDATION_ERROR = \"Please enter the account type\";\nexport const ECU_ACCOUNT_NUMBER_VALIDATION_ERROR =\n\t\"Please enter a valid account number (4-20 digits)\";\nexport const ECU_NAME_VALIDATION_ERROR = \"Please enter the account holder name\";\nexport const ECU_CEDULA_VALIDATION_ERROR = \"Please enter a valid Ecuadorian cédula or RUC\";\n\n// ── Validators ───────────────────────────────────────────────────────────────\n\nfunction isValidCedulaCore(cedula: string): boolean {\n\tif (!/^\\d{10}$/.test(cedula)) return false;\n\tconst province = Number(cedula.slice(0, 2));\n\tif (province < 1 || province > 24) return false;\n\tif (Number(cedula[2]) >= 6) return false;\n\n\tconst coefficients = [2, 1, 2, 1, 2, 1, 2, 1, 2];\n\tlet sum = 0;\n\tfor (let i = 0; i < 9; i++) {\n\t\tlet product = Number(cedula[i]) * coefficients[i];\n\t\tif (product > 9) product -= 9;\n\t\tsum += product;\n\t}\n\tconst checkDigit = sum % 10 === 0 ? 0 : 10 - (sum % 10);\n\treturn checkDigit === Number(cedula[9]);\n}\n\n/**\n * Validates an Ecuadorian cédula (10-digit, módulo-10 checksum) or a 13-digit RUC\n * whose first 10 digits form a valid cédula. Province must be 01–24 and the third\n * digit < 6 (natural person).\n */\nexport function validateEcuadorianCedula(value: string): boolean {\n\tif (!value || value.trim().length === 0) return false;\n\tconst cleaned = value.trim().replace(/\\D/g, \"\");\n\tif (cleaned.length === 13) return isValidCedulaCore(cleaned.slice(0, 10));\n\tif (cleaned.length !== 10) return false;\n\treturn isValidCedulaCore(cleaned);\n}\n\n/** Validates an Ecuadorian bank account number — 4–20 digits after stripping separators. */\nexport function validateEcuadorianAccountNumber(value: string): boolean {\n\tif (!value || value.trim().length === 0) return false;\n\tconst cleaned = value.trim().replace(/\\D/g, \"\");\n\treturn /^\\d{4,20}$/.test(cleaned);\n}\n\n/** Validates an account holder name — non-empty, letters/spaces/apostrophe/period/hyphen only. */\nexport function validateEcuadorianAccountName(value: string): boolean {\n\tif (!value || value.trim().length === 0) return false;\n\treturn /^[A-Za-zÀ-ÿ][A-Za-zÀ-ÿ .'-]{1,}$/.test(value.trim());\n}\n\n// ── Payment fields ───────────────────────────────────────────────────────────\n\n/** Payment ID field configuration for ECU (Ecuador, bank transfer — all free text). */\nexport const ECU_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"bank-name\",\n\t\tlabel: \"BANK_NAME\",\n\t\tplaceholder: ECU_PLACEHOLDER_BANK,\n\t\tdisplayLabel: \"Bank\",\n\t\tvalidate: (v: string) => v.trim().length > 0,\n\t\tvalidationErrorMessage: ECU_BANK_VALIDATION_ERROR,\n\t},\n\t{\n\t\tkey: \"account-type\",\n\t\tlabel: \"ACCOUNT_TYPE\",\n\t\tplaceholder: ECU_PLACEHOLDER_ACCOUNT_TYPE,\n\t\tdisplayLabel: \"Account Type\",\n\t\tvalidate: (v: string) => v.trim().length > 0,\n\t\tvalidationErrorMessage: ECU_ACCOUNT_TYPE_VALIDATION_ERROR,\n\t},\n\t{\n\t\tkey: \"account-number\",\n\t\tlabel: \"ACCOUNT_NUMBER\",\n\t\tplaceholder: ECU_PLACEHOLDER_ACCOUNT_NUMBER,\n\t\tdisplayLabel: \"Account Number\",\n\t\tvalidate: validateEcuadorianAccountNumber,\n\t\tvalidationErrorMessage: ECU_ACCOUNT_NUMBER_VALIDATION_ERROR,\n\t},\n\t{\n\t\tkey: \"account-name\",\n\t\tlabel: \"NAME\",\n\t\tplaceholder: ECU_PLACEHOLDER_NAME,\n\t\tdisplayLabel: \"Name\",\n\t\tvalidate: validateEcuadorianAccountName,\n\t\tvalidationErrorMessage: ECU_NAME_VALIDATION_ERROR,\n\t},\n\t{\n\t\tkey: \"cedula\",\n\t\tlabel: \"CEDULA\",\n\t\tplaceholder: ECU_PLACEHOLDER_CEDULA,\n\t\tdisplayLabel: \"Cédula\",\n\t\tvalidate: validateEcuadorianCedula,\n\t\tvalidationErrorMessage: ECU_CEDULA_VALIDATION_ERROR,\n\t},\n];\n\n// ── Country option ───────────────────────────────────────────────────────────\n\n/** Country option for Ecuador (ECU — USD-denominated, bank transfer + DeUna QR). */\nexport const ECU_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Ecuador\",\n\tcurrency: CURRENCY.ECU,\n\tinternationalFormat: \"USD\",\n\tsymbolNative: \"$\",\n\tlocale: \"es-EC\",\n\tpaymentMethod: \"TRANSFERENCIA\",\n\tpaymentAddressName: \"ECU_BANK_DETAILS\",\n\ttimezone: \"America/Guayaquil\",\n\ttimezone_name: \"ECT\",\n\tflag: \"🇪🇨\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1ea-1f1e8.png\",\n\tphoneCode: \"+593\",\n\ttelegramSupportChannel: \"https://t.me/Ecuador_P2P\",\n\ttwitterUsername: \"P2Pdotme_Ecu\",\n\tsmsCountryCodes: [],\n\tprecision: 2,\n\tisAlpha: true,\n\tdisabled: false,\n\tdisabledPaymentTypes: [],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const EUR_PLACEHOLDER = \"@username or email\";\nexport const EUR_VALIDATION_ERROR = \"Please enter a valid Revolut ID (username, email, or phone)\";\n\n/**\n * Validates Revolut ID (username, email, or phone number).\n */\nexport function validateRevolutId(revolutId: string): boolean {\n\tif (!revolutId || revolutId.trim().length === 0) return false;\n\n\tconst trimmed = revolutId.trim();\n\n\tif (/^@?[a-zA-Z0-9._-]{3,30}$/.test(trimmed)) return true;\n\tif (/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(trimmed)) return true;\n\tif (/^\\+?\\d{7,15}$/.test(trimmed)) return true;\n\n\treturn false;\n}\n\n/** Payment ID field configuration for EUR (Revolut EUR). */\nexport const EUR_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"revolut\",\n\t\tlabel: \"REVOLUT_ID\",\n\t\tplaceholder: EUR_PLACEHOLDER,\n\t\tdisplayLabel: \"Revolut ID\",\n\t\tvalidate: validateRevolutId,\n\t\tvalidationErrorMessage: EUR_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for Revolut EUR. */\nexport const EUR_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Revolut EUR\",\n\tcurrency: CURRENCY.EUR,\n\tsymbolNative: \"€\",\n\tlocale: \"de-DE\",\n\tpaymentMethod: \"REVOLUT\",\n\tpaymentAddressName: \"REVOLUT_ID\",\n\ttimezone: \"Europe/Berlin\",\n\ttimezone_name: \"CET\",\n\tflag: \"\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f310.png\",\n\tphoneCode: \"\",\n\ttelegramSupportChannel: \"https://t.me/P2Pdotme\",\n\ttwitterUsername: \"P2Pdotme\",\n\tsmsCountryCodes: [],\n\tprecision: 2,\n\tisAlpha: true,\n\tdisabled: true,\n\tdisabledPaymentTypes: [\"PAY\"],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const IDR_PLACEHOLDER = \"8123456789\";\nexport const IDR_VALIDATION_ERROR =\n\t\"Please enter a valid Indonesian phone number (e.g., 8123456789)\";\n\n/**\n * Validates Indonesian phone number.\n * Validates just the number part (9-12 digits).\n */\nexport function validateIndonesianPhoneNumber(phoneNumber: string): boolean {\n\tif (!phoneNumber || phoneNumber.trim().length === 0) return false;\n\tif (/[a-zA-Z]/.test(phoneNumber)) return false;\n\tconst cleaned = phoneNumber.replace(/\\D/g, \"\");\n\treturn /^\\d{9,12}$/.test(cleaned);\n}\n\n/** Payment ID field configuration for IDR (Indonesia, QRIS). */\nexport const IDR_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"phone\",\n\t\tlabel: \"PHONE_NUMBER\",\n\t\tplaceholder: IDR_PLACEHOLDER,\n\t\tdisplayLabel: \"Phone Number\",\n\t\tvalidate: validateIndonesianPhoneNumber,\n\t\tvalidationErrorMessage: IDR_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for Indonesia (IDR). */\nexport const IDR_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Indonesia\",\n\tcurrency: CURRENCY.IDR,\n\tsymbolNative: \"Rp\",\n\tlocale: \"id-ID\",\n\tpaymentMethod: \"QRIS\",\n\tpaymentAddressName: \"PHONE_NUMBER\",\n\ttimezone: \"Asia/Jakarta\",\n\ttimezone_name: \"WIB\",\n\tflag: \"🇮🇩\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1ee-1f1e9.png\",\n\tphoneCode: \"+62\",\n\ttelegramSupportChannel: \"https://t.me/p2pmeindonesia\",\n\ttwitterUsername: \"p2pdotmeID\",\n\tsmsCountryCodes: [],\n\tprecision: 0,\n\tisAlpha: false,\n\tdisabled: false,\n\tdisabledPaymentTypes: [],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const INR_PLACEHOLDER = \"merchant@upi\";\nexport const INR_VALIDATION_ERROR = \"Please enter a valid UPI ID (e.g., username@bankname)\";\n\n/**\n * Validates UPI ID format.\n * UPI ID format: username@bankname (e.g., john@paytm, user@ybl, 8658404239@kotak811)\n */\nexport function validateUPIId(upiId: string): boolean {\n\tif (!upiId || upiId.trim().length === 0) return false;\n\tconst upiRegex = /^[a-zA-Z0-9.\\-_]{2,256}@[a-zA-Z0-9]{2,64}$/;\n\treturn upiRegex.test(upiId.trim());\n}\n\n/** Payment ID field configuration for INR (India, UPI). */\nexport const INR_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"upi\",\n\t\tlabel: \"UPI_ID\",\n\t\tplaceholder: INR_PLACEHOLDER,\n\t\tdisplayLabel: \"UPI ID\",\n\t\tvalidate: validateUPIId,\n\t\tvalidationErrorMessage: INR_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for India (INR). */\nexport const INR_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"India\",\n\tcurrency: CURRENCY.INR,\n\tsymbolNative: \"₹\",\n\tlocale: \"en-IN\",\n\tpaymentMethod: \"UPI\",\n\tpaymentAddressName: \"UPI_ID\",\n\ttimezone: \"Asia/Kolkata\",\n\ttimezone_name: \"IST\",\n\tflag: \"🇮🇳\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1ee-1f1f3.png\",\n\tphoneCode: \"+91\",\n\ttelegramSupportChannel: \"https://t.me/P2Pdotme\",\n\ttwitterUsername: \"P2Pdotme\",\n\tsmsCountryCodes: [\"IN\"],\n\tprecision: 2,\n\tisAlpha: false,\n\tdisabled: false,\n\tdisabledPaymentTypes: [],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const MEX_PLACEHOLDER = \"012345678901234567\";\nexport const MEX_VALIDATION_ERROR =\n\t\"Please enter a valid CLABE (18 digits), card number, or phone number\";\n\n/**\n * Validates Mexican payment IDs (CLABE, card number, or phone number).\n * CLABE: 18 digits. Card: 16 digits. Phone: 10 digits.\n */\nexport function validateMexicanPaymentId(paymentId: string): boolean {\n\tif (!paymentId || paymentId.trim().length === 0) return false;\n\n\tconst trimmed = paymentId.trim().replace(/\\D/g, \"\");\n\n\tif (/^\\d{18}$/.test(trimmed)) return true;\n\tif (/^\\d{16}$/.test(trimmed)) return true;\n\tif (/^\\d{10}$/.test(trimmed)) return true;\n\n\treturn false;\n}\n\n/** Payment ID field configuration for MEX (Mexico, SPEI). */\nexport const MEX_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"clabe\",\n\t\tlabel: \"CLABE_ID\",\n\t\tplaceholder: MEX_PLACEHOLDER,\n\t\tdisplayLabel: \"CLABE\",\n\t\tvalidate: validateMexicanPaymentId,\n\t\tvalidationErrorMessage: MEX_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for Mexico (MEX). */\nexport const MEX_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Mexico\",\n\tcurrency: CURRENCY.MEX,\n\tinternationalFormat: \"MXN\",\n\tsymbolNative: \"Mx\",\n\tlocale: \"es-MX\",\n\tpaymentMethod: \"SPEI\",\n\tpaymentAddressName: \"CLABE_ID\",\n\ttimezone: \"America/Mexico_City\",\n\ttimezone_name: \"CST\",\n\tflag: \"🇲🇽\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1f2-1f1fd.png\",\n\tphoneCode: \"+52\",\n\ttelegramSupportChannel: \"https://t.me/p2pdotmex\",\n\ttwitterUsername: \"p2pmemexico\",\n\tsmsCountryCodes: [\"MX\"],\n\tprecision: 2,\n\tisAlpha: true,\n\tdisabled: false,\n\tdisabledPaymentTypes: [\"PAY\"],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const NGN_PLACEHOLDER = \"0123456789\";\nexport const NGN_PLACEHOLDER_BANK = \"Bank Name\";\nexport const NGN_PLACEHOLDER_ACCOUNT_NAME = \"Account Name\";\nexport const NGN_VALIDATION_ERROR = \"Please enter a valid 10-digit account number\";\nexport const NGN_BANK_NAME_VALIDATION_ERROR = \"Please enter a valid bank name\";\nexport const NGN_ACCOUNT_NAME_VALIDATION_ERROR = \"Please enter a valid account name\";\n\n/**\n * Validates Nigerian bank account number (NUBAN format, 10 digits).\n */\nexport function validateNigerianAccountNumber(accountNumber: string): boolean {\n\tif (!accountNumber || accountNumber.trim().length === 0) return false;\n\tconst cleaned = accountNumber.trim().replace(/\\D/g, \"\");\n\treturn /^\\d{10}$/.test(cleaned);\n}\n\n/**\n * Validates a Nigerian bank account holder name (non-empty, letters/spaces/.'- only).\n */\nexport function validateNigerianAccountName(accountName: string): boolean {\n\tif (!accountName || accountName.trim().length === 0) return false;\n\treturn /^[A-Za-z][A-Za-z .'-]{1,}$/.test(accountName.trim());\n}\n\n/** Payment ID field configuration for NGN (Nigeria, NIP). */\nexport const NGN_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"account\",\n\t\tlabel: \"ACCOUNT_NUMBER\",\n\t\tplaceholder: NGN_PLACEHOLDER,\n\t\tdisplayLabel: \"Account Number\",\n\t\tvalidate: validateNigerianAccountNumber,\n\t\tvalidationErrorMessage: NGN_VALIDATION_ERROR,\n\t},\n\t{\n\t\tkey: \"bank-name\",\n\t\tlabel: \"BANK_NAME\",\n\t\tplaceholder: NGN_PLACEHOLDER_BANK,\n\t\tdisplayLabel: \"Bank Name\",\n\t\tvalidate: (v: string) => v.trim().length > 0,\n\t\tvalidationErrorMessage: NGN_BANK_NAME_VALIDATION_ERROR,\n\t},\n\t{\n\t\tkey: \"account-name\",\n\t\tlabel: \"ACCOUNT_NAME\",\n\t\tplaceholder: NGN_PLACEHOLDER_ACCOUNT_NAME,\n\t\tdisplayLabel: \"Account Name\",\n\t\tvalidate: validateNigerianAccountName,\n\t\tvalidationErrorMessage: NGN_ACCOUNT_NAME_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for Nigeria (NGN). */\nexport const NGN_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Nigeria\",\n\tcurrency: CURRENCY.NGN,\n\tsymbolNative: \"₦\",\n\tlocale: \"en-NG\",\n\tpaymentMethod: \"NIP\",\n\tpaymentAddressName: \"ACCOUNT_NUMBER\",\n\ttimezone: \"Africa/Lagos\",\n\ttimezone_name: \"WAT\",\n\tflag: \"🇳🇬\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1f3-1f1ec.png\",\n\tphoneCode: \"+234\",\n\ttelegramSupportChannel: \"https://t.me/p2pmengn\",\n\ttwitterUsername: \"p2pmeNigeria\",\n\tsmsCountryCodes: [],\n\tprecision: 2,\n\tisAlpha: true,\n\tdisabled: false,\n\tdisabledPaymentTypes: [],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const PEN_PLACEHOLDER = \"CCI (20 digits) or Yape/Plin phone (9XXXXXXXX)\";\nexport const PEN_VALIDATION_ERROR = \"Please enter a valid 20-digit CCI or Yape/Plin phone number\";\n\n/**\n * Validates a Peruvian payment key for the SELL text-key path.\n * Accepts either a 20-digit CCI (Código de Cuenta Interbancario, spaces ignored)\n * or a Yape/Plin phone number (optional `+51`/`51` prefix, then `9` + 8 digits).\n */\nexport function validatePeruvianPaymentKey(value: string): boolean {\n\tif (!value || value.trim().length === 0) return false;\n\tconst trimmed = value.trim();\n\n\tconst cci = trimmed.replace(/\\s+/g, \"\");\n\tif (/^\\d{20}$/.test(cci)) return true;\n\n\tconst phone = trimmed.replace(/\\s+/g, \"\").replace(/^\\+?51/, \"\");\n\tif (/^9\\d{8}$/.test(phone)) return true;\n\n\treturn false;\n}\n\n/**\n * Computes CRC-16/CCITT-FALSE (poly 0x1021, init 0xFFFF, no reflection, xorout 0)\n * over the input string and returns the 4-char uppercase hex checksum.\n */\nfunction crc16ccitt(s: string): string {\n\tlet crc = 0xffff;\n\tfor (let i = 0; i < s.length; i++) {\n\t\tcrc ^= s.charCodeAt(i) << 8;\n\t\tfor (let j = 0; j < 8; j++) {\n\t\t\tcrc = crc & 0x8000 ? (crc << 1) ^ 0x1021 : crc << 1;\n\t\t\tcrc &= 0xffff;\n\t\t}\n\t}\n\treturn crc.toString(16).toUpperCase().padStart(4, \"0\");\n}\n\n/**\n * Validates a Yape/Plin EMVCo QR payload: parseable TLV, country (tag 58) `PE`,\n * currency (tag 53) `604` (PEN), and a matching CRC-16/CCITT-FALSE (tag 63).\n */\nexport function validatePeruvianQr(payload: string): boolean {\n\tif (!payload || payload.trim().length === 0) return false;\n\tconst data = payload.trim();\n\n\tconst tags: Record<string, string> = {};\n\tlet pos = 0;\n\twhile (pos + 4 <= data.length) {\n\t\tconst tag = data.substring(pos, pos + 2);\n\t\tconst lengthStr = data.substring(pos + 2, pos + 4);\n\t\tif (!/^[0-9]{2}$/.test(tag) || !/^[0-9]{2}$/.test(lengthStr)) break;\n\t\tconst length = Number.parseInt(lengthStr, 10);\n\t\tif (pos + 4 + length > data.length) break;\n\t\ttags[tag] = data.substring(pos + 4, pos + 4 + length);\n\t\tpos += 4 + length;\n\t}\n\n\tif (tags[\"58\"] !== \"PE\") return false;\n\tif (tags[\"53\"] !== \"604\") return false;\n\n\tconst crcTag = tags[\"63\"];\n\tif (!crcTag) return false;\n\n\tconst marker = data.lastIndexOf(\"6304\");\n\tif (marker === -1) return false;\n\n\tconst expected = crc16ccitt(data.substring(0, marker + 4));\n\treturn expected.toUpperCase() === crcTag.toUpperCase();\n}\n\n/** Payment ID field configuration for PEN (Peru, Yape / Plin / CCI). */\nexport const PEN_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"paymentId\",\n\t\tlabel: \"CCI_YAPE_PLIN\",\n\t\tplaceholder: PEN_PLACEHOLDER,\n\t\tdisplayLabel: \"CCI / Yape / Plin\",\n\t\tvalidate: validatePeruvianPaymentKey,\n\t\tvalidationErrorMessage: PEN_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for Peru (PEN). */\nexport const PEN_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Peru\",\n\tcurrency: CURRENCY.PEN,\n\tsymbolNative: \"S/\",\n\tlocale: \"es-PE\",\n\tpaymentMethod: \"YAPE_PLIN_CCI\",\n\tpaymentAddressName: \"YAPE_PLIN_CCI_DETAILS\",\n\ttimezone: \"America/Lima\",\n\ttimezone_name: \"PET\",\n\tflag: \"🇵🇪\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1f5-1f1ea.png\",\n\tphoneCode: \"+51\",\n\ttelegramSupportChannel: \"https://t.me/p2pmeperu\",\n\ttwitterUsername: \"p2pmePeru\",\n\tsmsCountryCodes: [\"PE\"],\n\tprecision: 2,\n\tisAlpha: true,\n\tdisabled: false,\n\tdisabledPaymentTypes: [],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\nimport { EUR_PLACEHOLDER, EUR_VALIDATION_ERROR, validateRevolutId } from \"./eur\";\n\nexport const USD_PLACEHOLDER = EUR_PLACEHOLDER;\nexport const USD_VALIDATION_ERROR = EUR_VALIDATION_ERROR;\n\n/** Payment ID field configuration for USD (Revolut USD). */\nexport const USD_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"revolut\",\n\t\tlabel: \"REVOLUT_ID\",\n\t\tplaceholder: USD_PLACEHOLDER,\n\t\tdisplayLabel: \"Revolut ID\",\n\t\tvalidate: validateRevolutId,\n\t\tvalidationErrorMessage: USD_VALIDATION_ERROR,\n\t},\n];\n\n/** Country option for Revolut USD. */\nexport const USD_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Revolut USD\",\n\tcurrency: CURRENCY.USD,\n\tsymbolNative: \"$\",\n\tlocale: \"en-US\",\n\tpaymentMethod: \"REVOLUT\",\n\tpaymentAddressName: \"REVOLUT_ID\",\n\ttimezone: \"America/New_York\",\n\ttimezone_name: \"EST\",\n\tflag: \"\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f310.png\",\n\tphoneCode: \"+1\",\n\ttelegramSupportChannel: \"https://t.me/P2Pdotme\",\n\ttwitterUsername: \"P2Pdotme\",\n\tsmsCountryCodes: [\"US\"],\n\tprecision: 2,\n\tisAlpha: true,\n\tdisabled: true,\n\tdisabledPaymentTypes: [\"PAY\"],\n};\n","import { CURRENCY } from \"../currency\";\nimport type { CountryOption, PaymentIdFieldConfig } from \"../types\";\n\nexport const VEN_PLACEHOLDER = \"04121234567\";\nexport const VEN_PLACEHOLDER_RIF = \"V12345678\";\nexport const VEN_PLACEHOLDER_BANK = \"Banesco\";\n\nexport const VEN_VALIDATION_ERROR = \"Please enter a valid phone number (e.g., 04121234567)\";\nexport const VEN_VALIDATION_ERROR_RIF = \"Please enter a valid Cédula (e.g., V12345678)\";\nexport const VEN_VALIDATION_ERROR_BANK = \"Please enter a bank name\";\n\n/**\n * Validates Venezuelan phone number for Pago Movil.\n * Format: 04XX-XXXXXXX (11 digits starting with 04).\n */\nexport function validateVenezuelanPhoneNumber(phoneNumber: string): boolean {\n\tif (!phoneNumber || phoneNumber.trim().length === 0) return false;\n\n\tconst cleaned = phoneNumber.trim().replace(/\\D/g, \"\");\n\n\tif (/^04\\d{9}$/.test(cleaned)) return true;\n\tif (/^4\\d{9}$/.test(cleaned)) return true;\n\n\treturn false;\n}\n\n/**\n * Validates Venezuelan Cédula. Format: \"V\" followed by digits.\n * Only natural-person cédulas (V) are accepted; legal-entity RIFs are not.\n */\nexport function validateVenezuelanRif(rif: string): boolean {\n\tif (!rif || rif.trim().length === 0) return false;\n\tconst trimmed = rif.trim().toUpperCase();\n\treturn /^V\\d+$/.test(trimmed);\n}\n\n/** Payment ID field configuration for VEN (Venezuela, Pago Móvil). */\nexport const VEN_PAYMENT_FIELDS: PaymentIdFieldConfig[] = [\n\t{\n\t\tkey: \"phone\",\n\t\tlabel: \"PHONE_NUMBER\",\n\t\tplaceholder: VEN_PLACEHOLDER,\n\t\tdisplayLabel: \"Phone\",\n\t\tvalidate: validateVenezuelanPhoneNumber,\n\t\tvalidationErrorMessage: VEN_VALIDATION_ERROR,\n\t},\n\t{\n\t\tkey: \"rif\",\n\t\tlabel: \"RIF_LABEL\",\n\t\tplaceholder: VEN_PLACEHOLDER_RIF,\n\t\tdisplayLabel: \"Cedula con V\",\n\t\tvalidate: validateVenezuelanRif,\n\t\tvalidationErrorMessage: VEN_VALIDATION_ERROR_RIF,\n\t},\n\t{\n\t\tkey: \"bank\",\n\t\tlabel: \"BANK_LABEL\",\n\t\tplaceholder: VEN_PLACEHOLDER_BANK,\n\t\tdisplayLabel: \"Banco\",\n\t\tvalidate: (v: string) => v.trim().length > 0,\n\t\tvalidationErrorMessage: VEN_VALIDATION_ERROR_BANK,\n\t},\n];\n\n/** Country option for Venezuela (VEN). */\nexport const VEN_COUNTRY_OPTION: CountryOption = {\n\tcountry: \"Venezuela\",\n\tcurrency: CURRENCY.VEN,\n\tinternationalFormat: \"VES\",\n\tsymbolNative: \"Bs\",\n\tlocale: \"es-VE\",\n\tpaymentMethod: \"PAGO_MOVIL\",\n\tpaymentAddressName: \"PAGO_MOVIL_DETAILS\",\n\ttimezone: \"America/Caracas\",\n\ttimezone_name: \"VET\",\n\tflag: \"🇻🇪\",\n\tflagUrl: \"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f1fb-1f1ea.png\",\n\tphoneCode: \"+58\",\n\ttelegramSupportChannel: \"https://t.me/p2pmevenezuela\",\n\ttwitterUsername: \"p2pmevenezuela\",\n\tsmsCountryCodes: [\"VE\"],\n\tprecision: 2,\n\tisAlpha: true,\n\tdisabled: false,\n\tdisabledPaymentTypes: [],\n};\n","import {\n\tARS_COUNTRY_OPTION,\n\tBRL_COUNTRY_OPTION,\n\tCOP_COUNTRY_OPTION,\n\tECU_COUNTRY_OPTION,\n\tEUR_COUNTRY_OPTION,\n\tIDR_COUNTRY_OPTION,\n\tINR_COUNTRY_OPTION,\n\tMEX_COUNTRY_OPTION,\n\tNGN_COUNTRY_OPTION,\n\tPEN_COUNTRY_OPTION,\n\tUSD_COUNTRY_OPTION,\n\tVEN_COUNTRY_OPTION,\n} from \"./currencies\";\nimport type { CountryOption } from \"./types\";\n\n/** All supported countries with their currency metadata, payment methods, and display config. */\nexport const COUNTRY_OPTIONS: readonly CountryOption[] = [\n\tINR_COUNTRY_OPTION,\n\tIDR_COUNTRY_OPTION,\n\tBRL_COUNTRY_OPTION,\n\tARS_COUNTRY_OPTION,\n\tMEX_COUNTRY_OPTION,\n\tVEN_COUNTRY_OPTION,\n\tNGN_COUNTRY_OPTION,\n\tCOP_COUNTRY_OPTION,\n\tECU_COUNTRY_OPTION,\n\tPEN_COUNTRY_OPTION,\n\tEUR_COUNTRY_OPTION,\n\tUSD_COUNTRY_OPTION,\n];\n","import type { CurrencyCode } from \"../types\";\nimport {\n\tARS_PAYMENT_FIELDS,\n\tBRL_PAYMENT_FIELDS,\n\tCOP_PAYMENT_FIELDS,\n\tECU_PAYMENT_FIELDS,\n\tEUR_PAYMENT_FIELDS,\n\tIDR_PAYMENT_FIELDS,\n\tINR_PAYMENT_FIELDS,\n\tMEX_PAYMENT_FIELDS,\n\tNGN_PAYMENT_FIELDS,\n\tPEN_PAYMENT_FIELDS,\n\tUSD_PAYMENT_FIELDS,\n\tVEN_PAYMENT_FIELDS,\n} from \"./currencies\";\nimport type { PaymentIdFieldConfig } from \"./types\";\n\n/** Payment ID field configuration for each supported currency. */\nexport const PAYMENT_ID_FIELDS: Record<CurrencyCode, PaymentIdFieldConfig[]> = {\n\tINR: INR_PAYMENT_FIELDS,\n\tIDR: IDR_PAYMENT_FIELDS,\n\tBRL: BRL_PAYMENT_FIELDS,\n\tARS: ARS_PAYMENT_FIELDS,\n\tMEX: MEX_PAYMENT_FIELDS,\n\tVEN: VEN_PAYMENT_FIELDS,\n\tNGN: NGN_PAYMENT_FIELDS,\n\tEUR: EUR_PAYMENT_FIELDS,\n\tUSD: USD_PAYMENT_FIELDS,\n\tCOP: COP_PAYMENT_FIELDS,\n\tECU: ECU_PAYMENT_FIELDS,\n\tPEN: PEN_PAYMENT_FIELDS,\n};\n","export {\n\tvalidateArgentinePaymentId,\n\tvalidateColombianPaymentId,\n\tvalidateEcuadorianAccountName,\n\tvalidateEcuadorianAccountNumber,\n\tvalidateEcuadorianCedula,\n\tvalidateIndonesianPhoneNumber,\n\tvalidateMexicanPaymentId,\n\tvalidateNigerianAccountName,\n\tvalidateNigerianAccountNumber,\n\tvalidatePeruvianPaymentKey,\n\tvalidatePeruvianQr,\n\tvalidatePIXId,\n\tvalidateRevolutId,\n\tvalidateUPIId,\n\tvalidateVenezuelanPhoneNumber,\n\tvalidateVenezuelanRif,\n} from \"./currencies\";\n\n/** Serializes multiple fields into a pipe-separated string. */\nexport function serializeCompoundPaymentId(...fields: string[]): string {\n\treturn fields.join(\"|\");\n}\n\n/** Deserializes a pipe-separated payment ID into its component fields. */\nexport function deserializeCompoundPaymentId(paymentId: string): string[] {\n\treturn paymentId.split(\"|\");\n}\n\n/**\n * Formats a compound payment ID for display using optional labels.\n * Fields without a label are shown as-is, fields with a label are shown as \"Label: value\".\n */\nexport function formatCompoundPaymentIdForDisplay(\n\tpaymentId: string,\n\tlabels: (string | null)[],\n): string {\n\tconst parts = deserializeCompoundPaymentId(paymentId);\n\treturn parts.map((part, i) => (labels[i] ? `${labels[i]}: ${part}` : part)).join(\" | \");\n}\n"],"mappings":"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","names":[]}
|
package/dist/fraud-engine.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/fraud-engine/index.ts","../src/fraud-engine/client.ts","../src/lib/encoding.ts","../src/lib/logger.ts","../src/lib/subgraph.ts","../src/validation/errors.validation.ts","../src/validation/schemas.validation.ts","../src/country/currency.ts","../src/fraud-engine/device.ts","../src/fraud-engine/errors.ts","../src/fraud-engine/encryption.ts","../src/fraud-engine/fingerprint.ts","../src/fraud-engine/seon.ts","../src/fraud-engine/signing.ts","../src/fraud-engine/validation.ts"],"sourcesContent":["// ── Main entry point ────────────────────────────────────────────────────\n\nexport { createFraudEngine } from \"./client\";\n\n// ── Types ───────────────────────────────────────────────────────────────\n\nexport type {\n\tActivityType,\n\tBuyOrderDetails,\n\tDeviceDetails,\n\tFingerprintLogResult,\n\tFraudCheckApiResponse,\n\tFraudCheckResult,\n\tFraudEngine,\n\tFraudEngineConfig,\n\tFraudEngineSigner,\n\tLinkOrderResult,\n\tProcessBuyOrderResult,\n\tUserDetails,\n} from \"./types\";\n\n// ── Logger ──────────────────────────────────────────────────────────────\n\nexport { type Logger, noopLogger } from \"../lib\";\n\n// ── Errors ──────────────────────────────────────────────────────────────\n\nexport { FraudEngineError, type FraudEngineErrorCode } from \"./errors\";\n\n// ── Low-level exports (for advanced use) ────────────────────────────────\n\nexport { fetchIpAddress, getBasicDeviceDetails, getDeviceDetails } from \"./device\";\nexport { encryptPayload } from \"./encryption\";\nexport { getFingerprint, loadFingerprintAgent } from \"./fingerprint\";\nexport { cleanupSeonStorage, getSeonSession, initSeon } from \"./seon\";\nexport { getSignedHeaders } from \"./signing\";\n","import { errAsync, ResultAsync } from \"neverthrow\";\nimport { type Logger, noopLogger } from \"../lib\";\nimport { getDeviceDetails } from \"./device\";\nimport { encryptPayload } from \"./encryption\";\nimport { FraudEngineError } from \"./errors\";\nimport { getFingerprint as getFingerprintResult, loadFingerprintAgent } from \"./fingerprint\";\nimport { cleanupSeonStorage as cleanupSeon, getSeonSession, initSeon } from \"./seon\";\nimport { getSignedHeaders } from \"./signing\";\nimport type {\n\tBuyOrderDetails,\n\tFingerprintLogResult,\n\tFraudCheckApiResponse,\n\tFraudCheckResult,\n\tFraudEngine,\n\tFraudEngineConfig,\n\tFraudEngineSigner,\n\tLinkOrderResult,\n\tProcessBuyOrderResult,\n\tUserDetails,\n} from \"./types\";\nimport { validate, ZodFraudEngineConfigSchema } from \"./validation\";\n\nexport function createFraudEngine(config: FraudEngineConfig): FraudEngine {\n\tconst { apiUrl, encryptionKey } = config;\n\tconst seonRegion = config.seonRegion ?? \"asia\";\n\tconst logger: Logger = config.logger ?? noopLogger;\n\n\t// Validate eagerly so misconfiguration surfaces at construction time, but\n\t// never throw — the SDK's contract is that all failures flow through\n\t// `Result`/`ResultAsync`. Capture the error and short-circuit any method\n\t// that depends on the validated fields (`apiUrl`, `encryptionKey`).\n\t// Methods that don't depend on them (init, getFingerprint, getDeviceDetails,\n\t// cleanupSeonStorage) remain usable so consumers can still hydrate device\n\t// fingerprints even with a partially-configured engine.\n\tconst configResult = validate(ZodFraudEngineConfigSchema, {\n\t\tapiUrl,\n\t\tencryptionKey,\n\t\tseonRegion,\n\t});\n\tconst configError = configResult.isErr() ? configResult.error : null;\n\tif (configError) {\n\t\tlogger.error(\n\t\t\t\"Fraud engine config invalid; API methods will return VALIDATION_ERROR until fixed\",\n\t\t\t{ error: configError.message },\n\t\t);\n\t}\n\n\tfunction linkOrderInternal(\n\t\tsigner: FraudEngineSigner,\n\t\tactivityLogId: number,\n\t\torderId: string,\n\t): ResultAsync<LinkOrderResult, FraudEngineError> {\n\t\treturn ResultAsync.fromPromise(\n\t\t\t(async () => {\n\t\t\t\tlogger.info(\"Linking order to activity log\", { activityLogId, orderId });\n\n\t\t\t\tconst signedHeaders = await getSignedHeaders(signer, \"link-order\");\n\n\t\t\t\tconst response = await fetch(`${apiUrl}/activity-logs/link-order`, {\n\t\t\t\t\tmethod: \"PATCH\",\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\t...signedHeaders,\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\tactivity_log_id: activityLogId,\n\t\t\t\t\t\torder_id: orderId,\n\t\t\t\t\t\tuser_address: signer.address.toLowerCase(),\n\t\t\t\t\t}),\n\t\t\t\t});\n\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow new FraudEngineError(`Link order API returned ${response.status}`, {\n\t\t\t\t\t\tcode: \"API_ERROR\",\n\t\t\t\t\t\tcontext: { status: response.status },\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst data = (await response.json()) as LinkOrderResult;\n\t\t\t\tlogger.info(\"Order linked successfully\", { orderId });\n\t\t\t\treturn data;\n\t\t\t})(),\n\t\t\t(cause) => {\n\t\t\t\tif (cause instanceof FraudEngineError) return cause;\n\t\t\t\treturn new FraudEngineError(\"Link order failed\", {\n\t\t\t\t\tcode: \"NETWORK_ERROR\",\n\t\t\t\t\tcause,\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t}\n\n\tasync function checkBuyOrderInternal(params: {\n\t\tsigner: FraudEngineSigner;\n\t\torderDetails: BuyOrderDetails;\n\t\tuserDetails?: UserDetails;\n\t\torderSource?: string;\n\t}): Promise<FraudCheckApiResponse> {\n\t\tlogger.info(\"Checking buy order for fraud\", {\n\t\t\tcurrency: params.orderDetails.currency,\n\t\t\tfiatAmount: params.orderDetails.fiatAmount,\n\t\t});\n\n\t\tconst [seonSession, deviceDetails, signedHeaders] = await Promise.all([\n\t\t\tgetSeonSession(seonRegion),\n\t\t\tgetDeviceDetails(),\n\t\t\tgetSignedHeaders(params.signer, \"activity-log\"),\n\t\t]);\n\n\t\tconst device = { ...deviceDetails, seonSession };\n\n\t\tconst userAddress = params.signer.address.toLowerCase();\n\t\tconst timestamp = Date.now();\n\n\t\tconst payload = JSON.stringify({\n\t\t\tuser_details: {\n\t\t\t\tcurrency: params.userDetails?.currency,\n\t\t\t\tcountry: params.userDetails?.country,\n\t\t\t\tlanguage: params.userDetails?.language,\n\t\t\t\tlogin_method: params.userDetails?.loginMethod,\n\t\t\t\tlogin_email: params.userDetails?.loginEmail,\n\t\t\t\tlogin_phone: params.userDetails?.loginPhone,\n\t\t\t},\n\t\t\ttransaction_details: {\n\t\t\t\tcrypto_amount: params.orderDetails.cryptoAmount,\n\t\t\t\tfiat_amount: params.orderDetails.fiatAmount,\n\t\t\t\tcurrency: params.orderDetails.currency,\n\t\t\t\trecipient_address: params.orderDetails.recipientAddress,\n\t\t\t\tfee: params.orderDetails.fee,\n\t\t\t\tamount_after_fee: params.orderDetails.amountAfterFee,\n\t\t\t\tpayment_method: params.orderDetails.paymentMethod,\n\t\t\t\testimated_processing_time: params.orderDetails.estimatedProcessingTime,\n\t\t\t\torder_timestamp: timestamp,\n\t\t\t\torder_source: params.orderSource,\n\t\t\t},\n\t\t\tdevice_details: device,\n\t\t});\n\n\t\t// AAD format must match backend: \"type|user_address|timestamp\"\n\t\tconst aad = `buy_order|${userAddress}|${timestamp}`;\n\t\tconst encrypted = await encryptPayload(payload, aad, encryptionKey);\n\n\t\tconst response = await fetch(`${apiUrl}/activity-logs`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t...signedHeaders,\n\t\t\t},\n\t\t\tbody: JSON.stringify({\n\t\t\t\ttype: \"buy_order\",\n\t\t\t\tuser_address: userAddress,\n\t\t\t\ttimestamp,\n\t\t\t\tencrypted_payload: encrypted,\n\t\t\t}),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new FraudEngineError(`Fraud check API returned ${response.status}`, {\n\t\t\t\tcode: \"API_ERROR\",\n\t\t\t\tcontext: { status: response.status },\n\t\t\t});\n\t\t}\n\n\t\tconst data = (await response.json()) as FraudCheckApiResponse;\n\t\tlogger.info(\"Fraud check result\", {\n\t\t\tapproved: data.approved,\n\t\t\tactivityLogId: data.activity_log_id,\n\t\t});\n\t\treturn data;\n\t}\n\n\treturn {\n\t\tasync init() {\n\t\t\tlogger.info(\"Initializing fraud engine\");\n\t\t\ttry {\n\t\t\t\tinitSeon();\n\t\t\t} catch (cause) {\n\t\t\t\tlogger.error(\"SEON initialization failed\", { cause: String(cause) });\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait loadFingerprintAgent();\n\t\t\t} catch (cause) {\n\t\t\t\tlogger.error(\"FingerprintJS initialization failed\", {\n\t\t\t\t\tcause: String(cause),\n\t\t\t\t});\n\t\t\t}\n\t\t\tlogger.info(\"Fraud engine initialized\");\n\t\t},\n\n\t\tcheckBuyOrder(params: {\n\t\t\tsigner: FraudEngineSigner;\n\t\t\torderDetails: BuyOrderDetails;\n\t\t\tuserDetails?: UserDetails;\n\t\t\torderSource?: string;\n\t\t}): ResultAsync<FraudCheckResult, FraudEngineError> {\n\t\t\tif (configError) return errAsync(configError);\n\t\t\treturn ResultAsync.fromPromise(\n\t\t\t\tcheckBuyOrderInternal(params).then((data) => ({\n\t\t\t\t\tapproved: data.approved,\n\t\t\t\t\tactivityLogId: data.activity_log_id,\n\t\t\t\t\tmessage: data.message,\n\t\t\t\t\tlinkOrder: (orderId: string) =>\n\t\t\t\t\t\tlinkOrderInternal(params.signer, data.activity_log_id, orderId),\n\t\t\t\t})),\n\t\t\t\t(cause) => {\n\t\t\t\t\tif (cause instanceof FraudEngineError) return cause;\n\t\t\t\t\treturn new FraudEngineError(\"Fraud check failed\", {\n\t\t\t\t\t\tcode: \"NETWORK_ERROR\",\n\t\t\t\t\t\tcause,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\n\t\tprocessBuyOrder(params: {\n\t\t\tsigner: FraudEngineSigner;\n\t\t\torderDetails: BuyOrderDetails;\n\t\t\tuserDetails?: UserDetails;\n\t\t\torderSource?: string;\n\t\t\tplaceOrder: () => Promise<string>;\n\t\t}): ResultAsync<ProcessBuyOrderResult, FraudEngineError> {\n\t\t\tif (configError) return errAsync(configError);\n\t\t\treturn ResultAsync.fromPromise(\n\t\t\t\t(async () => {\n\t\t\t\t\tlet activityLogId: number | null = null;\n\n\t\t\t\t\t// Step 1: Fraud check (fail-open)\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst fraudCheck = await checkBuyOrderInternal(params);\n\t\t\t\t\t\tif (!fraudCheck.approved) {\n\t\t\t\t\t\t\treturn { status: \"rejected\" as const, message: fraudCheck.message };\n\t\t\t\t\t\t}\n\t\t\t\t\t\tactivityLogId = fraudCheck.activity_log_id;\n\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\tlogger.error(\"Fraud check failed, proceeding with order (fail-open)\", {\n\t\t\t\t\t\t\terror: String(cause),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Step 2: Place order (consumer callback)\n\t\t\t\t\tlet orderId: string;\n\t\t\t\t\ttry {\n\t\t\t\t\t\torderId = await params.placeOrder();\n\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\tthrow new FraudEngineError(\"Place order callback failed\", {\n\t\t\t\t\t\t\tcode: \"PLACE_ORDER_ERROR\",\n\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Step 3: Auto-link (fire-and-forget, only if fraud check succeeded)\n\t\t\t\t\tif (activityLogId !== null) {\n\t\t\t\t\t\tlinkOrderInternal(params.signer, activityLogId, orderId).mapErr((e) => {\n\t\t\t\t\t\t\tlogger.error(\"Failed to link order to activity log\", {\n\t\t\t\t\t\t\t\torderId,\n\t\t\t\t\t\t\t\tactivityLogId: activityLogId as number,\n\t\t\t\t\t\t\t\terror: e.message,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\treturn { status: \"placed\" as const, orderId };\n\t\t\t\t})(),\n\t\t\t\t(cause) => {\n\t\t\t\t\tif (cause instanceof FraudEngineError) return cause;\n\t\t\t\t\treturn new FraudEngineError(\"Process buy order failed\", {\n\t\t\t\t\t\tcode: \"NETWORK_ERROR\",\n\t\t\t\t\t\tcause,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\n\t\tlogFingerprint(params: {\n\t\t\tsigner: FraudEngineSigner;\n\t\t}): ResultAsync<FingerprintLogResult | null, FraudEngineError> {\n\t\t\tif (configError) return errAsync(configError);\n\t\t\treturn ResultAsync.fromPromise(\n\t\t\t\t(async () => {\n\t\t\t\t\tlogger.info(\"Logging fingerprint\");\n\n\t\t\t\t\tconst fingerprintResult = await getFingerprintResult(5000);\n\t\t\t\t\tif (!fingerprintResult) {\n\t\t\t\t\t\tlogger.warn(\"Fingerprint not available, skipping\");\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst signedHeaders = await getSignedHeaders(params.signer, \"fingerprint-log\");\n\n\t\t\t\t\tconst normalizedAddress = params.signer.address.toLowerCase();\n\t\t\t\t\tconst timestamp = Date.now();\n\n\t\t\t\t\tconst payload = JSON.stringify({\n\t\t\t\t\t\tfingerprint_id: fingerprintResult.visitorId,\n\t\t\t\t\t});\n\n\t\t\t\t\t// AAD format: \"fingerprint|user_address|timestamp\"\n\t\t\t\t\tconst aad = `fingerprint|${normalizedAddress}|${timestamp}`;\n\t\t\t\t\tconst encrypted = await encryptPayload(payload, aad, encryptionKey);\n\n\t\t\t\t\tconst response = await fetch(`${apiUrl}/fingerprint-log`, {\n\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\t\t...signedHeaders,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\t\tuser_address: normalizedAddress,\n\t\t\t\t\t\t\ttimestamp,\n\t\t\t\t\t\t\tencrypted_payload: encrypted,\n\t\t\t\t\t\t}),\n\t\t\t\t\t});\n\n\t\t\t\t\tif (!response.ok) {\n\t\t\t\t\t\tthrow new FraudEngineError(`Fingerprint log API returned ${response.status}`, {\n\t\t\t\t\t\t\tcode: \"API_ERROR\",\n\t\t\t\t\t\t\tcontext: { status: response.status },\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst data = (await response.json()) as FingerprintLogResult;\n\t\t\t\t\tlogger.info(\"Fingerprint logged successfully\");\n\t\t\t\t\treturn data;\n\t\t\t\t})(),\n\t\t\t\t(cause) => {\n\t\t\t\t\tif (cause instanceof FraudEngineError) return cause;\n\t\t\t\t\treturn new FraudEngineError(\"Fingerprint log failed\", {\n\t\t\t\t\t\tcode: \"NETWORK_ERROR\",\n\t\t\t\t\t\tcause,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\n\t\tasync getFingerprint() {\n\t\t\treturn getFingerprintResult(5000);\n\t\t},\n\n\t\tasync getDeviceDetails() {\n\t\t\treturn getDeviceDetails();\n\t\t},\n\n\t\tcleanupSeonStorage() {\n\t\t\tcleanupSeon();\n\t\t},\n\t};\n}\n","/** Converts a hex string to a Uint8Array. */\nexport function hexToBytes(hex: string): Uint8Array {\n\tconst bytes = new Uint8Array(hex.length / 2);\n\tfor (let i = 0; i < hex.length; i += 2) {\n\t\tbytes[i / 2] = Number.parseInt(hex.slice(i, i + 2), 16);\n\t}\n\treturn bytes;\n}\n\n/** Converts a Uint8Array to a base64 string. */\nexport function bytesToBase64(bytes: Uint8Array): string {\n\tlet binary = \"\";\n\tfor (const byte of bytes) {\n\t\tbinary += String.fromCharCode(byte);\n\t}\n\treturn btoa(binary);\n}\n","export interface Logger {\n\tdebug(message: string, data?: Record<string, unknown>): void;\n\tinfo(message: string, data?: Record<string, unknown>): void;\n\twarn(message: string, data?: Record<string, unknown>): void;\n\terror(message: string, data?: Record<string, unknown>): void;\n}\n\nconst noop = () => {};\n\nexport const noopLogger: Logger = {\n\tdebug: noop,\n\tinfo: noop,\n\twarn: noop,\n\terror: noop,\n};\n","import { ResultAsync } from \"neverthrow\";\nimport { SdkError } from \"../validation\";\nimport { sleep } from \"./sleep\";\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst MAX_RETRIES = 3;\nconst BACKOFF_MS = 500;\n\nexport type SubgraphErrorCode = \"HTTP_ERROR\" | \"GRAPHQL_ERROR\" | \"NO_DATA\" | \"TRANSPORT_ERROR\";\n\n/** Transport-level error from the shared subgraph client. Consumers remap to their own domain error. */\nexport class SubgraphError extends SdkError<SubgraphErrorCode> {\n\tconstructor(\n\t\tmessage: string,\n\t\toptions: {\n\t\t\tcode: SubgraphErrorCode;\n\t\t\tcause?: unknown;\n\t\t\tcontext?: Record<string, unknown>;\n\t\t},\n\t) {\n\t\tsuper(message, options);\n\t\tthis.name = \"SubgraphError\";\n\t}\n}\n\nexport interface SubgraphQueryParams {\n\treadonly query: string;\n\treadonly variables?: Record<string, unknown>;\n\treadonly timeoutMs?: number;\n}\n\nfunction isTransient(error: unknown): boolean {\n\tif (error instanceof SubgraphError) {\n\t\tif (error.code !== \"HTTP_ERROR\") return false;\n\t\tconst status = (error.context as { status?: number } | undefined)?.status;\n\t\treturn typeof status === \"number\" && status >= 500;\n\t}\n\tif (error instanceof DOMException && error.name === \"AbortError\") return true;\n\tif (error instanceof TypeError) return true;\n\treturn false;\n}\n\n/**\n * POSTs a GraphQL query to `url` with retry + timeout. Returns the `data` field on\n * success. All transport and GraphQL-level failures surface as `SubgraphError`.\n */\nexport function querySubgraph(\n\turl: string,\n\tparams: SubgraphQueryParams,\n): ResultAsync<unknown, SubgraphError> {\n\tconst timeoutMs = params.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\n\tconst fetchOnce = async () => {\n\t\tconst controller = new AbortController();\n\t\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tquery: params.query,\n\t\t\t\t\tvariables: params.variables,\n\t\t\t\t}),\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new SubgraphError(`Subgraph request failed (status: ${response.status})`, {\n\t\t\t\t\tcode: \"HTTP_ERROR\",\n\t\t\t\t\tcause: response,\n\t\t\t\t\tcontext: { status: response.status },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst json = await response.json();\n\n\t\t\tif (json.errors?.length > 0) {\n\t\t\t\tthrow new SubgraphError(\"Subgraph returned GraphQL errors\", {\n\t\t\t\t\tcode: \"GRAPHQL_ERROR\",\n\t\t\t\t\tcause: json.errors,\n\t\t\t\t\tcontext: { errors: json.errors },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (!json.data) {\n\t\t\t\tthrow new SubgraphError(\"Subgraph returned no data\", {\n\t\t\t\t\tcode: \"NO_DATA\",\n\t\t\t\t\tcause: \"Missing data field in GraphQL response\",\n\t\t\t\t\tcontext: { response: json },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn json.data;\n\t\t} finally {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t};\n\n\tconst fetchWithRetry = async () => {\n\t\tfor (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n\t\t\ttry {\n\t\t\t\treturn await fetchOnce();\n\t\t\t} catch (error) {\n\t\t\t\tconst lastAttempt = attempt === MAX_RETRIES;\n\t\t\t\tif (lastAttempt || !isTransient(error)) throw error;\n\t\t\t\tawait sleep(BACKOFF_MS * (attempt + 1));\n\t\t\t}\n\t\t}\n\t\tthrow new SubgraphError(\"Subgraph query exhausted retries\", { code: \"TRANSPORT_ERROR\" });\n\t};\n\n\treturn ResultAsync.fromPromise(fetchWithRetry(), (error) =>\n\t\terror instanceof SubgraphError\n\t\t\t? error\n\t\t\t: new SubgraphError(\"Subgraph query failed\", {\n\t\t\t\t\tcode: \"TRANSPORT_ERROR\",\n\t\t\t\t\tcause: error,\n\t\t\t\t}),\n\t);\n}\n","export class SdkError<TCode extends string = string> extends Error {\n\treadonly code: TCode;\n\treadonly cause?: unknown;\n\treadonly context?: Record<string, unknown>;\n\n\tconstructor(\n\t\tmessage: string,\n\t\toptions: {\n\t\t\tcode: TCode;\n\t\t\tcause?: unknown;\n\t\t\tcontext?: Record<string, unknown>;\n\t\t},\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"SdkError\";\n\t\tthis.code = options.code;\n\t\tthis.cause = options.cause;\n\t\tthis.context = options.context;\n\t}\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport { isAddress } from \"viem\";\nimport { z } from \"zod\";\nimport { CURRENCY_CODES } from \"../country/currency\";\n\nexport const ZodAddressSchema = z\n\t.string()\n\t.refine((s) => isAddress(s), { message: \"Invalid Ethereum address\" });\n\nexport const ZodCurrencySchema = z.enum(CURRENCY_CODES);\n\nexport function validate<S extends z.ZodType, E>(\n\tschema: S,\n\tdata: unknown,\n\ttoError: (message: string, cause: unknown, data: unknown) => E,\n): Result<z.infer<S>, E> {\n\tconst result = schema.safeParse(data);\n\tif (result.success) {\n\t\treturn ok(result.data as z.infer<S>);\n\t}\n\treturn err(toError(z.prettifyError(result.error), result.error, data));\n}\n","/**\n * All supported currency symbols. Single source of truth for the SDK.\n *\n * Lives alongside the country metadata so that adding a currency is a\n * single-folder operation: drop a new file in `currencies/<code>.ts`, add it\n * to this map, and both `COUNTRY_OPTIONS` and `ZodCurrencySchema` pick it up.\n */\nexport const CURRENCY = {\n\tIDR: \"IDR\",\n\tINR: \"INR\",\n\tBRL: \"BRL\",\n\tARS: \"ARS\",\n\tMEX: \"MEX\",\n\tVEN: \"VEN\",\n\tEUR: \"EUR\",\n\tNGN: \"NGN\",\n\tUSD: \"USD\",\n\tCOP: \"COP\",\n\tECU: \"ECU\",\n} as const;\n\n/** Union of supported currency codes. */\nexport type CurrencyCode = (typeof CURRENCY)[keyof typeof CURRENCY];\n\n/**\n * Tuple form of the currency codes — used by `z.enum(...)` in the shared\n * validation layer. Narrow tuple type required by Zod.\n */\nexport const CURRENCY_CODES = Object.values(CURRENCY) as [CurrencyCode, ...CurrencyCode[]];\n","import type { DeviceDetails } from \"./types\";\n\ninterface NavigatorConnection {\n\treadonly effectiveType?: string;\n}\n\ninterface NavigatorExtended extends Navigator {\n\treadonly connection?: NavigatorConnection;\n\treadonly deviceMemory?: number;\n}\n\nexport function getBasicDeviceDetails(): Omit<DeviceDetails, \"ip\" | \"seonSession\"> {\n\tconst nav = typeof navigator !== \"undefined\" ? (navigator as NavigatorExtended) : undefined;\n\tconst win = typeof window !== \"undefined\" ? window : undefined;\n\n\treturn {\n\t\tuserAgent: nav?.userAgent ?? \"\",\n\t\tplatform: nav?.platform ?? \"\",\n\t\tlanguage: nav?.language ?? \"\",\n\t\tlanguages: nav ? Array.from(nav.languages) : [],\n\t\tscreenWidth: win?.screen?.width ?? 0,\n\t\tscreenHeight: win?.screen?.height ?? 0,\n\t\tdevicePixelRatio: win?.devicePixelRatio ?? 1,\n\t\ttimezone: Intl?.DateTimeFormat?.()?.resolvedOptions?.()?.timeZone ?? \"\",\n\t\ttimezoneOffset: new Date().getTimezoneOffset(),\n\t\tcookiesEnabled: nav?.cookieEnabled ?? false,\n\t\tdoNotTrack: nav?.doNotTrack ?? null,\n\t\tonline: nav?.onLine ?? true,\n\t\tconnectionType: nav?.connection?.effectiveType,\n\t\tdeviceMemory: nav?.deviceMemory,\n\t\thardwareConcurrency: nav?.hardwareConcurrency,\n\t\ttouchSupport: nav ? \"ontouchstart\" in window : false,\n\t\tmaxTouchPoints: nav?.maxTouchPoints ?? 0,\n\t\tvendor: nav?.vendor ?? \"\",\n\t\tappVersion: nav?.appVersion ?? \"\",\n\t\tcolorDepth: win?.screen?.colorDepth ?? 0,\n\t\tpixelDepth: win?.screen?.pixelDepth ?? 0,\n\t};\n}\n\nexport async function fetchIpAddress(): Promise<string | undefined> {\n\ttry {\n\t\tconst response = await fetch(\"https://api.ipify.org?format=json\");\n\t\tconst data = (await response.json()) as { ip: string };\n\t\treturn data.ip;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport async function getDeviceDetails(seonSession?: string): Promise<DeviceDetails> {\n\tconst basic = getBasicDeviceDetails();\n\tconst ip = await fetchIpAddress();\n\treturn { ...basic, ip, seonSession };\n}\n","import { SdkError } from \"../validation\";\n\nexport type FraudEngineErrorCode =\n\t| \"API_ERROR\"\n\t| \"ENCRYPTION_ERROR\"\n\t| \"SIGNING_ERROR\"\n\t| \"VALIDATION_ERROR\"\n\t| \"NETWORK_ERROR\"\n\t| \"PLACE_ORDER_ERROR\";\n\nexport class FraudEngineError extends SdkError<FraudEngineErrorCode> {\n\tconstructor(\n\t\tmessage: string,\n\t\toptions: {\n\t\t\tcode: FraudEngineErrorCode;\n\t\t\tcause?: unknown;\n\t\t\tcontext?: Record<string, unknown>;\n\t\t},\n\t) {\n\t\tsuper(message, options);\n\t\tthis.name = \"FraudEngineError\";\n\t}\n}\n","import { bytesToBase64, hexToBytes } from \"../lib/encoding\";\nimport { FraudEngineError } from \"./errors\";\n\nexport async function getEncryptionKey(encryptionKeyHex: string): Promise<CryptoKey> {\n\tconst keyBytes = hexToBytes(encryptionKeyHex);\n\treturn crypto.subtle.importKey(\n\t\t\"raw\",\n\t\tkeyBytes.buffer as ArrayBuffer,\n\t\t{ name: \"AES-GCM\" },\n\t\tfalse,\n\t\t[\"encrypt\"],\n\t);\n}\n\nexport async function encryptPayload(\n\tpayload: string,\n\taad: string,\n\tencryptionKeyHex: string,\n): Promise<string> {\n\ttry {\n\t\tconst key = await getEncryptionKey(encryptionKeyHex);\n\t\tconst iv = crypto.getRandomValues(new Uint8Array(12));\n\t\tconst encoded = new TextEncoder().encode(payload);\n\t\tconst aadEncoded = new TextEncoder().encode(aad);\n\n\t\tconst ciphertext = await crypto.subtle.encrypt(\n\t\t\t{ name: \"AES-GCM\", iv, additionalData: aadEncoded, tagLength: 128 },\n\t\t\tkey,\n\t\t\tencoded,\n\t\t);\n\n\t\t// IV (12 bytes) + ciphertext + auth tag (16 bytes appended by Web Crypto)\n\t\tconst result = new Uint8Array(iv.length + ciphertext.byteLength);\n\t\tresult.set(iv, 0);\n\t\tresult.set(new Uint8Array(ciphertext), iv.length);\n\n\t\treturn bytesToBase64(result);\n\t} catch (cause) {\n\t\tthrow new FraudEngineError(\"Encryption failed\", {\n\t\t\tcode: \"ENCRYPTION_ERROR\",\n\t\t\tcause,\n\t\t});\n\t}\n}\n","import FingerprintJS from \"@fingerprintjs/fingerprintjs\";\n\nlet agent: Awaited<ReturnType<typeof FingerprintJS.load>> | null = null;\nlet cachedResult: { visitorId: string; confidence: number } | null = null;\n\nexport async function loadFingerprintAgent(): Promise<void> {\n\tif (agent) return;\n\tagent = await FingerprintJS.load();\n}\n\nexport async function getFingerprint(\n\ttimeoutMs = 5000,\n): Promise<{ visitorId: string; confidence: number } | null> {\n\tif (cachedResult) return cachedResult;\n\tif (!agent) {\n\t\ttry {\n\t\t\tawait loadFingerprintAgent();\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\tconst loadedAgent = agent;\n\tif (!loadedAgent) return null;\n\ttry {\n\t\tconst result = await Promise.race([\n\t\t\tloadedAgent.get(),\n\t\t\tnew Promise<never>((_, reject) =>\n\t\t\t\tsetTimeout(() => reject(new Error(\"FingerprintJS timed out\")), timeoutMs),\n\t\t\t),\n\t\t]);\n\t\tcachedResult = {\n\t\t\tvisitorId: result.visitorId,\n\t\t\tconfidence: result.confidence.score,\n\t\t};\n\t\treturn cachedResult;\n\t} catch {\n\t\treturn null;\n\t}\n}\n","import seon from \"@seontechnologies/seon-javascript-sdk\";\n\nlet initialized = false;\n\nexport function initSeon(): void {\n\tif (initialized) return;\n\tseon.init();\n\tinitialized = true;\n}\n\nexport async function getSeonSession(region: string): Promise<string | undefined> {\n\ttry {\n\t\treturn await seon.getSession({\n\t\t\tgeolocation: { canPrompt: false },\n\t\t\tnetworkTimeoutMs: 2000,\n\t\t\tfieldTimeoutMs: 2000,\n\t\t\tregion,\n\t\t\tsilentMode: true,\n\t\t});\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function cleanupSeonStorage(): void {\n\tif (typeof localStorage === \"undefined\") return;\n\tconst keysToRemove: string[] = [];\n\tfor (let i = 0; i < localStorage.length; i++) {\n\t\tconst key = localStorage.key(i);\n\t\tif (key?.startsWith(\"seon_session_sent_\")) keysToRemove.push(key);\n\t}\n\tfor (const key of keysToRemove) localStorage.removeItem(key);\n}\n","import { FraudEngineError } from \"./errors\";\nimport type { FraudEngineSigner } from \"./types\";\n\nexport async function getSignedHeaders(\n\tsigner: FraudEngineSigner,\n\taction: \"activity-log\" | \"link-order\" | \"fingerprint-log\",\n): Promise<Record<string, string>> {\n\t// The EIP-191 signed message is bound to the address of the key that\n\t// actually produces the signature (the admin EOA for AA smart wallets),\n\t// not to the tracked subject address. For plain EOA signers where no\n\t// separate `signerAddress` is provided, this falls back to `signer.address`\n\t// and behaviour is identical to the single-address case.\n\tconst signingAddress = (signer.signerAddress ?? signer.address).toLowerCase();\n\tconst timestamp = Math.floor(Date.now() / 1000).toString();\n\tconst message = `${action}:${signingAddress}:${timestamp}`;\n\n\ttry {\n\t\tconst signature = await signer.signMessage(message);\n\t\treturn {\n\t\t\t\"X-Signer-Address\": signingAddress,\n\t\t\t\"X-Timestamp\": timestamp,\n\t\t\t\"X-Signature\": signature,\n\t\t};\n\t} catch (cause) {\n\t\tthrow new FraudEngineError(\"Failed to sign message\", {\n\t\t\tcode: \"SIGNING_ERROR\",\n\t\t\tcause,\n\t\t});\n\t}\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport { z } from \"zod\";\nimport { FraudEngineError } from \"./errors\";\n\n// ── Config schema ──────────────────────────────────────────────────────\n\nexport const ZodFraudEngineConfigSchema = z.object({\n\tapiUrl: z.url(),\n\tencryptionKey: z.string().min(1),\n\tseonRegion: z.string().optional(),\n});\n\n// ── Buy order details schema ───────────────────────────────────────────\n\nexport const ZodBuyOrderDetailsSchema = z.object({\n\tcryptoAmount: z.number(),\n\tfiatAmount: z.number(),\n\tcurrency: z.string().min(1),\n\trecipientAddress: z.string().min(1),\n\tfee: z.number(),\n\tamountAfterFee: z.number(),\n\tpaymentMethod: z.string().optional(),\n\testimatedProcessingTime: z.string().optional(),\n});\n\n// ── User details schema ────────────────────────────────────────────────\n\nexport const ZodUserDetailsSchema = z.object({\n\tcurrency: z.string().optional(),\n\tcountry: z.string().optional(),\n\tlanguage: z.string().optional(),\n\tloginMethod: z.enum([\"email\", \"google\", \"phone\", \"passkey\", \"unknown\"]).optional(),\n\tloginEmail: z.string().optional(),\n\tloginPhone: z.string().optional(),\n});\n\n// ── Link order schema ──────────────────────────────────────────────────\n\nexport const ZodLinkOrderParamsSchema = z.object({\n\tactivityLogId: z.number().int().positive(),\n\torderId: z.string().min(1),\n});\n\n// ── Validate helper ────────────────────────────────────────────────────\n\nexport function validate<S extends z.ZodType>(\n\tschema: S,\n\tdata: unknown,\n): Result<z.infer<S>, FraudEngineError> {\n\tconst result = schema.safeParse(data);\n\tif (result.success) {\n\t\treturn ok(result.data as z.infer<S>);\n\t}\n\treturn err(\n\t\tnew FraudEngineError(z.prettifyError(result.error), {\n\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\tcause: result.error,\n\t\t\tcontext: { data },\n\t\t}),\n\t);\n}\n"],"mappings":"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","names":["import_neverthrow","import_neverthrow","FingerprintJS","seon","import_neverthrow","import_zod","validate","validate"]}
|
|
1
|
+
{"version":3,"sources":["../src/fraud-engine/index.ts","../src/fraud-engine/client.ts","../src/lib/encoding.ts","../src/lib/logger.ts","../src/lib/subgraph.ts","../src/validation/errors.validation.ts","../src/validation/schemas.validation.ts","../src/country/currency.ts","../src/fraud-engine/device.ts","../src/fraud-engine/errors.ts","../src/fraud-engine/encryption.ts","../src/fraud-engine/fingerprint.ts","../src/fraud-engine/seon.ts","../src/fraud-engine/signing.ts","../src/fraud-engine/validation.ts"],"sourcesContent":["// ── Main entry point ────────────────────────────────────────────────────\n\nexport { createFraudEngine } from \"./client\";\n\n// ── Types ───────────────────────────────────────────────────────────────\n\nexport type {\n\tActivityType,\n\tBuyOrderDetails,\n\tDeviceDetails,\n\tFingerprintLogResult,\n\tFraudCheckApiResponse,\n\tFraudCheckResult,\n\tFraudEngine,\n\tFraudEngineConfig,\n\tFraudEngineSigner,\n\tLinkOrderResult,\n\tProcessBuyOrderResult,\n\tUserDetails,\n} from \"./types\";\n\n// ── Logger ──────────────────────────────────────────────────────────────\n\nexport { type Logger, noopLogger } from \"../lib\";\n\n// ── Errors ──────────────────────────────────────────────────────────────\n\nexport { FraudEngineError, type FraudEngineErrorCode } from \"./errors\";\n\n// ── Low-level exports (for advanced use) ────────────────────────────────\n\nexport { fetchIpAddress, getBasicDeviceDetails, getDeviceDetails } from \"./device\";\nexport { encryptPayload } from \"./encryption\";\nexport { getFingerprint, loadFingerprintAgent } from \"./fingerprint\";\nexport { cleanupSeonStorage, getSeonSession, initSeon } from \"./seon\";\nexport { getSignedHeaders } from \"./signing\";\n","import { errAsync, ResultAsync } from \"neverthrow\";\nimport { type Logger, noopLogger } from \"../lib\";\nimport { getDeviceDetails } from \"./device\";\nimport { encryptPayload } from \"./encryption\";\nimport { FraudEngineError } from \"./errors\";\nimport { getFingerprint as getFingerprintResult, loadFingerprintAgent } from \"./fingerprint\";\nimport { cleanupSeonStorage as cleanupSeon, getSeonSession, initSeon } from \"./seon\";\nimport { getSignedHeaders } from \"./signing\";\nimport type {\n\tBuyOrderDetails,\n\tFingerprintLogResult,\n\tFraudCheckApiResponse,\n\tFraudCheckResult,\n\tFraudEngine,\n\tFraudEngineConfig,\n\tFraudEngineSigner,\n\tLinkOrderResult,\n\tProcessBuyOrderResult,\n\tUserDetails,\n} from \"./types\";\nimport { validate, ZodFraudEngineConfigSchema } from \"./validation\";\n\nexport function createFraudEngine(config: FraudEngineConfig): FraudEngine {\n\tconst { apiUrl, encryptionKey } = config;\n\tconst seonRegion = config.seonRegion ?? \"asia\";\n\tconst logger: Logger = config.logger ?? noopLogger;\n\n\t// Validate eagerly so misconfiguration surfaces at construction time, but\n\t// never throw — the SDK's contract is that all failures flow through\n\t// `Result`/`ResultAsync`. Capture the error and short-circuit any method\n\t// that depends on the validated fields (`apiUrl`, `encryptionKey`).\n\t// Methods that don't depend on them (init, getFingerprint, getDeviceDetails,\n\t// cleanupSeonStorage) remain usable so consumers can still hydrate device\n\t// fingerprints even with a partially-configured engine.\n\tconst configResult = validate(ZodFraudEngineConfigSchema, {\n\t\tapiUrl,\n\t\tencryptionKey,\n\t\tseonRegion,\n\t});\n\tconst configError = configResult.isErr() ? configResult.error : null;\n\tif (configError) {\n\t\tlogger.error(\n\t\t\t\"Fraud engine config invalid; API methods will return VALIDATION_ERROR until fixed\",\n\t\t\t{ error: configError.message },\n\t\t);\n\t}\n\n\tfunction linkOrderInternal(\n\t\tsigner: FraudEngineSigner,\n\t\tactivityLogId: number,\n\t\torderId: string,\n\t): ResultAsync<LinkOrderResult, FraudEngineError> {\n\t\treturn ResultAsync.fromPromise(\n\t\t\t(async () => {\n\t\t\t\tlogger.info(\"Linking order to activity log\", { activityLogId, orderId });\n\n\t\t\t\tconst signedHeaders = await getSignedHeaders(signer, \"link-order\");\n\n\t\t\t\tconst response = await fetch(`${apiUrl}/activity-logs/link-order`, {\n\t\t\t\t\tmethod: \"PATCH\",\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\t...signedHeaders,\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\tactivity_log_id: activityLogId,\n\t\t\t\t\t\torder_id: orderId,\n\t\t\t\t\t\tuser_address: signer.address.toLowerCase(),\n\t\t\t\t\t}),\n\t\t\t\t});\n\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow new FraudEngineError(`Link order API returned ${response.status}`, {\n\t\t\t\t\t\tcode: \"API_ERROR\",\n\t\t\t\t\t\tcontext: { status: response.status },\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst data = (await response.json()) as LinkOrderResult;\n\t\t\t\tlogger.info(\"Order linked successfully\", { orderId });\n\t\t\t\treturn data;\n\t\t\t})(),\n\t\t\t(cause) => {\n\t\t\t\tif (cause instanceof FraudEngineError) return cause;\n\t\t\t\treturn new FraudEngineError(\"Link order failed\", {\n\t\t\t\t\tcode: \"NETWORK_ERROR\",\n\t\t\t\t\tcause,\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t}\n\n\tasync function checkBuyOrderInternal(params: {\n\t\tsigner: FraudEngineSigner;\n\t\torderDetails: BuyOrderDetails;\n\t\tuserDetails?: UserDetails;\n\t\torderSource?: string;\n\t}): Promise<FraudCheckApiResponse> {\n\t\tlogger.info(\"Checking buy order for fraud\", {\n\t\t\tcurrency: params.orderDetails.currency,\n\t\t\tfiatAmount: params.orderDetails.fiatAmount,\n\t\t});\n\n\t\tconst [seonSession, deviceDetails, signedHeaders] = await Promise.all([\n\t\t\tgetSeonSession(seonRegion),\n\t\t\tgetDeviceDetails(),\n\t\t\tgetSignedHeaders(params.signer, \"activity-log\"),\n\t\t]);\n\n\t\tconst device = { ...deviceDetails, seonSession };\n\n\t\tconst userAddress = params.signer.address.toLowerCase();\n\t\tconst timestamp = Date.now();\n\n\t\tconst payload = JSON.stringify({\n\t\t\tuser_details: {\n\t\t\t\tcurrency: params.userDetails?.currency,\n\t\t\t\tcountry: params.userDetails?.country,\n\t\t\t\tlanguage: params.userDetails?.language,\n\t\t\t\tlogin_method: params.userDetails?.loginMethod,\n\t\t\t\tlogin_email: params.userDetails?.loginEmail,\n\t\t\t\tlogin_phone: params.userDetails?.loginPhone,\n\t\t\t},\n\t\t\ttransaction_details: {\n\t\t\t\tcrypto_amount: params.orderDetails.cryptoAmount,\n\t\t\t\tfiat_amount: params.orderDetails.fiatAmount,\n\t\t\t\tcurrency: params.orderDetails.currency,\n\t\t\t\trecipient_address: params.orderDetails.recipientAddress,\n\t\t\t\tfee: params.orderDetails.fee,\n\t\t\t\tamount_after_fee: params.orderDetails.amountAfterFee,\n\t\t\t\tpayment_method: params.orderDetails.paymentMethod,\n\t\t\t\testimated_processing_time: params.orderDetails.estimatedProcessingTime,\n\t\t\t\torder_timestamp: timestamp,\n\t\t\t\torder_source: params.orderSource,\n\t\t\t},\n\t\t\tdevice_details: device,\n\t\t});\n\n\t\t// AAD format must match backend: \"type|user_address|timestamp\"\n\t\tconst aad = `buy_order|${userAddress}|${timestamp}`;\n\t\tconst encrypted = await encryptPayload(payload, aad, encryptionKey);\n\n\t\tconst response = await fetch(`${apiUrl}/activity-logs`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t...signedHeaders,\n\t\t\t},\n\t\t\tbody: JSON.stringify({\n\t\t\t\ttype: \"buy_order\",\n\t\t\t\tuser_address: userAddress,\n\t\t\t\ttimestamp,\n\t\t\t\tencrypted_payload: encrypted,\n\t\t\t}),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new FraudEngineError(`Fraud check API returned ${response.status}`, {\n\t\t\t\tcode: \"API_ERROR\",\n\t\t\t\tcontext: { status: response.status },\n\t\t\t});\n\t\t}\n\n\t\tconst data = (await response.json()) as FraudCheckApiResponse;\n\t\tlogger.info(\"Fraud check result\", {\n\t\t\tapproved: data.approved,\n\t\t\tactivityLogId: data.activity_log_id,\n\t\t});\n\t\treturn data;\n\t}\n\n\treturn {\n\t\tasync init() {\n\t\t\tlogger.info(\"Initializing fraud engine\");\n\t\t\ttry {\n\t\t\t\tinitSeon();\n\t\t\t} catch (cause) {\n\t\t\t\tlogger.error(\"SEON initialization failed\", { cause: String(cause) });\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait loadFingerprintAgent();\n\t\t\t} catch (cause) {\n\t\t\t\tlogger.error(\"FingerprintJS initialization failed\", {\n\t\t\t\t\tcause: String(cause),\n\t\t\t\t});\n\t\t\t}\n\t\t\tlogger.info(\"Fraud engine initialized\");\n\t\t},\n\n\t\tcheckBuyOrder(params: {\n\t\t\tsigner: FraudEngineSigner;\n\t\t\torderDetails: BuyOrderDetails;\n\t\t\tuserDetails?: UserDetails;\n\t\t\torderSource?: string;\n\t\t}): ResultAsync<FraudCheckResult, FraudEngineError> {\n\t\t\tif (configError) return errAsync(configError);\n\t\t\treturn ResultAsync.fromPromise(\n\t\t\t\tcheckBuyOrderInternal(params).then((data) => ({\n\t\t\t\t\tapproved: data.approved,\n\t\t\t\t\tactivityLogId: data.activity_log_id,\n\t\t\t\t\tmessage: data.message,\n\t\t\t\t\tlinkOrder: (orderId: string) =>\n\t\t\t\t\t\tlinkOrderInternal(params.signer, data.activity_log_id, orderId),\n\t\t\t\t})),\n\t\t\t\t(cause) => {\n\t\t\t\t\tif (cause instanceof FraudEngineError) return cause;\n\t\t\t\t\treturn new FraudEngineError(\"Fraud check failed\", {\n\t\t\t\t\t\tcode: \"NETWORK_ERROR\",\n\t\t\t\t\t\tcause,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\n\t\tprocessBuyOrder(params: {\n\t\t\tsigner: FraudEngineSigner;\n\t\t\torderDetails: BuyOrderDetails;\n\t\t\tuserDetails?: UserDetails;\n\t\t\torderSource?: string;\n\t\t\tplaceOrder: () => Promise<string>;\n\t\t}): ResultAsync<ProcessBuyOrderResult, FraudEngineError> {\n\t\t\tif (configError) return errAsync(configError);\n\t\t\treturn ResultAsync.fromPromise(\n\t\t\t\t(async () => {\n\t\t\t\t\tlet activityLogId: number | null = null;\n\n\t\t\t\t\t// Step 1: Fraud check (fail-open)\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst fraudCheck = await checkBuyOrderInternal(params);\n\t\t\t\t\t\tif (!fraudCheck.approved) {\n\t\t\t\t\t\t\treturn { status: \"rejected\" as const, message: fraudCheck.message };\n\t\t\t\t\t\t}\n\t\t\t\t\t\tactivityLogId = fraudCheck.activity_log_id;\n\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\tlogger.error(\"Fraud check failed, proceeding with order (fail-open)\", {\n\t\t\t\t\t\t\terror: String(cause),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Step 2: Place order (consumer callback)\n\t\t\t\t\tlet orderId: string;\n\t\t\t\t\ttry {\n\t\t\t\t\t\torderId = await params.placeOrder();\n\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\tthrow new FraudEngineError(\"Place order callback failed\", {\n\t\t\t\t\t\t\tcode: \"PLACE_ORDER_ERROR\",\n\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Step 3: Auto-link (fire-and-forget, only if fraud check succeeded)\n\t\t\t\t\tif (activityLogId !== null) {\n\t\t\t\t\t\tlinkOrderInternal(params.signer, activityLogId, orderId).mapErr((e) => {\n\t\t\t\t\t\t\tlogger.error(\"Failed to link order to activity log\", {\n\t\t\t\t\t\t\t\torderId,\n\t\t\t\t\t\t\t\tactivityLogId: activityLogId as number,\n\t\t\t\t\t\t\t\terror: e.message,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\treturn { status: \"placed\" as const, orderId };\n\t\t\t\t})(),\n\t\t\t\t(cause) => {\n\t\t\t\t\tif (cause instanceof FraudEngineError) return cause;\n\t\t\t\t\treturn new FraudEngineError(\"Process buy order failed\", {\n\t\t\t\t\t\tcode: \"NETWORK_ERROR\",\n\t\t\t\t\t\tcause,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\n\t\tlogFingerprint(params: {\n\t\t\tsigner: FraudEngineSigner;\n\t\t}): ResultAsync<FingerprintLogResult | null, FraudEngineError> {\n\t\t\tif (configError) return errAsync(configError);\n\t\t\treturn ResultAsync.fromPromise(\n\t\t\t\t(async () => {\n\t\t\t\t\tlogger.info(\"Logging fingerprint\");\n\n\t\t\t\t\tconst fingerprintResult = await getFingerprintResult(5000);\n\t\t\t\t\tif (!fingerprintResult) {\n\t\t\t\t\t\tlogger.warn(\"Fingerprint not available, skipping\");\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst signedHeaders = await getSignedHeaders(params.signer, \"fingerprint-log\");\n\n\t\t\t\t\tconst normalizedAddress = params.signer.address.toLowerCase();\n\t\t\t\t\tconst timestamp = Date.now();\n\n\t\t\t\t\tconst payload = JSON.stringify({\n\t\t\t\t\t\tfingerprint_id: fingerprintResult.visitorId,\n\t\t\t\t\t});\n\n\t\t\t\t\t// AAD format: \"fingerprint|user_address|timestamp\"\n\t\t\t\t\tconst aad = `fingerprint|${normalizedAddress}|${timestamp}`;\n\t\t\t\t\tconst encrypted = await encryptPayload(payload, aad, encryptionKey);\n\n\t\t\t\t\tconst response = await fetch(`${apiUrl}/fingerprint-log`, {\n\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\t\t...signedHeaders,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\t\tuser_address: normalizedAddress,\n\t\t\t\t\t\t\ttimestamp,\n\t\t\t\t\t\t\tencrypted_payload: encrypted,\n\t\t\t\t\t\t}),\n\t\t\t\t\t});\n\n\t\t\t\t\tif (!response.ok) {\n\t\t\t\t\t\tthrow new FraudEngineError(`Fingerprint log API returned ${response.status}`, {\n\t\t\t\t\t\t\tcode: \"API_ERROR\",\n\t\t\t\t\t\t\tcontext: { status: response.status },\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst data = (await response.json()) as FingerprintLogResult;\n\t\t\t\t\tlogger.info(\"Fingerprint logged successfully\");\n\t\t\t\t\treturn data;\n\t\t\t\t})(),\n\t\t\t\t(cause) => {\n\t\t\t\t\tif (cause instanceof FraudEngineError) return cause;\n\t\t\t\t\treturn new FraudEngineError(\"Fingerprint log failed\", {\n\t\t\t\t\t\tcode: \"NETWORK_ERROR\",\n\t\t\t\t\t\tcause,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\n\t\tasync getFingerprint() {\n\t\t\treturn getFingerprintResult(5000);\n\t\t},\n\n\t\tasync getDeviceDetails() {\n\t\t\treturn getDeviceDetails();\n\t\t},\n\n\t\tcleanupSeonStorage() {\n\t\t\tcleanupSeon();\n\t\t},\n\t};\n}\n","/** Converts a hex string to a Uint8Array. */\nexport function hexToBytes(hex: string): Uint8Array {\n\tconst bytes = new Uint8Array(hex.length / 2);\n\tfor (let i = 0; i < hex.length; i += 2) {\n\t\tbytes[i / 2] = Number.parseInt(hex.slice(i, i + 2), 16);\n\t}\n\treturn bytes;\n}\n\n/** Converts a Uint8Array to a base64 string. */\nexport function bytesToBase64(bytes: Uint8Array): string {\n\tlet binary = \"\";\n\tfor (const byte of bytes) {\n\t\tbinary += String.fromCharCode(byte);\n\t}\n\treturn btoa(binary);\n}\n","export interface Logger {\n\tdebug(message: string, data?: Record<string, unknown>): void;\n\tinfo(message: string, data?: Record<string, unknown>): void;\n\twarn(message: string, data?: Record<string, unknown>): void;\n\terror(message: string, data?: Record<string, unknown>): void;\n}\n\nconst noop = () => {};\n\nexport const noopLogger: Logger = {\n\tdebug: noop,\n\tinfo: noop,\n\twarn: noop,\n\terror: noop,\n};\n","import { ResultAsync } from \"neverthrow\";\nimport { SdkError } from \"../validation\";\nimport { sleep } from \"./sleep\";\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst MAX_RETRIES = 3;\nconst BACKOFF_MS = 500;\n\nexport type SubgraphErrorCode = \"HTTP_ERROR\" | \"GRAPHQL_ERROR\" | \"NO_DATA\" | \"TRANSPORT_ERROR\";\n\n/** Transport-level error from the shared subgraph client. Consumers remap to their own domain error. */\nexport class SubgraphError extends SdkError<SubgraphErrorCode> {\n\tconstructor(\n\t\tmessage: string,\n\t\toptions: {\n\t\t\tcode: SubgraphErrorCode;\n\t\t\tcause?: unknown;\n\t\t\tcontext?: Record<string, unknown>;\n\t\t},\n\t) {\n\t\tsuper(message, options);\n\t\tthis.name = \"SubgraphError\";\n\t}\n}\n\nexport interface SubgraphQueryParams {\n\treadonly query: string;\n\treadonly variables?: Record<string, unknown>;\n\treadonly timeoutMs?: number;\n}\n\nfunction isTransient(error: unknown): boolean {\n\tif (error instanceof SubgraphError) {\n\t\tif (error.code !== \"HTTP_ERROR\") return false;\n\t\tconst status = (error.context as { status?: number } | undefined)?.status;\n\t\treturn typeof status === \"number\" && status >= 500;\n\t}\n\tif (error instanceof DOMException && error.name === \"AbortError\") return true;\n\tif (error instanceof TypeError) return true;\n\treturn false;\n}\n\n/**\n * POSTs a GraphQL query to `url` with retry + timeout. Returns the `data` field on\n * success. All transport and GraphQL-level failures surface as `SubgraphError`.\n */\nexport function querySubgraph(\n\turl: string,\n\tparams: SubgraphQueryParams,\n): ResultAsync<unknown, SubgraphError> {\n\tconst timeoutMs = params.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\n\tconst fetchOnce = async () => {\n\t\tconst controller = new AbortController();\n\t\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tquery: params.query,\n\t\t\t\t\tvariables: params.variables,\n\t\t\t\t}),\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new SubgraphError(`Subgraph request failed (status: ${response.status})`, {\n\t\t\t\t\tcode: \"HTTP_ERROR\",\n\t\t\t\t\tcause: response,\n\t\t\t\t\tcontext: { status: response.status },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst json = await response.json();\n\n\t\t\tif (json.errors?.length > 0) {\n\t\t\t\tthrow new SubgraphError(\"Subgraph returned GraphQL errors\", {\n\t\t\t\t\tcode: \"GRAPHQL_ERROR\",\n\t\t\t\t\tcause: json.errors,\n\t\t\t\t\tcontext: { errors: json.errors },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (!json.data) {\n\t\t\t\tthrow new SubgraphError(\"Subgraph returned no data\", {\n\t\t\t\t\tcode: \"NO_DATA\",\n\t\t\t\t\tcause: \"Missing data field in GraphQL response\",\n\t\t\t\t\tcontext: { response: json },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn json.data;\n\t\t} finally {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t};\n\n\tconst fetchWithRetry = async () => {\n\t\tfor (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n\t\t\ttry {\n\t\t\t\treturn await fetchOnce();\n\t\t\t} catch (error) {\n\t\t\t\tconst lastAttempt = attempt === MAX_RETRIES;\n\t\t\t\tif (lastAttempt || !isTransient(error)) throw error;\n\t\t\t\tawait sleep(BACKOFF_MS * (attempt + 1));\n\t\t\t}\n\t\t}\n\t\tthrow new SubgraphError(\"Subgraph query exhausted retries\", { code: \"TRANSPORT_ERROR\" });\n\t};\n\n\treturn ResultAsync.fromPromise(fetchWithRetry(), (error) =>\n\t\terror instanceof SubgraphError\n\t\t\t? error\n\t\t\t: new SubgraphError(\"Subgraph query failed\", {\n\t\t\t\t\tcode: \"TRANSPORT_ERROR\",\n\t\t\t\t\tcause: error,\n\t\t\t\t}),\n\t);\n}\n","export class SdkError<TCode extends string = string> extends Error {\n\treadonly code: TCode;\n\treadonly cause?: unknown;\n\treadonly context?: Record<string, unknown>;\n\n\tconstructor(\n\t\tmessage: string,\n\t\toptions: {\n\t\t\tcode: TCode;\n\t\t\tcause?: unknown;\n\t\t\tcontext?: Record<string, unknown>;\n\t\t},\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"SdkError\";\n\t\tthis.code = options.code;\n\t\tthis.cause = options.cause;\n\t\tthis.context = options.context;\n\t}\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport { isAddress } from \"viem\";\nimport { z } from \"zod\";\nimport { CURRENCY_CODES } from \"../country/currency\";\n\nexport const ZodAddressSchema = z\n\t.string()\n\t.refine((s) => isAddress(s), { message: \"Invalid Ethereum address\" });\n\nexport const ZodCurrencySchema = z.enum(CURRENCY_CODES);\n\nexport function validate<S extends z.ZodType, E>(\n\tschema: S,\n\tdata: unknown,\n\ttoError: (message: string, cause: unknown, data: unknown) => E,\n): Result<z.infer<S>, E> {\n\tconst result = schema.safeParse(data);\n\tif (result.success) {\n\t\treturn ok(result.data as z.infer<S>);\n\t}\n\treturn err(toError(z.prettifyError(result.error), result.error, data));\n}\n","/**\n * All supported currency symbols. Single source of truth for the SDK.\n *\n * Lives alongside the country metadata so that adding a currency is a\n * single-folder operation: drop a new file in `currencies/<code>.ts`, add it\n * to this map, and both `COUNTRY_OPTIONS` and `ZodCurrencySchema` pick it up.\n */\nexport const CURRENCY = {\n\tIDR: \"IDR\",\n\tINR: \"INR\",\n\tBRL: \"BRL\",\n\tARS: \"ARS\",\n\tMEX: \"MEX\",\n\tVEN: \"VEN\",\n\tEUR: \"EUR\",\n\tNGN: \"NGN\",\n\tUSD: \"USD\",\n\tCOP: \"COP\",\n\tECU: \"ECU\",\n\tPEN: \"PEN\",\n} as const;\n\n/** Union of supported currency codes. */\nexport type CurrencyCode = (typeof CURRENCY)[keyof typeof CURRENCY];\n\n/**\n * Tuple form of the currency codes — used by `z.enum(...)` in the shared\n * validation layer. Narrow tuple type required by Zod.\n */\nexport const CURRENCY_CODES = Object.values(CURRENCY) as [CurrencyCode, ...CurrencyCode[]];\n","import type { DeviceDetails } from \"./types\";\n\ninterface NavigatorConnection {\n\treadonly effectiveType?: string;\n}\n\ninterface NavigatorExtended extends Navigator {\n\treadonly connection?: NavigatorConnection;\n\treadonly deviceMemory?: number;\n}\n\nexport function getBasicDeviceDetails(): Omit<DeviceDetails, \"ip\" | \"seonSession\"> {\n\tconst nav = typeof navigator !== \"undefined\" ? (navigator as NavigatorExtended) : undefined;\n\tconst win = typeof window !== \"undefined\" ? window : undefined;\n\n\treturn {\n\t\tuserAgent: nav?.userAgent ?? \"\",\n\t\tplatform: nav?.platform ?? \"\",\n\t\tlanguage: nav?.language ?? \"\",\n\t\tlanguages: nav ? Array.from(nav.languages) : [],\n\t\tscreenWidth: win?.screen?.width ?? 0,\n\t\tscreenHeight: win?.screen?.height ?? 0,\n\t\tdevicePixelRatio: win?.devicePixelRatio ?? 1,\n\t\ttimezone: Intl?.DateTimeFormat?.()?.resolvedOptions?.()?.timeZone ?? \"\",\n\t\ttimezoneOffset: new Date().getTimezoneOffset(),\n\t\tcookiesEnabled: nav?.cookieEnabled ?? false,\n\t\tdoNotTrack: nav?.doNotTrack ?? null,\n\t\tonline: nav?.onLine ?? true,\n\t\tconnectionType: nav?.connection?.effectiveType,\n\t\tdeviceMemory: nav?.deviceMemory,\n\t\thardwareConcurrency: nav?.hardwareConcurrency,\n\t\ttouchSupport: nav ? \"ontouchstart\" in window : false,\n\t\tmaxTouchPoints: nav?.maxTouchPoints ?? 0,\n\t\tvendor: nav?.vendor ?? \"\",\n\t\tappVersion: nav?.appVersion ?? \"\",\n\t\tcolorDepth: win?.screen?.colorDepth ?? 0,\n\t\tpixelDepth: win?.screen?.pixelDepth ?? 0,\n\t};\n}\n\nexport async function fetchIpAddress(): Promise<string | undefined> {\n\ttry {\n\t\tconst response = await fetch(\"https://api.ipify.org?format=json\");\n\t\tconst data = (await response.json()) as { ip: string };\n\t\treturn data.ip;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport async function getDeviceDetails(seonSession?: string): Promise<DeviceDetails> {\n\tconst basic = getBasicDeviceDetails();\n\tconst ip = await fetchIpAddress();\n\treturn { ...basic, ip, seonSession };\n}\n","import { SdkError } from \"../validation\";\n\nexport type FraudEngineErrorCode =\n\t| \"API_ERROR\"\n\t| \"ENCRYPTION_ERROR\"\n\t| \"SIGNING_ERROR\"\n\t| \"VALIDATION_ERROR\"\n\t| \"NETWORK_ERROR\"\n\t| \"PLACE_ORDER_ERROR\";\n\nexport class FraudEngineError extends SdkError<FraudEngineErrorCode> {\n\tconstructor(\n\t\tmessage: string,\n\t\toptions: {\n\t\t\tcode: FraudEngineErrorCode;\n\t\t\tcause?: unknown;\n\t\t\tcontext?: Record<string, unknown>;\n\t\t},\n\t) {\n\t\tsuper(message, options);\n\t\tthis.name = \"FraudEngineError\";\n\t}\n}\n","import { bytesToBase64, hexToBytes } from \"../lib/encoding\";\nimport { FraudEngineError } from \"./errors\";\n\nexport async function getEncryptionKey(encryptionKeyHex: string): Promise<CryptoKey> {\n\tconst keyBytes = hexToBytes(encryptionKeyHex);\n\treturn crypto.subtle.importKey(\n\t\t\"raw\",\n\t\tkeyBytes.buffer as ArrayBuffer,\n\t\t{ name: \"AES-GCM\" },\n\t\tfalse,\n\t\t[\"encrypt\"],\n\t);\n}\n\nexport async function encryptPayload(\n\tpayload: string,\n\taad: string,\n\tencryptionKeyHex: string,\n): Promise<string> {\n\ttry {\n\t\tconst key = await getEncryptionKey(encryptionKeyHex);\n\t\tconst iv = crypto.getRandomValues(new Uint8Array(12));\n\t\tconst encoded = new TextEncoder().encode(payload);\n\t\tconst aadEncoded = new TextEncoder().encode(aad);\n\n\t\tconst ciphertext = await crypto.subtle.encrypt(\n\t\t\t{ name: \"AES-GCM\", iv, additionalData: aadEncoded, tagLength: 128 },\n\t\t\tkey,\n\t\t\tencoded,\n\t\t);\n\n\t\t// IV (12 bytes) + ciphertext + auth tag (16 bytes appended by Web Crypto)\n\t\tconst result = new Uint8Array(iv.length + ciphertext.byteLength);\n\t\tresult.set(iv, 0);\n\t\tresult.set(new Uint8Array(ciphertext), iv.length);\n\n\t\treturn bytesToBase64(result);\n\t} catch (cause) {\n\t\tthrow new FraudEngineError(\"Encryption failed\", {\n\t\t\tcode: \"ENCRYPTION_ERROR\",\n\t\t\tcause,\n\t\t});\n\t}\n}\n","import FingerprintJS from \"@fingerprintjs/fingerprintjs\";\n\nlet agent: Awaited<ReturnType<typeof FingerprintJS.load>> | null = null;\nlet cachedResult: { visitorId: string; confidence: number } | null = null;\n\nexport async function loadFingerprintAgent(): Promise<void> {\n\tif (agent) return;\n\tagent = await FingerprintJS.load();\n}\n\nexport async function getFingerprint(\n\ttimeoutMs = 5000,\n): Promise<{ visitorId: string; confidence: number } | null> {\n\tif (cachedResult) return cachedResult;\n\tif (!agent) {\n\t\ttry {\n\t\t\tawait loadFingerprintAgent();\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\tconst loadedAgent = agent;\n\tif (!loadedAgent) return null;\n\ttry {\n\t\tconst result = await Promise.race([\n\t\t\tloadedAgent.get(),\n\t\t\tnew Promise<never>((_, reject) =>\n\t\t\t\tsetTimeout(() => reject(new Error(\"FingerprintJS timed out\")), timeoutMs),\n\t\t\t),\n\t\t]);\n\t\tcachedResult = {\n\t\t\tvisitorId: result.visitorId,\n\t\t\tconfidence: result.confidence.score,\n\t\t};\n\t\treturn cachedResult;\n\t} catch {\n\t\treturn null;\n\t}\n}\n","import seon from \"@seontechnologies/seon-javascript-sdk\";\n\nlet initialized = false;\n\nexport function initSeon(): void {\n\tif (initialized) return;\n\tseon.init();\n\tinitialized = true;\n}\n\nexport async function getSeonSession(region: string): Promise<string | undefined> {\n\ttry {\n\t\treturn await seon.getSession({\n\t\t\tgeolocation: { canPrompt: false },\n\t\t\tnetworkTimeoutMs: 2000,\n\t\t\tfieldTimeoutMs: 2000,\n\t\t\tregion,\n\t\t\tsilentMode: true,\n\t\t});\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function cleanupSeonStorage(): void {\n\tif (typeof localStorage === \"undefined\") return;\n\tconst keysToRemove: string[] = [];\n\tfor (let i = 0; i < localStorage.length; i++) {\n\t\tconst key = localStorage.key(i);\n\t\tif (key?.startsWith(\"seon_session_sent_\")) keysToRemove.push(key);\n\t}\n\tfor (const key of keysToRemove) localStorage.removeItem(key);\n}\n","import { FraudEngineError } from \"./errors\";\nimport type { FraudEngineSigner } from \"./types\";\n\nexport async function getSignedHeaders(\n\tsigner: FraudEngineSigner,\n\taction: \"activity-log\" | \"link-order\" | \"fingerprint-log\",\n): Promise<Record<string, string>> {\n\t// The EIP-191 signed message is bound to the address of the key that\n\t// actually produces the signature (the admin EOA for AA smart wallets),\n\t// not to the tracked subject address. For plain EOA signers where no\n\t// separate `signerAddress` is provided, this falls back to `signer.address`\n\t// and behaviour is identical to the single-address case.\n\tconst signingAddress = (signer.signerAddress ?? signer.address).toLowerCase();\n\tconst timestamp = Math.floor(Date.now() / 1000).toString();\n\tconst message = `${action}:${signingAddress}:${timestamp}`;\n\n\ttry {\n\t\tconst signature = await signer.signMessage(message);\n\t\treturn {\n\t\t\t\"X-Signer-Address\": signingAddress,\n\t\t\t\"X-Timestamp\": timestamp,\n\t\t\t\"X-Signature\": signature,\n\t\t};\n\t} catch (cause) {\n\t\tthrow new FraudEngineError(\"Failed to sign message\", {\n\t\t\tcode: \"SIGNING_ERROR\",\n\t\t\tcause,\n\t\t});\n\t}\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport { z } from \"zod\";\nimport { FraudEngineError } from \"./errors\";\n\n// ── Config schema ──────────────────────────────────────────────────────\n\nexport const ZodFraudEngineConfigSchema = z.object({\n\tapiUrl: z.url(),\n\tencryptionKey: z.string().min(1),\n\tseonRegion: z.string().optional(),\n});\n\n// ── Buy order details schema ───────────────────────────────────────────\n\nexport const ZodBuyOrderDetailsSchema = z.object({\n\tcryptoAmount: z.number(),\n\tfiatAmount: z.number(),\n\tcurrency: z.string().min(1),\n\trecipientAddress: z.string().min(1),\n\tfee: z.number(),\n\tamountAfterFee: z.number(),\n\tpaymentMethod: z.string().optional(),\n\testimatedProcessingTime: z.string().optional(),\n});\n\n// ── User details schema ────────────────────────────────────────────────\n\nexport const ZodUserDetailsSchema = z.object({\n\tcurrency: z.string().optional(),\n\tcountry: z.string().optional(),\n\tlanguage: z.string().optional(),\n\tloginMethod: z.enum([\"email\", \"google\", \"phone\", \"passkey\", \"unknown\"]).optional(),\n\tloginEmail: z.string().optional(),\n\tloginPhone: z.string().optional(),\n});\n\n// ── Link order schema ──────────────────────────────────────────────────\n\nexport const ZodLinkOrderParamsSchema = z.object({\n\tactivityLogId: z.number().int().positive(),\n\torderId: z.string().min(1),\n});\n\n// ── Validate helper ────────────────────────────────────────────────────\n\nexport function validate<S extends z.ZodType>(\n\tschema: S,\n\tdata: unknown,\n): Result<z.infer<S>, FraudEngineError> {\n\tconst result = schema.safeParse(data);\n\tif (result.success) {\n\t\treturn ok(result.data as z.infer<S>);\n\t}\n\treturn err(\n\t\tnew FraudEngineError(z.prettifyError(result.error), {\n\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\tcause: result.error,\n\t\t\tcontext: { data },\n\t\t}),\n\t);\n}\n"],"mappings":"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","names":["import_neverthrow","import_neverthrow","FingerprintJS","seon","import_neverthrow","import_zod","validate","validate"]}
|