import * as core_Provider from '../Provider.js' import * as Provider from './Provider.js' describe('from', () => { test('preserves provider identity and adds the exchange category', () => { const provider = Provider.from({ id: 'example', name: 'Example', async quote() { throw new Provider.RouteUnavailableError() }, }) expect(provider).toMatchObject({ id: 'example', name: 'Example', type: 'exchange', }) }) test('rejects provider ids that are not normalized', () => { expect(() => Provider.from({ id: ' Example ', name: 'Example', async quote() { throw new Provider.RouteUnavailableError() }, }), ).toThrowErrorMatchingInlineSnapshot( `[ExchangeProvider.ProviderConfigurationError: Provider ids must be lowercase and trimmed.]`, ) }) }) describe('is', () => { test('accepts only exchange providers with quote capability', () => { const exchange = Provider.from({ id: 'exchange', name: 'Exchange', async quote() { throw new Provider.RouteUnavailableError() }, }) const incomplete = core_Provider.from({ id: 'incomplete', name: 'Incomplete', type: 'exchange', }) const funding = core_Provider.from({ id: 'funding', name: 'Funding', type: 'funding' }) expect([exchange, incomplete, funding].map(Provider.is)).toEqual([true, false, false]) }) }) describe('failure', () => { const provider = Provider.from({ id: 'example', name: 'Example', async quote() { throw new Provider.RouteUnavailableError() }, }) test('reports the upstream operation and status', () => { expect( Provider.failure( new Provider.ProviderResponseError({ operation: 'check_approval', status: 429 }), { chainId: 4217, operation: 'quote', provider }, ), ).toMatchInlineSnapshot(` { "chainId": 4217, "failure": "rate_limit", "id": "example", "operation": "check_approval", "status": 429, } `) }) test('reports payload failures at the enclosing operation', () => { expect( Provider.failure(new Provider.ProviderPayloadError(), { chainId: 4217, operation: 'finalize', provider, }), ).toMatchInlineSnapshot(` { "chainId": 4217, "failure": "payload", "id": "example", "operation": "finalize", } `) }) test('reports bounded payload validation codes', () => { expect( Provider.failure(new Provider.ProviderPayloadError({ code: 'quote.response.permitData' }), { chainId: 4217, operation: 'quote', provider, }), ).toMatchInlineSnapshot(` { "chainId": 4217, "code": "quote.response.permitData", "failure": "payload", "id": "example", "operation": "quote", } `) }) test('reports the upstream operation for network failures', () => { expect( Provider.failure( new Provider.ProviderNetworkError({ cause: new TypeError('secret network detail'), operation: 'check_approval', }), { chainId: 4217, operation: 'quote', provider }, ), ).toMatchInlineSnapshot(` { "chainId": 4217, "failure": "network", "id": "example", "operation": "check_approval", } `) }) test('ignores failures outside the provider boundary', () => { expect( Provider.failure(new Error('metadata lookup failed'), { chainId: 4217, operation: 'quote', provider, }), ).toBeUndefined() }) }) describe('validateExecution', () => { const account = '0x1111111111111111111111111111111111111111' const destinationToken = '0x20c0000000000000000000000000000000000002' const sourceToken = '0x20c0000000000000000000000000000000000001' const router = '0x2222222222222222222222222222222222222222' test('accepts transfers within exact-source bounds', () => { expect(() => Provider.validateExecution({ account, execution: { destinationAmount: '100', destinationToken, gasUnits: '1', minimumDestinationAmount: '99', mode: 'exactSource', sourceAmount: '50', sourceToken, }, transfers: [ { amount: 50n, from: account, to: router, token: sourceToken }, { amount: 99n, from: router, to: account, token: destinationToken }, ], }), ).not.toThrow() }) test('rejects a different outgoing token', () => { expect(() => Provider.validateExecution({ account, execution: { destinationAmount: '100', destinationToken, gasUnits: '1', minimumDestinationAmount: '99', mode: 'exactSource', sourceAmount: '50', sourceToken, }, transfers: [ { amount: 1n, from: account, to: router, token: destinationToken }, { amount: 50n, from: account, to: router, token: sourceToken }, { amount: 100n, from: router, to: account, token: destinationToken }, ], }), ).toThrow(Provider.ProviderPayloadError) }) test('rejects execution outside exact-destination bounds', () => { expect(() => Provider.validateExecution({ account, execution: { destinationAmount: '100', destinationToken, gasUnits: '1', maximumSourceAmount: '50', mode: 'exactDestination', sourceAmount: '49', sourceToken, }, transfers: [ { amount: 51n, from: account, to: router, token: sourceToken }, { amount: 100n, from: router, to: account, token: destinationToken }, ], }), ).toThrow(Provider.ProviderPayloadError) }) })