@nokinc-flur/sdk 1.0.4 → 1.0.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/index.cjs +352 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1343 -10
- package/dist/index.d.ts +1343 -10
- package/dist/index.js +334 -25
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/contracts.ts","../src/errors.ts","../src/primitives.ts","../src/nqr/fields.ts","../src/nqr/crc16.ts","../src/nqr/tlv.ts","../src/nqr/encoder.ts","../src/nqr/parser.ts","../src/nqr/routing.ts","../src/crypto/canonical.ts","../src/crypto/ct.ts","../src/crypto/ed25519.ts","../src/offline/oac.ts","../src/offline/codec.ts","../src/offline/messages.ts","../src/offline/settlements.ts","../src/auth/hmac.ts","../src/auth/middleware.ts","../src/passes/pass.ts","../src/passes/redemption.ts","../src/receipts/receipt.ts","../src/passes/client.ts","../src/receipts/client.ts","../src/client/flur.ts","../src/accounts/client.ts","../src/partner/client.ts"],"sourcesContent":["import { z, type ZodType } from \"zod\";\r\nimport {\r\n AccountSummaryResponseSchema,\r\n AuthLogoutRequestSchema,\r\n AuthRefreshRequestSchema,\r\n AuthRefreshResponseSchema,\r\n CreatePayLinkResponseSchema,\r\n CreateTransferRequestSchema,\r\n E164Regex,\r\n HealthResponseSchema,\r\n OkResponseSchema,\r\n OnboardingCompleteRequestSchema,\r\n OnboardingCompleteResponseSchema,\r\n OnboardingStartRequestSchema,\r\n OnboardingStartResponseSchema,\r\n PinSetRequestSchema,\r\n PinVerifyRequestSchema,\r\n PushRegisterRequestSchema,\r\n RegisterDeviceRequestSchema,\r\n RegisterDeviceResponseSchema,\r\n RegisterSendDeviceKeyRequestSchema,\r\n ResolvePayLinkResponseSchema,\r\n ResolveRecipientRequestSchema,\r\n ResolveRecipientResponseSchema,\r\n SendChallengeRequestSchema,\r\n SendChallengeResponseSchema,\r\n SendVerifyRequestSchema,\r\n SendVerifyResponseSchema,\r\n TransactionDetailResponseSchema,\r\n TransactionsListResponseSchema,\r\n TransferResponseSchema,\r\n WelcomeResponseSchema,\r\n} from \"./contracts.js\";\r\nimport { FlurError, mapToFlurError } from \"./errors.js\";\r\nimport { type Money, moneyMinorToNumber, normalizeE164 } from \"./primitives.js\";\r\n\r\nexport type FlurClientOptions = {\r\n baseUrl: string;\r\n fetchImpl?: typeof fetch;\r\n timeoutMs?: number;\r\n getExtraHeaders?: () => Record<string, string> | Promise<Record<string, string>>;\r\n};\r\n\r\nexport type OnboardingFallback = \"SILENT_AUTH\" | \"OTP\";\r\n\r\nexport type OnboardingStartInput = {\r\n phoneE164: string;\r\n appInstanceId: string;\r\n platform: \"android\" | \"ios\" | \"web\";\r\n turnstileToken?: string;\r\n appAttestation?: {\r\n provider: \"android\" | \"ios\" | \"web\";\r\n token: string;\r\n };\r\n firstName?: string;\r\n lastName?: string;\r\n};\r\n\r\nexport type OnboardingStartResponse = {\r\n requestId: string;\r\n checkUrl?: string;\r\n expiresInSec: number;\r\n fallback: OnboardingFallback;\r\n};\r\n\r\nexport type OnboardingRiskReason = \"SIM_SWAP_RECENT\" | \"ROAMING\" | \"CARRIER_CHANGED\";\r\n\r\nexport type OnboardingCompleteInput = {\r\n requestId: string;\r\n code: string;\r\n appInstanceId: string;\r\n fingerprintHash?: string;\r\n};\r\n\r\nexport type OnboardingCompleteResponse = {\r\n sessionToken: string;\r\n userId: string;\r\n restricted: boolean;\r\n risk_reasons: OnboardingRiskReason[];\r\n stepUpRequired?: boolean;\r\n riskStatus?: \"ok\" | \"unavailable\";\r\n};\r\n\r\nexport type RegisterDeviceInput = {\r\n userId: string;\r\n appInstanceId: string;\r\n platform: string;\r\n model?: string;\r\n networkSignals: {\r\n ip: string;\r\n asn?: number;\r\n country?: string;\r\n carrier?: string;\r\n };\r\n};\r\n\r\nexport type DeviceTrustState = \"TRUSTED_PRIMARY\" | \"TRUSTED_SECONDARY\" | \"UNVERIFIED\";\r\n\r\nexport type RegisterDeviceResponse = {\r\n deviceId: string;\r\n fingerprintHash: string;\r\n driftScore: number;\r\n trustState: DeviceTrustState;\r\n stepUpRequired: boolean;\r\n};\r\n\r\nexport type AuthRefreshInput = {\r\n userId: string;\r\n refreshToken: string;\r\n appInstanceId: string;\r\n fingerprintHash: string;\r\n};\r\n\r\nexport type AuthRefreshResponse = {\r\n refreshToken: string;\r\n stepUpRequired: boolean;\r\n};\r\n\r\nexport type AuthLogoutInput = {\r\n userId: string;\r\n refreshToken: string;\r\n};\r\n\r\nexport type PinSetInput = {\r\n userId: string;\r\n pin: string;\r\n};\r\n\r\nexport type PinVerifyInput = {\r\n userId: string;\r\n pin: string;\r\n};\r\n\r\nexport type RegisterSendDeviceKeyInput = {\r\n userId: string;\r\n deviceId: string;\r\n publicKey: string;\r\n};\r\n\r\nexport type SendChallengeInput = {\r\n userId: string;\r\n deviceId: string;\r\n};\r\n\r\nexport type SendChallengeResponse = {\r\n challengeId: string;\r\n nonce: string;\r\n expiresAt: string;\r\n};\r\n\r\nexport type SendVerifyInput = {\r\n userId: string;\r\n deviceId: string;\r\n challengeId: string;\r\n signature: string;\r\n};\r\n\r\nexport type SendVerifyResponse = {\r\n sendAuthToken: string;\r\n};\r\n\r\nexport type RecipientResolveInput = {\r\n identifier: string;\r\n};\r\n\r\nexport type RecipientResolveResponse = {\r\n recipientUserId: string;\r\n displayName: string;\r\n normalizedIdentifier: string;\r\n isActive: boolean;\r\n};\r\n\r\nexport type TransferInput = {\r\n recipientIdentifier: string;\r\n amountMinor: number;\r\n currency: string;\r\n sendAuthToken: string;\r\n};\r\n\r\nexport type TransferStatus = \"SETTLED\" | \"PENDING_REVIEW\" | \"DECLINED\";\r\n\r\nexport type TransferResponse = {\r\n transactionId: string;\r\n status: TransferStatus;\r\n userStatus: TransferStatus;\r\n recipientName: string;\r\n timestamp: string;\r\n};\r\n\r\nexport type TransactionDirection = \"OUTGOING\" | \"INCOMING\";\r\n\r\nexport type AccountActivityItem = {\r\n id: string;\r\n type: string;\r\n direction: TransactionDirection;\r\n name: string;\r\n identifier: string;\r\n amountMinor: number;\r\n currency: string;\r\n status: string;\r\n timestamp: string;\r\n};\r\n\r\nexport type AccountSummaryResponse = {\r\n balance: number;\r\n currency: string;\r\n dailySendLimit: number;\r\n dailySendRemaining: number;\r\n kycTier: string;\r\n kycStatus: string;\r\n recentActivity: AccountActivityItem[];\r\n};\r\n\r\nexport type TransactionsListResponse = {\r\n items: AccountActivityItem[];\r\n nextCursor: string | null;\r\n};\r\n\r\nexport type TransactionDetailResponse = {\r\n transactionId: string;\r\n type: string;\r\n direction: TransactionDirection;\r\n counterpartyName: string;\r\n counterpartyIdentifier: string;\r\n amountMinor: number;\r\n currency: string;\r\n status: string;\r\n timestamp: string;\r\n};\r\n\r\nexport type PushPlatform = \"ios\" | \"android\" | \"web\";\r\n\r\nexport type PushRegisterInput = {\r\n deviceId: string;\r\n platform: PushPlatform;\r\n token: string;\r\n};\r\n\r\nexport type CreatePayLinkResponse = {\r\n token: string;\r\n};\r\n\r\nexport type ResolvePayLinkResponse = {\r\n recipientUserId: string;\r\n displayName: string;\r\n normalizedIdentifier: string;\r\n isActive: boolean;\r\n};\r\n\r\nexport type AuthorizedOptions = {\r\n accessToken: string;\r\n};\r\n\r\nexport type CreateTransferOptions = AuthorizedOptions & {\r\n deviceId: string;\r\n idempotencyKey: string;\r\n};\r\n\r\nexport type ListTransactionsOptions = AuthorizedOptions & {\r\n cursor?: string;\r\n limit?: number;\r\n};\r\n\r\nexport type BiometricSigner = {\r\n getOrCreateKeyPair(deviceId: string): Promise<string>;\r\n sign(payload: string): Promise<string>;\r\n};\r\n\r\nexport type SendMoneyInput = {\r\n recipientIdentifier: string;\r\n money: Money;\r\n sendAuthToken: string;\r\n idempotencyKey?: string;\r\n defaultCountry?: string;\r\n};\r\n\r\nexport type SendMoneyOptions = AuthorizedOptions & {\r\n deviceId: string;\r\n};\r\n\r\nexport type AuthorizeSendWithBiometricInput = {\r\n userId: string;\r\n deviceId: string;\r\n accessToken: string;\r\n signer: BiometricSigner;\r\n};\r\n\r\nexport class FlurClient {\r\n private readonly baseUrl: string;\r\n private readonly fetchImpl: typeof fetch;\r\n private readonly timeoutMs: number;\r\n private readonly getExtraHeaders?: () => Record<string, string> | Promise<Record<string, string>>;\r\n\r\n constructor(opts: FlurClientOptions) {\r\n this.baseUrl = opts.baseUrl.replace(/\\/$/, \"\");\r\n this.fetchImpl = opts.fetchImpl ?? fetch;\r\n this.timeoutMs = opts.timeoutMs ?? 10_000;\r\n this.getExtraHeaders = opts.getExtraHeaders;\r\n }\r\n\r\n async health(): Promise<{ ok: boolean }> {\r\n return this.requestJson(\"/health\", { method: \"GET\" }, undefined, HealthResponseSchema);\r\n }\r\n\r\n async welcome(): Promise<{ message: string }> {\r\n return this.requestJson(\"/welcome\", { method: \"GET\" }, undefined, WelcomeResponseSchema);\r\n }\r\n\r\n async onboardingStart(input: OnboardingStartInput): Promise<OnboardingStartResponse> {\r\n return this.requestJson(\r\n \"/v1/onboarding/start\",\r\n {\r\n method: \"POST\",\r\n headers: { \"content-type\": \"application/json\" },\r\n },\r\n OnboardingStartRequestSchema,\r\n OnboardingStartResponseSchema,\r\n input\r\n );\r\n }\r\n\r\n async onboardingComplete(input: OnboardingCompleteInput): Promise<OnboardingCompleteResponse> {\r\n return this.requestJson(\r\n \"/v1/onboarding/complete\",\r\n {\r\n method: \"POST\",\r\n headers: { \"content-type\": \"application/json\" },\r\n },\r\n OnboardingCompleteRequestSchema,\r\n OnboardingCompleteResponseSchema,\r\n input\r\n );\r\n }\r\n\r\n async registerDevice(input: RegisterDeviceInput, options: AuthorizedOptions): Promise<RegisterDeviceResponse> {\r\n return this.requestJson(\r\n \"/v1/devices/register\",\r\n {\r\n method: \"POST\",\r\n headers: {\r\n \"content-type\": \"application/json\",\r\n authorization: `Bearer ${options.accessToken}`,\r\n },\r\n },\r\n RegisterDeviceRequestSchema,\r\n RegisterDeviceResponseSchema,\r\n input\r\n );\r\n }\r\n\r\n async authRefresh(input: AuthRefreshInput): Promise<AuthRefreshResponse> {\r\n return this.requestJson(\r\n \"/v1/auth/refresh\",\r\n {\r\n method: \"POST\",\r\n headers: { \"content-type\": \"application/json\" },\r\n },\r\n AuthRefreshRequestSchema,\r\n AuthRefreshResponseSchema,\r\n input\r\n );\r\n }\r\n\r\n async authLogout(input: AuthLogoutInput, options: AuthorizedOptions): Promise<{ ok: boolean }> {\r\n return this.requestJson(\r\n \"/v1/auth/logout\",\r\n {\r\n method: \"POST\",\r\n headers: {\r\n \"content-type\": \"application/json\",\r\n authorization: `Bearer ${options.accessToken}`,\r\n },\r\n },\r\n AuthLogoutRequestSchema,\r\n OkResponseSchema,\r\n input\r\n );\r\n }\r\n\r\n async pinSet(input: PinSetInput, options: AuthorizedOptions): Promise<{ ok: boolean }> {\r\n return this.requestJson(\r\n \"/v1/auth/pin/set\",\r\n {\r\n method: \"POST\",\r\n headers: {\r\n \"content-type\": \"application/json\",\r\n authorization: `Bearer ${options.accessToken}`,\r\n },\r\n },\r\n PinSetRequestSchema,\r\n OkResponseSchema,\r\n input\r\n );\r\n }\r\n\r\n async pinVerify(input: PinVerifyInput, options: AuthorizedOptions): Promise<{ ok: boolean }> {\r\n return this.requestJson(\r\n \"/v1/auth/pin/verify\",\r\n {\r\n method: \"POST\",\r\n headers: {\r\n \"content-type\": \"application/json\",\r\n authorization: `Bearer ${options.accessToken}`,\r\n },\r\n },\r\n PinVerifyRequestSchema,\r\n OkResponseSchema,\r\n input\r\n );\r\n }\r\n\r\n async registerSendDeviceKey(input: RegisterSendDeviceKeyInput, options: AuthorizedOptions): Promise<{ ok: boolean }> {\r\n return this.requestJson(\r\n \"/api/v1/auth/send/device-key\",\r\n {\r\n method: \"POST\",\r\n headers: {\r\n \"content-type\": \"application/json\",\r\n authorization: `Bearer ${options.accessToken}`,\r\n },\r\n },\r\n RegisterSendDeviceKeyRequestSchema,\r\n OkResponseSchema,\r\n input\r\n );\r\n }\r\n\r\n async createSendChallenge(input: SendChallengeInput, options: AuthorizedOptions): Promise<SendChallengeResponse> {\r\n return this.requestJson(\r\n \"/api/v1/auth/send/challenge\",\r\n {\r\n method: \"POST\",\r\n headers: {\r\n \"content-type\": \"application/json\",\r\n authorization: `Bearer ${options.accessToken}`,\r\n },\r\n },\r\n SendChallengeRequestSchema,\r\n SendChallengeResponseSchema,\r\n input\r\n );\r\n }\r\n\r\n async verifySendChallenge(input: SendVerifyInput, options: AuthorizedOptions): Promise<SendVerifyResponse> {\r\n return this.requestJson(\r\n \"/api/v1/auth/send/verify\",\r\n {\r\n method: \"POST\",\r\n headers: {\r\n \"content-type\": \"application/json\",\r\n authorization: `Bearer ${options.accessToken}`,\r\n },\r\n },\r\n SendVerifyRequestSchema,\r\n SendVerifyResponseSchema,\r\n input\r\n );\r\n }\r\n\r\n async registerBiometricDeviceKey(input: {\r\n userId: string;\r\n deviceId: string;\r\n accessToken: string;\r\n signer: BiometricSigner;\r\n }): Promise<{ ok: boolean }> {\r\n const publicKey = await input.signer.getOrCreateKeyPair(input.deviceId);\r\n return this.registerSendDeviceKey({\r\n userId: input.userId,\r\n deviceId: input.deviceId,\r\n publicKey,\r\n }, { accessToken: input.accessToken });\r\n }\r\n\r\n async authorizeSendWithBiometric(input: AuthorizeSendWithBiometricInput): Promise<SendVerifyResponse> {\r\n const challenge = await this.createSendChallenge({\r\n userId: input.userId,\r\n deviceId: input.deviceId,\r\n }, { accessToken: input.accessToken });\r\n\r\n const signature = await input.signer.sign(challenge.nonce);\r\n return this.verifySendChallenge({\r\n userId: input.userId,\r\n deviceId: input.deviceId,\r\n challengeId: challenge.challengeId,\r\n signature,\r\n }, { accessToken: input.accessToken });\r\n }\r\n\r\n async resolveRecipient(input: RecipientResolveInput, options: AuthorizedOptions): Promise<RecipientResolveResponse> {\r\n return this.requestJson(\r\n \"/api/v1/recipients/resolve\",\r\n {\r\n method: \"POST\",\r\n headers: {\r\n \"content-type\": \"application/json\",\r\n authorization: `Bearer ${options.accessToken}`,\r\n },\r\n },\r\n ResolveRecipientRequestSchema,\r\n ResolveRecipientResponseSchema,\r\n input\r\n );\r\n }\r\n\r\n async createTransfer(input: TransferInput, options: CreateTransferOptions): Promise<TransferResponse> {\r\n return this.requestJson(\r\n \"/api/v1/transfers\",\r\n {\r\n method: \"POST\",\r\n headers: {\r\n \"content-type\": \"application/json\",\r\n authorization: `Bearer ${options.accessToken}`,\r\n \"x-device-id\": options.deviceId,\r\n \"x-idempotency-key\": options.idempotencyKey,\r\n },\r\n },\r\n CreateTransferRequestSchema,\r\n TransferResponseSchema,\r\n input\r\n );\r\n }\r\n\r\n async sendMoney(input: SendMoneyInput, options: SendMoneyOptions): Promise<TransferResponse> {\r\n const normalizedRecipient = E164Regex.test(input.recipientIdentifier)\r\n ? input.recipientIdentifier\r\n : normalizeE164(input.recipientIdentifier, input.defaultCountry);\r\n\r\n const idempotencyKey = input.idempotencyKey ?? getSecureRandomUuid();\r\n return this.createTransfer(\r\n {\r\n recipientIdentifier: normalizedRecipient,\r\n amountMinor: moneyMinorToNumber(input.money.amountMinor),\r\n currency: input.money.currency,\r\n sendAuthToken: input.sendAuthToken,\r\n },\r\n {\r\n accessToken: options.accessToken,\r\n deviceId: options.deviceId,\r\n idempotencyKey,\r\n }\r\n );\r\n }\r\n\r\n async accountSummary(options: AuthorizedOptions): Promise<AccountSummaryResponse> {\r\n return this.requestJson(\r\n \"/api/v1/account/summary\",\r\n {\r\n method: \"GET\",\r\n headers: {\r\n authorization: `Bearer ${options.accessToken}`,\r\n },\r\n },\r\n undefined,\r\n AccountSummaryResponseSchema\r\n );\r\n }\r\n\r\n async listTransactions(options: ListTransactionsOptions): Promise<TransactionsListResponse> {\r\n const query = new URLSearchParams();\r\n if (typeof options.cursor === \"string\" && options.cursor.trim().length > 0) {\r\n query.set(\"cursor\", options.cursor);\r\n }\r\n if (typeof options.limit === \"number\") {\r\n query.set(\"limit\", String(options.limit));\r\n }\r\n\r\n const path = query.size > 0 ? `/api/v1/transactions?${query.toString()}` : \"/api/v1/transactions\";\r\n return this.requestJson(\r\n path,\r\n {\r\n method: \"GET\",\r\n headers: {\r\n authorization: `Bearer ${options.accessToken}`,\r\n },\r\n },\r\n undefined,\r\n TransactionsListResponseSchema\r\n );\r\n }\r\n\r\n async transactionDetail(transactionId: string, options: AuthorizedOptions): Promise<TransactionDetailResponse> {\r\n const encodedId = encodeURIComponent(transactionId);\r\n return this.requestJson(\r\n `/api/v1/transactions/${encodedId}`,\r\n {\r\n method: \"GET\",\r\n headers: {\r\n authorization: `Bearer ${options.accessToken}`,\r\n },\r\n },\r\n undefined,\r\n TransactionDetailResponseSchema\r\n );\r\n }\r\n\r\n async registerPushToken(input: PushRegisterInput, options: AuthorizedOptions): Promise<{ ok: boolean }> {\r\n return this.requestJson(\r\n \"/api/v1/push/register\",\r\n {\r\n method: \"POST\",\r\n headers: {\r\n \"content-type\": \"application/json\",\r\n authorization: `Bearer ${options.accessToken}`,\r\n },\r\n },\r\n PushRegisterRequestSchema,\r\n OkResponseSchema,\r\n input\r\n );\r\n }\r\n\r\n async createPayLink(options: AuthorizedOptions): Promise<CreatePayLinkResponse> {\r\n return this.requestJson(\r\n \"/api/v1/pay-links\",\r\n {\r\n method: \"POST\",\r\n headers: {\r\n authorization: `Bearer ${options.accessToken}`,\r\n },\r\n },\r\n undefined,\r\n CreatePayLinkResponseSchema,\r\n );\r\n }\r\n\r\n async resolvePayLink(token: string, options: AuthorizedOptions): Promise<ResolvePayLinkResponse> {\r\n const encodedToken = encodeURIComponent(token);\r\n return this.requestJson(\r\n `/api/v1/pay-links/${encodedToken}`,\r\n {\r\n method: \"GET\",\r\n headers: {\r\n authorization: `Bearer ${options.accessToken}`,\r\n },\r\n },\r\n undefined,\r\n ResolvePayLinkResponseSchema,\r\n );\r\n }\r\n\r\n private async requestJson<TInput, TOutput>(\r\n path: string,\r\n init: RequestInit,\r\n requestSchema?: ZodType<TInput>,\r\n responseSchema?: ZodType<TOutput>,\r\n input?: TInput\r\n ): Promise<TOutput> {\r\n const url = `${this.baseUrl}${path}`;\r\n const controller = new AbortController();\r\n const t = setTimeout(() => controller.abort(), this.timeoutMs);\r\n let body = init.body;\r\n try {\r\n body = requestSchema ? JSON.stringify(requestSchema.parse(input)) : init.body;\r\n } catch (err: unknown) {\r\n if (err instanceof z.ZodError) {\r\n throw new FlurError(\"Invalid request payload\", \"INVALID_REQUEST\", {\r\n details: err.flatten(),\r\n });\r\n }\r\n throw err;\r\n }\r\n\r\n try {\r\n let extraHeaders: Record<string, string> = {};\r\n if (this.getExtraHeaders) {\r\n extraHeaders = await this.getExtraHeaders();\r\n }\r\n\r\n const finalHeaders = {\r\n ...init.headers,\r\n ...extraHeaders,\r\n };\r\n\r\n const res = await this.fetchImpl(url, { ...init, headers: finalHeaders, body, signal: controller.signal });\r\n if (!res.ok) throw await mapToFlurError(res);\r\n const payload = (await res.json()) as unknown;\r\n if (!responseSchema) return payload as TOutput;\r\n try {\r\n return responseSchema.parse(payload);\r\n } catch (err: unknown) {\r\n if (err instanceof z.ZodError) {\r\n throw new FlurError(\"SDK contract validation failed\", \"INVALID_REQUEST\", {\r\n details: err.flatten(),\r\n });\r\n }\r\n throw err;\r\n }\r\n } catch (err: unknown) {\r\n if (err instanceof Error && err.name === \"AbortError\") {\r\n throw new FlurError(\"Request timed out\", \"TIMEOUT\");\r\n }\r\n if (err instanceof FlurError) throw err;\r\n throw new FlurError(\"Network error\", \"NETWORK_ERROR\", { details: String(err) });\r\n } finally {\r\n clearTimeout(t);\r\n }\r\n }\r\n}\r\n\r\nfunction getSecureRandomUuid(): string {\r\n if (typeof globalThis.crypto?.randomUUID === \"function\") {\r\n return globalThis.crypto.randomUUID();\r\n }\r\n throw new FlurError(\"Secure UUID generator unavailable; provide idempotencyKey\", \"INVALID_REQUEST\");\r\n}\r\n","import { z } from \"zod\";\r\n\r\nexport const E164Regex = /^\\+[1-9]\\d{7,14}$/;\r\n\r\nconst UuidSchema = z.string().uuid();\r\nconst IsoDateSchema = z.string().datetime({ offset: true });\r\nconst CurrencySchema = z.string().trim().length(3).transform((value) => value.toUpperCase());\r\n\r\nexport const HealthResponseSchema = z.object({\r\n ok: z.boolean(),\r\n});\r\n\r\nexport const WelcomeResponseSchema = z.object({\r\n message: z.string(),\r\n});\r\n\r\nexport const OnboardingStartRequestSchema = z.object({\r\n phoneE164: z.string().regex(E164Regex),\r\n appInstanceId: z.string().min(3),\r\n platform: z.enum([\"android\", \"ios\", \"web\"]),\r\n turnstileToken: z.string().min(20).optional(),\r\n appAttestation: z\r\n .object({\r\n provider: z.enum([\"android\", \"ios\", \"web\"]),\r\n token: z.string().min(24),\r\n })\r\n .optional(),\r\n firstName: z.string().trim().min(1).max(80).optional(),\r\n lastName: z.string().trim().min(1).max(80).optional(),\r\n});\r\n\r\nexport const OnboardingStartResponseSchema = z.object({\r\n requestId: z.string().min(1),\r\n checkUrl: z.string().url().optional(),\r\n expiresInSec: z.number().int().positive(),\r\n fallback: z.enum([\"SILENT_AUTH\", \"OTP\"]),\r\n});\r\n\r\nexport const OnboardingCompleteRequestSchema = z.object({\r\n requestId: z.string().min(1),\r\n code: z.string().min(1).max(32),\r\n appInstanceId: z.string().min(3),\r\n fingerprintHash: z.string().min(3).optional(),\r\n});\r\n\r\nexport const OnboardingCompleteResponseSchema = z.object({\r\n sessionToken: z.string().min(1),\r\n userId: UuidSchema,\r\n restricted: z.boolean(),\r\n risk_reasons: z.array(z.enum([\"SIM_SWAP_RECENT\", \"ROAMING\", \"CARRIER_CHANGED\"])),\r\n stepUpRequired: z.boolean().optional(),\r\n riskStatus: z.enum([\"ok\", \"unavailable\"]).optional(),\r\n});\r\n\r\nexport const RegisterDeviceRequestSchema = z.object({\r\n userId: UuidSchema,\r\n appInstanceId: z.string().min(3),\r\n platform: z.string().min(2),\r\n model: z.string().optional(),\r\n networkSignals: z.object({\r\n ip: z.string().min(3),\r\n asn: z.number().int().optional(),\r\n country: z.string().min(2).optional(),\r\n carrier: z.string().optional(),\r\n }),\r\n});\r\n\r\nexport const RegisterDeviceResponseSchema = z.object({\r\n deviceId: z.string().min(1),\r\n fingerprintHash: z.string().min(1),\r\n driftScore: z.number(),\r\n trustState: z.enum([\"TRUSTED_PRIMARY\", \"TRUSTED_SECONDARY\", \"UNVERIFIED\"]),\r\n stepUpRequired: z.boolean(),\r\n});\r\n\r\nexport const AuthRefreshRequestSchema = z.object({\r\n userId: UuidSchema,\r\n refreshToken: z.string().min(8),\r\n appInstanceId: z.string().min(3),\r\n fingerprintHash: z.string().min(3),\r\n});\r\n\r\nexport const AuthRefreshResponseSchema = z.object({\r\n refreshToken: z.string().min(8),\r\n stepUpRequired: z.boolean(),\r\n});\r\n\r\nexport const AuthLogoutRequestSchema = z.object({\r\n userId: UuidSchema,\r\n refreshToken: z.string().min(8),\r\n});\r\n\r\nexport const PinSetRequestSchema = z.object({\r\n userId: UuidSchema,\r\n pin: z.string().regex(/^\\d{6}$/),\r\n});\r\n\r\nexport const PinVerifyRequestSchema = z.object({\r\n userId: UuidSchema,\r\n pin: z.string().regex(/^\\d{6}$/),\r\n});\r\n\r\nexport const OkResponseSchema = z.object({\r\n ok: z.boolean(),\r\n});\r\n\r\nexport const RegisterSendDeviceKeyRequestSchema = z.object({\r\n userId: UuidSchema,\r\n deviceId: z.string().min(3),\r\n publicKey: z.string().min(32),\r\n});\r\n\r\nexport const SendChallengeRequestSchema = z.object({\r\n userId: UuidSchema,\r\n deviceId: z.string().min(3),\r\n});\r\n\r\nexport const SendChallengeResponseSchema = z.object({\r\n challengeId: UuidSchema,\r\n nonce: z.string().min(1),\r\n expiresAt: IsoDateSchema,\r\n});\r\n\r\nexport const SendVerifyRequestSchema = z.object({\r\n userId: UuidSchema,\r\n deviceId: z.string().min(3),\r\n challengeId: UuidSchema,\r\n signature: z.string().min(16),\r\n});\r\n\r\nexport const SendVerifyResponseSchema = z.object({\r\n sendAuthToken: z.string().min(16),\r\n});\r\n\r\nexport const ResolveRecipientRequestSchema = z.object({\r\n identifier: z.string().min(3),\r\n});\r\n\r\nexport const ResolveRecipientResponseSchema = z.object({\r\n recipientUserId: UuidSchema,\r\n displayName: z.string().min(1),\r\n normalizedIdentifier: z.string().regex(E164Regex),\r\n isActive: z.boolean(),\r\n});\r\n\r\nexport const CreateTransferRequestSchema = z.object({\r\n recipientIdentifier: z.string().min(3),\r\n amountMinor: z.number().int().positive(),\r\n currency: CurrencySchema,\r\n sendAuthToken: z.string().min(16),\r\n});\r\n\r\nconst TransferStatusSchema = z.enum([\"SETTLED\", \"PENDING_REVIEW\", \"DECLINED\"]);\r\n\r\nexport const TransferResponseSchema = z.object({\r\n transactionId: z.string().min(1),\r\n status: TransferStatusSchema,\r\n userStatus: TransferStatusSchema,\r\n recipientName: z.string().min(1),\r\n timestamp: IsoDateSchema,\r\n});\r\n\r\nconst DirectionSchema = z.enum([\"OUTGOING\", \"INCOMING\"]);\r\n\r\nexport const AccountActivityItemSchema = z.object({\r\n id: z.string().min(1),\r\n type: z.string().min(1),\r\n direction: DirectionSchema,\r\n name: z.string().min(1),\r\n identifier: z.string().min(1),\r\n amountMinor: z.number().int(),\r\n currency: CurrencySchema,\r\n status: z.string().min(1),\r\n timestamp: IsoDateSchema,\r\n});\r\n\r\nexport const AccountSummaryResponseSchema = z.object({\r\n balance: z.number().int(),\r\n currency: CurrencySchema,\r\n dailySendLimit: z.number().int().nonnegative(),\r\n dailySendRemaining: z.number().int().nonnegative(),\r\n kycTier: z.string().min(1),\r\n kycStatus: z.string().min(1),\r\n recentActivity: z.array(AccountActivityItemSchema),\r\n});\r\n\r\nexport const TransactionsListResponseSchema = z.object({\r\n items: z.array(AccountActivityItemSchema),\r\n nextCursor: z.string().nullable(),\r\n});\r\n\r\nexport const TransactionDetailResponseSchema = z.object({\r\n transactionId: z.string().min(1),\r\n type: z.string().min(1),\r\n direction: DirectionSchema,\r\n counterpartyName: z.string().min(1),\r\n counterpartyIdentifier: z.string().min(1),\r\n amountMinor: z.number().int(),\r\n currency: CurrencySchema,\r\n status: z.string().min(1),\r\n timestamp: IsoDateSchema,\r\n});\r\n\r\nexport const PushRegisterRequestSchema = z.object({\r\n deviceId: z.string().min(3),\r\n platform: z.enum([\"ios\", \"android\", \"web\"]),\r\n token: z.string().min(16),\r\n});\r\n\r\nexport const CreatePayLinkResponseSchema = z.object({\r\n token: z.string().min(1),\r\n});\r\n\r\nexport const ResolvePayLinkResponseSchema = z.object({\r\n recipientUserId: UuidSchema,\r\n displayName: z.string().min(1),\r\n normalizedIdentifier: z.string().regex(E164Regex),\r\n isActive: z.boolean(),\r\n});\r\n","export type FlurErrorCode =\n | 'NETWORK_ERROR'\n | 'HTTP_ERROR'\n | 'TIMEOUT'\n | 'UNKNOWN'\n | 'UNAUTHORIZED'\n | 'INVALID_REQUEST'\n | 'RATE_LIMITED'\n | 'NOT_FOUND'\n | 'USER_NOT_FOUND'\n | 'TOKEN_REPLAYED'\n | 'SESSION_MISMATCH'\n | 'PIN_INVALID'\n | 'PIN_LOCKED'\n | 'PIN_NOT_SET'\n | 'STEP_UP_REQUIRED'\n | 'DEVICE_KEY_NOT_REGISTERED'\n | 'CHALLENGE_INVALID'\n | 'CHALLENGE_EXPIRED'\n | 'DEVICE_KEY_REVOKED'\n | 'SIGNATURE_INVALID'\n | 'INVALID_RECIPIENT'\n | 'SEND_AUTH_INVALID'\n | 'IDEMPOTENCY_KEY_CONFLICT'\n | 'IDEMPOTENCY_IN_PROGRESS'\n | 'CANNOT_SEND_TO_SELF'\n | 'INSUFFICIENT_FUNDS';\n\nconst backendErrorCodeSet: ReadonlySet<FlurErrorCode> = new Set([\n 'UNAUTHORIZED',\n 'INVALID_REQUEST',\n 'RATE_LIMITED',\n 'NOT_FOUND',\n 'USER_NOT_FOUND',\n 'TOKEN_REPLAYED',\n 'SESSION_MISMATCH',\n 'PIN_INVALID',\n 'PIN_LOCKED',\n 'PIN_NOT_SET',\n 'STEP_UP_REQUIRED',\n 'DEVICE_KEY_NOT_REGISTERED',\n 'CHALLENGE_INVALID',\n 'CHALLENGE_EXPIRED',\n 'DEVICE_KEY_REVOKED',\n 'SIGNATURE_INVALID',\n 'INVALID_RECIPIENT',\n 'SEND_AUTH_INVALID',\n 'IDEMPOTENCY_KEY_CONFLICT',\n 'IDEMPOTENCY_IN_PROGRESS',\n 'CANNOT_SEND_TO_SELF',\n 'INSUFFICIENT_FUNDS',\n]);\n\nexport class FlurError extends Error {\n public readonly code: FlurErrorCode;\n public readonly status?: number;\n public readonly details?: unknown;\n public readonly reqId?: string | null;\n\n constructor(\n message: string,\n code: FlurErrorCode,\n opts?: { status?: number; details?: unknown; reqId?: string | null },\n ) {\n super(message);\n this.name = 'FlurError';\n this.code = code;\n this.status = opts?.status;\n this.details = opts?.details;\n this.reqId = opts?.reqId;\n }\n}\n\n/**\n * Generic API error thrown by HTTP clients in `flur.passes` / `flur.receipts`\n * for non-2xx responses. Lives at the SDK root so bounded-context modules\n * (passes, receipts) never cross-import each other.\n */\nexport class FlurApiError extends Error {\n constructor(\n public readonly status: number,\n public readonly code: string,\n message: string,\n public readonly raw?: unknown,\n ) {\n super(message);\n this.name = 'FlurApiError';\n }\n}\n\n/** Thrown by `buildRedemption` when the pass is past its `validUntilMs`. */\nexport class FlurExpiredError extends Error {\n public readonly code = 'PASS_EXPIRED' as const;\n constructor(message = 'pass is expired') {\n super(message);\n this.name = 'FlurExpiredError';\n }\n}\n\n/** Thrown by `buildRedemption` when `counter` is not strictly greater than the\n * caller-supplied `lastSeenCounter` (replay / out-of-order redemption attempt). */\nexport class FlurReplayError extends Error {\n public readonly code = 'PASS_REPLAY' as const;\n constructor(message = 'redemption counter is not strictly increasing') {\n super(message);\n this.name = 'FlurReplayError';\n }\n}\n\n/** Thrown by `buildRedemption` when this redemption would breach the pass's\n * `cumulativeCapKobo` given the caller-supplied `cumulativeUsedKobo`. */\nexport class FlurCapExceededError extends Error {\n public readonly code = 'PASS_CAP_EXCEEDED' as const;\n constructor(message = 'redemption exceeds cumulative cap') {\n super(message);\n this.name = 'FlurCapExceededError';\n }\n}\n\nexport async function mapToFlurError(res: Response): Promise<FlurError> {\n const reqId = res.headers.get('x-request-id');\n let details: unknown = undefined;\n let mappedCode: FlurErrorCode = 'HTTP_ERROR';\n let mappedMessage = `HTTP ${res.status}`;\n try {\n const ct = res.headers.get('content-type') ?? '';\n details = ct.includes('application/json')\n ? await res.json()\n : await res.text();\n if (details && typeof details === 'object') {\n const candidateCode = (details as { code?: unknown }).code;\n const candidateMessage = (\n details as { message?: unknown; error?: unknown }\n ).message;\n const fallbackMessage = (details as { error?: unknown }).error;\n\n if (\n typeof candidateCode === 'string' &&\n backendErrorCodeSet.has(candidateCode as FlurErrorCode)\n ) {\n mappedCode = candidateCode as FlurErrorCode;\n }\n\n if (typeof candidateMessage === 'string' && candidateMessage.length > 0) {\n mappedMessage = candidateMessage;\n } else if (\n typeof fallbackMessage === 'string' &&\n fallbackMessage.length > 0\n ) {\n mappedMessage = fallbackMessage;\n }\n }\n } catch {\n // ignore parse issues\n }\n return new FlurError(mappedMessage, mappedCode, {\n status: res.status,\n details,\n reqId,\n });\n}\n","import { z } from \"zod\";\r\nimport { FlurError } from \"./errors.js\";\r\nimport { E164Regex } from \"./contracts.js\";\r\n\r\nexport type Money = {\r\n amountMinor: bigint;\r\n currency: string;\r\n};\r\n\r\nconst CurrencyCodeSchema = z.string().trim().length(3).transform((value) => value.toUpperCase());\r\n\r\nconst currencyFractionDigits: Record<string, number> = {\r\n NGN: 2,\r\n USD: 2,\r\n EUR: 2,\r\n GBP: 2,\r\n CAD: 2,\r\n JPY: 0,\r\n};\r\n\r\nfunction getFractionDigits(currency: string): number {\r\n return currencyFractionDigits[currency] ?? 2;\r\n}\r\n\r\nexport function parseAmountInput(value: string, currency: string): Money {\r\n const normalizedCurrency = CurrencyCodeSchema.parse(currency);\r\n const raw = value.trim();\r\n\r\n if (!/^\\d+(\\.\\d+)?$/.test(raw)) {\r\n throw new FlurError(\"Invalid amount format\", \"INVALID_REQUEST\");\r\n }\r\n\r\n const [whole, fraction = \"\"] = raw.split(\".\");\r\n const fractionDigits = getFractionDigits(normalizedCurrency);\r\n\r\n if (fraction.length > fractionDigits) {\r\n throw new FlurError(\"Too many decimal places for currency\", \"INVALID_REQUEST\");\r\n }\r\n\r\n const paddedFraction = fraction.padEnd(fractionDigits, \"0\");\r\n const minorAsString = `${whole}${paddedFraction}`.replace(/^0+(\\d)/, \"$1\") || \"0\";\r\n const amountMinor = BigInt(minorAsString);\r\n\r\n if (amountMinor < 0n) {\r\n throw new FlurError(\"Amount cannot be negative\", \"INVALID_REQUEST\");\r\n }\r\n\r\n return {\r\n amountMinor,\r\n currency: normalizedCurrency,\r\n };\r\n}\r\n\r\nexport function formatAmount(amountMinor: bigint, currency: string): string {\r\n const normalizedCurrency = CurrencyCodeSchema.parse(currency);\r\n if (amountMinor < 0n) {\r\n throw new FlurError(\"Amount cannot be negative\", \"INVALID_REQUEST\");\r\n }\r\n\r\n const fractionDigits = getFractionDigits(normalizedCurrency);\r\n if (fractionDigits === 0) {\r\n return amountMinor.toString();\r\n }\r\n\r\n const divisor = 10n ** BigInt(fractionDigits);\r\n const whole = amountMinor / divisor;\r\n const fraction = (amountMinor % divisor).toString().padStart(fractionDigits, \"0\");\r\n return `${whole.toString()}.${fraction}`;\r\n}\r\n\r\nconst defaultCountryDialingCode: Record<string, string> = {\r\n NG: \"234\",\r\n US: \"1\",\r\n CA: \"1\",\r\n GB: \"44\",\r\n};\r\n\r\nexport function normalizeE164(input: string, defaultCountry?: string): string {\r\n const trimmed = input.trim();\r\n\r\n if (trimmed.startsWith(\"+\")) {\r\n if (!E164Regex.test(trimmed)) {\r\n throw new FlurError(\"Invalid phone number\", \"INVALID_REQUEST\");\r\n }\r\n return trimmed;\r\n }\r\n\r\n const digits = trimmed.replace(/\\D/g, \"\");\r\n if (digits.length === 0) {\r\n throw new FlurError(\"Invalid phone number\", \"INVALID_REQUEST\");\r\n }\r\n\r\n if (digits.startsWith(\"00\")) {\r\n const candidate = `+${digits.slice(2)}`;\r\n if (!E164Regex.test(candidate)) {\r\n throw new FlurError(\"Invalid phone number\", \"INVALID_REQUEST\");\r\n }\r\n return candidate;\r\n }\r\n\r\n const normalizedCountry = defaultCountry?.trim().toUpperCase();\r\n const countryCode = normalizedCountry ? defaultCountryDialingCode[normalizedCountry] : undefined;\r\n if (!countryCode) {\r\n throw new FlurError(\"Invalid phone number\", \"INVALID_REQUEST\");\r\n }\r\n\r\n const localDigits = digits.startsWith(\"0\") ? digits.slice(1) : digits;\r\n const candidate = `+${countryCode}${localDigits}`;\r\n if (!E164Regex.test(candidate)) {\r\n throw new FlurError(\"Invalid phone number\", \"INVALID_REQUEST\");\r\n }\r\n return candidate;\r\n}\r\n\r\nexport function moneyMinorToNumber(amountMinor: bigint): number {\r\n const asNumber = Number(amountMinor);\r\n if (!Number.isSafeInteger(asNumber)) {\r\n throw new FlurError(\"Amount exceeds safe integer range\", \"INVALID_REQUEST\");\r\n }\r\n return asNumber;\r\n}\r\n","/**\n * EMV / NQR Merchant-Presented top-level field IDs.\n * See EMVCo MPM v1.1 §4 and NIBSS NQR specification.\n */\nexport const FIELD = {\n PAYLOAD_FORMAT_INDICATOR: '00',\n POINT_OF_INITIATION: '01',\n // 02..51 — Merchant Account Information templates (issuer-specific)\n MERCHANT_CATEGORY_CODE: '52',\n TRANSACTION_CURRENCY: '53',\n TRANSACTION_AMOUNT: '54',\n TIP_OR_CONVENIENCE_INDICATOR: '55',\n VALUE_CONVENIENCE_FEE_FIXED: '56',\n VALUE_CONVENIENCE_FEE_PERCENT: '57',\n COUNTRY_CODE: '58',\n MERCHANT_NAME: '59',\n MERCHANT_CITY: '60',\n POSTAL_CODE: '61',\n ADDITIONAL_DATA_FIELD: '62',\n CRC: '63',\n MERCHANT_INFO_LANGUAGE: '64',\n // 80..99 — Unreserved Templates\n} as const;\n\nexport const ADDITIONAL_DATA_SUBFIELD = {\n BILL_NUMBER: '01',\n MOBILE_NUMBER: '02',\n STORE_LABEL: '03',\n LOYALTY_NUMBER: '04',\n REFERENCE_LABEL: '05',\n CUSTOMER_LABEL: '06',\n TERMINAL_LABEL: '07',\n PURPOSE_OF_TRANSACTION: '08',\n} as const;\n\nexport const POINT_OF_INITIATION = {\n STATIC: '11',\n DYNAMIC: '12',\n} as const;\n\nexport const PAYLOAD_FORMAT_INDICATOR_VALUE = '01';\nexport const NGN_CURRENCY_CODE = '566';\nexport const NG_COUNTRY_CODE = 'NG';\nexport const CRC_TAG_PREFIX = '6304'; // tag 63 + length 04\n","/**\n * CRC-16/CCITT-FALSE — polynomial 0x1021, initial 0xFFFF, no reflection,\n * no XOR-out. Specified by EMVCo MPM for tag 63 (CRC).\n */\nexport function crc16ccitt(bytes: Uint8Array): number {\n let crc = 0xffff;\n for (let i = 0; i < bytes.length; i++) {\n crc ^= bytes[i] << 8;\n for (let j = 0; j < 8; j++) {\n if (crc & 0x8000) {\n crc = (crc << 1) ^ 0x1021;\n } else {\n crc <<= 1;\n }\n crc &= 0xffff;\n }\n }\n return crc;\n}\n\nexport function crc16ccittHex(bytes: Uint8Array): string {\n return crc16ccitt(bytes).toString(16).toUpperCase().padStart(4, '0');\n}\n","/**\n * EMV TLV (Tag-Length-Value) primitives.\n * - Tag is 2 ASCII digits.\n * - Length is 2 ASCII digits (00..99).\n * - Value is up to 99 ASCII characters.\n */\n\nexport type TLVField = { tag: string; value: string };\n\nexport function writeTLV(tag: string, value: string): string {\n if (!/^\\d{2}$/.test(tag)) {\n throw new Error(`TLV: tag must be 2 digits, got \"${tag}\"`);\n }\n if (value.length > 99) {\n throw new Error(\n `TLV: value for tag ${tag} exceeds 99 chars (${value.length})`,\n );\n }\n const len = value.length.toString().padStart(2, '0');\n return `${tag}${len}${value}`;\n}\n\nexport function readTLV(buf: string): TLVField[] {\n const out: TLVField[] = [];\n let i = 0;\n while (i < buf.length) {\n if (i + 4 > buf.length) {\n throw new Error(`TLV: truncated header at offset ${i}`);\n }\n const tag = buf.slice(i, i + 2);\n const lenStr = buf.slice(i + 2, i + 4);\n if (!/^\\d{2}$/.test(tag)) {\n throw new Error(`TLV: bad tag \"${tag}\" at offset ${i}`);\n }\n if (!/^\\d{2}$/.test(lenStr)) {\n throw new Error(`TLV: bad length \"${lenStr}\" at offset ${i + 2}`);\n }\n const len = parseInt(lenStr, 10);\n const valStart = i + 4;\n const valEnd = valStart + len;\n if (valEnd > buf.length) {\n throw new Error(\n `TLV: truncated value for tag ${tag} at offset ${valStart}`,\n );\n }\n out.push({ tag, value: buf.slice(valStart, valEnd) });\n i = valEnd;\n }\n return out;\n}\n","import {\n ADDITIONAL_DATA_SUBFIELD,\n CRC_TAG_PREFIX,\n FIELD,\n NGN_CURRENCY_CODE,\n NG_COUNTRY_CODE,\n PAYLOAD_FORMAT_INDICATOR_VALUE,\n POINT_OF_INITIATION,\n} from './fields.js';\nimport { crc16ccittHex } from './crc16.js';\nimport { writeTLV } from './tlv.js';\nimport type {\n AdditionalData,\n MerchantAccountInfo,\n NQRPayloadInput,\n} from './types.js';\n\nconst ASCII_PRINTABLE = /^[\\x20-\\x7E]*$/;\n\n/** Build the inner content of a Merchant Account Information template. */\nfunction buildMAIValue(mai: MerchantAccountInfo): string {\n if (!/^(0[2-9]|[1-4]\\d|5[0-1])$/.test(mai.tag)) {\n throw new Error(\n `encodeNQR: merchantAccountInfo.tag must be in 02..51, got \"${mai.tag}\"`,\n );\n }\n let out = '';\n for (const c of mai.children) {\n out += writeTLV(c.tag, c.value);\n }\n return out;\n}\n\nfunction buildAdditionalDataValue(ad: AdditionalData): string {\n let out = '';\n const map: Array<[keyof AdditionalData, string]> = [\n ['billNumber', ADDITIONAL_DATA_SUBFIELD.BILL_NUMBER],\n ['mobileNumber', ADDITIONAL_DATA_SUBFIELD.MOBILE_NUMBER],\n ['storeLabel', ADDITIONAL_DATA_SUBFIELD.STORE_LABEL],\n ['loyaltyNumber', ADDITIONAL_DATA_SUBFIELD.LOYALTY_NUMBER],\n ['referenceLabel', ADDITIONAL_DATA_SUBFIELD.REFERENCE_LABEL],\n ['customerLabel', ADDITIONAL_DATA_SUBFIELD.CUSTOMER_LABEL],\n ['terminalLabel', ADDITIONAL_DATA_SUBFIELD.TERMINAL_LABEL],\n ['purposeOfTransaction', ADDITIONAL_DATA_SUBFIELD.PURPOSE_OF_TRANSACTION],\n ];\n for (const [k, t] of map) {\n const v = ad[k];\n if (v !== undefined) {\n out += writeTLV(t, v);\n }\n }\n return out;\n}\n\nfunction assertAscii(name: string, v: string): void {\n if (!ASCII_PRINTABLE.test(v)) {\n throw new Error(\n `encodeNQR: ${name} contains non-printable-ASCII characters`,\n );\n }\n}\n\nfunction assertMaxLen(name: string, v: string, max: number): void {\n if (v.length > max) {\n throw new Error(`encodeNQR: ${name} length ${v.length} exceeds max ${max}`);\n }\n}\n\nfunction assertMCC(mcc: string): void {\n if (!/^\\d{4}$/.test(mcc)) {\n throw new Error(\n `encodeNQR: merchantCategoryCode must be 4 digits, got \"${mcc}\"`,\n );\n }\n}\n\nfunction assertAmount(amt: string): void {\n // Up to 13 chars per EMV; decimal fraction separator is \".\"\n if (!/^\\d{1,10}(\\.\\d{1,2})?$/.test(amt)) {\n throw new Error(\n `encodeNQR: transactionAmount must match /^\\\\d{1,10}(\\\\.\\\\d{1,2})?$/, got \"${amt}\"`,\n );\n }\n if (amt.length > 13) {\n throw new Error(\n `encodeNQR: transactionAmount length ${amt.length} exceeds 13`,\n );\n }\n}\n\nexport function encodeNQR(input: NQRPayloadInput): string {\n assertMCC(input.merchantCategoryCode);\n assertAscii('merchantName', input.merchantName);\n assertMaxLen('merchantName', input.merchantName, 25);\n assertAscii('merchantCity', input.merchantCity);\n assertMaxLen('merchantCity', input.merchantCity, 15);\n if (input.postalCode !== undefined) {\n assertAscii('postalCode', input.postalCode);\n assertMaxLen('postalCode', input.postalCode, 10);\n }\n if (input.transactionAmount !== undefined) {\n assertAmount(input.transactionAmount);\n }\n if (\n input.pointOfInitiation === 'dynamic' &&\n input.transactionAmount === undefined\n ) {\n // amount is optional even for dynamic per spec, but warn-by-throw kept for now.\n // Allow undefined: some dynamic flows fill the amount in real-time. No throw.\n }\n\n let out = '';\n out += writeTLV(\n FIELD.PAYLOAD_FORMAT_INDICATOR,\n PAYLOAD_FORMAT_INDICATOR_VALUE,\n );\n out += writeTLV(\n FIELD.POINT_OF_INITIATION,\n input.pointOfInitiation === 'dynamic'\n ? POINT_OF_INITIATION.DYNAMIC\n : POINT_OF_INITIATION.STATIC,\n );\n out += writeTLV(\n input.merchantAccountInfo.tag,\n buildMAIValue(input.merchantAccountInfo),\n );\n out += writeTLV(FIELD.MERCHANT_CATEGORY_CODE, input.merchantCategoryCode);\n out += writeTLV(FIELD.TRANSACTION_CURRENCY, NGN_CURRENCY_CODE);\n if (input.transactionAmount !== undefined) {\n out += writeTLV(FIELD.TRANSACTION_AMOUNT, input.transactionAmount);\n }\n out += writeTLV(FIELD.COUNTRY_CODE, NG_COUNTRY_CODE);\n out += writeTLV(FIELD.MERCHANT_NAME, input.merchantName);\n out += writeTLV(FIELD.MERCHANT_CITY, input.merchantCity);\n if (input.postalCode !== undefined) {\n out += writeTLV(FIELD.POSTAL_CODE, input.postalCode);\n }\n if (input.additionalData) {\n const adfValue = buildAdditionalDataValue(input.additionalData);\n if (adfValue.length > 0) {\n out += writeTLV(FIELD.ADDITIONAL_DATA_FIELD, adfValue);\n }\n }\n\n // CRC over everything including \"6304\" header.\n out += CRC_TAG_PREFIX;\n const crc = crc16ccittHex(new TextEncoder().encode(out));\n out += crc;\n return out;\n}\n","import {\n CRC_TAG_PREFIX,\n FIELD,\n NGN_CURRENCY_CODE,\n NG_COUNTRY_CODE,\n} from './fields.js';\nimport { crc16ccittHex } from './crc16.js';\nimport { readTLV } from './tlv.js';\nimport type {\n AdditionalData,\n MerchantAccountInfo,\n ParsedNQR,\n} from './types.js';\n\nexport class NQRParseError extends Error {\n readonly path: string;\n constructor(message: string, path = '') {\n super(message);\n this.name = 'NQRParseError';\n this.path = path;\n }\n}\n\nexport function parseNQR(payload: string): ParsedNQR {\n if (payload.length < 8) {\n throw new NQRParseError(`payload too short (${payload.length} chars)`);\n }\n // CRC validation: last 4 chars are CRC; preceding 4 must be \"6304\".\n const crcTagAndLen = payload.slice(-8, -4);\n const crcValue = payload.slice(-4);\n if (crcTagAndLen !== CRC_TAG_PREFIX) {\n throw new NQRParseError(\n `CRC tag prefix not found (expected \"6304\" at end)`,\n );\n }\n const beforeCrc = payload.slice(0, -4);\n const expectedCrc = crc16ccittHex(new TextEncoder().encode(beforeCrc));\n if (expectedCrc !== crcValue.toUpperCase()) {\n throw new NQRParseError(\n `CRC mismatch: payload says ${crcValue}, computed ${expectedCrc}`,\n '63',\n );\n }\n\n // Parse top-level TLV (excluding the trailing CRC field).\n const topBuf = payload.slice(0, -8);\n const top = readTLV(topBuf);\n\n const get = (tag: string): string | undefined =>\n top.find((f) => f.tag === tag)?.value;\n\n const pfi = get(FIELD.PAYLOAD_FORMAT_INDICATOR);\n if (pfi !== '01')\n throw new NQRParseError(\n `payloadFormatIndicator must be \"01\", got \"${pfi}\"`,\n '00',\n );\n\n const poiRaw = get(FIELD.POINT_OF_INITIATION);\n const pointOfInitiation: ParsedNQR['pointOfInitiation'] =\n poiRaw === '11' ? 'static' : poiRaw === '12' ? 'dynamic' : 'unknown';\n\n const currency = get(FIELD.TRANSACTION_CURRENCY);\n if (currency !== NGN_CURRENCY_CODE) {\n throw new NQRParseError(\n `unsupported currency \"${currency}\" (expected ${NGN_CURRENCY_CODE})`,\n '53',\n );\n }\n const country = get(FIELD.COUNTRY_CODE);\n if (country !== NG_COUNTRY_CODE) {\n throw new NQRParseError(\n `unsupported country \"${country}\" (expected ${NG_COUNTRY_CODE})`,\n '58',\n );\n }\n\n const mcc = get(FIELD.MERCHANT_CATEGORY_CODE);\n if (!mcc) throw new NQRParseError('merchantCategoryCode missing', '52');\n const merchantName = get(FIELD.MERCHANT_NAME) ?? '';\n const merchantCity = get(FIELD.MERCHANT_CITY) ?? '';\n const transactionAmount = get(FIELD.TRANSACTION_AMOUNT);\n const postalCode = get(FIELD.POSTAL_CODE);\n\n // Merchant Account Information templates: tags 02..51.\n const mais: MerchantAccountInfo[] = [];\n for (const f of top) {\n const n = parseInt(f.tag, 10);\n if (n >= 2 && n <= 51) {\n const children = readTLV(f.value).map((c) => ({\n tag: c.tag,\n value: c.value,\n }));\n mais.push({ tag: f.tag, children });\n }\n }\n\n // Additional Data Field (62).\n let additionalData: AdditionalData | undefined;\n const adfRaw = get(FIELD.ADDITIONAL_DATA_FIELD);\n if (adfRaw !== undefined) {\n additionalData = {};\n for (const c of readTLV(adfRaw)) {\n switch (c.tag) {\n case '01':\n additionalData.billNumber = c.value;\n break;\n case '02':\n additionalData.mobileNumber = c.value;\n break;\n case '03':\n additionalData.storeLabel = c.value;\n break;\n case '04':\n additionalData.loyaltyNumber = c.value;\n break;\n case '05':\n additionalData.referenceLabel = c.value;\n break;\n case '06':\n additionalData.customerLabel = c.value;\n break;\n case '07':\n additionalData.terminalLabel = c.value;\n break;\n case '08':\n additionalData.purposeOfTransaction = c.value;\n break;\n // unknown sub-tags ignored (forward-compat).\n }\n }\n }\n\n return {\n payloadFormatIndicator: pfi,\n pointOfInitiation,\n merchantAccountInfo: mais,\n merchantCategoryCode: mcc,\n transactionCurrency: currency,\n transactionAmount,\n countryCode: country,\n merchantName,\n merchantCity,\n postalCode,\n additionalData,\n flurReference: additionalData?.referenceLabel?.startsWith('FL-')\n ? additionalData.referenceLabel\n : undefined,\n raw: payload,\n };\n}\n","import type { ParsedNQR } from './types.js';\n\nexport type RoutingHint = 'flur-onus' | 'nibss' | 'unknown';\n\n/**\n * Decide whether a parsed NQR payload should be routed on-us through Flur\n * (because it carries a Flur reference label) or sent through standard NIBSS.\n */\nexport function routingHint(parsed: ParsedNQR): RoutingHint {\n if (parsed.flurReference && parsed.flurReference.startsWith('FL-')) {\n return 'flur-onus';\n }\n if (parsed.merchantAccountInfo.length > 0) return 'nibss';\n return 'unknown';\n}\n","/**\n * Deterministic JSON serialization for cryptographic signing.\n *\n * Rules:\n * - Object keys sorted lexicographically (recursively).\n * - Arrays preserve order.\n * - undefined / NaN / Infinity / bigint / function / symbol are rejected.\n * Signatures must be unambiguous; ambiguous values are bugs.\n */\nexport function canonicalJSONStringify(value: unknown): string {\n return stringify(value);\n}\n\nexport function canonicalJSONBytes(value: unknown): Uint8Array {\n return new TextEncoder().encode(canonicalJSONStringify(value));\n}\n\nfunction stringify(v: unknown): string {\n if (v === null) return 'null';\n const t = typeof v;\n if (t === 'string') return JSON.stringify(v);\n if (t === 'boolean') return v ? 'true' : 'false';\n if (t === 'number') {\n if (!Number.isFinite(v as number)) {\n throw new Error('canonicalJSON: non-finite number not allowed');\n }\n return JSON.stringify(v);\n }\n if (\n t === 'bigint' ||\n t === 'function' ||\n t === 'symbol' ||\n t === 'undefined'\n ) {\n throw new Error(`canonicalJSON: unsupported value type ${t}`);\n }\n if (Array.isArray(v)) {\n const parts: string[] = [];\n for (const item of v) parts.push(stringify(item));\n return '[' + parts.join(',') + ']';\n }\n if (t === 'object') {\n const obj = v as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n const parts: string[] = [];\n for (const k of keys) {\n const val = obj[k];\n if (val === undefined) {\n throw new Error(`canonicalJSON: undefined value at key \"${k}\"`);\n }\n parts.push(JSON.stringify(k) + ':' + stringify(val));\n }\n return '{' + parts.join(',') + '}';\n }\n throw new Error(`canonicalJSON: unsupported value type ${t}`);\n}\n","/**\n * Constant-time equality for byte arrays. Returns false fast on length\n * mismatch (length is not secret); compares byte-wise without short-circuit\n * for equal-length inputs.\n */\nexport function constantTimeEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];\n return diff === 0;\n}\n","import { ed25519 } from '@noble/curves/ed25519';\nimport { canonicalJSONBytes } from './canonical.js';\n\nexport type Ed25519KeyPair = {\n privateKey: Uint8Array; // 32 bytes\n publicKey: Uint8Array; // 32 bytes\n};\n\nexport function generateKeyPair(): Ed25519KeyPair {\n const privateKey = ed25519.utils.randomPrivateKey();\n const publicKey = ed25519.getPublicKey(privateKey);\n return { privateKey, publicKey };\n}\n\nexport function publicKeyFromPrivate(privateKey: Uint8Array): Uint8Array {\n return ed25519.getPublicKey(privateKey);\n}\n\nexport function sign(message: Uint8Array, privateKey: Uint8Array): Uint8Array {\n return ed25519.sign(message, privateKey);\n}\n\nexport function verify(\n message: Uint8Array,\n signature: Uint8Array,\n publicKey: Uint8Array,\n): boolean {\n try {\n return ed25519.verify(signature, message, publicKey);\n } catch {\n return false;\n }\n}\n\n/**\n * Sign a value by canonicalizing it to JSON bytes first.\n * Use this for any object payload that must round-trip across devices.\n */\nexport function signCanonical(\n value: unknown,\n privateKey: Uint8Array,\n): Uint8Array {\n return sign(canonicalJSONBytes(value), privateKey);\n}\n\nexport function verifyCanonical(\n value: unknown,\n signature: Uint8Array,\n publicKey: Uint8Array,\n): boolean {\n return verify(canonicalJSONBytes(value), signature, publicKey);\n}\n","import { z } from 'zod';\nimport { sign, verify } from '../crypto/ed25519.js';\nimport { canonicalJSONBytes } from '../crypto/canonical.js';\n\nexport const OAC_DEFAULT_PER_TX_KOBO = 500_000;\nexport const OAC_DEFAULT_CUMULATIVE_KOBO = 2_000_000;\nexport const OAC_DEFAULT_VALIDITY_MS = 24 * 60 * 60 * 1000;\n\nconst HexString = (length: number) =>\n z\n .string()\n .regex(\n new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),\n `expected ${length}-byte hex string`,\n );\n\nexport const OACSchema = z\n .object({\n userId: z.string().min(1),\n deviceId: z.string().min(1),\n devicePublicKey: HexString(32),\n perTxCapKobo: z.number().int().nonnegative(),\n cumulativeCapKobo: z.number().int().nonnegative(),\n validFromMs: z.number().int().nonnegative(),\n validUntilMs: z.number().int().positive(),\n counterSeed: z.number().int().nonnegative(),\n nonce: z.string().min(1),\n issuerSig: HexString(64),\n })\n .refine((v) => v.validUntilMs > v.validFromMs, {\n message: 'validUntilMs must be greater than validFromMs',\n })\n .refine((v) => v.perTxCapKobo <= v.cumulativeCapKobo, {\n message: 'perTxCapKobo must not exceed cumulativeCapKobo',\n });\n\nexport type OAC = z.infer<typeof OACSchema>;\n\nexport type UnsignedOAC = Omit<OAC, 'issuerSig'>;\n\nexport function buildOAC(input: {\n userId: string;\n deviceId: string;\n devicePublicKey: Uint8Array | string;\n perTxCapKobo?: number;\n cumulativeCapKobo?: number;\n validFromMs: number;\n validUntilMs: number;\n counterSeed?: number;\n nonce: string;\n}): UnsignedOAC {\n const devicePublicKey =\n typeof input.devicePublicKey === 'string'\n ? input.devicePublicKey\n : bytesToHex(input.devicePublicKey);\n return {\n userId: input.userId,\n deviceId: input.deviceId,\n devicePublicKey,\n perTxCapKobo: input.perTxCapKobo ?? OAC_DEFAULT_PER_TX_KOBO,\n cumulativeCapKobo: input.cumulativeCapKobo ?? OAC_DEFAULT_CUMULATIVE_KOBO,\n validFromMs: input.validFromMs,\n validUntilMs: input.validUntilMs,\n counterSeed: input.counterSeed ?? 0,\n nonce: input.nonce,\n };\n}\n\nexport function signOAC(\n unsigned: UnsignedOAC,\n issuerPrivateKey: Uint8Array,\n): OAC {\n const issuerSig = bytesToHex(\n sign(canonicalJSONBytes(unsigned), issuerPrivateKey),\n );\n return { ...unsigned, issuerSig };\n}\n\nexport function verifyOAC(oac: OAC, issuerPublicKey: Uint8Array): boolean {\n try {\n const parsed = OACSchema.parse(oac);\n const { issuerSig, ...unsigned } = parsed;\n return verify(\n canonicalJSONBytes(unsigned),\n hexToBytes(issuerSig),\n issuerPublicKey,\n );\n } catch {\n return false;\n }\n}\n\nexport function bytesToHex(b: Uint8Array): string {\n let s = '';\n for (let i = 0; i < b.length; i++) s += b[i].toString(16).padStart(2, '0');\n return s;\n}\n\nexport function hexToBytes(s: string): Uint8Array {\n if (s.length % 2 !== 0) throw new Error('hex: odd length');\n const out = new Uint8Array(s.length / 2);\n for (let i = 0; i < out.length; i++)\n out[i] = parseInt(s.slice(i * 2, i * 2 + 2), 16);\n return out;\n}\n","// RFC 9285 base45 encoder/decoder.\nconst ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:';\nconst REVERSE: Record<string, number> = {};\nfor (let i = 0; i < ALPHABET.length; i++) REVERSE[ALPHABET[i]] = i;\n\nexport function encodeBase45(bytes: Uint8Array): string {\n let out = '';\n let i = 0;\n for (; i + 1 < bytes.length; i += 2) {\n const x = (bytes[i] << 8) | bytes[i + 1];\n const e = Math.floor(x / (45 * 45));\n const d = Math.floor((x % (45 * 45)) / 45);\n const c = x % 45;\n out += ALPHABET[c] + ALPHABET[d] + ALPHABET[e];\n }\n if (i < bytes.length) {\n const x = bytes[i];\n const d = Math.floor(x / 45);\n const c = x % 45;\n out += ALPHABET[c] + ALPHABET[d];\n }\n return out;\n}\n\nexport function decodeBase45(s: string): Uint8Array {\n if (s.length === 0) return new Uint8Array(0);\n const fullChunks = Math.floor(s.length / 3);\n const tail = s.length - fullChunks * 3;\n if (tail === 1) throw new Error('base45: invalid length');\n const out = new Uint8Array(fullChunks * 2 + (tail === 2 ? 1 : 0));\n let oi = 0;\n for (let i = 0; i < fullChunks; i++) {\n const c = REVERSE[s[i * 3]];\n const d = REVERSE[s[i * 3 + 1]];\n const e = REVERSE[s[i * 3 + 2]];\n if (c === undefined || d === undefined || e === undefined) {\n throw new Error('base45: invalid character');\n }\n const x = c + 45 * d + 45 * 45 * e;\n if (x > 0xffff) throw new Error('base45: chunk overflow');\n out[oi++] = (x >> 8) & 0xff;\n out[oi++] = x & 0xff;\n }\n if (tail === 2) {\n const c = REVERSE[s[fullChunks * 3]];\n const d = REVERSE[s[fullChunks * 3 + 1]];\n if (c === undefined || d === undefined)\n throw new Error('base45: invalid character');\n const x = c + 45 * d;\n if (x > 0xff) throw new Error('base45: tail overflow');\n out[oi++] = x & 0xff;\n }\n return out;\n}\n","import { z } from 'zod';\nimport { sign, verify } from '../crypto/ed25519.js';\nimport { canonicalJSONBytes } from '../crypto/canonical.js';\nimport { OACSchema, type OAC, bytesToHex, hexToBytes } from './oac.js';\nimport { encodeBase45, decodeBase45 } from './codec.js';\n\nconst HexSig = z\n .string()\n .regex(/^[0-9a-fA-F]{128}$/, 'expected 64-byte hex signature');\n\nexport const OfflinePaymentRequestSchema = z.object({\n reference: z.string().min(1),\n amountKobo: z.number().int().positive(),\n merchantOAC: OACSchema,\n expiresAtMs: z.number().int().positive(),\n merchantSig: HexSig,\n});\nexport type OfflinePaymentRequest = z.infer<typeof OfflinePaymentRequestSchema>;\nexport type UnsignedOfflinePaymentRequest = Omit<\n OfflinePaymentRequest,\n 'merchantSig'\n>;\n\nexport const OfflinePaymentAuthorizationSchema = z.object({\n request: OfflinePaymentRequestSchema,\n payerOAC: OACSchema,\n payerCounter: z.number().int().positive(),\n payerSig: HexSig,\n});\nexport type OfflinePaymentAuthorization = z.infer<\n typeof OfflinePaymentAuthorizationSchema\n>;\nexport type UnsignedOfflinePaymentAuthorization = Omit<\n OfflinePaymentAuthorization,\n 'payerSig'\n>;\n\nexport function buildPaymentRequest(input: {\n reference: string;\n amountKobo: number;\n merchantOAC: OAC;\n expiresAtMs: number;\n}): UnsignedOfflinePaymentRequest {\n if (!Number.isInteger(input.amountKobo) || input.amountKobo <= 0) {\n throw new Error('amountKobo must be a positive integer');\n }\n if (input.amountKobo > input.merchantOAC.perTxCapKobo) {\n throw new Error('amountKobo exceeds merchant OAC perTxCapKobo');\n }\n return {\n reference: input.reference,\n amountKobo: input.amountKobo,\n merchantOAC: input.merchantOAC,\n expiresAtMs: input.expiresAtMs,\n };\n}\n\nexport function signPaymentRequest(\n unsigned: UnsignedOfflinePaymentRequest,\n merchantDevicePrivateKey: Uint8Array,\n): OfflinePaymentRequest {\n const merchantSig = bytesToHex(\n sign(canonicalJSONBytes(unsigned), merchantDevicePrivateKey),\n );\n return { ...unsigned, merchantSig };\n}\n\nexport function verifyPaymentRequest(\n req: OfflinePaymentRequest,\n issuerPublicKey: Uint8Array,\n): boolean {\n try {\n const parsed = OfflinePaymentRequestSchema.parse(req);\n // 1. Issuer must have signed the merchant OAC.\n const { issuerSig: merchantOacSig, ...merchantOacUnsigned } =\n parsed.merchantOAC;\n if (\n !verify(\n canonicalJSONBytes(merchantOacUnsigned),\n hexToBytes(merchantOacSig),\n issuerPublicKey,\n )\n ) {\n return false;\n }\n // 2. The merchant's device key (in OAC) must have signed this request.\n const { merchantSig, ...unsigned } = parsed;\n return verify(\n canonicalJSONBytes(unsigned),\n hexToBytes(merchantSig),\n hexToBytes(parsed.merchantOAC.devicePublicKey),\n );\n } catch {\n return false;\n }\n}\n\nexport function buildAuthorization(input: {\n request: OfflinePaymentRequest;\n payerOAC: OAC;\n payerCounter: number;\n}): UnsignedOfflinePaymentAuthorization {\n if (!Number.isInteger(input.payerCounter) || input.payerCounter <= 0) {\n throw new Error('payerCounter must be a positive integer');\n }\n if (input.request.amountKobo > input.payerOAC.perTxCapKobo) {\n throw new Error('amountKobo exceeds payer OAC perTxCapKobo');\n }\n return {\n request: input.request,\n payerOAC: input.payerOAC,\n payerCounter: input.payerCounter,\n };\n}\n\nexport function signAuthorization(\n unsigned: UnsignedOfflinePaymentAuthorization,\n payerDevicePrivateKey: Uint8Array,\n): OfflinePaymentAuthorization {\n const payerSig = bytesToHex(\n sign(canonicalJSONBytes(unsigned), payerDevicePrivateKey),\n );\n return { ...unsigned, payerSig };\n}\n\nexport function verifyAuthorization(\n auth: OfflinePaymentAuthorization,\n issuerPublicKey: Uint8Array,\n): boolean {\n try {\n const parsed = OfflinePaymentAuthorizationSchema.parse(auth);\n if (!verifyPaymentRequest(parsed.request, issuerPublicKey)) return false;\n // Issuer must have signed the payer OAC.\n const { issuerSig: payerOacSig, ...payerOacUnsigned } = parsed.payerOAC;\n if (\n !verify(\n canonicalJSONBytes(payerOacUnsigned),\n hexToBytes(payerOacSig),\n issuerPublicKey,\n )\n ) {\n return false;\n }\n // Payer device key must have signed this authorization.\n const { payerSig, ...unsigned } = parsed;\n return verify(\n canonicalJSONBytes(unsigned),\n hexToBytes(payerSig),\n hexToBytes(parsed.payerOAC.devicePublicKey),\n );\n } catch {\n return false;\n }\n}\n\nexport function encodePaymentRequestQR(req: OfflinePaymentRequest): string {\n const json = JSON.stringify(req);\n return 'FLUR1:' + encodeBase45(new TextEncoder().encode(json));\n}\n\nexport function decodePaymentRequestQR(s: string): OfflinePaymentRequest {\n if (!s.startsWith('FLUR1:'))\n throw new Error('not a Flur offline payment request QR');\n const bytes = decodeBase45(s.slice('FLUR1:'.length));\n const json = new TextDecoder().decode(bytes);\n return OfflinePaymentRequestSchema.parse(JSON.parse(json));\n}\n\nexport function encodeAuthorizationQR(\n auth: OfflinePaymentAuthorization,\n): string {\n const json = JSON.stringify(auth);\n return 'FLUR2:' + encodeBase45(new TextEncoder().encode(json));\n}\n\nexport function decodeAuthorizationQR(s: string): OfflinePaymentAuthorization {\n if (!s.startsWith('FLUR2:'))\n throw new Error('not a Flur offline authorization QR');\n const bytes = decodeBase45(s.slice('FLUR2:'.length));\n const json = new TextDecoder().decode(bytes);\n return OfflinePaymentAuthorizationSchema.parse(JSON.parse(json));\n}\n","/**\n * Offline settlement SDK helpers.\n *\n * The SDK does not \"pay\" offline — it produces signed `PaymentClaim`s and posts\n * them to `/v1/offline/settlements`. The backend enforces \"paid once\" via\n * UNIQUE(settlement_key) and UNIQUE(token_serial).\n */\nimport { z } from 'zod';\nimport type { FlurPartnerClient } from '../partner/client.js';\n\n// ───────────────────────────── schemas ─────────────────────────────\n\nexport const OfflineTokenSchema = z.object({\n tokenId: z.string().uuid(),\n tokenSerial: z.string(),\n issuerAccountId: z.string().uuid(),\n payerUserId: z.string().uuid(),\n maxAmountKobo: z.number().int().positive(),\n currency: z.string().length(3),\n issuedAtMs: z.number().int().nonnegative(),\n expiresAtMs: z.number().int().nonnegative(),\n issuerSig: z.string(),\n});\nexport type OfflineToken = z.infer<typeof OfflineTokenSchema>;\n\nexport const PaymentClaimSchema = z.object({\n encounterId: z\n .string()\n .regex(/^[0-9a-f]{64}$/i)\n .optional(),\n tokenSerial: z.string(),\n payerUserId: z.string().uuid(),\n payeeUserId: z.string().uuid(),\n payerNonce: z.string(),\n payeeNonce: z.string(),\n amountKobo: z.number().int().positive(),\n currency: z.string().length(3).default('NGN'),\n occurredAtMs: z.number().int().nonnegative(),\n completedAtMs: z.number().int().nonnegative().optional(),\n contextId: z.string().optional(),\n payerPubkey: z.string().regex(/^[0-9a-f]{64}$/i),\n payerSignature: z.string().regex(/^[0-9a-f]+$/i),\n payeePubkey: z\n .string()\n .regex(/^[0-9a-f]{64}$/i)\n .optional(),\n payeeSignature: z\n .string()\n .regex(/^[0-9a-f]+$/i)\n .optional(),\n});\nexport type PaymentClaim = z.infer<typeof PaymentClaimSchema>;\n\nexport const SettlementSchema = z.object({\n settlementId: z.string().uuid(),\n settlementKey: z.string().regex(/^[0-9a-f]{64}$/i),\n encounterId: z.string().regex(/^[0-9a-f]{64}$/i),\n issuerAccountId: z.string().uuid(),\n tokenSerial: z.string(),\n payerUserId: z.string().uuid(),\n payeeUserId: z.string().uuid(),\n amountKobo: z.number().int().nonnegative(),\n currency: z.string().length(3),\n receiptId: z.string().nullable(),\n status: z.enum(['SETTLED', 'REVIEW', 'REJECTED']),\n issuerSig: z.string(),\n createdAtMs: z.number().int().nonnegative(),\n});\nexport type Settlement = z.infer<typeof SettlementSchema>;\n\nexport const SettleResponseSchema = z.object({\n settlement: SettlementSchema,\n encounterId: z.string().regex(/^[0-9a-f]{64}$/i),\n replayed: z.boolean(),\n});\nexport type SettleResponse = z.infer<typeof SettleResponseSchema>;\n\n// ───────────────────────────── deterministic ids ─────────────────────────────\n\nimport { sha256 } from '@noble/hashes/sha256';\nimport { bytesToHex } from '@noble/hashes/utils';\n\nconst ENCOUNTER_DOMAIN = 'offline:v1:encounter';\n\n/** SHA-256 hex helper. Pure-JS via @noble/hashes — works in Node, browser, and React Native. */\nasync function sha256Hex(input: string): Promise<string> {\n return bytesToHex(sha256(new TextEncoder().encode(input)));\n}\n\n/**\n * Compute the deterministic encounterId. Both parties produce the same value;\n * the backend enforces it.\n */\nexport async function computeEncounterId(input: {\n payerUserId: string;\n payeeUserId: string;\n payerNonce: string;\n payeeNonce: string;\n tokenSerial: string;\n}): Promise<string> {\n return sha256Hex(\n ENCOUNTER_DOMAIN +\n '|' +\n [\n input.payerUserId,\n input.payeeUserId,\n input.payerNonce,\n input.payeeNonce,\n input.tokenSerial,\n ].join('|'),\n );\n}\n\n// ───────────────────────────── client ─────────────────────────────\n\nexport type IssueOfflineTokenInput = {\n /** Optional client-supplied serial (must be unique). */\n tokenSerial?: string;\n payerUserId: string;\n maxAmountKobo: number;\n currency?: string;\n ttlMs: number;\n};\n\nexport type FlurOfflineSettlementsClient = {\n /** Partner-only: pre-issue a bounded offline settlement token. */\n issueOfflineToken: (input: IssueOfflineTokenInput) => Promise<OfflineToken>;\n /** Get a token by serial (partner-scoped). */\n getOfflineToken: (tokenSerial: string) => Promise<OfflineToken>;\n /** Atomically settle a signed payment claim (idempotent). */\n settle: (claim: PaymentClaim) => Promise<SettleResponse>;\n /** Fetch a stored settlement by id or settlement_key. */\n getSettlement: (idOrKey: string) => Promise<Settlement>;\n /** List queued conflict/review items (partner-scoped). */\n listConflicts: () => Promise<{ items: unknown[] }>;\n};\n\nexport function createOfflineSettlementsClient(\n partner: FlurPartnerClient,\n): FlurOfflineSettlementsClient {\n return {\n issueOfflineToken: (input) =>\n partner.request<OfflineToken>({\n method: 'POST',\n path: '/v1/offline/tokens',\n body: {\n payerUserId: input.payerUserId,\n maxAmountKobo: input.maxAmountKobo,\n currency: input.currency ?? 'NGN',\n ttlMs: input.ttlMs,\n ...(input.tokenSerial ? { tokenSerial: input.tokenSerial } : {}),\n },\n }),\n getOfflineToken: (serial) =>\n partner.request<OfflineToken>({\n method: 'GET',\n path: `/v1/offline/tokens/${encodeURIComponent(serial)}`,\n }),\n settle: (claim) =>\n partner.request<SettleResponse>({\n method: 'POST',\n path: '/v1/offline/settlements',\n body: claim,\n }),\n getSettlement: (id) =>\n partner.request<Settlement>({\n method: 'GET',\n path: `/v1/offline/settlements/${encodeURIComponent(id)}`,\n }),\n listConflicts: () =>\n partner.request<{ items: unknown[] }>({\n method: 'GET',\n path: '/v1/offline/conflicts',\n }),\n };\n}\n","import { hmac } from '@noble/hashes/hmac';\nimport { sha256 } from '@noble/hashes/sha256';\n\nfunction bytesToHex(b: Uint8Array): string {\n let s = '';\n for (let i = 0; i < b.length; i++) s += b[i].toString(16).padStart(2, '0');\n return s;\n}\n\nfunction constantTimeStringEqual(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a.charCodeAt(i) ^ b.charCodeAt(i);\n return diff === 0;\n}\n\nexport function bodySha256Hex(body: string): string {\n return bytesToHex(sha256(new TextEncoder().encode(body)));\n}\n\nexport function canonicalRequestString(input: {\n method: string;\n path: string;\n timestamp: string;\n nonce: string;\n body: string;\n}): string {\n return [\n input.method.toUpperCase(),\n input.path,\n input.timestamp,\n input.nonce,\n bodySha256Hex(input.body),\n ].join('\\n');\n}\n\nexport function signRequestHMAC(input: {\n method: string;\n path: string;\n timestamp: string;\n nonce: string;\n body: string;\n apiSecret: string;\n}): string {\n return bytesToHex(\n hmac(sha256, input.apiSecret, canonicalRequestString(input)),\n );\n}\n\nexport function verifyRequestHMAC(input: {\n method: string;\n path: string;\n timestamp: string;\n nonce: string;\n body: string;\n apiSecret: string;\n signature: string;\n}): boolean {\n const expected = signRequestHMAC(input);\n return constantTimeStringEqual(expected, input.signature.toLowerCase());\n}\n","import { signRequestHMAC } from './hmac.js';\n\nexport const REPLAY_WINDOW_MS = 5 * 60 * 1000;\n\n/**\n * Server may signal clock skew in this header (RFC3339 or epoch seconds/ms).\n * The HMAC client uses it to perform a single bounded retry on 401.\n */\nexport const SERVER_TIME_HEADER = 'x-flur-server-time';\n\nexport type HmacFetchOptions = {\n apiKey: string;\n apiSecret: string;\n fetchImpl?: typeof fetch;\n nowMs?: () => number;\n nonceFn?: () => string;\n /** Optional scope claim forwarded as `X-Flur-Scope` (comma-joined). Backend remains authoritative. */\n scope?: readonly string[];\n};\n\n/** Generate a 128-bit nonce as hex. CSPRNG-only — throws if unavailable. */\nfunction defaultNonce(): string {\n const c = globalThis.crypto;\n if (typeof c?.randomUUID === 'function') return c.randomUUID();\n if (typeof c?.getRandomValues !== 'function') {\n throw new Error(\n 'Flur SDK: no CSPRNG available (globalThis.crypto.getRandomValues missing). ' +\n 'Refusing to fall back to Math.random for HMAC nonce generation.',\n );\n }\n const arr = new Uint8Array(16);\n c.getRandomValues(arr);\n let s = '';\n for (let i = 0; i < arr.length; i++)\n s += arr[i].toString(16).padStart(2, '0');\n return s;\n}\n\nfunction assertCSPRNG(): void {\n const c = globalThis.crypto;\n if (\n typeof c?.getRandomValues !== 'function' &&\n typeof c?.randomUUID !== 'function'\n ) {\n throw new Error(\n 'Flur SDK: no CSPRNG available (globalThis.crypto missing). ' +\n 'Initialize on a runtime that provides Web Crypto (Node 19+, modern browsers, RN 0.74+).',\n );\n }\n}\n\n/** Parse a server-time hint as either epoch (s or ms) or RFC3339; returns ms or null. */\nfunction parseServerTimeMs(value: string | null): number | null {\n if (!value) return null;\n const trimmed = value.trim();\n if (/^\\d+$/.test(trimmed)) {\n const n = Number(trimmed);\n return n < 1e12 ? n * 1000 : n; // seconds vs ms heuristic\n }\n const t = Date.parse(trimmed);\n return Number.isFinite(t) ? t : null;\n}\n\nexport function createHmacFetch(opts: HmacFetchOptions): typeof fetch {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl)\n throw new Error('createHmacFetch: no fetch implementation available');\n if (!opts.nonceFn) assertCSPRNG(); // fail-fast unless caller injected a nonce source\n\n const nowMs = opts.nowMs ?? (() => Date.now());\n const nonceFn = opts.nonceFn ?? defaultNonce;\n const scopeHeader =\n opts.scope && opts.scope.length > 0 ? opts.scope.join(',') : undefined;\n\n async function signAndSend(\n req: Request,\n skewOffsetMs: number,\n ): Promise<Response> {\n // Clone first so the caller can keep using `req` (e.g., for a retry).\n const cloned = req.clone();\n const url = new URL(cloned.url);\n const path = url.pathname + url.search;\n const method = cloned.method.toUpperCase();\n const bodyText =\n method === 'GET' || method === 'HEAD' ? '' : await cloned.clone().text();\n const timestamp = Math.floor((nowMs() + skewOffsetMs) / 1000).toString();\n const nonce = nonceFn();\n const signature = signRequestHMAC({\n method,\n path,\n timestamp,\n nonce,\n body: bodyText,\n apiSecret: opts.apiSecret,\n });\n const headers = new Headers(cloned.headers);\n headers.set('x-flur-key', opts.apiKey);\n headers.set('x-flur-timestamp', timestamp);\n headers.set('x-flur-nonce', nonce);\n headers.set('x-flur-signature', signature);\n if (scopeHeader) headers.set('x-flur-scope', scopeHeader);\n const signed = new Request(cloned, { headers });\n return fetchImpl(signed);\n }\n\n return (async (input: RequestInfo | URL, init?: RequestInit) => {\n const req = input instanceof Request ? input : new Request(input, init);\n let resp = await signAndSend(req, 0);\n\n if (resp.status === 401) {\n const serverTimeMs = parseServerTimeMs(\n resp.headers.get(SERVER_TIME_HEADER),\n );\n if (serverTimeMs !== null) {\n const skew = serverTimeMs - nowMs();\n if (Math.abs(skew) > 0) {\n // Bounded single retry with corrected timestamp.\n resp = await signAndSend(req, skew);\n }\n }\n }\n return resp;\n }) as typeof fetch;\n}\n","import { z } from 'zod';\nimport { sign, verify } from '../crypto/ed25519.js';\nimport { canonicalJSONBytes } from '../crypto/canonical.js';\nimport { bytesToHex, hexToBytes } from '../offline/oac.js';\n\nexport const PASS_KINDS = [\n 'ride-ticket',\n 'transit-pass',\n 'event-ticket',\n 'voucher',\n 'loyalty',\n 'receipt-link',\n] as const;\nexport type PassKind = (typeof PASS_KINDS)[number];\n\nexport const PASS_STATES = [\n 'issued',\n 'active',\n 'redeemed',\n 'expired',\n 'revoked',\n] as const;\nexport type PassState = (typeof PASS_STATES)[number];\n\nconst HexString = (length: number) =>\n z\n .string()\n .regex(\n new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),\n `expected ${length}-byte hex string`,\n );\n\n/** JSON-serialisable metadata payload — bounded to keep QR/offline encodings tractable. */\nexport const PassMetadataSchema = z.record(\n z.union([z.string(), z.number(), z.boolean(), z.null()]),\n);\nexport type PassMetadata = z.infer<typeof PassMetadataSchema>;\n\nexport const PassSchema = z\n .object({\n passId: z.string().min(1),\n /** Optional client/template grouping id (server may omit). */\n templateId: z.string().min(1).optional(),\n /** Optional human-facing holder identity (server may omit). The cryptographic binding\n * is `holderDevicePubkey` below. */\n holderUserId: z.string().min(1).optional(),\n kind: z.enum(PASS_KINDS),\n issuerId: z.string().min(1),\n issuedAtMs: z.number().int().nonnegative(),\n validFromMs: z.number().int().nonnegative(),\n validUntilMs: z.number().int().positive(),\n state: z.enum(PASS_STATES),\n metadata: PassMetadataSchema,\n nonce: z.string().min(1),\n /** Device id this pass is bound to (FK to backend `device_keys`). */\n holderDeviceId: z.string().min(1),\n /** 32-byte hex Ed25519 public key of the bound device. The redemption signature\n * is verified against this key — it is the security-critical binding. */\n holderDevicePubkey: HexString(32),\n /** Optional fixed amount for monetary passes (vouchers, gift cards) in kobo. */\n amountKobo: z.number().int().nonnegative().optional(),\n /** ISO-4217-ish currency code; required on the wire. SDK builders default to NGN. */\n currency: z.string().min(3).max(8),\n /** Monotonic redemption counter floor. Redemption.counter MUST be > counterSeed. */\n counterSeed: z.number().int().nonnegative(),\n /** Optional cumulative spend cap in kobo across all redemptions of this pass. */\n cumulativeCapKobo: z.number().int().nonnegative().optional(),\n issuerSig: HexString(64),\n })\n .refine((v) => v.validUntilMs > v.validFromMs, {\n message: 'validUntilMs must be greater than validFromMs',\n });\n\nexport type Pass = z.infer<typeof PassSchema>;\nexport type UnsignedPass = Omit<Pass, 'issuerSig'>;\n\nexport type BuildPassInput = {\n passId: string;\n templateId?: string;\n holderUserId?: string;\n kind: PassKind;\n issuerId: string;\n issuedAtMs: number;\n validFromMs: number;\n validUntilMs: number;\n state: PassState;\n metadata: PassMetadata;\n nonce: string;\n holderDeviceId: string;\n holderDevicePubkey: string;\n amountKobo?: number;\n currency?: string;\n counterSeed: number;\n cumulativeCapKobo?: number;\n};\n\nexport function buildPass(input: BuildPassInput): UnsignedPass {\n if (input.validUntilMs <= input.validFromMs) {\n throw new Error('validUntilMs must be greater than validFromMs');\n }\n const out: UnsignedPass = {\n passId: input.passId,\n kind: input.kind,\n issuerId: input.issuerId,\n issuedAtMs: input.issuedAtMs,\n validFromMs: input.validFromMs,\n validUntilMs: input.validUntilMs,\n state: input.state,\n metadata: input.metadata,\n nonce: input.nonce,\n holderDeviceId: input.holderDeviceId,\n holderDevicePubkey: input.holderDevicePubkey,\n currency: input.currency ?? 'NGN',\n counterSeed: input.counterSeed,\n };\n if (typeof input.templateId === 'string') out.templateId = input.templateId;\n if (typeof input.holderUserId === 'string')\n out.holderUserId = input.holderUserId;\n if (typeof input.amountKobo === 'number') out.amountKobo = input.amountKobo;\n if (typeof input.cumulativeCapKobo === 'number') {\n out.cumulativeCapKobo = input.cumulativeCapKobo;\n }\n return out;\n}\n\nexport function signPass(\n unsigned: UnsignedPass,\n issuerPrivateKey: Uint8Array,\n): Pass {\n const issuerSig = bytesToHex(\n sign(canonicalJSONBytes(unsigned), issuerPrivateKey),\n );\n return { ...unsigned, issuerSig };\n}\n\nexport function verifyPass(pass: Pass, issuerPublicKey: Uint8Array): boolean {\n try {\n const parsed = PassSchema.parse(pass);\n const { issuerSig, ...unsigned } = parsed;\n return verify(\n canonicalJSONBytes(unsigned),\n hexToBytes(issuerSig),\n issuerPublicKey,\n );\n } catch {\n return false;\n }\n}\n\n/**\n * Validity window check is done separately from signature verification so callers can\n * decide their clock-skew tolerance.\n */\nexport function isPassWithinValidity(pass: Pass, nowMs: number): boolean {\n return nowMs >= pass.validFromMs && nowMs < pass.validUntilMs;\n}\n","import { z } from 'zod';\nimport { sign, verify } from '../crypto/ed25519.js';\nimport { canonicalJSONBytes } from '../crypto/canonical.js';\nimport { bytesToHex, hexToBytes } from '../offline/oac.js';\nimport { PassSchema, type Pass } from './pass.js';\nimport {\n FlurExpiredError,\n FlurReplayError,\n FlurCapExceededError,\n} from '../errors.js';\n\nconst HexSig = z\n .string()\n .regex(/^[0-9a-fA-F]{128}$/, 'expected 64-byte hex signature');\n\nexport const RedemptionSchema = z.object({\n pass: PassSchema,\n redeemerId: z.string().min(1),\n redeemedAtMs: z.number().int().nonnegative(),\n /** Strictly monotonic counter scoped to a single pass. Must be > pass.counterSeed\n * and > the redeemer's lastSeenCounter for this pass. */\n counter: z.number().int().positive(),\n /** Amount being redeemed in kobo (0 for non-monetary passes like ride tickets). */\n amountKobo: z.number().int().nonnegative(),\n nonce: z.string().min(1),\n holderSig: HexSig,\n});\nexport type Redemption = z.infer<typeof RedemptionSchema>;\nexport type UnsignedRedemption = Omit<Redemption, 'holderSig'>;\n\nexport type BuildRedemptionInput = {\n pass: Pass;\n redeemerId: string;\n redeemedAtMs: number;\n counter: number;\n amountKobo?: number;\n nonce: string;\n /** Optional local clock — if supplied, fail-fast against pass.validUntilMs. */\n nowMs?: number;\n /** Last counter the holder has seen for this pass (default: pass.counterSeed). */\n lastSeenCounter?: number;\n /** Total kobo already redeemed against this pass (default: 0). Used with pass.cumulativeCapKobo. */\n cumulativeUsedKobo?: number;\n};\n\nconst REDEEMABLE_STATES = new Set(['issued', 'active']);\n\nexport function buildRedemption(\n input: BuildRedemptionInput,\n): UnsignedRedemption {\n if (!REDEEMABLE_STATES.has(input.pass.state)) {\n throw new Error(`pass not in redeemable state: ${input.pass.state}`);\n }\n if (input.redeemedAtMs < input.pass.validFromMs) {\n throw new Error('redeemedAtMs is before pass validFromMs');\n }\n if (input.redeemedAtMs >= input.pass.validUntilMs) {\n throw new FlurExpiredError(\n `pass ${input.pass.passId} expired at ${input.pass.validUntilMs}`,\n );\n }\n // Wall-clock expiry check (offline-safe; backend remains authoritative).\n const now =\n typeof input.nowMs === 'number' ? input.nowMs : input.redeemedAtMs;\n if (now >= input.pass.validUntilMs) {\n throw new FlurExpiredError(\n `pass ${input.pass.passId} expired at ${input.pass.validUntilMs}`,\n );\n }\n if (!input.pass.holderDevicePubkey) {\n throw new Error(\n 'pass.holderDevicePubkey is required to build a redemption',\n );\n }\n\n // Counter monotonicity: must exceed both seed and any locally-known prior counter.\n const lastSeen = Math.max(\n input.pass.counterSeed,\n typeof input.lastSeenCounter === 'number' ? input.lastSeenCounter : 0,\n );\n if (input.counter <= lastSeen) {\n throw new FlurReplayError(\n `redemption counter ${input.counter} must be > lastSeenCounter ${lastSeen}`,\n );\n }\n\n const amount = input.amountKobo ?? 0;\n\n // Cumulative cap (when set on the pass): used + this <= cap.\n if (typeof input.pass.cumulativeCapKobo === 'number') {\n const used = input.cumulativeUsedKobo ?? 0;\n if (used + amount > input.pass.cumulativeCapKobo) {\n throw new FlurCapExceededError(\n `pass ${input.pass.passId} cap ${input.pass.cumulativeCapKobo} would be exceeded (used ${used} + ${amount})`,\n );\n }\n }\n\n return {\n pass: input.pass,\n redeemerId: input.redeemerId,\n redeemedAtMs: input.redeemedAtMs,\n counter: input.counter,\n amountKobo: amount,\n nonce: input.nonce,\n };\n}\n\nexport function signRedemption(\n unsigned: UnsignedRedemption,\n holderDevicePrivateKey: Uint8Array,\n): Redemption {\n const holderSig = bytesToHex(\n sign(canonicalJSONBytes(unsigned), holderDevicePrivateKey),\n );\n return { ...unsigned, holderSig };\n}\n\n/**\n * Verifies, in order:\n * 1. The pass itself is signed by the issuer.\n * 2. The pass binds a `holderDevicePubkey` (top-level, security-critical).\n * 3. The redemption is signed by that bound device key.\n * 4. The redemption counter is strictly greater than pass.counterSeed.\n */\nexport function verifyRedemption(\n r: Redemption,\n issuerPublicKey: Uint8Array,\n): boolean {\n try {\n const parsed = RedemptionSchema.parse(r);\n if (parsed.counter <= parsed.pass.counterSeed) return false;\n const { issuerSig, ...passUnsigned } = parsed.pass;\n if (\n !verify(\n canonicalJSONBytes(passUnsigned),\n hexToBytes(issuerSig),\n issuerPublicKey,\n )\n ) {\n return false;\n }\n const holderHex = parsed.pass.holderDevicePubkey;\n if (typeof holderHex !== 'string') return false;\n const { holderSig, ...unsigned } = parsed;\n return verify(\n canonicalJSONBytes(unsigned),\n hexToBytes(holderSig),\n hexToBytes(holderHex),\n );\n } catch {\n return false;\n }\n}\n","import { z } from 'zod';\nimport { sign, verify } from '../crypto/ed25519.js';\nimport { canonicalJSONBytes } from '../crypto/canonical.js';\nimport { bytesToHex, hexToBytes } from '../offline/oac.js';\n\nexport const RECEIPT_CHANNELS = ['cash', 'pass'] as const;\nexport type ReceiptChannel = (typeof RECEIPT_CHANNELS)[number];\n\n/** @deprecated use {@link RECEIPT_CHANNELS}. Will be removed before 1.0. */\nexport const RECEIPT_KINDS = RECEIPT_CHANNELS;\n/** @deprecated use {@link ReceiptChannel}. */\nexport type ReceiptKind = ReceiptChannel;\n\nconst HexString = (length: number) =>\n z\n .string()\n .regex(\n new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),\n `expected ${length}-byte hex string`,\n );\n\n/** Free-form payload reserved for channel-specific extras (e.g. memo, intent metadata).\n * Top-level fields below are the security-relevant facts and must not be duplicated here. */\nexport const ReceiptPayloadSchema = z.record(\n z.union([z.string(), z.number(), z.boolean(), z.null()]),\n);\nexport type ReceiptPayload = z.infer<typeof ReceiptPayloadSchema>;\n\n/** BE-20 wire schema: channel + exactly one of `intentId` (cash) or `passRedemptionId` (pass). */\nexport const ReceiptSchema = z\n .object({\n receiptId: z.string().min(1),\n channel: z.enum(RECEIPT_CHANNELS),\n /** Cash-channel: send_intents.id. Required when channel === 'cash'. */\n intentId: z.string().min(1).optional(),\n /** Pass-channel: pass_redemptions.id. Required when channel === 'pass'. */\n passRedemptionId: z.string().min(1).optional(),\n payerUserId: z.string().min(1),\n payeeUserId: z.string().min(1),\n amountKobo: z.number().int().nonnegative(),\n currency: z.string().min(3).max(8),\n issuedAtMs: z.number().int().nonnegative(),\n issuerId: z.string().min(1),\n payload: ReceiptPayloadSchema,\n issuerSig: HexString(64),\n })\n .superRefine((v, ctx) => {\n if (v.channel === 'cash') {\n if (!v.intentId) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'cash receipts require intentId',\n path: ['intentId'],\n });\n }\n if (v.passRedemptionId) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'cash receipts must not carry passRedemptionId',\n path: ['passRedemptionId'],\n });\n }\n } else if (v.channel === 'pass') {\n if (!v.passRedemptionId) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'pass receipts require passRedemptionId',\n path: ['passRedemptionId'],\n });\n }\n if (v.intentId) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'pass receipts must not carry intentId',\n path: ['intentId'],\n });\n }\n }\n });\nexport type Receipt = z.infer<typeof ReceiptSchema>;\nexport type UnsignedReceipt = Omit<Receipt, 'issuerSig'>;\n\nexport type BuildReceiptInput = {\n receiptId: string;\n channel: ReceiptChannel;\n intentId?: string;\n passRedemptionId?: string;\n payerUserId: string;\n payeeUserId: string;\n amountKobo: number;\n currency: string;\n issuedAtMs: number;\n issuerId: string;\n payload?: ReceiptPayload;\n};\n\nexport function buildReceipt(input: BuildReceiptInput): UnsignedReceipt {\n if (input.channel === 'cash') {\n if (!input.intentId) {\n throw new Error('cash receipts require intentId');\n }\n if (input.passRedemptionId) {\n throw new Error('cash receipts must not carry passRedemptionId');\n }\n } else {\n if (!input.passRedemptionId) {\n throw new Error('pass receipts require passRedemptionId');\n }\n if (input.intentId) {\n throw new Error('pass receipts must not carry intentId');\n }\n }\n const out: UnsignedReceipt = {\n receiptId: input.receiptId,\n channel: input.channel,\n payerUserId: input.payerUserId,\n payeeUserId: input.payeeUserId,\n amountKobo: input.amountKobo,\n currency: input.currency,\n issuedAtMs: input.issuedAtMs,\n issuerId: input.issuerId,\n payload: input.payload ?? {},\n };\n if (input.intentId) out.intentId = input.intentId;\n if (input.passRedemptionId) out.passRedemptionId = input.passRedemptionId;\n return out;\n}\n\nexport function signReceipt(\n unsigned: UnsignedReceipt,\n issuerPrivateKey: Uint8Array,\n): Receipt {\n const issuerSig = bytesToHex(\n sign(canonicalJSONBytes(unsigned), issuerPrivateKey),\n );\n return { ...unsigned, issuerSig };\n}\n\nexport function verifyReceipt(\n r: Receipt,\n issuerPublicKey: Uint8Array,\n): boolean {\n try {\n const parsed = ReceiptSchema.parse(r);\n const { issuerSig, ...unsigned } = parsed;\n return verify(\n canonicalJSONBytes(unsigned),\n hexToBytes(issuerSig),\n issuerPublicKey,\n );\n } catch {\n return false;\n }\n}\n","import {\n PassSchema,\n verifyPass as verifyPassFn,\n type Pass,\n type PassKind,\n type PassMetadata,\n type PassState,\n} from './pass.js';\nimport { RedemptionSchema, type Redemption } from './redemption.js';\nimport {\n ReceiptSchema,\n type ReceiptPayload,\n type Receipt,\n} from '../receipts/receipt.js';\nimport { FlurApiError } from '../errors.js';\n\n// Re-export so existing `from \"./client.js\"` imports keep working.\nexport { FlurApiError };\n\nexport type PassesClientOptions = {\n baseUrl: string;\n /** Pre-configured fetch (typically `createHmacFetch(...)`). Falls back to global fetch. */\n fetchImpl?: typeof fetch;\n};\n\nexport type IssuePassInput = {\n /** Device this pass is bound to. Required (BE-19). */\n holderDeviceId: string;\n /** 32-byte hex Ed25519 public key of the bound device. Required (BE-19). */\n holderDevicePubkey: string;\n /** Pass kind (server may default for templated flows). */\n kind: PassKind;\n /** Optional fixed amount for monetary passes (kobo). */\n amountKobo?: number;\n /** Optional cumulative spend cap in kobo across all redemptions. */\n cumulativeCapKobo?: number;\n validFromMs: number;\n validUntilMs: number;\n metadata?: PassMetadata;\n /** Optional template grouping id (server may emit one if omitted). */\n templateId?: string;\n /** Optional human-facing holder identity. */\n holderUserId?: string;\n /** Optional client-supplied id for idempotency / retries. */\n passId?: string;\n};\n\nexport type ListPassesInput = {\n holderDeviceId?: string;\n holderUserId?: string;\n state?: PassState;\n kind?: PassKind;\n templateId?: string;\n limit?: number;\n cursor?: string;\n};\n\nexport type ListPassesResponse = {\n items: Pass[];\n nextCursor: string | null;\n};\n\nexport type RevokePassInput = {\n reason: string;\n};\n\nexport type RedeemPassResponse = {\n pass: Pass;\n redemptionId: string;\n};\n\nexport type AtomicRedeemReceiptInput = {\n payeeUserId: string;\n payload?: ReceiptPayload;\n receiptId?: string;\n};\n\nexport type AtomicRedeemResponse = {\n pass: Pass;\n redemptionId: string;\n receipt: Receipt;\n};\n\nexport type PassesClient = {\n issuePass: (input: IssuePassInput) => Promise<Pass>;\n listPasses: (input: ListPassesInput) => Promise<ListPassesResponse>;\n getPass: (passId: string) => Promise<Pass>;\n redeemPassDetailed: (\n passId: string,\n redemption: Redemption,\n ) => Promise<RedeemPassResponse>;\n redeemPass: (passId: string, redemption: Redemption) => Promise<Pass>;\n redeemPassWithReceipt: (\n passId: string,\n redemption: Redemption,\n receipt: AtomicRedeemReceiptInput,\n ) => Promise<AtomicRedeemResponse>;\n revokePass: (passId: string, input: RevokePassInput) => Promise<Pass>;\n /** Local Ed25519 verification of a pass envelope under the supplied issuer public key. */\n verifyPass: (pass: Pass, issuerPublicKey: Uint8Array) => boolean;\n};\n\nexport function createPassesClient(opts: PassesClientOptions): PassesClient {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl)\n throw new Error('createPassesClient: no fetch implementation available');\n const baseUrl = opts.baseUrl.replace(/\\/$/, '');\n\n async function call<T>(\n method: string,\n path: string,\n body: unknown,\n parser: (raw: unknown) => T,\n ): Promise<T> {\n const init: RequestInit = {\n method,\n headers: {\n 'content-type': 'application/json',\n accept: 'application/json',\n },\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n const resp = await fetchImpl(`${baseUrl}${path}`, init);\n const text = await resp.text();\n let raw: unknown = undefined;\n if (text) {\n try {\n raw = JSON.parse(text);\n } catch {\n // non-JSON error body\n }\n }\n if (!resp.ok) {\n const code =\n (raw &&\n typeof raw === 'object' &&\n 'code' in raw &&\n typeof (raw as { code: unknown }).code === 'string'\n ? (raw as { code: string }).code\n : undefined) ?? `http_${resp.status}`;\n const message =\n (raw &&\n typeof raw === 'object' &&\n 'message' in raw &&\n typeof (raw as { message: unknown }).message === 'string'\n ? (raw as { message: string }).message\n : undefined) ?? `request failed with status ${resp.status}`;\n throw new FlurApiError(resp.status, code, message, raw);\n }\n return parser(raw);\n }\n\n return {\n issuePass: (input) =>\n call('POST', '/v1/passes', input, (raw) => PassSchema.parse(raw)),\n\n listPasses: (input) => {\n const qs = new URLSearchParams();\n if (input.holderDeviceId) qs.set('holderDeviceId', input.holderDeviceId);\n if (input.holderUserId) qs.set('holderUserId', input.holderUserId);\n if (input.state) qs.set('state', input.state);\n if (input.kind) qs.set('kind', input.kind);\n if (input.templateId) qs.set('templateId', input.templateId);\n if (typeof input.limit === 'number') qs.set('limit', String(input.limit));\n if (input.cursor) qs.set('cursor', input.cursor);\n const path = `/v1/passes${qs.size > 0 ? `?${qs.toString()}` : ''}`;\n return call('GET', path, undefined, (raw) => {\n const obj = raw as { items?: unknown; nextCursor?: unknown };\n const items = (obj.items as unknown[]).map((it) =>\n PassSchema.parse(it),\n );\n const nextCursor =\n typeof obj.nextCursor === 'string' ? obj.nextCursor : null;\n return { items, nextCursor };\n });\n },\n\n getPass: (passId) =>\n call(\n 'GET',\n `/v1/passes/${encodeURIComponent(passId)}`,\n undefined,\n (raw) => PassSchema.parse(raw),\n ),\n\n redeemPass: (passId, redemption) =>\n call(\n 'POST',\n `/v1/passes/${encodeURIComponent(passId)}/redeem`,\n RedemptionSchema.parse(redemption),\n (raw) => {\n const obj = raw as { redemptionId?: unknown };\n return {\n pass: PassSchema.parse(raw),\n redemptionId:\n typeof obj.redemptionId === 'string' ? obj.redemptionId : '',\n };\n },\n ).then((result) => result.pass),\n\n redeemPassDetailed: (passId, redemption) =>\n call(\n 'POST',\n `/v1/passes/${encodeURIComponent(passId)}/redeem`,\n RedemptionSchema.parse(redemption),\n (raw) => {\n const obj = raw as { redemptionId?: unknown };\n return {\n pass: PassSchema.parse(raw),\n redemptionId:\n typeof obj.redemptionId === 'string' ? obj.redemptionId : '',\n };\n },\n ),\n\n redeemPassWithReceipt: (passId, redemption, receipt) =>\n call(\n 'POST',\n `/v1/passes/${encodeURIComponent(passId)}/redeem-with-receipt`,\n {\n redemption: RedemptionSchema.parse(redemption),\n receipt,\n },\n (raw) => {\n const obj = raw as {\n pass?: unknown;\n redemptionId?: unknown;\n receipt?: unknown;\n };\n return {\n pass: PassSchema.parse(obj.pass),\n redemptionId:\n typeof obj.redemptionId === 'string' ? obj.redemptionId : '',\n receipt: ReceiptSchema.parse(obj.receipt),\n };\n },\n ),\n\n revokePass: (passId, input) =>\n call(\n 'POST',\n `/v1/passes/${encodeURIComponent(passId)}/revoke`,\n input,\n (raw) => PassSchema.parse(raw),\n ),\n\n verifyPass: (pass, issuerPublicKey) => verifyPassFn(pass, issuerPublicKey),\n };\n}\n","import {\n ReceiptSchema,\n verifyReceipt as verifyReceiptFn,\n type Receipt,\n type ReceiptChannel,\n type ReceiptPayload,\n} from './receipt.js';\nimport { FlurApiError } from '../errors.js';\n\nexport type ReceiptsClientOptions = {\n baseUrl: string;\n fetchImpl?: typeof fetch;\n};\n\nexport type IssueReceiptInput = {\n channel: ReceiptChannel;\n /** Required for cash channel; FK to send_intents.id. */\n intentId?: string;\n /** Required for pass channel; FK to pass_redemptions.id. */\n passRedemptionId?: string;\n payerUserId: string;\n payeeUserId: string;\n amountKobo: number;\n currency: string;\n payload?: ReceiptPayload;\n /** Optional client-supplied id for idempotency / retries. */\n receiptId?: string;\n};\n\nexport type ListReceiptsInput = {\n /** Filter by either side of the receipt. Server scopes by caller identity. */\n payerUserId?: string;\n payeeUserId?: string;\n channel?: ReceiptChannel;\n limit?: number;\n cursor?: string;\n};\n\nexport type ListReceiptsResponse = {\n items: Receipt[];\n nextCursor: string | null;\n};\n\nexport type ReceiptsClient = {\n issueReceipt: (input: IssueReceiptInput) => Promise<Receipt>;\n /** Alias of `getById`, matches addendum surface. */\n getReceipt: (receiptId: string) => Promise<Receipt>;\n getById: (receiptId: string) => Promise<Receipt>;\n /** Look up a cash-channel receipt by its originating intentId. */\n getByIntentId: (intentId: string) => Promise<Receipt>;\n /** Look up a pass-channel receipt by its originating passRedemptionId. */\n getByPassRedemptionId: (passRedemptionId: string) => Promise<Receipt>;\n listForUser: (input: ListReceiptsInput) => Promise<ListReceiptsResponse>;\n /** Local Ed25519 verification of a receipt envelope under the supplied issuer key. */\n verifyReceipt: (receipt: Receipt, issuerPublicKey: Uint8Array) => boolean;\n};\n\nexport function createReceiptsClient(\n opts: ReceiptsClientOptions,\n): ReceiptsClient {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl)\n throw new Error('createReceiptsClient: no fetch implementation available');\n const baseUrl = opts.baseUrl.replace(/\\/$/, '');\n\n async function call<T>(\n method: string,\n path: string,\n body: unknown,\n parser: (raw: unknown) => T,\n ): Promise<T> {\n const init: RequestInit = {\n method,\n headers: {\n 'content-type': 'application/json',\n accept: 'application/json',\n },\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n const resp = await fetchImpl(`${baseUrl}${path}`, init);\n const text = await resp.text();\n let raw: unknown = undefined;\n if (text) {\n try {\n raw = JSON.parse(text);\n } catch {\n // ignore non-JSON\n }\n }\n if (!resp.ok) {\n const code =\n raw &&\n typeof raw === 'object' &&\n 'code' in raw &&\n typeof (raw as { code: unknown }).code === 'string'\n ? (raw as { code: string }).code\n : `http_${resp.status}`;\n const message =\n raw &&\n typeof raw === 'object' &&\n 'message' in raw &&\n typeof (raw as { message: unknown }).message === 'string'\n ? (raw as { message: string }).message\n : `request failed with status ${resp.status}`;\n throw new FlurApiError(resp.status, code, message, raw);\n }\n return parser(raw);\n }\n\n const getById: ReceiptsClient['getById'] = (receiptId) =>\n call(\n 'GET',\n `/v1/receipts/${encodeURIComponent(receiptId)}`,\n undefined,\n (raw) => ReceiptSchema.parse(raw),\n );\n\n return {\n issueReceipt: (input) =>\n call('POST', '/v1/receipts', input, (raw) => ReceiptSchema.parse(raw)),\n\n getReceipt: getById,\n getById,\n\n getByIntentId: (intentId) =>\n call(\n 'GET',\n `/v1/receipts/by-intent/${encodeURIComponent(intentId)}`,\n undefined,\n (raw) => ReceiptSchema.parse(raw),\n ),\n\n getByPassRedemptionId: (passRedemptionId) =>\n call(\n 'GET',\n `/v1/receipts/by-pass-redemption/${encodeURIComponent(passRedemptionId)}`,\n undefined,\n (raw) => ReceiptSchema.parse(raw),\n ),\n\n listForUser: (input) => {\n const qs = new URLSearchParams();\n if (input.payerUserId) qs.set('payerUserId', input.payerUserId);\n if (input.payeeUserId) qs.set('payeeUserId', input.payeeUserId);\n if (input.channel) qs.set('channel', input.channel);\n if (typeof input.limit === 'number') qs.set('limit', String(input.limit));\n if (input.cursor) qs.set('cursor', input.cursor);\n const path = `/v1/receipts${qs.size > 0 ? `?${qs.toString()}` : ''}`;\n return call('GET', path, undefined, (raw) => {\n const obj = raw as { items?: unknown; nextCursor?: unknown };\n const items = (obj.items as unknown[]).map((it) =>\n ReceiptSchema.parse(it),\n );\n const nextCursor =\n typeof obj.nextCursor === 'string' ? obj.nextCursor : null;\n return { items, nextCursor };\n });\n },\n\n verifyReceipt: (receipt, issuerPublicKey) =>\n verifyReceiptFn(receipt, issuerPublicKey),\n };\n}\n","import {\n encodeNQR,\n parseNQR,\n type NQRPayloadInput,\n type ParsedNQR,\n} from '../nqr/index.js';\nimport { createHmacFetch } from '../auth/middleware.js';\nimport { createPassesClient, type PassesClient } from '../passes/index.js';\nimport {\n createReceiptsClient,\n type ReceiptsClient,\n} from '../receipts/index.js';\n\nexport type FlurInitOptions = {\n apiKey: string;\n apiSecret: string;\n baseUrl: string;\n fetchImpl?: typeof fetch;\n /** When true, all QR generation is performed locally without any network call. */\n offlineMode?: boolean;\n /** Optional scope claim forwarded as `X-Flur-Scope`. Backend remains authoritative. */\n scope?: readonly string[];\n};\n\nexport type FlurPaymentEvent = {\n type: string;\n reference?: string;\n [k: string]: unknown;\n};\n\nexport type SubscribeOptions = {\n reference: string;\n onEvent: (event: FlurPaymentEvent) => void;\n onError?: (err: unknown) => void;\n};\n\nexport function generateStaticQR(\n input: Omit<NQRPayloadInput, 'pointOfInitiation'>,\n): string {\n return encodeNQR({ ...input, pointOfInitiation: 'static' });\n}\n\nexport function generateDynamicQR(\n input: Omit<NQRPayloadInput, 'pointOfInitiation'>,\n): string {\n return encodeNQR({ ...input, pointOfInitiation: 'dynamic' });\n}\n\nexport function parseQR(payload: string): ParsedNQR {\n return parseNQR(payload);\n}\n\nexport type CashNamespace = {\n generateStaticQR: typeof generateStaticQR;\n generateDynamicQR: typeof generateDynamicQR;\n parseQR: typeof parseQR;\n subscribeToPayments: (opts: SubscribeOptions) => () => void;\n};\n\nexport type FlurHandle = CashNamespace & {\n /** Cash / money: NQR generation, payment subscriptions, transfers (future). */\n cash: CashNamespace;\n /** Passes: tickets, vouchers, loyalty, transit. */\n passes: PassesClient;\n /** Receipts: signed, immutable views over cash + pass events. */\n receipts: ReceiptsClient;\n};\n\nexport function init(opts: FlurInitOptions): FlurHandle {\n const signedFetch = createHmacFetch({\n apiKey: opts.apiKey,\n apiSecret: opts.apiSecret,\n fetchImpl: opts.fetchImpl,\n scope: opts.scope,\n });\n const baseUrl = opts.baseUrl.replace(/\\/$/, '');\n\n function subscribeToPayments(s: SubscribeOptions) {\n const controller = new AbortController();\n let cancelled = false;\n\n (async () => {\n try {\n const url = `${baseUrl}/v1/payments/subscribe?reference=${encodeURIComponent(s.reference)}`;\n const resp = await signedFetch(url, {\n method: 'GET',\n headers: { accept: 'text/event-stream' },\n signal: controller.signal,\n });\n if (!resp.body) return;\n const reader = resp.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n while (!cancelled) {\n const { value, done } = await reader.read();\n if (done) return;\n buffer += decoder.decode(value, { stream: true });\n let idx;\n while ((idx = buffer.indexOf('\\n\\n')) >= 0) {\n const chunk = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 2);\n for (const line of chunk.split('\\n')) {\n if (!line.startsWith('data:')) continue;\n const json = line.slice(5).trim();\n if (!json) continue;\n try {\n s.onEvent(JSON.parse(json) as FlurPaymentEvent);\n } catch (err) {\n s.onError?.(err);\n }\n }\n }\n }\n } catch (err) {\n if (!cancelled) s.onError?.(err);\n }\n })();\n\n return () => {\n cancelled = true;\n controller.abort();\n };\n }\n\n const cash: CashNamespace = {\n generateStaticQR,\n generateDynamicQR,\n parseQR,\n subscribeToPayments,\n };\n\n const passes = createPassesClient({ baseUrl, fetchImpl: signedFetch });\n const receipts = createReceiptsClient({ baseUrl, fetchImpl: signedFetch });\n\n return {\n // top-level back-compat surface\n generateStaticQR,\n generateDynamicQR,\n parseQR,\n subscribeToPayments,\n // namespaces\n cash,\n passes,\n receipts,\n };\n}\n","import { z } from 'zod';\nimport { FlurApiError } from '../errors.js';\n\nexport const ACCOUNT_TYPES = ['personal', 'business', 'partner'] as const;\nexport type AccountType = (typeof ACCOUNT_TYPES)[number];\n\nexport const ACCOUNT_STATUSES = ['active', 'suspended', 'closed'] as const;\nexport type AccountStatus = (typeof ACCOUNT_STATUSES)[number];\n\nexport const MEMBERSHIP_ROLES = ['owner', 'admin', 'driver', 'staff'] as const;\nexport type MembershipRole = (typeof MEMBERSHIP_ROLES)[number];\n\nexport const AccountSchema = z.object({\n accountId: z.string().uuid(),\n type: z.enum(ACCOUNT_TYPES),\n displayName: z.string().min(1),\n status: z.enum(ACCOUNT_STATUSES),\n ownerUserId: z.string().uuid().nullable(),\n createdAtMs: z.number().int().nonnegative(),\n});\nexport type Account = z.infer<typeof AccountSchema>;\n\nexport const AccountMembershipSchema = z.object({\n accountId: z.string().uuid(),\n userId: z.string().uuid(),\n role: z.enum(MEMBERSHIP_ROLES),\n createdAtMs: z.number().int().nonnegative(),\n});\nexport type AccountMembership = z.infer<typeof AccountMembershipSchema>;\n\nexport type AccountsClientOptions = {\n baseUrl: string;\n /** Pre-configured fetch (e.g. with a session bearer or partner HMAC). */\n fetchImpl?: typeof fetch;\n};\n\nexport type CreateBusinessAccountInput = {\n displayName: string;\n type?: 'business' | 'partner';\n};\n\nexport type AddMemberInput = {\n userId: string;\n role: MembershipRole;\n};\n\nexport type AccountsClient = {\n listMyAccounts: () => Promise<{ items: Account[] }>;\n getAccount: (accountId: string) => Promise<Account>;\n listMembers: (accountId: string) => Promise<{ items: AccountMembership[] }>;\n createBusinessAccount: (\n input: CreateBusinessAccountInput,\n ) => Promise<Account>;\n addMember: (\n accountId: string,\n input: AddMemberInput,\n ) => Promise<AccountMembership>;\n};\n\nexport function createAccountsClient(\n opts: AccountsClientOptions,\n): AccountsClient {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error('createAccountsClient: no fetch implementation available');\n }\n const baseUrl = opts.baseUrl.replace(/\\/$/, '');\n\n async function call<T>(\n method: string,\n path: string,\n body: unknown,\n parser: (raw: unknown) => T,\n ): Promise<T> {\n const init: RequestInit = {\n method,\n headers: {\n 'content-type': 'application/json',\n accept: 'application/json',\n },\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n const resp = await fetchImpl(`${baseUrl}${path}`, init);\n const text = await resp.text();\n let raw: unknown = undefined;\n if (text) {\n try {\n raw = JSON.parse(text);\n } catch {\n // non-JSON\n }\n }\n if (!resp.ok) {\n const code =\n raw &&\n typeof raw === 'object' &&\n 'code' in raw &&\n typeof (raw as { code: unknown }).code === 'string'\n ? (raw as { code: string }).code\n : `http_${resp.status}`;\n const message =\n raw &&\n typeof raw === 'object' &&\n 'message' in raw &&\n typeof (raw as { message: unknown }).message === 'string'\n ? (raw as { message: string }).message\n : `request failed with status ${resp.status}`;\n throw new FlurApiError(resp.status, code, message, raw);\n }\n return parser(raw);\n }\n\n const itemsSchema = z.object({ items: z.array(AccountSchema) });\n const memberItemsSchema = z.object({\n items: z.array(AccountMembershipSchema),\n });\n\n return {\n listMyAccounts: () =>\n call('GET', '/v1/accounts/me', undefined, (raw) =>\n itemsSchema.parse(raw),\n ),\n getAccount: (accountId) =>\n call(\n 'GET',\n `/v1/accounts/${encodeURIComponent(accountId)}`,\n undefined,\n (raw) => AccountSchema.parse(raw),\n ),\n listMembers: (accountId) =>\n call(\n 'GET',\n `/v1/accounts/${encodeURIComponent(accountId)}/members`,\n undefined,\n (raw) => memberItemsSchema.parse(raw),\n ),\n createBusinessAccount: (input) =>\n call('POST', '/v1/accounts', input, (raw) => AccountSchema.parse(raw)),\n addMember: (accountId, input) =>\n call(\n 'POST',\n `/v1/accounts/${encodeURIComponent(accountId)}/members`,\n input,\n (raw) => AccountMembershipSchema.parse(raw),\n ),\n };\n}\n","import { z } from 'zod';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { hmac } from '@noble/hashes/hmac';\nimport { bytesToHex } from '@noble/hashes/utils';\nimport { FlurApiError } from '../errors.js';\n\nexport const PARTNER_SCOPES = [\n 'passes:write',\n 'passes:read',\n 'passes:redeem',\n 'receipts:write',\n 'receipts:read',\n 'offline:issue',\n 'offline:settle',\n 'offline:read',\n] as const;\nexport type PartnerScope = (typeof PARTNER_SCOPES)[number];\n\nexport const ApiCredentialPublicSchema = z.object({\n id: z.string().uuid(),\n accountId: z.string().uuid(),\n keyId: z.string(),\n scopes: z.array(z.enum(PARTNER_SCOPES)),\n label: z.string().nullable(),\n createdAtMs: z.number().int().nonnegative(),\n lastUsedAtMs: z.number().int().nonnegative().nullable(),\n revokedAtMs: z.number().int().nonnegative().nullable(),\n});\nexport type ApiCredentialPublic = z.infer<typeof ApiCredentialPublicSchema>;\n\nexport const MintedApiCredentialSchema = ApiCredentialPublicSchema.extend({\n secret: z.string().min(1),\n});\nexport type MintedApiCredential = z.infer<typeof MintedApiCredentialSchema>;\n\nexport type PartnerClientOptions = {\n baseUrl: string;\n /** Stable account id of the partner; included for observability only. */\n accountId?: string;\n /** Public key id from the mint response (e.g. flur_pk_...). */\n keyId: string;\n /** Plaintext secret from the mint response (e.g. flur_sk_...). */\n secret: string;\n fetchImpl?: typeof fetch;\n /** Override clock for tests. Returns ms. */\n nowMs?: () => number;\n /** Override nonce generator for tests. */\n nonce?: () => string;\n};\n\nconst enc = new TextEncoder();\n\nasync function sha256Hex(input: string | Uint8Array): Promise<string> {\n const data = typeof input === 'string' ? enc.encode(input) : input;\n return bytesToHex(sha256(data));\n}\n\nasync function hmacSha256Hex(keyHex: string, message: string): Promise<string> {\n // The server stores `secret_hash` as the hex string of sha256(secret) and\n // uses Node `createHmac('sha256', secret_hash)`, which treats the hex\n // STRING as raw UTF-8 bytes for the HMAC key. We do the same here.\n return bytesToHex(hmac(sha256, enc.encode(keyHex), enc.encode(message)));\n}\n\nfunction defaultNonce(): string {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n if (c?.randomUUID) return c.randomUUID();\n return `${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}`;\n}\n\n/**\n * Build the canonical signing string. Must mirror the server.\n */\nfunction canonical(params: {\n method: string;\n path: string;\n ts: string;\n nonce: string;\n bodyHash: string;\n}): string {\n return [\n params.method.toUpperCase(),\n params.path,\n params.ts,\n params.nonce,\n params.bodyHash,\n ].join('\\n');\n}\n\nexport type PartnerSignResult = {\n authorization: string;\n ts: string;\n nonce: string;\n bodyHash: string;\n};\n\nexport async function signPartnerRequest(params: {\n keyId: string;\n secret: string;\n method: string;\n path: string;\n body?: string | Uint8Array;\n nowMs?: number;\n nonce?: string;\n}): Promise<PartnerSignResult> {\n const ts = String(Math.floor((params.nowMs ?? Date.now()) / 1000));\n const nonce = params.nonce ?? defaultNonce();\n const bodyData =\n typeof params.body === 'string'\n ? enc.encode(params.body)\n : (params.body ?? new Uint8Array());\n const bodyHash = await sha256Hex(bodyData);\n const message = canonical({\n method: params.method,\n path: params.path,\n ts,\n nonce,\n bodyHash,\n });\n const signingKey = await sha256Hex(params.secret);\n const sig = await hmacSha256Hex(signingKey, message);\n return {\n authorization: `Flur-Hmac key=${params.keyId}, ts=${ts}, nonce=${nonce}, sig=${sig}`,\n ts,\n nonce,\n bodyHash,\n };\n}\n\nexport type FlurPartnerClient = {\n /** Make a signed request. Resolves to parsed JSON or throws FlurApiError. */\n request: <T = unknown>(opts: {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE';\n path: string;\n body?: unknown;\n }) => Promise<T>;\n /** Returns a fetch-compatible function with auto-signing. */\n fetch: typeof fetch;\n};\n\nexport function createFlurPartnerClient(\n opts: PartnerClientOptions,\n): FlurPartnerClient {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\n 'createFlurPartnerClient: no fetch implementation available',\n );\n }\n const baseUrl = opts.baseUrl.replace(/\\/$/, '');\n\n async function makeSignedInit(\n method: string,\n path: string,\n body?: string,\n ): Promise<RequestInit> {\n const sig = await signPartnerRequest({\n keyId: opts.keyId,\n secret: opts.secret,\n method,\n path,\n body: body ?? '',\n nowMs: opts.nowMs?.(),\n nonce: opts.nonce?.(),\n });\n const headers: Record<string, string> = {\n authorization: sig.authorization,\n accept: 'application/json',\n };\n if (body !== undefined) headers['content-type'] = 'application/json';\n const init: RequestInit = { method, headers };\n if (body !== undefined) init.body = body;\n return init;\n }\n\n async function request<T>(opts2: {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE';\n path: string;\n body?: unknown;\n }): Promise<T> {\n const bodyStr =\n opts2.body === undefined ? undefined : JSON.stringify(opts2.body);\n const init = await makeSignedInit(opts2.method, opts2.path, bodyStr);\n const resp = await fetchImpl(`${baseUrl}${opts2.path}`, init);\n const text = await resp.text();\n let raw: unknown;\n if (text) {\n try {\n raw = JSON.parse(text);\n } catch {\n // non-JSON\n }\n }\n if (!resp.ok) {\n const code =\n raw &&\n typeof raw === 'object' &&\n 'code' in raw &&\n typeof (raw as { code: unknown }).code === 'string'\n ? (raw as { code: string }).code\n : `http_${resp.status}`;\n const message =\n raw &&\n typeof raw === 'object' &&\n 'message' in raw &&\n typeof (raw as { message: unknown }).message === 'string'\n ? (raw as { message: string }).message\n : `request failed with status ${resp.status}`;\n throw new FlurApiError(resp.status, code, message, raw);\n }\n return raw as T;\n }\n\n const fetchLike: typeof fetch = async (input, init) => {\n const url = typeof input === 'string' ? input : (input as URL).toString();\n const u = new URL(url, baseUrl);\n const path = `${u.pathname}${u.search}`;\n const method = (init?.method ?? 'GET').toUpperCase();\n let bodyStr: string | undefined;\n if (init?.body) {\n bodyStr =\n typeof init.body === 'string'\n ? init.body\n : (init.body as { toString(): string }).toString();\n }\n const signed = await makeSignedInit(method, path, bodyStr);\n return fetchImpl(`${baseUrl}${path}`, {\n ...init,\n ...signed,\n headers: {\n ...(init?.headers as Record<string, string>),\n ...(signed.headers as Record<string, string>),\n },\n });\n };\n\n return { request, fetch: fetchLike };\n}\n\n/**\n * SDK helper for partner credential management endpoints. Uses an arbitrary\n * fetchImpl (typically a session-authenticated fetch) — not the partner HMAC.\n */\nexport type ApiCredentialsAdminClient = {\n list: (accountId: string) => Promise<{ items: ApiCredentialPublic[] }>;\n mint: (\n accountId: string,\n input: { scopes: PartnerScope[]; label?: string | null },\n ) => Promise<MintedApiCredential>;\n revoke: (\n accountId: string,\n credentialId: string,\n ) => Promise<ApiCredentialPublic>;\n};\n\nexport function createApiCredentialsAdminClient(opts: {\n baseUrl: string;\n fetchImpl?: typeof fetch;\n}): ApiCredentialsAdminClient {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\n 'createApiCredentialsAdminClient: no fetch implementation available',\n );\n }\n const baseUrl = opts.baseUrl.replace(/\\/$/, '');\n\n async function call<T>(\n method: string,\n path: string,\n body: unknown,\n parser: (raw: unknown) => T,\n ): Promise<T> {\n const init: RequestInit = {\n method,\n headers: {\n 'content-type': 'application/json',\n accept: 'application/json',\n },\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n const resp = await fetchImpl(`${baseUrl}${path}`, init);\n const text = await resp.text();\n let raw: unknown;\n if (text) {\n try {\n raw = JSON.parse(text);\n } catch {\n // non-JSON\n }\n }\n if (!resp.ok) {\n const code =\n raw &&\n typeof raw === 'object' &&\n 'code' in raw &&\n typeof (raw as { code: unknown }).code === 'string'\n ? (raw as { code: string }).code\n : `http_${resp.status}`;\n const message =\n raw &&\n typeof raw === 'object' &&\n 'message' in raw &&\n typeof (raw as { message: unknown }).message === 'string'\n ? (raw as { message: string }).message\n : `request failed with status ${resp.status}`;\n throw new FlurApiError(resp.status, code, message, raw);\n }\n return parser(raw);\n }\n\n const listSchema = z.object({\n items: z.array(ApiCredentialPublicSchema),\n });\n\n return {\n list: (accountId) =>\n call(\n 'GET',\n `/v1/accounts/${accountId}/api-credentials`,\n undefined,\n (raw) => listSchema.parse(raw),\n ),\n mint: (accountId, input) =>\n call('POST', `/v1/accounts/${accountId}/api-credentials`, input, (raw) =>\n MintedApiCredentialSchema.parse(raw),\n ),\n revoke: (accountId, credentialId) =>\n call(\n 'DELETE',\n `/v1/accounts/${accountId}/api-credentials/${credentialId}`,\n undefined,\n (raw) => ApiCredentialPublicSchema.parse(raw),\n ),\n };\n}\n"],"mappings":"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","names":["z","z","z","candidate","init","z","z","z","z","z","z","bytesToHex","sha256","bytesToHex","init","z","HexString","z","z","HexSig","z","z","HexString","z","init","init","z","z","init","z","sha256","hmac","bytesToHex","z","sha256Hex","bytesToHex","sha256","hmac","defaultNonce","init"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/contracts.ts","../src/errors.ts","../src/primitives.ts","../src/nqr/fields.ts","../src/nqr/crc16.ts","../src/nqr/tlv.ts","../src/nqr/encoder.ts","../src/nqr/parser.ts","../src/nqr/routing.ts","../src/crypto/canonical.ts","../src/crypto/ct.ts","../src/crypto/ed25519.ts","../src/offline/oac.ts","../src/offline/codec.ts","../src/offline/messages.ts","../src/offline/settlements.ts","../src/auth/hmac.ts","../src/auth/middleware.ts","../src/passes/pass.ts","../src/passes/redemption.ts","../src/receipts/receipt.ts","../src/passes/client.ts","../src/receipts/client.ts","../src/client/flur.ts","../src/accounts/client.ts","../src/partner/client.ts","../src/me-offline/client.ts"],"sourcesContent":["import { z, type ZodType } from 'zod';\nimport {\n AccountSummaryResponseSchema,\n AuthLogoutRequestSchema,\n AuthRefreshRequestSchema,\n AuthRefreshResponseSchema,\n CreatePayLinkResponseSchema,\n CreateTransferRequestSchema,\n E164Regex,\n HealthResponseSchema,\n OkResponseSchema,\n OnboardingCompleteRequestSchema,\n OnboardingCompleteResponseSchema,\n OnboardingStartRequestSchema,\n OnboardingStartResponseSchema,\n PinSetRequestSchema,\n PinVerifyRequestSchema,\n PushRegisterRequestSchema,\n RegisterDeviceRequestSchema,\n RegisterDeviceResponseSchema,\n RegisterSendDeviceKeyRequestSchema,\n ResolvePayLinkResponseSchema,\n ResolveRecipientRequestSchema,\n ResolveRecipientResponseSchema,\n SendChallengeRequestSchema,\n SendChallengeResponseSchema,\n SendVerifyRequestSchema,\n SendVerifyResponseSchema,\n TransactionDetailResponseSchema,\n TransactionsListResponseSchema,\n TransferResponseSchema,\n WelcomeResponseSchema,\n} from './contracts.js';\nimport { FlurError, mapToFlurError } from './errors.js';\nimport { type Money, moneyMinorToNumber, normalizeE164 } from './primitives.js';\n\nexport type FlurClientOptions = {\n baseUrl: string;\n fetchImpl?: typeof fetch;\n timeoutMs?: number;\n getExtraHeaders?: () =>\n | Record<string, string>\n | Promise<Record<string, string>>;\n};\n\nexport type OnboardingFallback = 'SILENT_AUTH' | 'OTP';\n\nexport type OnboardingStartInput = {\n phoneE164: string;\n appInstanceId: string;\n platform: 'android' | 'ios' | 'web';\n turnstileToken?: string;\n appAttestation?: {\n provider: 'android' | 'ios' | 'web';\n token: string;\n };\n firstName?: string;\n lastName?: string;\n};\n\nexport type OnboardingStartResponse = {\n requestId: string;\n checkUrl?: string;\n expiresInSec: number;\n fallback: OnboardingFallback;\n};\n\nexport type OnboardingRiskReason =\n | 'SIM_SWAP_RECENT'\n | 'ROAMING'\n | 'CARRIER_CHANGED';\n\nexport type OnboardingCompleteInput = {\n requestId: string;\n code: string;\n appInstanceId: string;\n fingerprintHash?: string;\n};\n\nexport type OnboardingCompleteResponse = {\n sessionToken: string;\n userId: string;\n restricted: boolean;\n risk_reasons: OnboardingRiskReason[];\n stepUpRequired?: boolean;\n riskStatus?: 'ok' | 'unavailable';\n};\n\nexport type RegisterDeviceInput = {\n userId: string;\n appInstanceId: string;\n platform: string;\n model?: string;\n networkSignals: {\n ip: string;\n asn?: number;\n country?: string;\n carrier?: string;\n };\n};\n\nexport type DeviceTrustState =\n | 'TRUSTED_PRIMARY'\n | 'TRUSTED_SECONDARY'\n | 'UNVERIFIED';\n\nexport type RegisterDeviceResponse = {\n deviceId: string;\n fingerprintHash: string;\n driftScore: number;\n trustState: DeviceTrustState;\n stepUpRequired: boolean;\n};\n\nexport type AuthRefreshInput = {\n userId: string;\n refreshToken: string;\n appInstanceId: string;\n fingerprintHash: string;\n};\n\nexport type AuthRefreshResponse = {\n refreshToken: string;\n stepUpRequired: boolean;\n};\n\nexport type AuthLogoutInput = {\n userId: string;\n refreshToken: string;\n};\n\nexport type PinSetInput = {\n userId: string;\n pin: string;\n};\n\nexport type PinVerifyInput = {\n userId: string;\n pin: string;\n};\n\nexport type RegisterSendDeviceKeyInput = {\n userId: string;\n deviceId: string;\n publicKey: string;\n};\n\nexport type SendChallengeInput = {\n userId: string;\n deviceId: string;\n /** Optional step-up purpose. Backend defaults to 'send_money'. */\n purpose?: 'send_money' | 'offline_revoke';\n};\n\nexport type SendChallengeResponse = {\n challengeId: string;\n nonce: string;\n expiresAt: string;\n};\n\nexport type SendVerifyInput = {\n userId: string;\n deviceId: string;\n challengeId: string;\n signature: string;\n};\n\nexport type SendVerifyResponse = {\n sendAuthToken: string;\n};\n\nexport type RecipientResolveInput = {\n identifier: string;\n};\n\nexport type RecipientResolveResponse = {\n recipientUserId: string;\n displayName: string;\n normalizedIdentifier: string;\n isActive: boolean;\n};\n\nexport type TransferInput = {\n recipientIdentifier: string;\n amountMinor: number;\n currency: string;\n sendAuthToken: string;\n};\n\nexport type TransferStatus = 'SETTLED' | 'PENDING_REVIEW' | 'DECLINED';\n\nexport type TransferResponse = {\n transactionId: string;\n status: TransferStatus;\n userStatus: TransferStatus;\n recipientName: string;\n timestamp: string;\n};\n\nexport type TransactionDirection = 'OUTGOING' | 'INCOMING';\n\nexport type AccountActivityItem = {\n id: string;\n type: string;\n direction: TransactionDirection;\n name: string;\n identifier: string;\n amountMinor: number;\n currency: string;\n status: string;\n timestamp: string;\n};\n\nexport type AccountSummaryResponse = {\n balance: number;\n currency: string;\n dailySendLimit: number;\n dailySendRemaining: number;\n kycTier: string;\n kycStatus: string;\n recentActivity: AccountActivityItem[];\n};\n\nexport type TransactionsListResponse = {\n items: AccountActivityItem[];\n nextCursor: string | null;\n};\n\nexport type TransactionDetailResponse = {\n transactionId: string;\n type: string;\n direction: TransactionDirection;\n counterpartyName: string;\n counterpartyIdentifier: string;\n amountMinor: number;\n currency: string;\n status: string;\n timestamp: string;\n};\n\nexport type PushPlatform = 'ios' | 'android' | 'web';\n\nexport type PushRegisterInput = {\n deviceId: string;\n platform: PushPlatform;\n token: string;\n};\n\nexport type CreatePayLinkResponse = {\n token: string;\n};\n\nexport type ResolvePayLinkResponse = {\n recipientUserId: string;\n displayName: string;\n normalizedIdentifier: string;\n isActive: boolean;\n};\n\nexport type AuthorizedOptions = {\n accessToken: string;\n};\n\nexport type CreateTransferOptions = AuthorizedOptions & {\n deviceId: string;\n idempotencyKey: string;\n};\n\nexport type ListTransactionsOptions = AuthorizedOptions & {\n cursor?: string;\n limit?: number;\n};\n\nexport type BiometricSigner = {\n getOrCreateKeyPair(deviceId: string): Promise<string>;\n sign(payload: string): Promise<string>;\n};\n\nexport type SendMoneyInput = {\n recipientIdentifier: string;\n money: Money;\n sendAuthToken: string;\n idempotencyKey?: string;\n defaultCountry?: string;\n};\n\nexport type SendMoneyOptions = AuthorizedOptions & {\n deviceId: string;\n};\n\nexport type AuthorizeSendWithBiometricInput = {\n userId: string;\n deviceId: string;\n accessToken: string;\n signer: BiometricSigner;\n};\n\nexport class FlurClient {\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof fetch;\n private readonly timeoutMs: number;\n private readonly getExtraHeaders?: () =>\n | Record<string, string>\n | Promise<Record<string, string>>;\n\n constructor(opts: FlurClientOptions) {\n this.baseUrl = opts.baseUrl.replace(/\\/$/, '');\n this.fetchImpl = opts.fetchImpl ?? fetch;\n this.timeoutMs = opts.timeoutMs ?? 10_000;\n this.getExtraHeaders = opts.getExtraHeaders;\n }\n\n async health(): Promise<{ ok: boolean }> {\n return this.requestJson(\n '/health',\n { method: 'GET' },\n undefined,\n HealthResponseSchema,\n );\n }\n\n async welcome(): Promise<{ message: string }> {\n return this.requestJson(\n '/welcome',\n { method: 'GET' },\n undefined,\n WelcomeResponseSchema,\n );\n }\n\n async onboardingStart(\n input: OnboardingStartInput,\n ): Promise<OnboardingStartResponse> {\n return this.requestJson(\n '/v1/onboarding/start',\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n },\n OnboardingStartRequestSchema,\n OnboardingStartResponseSchema,\n input,\n );\n }\n\n async onboardingComplete(\n input: OnboardingCompleteInput,\n ): Promise<OnboardingCompleteResponse> {\n return this.requestJson(\n '/v1/onboarding/complete',\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n },\n OnboardingCompleteRequestSchema,\n OnboardingCompleteResponseSchema,\n input,\n );\n }\n\n async registerDevice(\n input: RegisterDeviceInput,\n options: AuthorizedOptions,\n ): Promise<RegisterDeviceResponse> {\n return this.requestJson(\n '/v1/devices/register',\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.accessToken}`,\n },\n },\n RegisterDeviceRequestSchema,\n RegisterDeviceResponseSchema,\n input,\n );\n }\n\n async authRefresh(input: AuthRefreshInput): Promise<AuthRefreshResponse> {\n return this.requestJson(\n '/v1/auth/refresh',\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n },\n AuthRefreshRequestSchema,\n AuthRefreshResponseSchema,\n input,\n );\n }\n\n async authLogout(\n input: AuthLogoutInput,\n options: AuthorizedOptions,\n ): Promise<{ ok: boolean }> {\n return this.requestJson(\n '/v1/auth/logout',\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.accessToken}`,\n },\n },\n AuthLogoutRequestSchema,\n OkResponseSchema,\n input,\n );\n }\n\n async pinSet(\n input: PinSetInput,\n options: AuthorizedOptions,\n ): Promise<{ ok: boolean }> {\n return this.requestJson(\n '/v1/auth/pin/set',\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.accessToken}`,\n },\n },\n PinSetRequestSchema,\n OkResponseSchema,\n input,\n );\n }\n\n async pinVerify(\n input: PinVerifyInput,\n options: AuthorizedOptions,\n ): Promise<{ ok: boolean }> {\n return this.requestJson(\n '/v1/auth/pin/verify',\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.accessToken}`,\n },\n },\n PinVerifyRequestSchema,\n OkResponseSchema,\n input,\n );\n }\n\n async registerSendDeviceKey(\n input: RegisterSendDeviceKeyInput,\n options: AuthorizedOptions,\n ): Promise<{ ok: boolean }> {\n return this.requestJson(\n '/api/v1/auth/send/device-key',\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.accessToken}`,\n },\n },\n RegisterSendDeviceKeyRequestSchema,\n OkResponseSchema,\n input,\n );\n }\n\n async createSendChallenge(\n input: SendChallengeInput,\n options: AuthorizedOptions,\n ): Promise<SendChallengeResponse> {\n return this.requestJson(\n '/api/v1/auth/send/challenge',\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.accessToken}`,\n },\n },\n SendChallengeRequestSchema,\n SendChallengeResponseSchema,\n input,\n );\n }\n\n async verifySendChallenge(\n input: SendVerifyInput,\n options: AuthorizedOptions,\n ): Promise<SendVerifyResponse> {\n return this.requestJson(\n '/api/v1/auth/send/verify',\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.accessToken}`,\n },\n },\n SendVerifyRequestSchema,\n SendVerifyResponseSchema,\n input,\n );\n }\n\n async registerBiometricDeviceKey(input: {\n userId: string;\n deviceId: string;\n accessToken: string;\n signer: BiometricSigner;\n }): Promise<{ ok: boolean }> {\n const publicKey = await input.signer.getOrCreateKeyPair(input.deviceId);\n return this.registerSendDeviceKey(\n {\n userId: input.userId,\n deviceId: input.deviceId,\n publicKey,\n },\n { accessToken: input.accessToken },\n );\n }\n\n async authorizeSendWithBiometric(\n input: AuthorizeSendWithBiometricInput,\n ): Promise<SendVerifyResponse> {\n const challenge = await this.createSendChallenge(\n {\n userId: input.userId,\n deviceId: input.deviceId,\n },\n { accessToken: input.accessToken },\n );\n\n const signature = await input.signer.sign(challenge.nonce);\n return this.verifySendChallenge(\n {\n userId: input.userId,\n deviceId: input.deviceId,\n challengeId: challenge.challengeId,\n signature,\n },\n { accessToken: input.accessToken },\n );\n }\n\n async resolveRecipient(\n input: RecipientResolveInput,\n options: AuthorizedOptions,\n ): Promise<RecipientResolveResponse> {\n return this.requestJson(\n '/api/v1/recipients/resolve',\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.accessToken}`,\n },\n },\n ResolveRecipientRequestSchema,\n ResolveRecipientResponseSchema,\n input,\n );\n }\n\n async createTransfer(\n input: TransferInput,\n options: CreateTransferOptions,\n ): Promise<TransferResponse> {\n return this.requestJson(\n '/api/v1/transfers',\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.accessToken}`,\n 'x-device-id': options.deviceId,\n 'x-idempotency-key': options.idempotencyKey,\n },\n },\n CreateTransferRequestSchema,\n TransferResponseSchema,\n input,\n );\n }\n\n async sendMoney(\n input: SendMoneyInput,\n options: SendMoneyOptions,\n ): Promise<TransferResponse> {\n const normalizedRecipient = E164Regex.test(input.recipientIdentifier)\n ? input.recipientIdentifier\n : normalizeE164(input.recipientIdentifier, input.defaultCountry);\n\n const idempotencyKey = input.idempotencyKey ?? getSecureRandomUuid();\n return this.createTransfer(\n {\n recipientIdentifier: normalizedRecipient,\n amountMinor: moneyMinorToNumber(input.money.amountMinor),\n currency: input.money.currency,\n sendAuthToken: input.sendAuthToken,\n },\n {\n accessToken: options.accessToken,\n deviceId: options.deviceId,\n idempotencyKey,\n },\n );\n }\n\n async accountSummary(\n options: AuthorizedOptions,\n ): Promise<AccountSummaryResponse> {\n return this.requestJson(\n '/api/v1/account/summary',\n {\n method: 'GET',\n headers: {\n authorization: `Bearer ${options.accessToken}`,\n },\n },\n undefined,\n AccountSummaryResponseSchema,\n );\n }\n\n async listTransactions(\n options: ListTransactionsOptions,\n ): Promise<TransactionsListResponse> {\n const query = new URLSearchParams();\n if (\n typeof options.cursor === 'string' &&\n options.cursor.trim().length > 0\n ) {\n query.set('cursor', options.cursor);\n }\n if (typeof options.limit === 'number') {\n query.set('limit', String(options.limit));\n }\n\n const path =\n query.size > 0\n ? `/api/v1/transactions?${query.toString()}`\n : '/api/v1/transactions';\n return this.requestJson(\n path,\n {\n method: 'GET',\n headers: {\n authorization: `Bearer ${options.accessToken}`,\n },\n },\n undefined,\n TransactionsListResponseSchema,\n );\n }\n\n async transactionDetail(\n transactionId: string,\n options: AuthorizedOptions,\n ): Promise<TransactionDetailResponse> {\n const encodedId = encodeURIComponent(transactionId);\n return this.requestJson(\n `/api/v1/transactions/${encodedId}`,\n {\n method: 'GET',\n headers: {\n authorization: `Bearer ${options.accessToken}`,\n },\n },\n undefined,\n TransactionDetailResponseSchema,\n );\n }\n\n async registerPushToken(\n input: PushRegisterInput,\n options: AuthorizedOptions,\n ): Promise<{ ok: boolean }> {\n return this.requestJson(\n '/api/v1/push/register',\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.accessToken}`,\n },\n },\n PushRegisterRequestSchema,\n OkResponseSchema,\n input,\n );\n }\n\n async createPayLink(\n options: AuthorizedOptions,\n ): Promise<CreatePayLinkResponse> {\n return this.requestJson(\n '/api/v1/pay-links',\n {\n method: 'POST',\n headers: {\n authorization: `Bearer ${options.accessToken}`,\n },\n },\n undefined,\n CreatePayLinkResponseSchema,\n );\n }\n\n async resolvePayLink(\n token: string,\n options: AuthorizedOptions,\n ): Promise<ResolvePayLinkResponse> {\n const encodedToken = encodeURIComponent(token);\n return this.requestJson(\n `/api/v1/pay-links/${encodedToken}`,\n {\n method: 'GET',\n headers: {\n authorization: `Bearer ${options.accessToken}`,\n },\n },\n undefined,\n ResolvePayLinkResponseSchema,\n );\n }\n\n private async requestJson<TInput, TOutput>(\n path: string,\n init: RequestInit,\n requestSchema?: ZodType<TInput>,\n responseSchema?: ZodType<TOutput>,\n input?: TInput,\n ): Promise<TOutput> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n const t = setTimeout(() => controller.abort(), this.timeoutMs);\n let body = init.body;\n try {\n body = requestSchema\n ? JSON.stringify(requestSchema.parse(input))\n : init.body;\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new FlurError('Invalid request payload', 'INVALID_REQUEST', {\n details: err.flatten(),\n });\n }\n throw err;\n }\n\n try {\n let extraHeaders: Record<string, string> = {};\n if (this.getExtraHeaders) {\n extraHeaders = await this.getExtraHeaders();\n }\n\n const finalHeaders = {\n ...init.headers,\n ...extraHeaders,\n };\n\n const res = await this.fetchImpl(url, {\n ...init,\n headers: finalHeaders,\n body,\n signal: controller.signal,\n });\n if (!res.ok) throw await mapToFlurError(res);\n const payload = (await res.json()) as unknown;\n if (!responseSchema) return payload as TOutput;\n try {\n return responseSchema.parse(payload);\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new FlurError(\n 'SDK contract validation failed',\n 'INVALID_REQUEST',\n {\n details: err.flatten(),\n },\n );\n }\n throw err;\n }\n } catch (err: unknown) {\n if (err instanceof Error && err.name === 'AbortError') {\n throw new FlurError('Request timed out', 'TIMEOUT');\n }\n if (err instanceof FlurError) throw err;\n throw new FlurError('Network error', 'NETWORK_ERROR', {\n details: String(err),\n });\n } finally {\n clearTimeout(t);\n }\n }\n}\n\nfunction getSecureRandomUuid(): string {\n if (typeof globalThis.crypto?.randomUUID === 'function') {\n return globalThis.crypto.randomUUID();\n }\n throw new FlurError(\n 'Secure UUID generator unavailable; provide idempotencyKey',\n 'INVALID_REQUEST',\n );\n}\n","import { z } from 'zod';\n\nexport const E164Regex = /^\\+[1-9]\\d{7,14}$/;\n\nconst UuidSchema = z.string().uuid();\nconst IsoDateSchema = z.string().datetime({ offset: true });\nconst CurrencySchema = z\n .string()\n .trim()\n .length(3)\n .transform((value) => value.toUpperCase());\n\nexport const HealthResponseSchema = z.object({\n ok: z.boolean(),\n});\n\nexport const WelcomeResponseSchema = z.object({\n message: z.string(),\n});\n\nexport const OnboardingStartRequestSchema = z.object({\n phoneE164: z.string().regex(E164Regex),\n appInstanceId: z.string().min(3),\n platform: z.enum(['android', 'ios', 'web']),\n turnstileToken: z.string().min(20).optional(),\n appAttestation: z\n .object({\n provider: z.enum(['android', 'ios', 'web']),\n token: z.string().min(24),\n })\n .optional(),\n firstName: z.string().trim().min(1).max(80).optional(),\n lastName: z.string().trim().min(1).max(80).optional(),\n});\n\nexport const OnboardingStartResponseSchema = z.object({\n requestId: z.string().min(1),\n checkUrl: z.string().url().optional(),\n expiresInSec: z.number().int().positive(),\n fallback: z.enum(['SILENT_AUTH', 'OTP']),\n});\n\nexport const OnboardingCompleteRequestSchema = z.object({\n requestId: z.string().min(1),\n code: z.string().min(1).max(32),\n appInstanceId: z.string().min(3),\n fingerprintHash: z.string().min(3).optional(),\n});\n\nexport const OnboardingCompleteResponseSchema = z.object({\n sessionToken: z.string().min(1),\n userId: UuidSchema,\n restricted: z.boolean(),\n risk_reasons: z.array(\n z.enum(['SIM_SWAP_RECENT', 'ROAMING', 'CARRIER_CHANGED']),\n ),\n stepUpRequired: z.boolean().optional(),\n riskStatus: z.enum(['ok', 'unavailable']).optional(),\n});\n\nexport const RegisterDeviceRequestSchema = z.object({\n userId: UuidSchema,\n appInstanceId: z.string().min(3),\n platform: z.string().min(2),\n model: z.string().optional(),\n networkSignals: z.object({\n ip: z.string().min(3),\n asn: z.number().int().optional(),\n country: z.string().min(2).optional(),\n carrier: z.string().optional(),\n }),\n});\n\nexport const RegisterDeviceResponseSchema = z.object({\n deviceId: z.string().min(1),\n fingerprintHash: z.string().min(1),\n driftScore: z.number(),\n trustState: z.enum(['TRUSTED_PRIMARY', 'TRUSTED_SECONDARY', 'UNVERIFIED']),\n stepUpRequired: z.boolean(),\n});\n\nexport const AuthRefreshRequestSchema = z.object({\n userId: UuidSchema,\n refreshToken: z.string().min(8),\n appInstanceId: z.string().min(3),\n fingerprintHash: z.string().min(3),\n});\n\nexport const AuthRefreshResponseSchema = z.object({\n refreshToken: z.string().min(8),\n stepUpRequired: z.boolean(),\n});\n\nexport const AuthLogoutRequestSchema = z.object({\n userId: UuidSchema,\n refreshToken: z.string().min(8),\n});\n\nexport const PinSetRequestSchema = z.object({\n userId: UuidSchema,\n pin: z.string().regex(/^\\d{6}$/),\n});\n\nexport const PinVerifyRequestSchema = z.object({\n userId: UuidSchema,\n pin: z.string().regex(/^\\d{6}$/),\n});\n\nexport const OkResponseSchema = z.object({\n ok: z.boolean(),\n});\n\nexport const RegisterSendDeviceKeyRequestSchema = z.object({\n userId: UuidSchema,\n deviceId: z.string().min(3),\n publicKey: z.string().min(32),\n});\n\n/**\n * Supported step-up purposes for /api/v1/auth/send/challenge.\n * Mirrors `SUPPORTED_SEND_AUTH_PURPOSES` in flur-backend/src/routes/auth.ts.\n * Defaults to 'send_money' server-side when omitted.\n */\nexport const SEND_AUTH_PURPOSES = ['send_money', 'offline_revoke'] as const;\nexport type SendAuthPurpose = (typeof SEND_AUTH_PURPOSES)[number];\n\nexport const SendChallengeRequestSchema = z.object({\n userId: UuidSchema,\n deviceId: z.string().min(3),\n purpose: z.enum(SEND_AUTH_PURPOSES).optional(),\n});\n\nexport const SendChallengeResponseSchema = z.object({\n challengeId: UuidSchema,\n nonce: z.string().min(1),\n expiresAt: IsoDateSchema,\n});\n\nexport const SendVerifyRequestSchema = z.object({\n userId: UuidSchema,\n deviceId: z.string().min(3),\n challengeId: UuidSchema,\n signature: z.string().min(16),\n});\n\nexport const SendVerifyResponseSchema = z.object({\n sendAuthToken: z.string().min(16),\n});\n\nexport const ResolveRecipientRequestSchema = z.object({\n identifier: z.string().min(3),\n});\n\nexport const ResolveRecipientResponseSchema = z.object({\n recipientUserId: UuidSchema,\n displayName: z.string().min(1),\n normalizedIdentifier: z.string().regex(E164Regex),\n isActive: z.boolean(),\n});\n\nexport const CreateTransferRequestSchema = z.object({\n recipientIdentifier: z.string().min(3),\n amountMinor: z.number().int().positive(),\n currency: CurrencySchema,\n sendAuthToken: z.string().min(16),\n});\n\nconst TransferStatusSchema = z.enum(['SETTLED', 'PENDING_REVIEW', 'DECLINED']);\n\nexport const TransferResponseSchema = z.object({\n transactionId: z.string().min(1),\n status: TransferStatusSchema,\n userStatus: TransferStatusSchema,\n recipientName: z.string().min(1),\n timestamp: IsoDateSchema,\n});\n\nconst DirectionSchema = z.enum(['OUTGOING', 'INCOMING']);\n\nexport const AccountActivityItemSchema = z.object({\n id: z.string().min(1),\n type: z.string().min(1),\n direction: DirectionSchema,\n name: z.string().min(1),\n identifier: z.string().min(1),\n amountMinor: z.number().int(),\n currency: CurrencySchema,\n status: z.string().min(1),\n timestamp: IsoDateSchema,\n});\n\nexport const AccountSummaryResponseSchema = z.object({\n balance: z.number().int(),\n currency: CurrencySchema,\n dailySendLimit: z.number().int().nonnegative(),\n dailySendRemaining: z.number().int().nonnegative(),\n kycTier: z.string().min(1),\n kycStatus: z.string().min(1),\n recentActivity: z.array(AccountActivityItemSchema),\n});\n\nexport const TransactionsListResponseSchema = z.object({\n items: z.array(AccountActivityItemSchema),\n nextCursor: z.string().nullable(),\n});\n\nexport const TransactionDetailResponseSchema = z.object({\n transactionId: z.string().min(1),\n type: z.string().min(1),\n direction: DirectionSchema,\n counterpartyName: z.string().min(1),\n counterpartyIdentifier: z.string().min(1),\n amountMinor: z.number().int(),\n currency: CurrencySchema,\n status: z.string().min(1),\n timestamp: IsoDateSchema,\n});\n\nexport const PushRegisterRequestSchema = z.object({\n deviceId: z.string().min(3),\n platform: z.enum(['ios', 'android', 'web']),\n token: z.string().min(16),\n});\n\nexport const CreatePayLinkResponseSchema = z.object({\n token: z.string().min(1),\n});\n\nexport const ResolvePayLinkResponseSchema = z.object({\n recipientUserId: UuidSchema,\n displayName: z.string().min(1),\n normalizedIdentifier: z.string().regex(E164Regex),\n isActive: z.boolean(),\n});\n","export type FlurErrorCode =\n | 'NETWORK_ERROR'\n | 'HTTP_ERROR'\n | 'TIMEOUT'\n | 'UNKNOWN'\n | 'UNAUTHORIZED'\n | 'INVALID_REQUEST'\n | 'RATE_LIMITED'\n | 'NOT_FOUND'\n | 'USER_NOT_FOUND'\n | 'TOKEN_REPLAYED'\n | 'SESSION_MISMATCH'\n | 'PIN_INVALID'\n | 'PIN_LOCKED'\n | 'PIN_NOT_SET'\n | 'STEP_UP_REQUIRED'\n | 'DEVICE_KEY_NOT_REGISTERED'\n | 'CHALLENGE_INVALID'\n | 'CHALLENGE_EXPIRED'\n | 'DEVICE_KEY_REVOKED'\n | 'SIGNATURE_INVALID'\n | 'INVALID_RECIPIENT'\n | 'SEND_AUTH_INVALID'\n | 'IDEMPOTENCY_KEY_CONFLICT'\n | 'IDEMPOTENCY_IN_PROGRESS'\n | 'CANNOT_SEND_TO_SELF'\n | 'INSUFFICIENT_FUNDS';\n\nconst backendErrorCodeSet: ReadonlySet<FlurErrorCode> = new Set([\n 'UNAUTHORIZED',\n 'INVALID_REQUEST',\n 'RATE_LIMITED',\n 'NOT_FOUND',\n 'USER_NOT_FOUND',\n 'TOKEN_REPLAYED',\n 'SESSION_MISMATCH',\n 'PIN_INVALID',\n 'PIN_LOCKED',\n 'PIN_NOT_SET',\n 'STEP_UP_REQUIRED',\n 'DEVICE_KEY_NOT_REGISTERED',\n 'CHALLENGE_INVALID',\n 'CHALLENGE_EXPIRED',\n 'DEVICE_KEY_REVOKED',\n 'SIGNATURE_INVALID',\n 'INVALID_RECIPIENT',\n 'SEND_AUTH_INVALID',\n 'IDEMPOTENCY_KEY_CONFLICT',\n 'IDEMPOTENCY_IN_PROGRESS',\n 'CANNOT_SEND_TO_SELF',\n 'INSUFFICIENT_FUNDS',\n]);\n\nexport class FlurError extends Error {\n public readonly code: FlurErrorCode;\n public readonly status?: number;\n public readonly details?: unknown;\n public readonly reqId?: string | null;\n\n constructor(\n message: string,\n code: FlurErrorCode,\n opts?: { status?: number; details?: unknown; reqId?: string | null },\n ) {\n super(message);\n this.name = 'FlurError';\n this.code = code;\n this.status = opts?.status;\n this.details = opts?.details;\n this.reqId = opts?.reqId;\n }\n}\n\n/**\n * Generic API error thrown by HTTP clients in `flur.passes` / `flur.receipts`\n * for non-2xx responses. Lives at the SDK root so bounded-context modules\n * (passes, receipts) never cross-import each other.\n */\nexport class FlurApiError extends Error {\n constructor(\n public readonly status: number,\n public readonly code: string,\n message: string,\n public readonly raw?: unknown,\n ) {\n super(message);\n this.name = 'FlurApiError';\n }\n}\n\n/** Thrown by `buildRedemption` when the pass is past its `validUntilMs`. */\nexport class FlurExpiredError extends Error {\n public readonly code = 'PASS_EXPIRED' as const;\n constructor(message = 'pass is expired') {\n super(message);\n this.name = 'FlurExpiredError';\n }\n}\n\n/** Thrown by `buildRedemption` when `counter` is not strictly greater than the\n * caller-supplied `lastSeenCounter` (replay / out-of-order redemption attempt). */\nexport class FlurReplayError extends Error {\n public readonly code = 'PASS_REPLAY' as const;\n constructor(message = 'redemption counter is not strictly increasing') {\n super(message);\n this.name = 'FlurReplayError';\n }\n}\n\n/** Thrown by `buildRedemption` when this redemption would breach the pass's\n * `cumulativeCapKobo` given the caller-supplied `cumulativeUsedKobo`. */\nexport class FlurCapExceededError extends Error {\n public readonly code = 'PASS_CAP_EXCEEDED' as const;\n constructor(message = 'redemption exceeds cumulative cap') {\n super(message);\n this.name = 'FlurCapExceededError';\n }\n}\n\nexport async function mapToFlurError(res: Response): Promise<FlurError> {\n const reqId = res.headers.get('x-request-id');\n let details: unknown = undefined;\n let mappedCode: FlurErrorCode = 'HTTP_ERROR';\n let mappedMessage = `HTTP ${res.status}`;\n try {\n const ct = res.headers.get('content-type') ?? '';\n details = ct.includes('application/json')\n ? await res.json()\n : await res.text();\n if (details && typeof details === 'object') {\n const candidateCode = (details as { code?: unknown }).code;\n const candidateMessage = (\n details as { message?: unknown; error?: unknown }\n ).message;\n const fallbackMessage = (details as { error?: unknown }).error;\n\n if (\n typeof candidateCode === 'string' &&\n backendErrorCodeSet.has(candidateCode as FlurErrorCode)\n ) {\n mappedCode = candidateCode as FlurErrorCode;\n }\n\n if (typeof candidateMessage === 'string' && candidateMessage.length > 0) {\n mappedMessage = candidateMessage;\n } else if (\n typeof fallbackMessage === 'string' &&\n fallbackMessage.length > 0\n ) {\n mappedMessage = fallbackMessage;\n }\n }\n } catch {\n // ignore parse issues\n }\n return new FlurError(mappedMessage, mappedCode, {\n status: res.status,\n details,\n reqId,\n });\n}\n","import { z } from \"zod\";\r\nimport { FlurError } from \"./errors.js\";\r\nimport { E164Regex } from \"./contracts.js\";\r\n\r\nexport type Money = {\r\n amountMinor: bigint;\r\n currency: string;\r\n};\r\n\r\nconst CurrencyCodeSchema = z.string().trim().length(3).transform((value) => value.toUpperCase());\r\n\r\nconst currencyFractionDigits: Record<string, number> = {\r\n NGN: 2,\r\n USD: 2,\r\n EUR: 2,\r\n GBP: 2,\r\n CAD: 2,\r\n JPY: 0,\r\n};\r\n\r\nfunction getFractionDigits(currency: string): number {\r\n return currencyFractionDigits[currency] ?? 2;\r\n}\r\n\r\nexport function parseAmountInput(value: string, currency: string): Money {\r\n const normalizedCurrency = CurrencyCodeSchema.parse(currency);\r\n const raw = value.trim();\r\n\r\n if (!/^\\d+(\\.\\d+)?$/.test(raw)) {\r\n throw new FlurError(\"Invalid amount format\", \"INVALID_REQUEST\");\r\n }\r\n\r\n const [whole, fraction = \"\"] = raw.split(\".\");\r\n const fractionDigits = getFractionDigits(normalizedCurrency);\r\n\r\n if (fraction.length > fractionDigits) {\r\n throw new FlurError(\"Too many decimal places for currency\", \"INVALID_REQUEST\");\r\n }\r\n\r\n const paddedFraction = fraction.padEnd(fractionDigits, \"0\");\r\n const minorAsString = `${whole}${paddedFraction}`.replace(/^0+(\\d)/, \"$1\") || \"0\";\r\n const amountMinor = BigInt(minorAsString);\r\n\r\n if (amountMinor < 0n) {\r\n throw new FlurError(\"Amount cannot be negative\", \"INVALID_REQUEST\");\r\n }\r\n\r\n return {\r\n amountMinor,\r\n currency: normalizedCurrency,\r\n };\r\n}\r\n\r\nexport function formatAmount(amountMinor: bigint, currency: string): string {\r\n const normalizedCurrency = CurrencyCodeSchema.parse(currency);\r\n if (amountMinor < 0n) {\r\n throw new FlurError(\"Amount cannot be negative\", \"INVALID_REQUEST\");\r\n }\r\n\r\n const fractionDigits = getFractionDigits(normalizedCurrency);\r\n if (fractionDigits === 0) {\r\n return amountMinor.toString();\r\n }\r\n\r\n const divisor = 10n ** BigInt(fractionDigits);\r\n const whole = amountMinor / divisor;\r\n const fraction = (amountMinor % divisor).toString().padStart(fractionDigits, \"0\");\r\n return `${whole.toString()}.${fraction}`;\r\n}\r\n\r\nconst defaultCountryDialingCode: Record<string, string> = {\r\n NG: \"234\",\r\n US: \"1\",\r\n CA: \"1\",\r\n GB: \"44\",\r\n};\r\n\r\nexport function normalizeE164(input: string, defaultCountry?: string): string {\r\n const trimmed = input.trim();\r\n\r\n if (trimmed.startsWith(\"+\")) {\r\n if (!E164Regex.test(trimmed)) {\r\n throw new FlurError(\"Invalid phone number\", \"INVALID_REQUEST\");\r\n }\r\n return trimmed;\r\n }\r\n\r\n const digits = trimmed.replace(/\\D/g, \"\");\r\n if (digits.length === 0) {\r\n throw new FlurError(\"Invalid phone number\", \"INVALID_REQUEST\");\r\n }\r\n\r\n if (digits.startsWith(\"00\")) {\r\n const candidate = `+${digits.slice(2)}`;\r\n if (!E164Regex.test(candidate)) {\r\n throw new FlurError(\"Invalid phone number\", \"INVALID_REQUEST\");\r\n }\r\n return candidate;\r\n }\r\n\r\n const normalizedCountry = defaultCountry?.trim().toUpperCase();\r\n const countryCode = normalizedCountry ? defaultCountryDialingCode[normalizedCountry] : undefined;\r\n if (!countryCode) {\r\n throw new FlurError(\"Invalid phone number\", \"INVALID_REQUEST\");\r\n }\r\n\r\n const localDigits = digits.startsWith(\"0\") ? digits.slice(1) : digits;\r\n const candidate = `+${countryCode}${localDigits}`;\r\n if (!E164Regex.test(candidate)) {\r\n throw new FlurError(\"Invalid phone number\", \"INVALID_REQUEST\");\r\n }\r\n return candidate;\r\n}\r\n\r\nexport function moneyMinorToNumber(amountMinor: bigint): number {\r\n const asNumber = Number(amountMinor);\r\n if (!Number.isSafeInteger(asNumber)) {\r\n throw new FlurError(\"Amount exceeds safe integer range\", \"INVALID_REQUEST\");\r\n }\r\n return asNumber;\r\n}\r\n","/**\n * EMV / NQR Merchant-Presented top-level field IDs.\n * See EMVCo MPM v1.1 §4 and NIBSS NQR specification.\n */\nexport const FIELD = {\n PAYLOAD_FORMAT_INDICATOR: '00',\n POINT_OF_INITIATION: '01',\n // 02..51 — Merchant Account Information templates (issuer-specific)\n MERCHANT_CATEGORY_CODE: '52',\n TRANSACTION_CURRENCY: '53',\n TRANSACTION_AMOUNT: '54',\n TIP_OR_CONVENIENCE_INDICATOR: '55',\n VALUE_CONVENIENCE_FEE_FIXED: '56',\n VALUE_CONVENIENCE_FEE_PERCENT: '57',\n COUNTRY_CODE: '58',\n MERCHANT_NAME: '59',\n MERCHANT_CITY: '60',\n POSTAL_CODE: '61',\n ADDITIONAL_DATA_FIELD: '62',\n CRC: '63',\n MERCHANT_INFO_LANGUAGE: '64',\n // 80..99 — Unreserved Templates\n} as const;\n\nexport const ADDITIONAL_DATA_SUBFIELD = {\n BILL_NUMBER: '01',\n MOBILE_NUMBER: '02',\n STORE_LABEL: '03',\n LOYALTY_NUMBER: '04',\n REFERENCE_LABEL: '05',\n CUSTOMER_LABEL: '06',\n TERMINAL_LABEL: '07',\n PURPOSE_OF_TRANSACTION: '08',\n} as const;\n\nexport const POINT_OF_INITIATION = {\n STATIC: '11',\n DYNAMIC: '12',\n} as const;\n\nexport const PAYLOAD_FORMAT_INDICATOR_VALUE = '01';\nexport const NGN_CURRENCY_CODE = '566';\nexport const NG_COUNTRY_CODE = 'NG';\nexport const CRC_TAG_PREFIX = '6304'; // tag 63 + length 04\n","/**\n * CRC-16/CCITT-FALSE — polynomial 0x1021, initial 0xFFFF, no reflection,\n * no XOR-out. Specified by EMVCo MPM for tag 63 (CRC).\n */\nexport function crc16ccitt(bytes: Uint8Array): number {\n let crc = 0xffff;\n for (let i = 0; i < bytes.length; i++) {\n crc ^= bytes[i] << 8;\n for (let j = 0; j < 8; j++) {\n if (crc & 0x8000) {\n crc = (crc << 1) ^ 0x1021;\n } else {\n crc <<= 1;\n }\n crc &= 0xffff;\n }\n }\n return crc;\n}\n\nexport function crc16ccittHex(bytes: Uint8Array): string {\n return crc16ccitt(bytes).toString(16).toUpperCase().padStart(4, '0');\n}\n","/**\n * EMV TLV (Tag-Length-Value) primitives.\n * - Tag is 2 ASCII digits.\n * - Length is 2 ASCII digits (00..99).\n * - Value is up to 99 ASCII characters.\n */\n\nexport type TLVField = { tag: string; value: string };\n\nexport function writeTLV(tag: string, value: string): string {\n if (!/^\\d{2}$/.test(tag)) {\n throw new Error(`TLV: tag must be 2 digits, got \"${tag}\"`);\n }\n if (value.length > 99) {\n throw new Error(\n `TLV: value for tag ${tag} exceeds 99 chars (${value.length})`,\n );\n }\n const len = value.length.toString().padStart(2, '0');\n return `${tag}${len}${value}`;\n}\n\nexport function readTLV(buf: string): TLVField[] {\n const out: TLVField[] = [];\n let i = 0;\n while (i < buf.length) {\n if (i + 4 > buf.length) {\n throw new Error(`TLV: truncated header at offset ${i}`);\n }\n const tag = buf.slice(i, i + 2);\n const lenStr = buf.slice(i + 2, i + 4);\n if (!/^\\d{2}$/.test(tag)) {\n throw new Error(`TLV: bad tag \"${tag}\" at offset ${i}`);\n }\n if (!/^\\d{2}$/.test(lenStr)) {\n throw new Error(`TLV: bad length \"${lenStr}\" at offset ${i + 2}`);\n }\n const len = parseInt(lenStr, 10);\n const valStart = i + 4;\n const valEnd = valStart + len;\n if (valEnd > buf.length) {\n throw new Error(\n `TLV: truncated value for tag ${tag} at offset ${valStart}`,\n );\n }\n out.push({ tag, value: buf.slice(valStart, valEnd) });\n i = valEnd;\n }\n return out;\n}\n","import {\n ADDITIONAL_DATA_SUBFIELD,\n CRC_TAG_PREFIX,\n FIELD,\n NGN_CURRENCY_CODE,\n NG_COUNTRY_CODE,\n PAYLOAD_FORMAT_INDICATOR_VALUE,\n POINT_OF_INITIATION,\n} from './fields.js';\nimport { crc16ccittHex } from './crc16.js';\nimport { writeTLV } from './tlv.js';\nimport type {\n AdditionalData,\n MerchantAccountInfo,\n NQRPayloadInput,\n} from './types.js';\n\nconst ASCII_PRINTABLE = /^[\\x20-\\x7E]*$/;\n\n/** Build the inner content of a Merchant Account Information template. */\nfunction buildMAIValue(mai: MerchantAccountInfo): string {\n if (!/^(0[2-9]|[1-4]\\d|5[0-1])$/.test(mai.tag)) {\n throw new Error(\n `encodeNQR: merchantAccountInfo.tag must be in 02..51, got \"${mai.tag}\"`,\n );\n }\n let out = '';\n for (const c of mai.children) {\n out += writeTLV(c.tag, c.value);\n }\n return out;\n}\n\nfunction buildAdditionalDataValue(ad: AdditionalData): string {\n let out = '';\n const map: Array<[keyof AdditionalData, string]> = [\n ['billNumber', ADDITIONAL_DATA_SUBFIELD.BILL_NUMBER],\n ['mobileNumber', ADDITIONAL_DATA_SUBFIELD.MOBILE_NUMBER],\n ['storeLabel', ADDITIONAL_DATA_SUBFIELD.STORE_LABEL],\n ['loyaltyNumber', ADDITIONAL_DATA_SUBFIELD.LOYALTY_NUMBER],\n ['referenceLabel', ADDITIONAL_DATA_SUBFIELD.REFERENCE_LABEL],\n ['customerLabel', ADDITIONAL_DATA_SUBFIELD.CUSTOMER_LABEL],\n ['terminalLabel', ADDITIONAL_DATA_SUBFIELD.TERMINAL_LABEL],\n ['purposeOfTransaction', ADDITIONAL_DATA_SUBFIELD.PURPOSE_OF_TRANSACTION],\n ];\n for (const [k, t] of map) {\n const v = ad[k];\n if (v !== undefined) {\n out += writeTLV(t, v);\n }\n }\n return out;\n}\n\nfunction assertAscii(name: string, v: string): void {\n if (!ASCII_PRINTABLE.test(v)) {\n throw new Error(\n `encodeNQR: ${name} contains non-printable-ASCII characters`,\n );\n }\n}\n\nfunction assertMaxLen(name: string, v: string, max: number): void {\n if (v.length > max) {\n throw new Error(`encodeNQR: ${name} length ${v.length} exceeds max ${max}`);\n }\n}\n\nfunction assertMCC(mcc: string): void {\n if (!/^\\d{4}$/.test(mcc)) {\n throw new Error(\n `encodeNQR: merchantCategoryCode must be 4 digits, got \"${mcc}\"`,\n );\n }\n}\n\nfunction assertAmount(amt: string): void {\n // Up to 13 chars per EMV; decimal fraction separator is \".\"\n if (!/^\\d{1,10}(\\.\\d{1,2})?$/.test(amt)) {\n throw new Error(\n `encodeNQR: transactionAmount must match /^\\\\d{1,10}(\\\\.\\\\d{1,2})?$/, got \"${amt}\"`,\n );\n }\n if (amt.length > 13) {\n throw new Error(\n `encodeNQR: transactionAmount length ${amt.length} exceeds 13`,\n );\n }\n}\n\nexport function encodeNQR(input: NQRPayloadInput): string {\n assertMCC(input.merchantCategoryCode);\n assertAscii('merchantName', input.merchantName);\n assertMaxLen('merchantName', input.merchantName, 25);\n assertAscii('merchantCity', input.merchantCity);\n assertMaxLen('merchantCity', input.merchantCity, 15);\n if (input.postalCode !== undefined) {\n assertAscii('postalCode', input.postalCode);\n assertMaxLen('postalCode', input.postalCode, 10);\n }\n if (input.transactionAmount !== undefined) {\n assertAmount(input.transactionAmount);\n }\n if (\n input.pointOfInitiation === 'dynamic' &&\n input.transactionAmount === undefined\n ) {\n // amount is optional even for dynamic per spec, but warn-by-throw kept for now.\n // Allow undefined: some dynamic flows fill the amount in real-time. No throw.\n }\n\n let out = '';\n out += writeTLV(\n FIELD.PAYLOAD_FORMAT_INDICATOR,\n PAYLOAD_FORMAT_INDICATOR_VALUE,\n );\n out += writeTLV(\n FIELD.POINT_OF_INITIATION,\n input.pointOfInitiation === 'dynamic'\n ? POINT_OF_INITIATION.DYNAMIC\n : POINT_OF_INITIATION.STATIC,\n );\n out += writeTLV(\n input.merchantAccountInfo.tag,\n buildMAIValue(input.merchantAccountInfo),\n );\n out += writeTLV(FIELD.MERCHANT_CATEGORY_CODE, input.merchantCategoryCode);\n out += writeTLV(FIELD.TRANSACTION_CURRENCY, NGN_CURRENCY_CODE);\n if (input.transactionAmount !== undefined) {\n out += writeTLV(FIELD.TRANSACTION_AMOUNT, input.transactionAmount);\n }\n out += writeTLV(FIELD.COUNTRY_CODE, NG_COUNTRY_CODE);\n out += writeTLV(FIELD.MERCHANT_NAME, input.merchantName);\n out += writeTLV(FIELD.MERCHANT_CITY, input.merchantCity);\n if (input.postalCode !== undefined) {\n out += writeTLV(FIELD.POSTAL_CODE, input.postalCode);\n }\n if (input.additionalData) {\n const adfValue = buildAdditionalDataValue(input.additionalData);\n if (adfValue.length > 0) {\n out += writeTLV(FIELD.ADDITIONAL_DATA_FIELD, adfValue);\n }\n }\n\n // CRC over everything including \"6304\" header.\n out += CRC_TAG_PREFIX;\n const crc = crc16ccittHex(new TextEncoder().encode(out));\n out += crc;\n return out;\n}\n","import {\n CRC_TAG_PREFIX,\n FIELD,\n NGN_CURRENCY_CODE,\n NG_COUNTRY_CODE,\n} from './fields.js';\nimport { crc16ccittHex } from './crc16.js';\nimport { readTLV } from './tlv.js';\nimport type {\n AdditionalData,\n MerchantAccountInfo,\n ParsedNQR,\n} from './types.js';\n\nexport class NQRParseError extends Error {\n readonly path: string;\n constructor(message: string, path = '') {\n super(message);\n this.name = 'NQRParseError';\n this.path = path;\n }\n}\n\nexport function parseNQR(payload: string): ParsedNQR {\n if (payload.length < 8) {\n throw new NQRParseError(`payload too short (${payload.length} chars)`);\n }\n // CRC validation: last 4 chars are CRC; preceding 4 must be \"6304\".\n const crcTagAndLen = payload.slice(-8, -4);\n const crcValue = payload.slice(-4);\n if (crcTagAndLen !== CRC_TAG_PREFIX) {\n throw new NQRParseError(\n `CRC tag prefix not found (expected \"6304\" at end)`,\n );\n }\n const beforeCrc = payload.slice(0, -4);\n const expectedCrc = crc16ccittHex(new TextEncoder().encode(beforeCrc));\n if (expectedCrc !== crcValue.toUpperCase()) {\n throw new NQRParseError(\n `CRC mismatch: payload says ${crcValue}, computed ${expectedCrc}`,\n '63',\n );\n }\n\n // Parse top-level TLV (excluding the trailing CRC field).\n const topBuf = payload.slice(0, -8);\n const top = readTLV(topBuf);\n\n const get = (tag: string): string | undefined =>\n top.find((f) => f.tag === tag)?.value;\n\n const pfi = get(FIELD.PAYLOAD_FORMAT_INDICATOR);\n if (pfi !== '01')\n throw new NQRParseError(\n `payloadFormatIndicator must be \"01\", got \"${pfi}\"`,\n '00',\n );\n\n const poiRaw = get(FIELD.POINT_OF_INITIATION);\n const pointOfInitiation: ParsedNQR['pointOfInitiation'] =\n poiRaw === '11' ? 'static' : poiRaw === '12' ? 'dynamic' : 'unknown';\n\n const currency = get(FIELD.TRANSACTION_CURRENCY);\n if (currency !== NGN_CURRENCY_CODE) {\n throw new NQRParseError(\n `unsupported currency \"${currency}\" (expected ${NGN_CURRENCY_CODE})`,\n '53',\n );\n }\n const country = get(FIELD.COUNTRY_CODE);\n if (country !== NG_COUNTRY_CODE) {\n throw new NQRParseError(\n `unsupported country \"${country}\" (expected ${NG_COUNTRY_CODE})`,\n '58',\n );\n }\n\n const mcc = get(FIELD.MERCHANT_CATEGORY_CODE);\n if (!mcc) throw new NQRParseError('merchantCategoryCode missing', '52');\n const merchantName = get(FIELD.MERCHANT_NAME) ?? '';\n const merchantCity = get(FIELD.MERCHANT_CITY) ?? '';\n const transactionAmount = get(FIELD.TRANSACTION_AMOUNT);\n const postalCode = get(FIELD.POSTAL_CODE);\n\n // Merchant Account Information templates: tags 02..51.\n const mais: MerchantAccountInfo[] = [];\n for (const f of top) {\n const n = parseInt(f.tag, 10);\n if (n >= 2 && n <= 51) {\n const children = readTLV(f.value).map((c) => ({\n tag: c.tag,\n value: c.value,\n }));\n mais.push({ tag: f.tag, children });\n }\n }\n\n // Additional Data Field (62).\n let additionalData: AdditionalData | undefined;\n const adfRaw = get(FIELD.ADDITIONAL_DATA_FIELD);\n if (adfRaw !== undefined) {\n additionalData = {};\n for (const c of readTLV(adfRaw)) {\n switch (c.tag) {\n case '01':\n additionalData.billNumber = c.value;\n break;\n case '02':\n additionalData.mobileNumber = c.value;\n break;\n case '03':\n additionalData.storeLabel = c.value;\n break;\n case '04':\n additionalData.loyaltyNumber = c.value;\n break;\n case '05':\n additionalData.referenceLabel = c.value;\n break;\n case '06':\n additionalData.customerLabel = c.value;\n break;\n case '07':\n additionalData.terminalLabel = c.value;\n break;\n case '08':\n additionalData.purposeOfTransaction = c.value;\n break;\n // unknown sub-tags ignored (forward-compat).\n }\n }\n }\n\n return {\n payloadFormatIndicator: pfi,\n pointOfInitiation,\n merchantAccountInfo: mais,\n merchantCategoryCode: mcc,\n transactionCurrency: currency,\n transactionAmount,\n countryCode: country,\n merchantName,\n merchantCity,\n postalCode,\n additionalData,\n flurReference: additionalData?.referenceLabel?.startsWith('FL-')\n ? additionalData.referenceLabel\n : undefined,\n raw: payload,\n };\n}\n","import type { ParsedNQR } from './types.js';\n\nexport type RoutingHint = 'flur-onus' | 'nibss' | 'unknown';\n\n/**\n * Decide whether a parsed NQR payload should be routed on-us through Flur\n * (because it carries a Flur reference label) or sent through standard NIBSS.\n */\nexport function routingHint(parsed: ParsedNQR): RoutingHint {\n if (parsed.flurReference && parsed.flurReference.startsWith('FL-')) {\n return 'flur-onus';\n }\n if (parsed.merchantAccountInfo.length > 0) return 'nibss';\n return 'unknown';\n}\n","/**\n * Deterministic JSON serialization for cryptographic signing.\n *\n * Rules:\n * - Object keys sorted lexicographically (recursively).\n * - Arrays preserve order.\n * - undefined / NaN / Infinity / bigint / function / symbol are rejected.\n * Signatures must be unambiguous; ambiguous values are bugs.\n */\nexport function canonicalJSONStringify(value: unknown): string {\n return stringify(value);\n}\n\nexport function canonicalJSONBytes(value: unknown): Uint8Array {\n return new TextEncoder().encode(canonicalJSONStringify(value));\n}\n\nfunction stringify(v: unknown): string {\n if (v === null) return 'null';\n const t = typeof v;\n if (t === 'string') return JSON.stringify(v);\n if (t === 'boolean') return v ? 'true' : 'false';\n if (t === 'number') {\n if (!Number.isFinite(v as number)) {\n throw new Error('canonicalJSON: non-finite number not allowed');\n }\n return JSON.stringify(v);\n }\n if (\n t === 'bigint' ||\n t === 'function' ||\n t === 'symbol' ||\n t === 'undefined'\n ) {\n throw new Error(`canonicalJSON: unsupported value type ${t}`);\n }\n if (Array.isArray(v)) {\n const parts: string[] = [];\n for (const item of v) parts.push(stringify(item));\n return '[' + parts.join(',') + ']';\n }\n if (t === 'object') {\n const obj = v as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n const parts: string[] = [];\n for (const k of keys) {\n const val = obj[k];\n if (val === undefined) {\n throw new Error(`canonicalJSON: undefined value at key \"${k}\"`);\n }\n parts.push(JSON.stringify(k) + ':' + stringify(val));\n }\n return '{' + parts.join(',') + '}';\n }\n throw new Error(`canonicalJSON: unsupported value type ${t}`);\n}\n","/**\n * Constant-time equality for byte arrays. Returns false fast on length\n * mismatch (length is not secret); compares byte-wise without short-circuit\n * for equal-length inputs.\n */\nexport function constantTimeEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];\n return diff === 0;\n}\n","import { ed25519 } from '@noble/curves/ed25519';\nimport { canonicalJSONBytes } from './canonical.js';\n\nexport type Ed25519KeyPair = {\n privateKey: Uint8Array; // 32 bytes\n publicKey: Uint8Array; // 32 bytes\n};\n\nexport function generateKeyPair(): Ed25519KeyPair {\n const privateKey = ed25519.utils.randomPrivateKey();\n const publicKey = ed25519.getPublicKey(privateKey);\n return { privateKey, publicKey };\n}\n\nexport function publicKeyFromPrivate(privateKey: Uint8Array): Uint8Array {\n return ed25519.getPublicKey(privateKey);\n}\n\nexport function sign(message: Uint8Array, privateKey: Uint8Array): Uint8Array {\n return ed25519.sign(message, privateKey);\n}\n\nexport function verify(\n message: Uint8Array,\n signature: Uint8Array,\n publicKey: Uint8Array,\n): boolean {\n try {\n return ed25519.verify(signature, message, publicKey);\n } catch {\n return false;\n }\n}\n\n/**\n * Sign a value by canonicalizing it to JSON bytes first.\n * Use this for any object payload that must round-trip across devices.\n */\nexport function signCanonical(\n value: unknown,\n privateKey: Uint8Array,\n): Uint8Array {\n return sign(canonicalJSONBytes(value), privateKey);\n}\n\nexport function verifyCanonical(\n value: unknown,\n signature: Uint8Array,\n publicKey: Uint8Array,\n): boolean {\n return verify(canonicalJSONBytes(value), signature, publicKey);\n}\n","import { z } from 'zod';\nimport { sign, verify } from '../crypto/ed25519.js';\nimport { canonicalJSONBytes } from '../crypto/canonical.js';\n\nexport const OAC_DEFAULT_PER_TX_KOBO = 500_000;\nexport const OAC_DEFAULT_CUMULATIVE_KOBO = 2_000_000;\nexport const OAC_DEFAULT_VALIDITY_MS = 24 * 60 * 60 * 1000;\n\nconst HexString = (length: number) =>\n z\n .string()\n .regex(\n new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),\n `expected ${length}-byte hex string`,\n );\n\nexport const OACSchema = z\n .object({\n userId: z.string().min(1),\n deviceId: z.string().min(1),\n devicePublicKey: HexString(32),\n perTxCapKobo: z.number().int().nonnegative(),\n cumulativeCapKobo: z.number().int().nonnegative(),\n validFromMs: z.number().int().nonnegative(),\n validUntilMs: z.number().int().positive(),\n counterSeed: z.number().int().nonnegative(),\n nonce: z.string().min(1),\n issuerSig: HexString(64),\n })\n .refine((v) => v.validUntilMs > v.validFromMs, {\n message: 'validUntilMs must be greater than validFromMs',\n })\n .refine((v) => v.perTxCapKobo <= v.cumulativeCapKobo, {\n message: 'perTxCapKobo must not exceed cumulativeCapKobo',\n });\n\nexport type OAC = z.infer<typeof OACSchema>;\n\nexport type UnsignedOAC = Omit<OAC, 'issuerSig'>;\n\nexport function buildOAC(input: {\n userId: string;\n deviceId: string;\n devicePublicKey: Uint8Array | string;\n perTxCapKobo?: number;\n cumulativeCapKobo?: number;\n validFromMs: number;\n validUntilMs: number;\n counterSeed?: number;\n nonce: string;\n}): UnsignedOAC {\n const devicePublicKey =\n typeof input.devicePublicKey === 'string'\n ? input.devicePublicKey\n : bytesToHex(input.devicePublicKey);\n return {\n userId: input.userId,\n deviceId: input.deviceId,\n devicePublicKey,\n perTxCapKobo: input.perTxCapKobo ?? OAC_DEFAULT_PER_TX_KOBO,\n cumulativeCapKobo: input.cumulativeCapKobo ?? OAC_DEFAULT_CUMULATIVE_KOBO,\n validFromMs: input.validFromMs,\n validUntilMs: input.validUntilMs,\n counterSeed: input.counterSeed ?? 0,\n nonce: input.nonce,\n };\n}\n\nexport function signOAC(\n unsigned: UnsignedOAC,\n issuerPrivateKey: Uint8Array,\n): OAC {\n const issuerSig = bytesToHex(\n sign(canonicalJSONBytes(unsigned), issuerPrivateKey),\n );\n return { ...unsigned, issuerSig };\n}\n\nexport function verifyOAC(oac: OAC, issuerPublicKey: Uint8Array): boolean {\n try {\n const parsed = OACSchema.parse(oac);\n const { issuerSig, ...unsigned } = parsed;\n return verify(\n canonicalJSONBytes(unsigned),\n hexToBytes(issuerSig),\n issuerPublicKey,\n );\n } catch {\n return false;\n }\n}\n\nexport function bytesToHex(b: Uint8Array): string {\n let s = '';\n for (let i = 0; i < b.length; i++) s += b[i].toString(16).padStart(2, '0');\n return s;\n}\n\nexport function hexToBytes(s: string): Uint8Array {\n if (s.length % 2 !== 0) throw new Error('hex: odd length');\n const out = new Uint8Array(s.length / 2);\n for (let i = 0; i < out.length; i++)\n out[i] = parseInt(s.slice(i * 2, i * 2 + 2), 16);\n return out;\n}\n","// RFC 9285 base45 encoder/decoder.\nconst ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:';\nconst REVERSE: Record<string, number> = {};\nfor (let i = 0; i < ALPHABET.length; i++) REVERSE[ALPHABET[i]] = i;\n\nexport function encodeBase45(bytes: Uint8Array): string {\n let out = '';\n let i = 0;\n for (; i + 1 < bytes.length; i += 2) {\n const x = (bytes[i] << 8) | bytes[i + 1];\n const e = Math.floor(x / (45 * 45));\n const d = Math.floor((x % (45 * 45)) / 45);\n const c = x % 45;\n out += ALPHABET[c] + ALPHABET[d] + ALPHABET[e];\n }\n if (i < bytes.length) {\n const x = bytes[i];\n const d = Math.floor(x / 45);\n const c = x % 45;\n out += ALPHABET[c] + ALPHABET[d];\n }\n return out;\n}\n\nexport function decodeBase45(s: string): Uint8Array {\n if (s.length === 0) return new Uint8Array(0);\n const fullChunks = Math.floor(s.length / 3);\n const tail = s.length - fullChunks * 3;\n if (tail === 1) throw new Error('base45: invalid length');\n const out = new Uint8Array(fullChunks * 2 + (tail === 2 ? 1 : 0));\n let oi = 0;\n for (let i = 0; i < fullChunks; i++) {\n const c = REVERSE[s[i * 3]];\n const d = REVERSE[s[i * 3 + 1]];\n const e = REVERSE[s[i * 3 + 2]];\n if (c === undefined || d === undefined || e === undefined) {\n throw new Error('base45: invalid character');\n }\n const x = c + 45 * d + 45 * 45 * e;\n if (x > 0xffff) throw new Error('base45: chunk overflow');\n out[oi++] = (x >> 8) & 0xff;\n out[oi++] = x & 0xff;\n }\n if (tail === 2) {\n const c = REVERSE[s[fullChunks * 3]];\n const d = REVERSE[s[fullChunks * 3 + 1]];\n if (c === undefined || d === undefined)\n throw new Error('base45: invalid character');\n const x = c + 45 * d;\n if (x > 0xff) throw new Error('base45: tail overflow');\n out[oi++] = x & 0xff;\n }\n return out;\n}\n","import { z } from 'zod';\nimport { sign, verify } from '../crypto/ed25519.js';\nimport { canonicalJSONBytes } from '../crypto/canonical.js';\nimport { OACSchema, type OAC, bytesToHex, hexToBytes } from './oac.js';\nimport { encodeBase45, decodeBase45 } from './codec.js';\n\nconst HexSig = z\n .string()\n .regex(/^[0-9a-fA-F]{128}$/, 'expected 64-byte hex signature');\n\nexport const OfflinePaymentRequestSchema = z.object({\n reference: z.string().min(1),\n amountKobo: z.number().int().positive(),\n merchantOAC: OACSchema,\n expiresAtMs: z.number().int().positive(),\n merchantSig: HexSig,\n});\nexport type OfflinePaymentRequest = z.infer<typeof OfflinePaymentRequestSchema>;\nexport type UnsignedOfflinePaymentRequest = Omit<\n OfflinePaymentRequest,\n 'merchantSig'\n>;\n\nexport const OfflinePaymentAuthorizationSchema = z.object({\n request: OfflinePaymentRequestSchema,\n payerOAC: OACSchema,\n payerCounter: z.number().int().positive(),\n payerSig: HexSig,\n});\nexport type OfflinePaymentAuthorization = z.infer<\n typeof OfflinePaymentAuthorizationSchema\n>;\nexport type UnsignedOfflinePaymentAuthorization = Omit<\n OfflinePaymentAuthorization,\n 'payerSig'\n>;\n\nexport function buildPaymentRequest(input: {\n reference: string;\n amountKobo: number;\n merchantOAC: OAC;\n expiresAtMs: number;\n}): UnsignedOfflinePaymentRequest {\n if (!Number.isInteger(input.amountKobo) || input.amountKobo <= 0) {\n throw new Error('amountKobo must be a positive integer');\n }\n if (input.amountKobo > input.merchantOAC.perTxCapKobo) {\n throw new Error('amountKobo exceeds merchant OAC perTxCapKobo');\n }\n return {\n reference: input.reference,\n amountKobo: input.amountKobo,\n merchantOAC: input.merchantOAC,\n expiresAtMs: input.expiresAtMs,\n };\n}\n\nexport function signPaymentRequest(\n unsigned: UnsignedOfflinePaymentRequest,\n merchantDevicePrivateKey: Uint8Array,\n): OfflinePaymentRequest {\n const merchantSig = bytesToHex(\n sign(canonicalJSONBytes(unsigned), merchantDevicePrivateKey),\n );\n return { ...unsigned, merchantSig };\n}\n\nexport function verifyPaymentRequest(\n req: OfflinePaymentRequest,\n issuerPublicKey: Uint8Array,\n): boolean {\n try {\n const parsed = OfflinePaymentRequestSchema.parse(req);\n // 1. Issuer must have signed the merchant OAC.\n const { issuerSig: merchantOacSig, ...merchantOacUnsigned } =\n parsed.merchantOAC;\n if (\n !verify(\n canonicalJSONBytes(merchantOacUnsigned),\n hexToBytes(merchantOacSig),\n issuerPublicKey,\n )\n ) {\n return false;\n }\n // 2. The merchant's device key (in OAC) must have signed this request.\n const { merchantSig, ...unsigned } = parsed;\n return verify(\n canonicalJSONBytes(unsigned),\n hexToBytes(merchantSig),\n hexToBytes(parsed.merchantOAC.devicePublicKey),\n );\n } catch {\n return false;\n }\n}\n\nexport function buildAuthorization(input: {\n request: OfflinePaymentRequest;\n payerOAC: OAC;\n payerCounter: number;\n}): UnsignedOfflinePaymentAuthorization {\n if (!Number.isInteger(input.payerCounter) || input.payerCounter <= 0) {\n throw new Error('payerCounter must be a positive integer');\n }\n if (input.request.amountKobo > input.payerOAC.perTxCapKobo) {\n throw new Error('amountKobo exceeds payer OAC perTxCapKobo');\n }\n return {\n request: input.request,\n payerOAC: input.payerOAC,\n payerCounter: input.payerCounter,\n };\n}\n\nexport function signAuthorization(\n unsigned: UnsignedOfflinePaymentAuthorization,\n payerDevicePrivateKey: Uint8Array,\n): OfflinePaymentAuthorization {\n const payerSig = bytesToHex(\n sign(canonicalJSONBytes(unsigned), payerDevicePrivateKey),\n );\n return { ...unsigned, payerSig };\n}\n\nexport function verifyAuthorization(\n auth: OfflinePaymentAuthorization,\n issuerPublicKey: Uint8Array,\n): boolean {\n try {\n const parsed = OfflinePaymentAuthorizationSchema.parse(auth);\n if (!verifyPaymentRequest(parsed.request, issuerPublicKey)) return false;\n // Issuer must have signed the payer OAC.\n const { issuerSig: payerOacSig, ...payerOacUnsigned } = parsed.payerOAC;\n if (\n !verify(\n canonicalJSONBytes(payerOacUnsigned),\n hexToBytes(payerOacSig),\n issuerPublicKey,\n )\n ) {\n return false;\n }\n // Payer device key must have signed this authorization.\n const { payerSig, ...unsigned } = parsed;\n return verify(\n canonicalJSONBytes(unsigned),\n hexToBytes(payerSig),\n hexToBytes(parsed.payerOAC.devicePublicKey),\n );\n } catch {\n return false;\n }\n}\n\nexport function encodePaymentRequestQR(req: OfflinePaymentRequest): string {\n const json = JSON.stringify(req);\n return 'FLUR1:' + encodeBase45(new TextEncoder().encode(json));\n}\n\nexport function decodePaymentRequestQR(s: string): OfflinePaymentRequest {\n if (!s.startsWith('FLUR1:'))\n throw new Error('not a Flur offline payment request QR');\n const bytes = decodeBase45(s.slice('FLUR1:'.length));\n const json = new TextDecoder().decode(bytes);\n return OfflinePaymentRequestSchema.parse(JSON.parse(json));\n}\n\nexport function encodeAuthorizationQR(\n auth: OfflinePaymentAuthorization,\n): string {\n const json = JSON.stringify(auth);\n return 'FLUR2:' + encodeBase45(new TextEncoder().encode(json));\n}\n\nexport function decodeAuthorizationQR(s: string): OfflinePaymentAuthorization {\n if (!s.startsWith('FLUR2:'))\n throw new Error('not a Flur offline authorization QR');\n const bytes = decodeBase45(s.slice('FLUR2:'.length));\n const json = new TextDecoder().decode(bytes);\n return OfflinePaymentAuthorizationSchema.parse(JSON.parse(json));\n}\n","/**\n * Offline settlement SDK helpers.\n *\n * The SDK does not \"pay\" offline — it produces signed `PaymentClaim`s and posts\n * them to `/v1/offline/settlements`. The backend enforces \"paid once\" via\n * UNIQUE(settlement_key) and UNIQUE(token_serial).\n */\nimport { z } from 'zod';\nimport type { FlurPartnerClient } from '../partner/client.js';\n\n// ───────────────────────────── schemas ─────────────────────────────\n\nexport const OfflineTokenSchema = z.object({\n tokenId: z.string().uuid(),\n tokenSerial: z.string(),\n issuerAccountId: z.string().uuid(),\n payerUserId: z.string().uuid(),\n maxAmountKobo: z.number().int().positive(),\n currency: z.string().length(3),\n issuedAtMs: z.number().int().nonnegative(),\n expiresAtMs: z.number().int().nonnegative(),\n issuerSig: z.string(),\n});\nexport type OfflineToken = z.infer<typeof OfflineTokenSchema>;\n\nexport const PaymentClaimSchema = z.object({\n encounterId: z\n .string()\n .regex(/^[0-9a-f]{64}$/i)\n .optional(),\n tokenSerial: z.string(),\n payerUserId: z.string().uuid(),\n payeeUserId: z.string().uuid(),\n payerNonce: z.string(),\n payeeNonce: z.string(),\n amountKobo: z.number().int().positive(),\n currency: z.string().length(3).default('NGN'),\n occurredAtMs: z.number().int().nonnegative(),\n completedAtMs: z.number().int().nonnegative().optional(),\n contextId: z.string().optional(),\n payerPubkey: z.string().regex(/^[0-9a-f]{64}$/i),\n payerSignature: z.string().regex(/^[0-9a-f]+$/i),\n payeePubkey: z\n .string()\n .regex(/^[0-9a-f]{64}$/i)\n .optional(),\n payeeSignature: z\n .string()\n .regex(/^[0-9a-f]+$/i)\n .optional(),\n});\nexport type PaymentClaim = z.infer<typeof PaymentClaimSchema>;\n\nexport const SettlementSchema = z.object({\n settlementId: z.string().uuid(),\n settlementKey: z.string().regex(/^[0-9a-f]{64}$/i),\n encounterId: z.string().regex(/^[0-9a-f]{64}$/i),\n issuerAccountId: z.string().uuid(),\n tokenSerial: z.string(),\n payerUserId: z.string().uuid(),\n payeeUserId: z.string().uuid(),\n amountKobo: z.number().int().nonnegative(),\n currency: z.string().length(3),\n receiptId: z.string().nullable(),\n status: z.enum(['SETTLED', 'REVIEW', 'REJECTED']),\n issuerSig: z.string(),\n createdAtMs: z.number().int().nonnegative(),\n});\nexport type Settlement = z.infer<typeof SettlementSchema>;\n\nexport const SettleResponseSchema = z.object({\n settlement: SettlementSchema,\n encounterId: z.string().regex(/^[0-9a-f]{64}$/i),\n replayed: z.boolean(),\n});\nexport type SettleResponse = z.infer<typeof SettleResponseSchema>;\n\n// ───────────────────────────── deterministic ids ─────────────────────────────\n\nimport { sha256 } from '@noble/hashes/sha256';\nimport { bytesToHex } from '@noble/hashes/utils';\n\nconst ENCOUNTER_DOMAIN = 'offline:v1:encounter';\n\n/** SHA-256 hex helper. Pure-JS via @noble/hashes — works in Node, browser, and React Native. */\nasync function sha256Hex(input: string): Promise<string> {\n return bytesToHex(sha256(new TextEncoder().encode(input)));\n}\n\n/**\n * Compute the deterministic encounterId. Both parties produce the same value;\n * the backend enforces it.\n */\nexport async function computeEncounterId(input: {\n payerUserId: string;\n payeeUserId: string;\n payerNonce: string;\n payeeNonce: string;\n tokenSerial: string;\n}): Promise<string> {\n return sha256Hex(\n ENCOUNTER_DOMAIN +\n '|' +\n [\n input.payerUserId,\n input.payeeUserId,\n input.payerNonce,\n input.payeeNonce,\n input.tokenSerial,\n ].join('|'),\n );\n}\n\n// ───────────────────────────── client ─────────────────────────────\n\nexport type IssueOfflineTokenInput = {\n /** Optional client-supplied serial (must be unique). */\n tokenSerial?: string;\n payerUserId: string;\n maxAmountKobo: number;\n currency?: string;\n ttlMs: number;\n};\n\nexport type FlurOfflineSettlementsClient = {\n /** Partner-only: pre-issue a bounded offline settlement token. */\n issueOfflineToken: (input: IssueOfflineTokenInput) => Promise<OfflineToken>;\n /** Get a token by serial (partner-scoped). */\n getOfflineToken: (tokenSerial: string) => Promise<OfflineToken>;\n /** Atomically settle a signed payment claim (idempotent). */\n settle: (claim: PaymentClaim) => Promise<SettleResponse>;\n /** Fetch a stored settlement by id or settlement_key. */\n getSettlement: (idOrKey: string) => Promise<Settlement>;\n /** List queued conflict/review items (partner-scoped). */\n listConflicts: () => Promise<{ items: unknown[] }>;\n};\n\nexport function createOfflineSettlementsClient(\n partner: FlurPartnerClient,\n): FlurOfflineSettlementsClient {\n return {\n issueOfflineToken: (input) =>\n partner.request<OfflineToken>({\n method: 'POST',\n path: '/v1/offline/tokens',\n body: {\n payerUserId: input.payerUserId,\n maxAmountKobo: input.maxAmountKobo,\n currency: input.currency ?? 'NGN',\n ttlMs: input.ttlMs,\n ...(input.tokenSerial ? { tokenSerial: input.tokenSerial } : {}),\n },\n }),\n getOfflineToken: (serial) =>\n partner.request<OfflineToken>({\n method: 'GET',\n path: `/v1/offline/tokens/${encodeURIComponent(serial)}`,\n }),\n settle: (claim) =>\n partner.request<SettleResponse>({\n method: 'POST',\n path: '/v1/offline/settlements',\n body: claim,\n }),\n getSettlement: (id) =>\n partner.request<Settlement>({\n method: 'GET',\n path: `/v1/offline/settlements/${encodeURIComponent(id)}`,\n }),\n listConflicts: () =>\n partner.request<{ items: unknown[] }>({\n method: 'GET',\n path: '/v1/offline/conflicts',\n }),\n };\n}\n","import { hmac } from '@noble/hashes/hmac';\nimport { sha256 } from '@noble/hashes/sha256';\n\nfunction bytesToHex(b: Uint8Array): string {\n let s = '';\n for (let i = 0; i < b.length; i++) s += b[i].toString(16).padStart(2, '0');\n return s;\n}\n\nfunction constantTimeStringEqual(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a.charCodeAt(i) ^ b.charCodeAt(i);\n return diff === 0;\n}\n\nexport function bodySha256Hex(body: string): string {\n return bytesToHex(sha256(new TextEncoder().encode(body)));\n}\n\nexport function canonicalRequestString(input: {\n method: string;\n path: string;\n timestamp: string;\n nonce: string;\n body: string;\n}): string {\n return [\n input.method.toUpperCase(),\n input.path,\n input.timestamp,\n input.nonce,\n bodySha256Hex(input.body),\n ].join('\\n');\n}\n\nexport function signRequestHMAC(input: {\n method: string;\n path: string;\n timestamp: string;\n nonce: string;\n body: string;\n apiSecret: string;\n}): string {\n return bytesToHex(\n hmac(sha256, input.apiSecret, canonicalRequestString(input)),\n );\n}\n\nexport function verifyRequestHMAC(input: {\n method: string;\n path: string;\n timestamp: string;\n nonce: string;\n body: string;\n apiSecret: string;\n signature: string;\n}): boolean {\n const expected = signRequestHMAC(input);\n return constantTimeStringEqual(expected, input.signature.toLowerCase());\n}\n","import { signRequestHMAC } from './hmac.js';\n\nexport const REPLAY_WINDOW_MS = 5 * 60 * 1000;\n\n/**\n * Server may signal clock skew in this header (RFC3339 or epoch seconds/ms).\n * The HMAC client uses it to perform a single bounded retry on 401.\n */\nexport const SERVER_TIME_HEADER = 'x-flur-server-time';\n\nexport type HmacFetchOptions = {\n apiKey: string;\n apiSecret: string;\n fetchImpl?: typeof fetch;\n nowMs?: () => number;\n nonceFn?: () => string;\n /** Optional scope claim forwarded as `X-Flur-Scope` (comma-joined). Backend remains authoritative. */\n scope?: readonly string[];\n};\n\n/** Generate a 128-bit nonce as hex. CSPRNG-only — throws if unavailable. */\nfunction defaultNonce(): string {\n const c = globalThis.crypto;\n if (typeof c?.randomUUID === 'function') return c.randomUUID();\n if (typeof c?.getRandomValues !== 'function') {\n throw new Error(\n 'Flur SDK: no CSPRNG available (globalThis.crypto.getRandomValues missing). ' +\n 'Refusing to fall back to Math.random for HMAC nonce generation.',\n );\n }\n const arr = new Uint8Array(16);\n c.getRandomValues(arr);\n let s = '';\n for (let i = 0; i < arr.length; i++)\n s += arr[i].toString(16).padStart(2, '0');\n return s;\n}\n\nfunction assertCSPRNG(): void {\n const c = globalThis.crypto;\n if (\n typeof c?.getRandomValues !== 'function' &&\n typeof c?.randomUUID !== 'function'\n ) {\n throw new Error(\n 'Flur SDK: no CSPRNG available (globalThis.crypto missing). ' +\n 'Initialize on a runtime that provides Web Crypto (Node 19+, modern browsers, RN 0.74+).',\n );\n }\n}\n\n/** Parse a server-time hint as either epoch (s or ms) or RFC3339; returns ms or null. */\nfunction parseServerTimeMs(value: string | null): number | null {\n if (!value) return null;\n const trimmed = value.trim();\n if (/^\\d+$/.test(trimmed)) {\n const n = Number(trimmed);\n return n < 1e12 ? n * 1000 : n; // seconds vs ms heuristic\n }\n const t = Date.parse(trimmed);\n return Number.isFinite(t) ? t : null;\n}\n\nexport function createHmacFetch(opts: HmacFetchOptions): typeof fetch {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl)\n throw new Error('createHmacFetch: no fetch implementation available');\n if (!opts.nonceFn) assertCSPRNG(); // fail-fast unless caller injected a nonce source\n\n const nowMs = opts.nowMs ?? (() => Date.now());\n const nonceFn = opts.nonceFn ?? defaultNonce;\n const scopeHeader =\n opts.scope && opts.scope.length > 0 ? opts.scope.join(',') : undefined;\n\n async function signAndSend(\n req: Request,\n skewOffsetMs: number,\n ): Promise<Response> {\n // Clone first so the caller can keep using `req` (e.g., for a retry).\n const cloned = req.clone();\n const url = new URL(cloned.url);\n const path = url.pathname + url.search;\n const method = cloned.method.toUpperCase();\n const bodyText =\n method === 'GET' || method === 'HEAD' ? '' : await cloned.clone().text();\n const timestamp = Math.floor((nowMs() + skewOffsetMs) / 1000).toString();\n const nonce = nonceFn();\n const signature = signRequestHMAC({\n method,\n path,\n timestamp,\n nonce,\n body: bodyText,\n apiSecret: opts.apiSecret,\n });\n const headers = new Headers(cloned.headers);\n headers.set('x-flur-key', opts.apiKey);\n headers.set('x-flur-timestamp', timestamp);\n headers.set('x-flur-nonce', nonce);\n headers.set('x-flur-signature', signature);\n if (scopeHeader) headers.set('x-flur-scope', scopeHeader);\n const signed = new Request(cloned, { headers });\n return fetchImpl(signed);\n }\n\n return (async (input: RequestInfo | URL, init?: RequestInit) => {\n const req = input instanceof Request ? input : new Request(input, init);\n let resp = await signAndSend(req, 0);\n\n if (resp.status === 401) {\n const serverTimeMs = parseServerTimeMs(\n resp.headers.get(SERVER_TIME_HEADER),\n );\n if (serverTimeMs !== null) {\n const skew = serverTimeMs - nowMs();\n if (Math.abs(skew) > 0) {\n // Bounded single retry with corrected timestamp.\n resp = await signAndSend(req, skew);\n }\n }\n }\n return resp;\n }) as typeof fetch;\n}\n","import { z } from 'zod';\nimport { sign, verify } from '../crypto/ed25519.js';\nimport { canonicalJSONBytes } from '../crypto/canonical.js';\nimport { bytesToHex, hexToBytes } from '../offline/oac.js';\n\nexport const PASS_KINDS = [\n 'ride-ticket',\n 'transit-pass',\n 'event-ticket',\n 'voucher',\n 'loyalty',\n 'receipt-link',\n] as const;\nexport type PassKind = (typeof PASS_KINDS)[number];\n\nexport const PASS_STATES = [\n 'issued',\n 'active',\n 'redeemed',\n 'expired',\n 'revoked',\n] as const;\nexport type PassState = (typeof PASS_STATES)[number];\n\nconst HexString = (length: number) =>\n z\n .string()\n .regex(\n new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),\n `expected ${length}-byte hex string`,\n );\n\n/** JSON-serialisable metadata payload — bounded to keep QR/offline encodings tractable. */\nexport const PassMetadataSchema = z.record(\n z.union([z.string(), z.number(), z.boolean(), z.null()]),\n);\nexport type PassMetadata = z.infer<typeof PassMetadataSchema>;\n\nexport const PassSchema = z\n .object({\n passId: z.string().min(1),\n /** Optional client/template grouping id (server may omit). */\n templateId: z.string().min(1).optional(),\n /** Optional human-facing holder identity (server may omit). The cryptographic binding\n * is `holderDevicePubkey` below. */\n holderUserId: z.string().min(1).optional(),\n kind: z.enum(PASS_KINDS),\n issuerId: z.string().min(1),\n issuedAtMs: z.number().int().nonnegative(),\n validFromMs: z.number().int().nonnegative(),\n validUntilMs: z.number().int().positive(),\n state: z.enum(PASS_STATES),\n metadata: PassMetadataSchema,\n nonce: z.string().min(1),\n /** Device id this pass is bound to (FK to backend `device_keys`). */\n holderDeviceId: z.string().min(1),\n /** 32-byte hex Ed25519 public key of the bound device. The redemption signature\n * is verified against this key — it is the security-critical binding. */\n holderDevicePubkey: HexString(32),\n /** Optional fixed amount for monetary passes (vouchers, gift cards) in kobo. */\n amountKobo: z.number().int().nonnegative().optional(),\n /** ISO-4217-ish currency code; required on the wire. SDK builders default to NGN. */\n currency: z.string().min(3).max(8),\n /** Monotonic redemption counter floor. Redemption.counter MUST be > counterSeed. */\n counterSeed: z.number().int().nonnegative(),\n /** Optional cumulative spend cap in kobo across all redemptions of this pass. */\n cumulativeCapKobo: z.number().int().nonnegative().optional(),\n issuerSig: HexString(64),\n })\n .refine((v) => v.validUntilMs > v.validFromMs, {\n message: 'validUntilMs must be greater than validFromMs',\n });\n\nexport type Pass = z.infer<typeof PassSchema>;\nexport type UnsignedPass = Omit<Pass, 'issuerSig'>;\n\nexport type BuildPassInput = {\n passId: string;\n templateId?: string;\n holderUserId?: string;\n kind: PassKind;\n issuerId: string;\n issuedAtMs: number;\n validFromMs: number;\n validUntilMs: number;\n state: PassState;\n metadata: PassMetadata;\n nonce: string;\n holderDeviceId: string;\n holderDevicePubkey: string;\n amountKobo?: number;\n currency?: string;\n counterSeed: number;\n cumulativeCapKobo?: number;\n};\n\nexport function buildPass(input: BuildPassInput): UnsignedPass {\n if (input.validUntilMs <= input.validFromMs) {\n throw new Error('validUntilMs must be greater than validFromMs');\n }\n const out: UnsignedPass = {\n passId: input.passId,\n kind: input.kind,\n issuerId: input.issuerId,\n issuedAtMs: input.issuedAtMs,\n validFromMs: input.validFromMs,\n validUntilMs: input.validUntilMs,\n state: input.state,\n metadata: input.metadata,\n nonce: input.nonce,\n holderDeviceId: input.holderDeviceId,\n holderDevicePubkey: input.holderDevicePubkey,\n currency: input.currency ?? 'NGN',\n counterSeed: input.counterSeed,\n };\n if (typeof input.templateId === 'string') out.templateId = input.templateId;\n if (typeof input.holderUserId === 'string')\n out.holderUserId = input.holderUserId;\n if (typeof input.amountKobo === 'number') out.amountKobo = input.amountKobo;\n if (typeof input.cumulativeCapKobo === 'number') {\n out.cumulativeCapKobo = input.cumulativeCapKobo;\n }\n return out;\n}\n\nexport function signPass(\n unsigned: UnsignedPass,\n issuerPrivateKey: Uint8Array,\n): Pass {\n const issuerSig = bytesToHex(\n sign(canonicalJSONBytes(unsigned), issuerPrivateKey),\n );\n return { ...unsigned, issuerSig };\n}\n\nexport function verifyPass(pass: Pass, issuerPublicKey: Uint8Array): boolean {\n try {\n const parsed = PassSchema.parse(pass);\n const { issuerSig, ...unsigned } = parsed;\n return verify(\n canonicalJSONBytes(unsigned),\n hexToBytes(issuerSig),\n issuerPublicKey,\n );\n } catch {\n return false;\n }\n}\n\n/**\n * Validity window check is done separately from signature verification so callers can\n * decide their clock-skew tolerance.\n */\nexport function isPassWithinValidity(pass: Pass, nowMs: number): boolean {\n return nowMs >= pass.validFromMs && nowMs < pass.validUntilMs;\n}\n","import { z } from 'zod';\nimport { sign, verify } from '../crypto/ed25519.js';\nimport { canonicalJSONBytes } from '../crypto/canonical.js';\nimport { bytesToHex, hexToBytes } from '../offline/oac.js';\nimport { PassSchema, type Pass } from './pass.js';\nimport {\n FlurExpiredError,\n FlurReplayError,\n FlurCapExceededError,\n} from '../errors.js';\n\nconst HexSig = z\n .string()\n .regex(/^[0-9a-fA-F]{128}$/, 'expected 64-byte hex signature');\n\nexport const RedemptionSchema = z.object({\n pass: PassSchema,\n redeemerId: z.string().min(1),\n redeemedAtMs: z.number().int().nonnegative(),\n /** Strictly monotonic counter scoped to a single pass. Must be > pass.counterSeed\n * and > the redeemer's lastSeenCounter for this pass. */\n counter: z.number().int().positive(),\n /** Amount being redeemed in kobo (0 for non-monetary passes like ride tickets). */\n amountKobo: z.number().int().nonnegative(),\n nonce: z.string().min(1),\n holderSig: HexSig,\n});\nexport type Redemption = z.infer<typeof RedemptionSchema>;\nexport type UnsignedRedemption = Omit<Redemption, 'holderSig'>;\n\nexport type BuildRedemptionInput = {\n pass: Pass;\n redeemerId: string;\n redeemedAtMs: number;\n counter: number;\n amountKobo?: number;\n nonce: string;\n /** Optional local clock — if supplied, fail-fast against pass.validUntilMs. */\n nowMs?: number;\n /** Last counter the holder has seen for this pass (default: pass.counterSeed). */\n lastSeenCounter?: number;\n /** Total kobo already redeemed against this pass (default: 0). Used with pass.cumulativeCapKobo. */\n cumulativeUsedKobo?: number;\n};\n\nconst REDEEMABLE_STATES = new Set(['issued', 'active']);\n\nexport function buildRedemption(\n input: BuildRedemptionInput,\n): UnsignedRedemption {\n if (!REDEEMABLE_STATES.has(input.pass.state)) {\n throw new Error(`pass not in redeemable state: ${input.pass.state}`);\n }\n if (input.redeemedAtMs < input.pass.validFromMs) {\n throw new Error('redeemedAtMs is before pass validFromMs');\n }\n if (input.redeemedAtMs >= input.pass.validUntilMs) {\n throw new FlurExpiredError(\n `pass ${input.pass.passId} expired at ${input.pass.validUntilMs}`,\n );\n }\n // Wall-clock expiry check (offline-safe; backend remains authoritative).\n const now =\n typeof input.nowMs === 'number' ? input.nowMs : input.redeemedAtMs;\n if (now >= input.pass.validUntilMs) {\n throw new FlurExpiredError(\n `pass ${input.pass.passId} expired at ${input.pass.validUntilMs}`,\n );\n }\n if (!input.pass.holderDevicePubkey) {\n throw new Error(\n 'pass.holderDevicePubkey is required to build a redemption',\n );\n }\n\n // Counter monotonicity: must exceed both seed and any locally-known prior counter.\n const lastSeen = Math.max(\n input.pass.counterSeed,\n typeof input.lastSeenCounter === 'number' ? input.lastSeenCounter : 0,\n );\n if (input.counter <= lastSeen) {\n throw new FlurReplayError(\n `redemption counter ${input.counter} must be > lastSeenCounter ${lastSeen}`,\n );\n }\n\n const amount = input.amountKobo ?? 0;\n\n // Cumulative cap (when set on the pass): used + this <= cap.\n if (typeof input.pass.cumulativeCapKobo === 'number') {\n const used = input.cumulativeUsedKobo ?? 0;\n if (used + amount > input.pass.cumulativeCapKobo) {\n throw new FlurCapExceededError(\n `pass ${input.pass.passId} cap ${input.pass.cumulativeCapKobo} would be exceeded (used ${used} + ${amount})`,\n );\n }\n }\n\n return {\n pass: input.pass,\n redeemerId: input.redeemerId,\n redeemedAtMs: input.redeemedAtMs,\n counter: input.counter,\n amountKobo: amount,\n nonce: input.nonce,\n };\n}\n\nexport function signRedemption(\n unsigned: UnsignedRedemption,\n holderDevicePrivateKey: Uint8Array,\n): Redemption {\n const holderSig = bytesToHex(\n sign(canonicalJSONBytes(unsigned), holderDevicePrivateKey),\n );\n return { ...unsigned, holderSig };\n}\n\n/**\n * Verifies, in order:\n * 1. The pass itself is signed by the issuer.\n * 2. The pass binds a `holderDevicePubkey` (top-level, security-critical).\n * 3. The redemption is signed by that bound device key.\n * 4. The redemption counter is strictly greater than pass.counterSeed.\n */\nexport function verifyRedemption(\n r: Redemption,\n issuerPublicKey: Uint8Array,\n): boolean {\n try {\n const parsed = RedemptionSchema.parse(r);\n if (parsed.counter <= parsed.pass.counterSeed) return false;\n const { issuerSig, ...passUnsigned } = parsed.pass;\n if (\n !verify(\n canonicalJSONBytes(passUnsigned),\n hexToBytes(issuerSig),\n issuerPublicKey,\n )\n ) {\n return false;\n }\n const holderHex = parsed.pass.holderDevicePubkey;\n if (typeof holderHex !== 'string') return false;\n const { holderSig, ...unsigned } = parsed;\n return verify(\n canonicalJSONBytes(unsigned),\n hexToBytes(holderSig),\n hexToBytes(holderHex),\n );\n } catch {\n return false;\n }\n}\n","import { z } from 'zod';\nimport { sign, verify } from '../crypto/ed25519.js';\nimport { canonicalJSONBytes } from '../crypto/canonical.js';\nimport { bytesToHex, hexToBytes } from '../offline/oac.js';\n\nexport const RECEIPT_CHANNELS = ['cash', 'pass'] as const;\nexport type ReceiptChannel = (typeof RECEIPT_CHANNELS)[number];\n\n/** @deprecated use {@link RECEIPT_CHANNELS}. Will be removed before 1.0. */\nexport const RECEIPT_KINDS = RECEIPT_CHANNELS;\n/** @deprecated use {@link ReceiptChannel}. */\nexport type ReceiptKind = ReceiptChannel;\n\nconst HexString = (length: number) =>\n z\n .string()\n .regex(\n new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),\n `expected ${length}-byte hex string`,\n );\n\n/** Free-form payload reserved for channel-specific extras (e.g. memo, intent metadata).\n * Top-level fields below are the security-relevant facts and must not be duplicated here. */\nexport const ReceiptPayloadSchema = z.record(\n z.union([z.string(), z.number(), z.boolean(), z.null()]),\n);\nexport type ReceiptPayload = z.infer<typeof ReceiptPayloadSchema>;\n\n/** BE-20 wire schema: channel + exactly one of `intentId` (cash) or `passRedemptionId` (pass). */\nexport const ReceiptSchema = z\n .object({\n receiptId: z.string().min(1),\n channel: z.enum(RECEIPT_CHANNELS),\n /** Cash-channel: send_intents.id. Required when channel === 'cash'. */\n intentId: z.string().min(1).optional(),\n /** Pass-channel: pass_redemptions.id. Required when channel === 'pass'. */\n passRedemptionId: z.string().min(1).optional(),\n payerUserId: z.string().min(1),\n payeeUserId: z.string().min(1),\n amountKobo: z.number().int().nonnegative(),\n currency: z.string().min(3).max(8),\n issuedAtMs: z.number().int().nonnegative(),\n issuerId: z.string().min(1),\n payload: ReceiptPayloadSchema,\n issuerSig: HexString(64),\n })\n .superRefine((v, ctx) => {\n if (v.channel === 'cash') {\n if (!v.intentId) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'cash receipts require intentId',\n path: ['intentId'],\n });\n }\n if (v.passRedemptionId) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'cash receipts must not carry passRedemptionId',\n path: ['passRedemptionId'],\n });\n }\n } else if (v.channel === 'pass') {\n if (!v.passRedemptionId) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'pass receipts require passRedemptionId',\n path: ['passRedemptionId'],\n });\n }\n if (v.intentId) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'pass receipts must not carry intentId',\n path: ['intentId'],\n });\n }\n }\n });\nexport type Receipt = z.infer<typeof ReceiptSchema>;\nexport type UnsignedReceipt = Omit<Receipt, 'issuerSig'>;\n\nexport type BuildReceiptInput = {\n receiptId: string;\n channel: ReceiptChannel;\n intentId?: string;\n passRedemptionId?: string;\n payerUserId: string;\n payeeUserId: string;\n amountKobo: number;\n currency: string;\n issuedAtMs: number;\n issuerId: string;\n payload?: ReceiptPayload;\n};\n\nexport function buildReceipt(input: BuildReceiptInput): UnsignedReceipt {\n if (input.channel === 'cash') {\n if (!input.intentId) {\n throw new Error('cash receipts require intentId');\n }\n if (input.passRedemptionId) {\n throw new Error('cash receipts must not carry passRedemptionId');\n }\n } else {\n if (!input.passRedemptionId) {\n throw new Error('pass receipts require passRedemptionId');\n }\n if (input.intentId) {\n throw new Error('pass receipts must not carry intentId');\n }\n }\n const out: UnsignedReceipt = {\n receiptId: input.receiptId,\n channel: input.channel,\n payerUserId: input.payerUserId,\n payeeUserId: input.payeeUserId,\n amountKobo: input.amountKobo,\n currency: input.currency,\n issuedAtMs: input.issuedAtMs,\n issuerId: input.issuerId,\n payload: input.payload ?? {},\n };\n if (input.intentId) out.intentId = input.intentId;\n if (input.passRedemptionId) out.passRedemptionId = input.passRedemptionId;\n return out;\n}\n\nexport function signReceipt(\n unsigned: UnsignedReceipt,\n issuerPrivateKey: Uint8Array,\n): Receipt {\n const issuerSig = bytesToHex(\n sign(canonicalJSONBytes(unsigned), issuerPrivateKey),\n );\n return { ...unsigned, issuerSig };\n}\n\nexport function verifyReceipt(\n r: Receipt,\n issuerPublicKey: Uint8Array,\n): boolean {\n try {\n const parsed = ReceiptSchema.parse(r);\n const { issuerSig, ...unsigned } = parsed;\n return verify(\n canonicalJSONBytes(unsigned),\n hexToBytes(issuerSig),\n issuerPublicKey,\n );\n } catch {\n return false;\n }\n}\n","import {\n PassSchema,\n verifyPass as verifyPassFn,\n type Pass,\n type PassKind,\n type PassMetadata,\n type PassState,\n} from './pass.js';\nimport { RedemptionSchema, type Redemption } from './redemption.js';\nimport {\n ReceiptSchema,\n type ReceiptPayload,\n type Receipt,\n} from '../receipts/receipt.js';\nimport { FlurApiError } from '../errors.js';\n\n// Re-export so existing `from \"./client.js\"` imports keep working.\nexport { FlurApiError };\n\nexport type PassesClientOptions = {\n baseUrl: string;\n /** Pre-configured fetch (typically `createHmacFetch(...)`). Falls back to global fetch. */\n fetchImpl?: typeof fetch;\n};\n\nexport type IssuePassInput = {\n /** Device this pass is bound to. Required (BE-19). */\n holderDeviceId: string;\n /** 32-byte hex Ed25519 public key of the bound device. Required (BE-19). */\n holderDevicePubkey: string;\n /** Pass kind (server may default for templated flows). */\n kind: PassKind;\n /** Optional fixed amount for monetary passes (kobo). */\n amountKobo?: number;\n /** Optional cumulative spend cap in kobo across all redemptions. */\n cumulativeCapKobo?: number;\n validFromMs: number;\n validUntilMs: number;\n metadata?: PassMetadata;\n /** Optional template grouping id (server may emit one if omitted). */\n templateId?: string;\n /** Optional human-facing holder identity. */\n holderUserId?: string;\n /** Optional client-supplied id for idempotency / retries. */\n passId?: string;\n};\n\nexport type ListPassesInput = {\n holderDeviceId?: string;\n holderUserId?: string;\n state?: PassState;\n kind?: PassKind;\n templateId?: string;\n limit?: number;\n cursor?: string;\n};\n\nexport type ListPassesResponse = {\n items: Pass[];\n nextCursor: string | null;\n};\n\nexport type RevokePassInput = {\n reason: string;\n};\n\nexport type RedeemPassResponse = {\n pass: Pass;\n redemptionId: string;\n};\n\nexport type AtomicRedeemReceiptInput = {\n payeeUserId: string;\n payload?: ReceiptPayload;\n receiptId?: string;\n};\n\nexport type AtomicRedeemResponse = {\n pass: Pass;\n redemptionId: string;\n receipt: Receipt;\n};\n\nexport type PassesClient = {\n issuePass: (input: IssuePassInput) => Promise<Pass>;\n listPasses: (input: ListPassesInput) => Promise<ListPassesResponse>;\n getPass: (passId: string) => Promise<Pass>;\n redeemPassDetailed: (\n passId: string,\n redemption: Redemption,\n ) => Promise<RedeemPassResponse>;\n redeemPass: (passId: string, redemption: Redemption) => Promise<Pass>;\n redeemPassWithReceipt: (\n passId: string,\n redemption: Redemption,\n receipt: AtomicRedeemReceiptInput,\n ) => Promise<AtomicRedeemResponse>;\n revokePass: (passId: string, input: RevokePassInput) => Promise<Pass>;\n /** Local Ed25519 verification of a pass envelope under the supplied issuer public key. */\n verifyPass: (pass: Pass, issuerPublicKey: Uint8Array) => boolean;\n};\n\nexport function createPassesClient(opts: PassesClientOptions): PassesClient {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl)\n throw new Error('createPassesClient: no fetch implementation available');\n const baseUrl = opts.baseUrl.replace(/\\/$/, '');\n\n async function call<T>(\n method: string,\n path: string,\n body: unknown,\n parser: (raw: unknown) => T,\n ): Promise<T> {\n const init: RequestInit = {\n method,\n headers: {\n 'content-type': 'application/json',\n accept: 'application/json',\n },\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n const resp = await fetchImpl(`${baseUrl}${path}`, init);\n const text = await resp.text();\n let raw: unknown = undefined;\n if (text) {\n try {\n raw = JSON.parse(text);\n } catch {\n // non-JSON error body\n }\n }\n if (!resp.ok) {\n const code =\n (raw &&\n typeof raw === 'object' &&\n 'code' in raw &&\n typeof (raw as { code: unknown }).code === 'string'\n ? (raw as { code: string }).code\n : undefined) ?? `http_${resp.status}`;\n const message =\n (raw &&\n typeof raw === 'object' &&\n 'message' in raw &&\n typeof (raw as { message: unknown }).message === 'string'\n ? (raw as { message: string }).message\n : undefined) ?? `request failed with status ${resp.status}`;\n throw new FlurApiError(resp.status, code, message, raw);\n }\n return parser(raw);\n }\n\n return {\n issuePass: (input) =>\n call('POST', '/v1/passes', input, (raw) => PassSchema.parse(raw)),\n\n listPasses: (input) => {\n const qs = new URLSearchParams();\n if (input.holderDeviceId) qs.set('holderDeviceId', input.holderDeviceId);\n if (input.holderUserId) qs.set('holderUserId', input.holderUserId);\n if (input.state) qs.set('state', input.state);\n if (input.kind) qs.set('kind', input.kind);\n if (input.templateId) qs.set('templateId', input.templateId);\n if (typeof input.limit === 'number') qs.set('limit', String(input.limit));\n if (input.cursor) qs.set('cursor', input.cursor);\n const path = `/v1/passes${qs.size > 0 ? `?${qs.toString()}` : ''}`;\n return call('GET', path, undefined, (raw) => {\n const obj = raw as { items?: unknown; nextCursor?: unknown };\n const items = (obj.items as unknown[]).map((it) =>\n PassSchema.parse(it),\n );\n const nextCursor =\n typeof obj.nextCursor === 'string' ? obj.nextCursor : null;\n return { items, nextCursor };\n });\n },\n\n getPass: (passId) =>\n call(\n 'GET',\n `/v1/passes/${encodeURIComponent(passId)}`,\n undefined,\n (raw) => PassSchema.parse(raw),\n ),\n\n redeemPass: (passId, redemption) =>\n call(\n 'POST',\n `/v1/passes/${encodeURIComponent(passId)}/redeem`,\n RedemptionSchema.parse(redemption),\n (raw) => {\n const obj = raw as { redemptionId?: unknown };\n return {\n pass: PassSchema.parse(raw),\n redemptionId:\n typeof obj.redemptionId === 'string' ? obj.redemptionId : '',\n };\n },\n ).then((result) => result.pass),\n\n redeemPassDetailed: (passId, redemption) =>\n call(\n 'POST',\n `/v1/passes/${encodeURIComponent(passId)}/redeem`,\n RedemptionSchema.parse(redemption),\n (raw) => {\n const obj = raw as { redemptionId?: unknown };\n return {\n pass: PassSchema.parse(raw),\n redemptionId:\n typeof obj.redemptionId === 'string' ? obj.redemptionId : '',\n };\n },\n ),\n\n redeemPassWithReceipt: (passId, redemption, receipt) =>\n call(\n 'POST',\n `/v1/passes/${encodeURIComponent(passId)}/redeem-with-receipt`,\n {\n redemption: RedemptionSchema.parse(redemption),\n receipt,\n },\n (raw) => {\n const obj = raw as {\n pass?: unknown;\n redemptionId?: unknown;\n receipt?: unknown;\n };\n return {\n pass: PassSchema.parse(obj.pass),\n redemptionId:\n typeof obj.redemptionId === 'string' ? obj.redemptionId : '',\n receipt: ReceiptSchema.parse(obj.receipt),\n };\n },\n ),\n\n revokePass: (passId, input) =>\n call(\n 'POST',\n `/v1/passes/${encodeURIComponent(passId)}/revoke`,\n input,\n (raw) => PassSchema.parse(raw),\n ),\n\n verifyPass: (pass, issuerPublicKey) => verifyPassFn(pass, issuerPublicKey),\n };\n}\n","import {\n ReceiptSchema,\n verifyReceipt as verifyReceiptFn,\n type Receipt,\n type ReceiptChannel,\n type ReceiptPayload,\n} from './receipt.js';\nimport { FlurApiError } from '../errors.js';\n\nexport type ReceiptsClientOptions = {\n baseUrl: string;\n fetchImpl?: typeof fetch;\n};\n\nexport type IssueReceiptInput = {\n channel: ReceiptChannel;\n /** Required for cash channel; FK to send_intents.id. */\n intentId?: string;\n /** Required for pass channel; FK to pass_redemptions.id. */\n passRedemptionId?: string;\n payerUserId: string;\n payeeUserId: string;\n amountKobo: number;\n currency: string;\n payload?: ReceiptPayload;\n /** Optional client-supplied id for idempotency / retries. */\n receiptId?: string;\n};\n\nexport type ListReceiptsInput = {\n /** Filter by either side of the receipt. Server scopes by caller identity. */\n payerUserId?: string;\n payeeUserId?: string;\n channel?: ReceiptChannel;\n limit?: number;\n cursor?: string;\n};\n\nexport type ListReceiptsResponse = {\n items: Receipt[];\n nextCursor: string | null;\n};\n\nexport type ReceiptsClient = {\n issueReceipt: (input: IssueReceiptInput) => Promise<Receipt>;\n /** Alias of `getById`, matches addendum surface. */\n getReceipt: (receiptId: string) => Promise<Receipt>;\n getById: (receiptId: string) => Promise<Receipt>;\n /** Look up a cash-channel receipt by its originating intentId. */\n getByIntentId: (intentId: string) => Promise<Receipt>;\n /** Look up a pass-channel receipt by its originating passRedemptionId. */\n getByPassRedemptionId: (passRedemptionId: string) => Promise<Receipt>;\n listForUser: (input: ListReceiptsInput) => Promise<ListReceiptsResponse>;\n /** Local Ed25519 verification of a receipt envelope under the supplied issuer key. */\n verifyReceipt: (receipt: Receipt, issuerPublicKey: Uint8Array) => boolean;\n};\n\nexport function createReceiptsClient(\n opts: ReceiptsClientOptions,\n): ReceiptsClient {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl)\n throw new Error('createReceiptsClient: no fetch implementation available');\n const baseUrl = opts.baseUrl.replace(/\\/$/, '');\n\n async function call<T>(\n method: string,\n path: string,\n body: unknown,\n parser: (raw: unknown) => T,\n ): Promise<T> {\n const init: RequestInit = {\n method,\n headers: {\n 'content-type': 'application/json',\n accept: 'application/json',\n },\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n const resp = await fetchImpl(`${baseUrl}${path}`, init);\n const text = await resp.text();\n let raw: unknown = undefined;\n if (text) {\n try {\n raw = JSON.parse(text);\n } catch {\n // ignore non-JSON\n }\n }\n if (!resp.ok) {\n const code =\n raw &&\n typeof raw === 'object' &&\n 'code' in raw &&\n typeof (raw as { code: unknown }).code === 'string'\n ? (raw as { code: string }).code\n : `http_${resp.status}`;\n const message =\n raw &&\n typeof raw === 'object' &&\n 'message' in raw &&\n typeof (raw as { message: unknown }).message === 'string'\n ? (raw as { message: string }).message\n : `request failed with status ${resp.status}`;\n throw new FlurApiError(resp.status, code, message, raw);\n }\n return parser(raw);\n }\n\n const getById: ReceiptsClient['getById'] = (receiptId) =>\n call(\n 'GET',\n `/v1/receipts/${encodeURIComponent(receiptId)}`,\n undefined,\n (raw) => ReceiptSchema.parse(raw),\n );\n\n return {\n issueReceipt: (input) =>\n call('POST', '/v1/receipts', input, (raw) => ReceiptSchema.parse(raw)),\n\n getReceipt: getById,\n getById,\n\n getByIntentId: (intentId) =>\n call(\n 'GET',\n `/v1/receipts/by-intent/${encodeURIComponent(intentId)}`,\n undefined,\n (raw) => ReceiptSchema.parse(raw),\n ),\n\n getByPassRedemptionId: (passRedemptionId) =>\n call(\n 'GET',\n `/v1/receipts/by-pass-redemption/${encodeURIComponent(passRedemptionId)}`,\n undefined,\n (raw) => ReceiptSchema.parse(raw),\n ),\n\n listForUser: (input) => {\n const qs = new URLSearchParams();\n if (input.payerUserId) qs.set('payerUserId', input.payerUserId);\n if (input.payeeUserId) qs.set('payeeUserId', input.payeeUserId);\n if (input.channel) qs.set('channel', input.channel);\n if (typeof input.limit === 'number') qs.set('limit', String(input.limit));\n if (input.cursor) qs.set('cursor', input.cursor);\n const path = `/v1/receipts${qs.size > 0 ? `?${qs.toString()}` : ''}`;\n return call('GET', path, undefined, (raw) => {\n const obj = raw as { items?: unknown; nextCursor?: unknown };\n const items = (obj.items as unknown[]).map((it) =>\n ReceiptSchema.parse(it),\n );\n const nextCursor =\n typeof obj.nextCursor === 'string' ? obj.nextCursor : null;\n return { items, nextCursor };\n });\n },\n\n verifyReceipt: (receipt, issuerPublicKey) =>\n verifyReceiptFn(receipt, issuerPublicKey),\n };\n}\n","import {\n encodeNQR,\n parseNQR,\n type NQRPayloadInput,\n type ParsedNQR,\n} from '../nqr/index.js';\nimport { createHmacFetch } from '../auth/middleware.js';\nimport { createPassesClient, type PassesClient } from '../passes/index.js';\nimport {\n createReceiptsClient,\n type ReceiptsClient,\n} from '../receipts/index.js';\n\nexport type FlurInitOptions = {\n apiKey: string;\n apiSecret: string;\n baseUrl: string;\n fetchImpl?: typeof fetch;\n /** When true, all QR generation is performed locally without any network call. */\n offlineMode?: boolean;\n /** Optional scope claim forwarded as `X-Flur-Scope`. Backend remains authoritative. */\n scope?: readonly string[];\n};\n\nexport type FlurPaymentEvent = {\n type: string;\n reference?: string;\n [k: string]: unknown;\n};\n\nexport type SubscribeOptions = {\n reference: string;\n onEvent: (event: FlurPaymentEvent) => void;\n onError?: (err: unknown) => void;\n};\n\nexport function generateStaticQR(\n input: Omit<NQRPayloadInput, 'pointOfInitiation'>,\n): string {\n return encodeNQR({ ...input, pointOfInitiation: 'static' });\n}\n\nexport function generateDynamicQR(\n input: Omit<NQRPayloadInput, 'pointOfInitiation'>,\n): string {\n return encodeNQR({ ...input, pointOfInitiation: 'dynamic' });\n}\n\nexport function parseQR(payload: string): ParsedNQR {\n return parseNQR(payload);\n}\n\nexport type CashNamespace = {\n generateStaticQR: typeof generateStaticQR;\n generateDynamicQR: typeof generateDynamicQR;\n parseQR: typeof parseQR;\n subscribeToPayments: (opts: SubscribeOptions) => () => void;\n};\n\nexport type FlurHandle = CashNamespace & {\n /** Cash / money: NQR generation, payment subscriptions, transfers (future). */\n cash: CashNamespace;\n /** Passes: tickets, vouchers, loyalty, transit. */\n passes: PassesClient;\n /** Receipts: signed, immutable views over cash + pass events. */\n receipts: ReceiptsClient;\n};\n\nexport function init(opts: FlurInitOptions): FlurHandle {\n const signedFetch = createHmacFetch({\n apiKey: opts.apiKey,\n apiSecret: opts.apiSecret,\n fetchImpl: opts.fetchImpl,\n scope: opts.scope,\n });\n const baseUrl = opts.baseUrl.replace(/\\/$/, '');\n\n function subscribeToPayments(s: SubscribeOptions) {\n const controller = new AbortController();\n let cancelled = false;\n\n (async () => {\n try {\n const url = `${baseUrl}/v1/payments/subscribe?reference=${encodeURIComponent(s.reference)}`;\n const resp = await signedFetch(url, {\n method: 'GET',\n headers: { accept: 'text/event-stream' },\n signal: controller.signal,\n });\n if (!resp.body) return;\n const reader = resp.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n while (!cancelled) {\n const { value, done } = await reader.read();\n if (done) return;\n buffer += decoder.decode(value, { stream: true });\n let idx;\n while ((idx = buffer.indexOf('\\n\\n')) >= 0) {\n const chunk = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 2);\n for (const line of chunk.split('\\n')) {\n if (!line.startsWith('data:')) continue;\n const json = line.slice(5).trim();\n if (!json) continue;\n try {\n s.onEvent(JSON.parse(json) as FlurPaymentEvent);\n } catch (err) {\n s.onError?.(err);\n }\n }\n }\n }\n } catch (err) {\n if (!cancelled) s.onError?.(err);\n }\n })();\n\n return () => {\n cancelled = true;\n controller.abort();\n };\n }\n\n const cash: CashNamespace = {\n generateStaticQR,\n generateDynamicQR,\n parseQR,\n subscribeToPayments,\n };\n\n const passes = createPassesClient({ baseUrl, fetchImpl: signedFetch });\n const receipts = createReceiptsClient({ baseUrl, fetchImpl: signedFetch });\n\n return {\n // top-level back-compat surface\n generateStaticQR,\n generateDynamicQR,\n parseQR,\n subscribeToPayments,\n // namespaces\n cash,\n passes,\n receipts,\n };\n}\n","import { z } from 'zod';\nimport { FlurApiError } from '../errors.js';\n\nexport const ACCOUNT_TYPES = ['personal', 'business', 'partner'] as const;\nexport type AccountType = (typeof ACCOUNT_TYPES)[number];\n\nexport const ACCOUNT_STATUSES = ['active', 'suspended', 'closed'] as const;\nexport type AccountStatus = (typeof ACCOUNT_STATUSES)[number];\n\nexport const MEMBERSHIP_ROLES = ['owner', 'admin', 'driver', 'staff'] as const;\nexport type MembershipRole = (typeof MEMBERSHIP_ROLES)[number];\n\nexport const AccountSchema = z.object({\n accountId: z.string().uuid(),\n type: z.enum(ACCOUNT_TYPES),\n displayName: z.string().min(1),\n status: z.enum(ACCOUNT_STATUSES),\n ownerUserId: z.string().uuid().nullable(),\n createdAtMs: z.number().int().nonnegative(),\n});\nexport type Account = z.infer<typeof AccountSchema>;\n\nexport const AccountMembershipSchema = z.object({\n accountId: z.string().uuid(),\n userId: z.string().uuid(),\n role: z.enum(MEMBERSHIP_ROLES),\n createdAtMs: z.number().int().nonnegative(),\n});\nexport type AccountMembership = z.infer<typeof AccountMembershipSchema>;\n\nexport type AccountsClientOptions = {\n baseUrl: string;\n /** Pre-configured fetch (e.g. with a session bearer or partner HMAC). */\n fetchImpl?: typeof fetch;\n};\n\nexport type CreateBusinessAccountInput = {\n displayName: string;\n type?: 'business' | 'partner';\n};\n\nexport type AddMemberInput = {\n userId: string;\n role: MembershipRole;\n};\n\nexport type AccountsClient = {\n listMyAccounts: () => Promise<{ items: Account[] }>;\n getAccount: (accountId: string) => Promise<Account>;\n listMembers: (accountId: string) => Promise<{ items: AccountMembership[] }>;\n createBusinessAccount: (\n input: CreateBusinessAccountInput,\n ) => Promise<Account>;\n addMember: (\n accountId: string,\n input: AddMemberInput,\n ) => Promise<AccountMembership>;\n};\n\nexport function createAccountsClient(\n opts: AccountsClientOptions,\n): AccountsClient {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error('createAccountsClient: no fetch implementation available');\n }\n const baseUrl = opts.baseUrl.replace(/\\/$/, '');\n\n async function call<T>(\n method: string,\n path: string,\n body: unknown,\n parser: (raw: unknown) => T,\n ): Promise<T> {\n const init: RequestInit = {\n method,\n headers: {\n 'content-type': 'application/json',\n accept: 'application/json',\n },\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n const resp = await fetchImpl(`${baseUrl}${path}`, init);\n const text = await resp.text();\n let raw: unknown = undefined;\n if (text) {\n try {\n raw = JSON.parse(text);\n } catch {\n // non-JSON\n }\n }\n if (!resp.ok) {\n const code =\n raw &&\n typeof raw === 'object' &&\n 'code' in raw &&\n typeof (raw as { code: unknown }).code === 'string'\n ? (raw as { code: string }).code\n : `http_${resp.status}`;\n const message =\n raw &&\n typeof raw === 'object' &&\n 'message' in raw &&\n typeof (raw as { message: unknown }).message === 'string'\n ? (raw as { message: string }).message\n : `request failed with status ${resp.status}`;\n throw new FlurApiError(resp.status, code, message, raw);\n }\n return parser(raw);\n }\n\n const itemsSchema = z.object({ items: z.array(AccountSchema) });\n const memberItemsSchema = z.object({\n items: z.array(AccountMembershipSchema),\n });\n\n return {\n listMyAccounts: () =>\n call('GET', '/v1/accounts/me', undefined, (raw) =>\n itemsSchema.parse(raw),\n ),\n getAccount: (accountId) =>\n call(\n 'GET',\n `/v1/accounts/${encodeURIComponent(accountId)}`,\n undefined,\n (raw) => AccountSchema.parse(raw),\n ),\n listMembers: (accountId) =>\n call(\n 'GET',\n `/v1/accounts/${encodeURIComponent(accountId)}/members`,\n undefined,\n (raw) => memberItemsSchema.parse(raw),\n ),\n createBusinessAccount: (input) =>\n call('POST', '/v1/accounts', input, (raw) => AccountSchema.parse(raw)),\n addMember: (accountId, input) =>\n call(\n 'POST',\n `/v1/accounts/${encodeURIComponent(accountId)}/members`,\n input,\n (raw) => AccountMembershipSchema.parse(raw),\n ),\n };\n}\n","import { z } from 'zod';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { hmac } from '@noble/hashes/hmac';\nimport { bytesToHex } from '@noble/hashes/utils';\nimport { FlurApiError } from '../errors.js';\n\nexport const PARTNER_SCOPES = [\n 'passes:write',\n 'passes:read',\n 'passes:redeem',\n 'receipts:write',\n 'receipts:read',\n 'offline:issue',\n 'offline:settle',\n 'offline:read',\n] as const;\nexport type PartnerScope = (typeof PARTNER_SCOPES)[number];\n\nexport const ApiCredentialPublicSchema = z.object({\n id: z.string().uuid(),\n accountId: z.string().uuid(),\n keyId: z.string(),\n scopes: z.array(z.enum(PARTNER_SCOPES)),\n label: z.string().nullable(),\n createdAtMs: z.number().int().nonnegative(),\n lastUsedAtMs: z.number().int().nonnegative().nullable(),\n revokedAtMs: z.number().int().nonnegative().nullable(),\n});\nexport type ApiCredentialPublic = z.infer<typeof ApiCredentialPublicSchema>;\n\nexport const MintedApiCredentialSchema = ApiCredentialPublicSchema.extend({\n secret: z.string().min(1),\n});\nexport type MintedApiCredential = z.infer<typeof MintedApiCredentialSchema>;\n\nexport type PartnerClientOptions = {\n baseUrl: string;\n /** Stable account id of the partner; included for observability only. */\n accountId?: string;\n /** Public key id from the mint response (e.g. flur_pk_...). */\n keyId: string;\n /** Plaintext secret from the mint response (e.g. flur_sk_...). */\n secret: string;\n fetchImpl?: typeof fetch;\n /** Override clock for tests. Returns ms. */\n nowMs?: () => number;\n /** Override nonce generator for tests. */\n nonce?: () => string;\n};\n\nconst enc = new TextEncoder();\n\nasync function sha256Hex(input: string | Uint8Array): Promise<string> {\n const data = typeof input === 'string' ? enc.encode(input) : input;\n return bytesToHex(sha256(data));\n}\n\nasync function hmacSha256Hex(keyHex: string, message: string): Promise<string> {\n // The server stores `secret_hash` as the hex string of sha256(secret) and\n // uses Node `createHmac('sha256', secret_hash)`, which treats the hex\n // STRING as raw UTF-8 bytes for the HMAC key. We do the same here.\n return bytesToHex(hmac(sha256, enc.encode(keyHex), enc.encode(message)));\n}\n\nfunction defaultNonce(): string {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n if (c?.randomUUID) return c.randomUUID();\n return `${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}`;\n}\n\n/**\n * Build the canonical signing string. Must mirror the server.\n */\nfunction canonical(params: {\n method: string;\n path: string;\n ts: string;\n nonce: string;\n bodyHash: string;\n}): string {\n return [\n params.method.toUpperCase(),\n params.path,\n params.ts,\n params.nonce,\n params.bodyHash,\n ].join('\\n');\n}\n\nexport type PartnerSignResult = {\n authorization: string;\n ts: string;\n nonce: string;\n bodyHash: string;\n};\n\nexport async function signPartnerRequest(params: {\n keyId: string;\n secret: string;\n method: string;\n path: string;\n body?: string | Uint8Array;\n nowMs?: number;\n nonce?: string;\n}): Promise<PartnerSignResult> {\n const ts = String(Math.floor((params.nowMs ?? Date.now()) / 1000));\n const nonce = params.nonce ?? defaultNonce();\n const bodyData =\n typeof params.body === 'string'\n ? enc.encode(params.body)\n : (params.body ?? new Uint8Array());\n const bodyHash = await sha256Hex(bodyData);\n const message = canonical({\n method: params.method,\n path: params.path,\n ts,\n nonce,\n bodyHash,\n });\n const signingKey = await sha256Hex(params.secret);\n const sig = await hmacSha256Hex(signingKey, message);\n return {\n authorization: `Flur-Hmac key=${params.keyId}, ts=${ts}, nonce=${nonce}, sig=${sig}`,\n ts,\n nonce,\n bodyHash,\n };\n}\n\nexport type FlurPartnerClient = {\n /** Make a signed request. Resolves to parsed JSON or throws FlurApiError. */\n request: <T = unknown>(opts: {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE';\n path: string;\n body?: unknown;\n }) => Promise<T>;\n /** Returns a fetch-compatible function with auto-signing. */\n fetch: typeof fetch;\n};\n\nexport function createFlurPartnerClient(\n opts: PartnerClientOptions,\n): FlurPartnerClient {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\n 'createFlurPartnerClient: no fetch implementation available',\n );\n }\n const baseUrl = opts.baseUrl.replace(/\\/$/, '');\n\n async function makeSignedInit(\n method: string,\n path: string,\n body?: string,\n ): Promise<RequestInit> {\n const sig = await signPartnerRequest({\n keyId: opts.keyId,\n secret: opts.secret,\n method,\n path,\n body: body ?? '',\n nowMs: opts.nowMs?.(),\n nonce: opts.nonce?.(),\n });\n const headers: Record<string, string> = {\n authorization: sig.authorization,\n accept: 'application/json',\n };\n if (body !== undefined) headers['content-type'] = 'application/json';\n const init: RequestInit = { method, headers };\n if (body !== undefined) init.body = body;\n return init;\n }\n\n async function request<T>(opts2: {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE';\n path: string;\n body?: unknown;\n }): Promise<T> {\n const bodyStr =\n opts2.body === undefined ? undefined : JSON.stringify(opts2.body);\n const init = await makeSignedInit(opts2.method, opts2.path, bodyStr);\n const resp = await fetchImpl(`${baseUrl}${opts2.path}`, init);\n const text = await resp.text();\n let raw: unknown;\n if (text) {\n try {\n raw = JSON.parse(text);\n } catch {\n // non-JSON\n }\n }\n if (!resp.ok) {\n const code =\n raw &&\n typeof raw === 'object' &&\n 'code' in raw &&\n typeof (raw as { code: unknown }).code === 'string'\n ? (raw as { code: string }).code\n : `http_${resp.status}`;\n const message =\n raw &&\n typeof raw === 'object' &&\n 'message' in raw &&\n typeof (raw as { message: unknown }).message === 'string'\n ? (raw as { message: string }).message\n : `request failed with status ${resp.status}`;\n throw new FlurApiError(resp.status, code, message, raw);\n }\n return raw as T;\n }\n\n const fetchLike: typeof fetch = async (input, init) => {\n const url = typeof input === 'string' ? input : (input as URL).toString();\n const u = new URL(url, baseUrl);\n const path = `${u.pathname}${u.search}`;\n const method = (init?.method ?? 'GET').toUpperCase();\n let bodyStr: string | undefined;\n if (init?.body) {\n bodyStr =\n typeof init.body === 'string'\n ? init.body\n : (init.body as { toString(): string }).toString();\n }\n const signed = await makeSignedInit(method, path, bodyStr);\n return fetchImpl(`${baseUrl}${path}`, {\n ...init,\n ...signed,\n headers: {\n ...(init?.headers as Record<string, string>),\n ...(signed.headers as Record<string, string>),\n },\n });\n };\n\n return { request, fetch: fetchLike };\n}\n\n/**\n * SDK helper for partner credential management endpoints. Uses an arbitrary\n * fetchImpl (typically a session-authenticated fetch) — not the partner HMAC.\n */\nexport type ApiCredentialsAdminClient = {\n list: (accountId: string) => Promise<{ items: ApiCredentialPublic[] }>;\n mint: (\n accountId: string,\n input: { scopes: PartnerScope[]; label?: string | null },\n ) => Promise<MintedApiCredential>;\n revoke: (\n accountId: string,\n credentialId: string,\n ) => Promise<ApiCredentialPublic>;\n};\n\nexport function createApiCredentialsAdminClient(opts: {\n baseUrl: string;\n fetchImpl?: typeof fetch;\n}): ApiCredentialsAdminClient {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\n 'createApiCredentialsAdminClient: no fetch implementation available',\n );\n }\n const baseUrl = opts.baseUrl.replace(/\\/$/, '');\n\n async function call<T>(\n method: string,\n path: string,\n body: unknown,\n parser: (raw: unknown) => T,\n ): Promise<T> {\n const init: RequestInit = {\n method,\n headers: {\n 'content-type': 'application/json',\n accept: 'application/json',\n },\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n const resp = await fetchImpl(`${baseUrl}${path}`, init);\n const text = await resp.text();\n let raw: unknown;\n if (text) {\n try {\n raw = JSON.parse(text);\n } catch {\n // non-JSON\n }\n }\n if (!resp.ok) {\n const code =\n raw &&\n typeof raw === 'object' &&\n 'code' in raw &&\n typeof (raw as { code: unknown }).code === 'string'\n ? (raw as { code: string }).code\n : `http_${resp.status}`;\n const message =\n raw &&\n typeof raw === 'object' &&\n 'message' in raw &&\n typeof (raw as { message: unknown }).message === 'string'\n ? (raw as { message: string }).message\n : `request failed with status ${resp.status}`;\n throw new FlurApiError(resp.status, code, message, raw);\n }\n return parser(raw);\n }\n\n const listSchema = z.object({\n items: z.array(ApiCredentialPublicSchema),\n });\n\n return {\n list: (accountId) =>\n call(\n 'GET',\n `/v1/accounts/${accountId}/api-credentials`,\n undefined,\n (raw) => listSchema.parse(raw),\n ),\n mint: (accountId, input) =>\n call('POST', `/v1/accounts/${accountId}/api-credentials`, input, (raw) =>\n MintedApiCredentialSchema.parse(raw),\n ),\n revoke: (accountId, credentialId) =>\n call(\n 'DELETE',\n `/v1/accounts/${accountId}/api-credentials/${credentialId}`,\n undefined,\n (raw) => ApiCredentialPublicSchema.parse(raw),\n ),\n };\n}\n","/**\n * Consumer-side offline payments SDK client.\n *\n * Wraps the backend `/v1/me/offline/*` routes (session-bearer auth ONLY —\n * NOT partner HMAC). These power the Flur mobile app's offline-pay flow:\n * - register/list/revoke device signing keys\n * - enable / refresh / disable offline mode (real hold + OAC issuance)\n * - read offline status (current hold + active OAC)\n * - submit a signed offline payment claim for settlement\n *\n * Schemas mirror `flur-backend/src/offline-consumer/types.ts`.\n */\nimport { z } from 'zod';\nimport { FlurApiError } from '../errors.js';\n\n// ───────────────────────────── shared regex ─────────────────────────────\n\nconst Hex64 = z.string().regex(/^[0-9a-f]{64}$/i);\nconst HexAny = z.string().regex(/^[0-9a-f]+$/i);\nconst Sha256Hex = z.string().regex(/^[0-9a-f]{64}$/i);\n\n// ───────────────────────────── device key ─────────────────────────────\n\nexport const RegisterDeviceKeyInputSchema = z.object({\n deviceId: z.string().min(1).max(128),\n publicKeyHex: Hex64,\n});\nexport type RegisterDeviceKeyInput = z.infer<\n typeof RegisterDeviceKeyInputSchema\n>;\n\nexport const DeviceKeyRecordSchema = z.object({\n id: z.string().uuid(),\n userId: z.string().uuid(),\n deviceId: z.string(),\n publicKeyHex: Hex64,\n createdAtMs: z.number().int().nonnegative(),\n revokedAtMs: z.number().int().nonnegative().nullable(),\n});\nexport type DeviceKeyRecord = z.infer<typeof DeviceKeyRecordSchema>;\n\n// ───────────────────────────── OAC ─────────────────────────────\n\nexport const ConsumerOACSchema = z.object({\n oacId: z.string().uuid(),\n issuerId: z.string().min(1).max(64),\n userId: z.string().uuid(),\n deviceId: z.string().min(1).max(128),\n devicePubkeyHex: Hex64,\n perTxCapKobo: z.number().int().positive(),\n cumulativeCapKobo: z.number().int().positive(),\n currency: z.string().length(3),\n validFromMs: z.number().int().nonnegative(),\n validUntilMs: z.number().int().nonnegative(),\n counterSeed: z.number().int().nonnegative(),\n issuedAtMs: z.number().int().nonnegative(),\n});\nexport type ConsumerOAC = z.infer<typeof ConsumerOACSchema>;\n\nexport const SignedConsumerOACSchema = z.object({\n oac: ConsumerOACSchema,\n issuerSig: HexAny,\n issuerPublicKeyHex: Hex64,\n});\nexport type SignedConsumerOAC = z.infer<typeof SignedConsumerOACSchema>;\n\nexport const OACRecordSchema = SignedConsumerOACSchema.extend({\n currentOfflineSpentKobo: z.number().int().nonnegative(),\n status: z.enum([\n 'active',\n 'superseded',\n 'expired',\n 'revoked',\n 'disabling',\n 'draining',\n 'closed',\n ]),\n supersededAtMs: z.number().int().nonnegative().nullable(),\n revokedAtMs: z.number().int().nonnegative().nullable(),\n holdId: z.string().uuid().nullable().optional(),\n});\nexport type OACRecord = z.infer<typeof OACRecordSchema>;\n\nexport const IssueOACInputSchema = z.object({\n deviceId: z.string().min(1).max(128),\n perTxCapKobo: z.number().int().positive().optional(),\n cumulativeCapKobo: z.number().int().positive().optional(),\n ttlMs: z\n .number()\n .int()\n .min(60_000)\n .max(1000 * 60 * 60 * 24 * 7)\n .optional(),\n spendableOnlineKobo: z.number().int().nonnegative().optional(),\n});\nexport type IssueOACInput = z.infer<typeof IssueOACInputSchema>;\n\n// ───────────────────────────── enable / disable / hold ─────────────────────────────\n\nexport const EnableOfflineInputSchema = z.object({\n deviceId: z.string().min(1).max(128),\n amountKobo: z.number().int().positive(),\n perTxCapKobo: z.number().int().positive().optional(),\n ttlMs: z\n .number()\n .int()\n .min(60_000)\n .max(1000 * 60 * 60 * 24 * 7)\n .optional(),\n installId: z.string().min(1).max(128),\n partnerId: z.string().min(1).max(64).optional(),\n});\nexport type EnableOfflineInput = z.infer<typeof EnableOfflineInputSchema>;\n\nexport const DisableOfflineInputSchema = z.object({\n deviceId: z.string().min(1).max(128),\n installId: z.string().min(1).max(128).optional(),\n claims: z.array(z.unknown()).max(256).optional(),\n});\nexport type DisableOfflineInput = z.infer<typeof DisableOfflineInputSchema>;\n\nexport const OfflineHoldRecordSchema = z.object({\n holdId: z.string().uuid(),\n userId: z.string().uuid(),\n deviceId: z.string(),\n partnerId: z.string(),\n adapterKind: z.string(),\n externalHoldRef: z.string().nullable(),\n amountKobo: z.number().int().nonnegative(),\n capturedKobo: z.number().int().nonnegative(),\n releasedKobo: z.number().int().nonnegative(),\n remainingKobo: z.number().int().nonnegative(),\n currency: z.string().length(3),\n status: z.enum([\n 'placing',\n 'active',\n 'disabling',\n 'draining',\n 'closed',\n 'revoked',\n 'failed',\n ]),\n installId: z.string().nullable(),\n drainDeadlineMs: z.number().int().nonnegative(),\n disableRequestedAtMs: z.number().int().nonnegative().nullable(),\n createdAtMs: z.number().int().nonnegative(),\n closedAtMs: z.number().int().nonnegative().nullable(),\n isTrusted: z.boolean().optional(),\n});\nexport type OfflineHoldRecord = z.infer<typeof OfflineHoldRecordSchema>;\n\nexport const EnableOfflineResultSchema = z.object({\n hold: OfflineHoldRecordSchema,\n oac: OACRecordSchema,\n});\nexport type EnableOfflineResult = z.infer<typeof EnableOfflineResultSchema>;\n\nexport const DisableOfflineResultSchema = z.object({\n hold: OfflineHoldRecordSchema,\n trusted: z.boolean(),\n settledClaims: z.number().int().nonnegative(),\n});\nexport type DisableOfflineResult = z.infer<typeof DisableOfflineResultSchema>;\n\nexport const OfflineStatusResultSchema = z.object({\n hold: OfflineHoldRecordSchema.nullable(),\n active: OACRecordSchema.nullable(),\n});\nexport type OfflineStatusResult = z.infer<typeof OfflineStatusResultSchema>;\n\n// Legacy /state response shape: { active: OACRecord | null }\nexport const OfflineStateResultSchema = z.object({\n active: OACRecordSchema.nullable(),\n});\nexport type OfflineStateResult = z.infer<typeof OfflineStateResultSchema>;\n\n// ───────────────────────────── payment claim ─────────────────────────────\n\nexport const ConsumerPaymentClaimSchema = z.object({\n oacId: z.string().uuid(),\n encounterId: Sha256Hex.optional(),\n payerUserId: z.string().uuid(),\n payeeUserId: z.string().uuid(),\n payerDeviceId: z.string().min(1).max(128),\n payerNonce: z.string().min(8).max(128),\n payeeNonce: z.string().min(8).max(128),\n amountKobo: z.number().int().positive(),\n currency: z.string().length(3).default('NGN'),\n occurredAtMs: z.number().int().nonnegative(),\n completedAtMs: z.number().int().nonnegative().optional(),\n contextId: z.string().max(128).optional(),\n payerPubkeyHex: Hex64,\n payerSignature: HexAny,\n payeePubkeyHex: Hex64.optional(),\n payeeSignature: HexAny.optional(),\n});\nexport type ConsumerPaymentClaim = z.infer<typeof ConsumerPaymentClaimSchema>;\n\nexport const ConsumerSettlementSchema = z.object({\n settlementId: z.string().uuid(),\n settlementKey: Sha256Hex,\n encounterId: Sha256Hex,\n oacId: z.string().uuid(),\n payerUserId: z.string().uuid(),\n payeeUserId: z.string().uuid(),\n amountKobo: z.number().int().positive(),\n currency: z.string().length(3),\n status: z.enum(['SETTLED', 'REVIEW']),\n reviewReason: z.string().nullable(),\n ledgerRef: z.string().nullable(),\n issuerSig: HexAny,\n createdAtMs: z.number().int().nonnegative(),\n});\nexport type ConsumerSettlement = z.infer<typeof ConsumerSettlementSchema>;\n\nexport const ConsumerSettleResultSchema = z.object({\n settlement: ConsumerSettlementSchema,\n encounterId: Sha256Hex,\n replayed: z.boolean(),\n});\nexport type ConsumerSettleResult = z.infer<typeof ConsumerSettleResultSchema>;\n\n// ───────────────────────────── revoke ─────────────────────────────\n\nexport const RevokeDeviceKeyInputSchema = z.object({\n deviceId: z.string().min(1).max(128),\n /** Step-up token from /api/v1/auth/send/verify with purpose='offline_revoke'. */\n sendAuthToken: z.string().min(16),\n});\nexport type RevokeDeviceKeyInput = z.infer<typeof RevokeDeviceKeyInputSchema>;\n\n// ───────────────────────────── client ─────────────────────────────\n\nexport type MeOfflineClientOptions = {\n baseUrl: string;\n /** Pre-configured fetch (session bearer attached upstream). */\n fetchImpl?: typeof fetch;\n};\n\nexport type MeOfflineClient = {\n registerDeviceKey: (\n input: RegisterDeviceKeyInput,\n ) => Promise<DeviceKeyRecord>;\n listDeviceKeys: () => Promise<{ items: DeviceKeyRecord[] }>;\n revokeDeviceKey: (input: RevokeDeviceKeyInput) => Promise<void>;\n enable: (input: EnableOfflineInput) => Promise<EnableOfflineResult>;\n refresh: (input: IssueOACInput) => Promise<OACRecord>;\n disable: (input: DisableOfflineInput) => Promise<DisableOfflineResult>;\n getStatus: (deviceId?: string) => Promise<OfflineStatusResult>;\n getState: (deviceId?: string) => Promise<OfflineStateResult>;\n submitClaim: (claim: ConsumerPaymentClaim) => Promise<ConsumerSettleResult>;\n};\n\nexport function createMeOfflineClient(\n opts: MeOfflineClientOptions,\n): MeOfflineClient {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error('createMeOfflineClient: no fetch implementation available');\n }\n const baseUrl = opts.baseUrl.replace(/\\/$/, '');\n\n async function call<T>(\n method: string,\n path: string,\n body: unknown,\n parser: (raw: unknown) => T,\n ): Promise<T> {\n const init: RequestInit = {\n method,\n headers: {\n 'content-type': 'application/json',\n accept: 'application/json',\n },\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n const resp = await fetchImpl(`${baseUrl}${path}`, init);\n const text = await resp.text();\n let raw: unknown = undefined;\n if (text) {\n try {\n raw = JSON.parse(text);\n } catch {\n // non-JSON\n }\n }\n if (!resp.ok) {\n const code =\n raw &&\n typeof raw === 'object' &&\n 'code' in raw &&\n typeof (raw as { code: unknown }).code === 'string'\n ? (raw as { code: string }).code\n : `http_${resp.status}`;\n const message =\n raw &&\n typeof raw === 'object' &&\n 'message' in raw &&\n typeof (raw as { message: unknown }).message === 'string'\n ? (raw as { message: string }).message\n : `request failed with status ${resp.status}`;\n throw new FlurApiError(resp.status, code, message, raw);\n }\n return parser(raw);\n }\n\n const deviceKeyItems = z.object({ items: z.array(DeviceKeyRecordSchema) });\n\n return {\n registerDeviceKey: (input) =>\n call(\n 'POST',\n '/v1/me/offline/keys',\n RegisterDeviceKeyInputSchema.parse(input),\n (raw) => DeviceKeyRecordSchema.parse(raw),\n ),\n listDeviceKeys: () =>\n call('GET', '/v1/me/offline/keys', undefined, (raw) =>\n deviceKeyItems.parse(raw),\n ),\n revokeDeviceKey: (input) =>\n call(\n 'POST',\n '/v1/me/offline/keys/revoke',\n RevokeDeviceKeyInputSchema.parse(input),\n () => undefined,\n ),\n enable: (input) =>\n call(\n 'POST',\n '/v1/me/offline/enable',\n EnableOfflineInputSchema.parse(input),\n (raw) => EnableOfflineResultSchema.parse(raw),\n ),\n refresh: (input) =>\n call(\n 'POST',\n '/v1/me/offline/refresh',\n IssueOACInputSchema.parse(input),\n (raw) => OACRecordSchema.parse(raw),\n ),\n disable: (input) =>\n call(\n 'POST',\n '/v1/me/offline/disable',\n DisableOfflineInputSchema.parse(input),\n (raw) => DisableOfflineResultSchema.parse(raw),\n ),\n getStatus: (deviceId) => {\n const qs = deviceId ? `?deviceId=${encodeURIComponent(deviceId)}` : '';\n return call('GET', `/v1/me/offline/status${qs}`, undefined, (raw) =>\n OfflineStatusResultSchema.parse(raw),\n );\n },\n getState: (deviceId) => {\n const qs = deviceId ? `?deviceId=${encodeURIComponent(deviceId)}` : '';\n return call('GET', `/v1/me/offline/state${qs}`, undefined, (raw) =>\n OfflineStateResultSchema.parse(raw),\n );\n },\n submitClaim: (claim) =>\n call(\n 'POST',\n '/v1/me/offline/claims',\n ConsumerPaymentClaimSchema.parse(claim),\n (raw) => ConsumerSettleResultSchema.parse(raw),\n ),\n };\n}\n"],"mappings":"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","names":["z","z","z","candidate","init","z","z","z","z","z","z","bytesToHex","sha256","bytesToHex","init","z","HexString","z","z","HexSig","z","z","HexString","z","init","init","z","z","init","z","sha256","hmac","bytesToHex","z","sha256Hex","bytesToHex","sha256","hmac","defaultNonce","init","z","z","init"]}
|