@nokinc-flur/sdk 1.1.1 → 1.1.3

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.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/contracts.ts","../src/errors.ts","../src/primitives.ts","../src/collections/client.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/partner/client.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/me-offline/client.ts","../src/partner-funding/client.ts","../src/artifacts/envelope.ts","../src/artifacts/types.ts","../src/artifacts/codec.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';\nimport {\n CollectionPaymentResultSchema,\n PayCollectionInputSchema,\n PublicCollectionIntentSchema,\n type CollectionPaymentResult,\n type PayCollectionInput as CollectionPayInput,\n type PublicCollectionIntent,\n} from './collections/index.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 userId: string;\n nuban: string | null;\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 ResolveCollectionOptions = AuthorizedOptions;\n\nexport type PayCollectionOptions = AuthorizedOptions & {\n idempotencyKey?: string;\n};\n\nexport type ResolveCollectionResponse = PublicCollectionIntent;\nexport type PayCollectionResponse = CollectionPaymentResult;\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 resolveCollection(\n reference: string,\n options: ResolveCollectionOptions,\n ): Promise<ResolveCollectionResponse> {\n return this.requestJson(\n `/v1/collections/resolve/${encodeURIComponent(reference)}`,\n {\n method: 'GET',\n headers: {\n authorization: `Bearer ${options.accessToken}`,\n },\n },\n undefined,\n PublicCollectionIntentSchema,\n );\n }\n\n async payCollection(\n input: CollectionPayInput,\n options: PayCollectionOptions,\n ): Promise<PayCollectionResponse> {\n const idempotencyKey =\n input.idempotencyKey ?? options.idempotencyKey ?? getSecureRandomUuid();\n return this.requestJson(\n '/v1/collections/pay',\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.accessToken}`,\n 'x-idempotency-key': idempotencyKey,\n },\n },\n PayCollectionInputSchema,\n CollectionPaymentResultSchema,\n { ...input, idempotencyKey },\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 /** Authenticated user's stable internal id. */\n userId: UuidSchema,\n /**\n * 10-digit Nigeria Uniform Bank Account Number (NUBAN) allocated by the\n * bank partner. `null` when the user has no partner-allocated account yet.\n */\n nuban: z\n .string()\n .regex(/^[0-9]{10}$/)\n .nullable(),\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","import { z } from 'zod';\nimport { FlurApiError } from '../errors.js';\n\nexport const MERCHANT_PROFILE_STATUSES = [\n 'pending',\n 'active',\n 'suspended',\n 'closed',\n] as const;\nexport const SETTLEMENT_SCHEDULES = ['manual', 'daily', 't1'] as const;\nexport const COLLECTION_INTENT_STATUSES = [\n 'created',\n 'pending',\n 'paid',\n 'expired',\n 'cancelled',\n 'failed',\n 'reversed',\n] as const;\nexport const COLLECTION_PAYMENT_STATUSES = [\n 'pending',\n 'paid',\n 'failed',\n 'reversed',\n] as const;\nexport const MERCHANT_PAYOUT_STATUSES = [\n 'requested',\n 'processing',\n 'paid',\n 'failed',\n 'cancelled',\n] as const;\n\nconst MoneyKoboSchema = z\n .number()\n .int()\n .positive()\n .max(Number.MAX_SAFE_INTEGER);\nconst MetadataSchema = z.record(\n z.union([z.string(), z.number(), z.boolean(), z.null()]),\n);\nconst CurrencySchema = z\n .string()\n .trim()\n .length(3)\n .transform((value) => value.toUpperCase());\nconst ReferenceSchema = z\n .string()\n .trim()\n .min(6)\n .max(128)\n .regex(/^[A-Za-z0-9._:-]+$/);\n\nexport const MerchantProfileSchema = z.object({\n accountId: z.string().uuid(),\n legalName: z.string(),\n tradingName: z.string(),\n merchantCategoryCode: z.string().regex(/^\\d{4}$/),\n nqrMerchantId: z.string(),\n settlementBankCode: z.string(),\n settlementAccountNumber: z.string(),\n settlementAccountName: z.string(),\n settlementSchedule: z.enum(SETTLEMENT_SCHEDULES),\n status: z.enum(MERCHANT_PROFILE_STATUSES),\n offlineEnabled: z.boolean(),\n perTxLimitKobo: MoneyKoboSchema,\n dailyLimitKobo: MoneyKoboSchema,\n metadata: MetadataSchema,\n createdAtMs: z.number().int().nonnegative(),\n updatedAtMs: z.number().int().nonnegative(),\n});\nexport type MerchantProfile = z.infer<typeof MerchantProfileSchema>;\n\nexport const UpsertMerchantProfileInputSchema = z.object({\n legalName: z.string().trim().min(1).max(200),\n tradingName: z.string().trim().min(1).max(25),\n merchantCategoryCode: z\n .string()\n .trim()\n .regex(/^\\d{4}$/),\n nqrMerchantId: z.string().trim().min(3).max(64),\n settlementBankCode: z.string().trim().min(2).max(16),\n settlementAccountNumber: z.string().trim().min(5).max(32),\n settlementAccountName: z.string().trim().min(1).max(200),\n settlementSchedule: z.enum(SETTLEMENT_SCHEDULES).optional(),\n status: z.enum(MERCHANT_PROFILE_STATUSES).optional(),\n offlineEnabled: z.boolean().optional(),\n perTxLimitKobo: MoneyKoboSchema.optional(),\n dailyLimitKobo: MoneyKoboSchema.optional(),\n metadata: MetadataSchema.optional(),\n});\nexport type UpsertMerchantProfileInput = z.infer<\n typeof UpsertMerchantProfileInputSchema\n>;\n\nexport const CollectionIntentSchema = z.object({\n intentId: z.string().uuid(),\n accountId: z.string().uuid(),\n terminalId: z.string().uuid().nullable(),\n reference: z.string(),\n amountKobo: z.number().int().positive().nullable(),\n currency: z.string().length(3),\n status: z.enum(COLLECTION_INTENT_STATUSES),\n description: z.string().nullable(),\n nqrPayload: z.string(),\n provider: z.string(),\n providerReference: z.string().nullable(),\n metadata: MetadataSchema,\n expiresAtMs: z.number().int().nonnegative().nullable(),\n paidAtMs: z.number().int().nonnegative().nullable(),\n createdAtMs: z.number().int().nonnegative(),\n updatedAtMs: z.number().int().nonnegative(),\n});\nexport type CollectionIntent = z.infer<typeof CollectionIntentSchema>;\n\nexport const CreateCollectionIntentInputSchema = z.object({\n reference: ReferenceSchema.optional(),\n amountKobo: MoneyKoboSchema.optional(),\n currency: CurrencySchema.optional(),\n terminalId: z.string().uuid().optional(),\n terminalLabel: z.string().trim().min(1).max(25).optional(),\n merchantCity: z.string().trim().min(1).max(15).optional(),\n description: z.string().trim().min(1).max(280).optional(),\n expiresAtMs: z.number().int().positive().optional(),\n provider: z.string().trim().min(1).max(40).optional(),\n metadata: MetadataSchema.optional(),\n});\nexport type CreateCollectionIntentInput = z.infer<\n typeof CreateCollectionIntentInputSchema\n>;\n\nexport const PublicCollectionIntentSchema = z.object({\n intentId: z.string().uuid(),\n reference: z.string(),\n amountKobo: z.number().int().positive().nullable(),\n currency: z.string().length(3),\n status: z.enum(COLLECTION_INTENT_STATUSES),\n merchantAccountId: z.string().uuid(),\n merchantName: z.string(),\n merchantCategoryCode: z.string(),\n description: z.string().nullable(),\n expiresAtMs: z.number().int().nonnegative().nullable(),\n});\nexport type PublicCollectionIntent = z.infer<\n typeof PublicCollectionIntentSchema\n>;\n\nexport const PayCollectionInputSchema = z.object({\n reference: ReferenceSchema,\n amountKobo: MoneyKoboSchema.optional(),\n currency: CurrencySchema.optional(),\n idempotencyKey: z.string().trim().min(8).max(160).optional(),\n});\nexport type PayCollectionInput = z.infer<typeof PayCollectionInputSchema>;\n\nexport const CollectionPaymentSchema = z.object({\n paymentId: z.string().uuid(),\n intentId: z.string().uuid(),\n accountId: z.string().uuid(),\n payerUserId: z.string().uuid().nullable(),\n merchantOwnerUserId: z.string().uuid(),\n amountKobo: MoneyKoboSchema,\n currency: z.string().length(3),\n status: z.enum(COLLECTION_PAYMENT_STATUSES),\n provider: z.string(),\n providerReference: z.string().nullable(),\n idempotencyKey: z.string().nullable(),\n ledgerRef: z.string(),\n failureCode: z.string().nullable(),\n failureMessage: z.string().nullable(),\n paidAtMs: z.number().int().nonnegative().nullable(),\n createdAtMs: z.number().int().nonnegative(),\n updatedAtMs: z.number().int().nonnegative(),\n});\nexport type CollectionPayment = z.infer<typeof CollectionPaymentSchema>;\n\nexport const CollectionPaymentResultSchema = z.object({\n payment: CollectionPaymentSchema,\n intent: CollectionIntentSchema,\n receipt: z.unknown().optional(),\n replayed: z.boolean(),\n});\nexport type CollectionPaymentResult = z.infer<\n typeof CollectionPaymentResultSchema\n>;\n\nexport const CollectionReportSummarySchema = z.object({\n accountId: z.string().uuid(),\n fromMs: z.number().int().nonnegative(),\n toMs: z.number().int().nonnegative(),\n currency: z.string().length(3),\n paidCount: z.number().int().nonnegative(),\n paidAmountKobo: z.number().int().nonnegative(),\n pendingCount: z.number().int().nonnegative(),\n failedCount: z.number().int().nonnegative(),\n reversedCount: z.number().int().nonnegative(),\n availableBalanceKobo: z.number().int().nonnegative(),\n});\nexport type CollectionReportSummary = z.infer<\n typeof CollectionReportSummarySchema\n>;\n\nexport const CollectionStatementSchema = z.object({\n accountId: z.string().uuid(),\n year: z.number().int(),\n month: z.number().int().min(1).max(12),\n currency: z.string().length(3),\n totalPaidKobo: z.number().int().nonnegative(),\n items: z.array(CollectionPaymentSchema),\n});\nexport type CollectionStatement = z.infer<typeof CollectionStatementSchema>;\n\nexport const CreatePayoutInputSchema = z.object({\n amountKobo: MoneyKoboSchema,\n currency: CurrencySchema.optional(),\n idempotencyKey: z.string().trim().min(8).max(160),\n});\nexport type CreatePayoutInput = z.infer<typeof CreatePayoutInputSchema>;\n\nexport const MerchantPayoutSchema = z.object({\n payoutId: z.string().uuid(),\n accountId: z.string().uuid(),\n amountKobo: MoneyKoboSchema,\n currency: z.string().length(3),\n status: z.enum(MERCHANT_PAYOUT_STATUSES),\n idempotencyKey: z.string().nullable(),\n ledgerRef: z.string(),\n providerReference: z.string().nullable(),\n requestedByUserId: z.string().uuid().nullable(),\n failureCode: z.string().nullable(),\n failureMessage: z.string().nullable(),\n createdAtMs: z.number().int().nonnegative(),\n updatedAtMs: z.number().int().nonnegative(),\n});\nexport type MerchantPayout = z.infer<typeof MerchantPayoutSchema>;\n\nexport const ProviderEventInputSchema = z.object({\n provider: z.string().trim().min(1).max(80),\n eventId: z.string().trim().min(1).max(160),\n eventType: z.string().trim().min(1).max(120),\n payload: z.record(z.unknown()).optional(),\n});\nexport type ProviderEventInput = z.infer<typeof ProviderEventInputSchema>;\n\nexport const ProviderEventRecordSchema = z.object({\n id: z.string().uuid(),\n provider: z.string(),\n eventId: z.string(),\n eventType: z.string(),\n signatureVerified: z.boolean(),\n receivedAtMs: z.number().int().nonnegative(),\n processedAtMs: z.number().int().nonnegative().nullable(),\n});\nexport type ProviderEventRecord = z.infer<typeof ProviderEventRecordSchema>;\n\nexport type CollectionsClientOptions = {\n baseUrl: string;\n fetchImpl?: typeof fetch;\n};\n\nexport type CollectionsClient = {\n upsertMerchantProfile: (\n accountId: string,\n input: UpsertMerchantProfileInput,\n ) => Promise<MerchantProfile>;\n getMerchantProfile: (accountId: string) => Promise<MerchantProfile>;\n createIntent: (\n input: CreateCollectionIntentInput,\n ) => Promise<CollectionIntent>;\n getIntent: (intentId: string) => Promise<CollectionIntent>;\n resolveIntent: (reference: string) => Promise<PublicCollectionIntent>;\n pay: (input: PayCollectionInput) => Promise<CollectionPaymentResult>;\n reportSummary: (input: {\n fromMs: number;\n toMs: number;\n currency?: string;\n }) => Promise<CollectionReportSummary>;\n monthlyStatement: (input: {\n year: number;\n month: number;\n currency?: string;\n }) => Promise<CollectionStatement>;\n createPayout: (input: CreatePayoutInput) => Promise<MerchantPayout>;\n getPayout: (payoutId: string) => Promise<MerchantPayout>;\n recordProviderEvent: (\n input: ProviderEventInput,\n ) => Promise<ProviderEventRecord>;\n};\n\nexport type PartnerCollectionsClient = Pick<\n CollectionsClient,\n | 'createIntent'\n | 'getIntent'\n | 'reportSummary'\n | 'monthlyStatement'\n | 'createPayout'\n | 'getPayout'\n | 'recordProviderEvent'\n>;\n\nexport type ConsumerCollectionsClient = Pick<\n CollectionsClient,\n 'resolveIntent' | 'pay'\n>;\n\nexport function createCollectionsClient(\n opts: CollectionsClientOptions,\n): CollectionsClient {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\n 'createCollectionsClient: 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: { accept: 'application/json' },\n };\n if (body !== undefined) {\n init.body = JSON.stringify(body);\n init.headers = { ...init.headers, 'content-type': 'application/json' };\n }\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 raw = text;\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 return {\n upsertMerchantProfile: (accountId, input) =>\n call(\n 'PUT',\n `/v1/accounts/${encodeURIComponent(accountId)}/merchant-profile`,\n UpsertMerchantProfileInputSchema.parse(input),\n (raw) => MerchantProfileSchema.parse(raw),\n ),\n getMerchantProfile: (accountId) =>\n call(\n 'GET',\n `/v1/accounts/${encodeURIComponent(accountId)}/merchant-profile`,\n undefined,\n (raw) => MerchantProfileSchema.parse(raw),\n ),\n createIntent: (input) =>\n call(\n 'POST',\n '/v1/collections/intents',\n CreateCollectionIntentInputSchema.parse(input),\n (raw) => CollectionIntentSchema.parse(raw),\n ),\n getIntent: (intentId) =>\n call(\n 'GET',\n `/v1/collections/intents/${encodeURIComponent(intentId)}`,\n undefined,\n (raw) => CollectionIntentSchema.parse(raw),\n ),\n resolveIntent: (reference) =>\n call(\n 'GET',\n `/v1/collections/resolve/${encodeURIComponent(reference)}`,\n undefined,\n (raw) => PublicCollectionIntentSchema.parse(raw),\n ),\n pay: (input) =>\n call(\n 'POST',\n '/v1/collections/pay',\n PayCollectionInputSchema.parse(input),\n (raw) => CollectionPaymentResultSchema.parse(raw),\n ),\n reportSummary: (input) => {\n const qs = new URLSearchParams({\n fromMs: String(input.fromMs),\n toMs: String(input.toMs),\n });\n if (input.currency) qs.set('currency', input.currency);\n return call(\n 'GET',\n `/v1/collections/reports/summary?${qs.toString()}`,\n undefined,\n (raw) => CollectionReportSummarySchema.parse(raw),\n );\n },\n monthlyStatement: (input) => {\n const qs = new URLSearchParams({\n year: String(input.year),\n month: String(input.month),\n });\n if (input.currency) qs.set('currency', input.currency);\n return call(\n 'GET',\n `/v1/collections/statements/monthly?${qs.toString()}`,\n undefined,\n (raw) => CollectionStatementSchema.parse(raw),\n );\n },\n createPayout: (input) =>\n call(\n 'POST',\n '/v1/collections/payouts',\n CreatePayoutInputSchema.parse(input),\n (raw) => MerchantPayoutSchema.parse(raw),\n ),\n getPayout: (payoutId) =>\n call(\n 'GET',\n `/v1/collections/payouts/${encodeURIComponent(payoutId)}`,\n undefined,\n (raw) => MerchantPayoutSchema.parse(raw),\n ),\n recordProviderEvent: (input) =>\n call(\n 'POST',\n '/v1/collections/provider-events',\n ProviderEventInputSchema.parse(input),\n (raw) => ProviderEventRecordSchema.parse(raw),\n ),\n };\n}\n\nexport function createPartnerCollectionsClient(\n opts: CollectionsClientOptions,\n): PartnerCollectionsClient {\n const client = createCollectionsClient(opts);\n return {\n createIntent: client.createIntent,\n getIntent: client.getIntent,\n reportSummary: client.reportSummary,\n monthlyStatement: client.monthlyStatement,\n createPayout: client.createPayout,\n getPayout: client.getPayout,\n recordProviderEvent: client.recordProviderEvent,\n };\n}\n\nexport function createConsumerCollectionsClient(\n opts: CollectionsClientOptions,\n): ConsumerCollectionsClient {\n const client = createCollectionsClient(opts);\n return {\n resolveIntent: client.resolveIntent,\n pay: client.pay,\n };\n}\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 { 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 'collections:write',\n 'collections:read',\n 'collections:pay',\n 'collections:webhook',\n 'reports:read',\n 'payouts:write',\n 'payouts:read',\n 'partner:funding:write',\n 'partner:payout:write',\n 'partner:reconciliation: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 /** Optional scope claim forwarded as X-Flur-Scope; backend credentials remain authoritative. */\n scope?: readonly PartnerScope[];\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 const scopeHeader = normalizeScopeHeader(opts.scope);\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 (scopeHeader) headers['x-flur-scope'] = scopeHeader;\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\nfunction normalizeScopeHeader(\n scope: readonly PartnerScope[] | undefined,\n): string | undefined {\n if (!scope || scope.length === 0) return undefined;\n const unique = Array.from(new Set(scope));\n for (const item of unique) {\n if (!(PARTNER_SCOPES as readonly string[]).includes(item)) {\n throw new Error(`unsupported partner scope: ${item}`);\n }\n }\n return unique.join(' ');\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","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 { createFlurPartnerClient } from '../partner/index.js';\nimport type { PartnerScope } from '../partner/index.js';\nimport { createPassesClient, type PassesClient } from '../passes/index.js';\nimport {\n createReceiptsClient,\n type ReceiptsClient,\n} from '../receipts/index.js';\nimport {\n createPartnerCollectionsClient,\n type PartnerCollectionsClient,\n} from '../collections/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 credentials remain authoritative. */\n scope?: readonly PartnerScope[];\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 /** Collections: merchant NQR intents, reports, statements, payouts. */\n collections: PartnerCollectionsClient;\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 partner = createFlurPartnerClient({\n baseUrl: opts.baseUrl,\n keyId: opts.apiKey,\n secret: opts.apiSecret,\n fetchImpl: opts.fetchImpl,\n scope: opts.scope,\n });\n const signedFetch = partner.fetch;\n const baseUrl = opts.baseUrl.replace(/\\/$/, '');\n\n function subscribeToPayments(s: SubscribeOptions) {\n let cancelled = false;\n\n queueMicrotask(() => {\n if (cancelled) return;\n s.onError?.(\n new Error(\n 'cash.subscribeToPayments is not available on this backend release; use collections reports or provider webhooks for payment status.',\n ),\n );\n });\n\n return () => {\n cancelled = true;\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 const collections = createPartnerCollectionsClient({\n baseUrl,\n fetchImpl: signedFetch,\n });\n\n return {\n // top-level back-compat surface\n generateStaticQR,\n generateDynamicQR,\n parseQR,\n subscribeToPayments,\n // namespaces\n cash,\n collections,\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","/**\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","/**\n * Partner-funded wallet rails SDK.\n *\n * Provides two clients:\n * - `createPartnerFundingClient(partnerClient)` — uses partner HMAC for\n * the bank/merchant partner endpoints (funding webhook, payout events,\n * daily reconciliation). The caller MUST have minted credentials with\n * the appropriate scopes (`partner:funding:write`, `partner:payout:write`,\n * `partner:reconciliation:read`).\n * - `createConsumerWithdrawalsClient(opts)` — session-bearer auth for the\n * consumer endpoints (linked payout destinations, withdrawals).\n *\n * Schemas mirror `flur-backend/src/partner-funding/types.ts`. Money is\n * always represented in MINOR units (e.g. kobo for NGN). BIGINT-bearing\n * response fields are serialized as integer strings to avoid JS number\n * precision issues; reserve balances and imbalances may be signed.\n */\nimport { z } from 'zod';\nimport type { FlurPartnerClient } from '../partner/client.js';\nimport { FlurApiError } from '../errors.js';\n\n// ───────────────────────────── shared ─────────────────────────────\n\nconst MinorString = z.string().regex(/^-?\\d+$/);\nconst PositiveMinor = z.union([\n z.number().int().positive(),\n z.string().regex(/^[1-9]\\d{0,18}$/),\n]);\nconst Currency = z\n .string()\n .trim()\n .length(3)\n .transform((v) => v.toUpperCase());\nconst Metadata = z.record(z.unknown());\n\nexport const PARTNER_KINDS = ['bank', 'merchant'] as const;\nexport type PartnerKind = (typeof PARTNER_KINDS)[number];\n\nexport const CUSTODIAL_MODES = ['agent_of_bank', 'flur_virtual_pool'] as const;\nexport type CustodialMode = (typeof CUSTODIAL_MODES)[number];\n\nexport const PARTNER_PROFILE_STATUSES = [\n 'active',\n 'suspended',\n 'closed',\n] as const;\nexport type PartnerProfileStatus = (typeof PARTNER_PROFILE_STATUSES)[number];\n\nexport const PARTNER_FUNDING_DIRECTIONS = ['credit', 'debit'] as const;\nexport type PartnerFundingDirection =\n (typeof PARTNER_FUNDING_DIRECTIONS)[number];\n\nexport const PARTNER_FUNDING_STATUSES = [\n 'pending',\n 'posted',\n 'failed',\n] as const;\nexport type PartnerFundingStatus = (typeof PARTNER_FUNDING_STATUSES)[number];\n\nexport const PAYOUT_DESTINATION_STATUSES = [\n 'pending',\n 'verified',\n 'disabled',\n] as const;\nexport type PayoutDestinationStatus =\n (typeof PAYOUT_DESTINATION_STATUSES)[number];\n\nexport const WITHDRAWAL_STATES = [\n 'requested',\n 'submitted',\n 'processing',\n 'paid',\n 'failed',\n 'reversed',\n] as const;\nexport type WithdrawalState = (typeof WITHDRAWAL_STATES)[number];\n\n// ───────────────────────────── profile ─────────────────────────────\n\nexport const PartnerProfileSchema = z.object({\n partnerAccountId: z.string().uuid(),\n kind: z.enum(PARTNER_KINDS),\n custodialMode: z.enum(CUSTODIAL_MODES),\n displayName: z.string(),\n bankCode: z.string().nullable(),\n poolAccountNumber: z.string().nullable(),\n status: z.enum(PARTNER_PROFILE_STATUSES),\n metadata: Metadata,\n createdAtMs: z.number().int().nonnegative(),\n updatedAtMs: z.number().int().nonnegative(),\n});\nexport type PartnerProfile = z.infer<typeof PartnerProfileSchema>;\n\nexport const UpsertPartnerProfileInputSchema = z.object({\n kind: z.enum(PARTNER_KINDS),\n custodialMode: z.enum(CUSTODIAL_MODES),\n displayName: z.string().trim().min(1).max(200),\n bankCode: z.string().trim().min(1).max(64).optional(),\n poolAccountNumber: z.string().trim().min(1).max(64).optional(),\n metadata: Metadata.optional(),\n});\nexport type UpsertPartnerProfileInput = z.infer<\n typeof UpsertPartnerProfileInputSchema\n>;\n\n// ───────────────────────────── fundings ─────────────────────────────\n\nexport const PartnerFundingEventInputSchema = z.object({\n externalRef: z.string().trim().min(8).max(128),\n direction: z.enum(PARTNER_FUNDING_DIRECTIONS).optional(),\n userId: z.string().uuid().optional(),\n accountId: z.string().uuid().optional(),\n amountMinor: PositiveMinor,\n currency: Currency,\n fundingSource: z.string().trim().min(1).max(64).optional(),\n providerMetadata: Metadata.optional(),\n});\nexport type PartnerFundingEventInput = z.infer<\n typeof PartnerFundingEventInputSchema\n>;\n\nexport const PartnerFundingSchema = z.object({\n fundingId: z.string().uuid(),\n partnerId: z.string().uuid(),\n accountId: z.string().uuid(),\n userId: z.string().uuid().nullable(),\n direction: z.enum(PARTNER_FUNDING_DIRECTIONS),\n currency: z.string(),\n amountMinor: MinorString,\n externalRef: z.string(),\n status: z.enum(PARTNER_FUNDING_STATUSES),\n fundingSource: z.string(),\n ledgerRef: z.string(),\n providerMetadata: Metadata,\n createdAtMs: z.number().int().nonnegative(),\n updatedAtMs: z.number().int().nonnegative(),\n});\nexport type PartnerFunding = z.infer<typeof PartnerFundingSchema>;\n\nexport const IngestFundingResultSchema = z.object({\n funding: PartnerFundingSchema,\n replayed: z.boolean(),\n});\nexport type IngestFundingResult = z.infer<typeof IngestFundingResultSchema>;\n\n// ───────────────────────────── destinations ─────────────────────────────\n\nexport const PayoutDestinationSchema = z.object({\n destinationId: z.string().uuid(),\n accountId: z.string().uuid(),\n partnerId: z.string().uuid(),\n bankCode: z.string(),\n accountNumber: z.string(),\n accountName: z.string(),\n status: z.enum(PAYOUT_DESTINATION_STATUSES),\n verifiedAtMs: z.number().int().nonnegative().nullable(),\n metadata: Metadata,\n createdAtMs: z.number().int().nonnegative(),\n updatedAtMs: z.number().int().nonnegative(),\n});\nexport type PayoutDestination = z.infer<typeof PayoutDestinationSchema>;\n\nexport const CreatePayoutDestinationInputSchema = z.object({\n partnerId: z.string().uuid(),\n bankCode: z.string().trim().min(1).max(32),\n accountNumber: z.string().trim().min(4).max(64),\n accountName: z.string().trim().min(1).max(200),\n metadata: Metadata.optional(),\n});\nexport type CreatePayoutDestinationInput = z.infer<\n typeof CreatePayoutDestinationInputSchema\n>;\n\nexport const ListPayoutDestinationsResultSchema = z.object({\n items: z.array(PayoutDestinationSchema),\n});\nexport type ListPayoutDestinationsResult = z.infer<\n typeof ListPayoutDestinationsResultSchema\n>;\n\n// ───────────────────────────── withdrawals ─────────────────────────────\n\nexport const WithdrawalSchema = z.object({\n withdrawalId: z.string().uuid(),\n accountId: z.string().uuid(),\n userId: z.string().uuid(),\n partnerId: z.string().uuid(),\n destinationId: z.string().uuid(),\n currency: z.string(),\n amountMinor: MinorString,\n state: z.enum(WITHDRAWAL_STATES),\n idempotencyKey: z.string(),\n providerRef: z.string().nullable(),\n lastError: z.string().nullable(),\n ledgerRef: z.string(),\n reverseLedgerRef: z.string().nullable(),\n metadata: Metadata,\n createdAtMs: z.number().int().nonnegative(),\n updatedAtMs: z.number().int().nonnegative(),\n});\nexport type Withdrawal = z.infer<typeof WithdrawalSchema>;\n\nexport const CreateWithdrawalInputSchema = z.object({\n destinationId: z.string().uuid(),\n amountMinor: PositiveMinor,\n currency: Currency,\n idempotencyKey: z.string().trim().min(8).max(128),\n metadata: Metadata.optional(),\n});\nexport type CreateWithdrawalInput = z.infer<typeof CreateWithdrawalInputSchema>;\n\nexport const CreateWithdrawalResultSchema = z.object({\n withdrawal: WithdrawalSchema,\n replayed: z.boolean(),\n});\nexport type CreateWithdrawalResult = z.infer<\n typeof CreateWithdrawalResultSchema\n>;\n\n// ───────────────────────────── payout events ─────────────────────────────\n\nexport const PayoutEventInputSchema = z.object({\n externalRef: z.string().trim().min(8).max(128),\n withdrawalId: z.string().uuid().optional(),\n state: z.enum(['submitted', 'processing', 'paid', 'failed']),\n providerRef: z.string().trim().min(1).max(128).optional(),\n failureCode: z.string().trim().max(64).optional(),\n failureMessage: z.string().trim().max(512).optional(),\n providerMetadata: Metadata.optional(),\n});\nexport type PayoutEventInput = z.infer<typeof PayoutEventInputSchema>;\n\nexport const RecordPayoutEventResultSchema = z.object({\n withdrawal: WithdrawalSchema,\n replayed: z.boolean(),\n});\nexport type RecordPayoutEventResult = z.infer<\n typeof RecordPayoutEventResultSchema\n>;\n\n// ───────────────────────────── reconciliation ─────────────────────────────\n\nexport const ReconciliationReportSchema = z.object({\n partnerId: z.string().uuid(),\n currency: z.string(),\n fromMs: z.number().int().nonnegative(),\n toMs: z.number().int().nonnegative(),\n fundingsCreditMinor: MinorString,\n fundingsDebitMinor: MinorString,\n withdrawalsPaidMinor: MinorString,\n withdrawalsReversedMinor: MinorString,\n withdrawalsInFlightMinor: MinorString,\n expectedReserveBalanceMinor: MinorString,\n actualReserveBalanceMinor: MinorString,\n imbalanceMinor: MinorString,\n generatedAtMs: z.number().int().nonnegative(),\n});\nexport type ReconciliationReport = z.infer<typeof ReconciliationReportSchema>;\n\n// ───────────────────────────── partner client ─────────────────────────────\n\nexport type PartnerFundingClient = {\n /** Submit a funding event (idempotent on externalRef per partner). */\n ingestFunding: (\n input: PartnerFundingEventInput,\n ) => Promise<IngestFundingResult>;\n /** Send a payout state update (idempotent on terminal states). */\n recordPayoutEvent: (\n input: PayoutEventInput,\n ) => Promise<RecordPayoutEventResult>;\n /** Fetch the daily reconciliation report. */\n reconciliation: (input: {\n currency: string;\n fromMs?: number;\n toMs?: number;\n }) => Promise<ReconciliationReport>;\n};\n\nexport function createPartnerFundingClient(\n partner: FlurPartnerClient,\n): PartnerFundingClient {\n return {\n ingestFunding: async (input) => {\n const body = PartnerFundingEventInputSchema.parse(input);\n const raw = await partner.request({\n method: 'POST',\n path: '/v1/partners/fundings',\n body,\n });\n return IngestFundingResultSchema.parse(raw);\n },\n recordPayoutEvent: async (input) => {\n const body = PayoutEventInputSchema.parse(input);\n const raw = await partner.request({\n method: 'POST',\n path: '/v1/partners/payouts/events',\n body,\n });\n return RecordPayoutEventResultSchema.parse(raw);\n },\n reconciliation: async (input) => {\n const qs = new URLSearchParams({\n currency: input.currency,\n });\n if (typeof input.fromMs === 'number')\n qs.set('fromMs', String(input.fromMs));\n if (typeof input.toMs === 'number') qs.set('toMs', String(input.toMs));\n const raw = await partner.request({\n method: 'GET',\n path: `/v1/partners/reconciliation/daily?${qs.toString()}`,\n });\n return ReconciliationReportSchema.parse(raw);\n },\n };\n}\n\n// ───────────────────────────── consumer client ─────────────────────────────\n\nexport type ConsumerWithdrawalsClientOptions = {\n baseUrl: string;\n /** Session-authenticated fetch (Authorization: Bearer <session-token>). */\n fetchImpl?: typeof fetch;\n};\n\nexport type ConsumerWithdrawalsClient = {\n listDestinations: () => Promise<ListPayoutDestinationsResult>;\n createDestination: (\n input: CreatePayoutDestinationInput,\n ) => Promise<PayoutDestination>;\n verifyDestination: (destinationId: string) => Promise<PayoutDestination>;\n disableDestination: (destinationId: string) => Promise<PayoutDestination>;\n createWithdrawal: (\n input: CreateWithdrawalInput,\n ) => Promise<CreateWithdrawalResult>;\n getWithdrawal: (withdrawalId: string) => Promise<Withdrawal>;\n};\n\nexport function createConsumerWithdrawalsClient(\n opts: ConsumerWithdrawalsClientOptions,\n): ConsumerWithdrawalsClient {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\n 'createConsumerWithdrawalsClient: 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: { accept: 'application/json' },\n };\n if (body !== undefined) {\n init.body = JSON.stringify(body);\n init.headers = { ...init.headers, 'content-type': 'application/json' };\n }\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 raw = text;\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 return {\n listDestinations: () =>\n call('GET', '/v1/me/payout-destinations', undefined, (raw) =>\n ListPayoutDestinationsResultSchema.parse(raw),\n ),\n createDestination: (input) =>\n call(\n 'POST',\n '/v1/me/payout-destinations',\n CreatePayoutDestinationInputSchema.parse(input),\n (raw) => PayoutDestinationSchema.parse(raw),\n ),\n verifyDestination: (destinationId) =>\n call(\n 'POST',\n `/v1/me/payout-destinations/${encodeURIComponent(destinationId)}/verify`,\n {},\n (raw) => PayoutDestinationSchema.parse(raw),\n ),\n disableDestination: (destinationId) =>\n call(\n 'POST',\n `/v1/me/payout-destinations/${encodeURIComponent(destinationId)}/disable`,\n {},\n (raw) => PayoutDestinationSchema.parse(raw),\n ),\n createWithdrawal: (input) =>\n call(\n 'POST',\n '/v1/me/withdrawals',\n CreateWithdrawalInputSchema.parse(input),\n (raw) => CreateWithdrawalResultSchema.parse(raw),\n ),\n getWithdrawal: (withdrawalId) =>\n call(\n 'GET',\n `/v1/me/withdrawals/${encodeURIComponent(withdrawalId)}`,\n undefined,\n (raw) => WithdrawalSchema.parse(raw),\n ),\n };\n}\n\n// ───────────────────────────── partner profile admin ─────────────────────────────\n\n/**\n * Partner profile upsert is session-authenticated on the backend (a member\n * of the partner account must perform the action), so it uses a regular\n * session-bearer fetch rather than the partner HMAC client.\n */\nexport type PartnerProfileAdminClientOptions = {\n baseUrl: string;\n fetchImpl?: typeof fetch;\n};\n\nexport type PartnerProfileAdminClient = {\n upsertProfile: (\n partnerAccountId: string,\n input: UpsertPartnerProfileInput,\n ) => Promise<PartnerProfile>;\n};\n\nexport function createPartnerProfileAdminClient(\n opts: PartnerProfileAdminClientOptions,\n): PartnerProfileAdminClient {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\n 'createPartnerProfileAdminClient: no fetch implementation available',\n );\n }\n const baseUrl = opts.baseUrl.replace(/\\/$/, '');\n return {\n upsertProfile: async (partnerAccountId, input) => {\n const body = {\n partnerAccountId,\n ...UpsertPartnerProfileInputSchema.parse(input),\n };\n const resp = await fetchImpl(`${baseUrl}/v1/partners/profile`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n accept: 'application/json',\n },\n body: JSON.stringify(body),\n });\n const text = await resp.text();\n let raw: unknown;\n if (text) {\n try {\n raw = JSON.parse(text);\n } catch {\n raw = text;\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 PartnerProfileSchema.parse(raw);\n },\n };\n}\n","import { z } from 'zod';\nimport { canonicalJSONBytes } from '../crypto/canonical.js';\nimport { sign, verify } from '../crypto/ed25519.js';\nimport { bytesToHex, hexToBytes } from '../offline/oac.js';\n\n/**\n * Flur v1 Signed Artifact envelope.\n *\n * URI form:\n * flur://v1/<artifact-type>/<base64url(canonical-json(body))>.<base64url(sig)>\n *\n * Body shape (canonical JSON, sorted keys):\n * {\n * v: 1, // envelope version\n * t: '<artifact-type>', // matches the URI segment (redundant for safety)\n * iss: '<issuer-id>', // user/merchant/partner id\n * kid: '<device-key-id>', // identifier of the signing device key\n * iat: <epoch-seconds>, // issued-at\n * exp?: <epoch-seconds>, // optional expiry\n * nonce: '<string>', // unique per artifact (replay guard)\n * data: <artifact body> // type-specific, validated by registered schema\n * }\n *\n * Signature: Ed25519 over canonicalJSONBytes(body), hex-encoded (64 bytes / 128 hex chars).\n *\n * Design notes:\n * - URI scheme `flur://v1/...` is the single transport for all signed artifacts.\n * - Scanners route on the path segment; verifiers look up the issuer/kid public key.\n * - Pure NIBSS NQR payments remain unchanged; this envelope rides separately.\n */\n\nexport const FLUR_ARTIFACT_URI_SCHEME = 'flur';\nexport const FLUR_ARTIFACT_VERSION = 1;\nexport const FLUR_ARTIFACT_URI_PREFIX = `${FLUR_ARTIFACT_URI_SCHEME}://v${FLUR_ARTIFACT_VERSION}/`;\n\nconst ArtifactTypeRe = /^[a-z][a-z0-9_]{1,63}$/;\n\nexport const ArtifactHeaderSchema = z.object({\n v: z.literal(FLUR_ARTIFACT_VERSION),\n t: z.string().regex(ArtifactTypeRe, 'invalid artifact type'),\n iss: z.string().min(1).max(128),\n kid: z.string().min(1).max(128),\n iat: z.number().int().nonnegative(),\n exp: z.number().int().positive().optional(),\n nonce: z\n .string()\n .min(8)\n .max(64)\n .regex(/^[A-Za-z0-9_-]+$/, 'nonce must be url-safe'),\n});\n\nexport type ArtifactHeader = z.infer<typeof ArtifactHeaderSchema>;\n\nexport type ArtifactBody<T = unknown> = ArtifactHeader & { data: T };\n\nexport type SignedArtifact<T = unknown> = {\n body: ArtifactBody<T>;\n sig: string; // hex\n};\n\nexport class FlurArtifactError extends Error {\n constructor(\n message: string,\n public code:\n | 'INVALID_URI'\n | 'INVALID_TYPE'\n | 'INVALID_BODY'\n | 'INVALID_SIGNATURE'\n | 'EXPIRED'\n | 'TYPE_MISMATCH',\n ) {\n super(message);\n this.name = 'FlurArtifactError';\n }\n}\n\n// --- base64url helpers (no padding) ---\n\nexport function base64UrlEncode(bytes: Uint8Array): string {\n let bin = '';\n for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i]);\n // btoa is available in browsers, RN (Hermes), and Node >= 16.\n const b64 =\n typeof btoa === 'function'\n ? btoa(bin)\n : Buffer.from(bytes).toString('base64');\n return b64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nexport function base64UrlDecode(s: string): Uint8Array {\n const pad = s.length % 4 === 0 ? '' : '='.repeat(4 - (s.length % 4));\n const b64 = s.replace(/-/g, '+').replace(/_/g, '/') + pad;\n if (typeof atob === 'function') {\n const bin = atob(b64);\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n }\n return new Uint8Array(Buffer.from(b64, 'base64'));\n}\n\n// --- envelope build / sign / verify ---\n\nexport function buildArtifactBody<T>(input: {\n type: string;\n issuer: string;\n keyId: string;\n data: T;\n issuedAtSeconds?: number;\n expiresAtSeconds?: number;\n nonce: string;\n}): ArtifactBody<T> {\n if (!ArtifactTypeRe.test(input.type)) {\n throw new FlurArtifactError(\n `Invalid artifact type: ${input.type}`,\n 'INVALID_TYPE',\n );\n }\n const iat = input.issuedAtSeconds ?? Math.floor(Date.now() / 1000);\n const header: ArtifactHeader = {\n v: FLUR_ARTIFACT_VERSION,\n t: input.type,\n iss: input.issuer,\n kid: input.keyId,\n iat,\n ...(input.expiresAtSeconds !== undefined\n ? { exp: input.expiresAtSeconds }\n : {}),\n nonce: input.nonce,\n };\n // Validate header structure early so callers get a clean error.\n ArtifactHeaderSchema.parse(header);\n return { ...header, data: input.data };\n}\n\nexport function signArtifact<T>(\n body: ArtifactBody<T>,\n privateKey: Uint8Array,\n): SignedArtifact<T> {\n const sig = bytesToHex(sign(canonicalJSONBytes(body), privateKey));\n return { body, sig };\n}\n\nexport function encodeArtifactUri<T>(signed: SignedArtifact<T>): string {\n const bodyBytes = canonicalJSONBytes(signed.body);\n const bodyB64 = base64UrlEncode(bodyBytes);\n const sigB64 = base64UrlEncode(hexToBytes(signed.sig));\n return `${FLUR_ARTIFACT_URI_PREFIX}${signed.body.t}/${bodyB64}.${sigB64}`;\n}\n\nexport type DecodedArtifactUri = {\n type: string;\n bodyBytes: Uint8Array;\n body: ArtifactBody;\n sig: string; // hex\n};\n\nexport function decodeArtifactUri(uri: string): DecodedArtifactUri {\n if (!uri.startsWith(FLUR_ARTIFACT_URI_PREFIX)) {\n throw new FlurArtifactError(\n `URI does not start with ${FLUR_ARTIFACT_URI_PREFIX}`,\n 'INVALID_URI',\n );\n }\n const rest = uri.slice(FLUR_ARTIFACT_URI_PREFIX.length);\n const slash = rest.indexOf('/');\n if (slash <= 0) {\n throw new FlurArtifactError('Missing artifact type segment', 'INVALID_URI');\n }\n const type = rest.slice(0, slash);\n const payload = rest.slice(slash + 1);\n const dot = payload.indexOf('.');\n if (dot <= 0 || dot === payload.length - 1) {\n throw new FlurArtifactError(\n 'Missing body/signature separator',\n 'INVALID_URI',\n );\n }\n if (!ArtifactTypeRe.test(type)) {\n throw new FlurArtifactError(\n `Invalid artifact type: ${type}`,\n 'INVALID_TYPE',\n );\n }\n\n const bodyBytes = base64UrlDecode(payload.slice(0, dot));\n const sigBytes = base64UrlDecode(payload.slice(dot + 1));\n if (sigBytes.length !== 64) {\n throw new FlurArtifactError(\n `Signature must be 64 bytes, got ${sigBytes.length}`,\n 'INVALID_SIGNATURE',\n );\n }\n\n let bodyJson: unknown;\n try {\n bodyJson = JSON.parse(new TextDecoder().decode(bodyBytes));\n } catch {\n throw new FlurArtifactError('Body is not valid JSON', 'INVALID_BODY');\n }\n\n const headerOnly = ArtifactHeaderSchema.safeParse(bodyJson);\n if (!headerOnly.success) {\n throw new FlurArtifactError(\n `Body header invalid: ${headerOnly.error.message}`,\n 'INVALID_BODY',\n );\n }\n if (headerOnly.data.t !== type) {\n throw new FlurArtifactError(\n `URI type ${type} does not match body type ${headerOnly.data.t}`,\n 'TYPE_MISMATCH',\n );\n }\n\n return {\n type,\n bodyBytes,\n body: bodyJson as ArtifactBody,\n sig: bytesToHex(sigBytes),\n };\n}\n\nexport type VerifyArtifactOptions = {\n /** Caller-supplied current time (seconds). Defaults to Date.now()/1000. */\n nowSeconds?: number;\n /** When true (default), reject artifacts whose `exp` is in the past. */\n enforceExpiry?: boolean;\n};\n\nexport function verifyArtifactSignature(\n decoded: DecodedArtifactUri,\n publicKey: Uint8Array,\n options: VerifyArtifactOptions = {},\n): boolean {\n if (options.enforceExpiry !== false && decoded.body.exp !== undefined) {\n const now = options.nowSeconds ?? Math.floor(Date.now() / 1000);\n if (decoded.body.exp < now) {\n throw new FlurArtifactError('Artifact has expired', 'EXPIRED');\n }\n }\n return verify(decoded.bodyBytes, hexToBytes(decoded.sig), publicKey);\n}\n","import { z } from 'zod';\nimport { OfflinePaymentAuthorizationSchema } from '../offline/messages.js';\n\n/**\n * Registry of all Flur v1 signed artifact types.\n *\n * Each artifact has:\n * - a string discriminator (used in the URI path segment & header `t`),\n * - a Zod schema validating the `data` payload only (envelope header is validated separately).\n *\n * Two artifacts are fully specified in this slice (OPA + Receipt) as the\n * canonical implementation pattern. The remaining nine carry stub schemas\n * (`z.unknown()`) so types compile and the registry is complete; bodies\n * will be locked in subsequent slices once their backend ledger shapes\n * are finalised.\n */\n\nexport const ARTIFACT_TYPES = {\n OFFLINE_PAYMENT_AUTHORIZATION: 'offline_payment_authorization',\n RECEIPT: 'receipt',\n // --- stubs, schemas to be hardened in follow-ups ---\n NQR_PAYMENT_REQUEST: 'nqr_payment_request',\n PAYMENT_INTENT: 'payment_intent',\n OFFLINE_CLAIM: 'offline_claim',\n SETTLEMENT_RECORD: 'settlement_record',\n REVERSAL_RECORD: 'reversal_record',\n LEDGER_JOURNAL_ENTRY: 'ledger_journal_entry',\n STATEMENT: 'statement',\n PASS: 'pass',\n IDENTITY: 'identity',\n} as const;\n\nexport type ArtifactType = (typeof ARTIFACT_TYPES)[keyof typeof ARTIFACT_TYPES];\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// --- Fully specified: offline_payment_authorization ---\n// Wraps the existing FLUR2: payload in the unified envelope. The inner\n// OfflinePaymentAuthorization is already self-signed; embedding it here\n// adds the device-key issuer attestation + uniform nonce/expiry handling.\nexport const OfflinePaymentAuthorizationArtifactSchema = z.object({\n authorization: OfflinePaymentAuthorizationSchema,\n});\nexport type OfflinePaymentAuthorizationArtifact = z.infer<\n typeof OfflinePaymentAuthorizationArtifactSchema\n>;\n\n// --- Fully specified: receipt ---\n// Payment receipt produced by the payee after a payment settles (online or\n// reconciled from offline). Signed by the issuer's device key so payers and\n// auditors can verify provenance offline.\nexport const ReceiptArtifactSchema = z.object({\n receiptId: z.string().min(1).max(64),\n paymentReference: z.string().min(1).max(64),\n payerUserId: z.string().min(1).max(64).optional(),\n payeeUserId: z.string().min(1).max(64),\n amountKobo: z.number().int().positive(),\n currency: z.literal('NGN'),\n channel: z.enum(['online', 'offline_reconciled', 'pay_link', 'nqr']),\n settledAtMs: z.number().int().positive(),\n ledgerTxnId: z.string().min(1).max(64).optional(),\n memo: z.string().max(140).optional(),\n hashChainPrev: HexString(32).optional(),\n});\nexport type ReceiptArtifact = z.infer<typeof ReceiptArtifactSchema>;\n\n// --- Shared field primitives (reused across the remaining artifacts) ---\nconst ShortId = z.string().min(1).max(64);\nconst PositiveInt = z.number().int().positive();\nconst NonNegativeInt = z.number().int().nonnegative();\nconst Currency = z.literal('NGN');\nconst Memo = z.string().max(140);\n\n// --- nqr_payment_request ---\n// Merchant- or payee-issued payment request rendered as a Flur QR. The amount\n// may be omitted for \"any amount\" / open-tab flows. Verifiers should refuse\n// expired requests and surface `memo` to the payer.\nexport const NqrPaymentRequestArtifactSchema = z.object({\n requestId: ShortId,\n payeeUserId: ShortId,\n amountKobo: PositiveInt.optional(),\n currency: Currency,\n memo: Memo.optional(),\n expiresAtMs: PositiveInt.optional(),\n});\nexport type NqrPaymentRequestArtifact = z.infer<\n typeof NqrPaymentRequestArtifactSchema\n>;\n\n// --- payment_intent ---\n// Payer-side commitment to pay a specific payee. Bound to an idempotency key\n// so a single intent cannot drive multiple settlements server-side.\nexport const PaymentIntentArtifactSchema = z.object({\n intentId: ShortId,\n payerUserId: ShortId,\n payeeUserId: ShortId,\n amountKobo: PositiveInt,\n currency: Currency,\n idempotencyKey: ShortId,\n createdAtMs: PositiveInt,\n});\nexport type PaymentIntentArtifact = z.infer<typeof PaymentIntentArtifactSchema>;\n\n// --- offline_claim ---\n// Payee's signed claim submitted to settle a previously presented OPA.\n// `claimedAmountKobo` may differ from the OPA face value (e.g. partial fills).\nexport const OfflineClaimArtifactSchema = z.object({\n claimId: ShortId,\n authorizationId: ShortId,\n payeeUserId: ShortId,\n claimedAmountKobo: PositiveInt,\n currency: Currency,\n claimedAtMs: PositiveInt,\n paymentReference: ShortId.optional(),\n});\nexport type OfflineClaimArtifact = z.infer<typeof OfflineClaimArtifactSchema>;\n\n// --- settlement_record ---\n// Internal record of a settlement event, linking the source artifact (OPA,\n// claim, transfer, pay-link) to its ledger transaction.\nexport const SettlementRecordArtifactSchema = z.object({\n settlementId: ShortId,\n ledgerTxnId: ShortId,\n sourceRefType: z.enum([\n 'offline_authorization',\n 'offline_claim',\n 'transfer',\n 'pay_link',\n ]),\n sourceRefId: ShortId,\n amountKobo: PositiveInt,\n currency: Currency,\n settledAtMs: PositiveInt,\n});\nexport type SettlementRecordArtifact = z.infer<\n typeof SettlementRecordArtifactSchema\n>;\n\n// --- reversal_record ---\n// Reversal of a prior settled transaction. `reason` is a closed enum so\n// downstream analytics can bucket disputes reliably.\nexport const ReversalRecordArtifactSchema = z.object({\n reversalId: ShortId,\n originalTxnId: ShortId,\n amountKobo: PositiveInt,\n currency: Currency,\n reason: z.enum([\n 'user_dispute',\n 'fraud',\n 'duplicate',\n 'admin_correction',\n 'other',\n ]),\n reversedAtMs: PositiveInt,\n memo: Memo.optional(),\n});\nexport type ReversalRecordArtifact = z.infer<\n typeof ReversalRecordArtifactSchema\n>;\n\n// --- ledger_journal_entry ---\n// One side-balanced double-entry journal line. `debitAccountId` and\n// `creditAccountId` are opaque internal account identifiers.\nexport const LedgerJournalEntryArtifactSchema = z.object({\n entryId: ShortId,\n journalId: ShortId,\n debitAccountId: ShortId,\n creditAccountId: ShortId,\n amountKobo: PositiveInt,\n currency: Currency,\n postedAtMs: PositiveInt,\n refType: ShortId.optional(),\n refId: ShortId.optional(),\n});\nexport type LedgerJournalEntryArtifact = z.infer<\n typeof LedgerJournalEntryArtifactSchema\n>;\n\n// --- statement ---\n// Account-statement summary for a closed period. `hashChainPrev` links to\n// the prior statement for tamper-evident chaining.\nexport const StatementArtifactSchema = z\n .object({\n statementId: ShortId,\n userId: ShortId,\n periodStartMs: PositiveInt,\n periodEndMs: PositiveInt,\n openingBalanceKobo: z.number().int(),\n closingBalanceKobo: z.number().int(),\n transactionCount: NonNegativeInt,\n currency: Currency,\n hashChainPrev: HexString(32).optional(),\n })\n .refine((v) => v.periodEndMs > v.periodStartMs, {\n message: 'periodEndMs must be greater than periodStartMs',\n path: ['periodEndMs'],\n });\nexport type StatementArtifact = z.infer<typeof StatementArtifactSchema>;\n\n// --- pass ---\n// Generic digital pass (membership, ticket, loyalty, access, voucher).\n// `metadata` is intentionally narrow — only scalar values — so canonical\n// JSON ordering remains deterministic across SDK versions.\nexport const PassArtifactSchema = z\n .object({\n passId: ShortId,\n holderId: ShortId,\n category: z.enum(['membership', 'ticket', 'loyalty', 'access', 'voucher']),\n title: z.string().min(1).max(120),\n validFromMs: PositiveInt,\n validUntilMs: PositiveInt.optional(),\n metadata: z\n .record(\n z.string().min(1).max(64),\n z.union([z.string().max(280), z.number(), z.boolean()]),\n )\n .optional(),\n })\n .refine(\n (v) => v.validUntilMs === undefined || v.validUntilMs > v.validFromMs,\n {\n message: 'validUntilMs must be greater than validFromMs',\n path: ['validUntilMs'],\n },\n );\nexport type PassArtifact = z.infer<typeof PassArtifactSchema>;\n\n// --- identity ---\n// Identity attestation. `claimValueHash` is the SHA-256 of the underlying\n// value so the artifact can be shared without leaking PII.\nexport const IdentityArtifactSchema = z.object({\n attestationId: ShortId,\n subjectId: ShortId,\n claimType: z.enum([\n 'phone_verified',\n 'email_verified',\n 'bvn_verified',\n 'kyc_tier',\n 'age_band',\n ]),\n claimValueHash: HexString(32),\n attestedAtMs: PositiveInt,\n});\nexport type IdentityArtifact = z.infer<typeof IdentityArtifactSchema>;\n\nexport const ARTIFACT_BODY_SCHEMAS = {\n [ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION]:\n OfflinePaymentAuthorizationArtifactSchema,\n [ARTIFACT_TYPES.RECEIPT]: ReceiptArtifactSchema,\n [ARTIFACT_TYPES.NQR_PAYMENT_REQUEST]: NqrPaymentRequestArtifactSchema,\n [ARTIFACT_TYPES.PAYMENT_INTENT]: PaymentIntentArtifactSchema,\n [ARTIFACT_TYPES.OFFLINE_CLAIM]: OfflineClaimArtifactSchema,\n [ARTIFACT_TYPES.SETTLEMENT_RECORD]: SettlementRecordArtifactSchema,\n [ARTIFACT_TYPES.REVERSAL_RECORD]: ReversalRecordArtifactSchema,\n [ARTIFACT_TYPES.LEDGER_JOURNAL_ENTRY]: LedgerJournalEntryArtifactSchema,\n [ARTIFACT_TYPES.STATEMENT]: StatementArtifactSchema,\n [ARTIFACT_TYPES.PASS]: PassArtifactSchema,\n [ARTIFACT_TYPES.IDENTITY]: IdentityArtifactSchema,\n} as const;\n\n/** Artifact types whose body schema is fully specified and safe to dispatch. */\nexport const HARDENED_ARTIFACT_TYPES = new Set<ArtifactType>([\n ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION,\n ARTIFACT_TYPES.RECEIPT,\n ARTIFACT_TYPES.NQR_PAYMENT_REQUEST,\n ARTIFACT_TYPES.PAYMENT_INTENT,\n ARTIFACT_TYPES.OFFLINE_CLAIM,\n ARTIFACT_TYPES.SETTLEMENT_RECORD,\n ARTIFACT_TYPES.REVERSAL_RECORD,\n ARTIFACT_TYPES.LEDGER_JOURNAL_ENTRY,\n ARTIFACT_TYPES.STATEMENT,\n ARTIFACT_TYPES.PASS,\n ARTIFACT_TYPES.IDENTITY,\n]);\n\nexport function isKnownArtifactType(t: string): t is ArtifactType {\n return (Object.values(ARTIFACT_TYPES) as string[]).includes(t);\n}\n\nexport function isHardenedArtifactType(t: string): t is ArtifactType {\n return HARDENED_ARTIFACT_TYPES.has(t as ArtifactType);\n}\n","import { z } from 'zod';\nimport {\n decodeArtifactUri,\n FlurArtifactError,\n type ArtifactBody,\n type DecodedArtifactUri,\n type SignedArtifact,\n type VerifyArtifactOptions,\n buildArtifactBody,\n signArtifact,\n encodeArtifactUri,\n verifyArtifactSignature,\n} from './envelope.js';\nimport {\n ARTIFACT_BODY_SCHEMAS,\n ARTIFACT_TYPES,\n isHardenedArtifactType,\n isKnownArtifactType,\n type ArtifactType,\n type OfflinePaymentAuthorizationArtifact,\n type ReceiptArtifact,\n} from './types.js';\n\n/**\n * Build, sign and encode a typed artifact into a flur://v1/... URI.\n *\n * - Validates the body against the registered Zod schema for `type`.\n * - Refuses unknown artifact types.\n * - Refuses stub types (those without a hardened schema) to avoid shipping\n * unverifiable payloads.\n */\nexport function createArtifactUri<T>(input: {\n type: ArtifactType;\n issuer: string;\n keyId: string;\n privateKey: Uint8Array;\n data: T;\n nonce: string;\n issuedAtSeconds?: number;\n expiresAtSeconds?: number;\n}): { uri: string; signed: SignedArtifact<T> } {\n if (!isKnownArtifactType(input.type)) {\n throw new FlurArtifactError(\n `Unknown artifact type: ${input.type}`,\n 'INVALID_TYPE',\n );\n }\n if (!isHardenedArtifactType(input.type)) {\n throw new FlurArtifactError(\n `Artifact type ${input.type} is not yet hardened for emission`,\n 'INVALID_TYPE',\n );\n }\n const schema = ARTIFACT_BODY_SCHEMAS[input.type] as unknown as z.ZodType<T>;\n const parsedData = schema.parse(input.data);\n\n const body = buildArtifactBody({\n type: input.type,\n issuer: input.issuer,\n keyId: input.keyId,\n data: parsedData,\n nonce: input.nonce,\n issuedAtSeconds: input.issuedAtSeconds,\n expiresAtSeconds: input.expiresAtSeconds,\n });\n const signed = signArtifact(body, input.privateKey);\n return { uri: encodeArtifactUri(signed), signed };\n}\n\nexport type VerifiedArtifact<T = unknown> = {\n type: ArtifactType;\n body: ArtifactBody<T>;\n sig: string;\n decoded: DecodedArtifactUri;\n};\n\n/**\n * Decode and verify a flur://v1/... URI.\n *\n * - Parses the URI and envelope header.\n * - Validates the body against the registered Zod schema.\n * - Verifies the Ed25519 signature against the supplied public key.\n * - Enforces expiry unless `options.enforceExpiry === false`.\n *\n * The caller is responsible for resolving the public key from (issuer, kid)\n * against the backend device-key registry, and for enforcing nonce uniqueness\n * via the artifact_nonces store.\n */\nexport function verifyArtifactUri<T = unknown>(\n uri: string,\n publicKey: Uint8Array,\n options: VerifyArtifactOptions = {},\n): VerifiedArtifact<T> {\n const decoded = decodeArtifactUri(uri);\n\n if (!isKnownArtifactType(decoded.type)) {\n throw new FlurArtifactError(\n `Unknown artifact type: ${decoded.type}`,\n 'INVALID_TYPE',\n );\n }\n if (!isHardenedArtifactType(decoded.type)) {\n throw new FlurArtifactError(\n `Artifact type ${decoded.type} is not yet hardened for verification`,\n 'INVALID_TYPE',\n );\n }\n\n const schema = ARTIFACT_BODY_SCHEMAS[decoded.type as ArtifactType];\n const dataParsed = schema.safeParse(decoded.body.data);\n if (!dataParsed.success) {\n throw new FlurArtifactError(\n `Artifact body invalid: ${dataParsed.error.message}`,\n 'INVALID_BODY',\n );\n }\n\n const ok = verifyArtifactSignature(decoded, publicKey, options);\n if (!ok) {\n throw new FlurArtifactError(\n 'Artifact signature verification failed',\n 'INVALID_SIGNATURE',\n );\n }\n\n return {\n type: decoded.type as ArtifactType,\n body: decoded.body as ArtifactBody<T>,\n sig: decoded.sig,\n decoded,\n };\n}\n\n// Convenience helpers that pin the artifact-type generic for the two\n// hardened artifacts. Useful for app code that wants compile-time guarantees\n// without repeating the schema reference.\n\nexport function createReceiptArtifactUri(input: {\n issuer: string;\n keyId: string;\n privateKey: Uint8Array;\n data: ReceiptArtifact;\n nonce: string;\n issuedAtSeconds?: number;\n expiresAtSeconds?: number;\n}) {\n return createArtifactUri<ReceiptArtifact>({\n ...input,\n type: ARTIFACT_TYPES.RECEIPT,\n });\n}\n\nexport function createOfflinePaymentAuthorizationArtifactUri(input: {\n issuer: string;\n keyId: string;\n privateKey: Uint8Array;\n data: OfflinePaymentAuthorizationArtifact;\n nonce: string;\n issuedAtSeconds?: number;\n expiresAtSeconds?: number;\n}) {\n return createArtifactUri<OfflinePaymentAuthorizationArtifact>({\n ...input,\n type: ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION,\n });\n}\n"],"mappings":"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","names":["z","z","z","candidate","z","z","CurrencySchema","init","init","z","z","z","z","z","z","bytesToHex","sha256","bytesToHex","init","z","sha256","hmac","bytesToHex","z","sha256Hex","bytesToHex","sha256","hmac","defaultNonce","init","z","HexString","z","z","HexSig","z","z","HexString","z","init","init","z","z","init","z","z","init","z","z","init","z","z","z","HexString","z","Currency"]}
1
+ {"version":3,"sources":["../src/client.ts","../src/contracts.ts","../src/errors.ts","../src/primitives.ts","../src/collections/client.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/partner/client.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/me-offline/client.ts","../src/me-offline/signer.ts","../src/partner-funding/client.ts","../src/artifacts/envelope.ts","../src/artifacts/types.ts","../src/artifacts/codec.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';\nimport {\n CollectionPaymentResultSchema,\n PayCollectionInputSchema,\n PublicCollectionIntentSchema,\n type CollectionPaymentResult,\n type PayCollectionInput as CollectionPayInput,\n type PublicCollectionIntent,\n} from './collections/index.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 userId: string;\n nuban: string | null;\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 ResolveCollectionOptions = AuthorizedOptions;\n\nexport type PayCollectionOptions = AuthorizedOptions & {\n idempotencyKey?: string;\n};\n\nexport type ResolveCollectionResponse = PublicCollectionIntent;\nexport type PayCollectionResponse = CollectionPaymentResult;\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 resolveCollection(\n reference: string,\n options: ResolveCollectionOptions,\n ): Promise<ResolveCollectionResponse> {\n return this.requestJson(\n `/v1/collections/resolve/${encodeURIComponent(reference)}`,\n {\n method: 'GET',\n headers: {\n authorization: `Bearer ${options.accessToken}`,\n },\n },\n undefined,\n PublicCollectionIntentSchema,\n );\n }\n\n async payCollection(\n input: CollectionPayInput,\n options: PayCollectionOptions,\n ): Promise<PayCollectionResponse> {\n const idempotencyKey =\n input.idempotencyKey ?? options.idempotencyKey ?? getSecureRandomUuid();\n return this.requestJson(\n '/v1/collections/pay',\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${options.accessToken}`,\n 'x-idempotency-key': idempotencyKey,\n },\n },\n PayCollectionInputSchema,\n CollectionPaymentResultSchema,\n { ...input, idempotencyKey },\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 /** Authenticated user's stable internal id. */\n userId: UuidSchema,\n /**\n * 10-digit Nigeria Uniform Bank Account Number (NUBAN) allocated by the\n * bank partner. `null` when the user has no partner-allocated account yet.\n */\n nuban: z\n .string()\n .regex(/^[0-9]{10}$/)\n .nullable(),\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","import { z } from 'zod';\nimport { FlurApiError } from '../errors.js';\n\nexport const MERCHANT_PROFILE_STATUSES = [\n 'pending',\n 'active',\n 'suspended',\n 'closed',\n] as const;\nexport const SETTLEMENT_SCHEDULES = ['manual', 'daily', 't1'] as const;\nexport const COLLECTION_INTENT_STATUSES = [\n 'created',\n 'pending',\n 'paid',\n 'expired',\n 'cancelled',\n 'failed',\n 'reversed',\n] as const;\nexport const COLLECTION_PAYMENT_STATUSES = [\n 'pending',\n 'paid',\n 'failed',\n 'reversed',\n] as const;\nexport const MERCHANT_PAYOUT_STATUSES = [\n 'requested',\n 'processing',\n 'paid',\n 'failed',\n 'cancelled',\n] as const;\n\nconst MoneyKoboSchema = z\n .number()\n .int()\n .positive()\n .max(Number.MAX_SAFE_INTEGER);\nconst MetadataSchema = z.record(\n z.union([z.string(), z.number(), z.boolean(), z.null()]),\n);\nconst CurrencySchema = z\n .string()\n .trim()\n .length(3)\n .transform((value) => value.toUpperCase());\nconst ReferenceSchema = z\n .string()\n .trim()\n .min(6)\n .max(128)\n .regex(/^[A-Za-z0-9._:-]+$/);\n\nexport const MerchantProfileSchema = z.object({\n accountId: z.string().uuid(),\n legalName: z.string(),\n tradingName: z.string(),\n merchantCategoryCode: z.string().regex(/^\\d{4}$/),\n nqrMerchantId: z.string(),\n settlementBankCode: z.string(),\n settlementAccountNumber: z.string(),\n settlementAccountName: z.string(),\n settlementSchedule: z.enum(SETTLEMENT_SCHEDULES),\n status: z.enum(MERCHANT_PROFILE_STATUSES),\n offlineEnabled: z.boolean(),\n perTxLimitKobo: MoneyKoboSchema,\n dailyLimitKobo: MoneyKoboSchema,\n metadata: MetadataSchema,\n createdAtMs: z.number().int().nonnegative(),\n updatedAtMs: z.number().int().nonnegative(),\n});\nexport type MerchantProfile = z.infer<typeof MerchantProfileSchema>;\n\nexport const UpsertMerchantProfileInputSchema = z.object({\n legalName: z.string().trim().min(1).max(200),\n tradingName: z.string().trim().min(1).max(25),\n merchantCategoryCode: z\n .string()\n .trim()\n .regex(/^\\d{4}$/),\n nqrMerchantId: z.string().trim().min(3).max(64),\n settlementBankCode: z.string().trim().min(2).max(16),\n settlementAccountNumber: z.string().trim().min(5).max(32),\n settlementAccountName: z.string().trim().min(1).max(200),\n settlementSchedule: z.enum(SETTLEMENT_SCHEDULES).optional(),\n status: z.enum(MERCHANT_PROFILE_STATUSES).optional(),\n offlineEnabled: z.boolean().optional(),\n perTxLimitKobo: MoneyKoboSchema.optional(),\n dailyLimitKobo: MoneyKoboSchema.optional(),\n metadata: MetadataSchema.optional(),\n});\nexport type UpsertMerchantProfileInput = z.infer<\n typeof UpsertMerchantProfileInputSchema\n>;\n\nexport const CollectionIntentSchema = z.object({\n intentId: z.string().uuid(),\n accountId: z.string().uuid(),\n terminalId: z.string().uuid().nullable(),\n reference: z.string(),\n amountKobo: z.number().int().positive().nullable(),\n currency: z.string().length(3),\n status: z.enum(COLLECTION_INTENT_STATUSES),\n description: z.string().nullable(),\n nqrPayload: z.string(),\n provider: z.string(),\n providerReference: z.string().nullable(),\n metadata: MetadataSchema,\n expiresAtMs: z.number().int().nonnegative().nullable(),\n paidAtMs: z.number().int().nonnegative().nullable(),\n createdAtMs: z.number().int().nonnegative(),\n updatedAtMs: z.number().int().nonnegative(),\n});\nexport type CollectionIntent = z.infer<typeof CollectionIntentSchema>;\n\nexport const CreateCollectionIntentInputSchema = z.object({\n reference: ReferenceSchema.optional(),\n amountKobo: MoneyKoboSchema.optional(),\n currency: CurrencySchema.optional(),\n terminalId: z.string().uuid().optional(),\n terminalLabel: z.string().trim().min(1).max(25).optional(),\n merchantCity: z.string().trim().min(1).max(15).optional(),\n description: z.string().trim().min(1).max(280).optional(),\n expiresAtMs: z.number().int().positive().optional(),\n provider: z.string().trim().min(1).max(40).optional(),\n metadata: MetadataSchema.optional(),\n});\nexport type CreateCollectionIntentInput = z.infer<\n typeof CreateCollectionIntentInputSchema\n>;\n\nexport const PublicCollectionIntentSchema = z.object({\n intentId: z.string().uuid(),\n reference: z.string(),\n amountKobo: z.number().int().positive().nullable(),\n currency: z.string().length(3),\n status: z.enum(COLLECTION_INTENT_STATUSES),\n merchantAccountId: z.string().uuid(),\n merchantName: z.string(),\n merchantCategoryCode: z.string(),\n description: z.string().nullable(),\n expiresAtMs: z.number().int().nonnegative().nullable(),\n});\nexport type PublicCollectionIntent = z.infer<\n typeof PublicCollectionIntentSchema\n>;\n\nexport const PayCollectionInputSchema = z.object({\n reference: ReferenceSchema,\n amountKobo: MoneyKoboSchema.optional(),\n currency: CurrencySchema.optional(),\n idempotencyKey: z.string().trim().min(8).max(160).optional(),\n});\nexport type PayCollectionInput = z.infer<typeof PayCollectionInputSchema>;\n\nexport const CollectionPaymentSchema = z.object({\n paymentId: z.string().uuid(),\n intentId: z.string().uuid(),\n accountId: z.string().uuid(),\n payerUserId: z.string().uuid().nullable(),\n merchantOwnerUserId: z.string().uuid(),\n amountKobo: MoneyKoboSchema,\n currency: z.string().length(3),\n status: z.enum(COLLECTION_PAYMENT_STATUSES),\n provider: z.string(),\n providerReference: z.string().nullable(),\n idempotencyKey: z.string().nullable(),\n ledgerRef: z.string(),\n failureCode: z.string().nullable(),\n failureMessage: z.string().nullable(),\n paidAtMs: z.number().int().nonnegative().nullable(),\n createdAtMs: z.number().int().nonnegative(),\n updatedAtMs: z.number().int().nonnegative(),\n});\nexport type CollectionPayment = z.infer<typeof CollectionPaymentSchema>;\n\nexport const CollectionPaymentResultSchema = z.object({\n payment: CollectionPaymentSchema,\n intent: CollectionIntentSchema,\n receipt: z.unknown().optional(),\n replayed: z.boolean(),\n});\nexport type CollectionPaymentResult = z.infer<\n typeof CollectionPaymentResultSchema\n>;\n\nexport const CollectionReportSummarySchema = z.object({\n accountId: z.string().uuid(),\n fromMs: z.number().int().nonnegative(),\n toMs: z.number().int().nonnegative(),\n currency: z.string().length(3),\n paidCount: z.number().int().nonnegative(),\n paidAmountKobo: z.number().int().nonnegative(),\n pendingCount: z.number().int().nonnegative(),\n failedCount: z.number().int().nonnegative(),\n reversedCount: z.number().int().nonnegative(),\n availableBalanceKobo: z.number().int().nonnegative(),\n});\nexport type CollectionReportSummary = z.infer<\n typeof CollectionReportSummarySchema\n>;\n\nexport const CollectionStatementSchema = z.object({\n accountId: z.string().uuid(),\n year: z.number().int(),\n month: z.number().int().min(1).max(12),\n currency: z.string().length(3),\n totalPaidKobo: z.number().int().nonnegative(),\n items: z.array(CollectionPaymentSchema),\n});\nexport type CollectionStatement = z.infer<typeof CollectionStatementSchema>;\n\nexport const CreatePayoutInputSchema = z.object({\n amountKobo: MoneyKoboSchema,\n currency: CurrencySchema.optional(),\n idempotencyKey: z.string().trim().min(8).max(160),\n});\nexport type CreatePayoutInput = z.infer<typeof CreatePayoutInputSchema>;\n\nexport const MerchantPayoutSchema = z.object({\n payoutId: z.string().uuid(),\n accountId: z.string().uuid(),\n amountKobo: MoneyKoboSchema,\n currency: z.string().length(3),\n status: z.enum(MERCHANT_PAYOUT_STATUSES),\n idempotencyKey: z.string().nullable(),\n ledgerRef: z.string(),\n providerReference: z.string().nullable(),\n requestedByUserId: z.string().uuid().nullable(),\n failureCode: z.string().nullable(),\n failureMessage: z.string().nullable(),\n createdAtMs: z.number().int().nonnegative(),\n updatedAtMs: z.number().int().nonnegative(),\n});\nexport type MerchantPayout = z.infer<typeof MerchantPayoutSchema>;\n\nexport const ProviderEventInputSchema = z.object({\n provider: z.string().trim().min(1).max(80),\n eventId: z.string().trim().min(1).max(160),\n eventType: z.string().trim().min(1).max(120),\n payload: z.record(z.unknown()).optional(),\n});\nexport type ProviderEventInput = z.infer<typeof ProviderEventInputSchema>;\n\nexport const ProviderEventRecordSchema = z.object({\n id: z.string().uuid(),\n provider: z.string(),\n eventId: z.string(),\n eventType: z.string(),\n signatureVerified: z.boolean(),\n receivedAtMs: z.number().int().nonnegative(),\n processedAtMs: z.number().int().nonnegative().nullable(),\n});\nexport type ProviderEventRecord = z.infer<typeof ProviderEventRecordSchema>;\n\nexport type CollectionsClientOptions = {\n baseUrl: string;\n fetchImpl?: typeof fetch;\n};\n\nexport type CollectionsClient = {\n upsertMerchantProfile: (\n accountId: string,\n input: UpsertMerchantProfileInput,\n ) => Promise<MerchantProfile>;\n getMerchantProfile: (accountId: string) => Promise<MerchantProfile>;\n createIntent: (\n input: CreateCollectionIntentInput,\n ) => Promise<CollectionIntent>;\n getIntent: (intentId: string) => Promise<CollectionIntent>;\n resolveIntent: (reference: string) => Promise<PublicCollectionIntent>;\n pay: (input: PayCollectionInput) => Promise<CollectionPaymentResult>;\n reportSummary: (input: {\n fromMs: number;\n toMs: number;\n currency?: string;\n }) => Promise<CollectionReportSummary>;\n monthlyStatement: (input: {\n year: number;\n month: number;\n currency?: string;\n }) => Promise<CollectionStatement>;\n createPayout: (input: CreatePayoutInput) => Promise<MerchantPayout>;\n getPayout: (payoutId: string) => Promise<MerchantPayout>;\n recordProviderEvent: (\n input: ProviderEventInput,\n ) => Promise<ProviderEventRecord>;\n};\n\nexport type PartnerCollectionsClient = Pick<\n CollectionsClient,\n | 'createIntent'\n | 'getIntent'\n | 'reportSummary'\n | 'monthlyStatement'\n | 'createPayout'\n | 'getPayout'\n | 'recordProviderEvent'\n>;\n\nexport type ConsumerCollectionsClient = Pick<\n CollectionsClient,\n 'resolveIntent' | 'pay'\n>;\n\nexport function createCollectionsClient(\n opts: CollectionsClientOptions,\n): CollectionsClient {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\n 'createCollectionsClient: 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: { accept: 'application/json' },\n };\n if (body !== undefined) {\n init.body = JSON.stringify(body);\n init.headers = { ...init.headers, 'content-type': 'application/json' };\n }\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 raw = text;\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 return {\n upsertMerchantProfile: (accountId, input) =>\n call(\n 'PUT',\n `/v1/accounts/${encodeURIComponent(accountId)}/merchant-profile`,\n UpsertMerchantProfileInputSchema.parse(input),\n (raw) => MerchantProfileSchema.parse(raw),\n ),\n getMerchantProfile: (accountId) =>\n call(\n 'GET',\n `/v1/accounts/${encodeURIComponent(accountId)}/merchant-profile`,\n undefined,\n (raw) => MerchantProfileSchema.parse(raw),\n ),\n createIntent: (input) =>\n call(\n 'POST',\n '/v1/collections/intents',\n CreateCollectionIntentInputSchema.parse(input),\n (raw) => CollectionIntentSchema.parse(raw),\n ),\n getIntent: (intentId) =>\n call(\n 'GET',\n `/v1/collections/intents/${encodeURIComponent(intentId)}`,\n undefined,\n (raw) => CollectionIntentSchema.parse(raw),\n ),\n resolveIntent: (reference) =>\n call(\n 'GET',\n `/v1/collections/resolve/${encodeURIComponent(reference)}`,\n undefined,\n (raw) => PublicCollectionIntentSchema.parse(raw),\n ),\n pay: (input) =>\n call(\n 'POST',\n '/v1/collections/pay',\n PayCollectionInputSchema.parse(input),\n (raw) => CollectionPaymentResultSchema.parse(raw),\n ),\n reportSummary: (input) => {\n const qs = new URLSearchParams({\n fromMs: String(input.fromMs),\n toMs: String(input.toMs),\n });\n if (input.currency) qs.set('currency', input.currency);\n return call(\n 'GET',\n `/v1/collections/reports/summary?${qs.toString()}`,\n undefined,\n (raw) => CollectionReportSummarySchema.parse(raw),\n );\n },\n monthlyStatement: (input) => {\n const qs = new URLSearchParams({\n year: String(input.year),\n month: String(input.month),\n });\n if (input.currency) qs.set('currency', input.currency);\n return call(\n 'GET',\n `/v1/collections/statements/monthly?${qs.toString()}`,\n undefined,\n (raw) => CollectionStatementSchema.parse(raw),\n );\n },\n createPayout: (input) =>\n call(\n 'POST',\n '/v1/collections/payouts',\n CreatePayoutInputSchema.parse(input),\n (raw) => MerchantPayoutSchema.parse(raw),\n ),\n getPayout: (payoutId) =>\n call(\n 'GET',\n `/v1/collections/payouts/${encodeURIComponent(payoutId)}`,\n undefined,\n (raw) => MerchantPayoutSchema.parse(raw),\n ),\n recordProviderEvent: (input) =>\n call(\n 'POST',\n '/v1/collections/provider-events',\n ProviderEventInputSchema.parse(input),\n (raw) => ProviderEventRecordSchema.parse(raw),\n ),\n };\n}\n\nexport function createPartnerCollectionsClient(\n opts: CollectionsClientOptions,\n): PartnerCollectionsClient {\n const client = createCollectionsClient(opts);\n return {\n createIntent: client.createIntent,\n getIntent: client.getIntent,\n reportSummary: client.reportSummary,\n monthlyStatement: client.monthlyStatement,\n createPayout: client.createPayout,\n getPayout: client.getPayout,\n recordProviderEvent: client.recordProviderEvent,\n };\n}\n\nexport function createConsumerCollectionsClient(\n opts: CollectionsClientOptions,\n): ConsumerCollectionsClient {\n const client = createCollectionsClient(opts);\n return {\n resolveIntent: client.resolveIntent,\n pay: client.pay,\n };\n}\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 { 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 'collections:write',\n 'collections:read',\n 'collections:pay',\n 'collections:webhook',\n 'reports:read',\n 'payouts:write',\n 'payouts:read',\n 'partner:funding:write',\n 'partner:payout:write',\n 'partner:reconciliation: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 /** Optional scope claim forwarded as X-Flur-Scope; backend credentials remain authoritative. */\n scope?: readonly PartnerScope[];\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 const scopeHeader = normalizeScopeHeader(opts.scope);\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 (scopeHeader) headers['x-flur-scope'] = scopeHeader;\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\nfunction normalizeScopeHeader(\n scope: readonly PartnerScope[] | undefined,\n): string | undefined {\n if (!scope || scope.length === 0) return undefined;\n const unique = Array.from(new Set(scope));\n for (const item of unique) {\n if (!(PARTNER_SCOPES as readonly string[]).includes(item)) {\n throw new Error(`unsupported partner scope: ${item}`);\n }\n }\n return unique.join(' ');\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","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 { createFlurPartnerClient } from '../partner/index.js';\nimport type { PartnerScope } from '../partner/index.js';\nimport { createPassesClient, type PassesClient } from '../passes/index.js';\nimport {\n createReceiptsClient,\n type ReceiptsClient,\n} from '../receipts/index.js';\nimport {\n createPartnerCollectionsClient,\n type PartnerCollectionsClient,\n} from '../collections/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 credentials remain authoritative. */\n scope?: readonly PartnerScope[];\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 /** Collections: merchant NQR intents, reports, statements, payouts. */\n collections: PartnerCollectionsClient;\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 partner = createFlurPartnerClient({\n baseUrl: opts.baseUrl,\n keyId: opts.apiKey,\n secret: opts.apiSecret,\n fetchImpl: opts.fetchImpl,\n scope: opts.scope,\n });\n const signedFetch = partner.fetch;\n const baseUrl = opts.baseUrl.replace(/\\/$/, '');\n\n function subscribeToPayments(s: SubscribeOptions) {\n let cancelled = false;\n\n queueMicrotask(() => {\n if (cancelled) return;\n s.onError?.(\n new Error(\n 'cash.subscribeToPayments is not available on this backend release; use collections reports or provider webhooks for payment status.',\n ),\n );\n });\n\n return () => {\n cancelled = true;\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 const collections = createPartnerCollectionsClient({\n baseUrl,\n fetchImpl: signedFetch,\n });\n\n return {\n // top-level back-compat surface\n generateStaticQR,\n generateDynamicQR,\n parseQR,\n subscribeToPayments,\n // namespaces\n cash,\n collections,\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","/**\n * Consumer-side Offline Collect SDK client.\n *\n * Wraps the backend `/v1/me/offline/*` routes (session-bearer auth ONLY —\n * NOT partner HMAC). These power the payer authorization side of Flur Offline Collect:\n * - register/list/revoke device signing keys\n * - provision / refresh / release a hold-backed offline allowance\n * - read offline status (current hold + active OAC)\n * - submit a signed offline collection 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);\nconst Base64Std = z.string().regex(/^[A-Za-z0-9+/]+={0,2}$/);\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 AttestationSecurityLevelSchema = z.enum([\n 'STRONGBOX',\n 'TEE',\n 'SECURE_ENCLAVE',\n 'SOFTWARE',\n]);\nexport type AttestationSecurityLevel = z.infer<\n typeof AttestationSecurityLevelSchema\n>;\n\nexport const DeviceKeyAlgSchema = z.enum(['ed25519', 'p256']);\nexport type DeviceKeyAlg = z.infer<typeof DeviceKeyAlgSchema>;\n\nexport const RegisterDeviceKeyP256InputSchema = z.object({\n deviceId: z.string().min(1).max(128),\n /** P-256 SubjectPublicKeyInfo DER, base64. */\n publicKeySpkiB64: Base64Std.min(64).max(4096),\n /** Base64 of the server-issued enrollment challenge string. */\n challengeB64: Base64Std.min(8).max(1024),\n /** iOS App Attest payload or Android X.509 Key Attestation chain. */\n attestationChainB64: z.array(Base64Std.min(16).max(16_384)).min(1).max(16),\n securityLevel: AttestationSecurityLevelSchema,\n});\nexport type RegisterDeviceKeyP256Input = z.infer<\n typeof RegisterDeviceKeyP256InputSchema\n>;\n\nexport const P256EnrollmentChallengeInputSchema = z.object({\n deviceId: z.string().min(1).max(128),\n});\nexport type P256EnrollmentChallengeInput = z.infer<\n typeof P256EnrollmentChallengeInputSchema\n>;\n\nexport const P256EnrollmentChallengeResultSchema = z.object({\n challenge: z.string().min(16),\n expiresAtMs: z.number().int().positive(),\n});\nexport type P256EnrollmentChallengeResult = z.infer<\n typeof P256EnrollmentChallengeResultSchema\n>;\n\nexport const DeviceKeyRecordSchema = z.object({\n id: z.string().uuid(),\n userId: z.string().uuid(),\n deviceId: z.string(),\n alg: DeviceKeyAlgSchema.default('ed25519'),\n publicKeyHex: Hex64.nullable().default(null),\n publicKeySpkiB64: Base64Std.nullable().default(null),\n securityLevel: AttestationSecurityLevelSchema.nullable().default(null),\n hardwareBacked: z.boolean().default(false),\n attestedAtMs: z.number().int().nonnegative().nullable().default(null),\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//\n// OAC v2 is polymorphic in the bound device key — see backend types.ts.\n\nexport const ConsumerOACSchema = z\n .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 alg: z.enum(['ed25519', 'p256']).optional(),\n devicePubkeyHex: Hex64.optional(),\n devicePubkeySpkiB64: Base64Std.min(64).max(4096).optional(),\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 })\n .refine(\n (o) => {\n const alg = o.alg ?? 'ed25519';\n if (alg === 'ed25519') {\n return Boolean(o.devicePubkeyHex) && !o.devicePubkeySpkiB64;\n }\n return Boolean(o.devicePubkeySpkiB64) && !o.devicePubkeyHex;\n },\n { message: 'OAC device pubkey shape must match alg' },\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>;\nexport const ProvisionOfflineAllowanceInputSchema = EnableOfflineInputSchema;\nexport type ProvisionOfflineAllowanceInput = EnableOfflineInput;\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>;\nexport const ProvisionOfflineAllowanceResultSchema = EnableOfflineResultSchema;\nexport type ProvisionOfflineAllowanceResult = EnableOfflineResult;\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//\n// V2 polymorphic shape. The wire schema accepts BOTH algorithms via an `alg`\n// discriminator:\n//\n// alg='ed25519' (default — backward compatible with V1 clients):\n// payerPubkeyHex (32-byte hex) + payerSignature (64-byte hex)\n// Verified against the V1 canonical claim payload domain\n// `flur:consumer-offline:v1:claim`.\n//\n// alg='p256' (hardware-backed, produced by `flur-secure-signer`):\n// payerPubkeySpkiB64 (SubjectPublicKeyInfo DER, base64)\n// payerSignatureDerB64 (ASN.1 DER ECDSA signature, base64)\n// Verified against the V2 canonical claim bytes\n// `flur:consumer-offline:v2:claim` via `verifyClaimSignature` from\n// `@nokinc-flur/sdk` (single source of truth shared with the backend).\n//\n// Both shapes share the same identity/amount/timing fields so the settlement\n// state machine is identical — only the verification path branches.\n\nconst ClaimAlgSchema = z.enum(['ed25519', 'p256']);\n\nexport const ConsumerPaymentClaimSchema = z\n .object({\n /** Algorithm discriminator. Omit / 'ed25519' for V1 clients. */\n alg: ClaimAlgSchema.optional(),\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\n // ed25519 path\n payerPubkeyHex: Hex64.optional(),\n payerSignature: HexAny.optional(),\n payeePubkeyHex: Hex64.optional(),\n payeeSignature: HexAny.optional(),\n\n // p256 path\n payerPubkeySpkiB64: z.string().min(64).max(4096).optional(),\n payerSignatureDerB64: z.string().min(16).max(2048).optional(),\n payeePubkeySpkiB64: z.string().min(64).max(4096).optional(),\n payeeSignatureDerB64: z.string().min(16).max(2048).optional(),\n })\n .refine(\n (c) => {\n const alg = c.alg ?? 'ed25519';\n if (alg === 'ed25519') {\n return Boolean(c.payerPubkeyHex) && Boolean(c.payerSignature);\n }\n return Boolean(c.payerPubkeySpkiB64) && Boolean(c.payerSignatureDerB64);\n },\n {\n message:\n 'payer key/signature fields must match alg (ed25519: hex; p256: SPKI+DER b64)',\n },\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 issueP256EnrollmentChallenge: (\n input: P256EnrollmentChallengeInput,\n ) => Promise<P256EnrollmentChallengeResult>;\n registerDeviceKeyP256: (\n input: RegisterDeviceKeyP256Input,\n ) => Promise<DeviceKeyRecord>;\n listDeviceKeys: () => Promise<{ items: DeviceKeyRecord[] }>;\n revokeDeviceKey: (input: RevokeDeviceKeyInput) => Promise<void>;\n provisionAllowance: (\n input: ProvisionOfflineAllowanceInput,\n ) => Promise<ProvisionOfflineAllowanceResult>;\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 issueP256EnrollmentChallenge: (input) =>\n call(\n 'POST',\n '/v1/me/offline/keys/p256/challenge',\n P256EnrollmentChallengeInputSchema.parse(input),\n (raw) => P256EnrollmentChallengeResultSchema.parse(raw),\n ),\n registerDeviceKeyP256: (input) =>\n call(\n 'POST',\n '/v1/me/offline/keys/p256',\n RegisterDeviceKeyP256InputSchema.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 provisionAllowance: (input) =>\n call(\n 'POST',\n '/v1/me/offline/allowance',\n ProvisionOfflineAllowanceInputSchema.parse(input),\n (raw) => ProvisionOfflineAllowanceResultSchema.parse(raw),\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","/**\n * Offline-claim signer abstraction for Flur.\n *\n * Why this exists:\n * - Mobile clients sign payment claims with a hardware-backed P-256 key\n * (iOS Secure Enclave / Android Keystore StrongBox). Native modules\n * implement that custody, not this file.\n * - Server-side partners, test harnesses, and the historical Ed25519 path\n * need a *software* signer with the same surface so the SDK contract is\n * uniform.\n * - Both producers and verifiers (consumer mobile, partner backend, Flur\n * backend) must agree byte-for-byte on what gets signed. That's the job\n * of `canonicalClaimSigningPayload` / `canonicalClaimSigningBytes`.\n *\n * Wire format choices:\n * - Ed25519 (legacy v1): 32-byte public key hex, 64-byte signature hex.\n * - P-256 (v2, hardware-backed): SubjectPublicKeyInfo DER public key in\n * base64, ASN.1 DER ECDSA signature in base64. Same format the\n * Apple/Android native modules return.\n *\n * Domain separation:\n * - V2 payload binds `alg` and is tagged with `CLAIM_DOMAIN_V2`. A signature\n * over V2 bytes therefore can never be replayed against the V1 verifier\n * or vice versa. This is the cryptographic foundation of the alg-flag-day\n * migration plan.\n */\n\nimport { ed25519 } from '@noble/curves/ed25519';\nimport { p256 } from '@noble/curves/nist';\nimport { bytesToHex, hexToBytes } from '@noble/hashes/utils';\nimport { canonicalJSONBytes } from '../crypto/canonical.js';\n\n// ─────────────────────────── domain ───────────────────────────\n\n/**\n * V2 canonical claim domain. Must match the backend's V2 verifier exactly.\n * Bumped from `flur:consumer-offline:v1:claim` so a payer's V2 hardware\n * signature is non-replayable against a legacy V1 verifier and vice-versa.\n */\nexport const CLAIM_DOMAIN_V2 = 'flur:consumer-offline:v2:claim' as const;\n\n// ─────────────────────────── types ───────────────────────────\n\nexport type OfflineClaimAlgorithm = 'ed25519' | 'p256';\n\n/**\n * Inputs the SDK accepts to build canonical signing bytes.\n *\n * Optional fields default to `null` inside the canonical payload, so callers\n * that omit them still produce stable, deterministic bytes.\n */\nexport interface CanonicalClaimInput {\n alg: OfflineClaimAlgorithm;\n oacId: string;\n payerUserId: string;\n payeeUserId: string;\n payerDeviceId: string;\n payerNonce: string;\n payeeNonce: string;\n amountKobo: number;\n currency: string;\n occurredAtMs: number;\n completedAtMs?: number | null;\n contextId?: string | null;\n}\n\n/** Public key + signature pair from a signer. Encoding depends on `alg`. */\nexport interface SignerPublicKey {\n alg: OfflineClaimAlgorithm;\n /**\n * For `ed25519`: 32-byte raw key, lowercase hex (64 chars).\n * For `p256`: SubjectPublicKeyInfo DER, base64.\n */\n publicKey: string;\n}\n\nexport interface ClaimSignature {\n alg: OfflineClaimAlgorithm;\n /**\n * For `ed25519`: 64-byte raw signature, lowercase hex (128 chars).\n * For `p256`: ASN.1 DER ECDSA signature, base64.\n */\n signature: string;\n}\n\n/** Abstract signer interface. Software and native impls both honour this. */\nexport interface OfflineClaimSigner {\n readonly alg: OfflineClaimAlgorithm;\n getPublicKey(): Promise<SignerPublicKey>;\n sign(bytes: Uint8Array): Promise<ClaimSignature>;\n}\n\n// ─────────────────────────── canonical payload ───────────────────────────\n\n/**\n * The exact object that gets canonical-JSON-encoded and signed.\n *\n * Key ordering doesn't matter for the *output* because `canonicalJSONBytes`\n * sorts keys lexicographically — but the field SET and value normalization\n * must match the backend verifier byte-for-byte. Treat this function as the\n * cryptographic contract.\n */\nexport function canonicalClaimSigningPayload(claim: CanonicalClaimInput): {\n domain: typeof CLAIM_DOMAIN_V2;\n alg: OfflineClaimAlgorithm;\n oacId: string;\n payerUserId: string;\n payeeUserId: string;\n payerDeviceId: string;\n payerNonce: string;\n payeeNonce: string;\n amountKobo: number;\n currency: string;\n occurredAtMs: number;\n completedAtMs: number | null;\n contextId: string | null;\n} {\n return {\n domain: CLAIM_DOMAIN_V2,\n alg: claim.alg,\n oacId: claim.oacId,\n payerUserId: claim.payerUserId,\n payeeUserId: claim.payeeUserId,\n payerDeviceId: claim.payerDeviceId,\n payerNonce: claim.payerNonce,\n payeeNonce: claim.payeeNonce,\n amountKobo: claim.amountKobo,\n currency: claim.currency,\n occurredAtMs: claim.occurredAtMs,\n completedAtMs: claim.completedAtMs ?? null,\n contextId: claim.contextId ?? null,\n };\n}\n\n/** Bytes the signer must operate on. */\nexport function canonicalClaimSigningBytes(\n claim: CanonicalClaimInput,\n): Uint8Array {\n return canonicalJSONBytes(canonicalClaimSigningPayload(claim));\n}\n\n// ─────────────────────────── base64 ───────────────────────────\n//\n// Tiny base64 helpers that work in Node 18+ and all browsers without\n// pulling a new dep. We only need standard (not URL-safe) base64.\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(bytes).toString('base64');\n }\n let bin = '';\n for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i]!);\n // btoa is available in browsers and Node ≥ 16.\n return btoa(bin);\n}\n\nfunction base64ToBytes(b64: string): Uint8Array {\n if (typeof Buffer !== 'undefined') {\n return new Uint8Array(Buffer.from(b64, 'base64'));\n }\n const bin = atob(b64);\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n}\n\n// ─────────────────────────── P-256 SPKI helpers ───────────────────────────\n//\n// @noble/curves emits the raw X9.62 uncompressed point (0x04 || X || Y, 65\n// bytes). The backend ingests SubjectPublicKeyInfo DER (the same wrapper the\n// Android Keystore and iOS Secure Enclave native modules return). We wrap\n// and unwrap with the fixed P-256 SPKI header so the wire format is uniform\n// regardless of which signer produced it.\n\nconst P256_SPKI_HEADER = new Uint8Array([\n 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01,\n 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00,\n]);\n\nfunction p256PublicKeyToSpkiB64(rawUncompressed: Uint8Array): string {\n if (rawUncompressed.length !== 65 || rawUncompressed[0] !== 0x04) {\n throw new Error('p256: expected 65-byte uncompressed point');\n }\n const out = new Uint8Array(P256_SPKI_HEADER.length + rawUncompressed.length);\n out.set(P256_SPKI_HEADER, 0);\n out.set(rawUncompressed, P256_SPKI_HEADER.length);\n return bytesToBase64(out);\n}\n\nfunction p256SpkiB64ToPublicKey(spkiB64: string): Uint8Array {\n const spki = base64ToBytes(spkiB64);\n // Validate the header (cheap correctness check; full ASN.1 parse not needed\n // for a fixed key type).\n if (spki.length !== P256_SPKI_HEADER.length + 65) {\n throw new Error('p256: invalid SPKI length');\n }\n for (let i = 0; i < P256_SPKI_HEADER.length; i++) {\n if (spki[i] !== P256_SPKI_HEADER[i]) {\n throw new Error('p256: invalid SPKI header');\n }\n }\n return spki.slice(P256_SPKI_HEADER.length);\n}\n\n// ─────────────────────────── software signers ───────────────────────────\n\n/**\n * Legacy / test-only Ed25519 signer. NOT for production money on phones —\n * the on-device key is software and exfiltratable. Used by:\n * - the historical V1 backend path\n * - Node/server tests\n * - server-side partners that issue claims from their own backend\n */\nexport function createSoftwareEd25519Signer(\n privateKey: Uint8Array,\n): OfflineClaimSigner {\n const pub = ed25519.getPublicKey(privateKey);\n return {\n alg: 'ed25519',\n async getPublicKey() {\n return { alg: 'ed25519', publicKey: bytesToHex(pub) };\n },\n async sign(bytes: Uint8Array) {\n const sig = ed25519.sign(bytes, privateKey);\n return { alg: 'ed25519', signature: bytesToHex(sig) };\n },\n };\n}\n\n/**\n * Software P-256 signer. Useful for:\n * - test harnesses\n * - Node integrators that issue claims server-side (custodied wallets)\n * - simulators where Secure Enclave / StrongBox is unavailable\n *\n * The hardware-backed equivalent (mobile) implements the same interface\n * but defers key storage and signing to the OS secure element.\n */\nexport function createSoftwareP256Signer(\n privateKey: Uint8Array,\n): OfflineClaimSigner {\n // Uncompressed point: 0x04 || X(32) || Y(32) — matches what Apple/Android\n // raw public-key APIs emit before SPKI wrapping.\n const raw = p256.getPublicKey(privateKey, false);\n const spkiB64 = p256PublicKeyToSpkiB64(raw);\n\n return {\n alg: 'p256',\n async getPublicKey() {\n return { alg: 'p256', publicKey: spkiB64 };\n },\n async sign(bytes: Uint8Array) {\n // The backend (and the native modules) compute SHA-256 internally; for\n // wire interop we sign the SHA-256 hash of the canonical bytes here.\n // `prehash: true` keeps that pattern consistent across software and\n // hardware paths.\n const sig = p256.sign(bytes, privateKey, { prehash: true });\n // ECDSA DER encoding — the Apple/Android native signers also return\n // DER, so the wire format is identical regardless of producer.\n const der = sig.toBytes('der');\n return { alg: 'p256', signature: bytesToBase64(der) };\n },\n };\n}\n\n// ─────────────────────────── verification ───────────────────────────\n\nexport interface VerifyClaimSignatureInput {\n alg: OfflineClaimAlgorithm;\n bytes: Uint8Array;\n signature: string;\n publicKey: string;\n}\n\n/**\n * Verifier the backend, partners, and self-checks all share. Returns a plain\n * boolean — callers should treat `false` and thrown errors uniformly as\n * \"not authenticated\".\n */\nexport function verifyClaimSignature(\n input: VerifyClaimSignatureInput,\n): boolean {\n try {\n if (input.alg === 'ed25519') {\n return ed25519.verify(\n hexToBytes(input.signature),\n input.bytes,\n hexToBytes(input.publicKey),\n );\n }\n if (input.alg === 'p256') {\n const sigDer = base64ToBytes(input.signature);\n const pub = p256SpkiB64ToPublicKey(input.publicKey);\n return p256.verify(sigDer, input.bytes, pub, {\n prehash: true,\n format: 'der',\n });\n }\n return false;\n } catch {\n return false;\n }\n}\n","/**\n * Partner-funded wallet rails SDK.\n *\n * Provides two clients:\n * - `createPartnerFundingClient(partnerClient)` — uses partner HMAC for\n * the bank/merchant partner endpoints (funding webhook, payout events,\n * daily reconciliation). The caller MUST have minted credentials with\n * the appropriate scopes (`partner:funding:write`, `partner:payout:write`,\n * `partner:reconciliation:read`).\n * - `createConsumerWithdrawalsClient(opts)` — session-bearer auth for the\n * consumer endpoints (linked payout destinations, withdrawals).\n *\n * Schemas mirror `flur-backend/src/partner-funding/types.ts`. Money is\n * always represented in MINOR units (e.g. kobo for NGN). BIGINT-bearing\n * response fields are serialized as integer strings to avoid JS number\n * precision issues; reserve balances and imbalances may be signed.\n */\nimport { z } from 'zod';\nimport type { FlurPartnerClient } from '../partner/client.js';\nimport { FlurApiError } from '../errors.js';\n\n// ───────────────────────────── shared ─────────────────────────────\n\nconst MinorString = z.string().regex(/^-?\\d+$/);\nconst PositiveMinor = z.union([\n z.number().int().positive(),\n z.string().regex(/^[1-9]\\d{0,18}$/),\n]);\nconst Currency = z\n .string()\n .trim()\n .length(3)\n .transform((v) => v.toUpperCase());\nconst Metadata = z.record(z.unknown());\n\nexport const PARTNER_KINDS = ['bank', 'merchant'] as const;\nexport type PartnerKind = (typeof PARTNER_KINDS)[number];\n\nexport const CUSTODIAL_MODES = ['agent_of_bank', 'flur_virtual_pool'] as const;\nexport type CustodialMode = (typeof CUSTODIAL_MODES)[number];\n\nexport const PARTNER_PROFILE_STATUSES = [\n 'active',\n 'suspended',\n 'closed',\n] as const;\nexport type PartnerProfileStatus = (typeof PARTNER_PROFILE_STATUSES)[number];\n\nexport const PARTNER_FUNDING_DIRECTIONS = ['credit', 'debit'] as const;\nexport type PartnerFundingDirection =\n (typeof PARTNER_FUNDING_DIRECTIONS)[number];\n\nexport const PARTNER_FUNDING_STATUSES = [\n 'pending',\n 'posted',\n 'failed',\n] as const;\nexport type PartnerFundingStatus = (typeof PARTNER_FUNDING_STATUSES)[number];\n\nexport const PAYOUT_DESTINATION_STATUSES = [\n 'pending',\n 'verified',\n 'disabled',\n] as const;\nexport type PayoutDestinationStatus =\n (typeof PAYOUT_DESTINATION_STATUSES)[number];\n\nexport const WITHDRAWAL_STATES = [\n 'requested',\n 'submitted',\n 'processing',\n 'paid',\n 'failed',\n 'reversed',\n] as const;\nexport type WithdrawalState = (typeof WITHDRAWAL_STATES)[number];\n\n// ───────────────────────────── profile ─────────────────────────────\n\nexport const PartnerProfileSchema = z.object({\n partnerAccountId: z.string().uuid(),\n kind: z.enum(PARTNER_KINDS),\n custodialMode: z.enum(CUSTODIAL_MODES),\n displayName: z.string(),\n bankCode: z.string().nullable(),\n poolAccountNumber: z.string().nullable(),\n status: z.enum(PARTNER_PROFILE_STATUSES),\n metadata: Metadata,\n createdAtMs: z.number().int().nonnegative(),\n updatedAtMs: z.number().int().nonnegative(),\n});\nexport type PartnerProfile = z.infer<typeof PartnerProfileSchema>;\n\nexport const UpsertPartnerProfileInputSchema = z.object({\n kind: z.enum(PARTNER_KINDS),\n custodialMode: z.enum(CUSTODIAL_MODES),\n displayName: z.string().trim().min(1).max(200),\n bankCode: z.string().trim().min(1).max(64).optional(),\n poolAccountNumber: z.string().trim().min(1).max(64).optional(),\n metadata: Metadata.optional(),\n});\nexport type UpsertPartnerProfileInput = z.infer<\n typeof UpsertPartnerProfileInputSchema\n>;\n\n// ───────────────────────────── fundings ─────────────────────────────\n\nexport const PartnerFundingEventInputSchema = z.object({\n externalRef: z.string().trim().min(8).max(128),\n direction: z.enum(PARTNER_FUNDING_DIRECTIONS).optional(),\n userId: z.string().uuid().optional(),\n accountId: z.string().uuid().optional(),\n amountMinor: PositiveMinor,\n currency: Currency,\n fundingSource: z.string().trim().min(1).max(64).optional(),\n providerMetadata: Metadata.optional(),\n});\nexport type PartnerFundingEventInput = z.infer<\n typeof PartnerFundingEventInputSchema\n>;\n\nexport const PartnerFundingSchema = z.object({\n fundingId: z.string().uuid(),\n partnerId: z.string().uuid(),\n accountId: z.string().uuid(),\n userId: z.string().uuid().nullable(),\n direction: z.enum(PARTNER_FUNDING_DIRECTIONS),\n currency: z.string(),\n amountMinor: MinorString,\n externalRef: z.string(),\n status: z.enum(PARTNER_FUNDING_STATUSES),\n fundingSource: z.string(),\n ledgerRef: z.string(),\n providerMetadata: Metadata,\n createdAtMs: z.number().int().nonnegative(),\n updatedAtMs: z.number().int().nonnegative(),\n});\nexport type PartnerFunding = z.infer<typeof PartnerFundingSchema>;\n\nexport const IngestFundingResultSchema = z.object({\n funding: PartnerFundingSchema,\n replayed: z.boolean(),\n});\nexport type IngestFundingResult = z.infer<typeof IngestFundingResultSchema>;\n\n// ───────────────────────────── destinations ─────────────────────────────\n\nexport const PayoutDestinationSchema = z.object({\n destinationId: z.string().uuid(),\n accountId: z.string().uuid(),\n partnerId: z.string().uuid(),\n bankCode: z.string(),\n accountNumber: z.string(),\n accountName: z.string(),\n status: z.enum(PAYOUT_DESTINATION_STATUSES),\n verifiedAtMs: z.number().int().nonnegative().nullable(),\n metadata: Metadata,\n createdAtMs: z.number().int().nonnegative(),\n updatedAtMs: z.number().int().nonnegative(),\n});\nexport type PayoutDestination = z.infer<typeof PayoutDestinationSchema>;\n\nexport const CreatePayoutDestinationInputSchema = z.object({\n partnerId: z.string().uuid(),\n bankCode: z.string().trim().min(1).max(32),\n accountNumber: z.string().trim().min(4).max(64),\n accountName: z.string().trim().min(1).max(200),\n metadata: Metadata.optional(),\n});\nexport type CreatePayoutDestinationInput = z.infer<\n typeof CreatePayoutDestinationInputSchema\n>;\n\nexport const ListPayoutDestinationsResultSchema = z.object({\n items: z.array(PayoutDestinationSchema),\n});\nexport type ListPayoutDestinationsResult = z.infer<\n typeof ListPayoutDestinationsResultSchema\n>;\n\n// ───────────────────────────── withdrawals ─────────────────────────────\n\nexport const WithdrawalSchema = z.object({\n withdrawalId: z.string().uuid(),\n accountId: z.string().uuid(),\n userId: z.string().uuid(),\n partnerId: z.string().uuid(),\n destinationId: z.string().uuid(),\n currency: z.string(),\n amountMinor: MinorString,\n state: z.enum(WITHDRAWAL_STATES),\n idempotencyKey: z.string(),\n providerRef: z.string().nullable(),\n lastError: z.string().nullable(),\n ledgerRef: z.string(),\n reverseLedgerRef: z.string().nullable(),\n metadata: Metadata,\n createdAtMs: z.number().int().nonnegative(),\n updatedAtMs: z.number().int().nonnegative(),\n});\nexport type Withdrawal = z.infer<typeof WithdrawalSchema>;\n\nexport const CreateWithdrawalInputSchema = z.object({\n destinationId: z.string().uuid(),\n amountMinor: PositiveMinor,\n currency: Currency,\n idempotencyKey: z.string().trim().min(8).max(128),\n metadata: Metadata.optional(),\n});\nexport type CreateWithdrawalInput = z.infer<typeof CreateWithdrawalInputSchema>;\n\nexport const CreateWithdrawalResultSchema = z.object({\n withdrawal: WithdrawalSchema,\n replayed: z.boolean(),\n});\nexport type CreateWithdrawalResult = z.infer<\n typeof CreateWithdrawalResultSchema\n>;\n\n// ───────────────────────────── payout events ─────────────────────────────\n\nexport const PayoutEventInputSchema = z.object({\n externalRef: z.string().trim().min(8).max(128),\n withdrawalId: z.string().uuid().optional(),\n state: z.enum(['submitted', 'processing', 'paid', 'failed']),\n providerRef: z.string().trim().min(1).max(128).optional(),\n failureCode: z.string().trim().max(64).optional(),\n failureMessage: z.string().trim().max(512).optional(),\n providerMetadata: Metadata.optional(),\n});\nexport type PayoutEventInput = z.infer<typeof PayoutEventInputSchema>;\n\nexport const RecordPayoutEventResultSchema = z.object({\n withdrawal: WithdrawalSchema,\n replayed: z.boolean(),\n});\nexport type RecordPayoutEventResult = z.infer<\n typeof RecordPayoutEventResultSchema\n>;\n\n// ───────────────────────────── reconciliation ─────────────────────────────\n\nexport const ReconciliationReportSchema = z.object({\n partnerId: z.string().uuid(),\n currency: z.string(),\n fromMs: z.number().int().nonnegative(),\n toMs: z.number().int().nonnegative(),\n fundingsCreditMinor: MinorString,\n fundingsDebitMinor: MinorString,\n withdrawalsPaidMinor: MinorString,\n withdrawalsReversedMinor: MinorString,\n withdrawalsInFlightMinor: MinorString,\n expectedReserveBalanceMinor: MinorString,\n actualReserveBalanceMinor: MinorString,\n imbalanceMinor: MinorString,\n generatedAtMs: z.number().int().nonnegative(),\n});\nexport type ReconciliationReport = z.infer<typeof ReconciliationReportSchema>;\n\n// ───────────────────────────── partner client ─────────────────────────────\n\nexport type PartnerFundingClient = {\n /** Submit a funding event (idempotent on externalRef per partner). */\n ingestFunding: (\n input: PartnerFundingEventInput,\n ) => Promise<IngestFundingResult>;\n /** Send a payout state update (idempotent on terminal states). */\n recordPayoutEvent: (\n input: PayoutEventInput,\n ) => Promise<RecordPayoutEventResult>;\n /** Fetch the daily reconciliation report. */\n reconciliation: (input: {\n currency: string;\n fromMs?: number;\n toMs?: number;\n }) => Promise<ReconciliationReport>;\n};\n\nexport function createPartnerFundingClient(\n partner: FlurPartnerClient,\n): PartnerFundingClient {\n return {\n ingestFunding: async (input) => {\n const body = PartnerFundingEventInputSchema.parse(input);\n const raw = await partner.request({\n method: 'POST',\n path: '/v1/partners/fundings',\n body,\n });\n return IngestFundingResultSchema.parse(raw);\n },\n recordPayoutEvent: async (input) => {\n const body = PayoutEventInputSchema.parse(input);\n const raw = await partner.request({\n method: 'POST',\n path: '/v1/partners/payouts/events',\n body,\n });\n return RecordPayoutEventResultSchema.parse(raw);\n },\n reconciliation: async (input) => {\n const qs = new URLSearchParams({\n currency: input.currency,\n });\n if (typeof input.fromMs === 'number')\n qs.set('fromMs', String(input.fromMs));\n if (typeof input.toMs === 'number') qs.set('toMs', String(input.toMs));\n const raw = await partner.request({\n method: 'GET',\n path: `/v1/partners/reconciliation/daily?${qs.toString()}`,\n });\n return ReconciliationReportSchema.parse(raw);\n },\n };\n}\n\n// ───────────────────────────── consumer client ─────────────────────────────\n\nexport type ConsumerWithdrawalsClientOptions = {\n baseUrl: string;\n /** Session-authenticated fetch (Authorization: Bearer <session-token>). */\n fetchImpl?: typeof fetch;\n};\n\nexport type ConsumerWithdrawalsClient = {\n listDestinations: () => Promise<ListPayoutDestinationsResult>;\n createDestination: (\n input: CreatePayoutDestinationInput,\n ) => Promise<PayoutDestination>;\n verifyDestination: (destinationId: string) => Promise<PayoutDestination>;\n disableDestination: (destinationId: string) => Promise<PayoutDestination>;\n createWithdrawal: (\n input: CreateWithdrawalInput,\n ) => Promise<CreateWithdrawalResult>;\n getWithdrawal: (withdrawalId: string) => Promise<Withdrawal>;\n};\n\nexport function createConsumerWithdrawalsClient(\n opts: ConsumerWithdrawalsClientOptions,\n): ConsumerWithdrawalsClient {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\n 'createConsumerWithdrawalsClient: 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: { accept: 'application/json' },\n };\n if (body !== undefined) {\n init.body = JSON.stringify(body);\n init.headers = { ...init.headers, 'content-type': 'application/json' };\n }\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 raw = text;\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 return {\n listDestinations: () =>\n call('GET', '/v1/me/payout-destinations', undefined, (raw) =>\n ListPayoutDestinationsResultSchema.parse(raw),\n ),\n createDestination: (input) =>\n call(\n 'POST',\n '/v1/me/payout-destinations',\n CreatePayoutDestinationInputSchema.parse(input),\n (raw) => PayoutDestinationSchema.parse(raw),\n ),\n verifyDestination: (destinationId) =>\n call(\n 'POST',\n `/v1/me/payout-destinations/${encodeURIComponent(destinationId)}/verify`,\n {},\n (raw) => PayoutDestinationSchema.parse(raw),\n ),\n disableDestination: (destinationId) =>\n call(\n 'POST',\n `/v1/me/payout-destinations/${encodeURIComponent(destinationId)}/disable`,\n {},\n (raw) => PayoutDestinationSchema.parse(raw),\n ),\n createWithdrawal: (input) =>\n call(\n 'POST',\n '/v1/me/withdrawals',\n CreateWithdrawalInputSchema.parse(input),\n (raw) => CreateWithdrawalResultSchema.parse(raw),\n ),\n getWithdrawal: (withdrawalId) =>\n call(\n 'GET',\n `/v1/me/withdrawals/${encodeURIComponent(withdrawalId)}`,\n undefined,\n (raw) => WithdrawalSchema.parse(raw),\n ),\n };\n}\n\n// ───────────────────────────── partner profile admin ─────────────────────────────\n\n/**\n * Partner profile upsert is session-authenticated on the backend (a member\n * of the partner account must perform the action), so it uses a regular\n * session-bearer fetch rather than the partner HMAC client.\n */\nexport type PartnerProfileAdminClientOptions = {\n baseUrl: string;\n fetchImpl?: typeof fetch;\n};\n\nexport type PartnerProfileAdminClient = {\n upsertProfile: (\n partnerAccountId: string,\n input: UpsertPartnerProfileInput,\n ) => Promise<PartnerProfile>;\n};\n\nexport function createPartnerProfileAdminClient(\n opts: PartnerProfileAdminClientOptions,\n): PartnerProfileAdminClient {\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\n 'createPartnerProfileAdminClient: no fetch implementation available',\n );\n }\n const baseUrl = opts.baseUrl.replace(/\\/$/, '');\n return {\n upsertProfile: async (partnerAccountId, input) => {\n const body = {\n partnerAccountId,\n ...UpsertPartnerProfileInputSchema.parse(input),\n };\n const resp = await fetchImpl(`${baseUrl}/v1/partners/profile`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n accept: 'application/json',\n },\n body: JSON.stringify(body),\n });\n const text = await resp.text();\n let raw: unknown;\n if (text) {\n try {\n raw = JSON.parse(text);\n } catch {\n raw = text;\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 PartnerProfileSchema.parse(raw);\n },\n };\n}\n","import { z } from 'zod';\nimport { canonicalJSONBytes } from '../crypto/canonical.js';\nimport { sign, verify } from '../crypto/ed25519.js';\nimport { bytesToHex, hexToBytes } from '../offline/oac.js';\n\n/**\n * Flur v1 Signed Artifact envelope.\n *\n * URI form:\n * flur://v1/<artifact-type>/<base64url(canonical-json(body))>.<base64url(sig)>\n *\n * Body shape (canonical JSON, sorted keys):\n * {\n * v: 1, // envelope version\n * t: '<artifact-type>', // matches the URI segment (redundant for safety)\n * iss: '<issuer-id>', // user/merchant/partner id\n * kid: '<device-key-id>', // identifier of the signing device key\n * iat: <epoch-seconds>, // issued-at\n * exp?: <epoch-seconds>, // optional expiry\n * nonce: '<string>', // unique per artifact (replay guard)\n * data: <artifact body> // type-specific, validated by registered schema\n * }\n *\n * Signature: Ed25519 over canonicalJSONBytes(body), hex-encoded (64 bytes / 128 hex chars).\n *\n * Design notes:\n * - URI scheme `flur://v1/...` is the single transport for all signed artifacts.\n * - Scanners route on the path segment; verifiers look up the issuer/kid public key.\n * - Pure NIBSS NQR payments remain unchanged; this envelope rides separately.\n */\n\nexport const FLUR_ARTIFACT_URI_SCHEME = 'flur';\nexport const FLUR_ARTIFACT_VERSION = 1;\nexport const FLUR_ARTIFACT_URI_PREFIX = `${FLUR_ARTIFACT_URI_SCHEME}://v${FLUR_ARTIFACT_VERSION}/`;\n\nconst ArtifactTypeRe = /^[a-z][a-z0-9_]{1,63}$/;\n\nexport const ArtifactHeaderSchema = z.object({\n v: z.literal(FLUR_ARTIFACT_VERSION),\n t: z.string().regex(ArtifactTypeRe, 'invalid artifact type'),\n iss: z.string().min(1).max(128),\n kid: z.string().min(1).max(128),\n iat: z.number().int().nonnegative(),\n exp: z.number().int().positive().optional(),\n nonce: z\n .string()\n .min(8)\n .max(64)\n .regex(/^[A-Za-z0-9_-]+$/, 'nonce must be url-safe'),\n});\n\nexport type ArtifactHeader = z.infer<typeof ArtifactHeaderSchema>;\n\nexport type ArtifactBody<T = unknown> = ArtifactHeader & { data: T };\n\nexport type SignedArtifact<T = unknown> = {\n body: ArtifactBody<T>;\n sig: string; // hex\n};\n\nexport class FlurArtifactError extends Error {\n constructor(\n message: string,\n public code:\n | 'INVALID_URI'\n | 'INVALID_TYPE'\n | 'INVALID_BODY'\n | 'INVALID_SIGNATURE'\n | 'EXPIRED'\n | 'TYPE_MISMATCH',\n ) {\n super(message);\n this.name = 'FlurArtifactError';\n }\n}\n\n// --- base64url helpers (no padding) ---\n\nexport function base64UrlEncode(bytes: Uint8Array): string {\n let bin = '';\n for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i]);\n // btoa is available in browsers, RN (Hermes), and Node >= 16.\n const b64 =\n typeof btoa === 'function'\n ? btoa(bin)\n : Buffer.from(bytes).toString('base64');\n return b64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nexport function base64UrlDecode(s: string): Uint8Array {\n const pad = s.length % 4 === 0 ? '' : '='.repeat(4 - (s.length % 4));\n const b64 = s.replace(/-/g, '+').replace(/_/g, '/') + pad;\n if (typeof atob === 'function') {\n const bin = atob(b64);\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n }\n return new Uint8Array(Buffer.from(b64, 'base64'));\n}\n\n// --- envelope build / sign / verify ---\n\nexport function buildArtifactBody<T>(input: {\n type: string;\n issuer: string;\n keyId: string;\n data: T;\n issuedAtSeconds?: number;\n expiresAtSeconds?: number;\n nonce: string;\n}): ArtifactBody<T> {\n if (!ArtifactTypeRe.test(input.type)) {\n throw new FlurArtifactError(\n `Invalid artifact type: ${input.type}`,\n 'INVALID_TYPE',\n );\n }\n const iat = input.issuedAtSeconds ?? Math.floor(Date.now() / 1000);\n const header: ArtifactHeader = {\n v: FLUR_ARTIFACT_VERSION,\n t: input.type,\n iss: input.issuer,\n kid: input.keyId,\n iat,\n ...(input.expiresAtSeconds !== undefined\n ? { exp: input.expiresAtSeconds }\n : {}),\n nonce: input.nonce,\n };\n // Validate header structure early so callers get a clean error.\n ArtifactHeaderSchema.parse(header);\n return { ...header, data: input.data };\n}\n\nexport function signArtifact<T>(\n body: ArtifactBody<T>,\n privateKey: Uint8Array,\n): SignedArtifact<T> {\n const sig = bytesToHex(sign(canonicalJSONBytes(body), privateKey));\n return { body, sig };\n}\n\nexport function encodeArtifactUri<T>(signed: SignedArtifact<T>): string {\n const bodyBytes = canonicalJSONBytes(signed.body);\n const bodyB64 = base64UrlEncode(bodyBytes);\n const sigB64 = base64UrlEncode(hexToBytes(signed.sig));\n return `${FLUR_ARTIFACT_URI_PREFIX}${signed.body.t}/${bodyB64}.${sigB64}`;\n}\n\nexport type DecodedArtifactUri = {\n type: string;\n bodyBytes: Uint8Array;\n body: ArtifactBody;\n sig: string; // hex\n};\n\nexport function decodeArtifactUri(uri: string): DecodedArtifactUri {\n if (!uri.startsWith(FLUR_ARTIFACT_URI_PREFIX)) {\n throw new FlurArtifactError(\n `URI does not start with ${FLUR_ARTIFACT_URI_PREFIX}`,\n 'INVALID_URI',\n );\n }\n const rest = uri.slice(FLUR_ARTIFACT_URI_PREFIX.length);\n const slash = rest.indexOf('/');\n if (slash <= 0) {\n throw new FlurArtifactError('Missing artifact type segment', 'INVALID_URI');\n }\n const type = rest.slice(0, slash);\n const payload = rest.slice(slash + 1);\n const dot = payload.indexOf('.');\n if (dot <= 0 || dot === payload.length - 1) {\n throw new FlurArtifactError(\n 'Missing body/signature separator',\n 'INVALID_URI',\n );\n }\n if (!ArtifactTypeRe.test(type)) {\n throw new FlurArtifactError(\n `Invalid artifact type: ${type}`,\n 'INVALID_TYPE',\n );\n }\n\n const bodyBytes = base64UrlDecode(payload.slice(0, dot));\n const sigBytes = base64UrlDecode(payload.slice(dot + 1));\n if (sigBytes.length !== 64) {\n throw new FlurArtifactError(\n `Signature must be 64 bytes, got ${sigBytes.length}`,\n 'INVALID_SIGNATURE',\n );\n }\n\n let bodyJson: unknown;\n try {\n bodyJson = JSON.parse(new TextDecoder().decode(bodyBytes));\n } catch {\n throw new FlurArtifactError('Body is not valid JSON', 'INVALID_BODY');\n }\n\n const headerOnly = ArtifactHeaderSchema.safeParse(bodyJson);\n if (!headerOnly.success) {\n throw new FlurArtifactError(\n `Body header invalid: ${headerOnly.error.message}`,\n 'INVALID_BODY',\n );\n }\n if (headerOnly.data.t !== type) {\n throw new FlurArtifactError(\n `URI type ${type} does not match body type ${headerOnly.data.t}`,\n 'TYPE_MISMATCH',\n );\n }\n\n return {\n type,\n bodyBytes,\n body: bodyJson as ArtifactBody,\n sig: bytesToHex(sigBytes),\n };\n}\n\nexport type VerifyArtifactOptions = {\n /** Caller-supplied current time (seconds). Defaults to Date.now()/1000. */\n nowSeconds?: number;\n /** When true (default), reject artifacts whose `exp` is in the past. */\n enforceExpiry?: boolean;\n};\n\nexport function verifyArtifactSignature(\n decoded: DecodedArtifactUri,\n publicKey: Uint8Array,\n options: VerifyArtifactOptions = {},\n): boolean {\n if (options.enforceExpiry !== false && decoded.body.exp !== undefined) {\n const now = options.nowSeconds ?? Math.floor(Date.now() / 1000);\n if (decoded.body.exp < now) {\n throw new FlurArtifactError('Artifact has expired', 'EXPIRED');\n }\n }\n return verify(decoded.bodyBytes, hexToBytes(decoded.sig), publicKey);\n}\n","import { z } from 'zod';\nimport { OfflinePaymentAuthorizationSchema } from '../offline/messages.js';\n\n/**\n * Registry of all Flur v1 signed artifact types.\n *\n * Each artifact has:\n * - a string discriminator (used in the URI path segment & header `t`),\n * - a Zod schema validating the `data` payload only (envelope header is validated separately).\n *\n * Two artifacts are fully specified in this slice (OPA + Receipt) as the\n * canonical implementation pattern. The remaining nine carry stub schemas\n * (`z.unknown()`) so types compile and the registry is complete; bodies\n * will be locked in subsequent slices once their backend ledger shapes\n * are finalised.\n */\n\nexport const ARTIFACT_TYPES = {\n OFFLINE_PAYMENT_AUTHORIZATION: 'offline_payment_authorization',\n RECEIPT: 'receipt',\n // --- stubs, schemas to be hardened in follow-ups ---\n NQR_PAYMENT_REQUEST: 'nqr_payment_request',\n PAYMENT_INTENT: 'payment_intent',\n OFFLINE_CLAIM: 'offline_claim',\n SETTLEMENT_RECORD: 'settlement_record',\n REVERSAL_RECORD: 'reversal_record',\n LEDGER_JOURNAL_ENTRY: 'ledger_journal_entry',\n STATEMENT: 'statement',\n PASS: 'pass',\n IDENTITY: 'identity',\n} as const;\n\nexport type ArtifactType = (typeof ARTIFACT_TYPES)[keyof typeof ARTIFACT_TYPES];\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// --- Fully specified: offline_payment_authorization ---\n// Wraps the existing FLUR2: payload in the unified envelope. The inner\n// OfflinePaymentAuthorization is already self-signed; embedding it here\n// adds the device-key issuer attestation + uniform nonce/expiry handling.\nexport const OfflinePaymentAuthorizationArtifactSchema = z.object({\n authorization: OfflinePaymentAuthorizationSchema,\n});\nexport type OfflinePaymentAuthorizationArtifact = z.infer<\n typeof OfflinePaymentAuthorizationArtifactSchema\n>;\n\n// --- Fully specified: receipt ---\n// Payment receipt produced by the payee after a payment settles (online or\n// reconciled from offline). Signed by the issuer's device key so payers and\n// auditors can verify provenance offline.\nexport const ReceiptArtifactSchema = z.object({\n receiptId: z.string().min(1).max(64),\n paymentReference: z.string().min(1).max(64),\n payerUserId: z.string().min(1).max(64).optional(),\n payeeUserId: z.string().min(1).max(64),\n amountKobo: z.number().int().positive(),\n currency: z.literal('NGN'),\n channel: z.enum(['online', 'offline_reconciled', 'pay_link', 'nqr']),\n settledAtMs: z.number().int().positive(),\n ledgerTxnId: z.string().min(1).max(64).optional(),\n memo: z.string().max(140).optional(),\n hashChainPrev: HexString(32).optional(),\n});\nexport type ReceiptArtifact = z.infer<typeof ReceiptArtifactSchema>;\n\n// --- Shared field primitives (reused across the remaining artifacts) ---\nconst ShortId = z.string().min(1).max(64);\nconst PositiveInt = z.number().int().positive();\nconst NonNegativeInt = z.number().int().nonnegative();\nconst Currency = z.literal('NGN');\nconst Memo = z.string().max(140);\n\n// --- nqr_payment_request ---\n// Merchant- or payee-issued payment request rendered as a Flur QR. The amount\n// may be omitted for \"any amount\" / open-tab flows. Verifiers should refuse\n// expired requests and surface `memo` to the payer.\nexport const NqrPaymentRequestArtifactSchema = z.object({\n requestId: ShortId,\n payeeUserId: ShortId,\n amountKobo: PositiveInt.optional(),\n currency: Currency,\n memo: Memo.optional(),\n expiresAtMs: PositiveInt.optional(),\n});\nexport type NqrPaymentRequestArtifact = z.infer<\n typeof NqrPaymentRequestArtifactSchema\n>;\n\n// --- payment_intent ---\n// Payer-side commitment to pay a specific payee. Bound to an idempotency key\n// so a single intent cannot drive multiple settlements server-side.\nexport const PaymentIntentArtifactSchema = z.object({\n intentId: ShortId,\n payerUserId: ShortId,\n payeeUserId: ShortId,\n amountKobo: PositiveInt,\n currency: Currency,\n idempotencyKey: ShortId,\n createdAtMs: PositiveInt,\n});\nexport type PaymentIntentArtifact = z.infer<typeof PaymentIntentArtifactSchema>;\n\n// --- offline_claim ---\n// Payee's signed claim submitted to settle a previously presented OPA.\n// `claimedAmountKobo` may differ from the OPA face value (e.g. partial fills).\nexport const OfflineClaimArtifactSchema = z.object({\n claimId: ShortId,\n authorizationId: ShortId,\n payeeUserId: ShortId,\n claimedAmountKobo: PositiveInt,\n currency: Currency,\n claimedAtMs: PositiveInt,\n paymentReference: ShortId.optional(),\n});\nexport type OfflineClaimArtifact = z.infer<typeof OfflineClaimArtifactSchema>;\n\n// --- settlement_record ---\n// Internal record of a settlement event, linking the source artifact (OPA,\n// claim, transfer, pay-link) to its ledger transaction.\nexport const SettlementRecordArtifactSchema = z.object({\n settlementId: ShortId,\n ledgerTxnId: ShortId,\n sourceRefType: z.enum([\n 'offline_authorization',\n 'offline_claim',\n 'transfer',\n 'pay_link',\n ]),\n sourceRefId: ShortId,\n amountKobo: PositiveInt,\n currency: Currency,\n settledAtMs: PositiveInt,\n});\nexport type SettlementRecordArtifact = z.infer<\n typeof SettlementRecordArtifactSchema\n>;\n\n// --- reversal_record ---\n// Reversal of a prior settled transaction. `reason` is a closed enum so\n// downstream analytics can bucket disputes reliably.\nexport const ReversalRecordArtifactSchema = z.object({\n reversalId: ShortId,\n originalTxnId: ShortId,\n amountKobo: PositiveInt,\n currency: Currency,\n reason: z.enum([\n 'user_dispute',\n 'fraud',\n 'duplicate',\n 'admin_correction',\n 'other',\n ]),\n reversedAtMs: PositiveInt,\n memo: Memo.optional(),\n});\nexport type ReversalRecordArtifact = z.infer<\n typeof ReversalRecordArtifactSchema\n>;\n\n// --- ledger_journal_entry ---\n// One side-balanced double-entry journal line. `debitAccountId` and\n// `creditAccountId` are opaque internal account identifiers.\nexport const LedgerJournalEntryArtifactSchema = z.object({\n entryId: ShortId,\n journalId: ShortId,\n debitAccountId: ShortId,\n creditAccountId: ShortId,\n amountKobo: PositiveInt,\n currency: Currency,\n postedAtMs: PositiveInt,\n refType: ShortId.optional(),\n refId: ShortId.optional(),\n});\nexport type LedgerJournalEntryArtifact = z.infer<\n typeof LedgerJournalEntryArtifactSchema\n>;\n\n// --- statement ---\n// Account-statement summary for a closed period. `hashChainPrev` links to\n// the prior statement for tamper-evident chaining.\nexport const StatementArtifactSchema = z\n .object({\n statementId: ShortId,\n userId: ShortId,\n periodStartMs: PositiveInt,\n periodEndMs: PositiveInt,\n openingBalanceKobo: z.number().int(),\n closingBalanceKobo: z.number().int(),\n transactionCount: NonNegativeInt,\n currency: Currency,\n hashChainPrev: HexString(32).optional(),\n })\n .refine((v) => v.periodEndMs > v.periodStartMs, {\n message: 'periodEndMs must be greater than periodStartMs',\n path: ['periodEndMs'],\n });\nexport type StatementArtifact = z.infer<typeof StatementArtifactSchema>;\n\n// --- pass ---\n// Generic digital pass (membership, ticket, loyalty, access, voucher).\n// `metadata` is intentionally narrow — only scalar values — so canonical\n// JSON ordering remains deterministic across SDK versions.\nexport const PassArtifactSchema = z\n .object({\n passId: ShortId,\n holderId: ShortId,\n category: z.enum(['membership', 'ticket', 'loyalty', 'access', 'voucher']),\n title: z.string().min(1).max(120),\n validFromMs: PositiveInt,\n validUntilMs: PositiveInt.optional(),\n metadata: z\n .record(\n z.string().min(1).max(64),\n z.union([z.string().max(280), z.number(), z.boolean()]),\n )\n .optional(),\n })\n .refine(\n (v) => v.validUntilMs === undefined || v.validUntilMs > v.validFromMs,\n {\n message: 'validUntilMs must be greater than validFromMs',\n path: ['validUntilMs'],\n },\n );\nexport type PassArtifact = z.infer<typeof PassArtifactSchema>;\n\n// --- identity ---\n// Identity attestation. `claimValueHash` is the SHA-256 of the underlying\n// value so the artifact can be shared without leaking PII.\nexport const IdentityArtifactSchema = z.object({\n attestationId: ShortId,\n subjectId: ShortId,\n claimType: z.enum([\n 'phone_verified',\n 'email_verified',\n 'bvn_verified',\n 'kyc_tier',\n 'age_band',\n ]),\n claimValueHash: HexString(32),\n attestedAtMs: PositiveInt,\n});\nexport type IdentityArtifact = z.infer<typeof IdentityArtifactSchema>;\n\nexport const ARTIFACT_BODY_SCHEMAS = {\n [ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION]:\n OfflinePaymentAuthorizationArtifactSchema,\n [ARTIFACT_TYPES.RECEIPT]: ReceiptArtifactSchema,\n [ARTIFACT_TYPES.NQR_PAYMENT_REQUEST]: NqrPaymentRequestArtifactSchema,\n [ARTIFACT_TYPES.PAYMENT_INTENT]: PaymentIntentArtifactSchema,\n [ARTIFACT_TYPES.OFFLINE_CLAIM]: OfflineClaimArtifactSchema,\n [ARTIFACT_TYPES.SETTLEMENT_RECORD]: SettlementRecordArtifactSchema,\n [ARTIFACT_TYPES.REVERSAL_RECORD]: ReversalRecordArtifactSchema,\n [ARTIFACT_TYPES.LEDGER_JOURNAL_ENTRY]: LedgerJournalEntryArtifactSchema,\n [ARTIFACT_TYPES.STATEMENT]: StatementArtifactSchema,\n [ARTIFACT_TYPES.PASS]: PassArtifactSchema,\n [ARTIFACT_TYPES.IDENTITY]: IdentityArtifactSchema,\n} as const;\n\n/** Artifact types whose body schema is fully specified and safe to dispatch. */\nexport const HARDENED_ARTIFACT_TYPES = new Set<ArtifactType>([\n ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION,\n ARTIFACT_TYPES.RECEIPT,\n ARTIFACT_TYPES.NQR_PAYMENT_REQUEST,\n ARTIFACT_TYPES.PAYMENT_INTENT,\n ARTIFACT_TYPES.OFFLINE_CLAIM,\n ARTIFACT_TYPES.SETTLEMENT_RECORD,\n ARTIFACT_TYPES.REVERSAL_RECORD,\n ARTIFACT_TYPES.LEDGER_JOURNAL_ENTRY,\n ARTIFACT_TYPES.STATEMENT,\n ARTIFACT_TYPES.PASS,\n ARTIFACT_TYPES.IDENTITY,\n]);\n\nexport function isKnownArtifactType(t: string): t is ArtifactType {\n return (Object.values(ARTIFACT_TYPES) as string[]).includes(t);\n}\n\nexport function isHardenedArtifactType(t: string): t is ArtifactType {\n return HARDENED_ARTIFACT_TYPES.has(t as ArtifactType);\n}\n","import { z } from 'zod';\nimport {\n decodeArtifactUri,\n FlurArtifactError,\n type ArtifactBody,\n type DecodedArtifactUri,\n type SignedArtifact,\n type VerifyArtifactOptions,\n buildArtifactBody,\n signArtifact,\n encodeArtifactUri,\n verifyArtifactSignature,\n} from './envelope.js';\nimport {\n ARTIFACT_BODY_SCHEMAS,\n ARTIFACT_TYPES,\n isHardenedArtifactType,\n isKnownArtifactType,\n type ArtifactType,\n type OfflinePaymentAuthorizationArtifact,\n type ReceiptArtifact,\n} from './types.js';\n\n/**\n * Build, sign and encode a typed artifact into a flur://v1/... URI.\n *\n * - Validates the body against the registered Zod schema for `type`.\n * - Refuses unknown artifact types.\n * - Refuses stub types (those without a hardened schema) to avoid shipping\n * unverifiable payloads.\n */\nexport function createArtifactUri<T>(input: {\n type: ArtifactType;\n issuer: string;\n keyId: string;\n privateKey: Uint8Array;\n data: T;\n nonce: string;\n issuedAtSeconds?: number;\n expiresAtSeconds?: number;\n}): { uri: string; signed: SignedArtifact<T> } {\n if (!isKnownArtifactType(input.type)) {\n throw new FlurArtifactError(\n `Unknown artifact type: ${input.type}`,\n 'INVALID_TYPE',\n );\n }\n if (!isHardenedArtifactType(input.type)) {\n throw new FlurArtifactError(\n `Artifact type ${input.type} is not yet hardened for emission`,\n 'INVALID_TYPE',\n );\n }\n const schema = ARTIFACT_BODY_SCHEMAS[input.type] as unknown as z.ZodType<T>;\n const parsedData = schema.parse(input.data);\n\n const body = buildArtifactBody({\n type: input.type,\n issuer: input.issuer,\n keyId: input.keyId,\n data: parsedData,\n nonce: input.nonce,\n issuedAtSeconds: input.issuedAtSeconds,\n expiresAtSeconds: input.expiresAtSeconds,\n });\n const signed = signArtifact(body, input.privateKey);\n return { uri: encodeArtifactUri(signed), signed };\n}\n\nexport type VerifiedArtifact<T = unknown> = {\n type: ArtifactType;\n body: ArtifactBody<T>;\n sig: string;\n decoded: DecodedArtifactUri;\n};\n\n/**\n * Decode and verify a flur://v1/... URI.\n *\n * - Parses the URI and envelope header.\n * - Validates the body against the registered Zod schema.\n * - Verifies the Ed25519 signature against the supplied public key.\n * - Enforces expiry unless `options.enforceExpiry === false`.\n *\n * The caller is responsible for resolving the public key from (issuer, kid)\n * against the backend device-key registry, and for enforcing nonce uniqueness\n * via the artifact_nonces store.\n */\nexport function verifyArtifactUri<T = unknown>(\n uri: string,\n publicKey: Uint8Array,\n options: VerifyArtifactOptions = {},\n): VerifiedArtifact<T> {\n const decoded = decodeArtifactUri(uri);\n\n if (!isKnownArtifactType(decoded.type)) {\n throw new FlurArtifactError(\n `Unknown artifact type: ${decoded.type}`,\n 'INVALID_TYPE',\n );\n }\n if (!isHardenedArtifactType(decoded.type)) {\n throw new FlurArtifactError(\n `Artifact type ${decoded.type} is not yet hardened for verification`,\n 'INVALID_TYPE',\n );\n }\n\n const schema = ARTIFACT_BODY_SCHEMAS[decoded.type as ArtifactType];\n const dataParsed = schema.safeParse(decoded.body.data);\n if (!dataParsed.success) {\n throw new FlurArtifactError(\n `Artifact body invalid: ${dataParsed.error.message}`,\n 'INVALID_BODY',\n );\n }\n\n const ok = verifyArtifactSignature(decoded, publicKey, options);\n if (!ok) {\n throw new FlurArtifactError(\n 'Artifact signature verification failed',\n 'INVALID_SIGNATURE',\n );\n }\n\n return {\n type: decoded.type as ArtifactType,\n body: decoded.body as ArtifactBody<T>,\n sig: decoded.sig,\n decoded,\n };\n}\n\n// Convenience helpers that pin the artifact-type generic for the two\n// hardened artifacts. Useful for app code that wants compile-time guarantees\n// without repeating the schema reference.\n\nexport function createReceiptArtifactUri(input: {\n issuer: string;\n keyId: string;\n privateKey: Uint8Array;\n data: ReceiptArtifact;\n nonce: string;\n issuedAtSeconds?: number;\n expiresAtSeconds?: number;\n}) {\n return createArtifactUri<ReceiptArtifact>({\n ...input,\n type: ARTIFACT_TYPES.RECEIPT,\n });\n}\n\nexport function createOfflinePaymentAuthorizationArtifactUri(input: {\n issuer: string;\n keyId: string;\n privateKey: Uint8Array;\n data: OfflinePaymentAuthorizationArtifact;\n nonce: string;\n issuedAtSeconds?: number;\n expiresAtSeconds?: number;\n}) {\n return createArtifactUri<OfflinePaymentAuthorizationArtifact>({\n ...input,\n type: ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION,\n });\n}\n"],"mappings":"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","names":["z","z","z","candidate","z","z","CurrencySchema","init","init","z","z","z","z","z","z","bytesToHex","sha256","bytesToHex","init","z","sha256","hmac","bytesToHex","z","sha256Hex","bytesToHex","sha256","hmac","defaultNonce","init","z","HexString","z","z","HexSig","z","z","HexString","z","init","init","z","z","init","z","z","init","ed25519","bytesToHex","hexToBytes","ed25519","bytesToHex","hexToBytes","z","z","init","z","z","z","HexString","z","Currency"]}