/** * Heuristic SMS transaction parser tuned for South-Asian, MENA, and global * banks, mobile wallets, UPI, and credit-card alerts. Implemented entirely in * TypeScript so callers can re-run it on raw SMS pulled from anywhere — not * just the live broadcast. * * The parser is intentionally **strict**: a message is treated as a * transaction only when it satisfies BOTH of these: * * 1. A past-tense, money-moved keyword (`debited`, `credited`, `deducted`, * `withdrawn`, `transferred to/from`, `received from/in`, `refunded`, * `deposited`, `added to your`, `credit alert`, `debit alert`, …). * 2. A currency-tagged numeric amount (`Rs. 500`, `PKR 1,250`, `₹500`, * `$12.34`, `1500 PKR`, `Rs.500/-`, …). * * Either condition alone is not enough — bills, balance reminders, low-credit * alerts, recharge nags, and promotional offers all routinely match one or * the other in isolation. Requiring both eliminates the entire "any SMS with * a digit gets flagged" failure mode. * * Public functions exported from this module: * - parseTransactionSms(raw) — strict transaction parse * - isLikelyTransactionSms(body) — fast strict gate (same rule) * - isLikelyOtpSms(body) — true for 2FA / OTP codes (excludes transaction confirmations) * - isLikelyPromotionalSms(body) — true for promo / marketing messages * - extractOtp(raw) — pull the OTP digits out, when present * - classifySms(raw) — coarse SmsCategory classifier * - normaliseBankCode(addr) — DLT short code → canonical bank id * - runParsers(raw, custom) — custom parsers ↦ built-in fallback */ import type { CustomParser, ParsedOtp, ParsedTransaction, RawSmsMessage, SmsCategory } from './ExpoTransactionSmsReader.types'; /** * Turn a sender id like `VK-HDFCBK` or `JM-JAZZCS-S` into a stable canonical * code (`HDFC`, `JAZZCASH`, …) using {@link SENDER_BANK_REGISTRY}. Returns * `null` when no entry matched. */ export declare function normaliseBankCode(address: string): string | null; /** * Strict gate — true iff the body has BOTH a strong past-tense transaction * verb AND a currency-tagged numeric amount. This is the single source of * truth used by the parser; "any SMS with digits" no longer passes. */ export declare function isLikelyTransactionSms(body: string): boolean; /** * Returns `true` if the SMS body is a one-time-password / 2FA code rather * than a transaction confirmation. * * The check is deliberately *narrow*: a message is OTP only when it both * (a) contains an OTP-specific label like "OTP", "verification code", "2FA", * and (b) does NOT contain a strong past-tense transaction verb. Bank * transaction SMS routinely include OTP-security boilerplate ("do not * share OTP") — those are transactions, not OTPs. */ export declare function isLikelyOtpSms(body: string): boolean; /** * Returns `true` when the body looks like a marketing / promotional SMS * (offers, lucky draws, recharge nags, application reminders) AND lacks * any strong transaction signal. * * "Get Rs. 100 cashback when you spend!" → `true` (promo, no past-tense verb) * "Rs. 100 credited as cashback. Use code SAVE10 next time." → `false` (real txn) */ export declare function isLikelyPromotionalSms(body: string): boolean; /** * Extract the OTP from a message body, when one is present. Returns `null` * when the SMS does not look like an OTP (including transaction * confirmations that happen to include OTP-warning boilerplate). */ export declare function extractOtp(raw: RawSmsMessage): ParsedOtp | null; /** * Coarse classification of an SMS. The order matters: * * 1. OTP wins first (excluding transaction confirmations). * 2. Strict transaction gate. * 3. Promotional gate. * 4. Everything else → OTHER. */ export declare function classifySms(raw: RawSmsMessage): SmsCategory; /** * Run the built-in heuristic parser on a single SMS. * * Returns `null` unless the body satisfies the strict gate (strong * past-tense verb + currency-tagged amount). Promotional and OTP messages * are also rejected. Callers that want every SMS — including non-financial * ones — should subscribe via `addSmsListener` and inspect `event.category` * directly instead of calling this function. */ export declare function parseTransactionSms(raw: RawSmsMessage): ParsedTransaction | null; /** * Run an array of custom parsers, falling back to {@link parseTransactionSms}. * The first parser to return a non-null value wins. */ export declare function runParsers(raw: RawSmsMessage, custom?: CustomParser[]): ParsedTransaction | null; //# sourceMappingURL=parser.d.ts.map