import { nanoid } from 'nanoid' import { sql } from 'kysely' import * as TestRoutes from '../../../test/Routes.js' import * as Runtime from '../../../test/runtime.js' import * as Webhooks from '../../internal/Webhooks.js' import * as Viem from '../../internal/Viem.js' import * as Deposit from '../../internal/routes/Deposit.js' import * as DepositAddress from '../../internal/routes/DepositAddress.js' import * as Transfer from '../../internal/routes/Transfer.js' import * as Db from '../Db.js' import * as EnabledBillingSources from './enabledBillingSources.js' import * as Memberships from './memberships.js' import * as Organizations from './organizations.js' import * as RoutesDepositAddresses from './routesDepositAddresses.js' import * as RoutesDeposits from './routesDeposits.js' import * as RoutesIdempotency from './routesIdempotency.js' import * as SponsoredTransactions from './sponsoredTransactions.js' import * as StripeCustomers from './stripeCustomers.js' async function settleRouteRollout(db: Db.Db) { await db.kysely .updateTable('api_key_owner_tombstones') .set({ createdAt: '1970-01-01T00:00:00.000Z' }) .where('id', '=', 'routes-legacy-attempt-drain') .execute() } const create = () => { const db = Db.postgres({ connectionString: Runtime.postgresUrl, schema: `t_${nanoid()}` }) return { ...db, async migrate() { await db.migrate() await settleRouteRollout(db) }, } } /** Persists one prepared production Routes subsidy liability. */ async function subsidyLiability(db: Db.Db, orgId: string) { const snapshot = TestRoutes.depositAddressSnapshot({ provider: { id: 'stargate', name: 'Stargate' }, subsidize: true, }) const address = await DepositAddress.create(db, { deliveryStrategy: 'provider', environment: 'production', orgId, providerOutputToken: snapshot.destinationToken, snapshot, }) const amount = { baseUnits: '250000', currency: 'USD', decimals: 6, formatted: '0.25', } const record = await Deposit.create(db, { providerRequestId: 'request_routes_subsidy', settlementTransaction: `0x${'bb'.repeat(32)}`, settlementTransactionHash: `0x${'cc'.repeat(32)}`, snapshot: TestRoutes.depositSnapshot(address.id), sourceTransactionHash: `0x${'aa'.repeat(32)}`, subsidyAmount: amount, }) const result = await Deposit.transition(db, { expectedVersion: record.version, id: record.id, status: 'settling', subsidyAmount: amount, }) if (result.type !== 'applied') throw new Error('Expected prepared Routes subsidy.') return result.record } /** Persists one prepared outbound subsidy liability. */ async function transferSubsidyLiability(db: Db.Db, orgId: string) { const transfer = await Transfer.create(db, { apiKeyId: 'key_routes_transfer_subsidy', environment: 'production', orgId, snapshot: TestRoutes.transferSnapshot({ subsidize: true }), }) const processing = await Transfer.transition(db, { expectedVersion: transfer.version, id: transfer.id, status: 'processing', }) if (processing.type !== 'applied') throw new Error('Expected processing transfer.') const prepared = await Transfer.transition(db, { expectedVersion: processing.record.version, id: transfer.id, subsidyAmount: { baseUnits: '3001', currency: 'USD', decimals: 6, formatted: '0.003001', }, subsidyTransactionHash: `0x${'dd'.repeat(32)}`, }) if (prepared.type !== 'applied') throw new Error('Expected prepared transfer subsidy.') return prepared.record } /** Redacts nondeterministic row fields (generated nanoid ids, timestamps). */ function redact(record: Organizations.Record) { return { ...record, createdAt: '', id: /^org_[0-9A-Za-z]{24}$/.test(record.id) ? 'org_' : record.id, updatedAt: '', } } describe('create', () => { test('behavior: inserts with a generated id and defaults', async () => { const db = create() await db.migrate() const record = await Organizations.create(db, { name: 'Acme, Inc.' }) expect(record.id).toMatch(/^org_/) expect(redact(record)).toMatchInlineSnapshot(` { "createdAt": "", "createdBy": null, "id": "org_", "name": "Acme, Inc.", "sponsorshipSubsidyDurationDays": null, "sponsorshipSubsidyProjectSpendLimit": null, "updatedAt": "", "userId": null, } `) await db.close() }) test('behavior: preserves an explicit id and createdBy', async () => { const db = create() await db.migrate() const record = await Organizations.create(db, { createdBy: 'admin@tempo.xyz', id: 'org_explicit', name: 'Explicit', }) expect(redact(record)).toMatchInlineSnapshot(` { "createdAt": "", "createdBy": "admin@tempo.xyz", "id": "org_explicit", "name": "Explicit", "sponsorshipSubsidyDurationDays": null, "sponsorshipSubsidyProjectSpendLimit": null, "updatedAt": "", "userId": null, } `) await db.close() }) }) describe('createOwned', () => { test('behavior: creates the organization, owner, and enabled sources atomically', async () => { const db = create() await db.migrate() const record = await Organizations.createOwned(db, { enabledBillingSources: ['stripe'], name: 'Acme, Inc.', userId: 'usr_owner', }) expect( (await Memberships.listByOrg(db, record.id)).map(({ role, userId }) => ({ role, userId })), ).toMatchInlineSnapshot(` [ { "role": "owner", "userId": "usr_owner", }, ] `) expect( (await EnabledBillingSources.listByOrg(db, record.id)).map(({ createdBy, source }) => ({ createdBy, source, })), ).toMatchInlineSnapshot(` [ { "createdBy": "usr_owner", "source": "stripe", }, ] `) await db.close() }) test('behavior: rolls back all rows when initial source insertion fails', async () => { const db = create() await db.migrate() await expect( Organizations.createOwned(db, { enabledBillingSources: ['stripe', 'stripe'], name: 'Acme, Inc.', userId: 'usr_owner', }), ).rejects.toThrow() expect(await Organizations.listByUser(db, 'usr_owner')).toEqual([]) expect(await db.kysely.selectFrom('enabled_billing_sources').selectAll().execute()).toEqual([]) expect( await db.kysely .selectFrom('memberships') .selectAll() .where('userId', '=', 'usr_owner') .execute(), ).toEqual([]) await db.close() }) test('behavior: supports concurrent top-level transactions', async () => { const db = create() await db.migrate() const records = await Promise.all([ Organizations.createOwned(db, { name: 'First', userId: 'usr_first' }), Organizations.createOwned(db, { name: 'Second', userId: 'usr_second' }), ]) expect(records.map(({ name }) => name).sort()).toEqual(['First', 'Second']) await db.close() }) }) describe('get', () => { test('behavior: returns undefined when absent', async () => { const db = create() await db.migrate() expect(await Organizations.get(db, 'org_missing')).toBeUndefined() await db.close() }) }) describe('list', () => { test('behavior: lists newest first', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_a', name: 'A' }) // Distinct createdAt for a deterministic order. await new Promise((resolve) => setTimeout(resolve, 5)) await Organizations.create(db, { id: 'org_b', name: 'B' }) expect((await Organizations.list(db)).map((record) => record.id)).toMatchInlineSnapshot(` [ "org_b", "org_a", ] `) await db.close() }) }) describe('update', () => { test('behavior: renames and bumps updatedAt', async () => { const db = create() await db.migrate() const created = await Organizations.create(db, { id: 'org_1', name: 'Before' }) await new Promise((resolve) => setTimeout(resolve, 5)) const updated = await Organizations.update(db, 'org_1', { name: 'After' }) expect(updated?.name).toMatchInlineSnapshot(`"After"`) expect(updated && updated.updatedAt > created.updatedAt).toBe(true) await db.close() }) test('behavior: returns undefined when absent', async () => { const db = create() await db.migrate() expect(await Organizations.update(db, 'org_missing', { name: 'X' })).toBeUndefined() await db.close() }) }) describe('setSponsorshipSubsidy', () => { test('behavior: replaces and disables the organization policy', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) const enabled = await Organizations.setSponsorshipSubsidy(db, 'org_1', { attributionSpendLimit: '100.00', durationDays: 90, }) expect({ attributionSpendLimit: enabled?.sponsorshipSubsidyProjectSpendLimit, durationDays: enabled?.sponsorshipSubsidyDurationDays, }).toMatchInlineSnapshot(` { "attributionSpendLimit": "100.00", "durationDays": 90, } `) const disabled = await Organizations.setSponsorshipSubsidy(db, 'org_1', { attributionSpendLimit: null, durationDays: null, }) expect({ attributionSpendLimit: disabled?.sponsorshipSubsidyProjectSpendLimit, durationDays: disabled?.sponsorshipSubsidyDurationDays, }).toMatchInlineSnapshot(` { "attributionSpendLimit": null, "durationDays": null, } `) await db.close() }) }) describe('upsert', () => { test('behavior: inserts when absent, defaulting name to the id', async () => { const db = create() await db.migrate() await Organizations.upsert(db, { id: 'key_fallback' }) expect((await Organizations.get(db, 'key_fallback'))?.name).toMatchInlineSnapshot( `"key_fallback"`, ) await db.close() }) test('behavior: leaves an existing row untouched', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'Original' }) await Organizations.upsert(db, { id: 'org_1', name: 'Clobbered' }) expect((await Organizations.get(db, 'org_1'))?.name).toMatchInlineSnapshot(`"Original"`) await db.close() }) }) describe('deleteOrganization', () => { test('behavior: raw deletion commits before a blocked ownerless legacy claim', async () => { const schema = `t_${nanoid()}` const blocker = Db.postgres({ connectionString: Runtime.postgresUrl, schema }) const creator = Db.postgres({ connectionString: Runtime.postgresUrl, schema }) const deleter = Db.postgres({ connectionString: Runtime.postgresUrl, schema }) await blocker.migrate() await settleRouteRollout(blocker) await Organizations.create(blocker, { id: 'org_1', name: 'One' }) const locked = Promise.withResolvers() const release = Promise.withResolvers() const holder = blocker.transaction(async (tx) => { await sql`SELECT pg_advisory_xact_lock(hashtextextended(${'organization:org_1'}, 0))`.execute( tx.kysely, ) locked.resolve() await release.promise }) await locked.promise const deletion = deleter.kysely.deleteFrom('organizations').where('id', '=', 'org_1').execute() await expect( Promise.race([ deletion.then(() => 'deleted' as const), new Promise((resolve) => setTimeout(() => resolve('waiting'), 100)), ]), ).resolves.toBe('waiting') const creation = creator.kysely .insertInto('routes_idempotency_requests') .values({ apiKeyId: 'key_legacy_after_delete', createdAt: '2026-09-04T00:00:00.000Z', expiresAt: '2099-09-04T00:01:00.000Z', irrevocable: false, keyHash: 'key_hash_legacy_after_delete', matchHash: null, operation: null, orgId: null, requestHash: 'request_hash_legacy_after_delete', response: null, status: 'pending', transferId: null, }) .execute() await expect( Promise.race([ creation.then(() => 'created' as const), new Promise((resolve) => setTimeout(() => resolve('waiting'), 100)), ]), ).resolves.toBe('waiting') release.resolve() await holder await expect(deletion).resolves.toHaveLength(1) await expect(creation).rejects.toMatchObject({ code: '23503' }) await Promise.all([blocker.close(), creator.close(), deleter.close()]) }) test('behavior: raw deletion observes a committed ownerless legacy claim', async () => { const schema = `t_${nanoid()}` const claimer = Db.postgres({ connectionString: Runtime.postgresUrl, schema }) const deleter = Db.postgres({ connectionString: Runtime.postgresUrl, schema }) await claimer.migrate() await settleRouteRollout(claimer) await Organizations.create(claimer, { id: 'org_1', name: 'One' }) const inserted = Promise.withResolvers() const release = Promise.withResolvers() const claim = claimer.transaction(async (tx) => { await tx.kysely .insertInto('routes_idempotency_requests') .values({ apiKeyId: 'key_legacy_before_delete', createdAt: '2026-09-04T00:00:00.000Z', expiresAt: '2099-09-04T00:01:00.000Z', irrevocable: false, keyHash: 'key_hash_legacy_before_delete', matchHash: null, operation: null, orgId: null, requestHash: 'request_hash_legacy_before_delete', response: null, status: 'pending', transferId: null, }) .execute() inserted.resolve() await release.promise }) await inserted.promise const deletion = deleter.kysely.deleteFrom('organizations').where('id', '=', 'org_1').execute() await expect( Promise.race([ deletion.then(() => 'deleted' as const), new Promise((resolve) => setTimeout(() => resolve('waiting'), 100)), ]), ).resolves.toBe('waiting') release.resolve() await claim await expect(deletion).rejects.toMatchObject({ code: '23503' }) expect(await Organizations.get(claimer, 'org_1')).toBeDefined() await Promise.all([claimer.close(), deleter.close()]) }) test('behavior: database fence rejects a rolling-worker address after deletion', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) expect(await Organizations.deleteOrganization(db, 'org_1')).toBe(true) const snapshot = TestRoutes.depositAddressSnapshot() await expect( RoutesIdempotency.claim(db, { apiKeyId: 'key_1', irrevocable: false, keyHash: 'key_hash_1', operation: RoutesIdempotency.operations.depositAddress, orgId: 'org_1', requestHash: 'request_hash_1', ttlMs: 60_000, }), ).rejects.toMatchObject({ code: '23503' }) await expect( DepositAddress.create(db, { deliveryStrategy: 'provider', environment: 'production', orgId: 'org_1', providerOutputToken: snapshot.destinationToken, snapshot, }), ).rejects.toMatchObject({ code: '23503' }) await db.close() }) test('behavior: deleted organizations reject expired legacy checkpoint updates', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) await db.kysely .insertInto('routes_idempotency_requests') .values({ apiKeyId: 'key_expired_legacy', createdAt: '2026-09-01T00:00:00.000Z', expiresAt: '2026-09-02T00:00:00.000Z', irrevocable: false, keyHash: 'key_hash_expired_legacy', matchHash: null, operation: null, orgId: null, requestHash: 'request_hash_expired_legacy', response: null, status: 'pending', transferId: null, }) .execute() await expect( db.kysely.deleteFrom('organizations').where('id', '=', 'org_1').executeTakeFirst(), ).resolves.toMatchObject({ numDeletedRows: 1n }) await expect( db.kysely .updateTable('routes_idempotency_requests') .set({ expiresAt: '2099-09-04T00:00:00.000Z', response: '{"requestId":"late"}', status: 'provisioned', }) .where('apiKeyId', '=', 'key_expired_legacy') .execute(), ).rejects.toMatchObject({ code: '23503' }) await db.close() }) test('behavior: database fence blocks an old worker from deleting an active address', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) const snapshot = TestRoutes.depositAddressSnapshot() await DepositAddress.create(db, { deliveryStrategy: 'provider', environment: 'production', orgId: 'org_1', providerOutputToken: snapshot.destinationToken, snapshot, }) await expect( db.kysely.deleteFrom('organizations').where('id', '=', 'org_1').execute(), ).rejects.toMatchObject({ code: '23503' }) expect(await Organizations.deleteOrganization(db, 'org_1')).toBe(true) await db.close() }) test('behavior: database fence preserves deactivated subsidized Relay addresses', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) const snapshot = TestRoutes.depositAddressSnapshot({ subsidize: true }) await DepositAddress.create(db, { deliveryStrategy: 'provider', environment: 'production', orgId: 'org_1', providerOutputToken: snapshot.destinationToken, snapshot, }) await RoutesDepositAddresses.deactivateByOrganization(db, { now: '2026-09-04T00:00:00.000Z', orgId: 'org_1', }) await expect( db.kysely.deleteFrom('organizations').where('id', '=', 'org_1').execute(), ).rejects.toMatchObject({ code: '23503' }) await db.close() }) test('behavior: database fence preserves attributed provider work', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) const claim = await RoutesIdempotency.claim(db, { apiKeyId: 'key_1', irrevocable: false, keyHash: 'key_hash_1', operation: RoutesIdempotency.operations.depositAddress, orgId: 'org_1', requestHash: 'request_hash_1', ttlMs: 60_000, }) if (claim.type !== 'claimed') throw new Error('Expected a claimed request.') await expect( db.kysely.deleteFrom('organizations').where('id', '=', 'org_1').execute(), ).rejects.toMatchObject({ code: '23503' }) await RoutesIdempotency.release(db, { apiKeyId: 'key_1', createdAt: claim.createdAt, keyHash: 'key_hash_1', }) await expect( db.kysely.deleteFrom('organizations').where('id', '=', 'org_1').executeTakeFirst(), ).resolves.toMatchObject({ numDeletedRows: 1n }) await db.close() }) test('behavior: database fence drains live unattributed provider work', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) await db.kysely .insertInto('routes_idempotency_requests') .values({ apiKeyId: 'key_legacy', createdAt: '2026-09-04T00:00:00.000Z', expiresAt: '2099-09-04T00:01:00.000Z', irrevocable: false, keyHash: 'key_hash_legacy', matchHash: null, operation: null, orgId: null, requestHash: 'request_hash_legacy', response: null, status: 'pending', transferId: null, }) .execute() await expect( db.kysely.deleteFrom('organizations').where('id', '=', 'org_1').execute(), ).rejects.toMatchObject({ code: '23503' }) await db.kysely .deleteFrom('routes_idempotency_requests') .where('apiKeyId', '=', 'key_legacy') .where('keyHash', '=', 'key_hash_legacy') .execute() await expect( db.kysely.deleteFrom('organizations').where('id', '=', 'org_1').executeTakeFirst(), ).resolves.toMatchObject({ numDeletedRows: 1n }) await db.close() }) test('behavior: database fence retains expired unattributed provider checkpoints', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) await db.kysely .insertInto('routes_idempotency_requests') .values({ apiKeyId: 'key_legacy_checkpoint', createdAt: '2026-09-01T00:00:00.000Z', expiresAt: '2026-09-02T00:00:00.000Z', irrevocable: false, keyHash: 'key_hash_legacy_checkpoint', matchHash: null, operation: null, orgId: null, requestHash: 'request_hash_legacy_checkpoint', response: '{"requestId":"relay_legacy"}', status: 'provisioned', transferId: null, }) .execute() const drain = Db.migrations.find( (migration) => migration.name === '0264_routes_legacy_checkpoint_drain', ) if (!drain) throw new Error('Expected the legacy checkpoint drain migration.') await drain.up(db.kysely).execute() const expiry = await db.kysely .selectFrom('routes_idempotency_requests') .select('expiresAt') .where('apiKeyId', '=', 'key_legacy_checkpoint') .executeTakeFirstOrThrow() await drain.up(db.kysely).execute() await expect( db.kysely .selectFrom('routes_idempotency_requests') .select('expiresAt') .where('apiKeyId', '=', 'key_legacy_checkpoint') .executeTakeFirstOrThrow(), ).resolves.toEqual(expiry) await expect( db.kysely.deleteFrom('organizations').where('id', '=', 'org_1').execute(), ).rejects.toMatchObject({ code: '23503' }) await expect(Organizations.deleteOrganization(db, 'org_1')).rejects.toThrow( Organizations.IrrevocableDepositAddressError, ) await db.close() }) test('behavior: preserves an org with unreported billable sponsorships', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) await StripeCustomers.create(db, { orgId: 'org_1', stripeCustomerId: 'cus_org_1', }) await EnabledBillingSources.add(db, { createdBy: 'admin@tempo.xyz', orgId: 'org_1', source: 'stripe', }) await SponsoredTransactions.upsert(db, { apiKeyId: 'key_1', billable: true, chainId: 4217, environment: 'production', orgId: 'org_1', projectId: 'prj_1', signPayload: `0x${'bb'.repeat(32)}`, transaction: `0x76${'cc'.repeat(16)}`, transactionHash: `0x${'aa'.repeat(32)}`, }) expect(await Organizations.hasUnreportedMeteredUsage(db, 'org_1')).toBe(true) await expect(Organizations.deleteOrganization(db, 'org_1')).rejects.toThrow( Organizations.UnreportedMeteredUsageError, ) expect(await Organizations.get(db, 'org_1')).toBeDefined() expect(await EnabledBillingSources.isEnabled(db, { orgId: 'org_1', source: 'stripe' })).toBe( true, ) expect(await StripeCustomers.get(db, 'org_1')).toBeDefined() await db.close() }) test('behavior: deletes an org with only failed or non-mainnet sponsorships', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) const failed = await SponsoredTransactions.upsert(db, { apiKeyId: 'key_1', billable: true, chainId: Viem.chainId.mainnet, environment: 'production', orgId: 'org_1', projectId: 'prj_1', signPayload: `0x${'bb'.repeat(32)}`, transaction: `0x76${'cc'.repeat(16)}`, transactionHash: `0x${'aa'.repeat(32)}`, }) await SponsoredTransactions.fail(db, failed.id, '2026-01-01T00:00:00.000Z') const testnet = await SponsoredTransactions.upsert(db, { apiKeyId: 'key_1', billable: true, chainId: Viem.chainId.testnet, environment: 'production', orgId: 'org_1', projectId: 'prj_1', signPayload: `0x${'dd'.repeat(32)}`, transaction: `0x76${'ee'.repeat(16)}`, transactionHash: `0x${'ff'.repeat(32)}`, }) await SponsoredTransactions.finalize(db, testnet.id, { feeAmount: '100', finalizedAt: '2026-01-01T00:00:00.000Z', }) expect(await Organizations.hasUnreportedMeteredUsage(db, 'org_1')).toBe(false) expect(await Organizations.deleteOrganization(db, 'org_1')).toBe(true) await db.close() }) test('behavior: preserves an org with unsettled Routes subsidy spend', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) const subsidy = await subsidyLiability(db, 'org_1') expect(await Organizations.hasUnreportedMeteredUsage(db, 'org_1')).toBe(true) await expect(Organizations.deleteOrganization(db, 'org_1')).rejects.toThrow( Organizations.UnreportedMeteredUsageError, ) expect(await Organizations.get(db, 'org_1')).toBeDefined() const completed = await Deposit.transition(db, { expectedVersion: subsidy.version, id: subsidy.id, status: 'completed', }) if (completed.type !== 'applied') throw new Error('Expected completed Routes subsidy.') await RoutesDeposits.markSubsidyReported(db, completed.record.id, new Date().toISOString()) expect(await Organizations.hasUnreportedMeteredUsage(db, 'org_1')).toBe(false) expect(await Organizations.deleteOrganization(db, 'org_1')).toBe(true) await db.close() }) test('behavior: preserves an org with an irrevocable subsidized Relay address', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) const snapshot = TestRoutes.depositAddressSnapshot({ subsidize: true }) await DepositAddress.create(db, { deliveryStrategy: 'provider', environment: 'production', orgId: 'org_1', providerOutputToken: snapshot.destinationToken, snapshot, }) expect(await Organizations.hasUnreportedMeteredUsage(db, 'org_1')).toBe(false) await expect(Organizations.deleteOrganization(db, 'org_1')).rejects.toThrow( Organizations.IrrevocableDepositAddressError, ) expect(await Organizations.get(db, 'org_1')).toBeDefined() await db.close() }) test('behavior: deactivates unsubsidized addresses when deleting an organization', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) const snapshot = TestRoutes.depositAddressSnapshot() const address = await DepositAddress.create(db, { deliveryStrategy: 'provider', environment: 'production', orgId: 'org_1', providerOutputToken: snapshot.destinationToken, snapshot, }) const claim = await RoutesDepositAddresses.claim(db, { id: address.id, leaseUntil: '2027-01-01T00:01:00.000Z', now: '2027-01-01T00:00:00.000Z', }) if (!claim) throw new Error('Expected a claimed address.') expect(await Organizations.deleteOrganization(db, 'org_1')).toBe(true) expect(await RoutesDepositAddresses.get(db, address.id)).toMatchObject({ pollLeaseVersion: claim.pollLeaseVersion + 1, status: 'deactivated', }) expect( await RoutesDepositAddresses.checkpointPoll(db, { id: address.id, pollLeaseVersion: claim.pollLeaseVersion, providerState: { stale: true }, }), ).toBeUndefined() expect( await RoutesDepositAddresses.listActiveSources(db, { providerId: address.providerId, sourceChainId: address.sourceChainId, sourceTokenKey: address.sourceTokenKey, }), ).toEqual([]) await db.close() }) test('behavior: preserves unresolved subsidy transactions until a revert is verified', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) const subsidy = await subsidyLiability(db, 'org_1') const unavailable = await Deposit.transition(db, { expectedVersion: subsidy.version, id: subsidy.id, status: 'action-required', }) if (unavailable.type !== 'applied') throw new Error('Expected unresolved Routes subsidy.') expect(await Organizations.hasUnreportedMeteredUsage(db, 'org_1')).toBe(true) await expect(Organizations.deleteOrganization(db, 'org_1')).rejects.toThrow( Organizations.UnreportedMeteredUsageError, ) const reverted = await Deposit.transition(db, { expectedVersion: unavailable.record.version, id: unavailable.record.id, status: 'action-required', subsidyAmount: { baseUnits: '0', currency: 'USD', decimals: 6, formatted: '0' }, tempoGasPaid: '100', }) if (reverted.type !== 'applied') throw new Error('Expected reverted Routes subsidy.') expect(await Organizations.hasUnreportedMeteredUsage(db, 'org_1')).toBe(false) expect(await Organizations.deleteOrganization(db, 'org_1')).toBe(true) await db.close() }) test('behavior: preserves an org with an outbound subsidy liability', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) const subsidy = await transferSubsidyLiability(db, 'org_1') expect(await Organizations.hasUnreportedMeteredUsage(db, 'org_1')).toBe(true) await expect(Organizations.deleteOrganization(db, 'org_1')).rejects.toThrow( Organizations.UnreportedMeteredUsageError, ) const reverted = await Transfer.transition(db, { expectedVersion: subsidy.version, id: subsidy.id, status: 'action-required', subsidyAmount: { baseUnits: '0', currency: 'USD', decimals: 6, formatted: '0' }, }) if (reverted.type !== 'applied') throw new Error('Expected reverted transfer subsidy.') expect(await Organizations.hasUnreportedMeteredUsage(db, 'org_1')).toBe(false) expect(await Organizations.deleteOrganization(db, 'org_1')).toBe(true) await db.close() }) test('behavior: serializes deletion with subsidy liability persistence', async () => { const schema = `t_${nanoid()}` const db = Db.postgres({ connectionString: Runtime.postgresUrl, schema }) const concurrent = Db.postgres({ connectionString: Runtime.postgresUrl, schema }) await db.migrate() await settleRouteRollout(db) await Organizations.create(db, { id: 'org_1', name: 'One' }) const subsidy = await subsidyLiability(db, 'org_1') await RoutesDeposits.markSubsidyReported(db, subsidy.id, new Date().toISOString()) const locked = Promise.withResolvers() const release = Promise.withResolvers() const settlement = RoutesDeposits.withSubsidySettlement(db, { fn: async (tx) => { locked.resolve() await release.promise await tx.kysely .updateTable('routes_deposits') .set({ subsidyMeterReportedAt: null }) .where('id', '=', subsidy.id) .execute() }, orgId: 'org_1', }) await locked.promise const deletion = Organizations.deleteOrganization(concurrent, 'org_1') expect( await Promise.race([ deletion.then( () => 'deleted', () => 'rejected', ), new Promise((resolve) => setTimeout(() => resolve('waiting'), 100)), ]), ).toBe('waiting') release.resolve() await settlement await expect(deletion).rejects.toThrow(Organizations.UnreportedMeteredUsageError) expect(await Organizations.get(db, 'org_1')).toBeDefined() await concurrent.close() await db.close() }) test('behavior: serializes deletion with outbound commitment creation', async () => { const schema = `t_${nanoid()}` const db = Db.postgres({ connectionString: Runtime.postgresUrl, schema }) const concurrent = Db.postgres({ connectionString: Runtime.postgresUrl, schema }) await db.migrate() await settleRouteRollout(db) await Organizations.create(db, { id: 'org_1', name: 'One' }) const locked = Promise.withResolvers() const release = Promise.withResolvers() const commitment = db.transaction((tx) => Transfer.reserveSubsidyCommitmentIn( tx, { apiKeyId: 'key_routes_transfer_subsidy', environment: 'production', orgId: 'org_1', snapshot: TestRoutes.transferSnapshot({ quote: { expiresAt: '2099-01-01T00:01:00.000Z', sampledAt: '2099-01-01T00:00:00.000Z', }, }), }, { account: `0x${'55'.repeat(20)}`, chainId: 'eip155:8453', async check() { locked.resolve() await release.promise return { nativeAmount: '100' } }, subsidyCommitmentAmount: { baseUnits: '3001', currency: 'USD', decimals: 6, formatted: '0.003001', }, tokenAddress: `0x${'66'.repeat(20)}`, }, ), ) await locked.promise const deletion = Organizations.deleteOrganization(concurrent, 'org_1') expect( await Promise.race([ deletion.then( () => 'deleted', () => 'rejected', ), new Promise((resolve) => setTimeout(() => resolve('waiting'), 100)), ]), ).toBe('waiting') release.resolve() await commitment await expect(deletion).rejects.toThrow(Organizations.UnreportedMeteredUsageError) expect(await Organizations.get(db, 'org_1')).toBeDefined() await concurrent.close() await db.close() }) test('behavior: preserves an org with a recoverable failed fill intent', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) const failed = await SponsoredTransactions.upsert(db, { apiKeyId: 'key_1', billable: true, chainId: Viem.chainId.mainnet, environment: 'production', orgId: 'org_1', projectId: 'prj_1', signPayload: `0x${'bb'.repeat(32)}`, transaction: `0x76${'cc'.repeat(16)}`, }) await SponsoredTransactions.fail(db, failed.id, new Date().toISOString()) expect(await Organizations.hasUnreportedMeteredUsage(db, 'org_1')).toBe(true) await expect(Organizations.deleteOrganization(db, 'org_1')).rejects.toThrow( Organizations.UnreportedMeteredUsageError, ) expect(await Organizations.get(db, 'org_1')).toBeDefined() await db.close() }) test('behavior: deletes an org with only expired failed fill intents', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) const failed = await SponsoredTransactions.upsert(db, { apiKeyId: 'key_1', billable: true, chainId: Viem.chainId.mainnet, environment: 'production', orgId: 'org_1', projectId: 'prj_1', signPayload: `0x${'bb'.repeat(32)}`, transaction: `0x76${'cc'.repeat(16)}`, }) await SponsoredTransactions.fail( db, failed.id, new Date(Date.now() - SponsoredTransactions.failedIntentRecoveryTtlMs - 1).toISOString(), ) expect(await Organizations.hasUnreportedMeteredUsage(db, 'org_1')).toBe(false) expect(await Organizations.deleteOrganization(db, 'org_1')).toBe(true) await db.close() }) test('behavior: deletes enabled billing sources', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) await Organizations.create(db, { id: 'org_2', name: 'Two' }) await EnabledBillingSources.add(db, { createdBy: 'admin@tempo.xyz', orgId: 'org_1', source: 'stripe', }) await EnabledBillingSources.add(db, { createdBy: 'admin@tempo.xyz', orgId: 'org_1', source: 'tempo', }) await EnabledBillingSources.add(db, { createdBy: 'admin@tempo.xyz', orgId: 'org_2', source: 'stripe', }) expect(await Organizations.deleteOrganization(db, 'org_1')).toBe(true) expect(await EnabledBillingSources.listByOrg(db, 'org_1')).toEqual([]) expect((await EnabledBillingSources.listByOrg(db, 'org_2')).map((record) => record.source)) .toMatchInlineSnapshot(` [ "stripe", ] `) await db.close() }) test('behavior: deletes api-key-owned webhook subscriptions', async () => { const db = create() await db.migrate() await Organizations.create(db, { id: 'org_1', name: 'One' }) await Organizations.create(db, { id: 'org_2', name: 'Two' }) const deletedOrg = { orgId: 'org_1', type: 'api_key' } as const const keptOrg = { orgId: 'org_2', type: 'api_key' } as const const keptMpp = { payer: 'did:pkh:eip155:1:0xabc', type: 'mpp' } as const await Webhooks.createSubscription(db, subscription(deletedOrg)) const keptApiKey = await Webhooks.createSubscription(db, subscription(keptOrg)) const keptMppSubscription = await Webhooks.createSubscription(db, subscription(keptMpp)) expect(await Organizations.deleteOrganization(db, 'org_1')).toBe(true) expect(await Webhooks.listSubscriptions(db, deletedOrg)).toEqual([]) const active = await Webhooks.listActiveForChain(db, { chainId: 4217, eventTypes: ['token:transfer'], }) expect(active.map(({ subscription }) => subscription.id).sort()).toEqual( [keptApiKey.id, keptMppSubscription.id].sort(), ) await db.close() }) }) function subscription(owner: Webhooks.Owner): Webhooks.CreateInput { return { chainId: 4217, destination: { type: 'url', url: 'https://hooks.example.com/endpoint' }, eventType: 'token:transfer', owner, } }