import { encodeFunctionData, erc20Abi, keccak256 } from 'viem' import * as Anvil from '../../../test/Anvil.js' import * as TestApp from '../../../test/App.js' import * as TestRoutes from '../../../test/Routes.js' import * as Organizations from '../../db/tables/organizations.js' import * as RoutesTransferSubsidyNonces from '../../db/tables/routesTransferSubsidyNonces.js' import * as RoutesTransferTransactions from '../../db/tables/routesTransferTransactions.js' import * as RoutesTransfers from '../../db/tables/routesTransfers.js' import * as Transfer from './Transfer.js' import * as TransferSubsidy from './TransferSubsidy.js' const db = TestApp.database() const now = new Date('2026-01-01T00:00:00.000Z') beforeEach(() => vi.useFakeTimers({ now, toFake: ['Date'] })) afterEach(() => vi.useRealTimers()) function createInput(overrides: Partial = {}): Transfer.create.Input { return { apiKeyId: 'key_test', environment: 'production', orgId: 'org_test', snapshot: TestRoutes.transferSnapshot(), ...overrides, } } describe('canTransition', () => { test('encodes the public state chart', () => { const table = Object.fromEntries( Transfer.statuses.map((from) => [ from, Transfer.statuses.filter((to) => Transfer.canTransition(from, to)), ]), ) expect(table).toMatchInlineSnapshot(` { "action-required": [ "processing", "refunding", "completed", "refunded", ], "awaiting-source": [ "processing", "action-required", "expired", ], "completed": [], "expired": [], "processing": [ "awaiting-source", "refunding", "completed", "action-required", ], "refunded": [], "refunding": [ "refunded", "action-required", ], } `) }) }) describe('isTerminal', () => { test('only chain-verified and expiry outcomes are terminal', () => { expect(Transfer.statuses.filter(Transfer.isTerminal)).toMatchInlineSnapshot(` [ "completed", "refunded", "expired", ] `) }) }) describe('generateId', () => { test('embeds the timestamp so lexical order is chronological', () => { const earlier = Transfer.generateId(new Date('2026-01-01T00:00:00.000Z')) const later = Transfer.generateId(new Date('2026-01-01T00:00:01.000Z')) expect(earlier).toMatch(/^rtr_\d{15}_[0-9A-Za-z]{24}$/) expect(earlier < later).toBe(true) }) }) describe('create', () => { test('creates the row and its version-1 event atomically', async () => { const record = await Transfer.create(db, createInput()) const { id, snapshot: _, ...rest } = record expect(id).toMatch(/^rtr_/) expect(rest).toMatchInlineSnapshot(` { "apiKeyId": "key_test", "createdAt": "2026-01-01T00:00:00.000Z", "environment": "production", "method": "transaction", "mode": "exactSource", "orgId": "org_test", "projectId": null, "providerDeliveredAt": null, "providerId": "relay", "providerState": null, "quoteExpiresAt": "2026-01-01T00:01:00.000Z", "status": "awaiting-source", "statusReason": null, "statusUpdatedAt": "2026-01-01T00:00:00.000Z", "subsidyAccount": null, "subsidyAmount": null, "subsidyChainId": null, "subsidyCommitmentAmount": null, "subsidyMeterReportedAt": null, "subsidyNativeAmount": null, "subsidyTokenAddress": null, "subsidyTransactionHash": null, "updatedAt": "2026-01-01T00:00:00.000Z", "version": 1, } `) const events = await db.kysely .selectFrom('routes_transfer_events') .select(['status', 'transferId', 'version']) .where('transferId', '=', id) .execute() expect(events).toEqual([{ status: 'awaiting-source', transferId: id, version: 1 }]) }) test('normalizes quote expiry and strips executable actions before persistence', async () => { const snapshot = { ...TestRoutes.transferSnapshot({ quote: { expiresAt: '2026-01-01T00:01:00Z', sampledAt: '2026-01-01T00:00:00.000Z' }, }), action: { type: 'evm:calls' }, } const record = await Transfer.create(db, createInput({ snapshot })) expect({ action: 'action' in record.snapshot, expiresAt: record.snapshot.quote.expiresAt, quoteExpiresAt: record.quoteExpiresAt, }).toEqual({ action: false, expiresAt: '2026-01-01T00:01:00.000Z', quoteExpiresAt: '2026-01-01T00:01:00.000Z', }) }) test('persists one creation commitment and serializes concurrent inventory checks', async () => { const account = `0x${'55'.repeat(20)}` as const const chainId = 'eip155:8453' const commitment = { baseUnits: '20000', currency: 'USD', decimals: 6, formatted: '0.02', } as const const source = TestApp.databaseFactory() const database = source() await Organizations.create(database, { id: 'org_test', name: 'Test' }) const reservations: { nativeAmount: bigint; tokenAmount: bigint }[] = [] const createCommitted = (database: typeof db) => database.transaction((tx) => Transfer.reserveSubsidyCommitmentIn(tx, createInput(), { account, chainId, async check({ reservations: current }) { reservations.push(current) if (20_000n + current.tokenAmount > 20_000n) throw new TransferSubsidy.BalanceUnavailableError() return { nativeAmount: '100' } }, subsidyCommitmentAmount: commitment, tokenAddress: `0x${'66'.repeat(20)}`, }), ) const results = await Promise.allSettled([createCommitted(source()), createCommitted(source())]) const created = results.find((result) => result.status === 'fulfilled') if (!created || created.status !== 'fulfilled') throw new Error('Expected one commitment.') const rejected = results.find((result) => result.status === 'rejected') const rows = await database.kysely .selectFrom('routes_transfers') .select([ 'subsidyAccount', 'subsidyChainId', 'subsidyCommitmentAmount', 'subsidyNativeAmount', 'subsidyTokenAddress', ]) .where('id', '=', created.value.record.id) .execute() expect({ rejected: rejected?.reason instanceof TransferSubsidy.BalanceUnavailableError, reservations, rows, }).toMatchInlineSnapshot(` { "rejected": true, "reservations": [ { "nativeAmount": 0n, "tokenAmount": 0n, }, { "nativeAmount": 100n, "tokenAmount": 20000n, }, ], "rows": [ { "subsidyAccount": "0x5555555555555555555555555555555555555555", "subsidyChainId": "eip155:8453", "subsidyCommitmentAmount": { "baseUnits": "20000", "currency": "USD", "decimals": 6, "formatted": "0.02", }, "subsidyNativeAmount": "100", "subsidyTokenAddress": "0x6666666666666666666666666666666666666666", }, ], } `) }) test('rejects a missing owner after acquiring the organization lock', async () => { let checked = false await expect( db.transaction((tx) => Transfer.reserveSubsidyCommitmentIn(tx, createInput(), { account: `0x${'55'.repeat(20)}`, chainId: 'eip155:8453', async check() { checked = true return { nativeAmount: '100' } }, subsidyCommitmentAmount: { baseUnits: '1', currency: 'USD', decimals: 6, formatted: '0.000001', }, tokenAddress: `0x${'66'.repeat(20)}`, }), ), ).rejects.toThrow(Transfer.OrganizationNotFoundError) expect(checked).toBe(false) }) test('rejects a quote that expires while inventory is checked', async () => { await Organizations.create(db, { id: 'org_test', name: 'Test' }) const input = createInput() const before = await RoutesTransfers.listByOwner( db, { environment: 'production', orgId: 'org_test' }, { limit: 100 }, ) await expect( db.transaction((tx) => Transfer.reserveSubsidyCommitmentIn(tx, input, { account: `0x${'55'.repeat(20)}`, chainId: 'eip155:8453', async check() { vi.setSystemTime(new Date(input.snapshot.quote.expiresAt)) return { nativeAmount: '100' } }, subsidyCommitmentAmount: { baseUnits: '1', currency: 'USD', decimals: 6, formatted: '0.000001', }, tokenAddress: `0x${'66'.repeat(20)}`, }), ), ).rejects.toThrow(Transfer.QuoteExpiredError) const after = await RoutesTransfers.listByOwner( db, { environment: 'production', orgId: 'org_test' }, { limit: 100 }, ) expect(after.map(({ id }) => id)).toEqual(before.map(({ id }) => id)) }) }) describe('registerSourceTransactions', () => { const transactionHash = `0x${'a2'.repeat(32)}` test('atomically assigns source evidence and starts reconciliation', async () => { const record = await Transfer.create( db, createInput({ providerState: { routeConfiguration: { destinationPoolAddress: `0x${'cc'.repeat(20)}`, poolAddress: `0x${'dd'.repeat(20)}`, sourceEid: 30_184, }, }, snapshot: TestRoutes.transferSnapshot({ provider: { id: 'stargate', name: 'Stargate' } }), }), ) const destinationAmount = { ...record.snapshot.destinationAmount!, baseUnits: '980000', formatted: '0.98', } vi.setSystemTime(new Date('2026-01-01T00:00:10.000Z')) const result = await Transfer.registerSourceTransactions(db, { chainId: 'eip155:8453', destinationAmount, id: record.id, providerState: { stargate: { guid: `0x${'bb'.repeat(32)}`, sourceEid: 30_184 } }, transactionHashes: [`0x${'a6'.repeat(32)}`, `0x${'a1'.repeat(32)}`], }) expect(result.type).toBe('registered') if (result.type !== 'registered') return expect({ destinationAmount: result.record.snapshot.destinationAmount, providerState: result.record.providerState, sourceTransactionHashes: result.record.snapshot.sourceTransactionHashes, status: result.record.status, version: result.record.version, }).toMatchInlineSnapshot(` { "destinationAmount": { "baseUnits": "980000", "currency": "USD", "decimals": 6, "formatted": "0.98", }, "providerState": { "routeConfiguration": { "destinationPoolAddress": "0xcccccccccccccccccccccccccccccccccccccccc", "poolAddress": "0xdddddddddddddddddddddddddddddddddddddddd", "sourceEid": 30184, }, "stargate": { "guid": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "sourceEid": 30184, }, }, "sourceTransactionHashes": [ "0xa6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6", "0xa1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1", ], "status": "processing", "version": 2, } `) }) test('replays the same assignment and rejects reuse by another transfer', async () => { const first = await Transfer.create(db, createInput()) const second = await Transfer.create(db, createInput({ apiKeyId: 'key_rotated' })) const options = { chainId: 'eip155:8453', id: first.id, providerState: { stargate: { guid: `0x${'bb'.repeat(32)}`, sourceEid: 30_184 } }, transactionHashes: [transactionHash] as const, } await Transfer.registerSourceTransactions(db, options) const replayed = await Transfer.registerSourceTransactions(db, options) const conflict = await Transfer.registerSourceTransactions(db, { ...options, id: second.id }) expect({ conflict: conflict.type, replayed: replayed.type, replayedVersion: replayed.type === 'replayed' ? replayed.record.version : undefined, }).toEqual({ conflict: 'conflict', replayed: 'replayed', replayedVersion: 2 }) }) test.each(['processing', 'completed'] as const)( 'accepts legitimate source evidence after a foreign transfer is %s', async (status) => { const database = TestApp.database() const snapshot = TestRoutes.transferSnapshot() const legitimate = await Transfer.create(database, createInput({ snapshot })) const foreign = await Transfer.create( database, createInput({ apiKeyId: 'key_foreign', orgId: 'org_foreign', snapshot }), ) const evidence = { chainId: snapshot.sourceChain.id, providerState: {}, transactionHashes: [`0x${'af'.repeat(32)}`] as const, } const claimed = await Transfer.registerSourceTransactions(database, { ...evidence, id: foreign.id, }) expect(claimed.type).toBe('registered') if (status === 'completed') { const completed = await Transfer.complete(database, { chainId: snapshot.destinationChain.id, destinationAmount: snapshot.destinationAmount!, id: foreign.id, transactionHashes: [`0x${'df'.repeat(32)}`], }) expect(completed.type).toBe('completed') } const registered = await Transfer.registerSourceTransactions(database, { ...evidence, id: legitimate.id, }) expect(registered.type).toBe('registered') const replayed = await Transfer.registerSourceTransactions(database, { ...evidence, id: legitimate.id, }) const duplicate = await Transfer.create(database, createInput({ snapshot })) const conflict = await Transfer.registerSourceTransactions(database, { ...evidence, id: duplicate.id, }) expect({ conflict: conflict.type, foreignStatus: (await RoutesTransfers.get(database, foreign.id))?.status, legitimateStatus: (await RoutesTransfers.get(database, legitimate.id))?.status, replayed: replayed.type, }).toEqual({ conflict: 'conflict', foreignStatus: status, legitimateStatus: 'processing', replayed: 'replayed', }) }, ) test.each([{ environment: 'sandbox' as const }, { projectId: 'prj_other' }])( 'isolates source claims for $environment $projectId', async (scope) => { const database = TestApp.databaseFactory() const first = await Transfer.create(database(), createInput()) const second = await Transfer.create(database(), createInput(scope)) const results = await Promise.all( [first, second].map(({ id }) => Transfer.registerSourceTransactions(database(), { chainId: 'eip155:8453', id, providerState: {}, transactionHashes: [`0x${'ac'.repeat(32)}`], }), ), ) expect(results.map(({ type }) => type)).toEqual(['registered', 'registered']) const reopened = await Transfer.reopenSourceTransaction(database(), { chainId: 'eip155:8453', id: first.id, providerState: {}, transactionHash: `0x${'ac'.repeat(32)}`, }) expect(reopened.type).toBe('reopened') expect( ( await Transfer.registerSourceTransactions(database(), { chainId: 'eip155:8453', id: second.id, providerState: {}, transactionHashes: [`0x${'ac'.repeat(32)}`], }) ).type, ).toBe('replayed') }, ) test('rejects empty source evidence', async () => { const record = await Transfer.create(db, createInput()) const result = await Transfer.registerSourceTransactions(db, { chainId: 'eip155:8453', id: record.id, providerState: {}, transactionHashes: [] as never, }) expect(result).toMatchObject({ current: { status: 'awaiting-source' }, type: 'invalid' }) }) test('rejects late source registration before the expiry sweep', async () => { const transactionHash = `0x${'a9'.repeat(32)}` const record = await Transfer.create( db, createInput({ subsidyCommitment: { account: `0x${'55'.repeat(20)}`, amount: { baseUnits: '1', currency: 'USD', decimals: 6, formatted: '0.000001' }, chainId: 'eip155:8453', nativeAmount: '100', tokenAddress: `0x${'66'.repeat(20)}`, }, }), ) vi.setSystemTime( new Date( new Date(record.quoteExpiresAt).getTime() + RoutesTransfers.subsidyCommitmentRecoveryTtlMs, ), ) const result = await Transfer.registerSourceTransactions(db, { chainId: 'eip155:8453', id: record.id, providerState: {}, transactionHashes: [transactionHash], }) const claimed = await RoutesTransferTransactions.getSource(db, { chainId: 'eip155:8453', transactionRef: transactionHash, transferId: record.id, }) expect({ claimed, result }).toMatchObject({ claimed: undefined, result: { current: { status: 'awaiting-source' }, type: 'invalid' }, }) }) test('claims concurrent source evidence in a stable order', async () => { const database = TestApp.databaseFactory() const first = await Transfer.create(database(), createInput()) const second = await Transfer.create(database(), createInput()) const lower = `0x${'a7'.repeat(32)}` const upper = `0x${'a8'.repeat(32)}` const results = await Promise.all([ Transfer.registerSourceTransactions(database(), { chainId: 'eip155:8453', id: first.id, providerState: {}, transactionHashes: [lower, upper], }), Transfer.registerSourceTransactions(database(), { chainId: 'eip155:8453', id: second.id, providerState: {}, transactionHashes: [upper, lower], }), ]) expect(results.map((result) => result.type).toSorted()).toEqual(['conflict', 'registered']) }) }) describe('reopenSourceTransaction', () => { test('removes invalidated source evidence and accepts a replacement', async () => { const record = await Transfer.create(db, createInput()) const transactionHash = `0x${'a4'.repeat(32)}` await Transfer.registerSourceTransactions(db, { chainId: 'eip155:8453', id: record.id, providerState: { stargate: { guid: `0x${'bb'.repeat(32)}`, sourceEid: 30_184 } }, transactionHashes: [transactionHash], }) const reopened = await Transfer.reopenSourceTransaction(db, { chainId: 'eip155:8453', id: record.id, providerState: { routeConfiguration: { poolAddress: `0x${'cc'.repeat(20)}` } }, transactionHash: transactionHash.toUpperCase(), }) expect(reopened.type).toBe('reopened') if (reopened.type !== 'reopened') return expect({ providerState: reopened.record.providerState, sourceTransactionHashes: reopened.record.snapshot.sourceTransactionHashes, status: reopened.record.status, version: reopened.record.version, }).toEqual({ providerState: { routeConfiguration: { poolAddress: `0x${'cc'.repeat(20)}` } }, sourceTransactionHashes: undefined, status: 'awaiting-source', version: 3, }) const replacement = await Transfer.registerSourceTransactions(db, { chainId: 'eip155:8453', id: record.id, providerState: { stargate: { guid: `0x${'dd'.repeat(32)}`, sourceEid: 30_184 } }, transactionHashes: [`0x${'a5'.repeat(32)}`], }) expect(replacement.type).toBe('registered') }) }) describe('complete', () => { test('records verified destination evidence and completes once', async () => { const record = await Transfer.create(db, createInput()) await Transfer.registerSourceTransactions(db, { chainId: 'eip155:8453', id: record.id, providerState: { stargate: { guid: `0x${'bb'.repeat(32)}`, sourceEid: 30_184 } }, transactionHashes: [`0x${'a3'.repeat(32)}`], }) const options = { chainId: 'eip155:4217', destinationAmount: TestRoutes.transferSnapshot().destinationAmount!, id: record.id, transactionHashes: [`0x${'cc'.repeat(32)}`, `0x${'dd'.repeat(32)}`] as const, } const completed = await Transfer.complete(db, options) const replayed = await Transfer.complete(db, options) expect({ completed: completed.type, destinationTransactionHashes: completed.type === 'completed' ? completed.record.snapshot.destinationTransactionHashes : undefined, replayed: replayed.type, status: completed.type === 'completed' ? completed.record.status : undefined, version: completed.type === 'completed' ? completed.record.version : undefined, }).toMatchInlineSnapshot(` { "completed": "completed", "destinationTransactionHashes": [ "0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", ], "replayed": "replayed", "status": "completed", "version": 3, } `) }) }) describe('reserveSubsidy', () => { test('shares one signed subsidy across concurrent tenants and bills its owner once', async () => { const database = TestApp.databaseFactory() const account = Anvil.getAccount(0) const base = TestRoutes.transferSnapshot() const snapshot = TestRoutes.transferSnapshot({ destinationChain: base.sourceChain, destinationToken: base.sourceToken, sourceChain: base.destinationChain, sourceToken: base.destinationToken, }) const amount = { baseUnits: '3001', currency: 'USD', decimals: 6, formatted: '0.003001', } as const const subsidyCommitment = { account: account.address, amount, chainId: snapshot.destinationChain.id, nativeAmount: '100', tokenAddress: snapshot.destinationToken.address, } const records: RoutesTransfers.Record[] = [] for (const orgId of ['org_first', 'org_second']) { const record = await Transfer.create( database(), createInput({ orgId, snapshot, subsidyCommitment }), ) records.push(record) expect( ( await Transfer.registerSourceTransactions(database(), { chainId: snapshot.sourceChain.id, id: record.id, providerState: {}, transactionHashes: [`0x${'ee'.repeat(32)}`], }) ).type, ).toBe('registered') } const prepared: number[] = [] const reserve = (record: (typeof records)[number]) => Transfer.reserveSubsidy(database(), { account: account.address, chainId: snapshot.destinationChain.id, id: record.id, orgId: record.orgId, pendingNonce: 7, async prepare({ nonce }) { prepared.push(nonce) const transaction = await account.signTransaction({ chainId: 8453, data: encodeFunctionData({ abi: erc20Abi, args: [snapshot.recipient as `0x${string}`, 3001n], functionName: 'transfer', }), gas: 100_000n, maxFeePerGas: 1n, maxPriorityFeePerGas: 1n, nonce, to: snapshot.destinationToken.address as `0x${string}`, type: 'eip1559', }) return { account: account.address, amount: '3001', chainId: snapshot.destinationChain.id, hash: keccak256(transaction), nativeAmount: '100', nonce, transaction, } }, subsidyAmount: amount, tokenAddress: snapshot.destinationToken.address, }) const results = await Promise.all(records.map(reserve)) expect(results.map(({ type }) => type).toSorted()).toEqual(['reserved', 'shared']) expect(prepared).toEqual([7]) const owner = results.find((result) => result.type === 'reserved')! const shared = results.find((result) => result.type === 'shared')! expect(shared.transaction).toEqual(owner.transaction) expect(shared.record).toMatchObject({ subsidyAmount: null, subsidyCommitmentAmount: null, subsidyNativeAmount: null, subsidyTransactionHash: owner.transaction.hash, }) expect((await reserve(shared.record)).type).toBe('replayed') expect(prepared).toEqual([7]) for (const record of records) expect( ( await Transfer.complete(database(), { chainId: snapshot.destinationChain.id, destinationAmount: snapshot.destinationAmount!, id: record.id, transactionHashes: [`0x${'dd'.repeat(32)}`, owner.transaction.hash], }) ).type, ).toBe('completed') expect((await RoutesTransfers.listUnreportedSubsidies(database())).map(({ id }) => id)).toEqual( [owner.record.id], ) await RoutesTransfers.markSubsidyReported(database(), owner.record.id, now.toISOString()) expect(await RoutesTransfers.listUnreportedSubsidies(database())).toEqual([]) const mismatched = await Transfer.create( database(), createInput({ orgId: 'org_mismatched', snapshot: { ...snapshot, recipient: `0x${'ff'.repeat(20)}` }, subsidyCommitment, }), ) await Transfer.registerSourceTransactions(database(), { chainId: snapshot.sourceChain.id, id: mismatched.id, providerState: {}, transactionHashes: [`0x${'ee'.repeat(32)}`], }) await expect(reserve(mismatched)).rejects.toBeInstanceOf(Transfer.SubsidyEvidenceError) expect(prepared).toEqual([7]) await database() .kysely.deleteFrom('routes_transfers') .where('id', '=', owner.record.id) .execute() const retained = await Transfer.create( database(), createInput({ orgId: 'org_retained', snapshot, subsidyCommitment }), ) await Transfer.registerSourceTransactions(database(), { chainId: snapshot.sourceChain.id, id: retained.id, providerState: {}, transactionHashes: [`0x${'ee'.repeat(32)}`], }) const reused = await reserve(retained) expect(reused.type).toBe('shared') if (reused.type !== 'shared') throw new Error('Expected the retained subsidy settlement.') expect(reused.transaction).toEqual(owner.transaction) expect(prepared).toEqual([7]) }) test('serializes signer nonces and replays the persisted transaction', async () => { const account = `0x${'11'.repeat(20)}` as const const source = TestApp.databaseFactory() const database = source() const subsidyCommitment = { account, amount: { baseUnits: '3001', currency: 'USD', decimals: 6, formatted: '0.003001' }, chainId: 'eip155:8453', nativeAmount: '100', tokenAddress: `0x${'22'.repeat(20)}`, } as const const records = [ await Transfer.create(database, createInput({ subsidyCommitment })), await Transfer.create(database, createInput({ subsidyCommitment })), ] for (const [index, record] of records.entries()) await Transfer.registerSourceTransactions(database, { chainId: 'eip155:8453', id: record.id, providerState: {}, transactionHashes: [`0x${(index === 0 ? 'aa' : 'bb').repeat(32)}`], }) const inventory: Transfer.reserveSubsidy.PrepareOptions['reservations'][] = [] const reserve = (database: typeof db, id: string) => Transfer.reserveSubsidy(database, { account, chainId: 'eip155:8453', id, orgId: records.find((record) => record.id === id)!.orgId, pendingNonce: 7, prepare: async ({ nonce, reservations }) => { inventory.push(reservations) return { account, amount: '3001', chainId: 'eip155:8453', hash: `0x${String(nonce).padStart(64, '0')}` as const, nativeAmount: '100', nonce, transaction: `0x${String(nonce).padStart(2, '0')}` as const, } }, subsidyAmount: { baseUnits: '3001', currency: 'USD', decimals: 6, formatted: '0.003001', }, tokenAddress: `0x${'22'.repeat(20)}`, }) const databases = [source(), source()] const reserved = await Promise.all( records.map((record, index) => reserve(databases[index]!, record.id)), ) const replayed = await reserve(source(), records[0]!.id) const nonces = reserved.map((result) => result.type === 'reserved' || result.type === 'replayed' ? result.transaction.nonce : undefined, ) expect({ inventory: inventory.slice(0, 2), nonces: nonces.toSorted((left, right) => Number(left) - Number(right)), replayed: replayed.type, replayedSame: (replayed.type === 'reserved' || replayed.type === 'replayed') && replayed.transaction.nonce === nonces[0], }).toMatchInlineSnapshot(` { "inventory": [ { "nativeAmount": 100n, "tokenAmount": 3001n, }, { "nativeAmount": 100n, "tokenAmount": 3001n, }, ], "nonces": [ 7, 8, ], "replayed": "replayed", "replayedSame": true, } `) }) test('does not reserve behind a permanently rejected signer nonce', async () => { const account = `0x${'33'.repeat(20)}` as const const chainId = 'eip155:8453' const records = [ await Transfer.create( db, createInput({ subsidyCommitment: { account, amount: { baseUnits: '3001', currency: 'USD', decimals: 6, formatted: '0.003001' }, chainId, nativeAmount: '0', tokenAddress: `0x${'44'.repeat(20)}`, }, }), ), await Transfer.create( db, createInput({ subsidyCommitment: { account, amount: { baseUnits: '3001', currency: 'USD', decimals: 6, formatted: '0.003001' }, chainId, nativeAmount: '0', tokenAddress: `0x${'44'.repeat(20)}`, }, }), ), ] for (const [index, record] of records.entries()) await Transfer.registerSourceTransactions(db, { chainId, id: record.id, providerState: {}, transactionHashes: [`0x${(index === 0 ? 'cc' : 'dd').repeat(32)}`], }) const reserve = (id: string, prepare: Transfer.reserveSubsidy.Options['prepare']) => Transfer.reserveSubsidy(db, { account, chainId, id, orgId: records.find((record) => record.id === id)!.orgId, pendingNonce: 11, prepare, subsidyAmount: { baseUnits: '3001', currency: 'USD', decimals: 6, formatted: '0.003001', }, tokenAddress: `0x${'44'.repeat(20)}`, }) const first = await reserve(records[0]!.id, async ({ nonce }) => ({ account, amount: '3001', chainId, hash: `0x${String(nonce).padStart(64, '0')}` as const, nonce, transaction: `0x${String(nonce).padStart(2, '0')}` as const, })) if (first.type !== 'reserved') throw new Error('Expected the first nonce reservation.') await RoutesTransferSubsidyNonces.block(db, { account, chainId, reason: 'broadcast_rejected', transferId: records[0]!.id, }) let prepared = false const error = await reserve(records[1]!.id, async () => { prepared = true throw new Error('Blocked signer lane reached transaction preparation.') }).then( () => undefined, (cause: unknown) => cause, ) const cursor = await db.kysely .selectFrom('routes_transfer_subsidy_nonces') .selectAll() .where('account', '=', account) .where('chainId', '=', chainId) .executeTakeFirstOrThrow() expect({ blocked: error instanceof Transfer.SubsidySignerBlockedError, blockedReason: cursor.blockedReason, blockedTransferMatches: cursor.blockedTransferId === records[0]!.id, nextNonce: cursor.nextNonce, prepared, }).toMatchInlineSnapshot(` { "blocked": true, "blockedReason": "broadcast_rejected", "blockedTransferMatches": true, "nextNonce": "12", "prepared": false, } `) }) }) describe('transition', () => { test('applies a guarded status change and appends an event', async () => { const record = await Transfer.create(db, createInput()) vi.setSystemTime(new Date('2026-01-01T00:00:10.000Z')) const result = await Transfer.transition(db, { expectedVersion: 1, id: record.id, status: 'processing', }) expect(result.type).toBe('applied') if (result.type !== 'applied') return expect({ status: result.record.status, updatedAt: result.record.updatedAt, version: result.record.version, }).toEqual({ status: 'processing', updatedAt: '2026-01-01T00:00:10.000Z', version: 2 }) const events = await db.kysely .selectFrom('routes_transfer_events') .select(['status', 'version']) .where('transferId', '=', record.id) .orderBy('version', 'asc') .execute() expect(events).toEqual([ { status: 'awaiting-source', version: 1 }, { status: 'processing', version: 2 }, ]) }) test('competing transitions converge on one version', async () => { const record = await Transfer.create(db, createInput()) const first = await Transfer.transition(db, { expectedVersion: 1, id: record.id, status: 'processing', }) const second = await Transfer.transition(db, { expectedVersion: 1, id: record.id, status: 'expired', }) expect([first.type, second.type]).toEqual(['applied', 'stale']) if (second.type !== 'stale') return expect(second.current.version).toBe(2) }) test('rejects transitions the lifecycle does not allow', async () => { const record = await Transfer.create(db, createInput()) await Transfer.transition(db, { expectedVersion: 1, id: record.id, status: 'expired' }) const result = await Transfer.transition(db, { expectedVersion: 2, id: record.id, status: 'processing', }) expect(result.type).toBe('invalid') }) test('carries a customer-safe status reason', async () => { const record = await Transfer.create(db, createInput()) await Transfer.transition(db, { expectedVersion: 1, id: record.id, status: 'processing' }) const result = await Transfer.transition(db, { expectedVersion: 2, id: record.id, status: 'action-required', statusReason: { code: 'destination_amount_below_minimum', message: 'The verified destination amount did not satisfy the quoted minimum.', }, }) expect(result.type).toBe('applied') if (result.type !== 'applied') return expect(result.record.statusReason).toMatchInlineSnapshot(` { "code": "destination_amount_below_minimum", "message": "The verified destination amount did not satisfy the quoted minimum.", } `) }) test('preserves the reason for snapshot updates and clears it on lifecycle changes', async () => { const record = await Transfer.create(db, createInput()) await Transfer.transition(db, { expectedVersion: 1, id: record.id, status: 'processing' }) await Transfer.transition(db, { expectedVersion: 2, id: record.id, status: 'action-required', statusReason: { code: 'destination_amount_below_minimum', message: 'The verified destination amount did not satisfy the quoted minimum.', }, }) const snapshot = await Transfer.transition(db, { expectedVersion: 3, id: record.id, snapshot: TestRoutes.transferSnapshot({ sourceTransactionHashes: [`0x${'aa'.repeat(32)}`], }), }) expect(snapshot.type).toBe('applied') if (snapshot.type !== 'applied') return expect(snapshot.record.statusReason?.code).toBe('destination_amount_below_minimum') const processing = await Transfer.transition(db, { expectedVersion: 4, id: record.id, status: 'processing', }) expect(processing.type).toBe('applied') if (processing.type !== 'applied') return expect(processing.record.statusReason).toBeNull() }) test('updates the snapshot without a status change', async () => { const record = await Transfer.create(db, createInput()) const result = await Transfer.transition(db, { expectedVersion: 1, id: record.id, snapshot: TestRoutes.transferSnapshot({ sourceTransactionHashes: [`0x${'aa'.repeat(32)}`], }), }) expect(result.type).toBe('applied') if (result.type !== 'applied') return expect({ hashes: result.record.snapshot.sourceTransactionHashes, status: result.record.status, version: result.record.version, }).toEqual({ hashes: [`0x${'aa'.repeat(32)}`], status: 'awaiting-source', version: 2, }) }) test('strips executable actions from replacement snapshots', async () => { const record = await Transfer.create(db, createInput()) const snapshot = { ...TestRoutes.transferSnapshot(), action: { type: 'evm:calls' }, } const result = await Transfer.transition(db, { expectedVersion: 1, id: record.id, snapshot, }) expect(result.type).toBe('applied') if (result.type !== 'applied') return expect('action' in result.record.snapshot).toBe(false) }) test('reports a missing transfer', async () => { const result = await Transfer.transition(db, { expectedVersion: 1, id: 'rtr_000000000000000_000000000000000000000000', status: 'processing', }) expect(result.type).toBe('not_found') }) }) describe('toPublic', () => { test('serializes the snapshot with lifecycle fields and no ownership columns', async () => { const record = await Transfer.create(db, createInput({ projectId: 'prj_test' })) const { id, ...rest } = Transfer.toPublic(record) expect(id).toMatch(/^rtr_/) expect(rest).toMatchInlineSnapshot(` { "createdAt": "2026-01-01T00:00:00.000Z", "destinationAmount": { "baseUnits": "979295", "currency": "USD", "decimals": 6, "formatted": "0.979295", }, "destinationAmountMin": { "baseUnits": "939242", "currency": "USD", "decimals": 6, "formatted": "0.939242", }, "destinationChain": { "addressFormat": "hex", "id": "eip155:4217", "kind": "evm", "name": "Tempo", }, "destinationToken": { "address": "0x20c000000000000000000000b9537d11c60e8b50", "currency": "USD", "decimals": 6, "name": "Bridged USDC (Stargate)", "standard": "TIP-20", "symbol": "USDC.e", "tokenKey": "eip155:4217/erc20:0x20c000000000000000000000b9537d11c60e8b50", "verified": true, }, "fees": [], "method": "transaction", "mode": "exactSource", "provider": { "id": "relay", "name": "Relay", }, "quote": { "expiresAt": "2026-01-01T00:01:00.000Z", "sampledAt": "2026-01-01T00:00:00.000Z", }, "recipient": "0x1111111111111111111111111111111111111111", "sender": "0x2222222222222222222222222222222222222222", "sourceAmount": { "baseUnits": "1000000", "currency": "USD", "decimals": 6, "formatted": "1", }, "sourceChain": { "addressFormat": "hex", "id": "eip155:8453", "kind": "evm", "name": "Base", }, "sourceToken": { "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "currency": "USD", "decimals": 6, "name": "USD Coin", "standard": "ERC-20", "symbol": "USDC", "tokenKey": "eip155:8453/erc20:0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "verified": true, }, "status": "awaiting-source", "subsidize": false, "updatedAt": "2026-01-01T00:00:00.000Z", "version": 1, } `) }) })