tapimo 0.12.0 → 0.13.0
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/App.d.ts +5561 -5026
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +38 -3
- package/dist/App.js.map +1 -1
- package/dist/Scope.d.ts +2 -0
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +17 -0
- package/dist/Scope.js.map +1 -1
- package/dist/admin/App.d.ts +123 -74
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +80 -0
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +54 -0
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/earn-vaults.d.ts +15 -15
- package/dist/admin/apps/earn-vaults.js +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +81 -81
- package/dist/admin/ui.generated.d.ts +1 -1
- package/dist/admin/ui.generated.d.ts.map +1 -1
- package/dist/admin/ui.generated.js +151 -151
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/apps/Zones.d.ts +16 -16
- package/dist/apps/Zones.js +4 -4
- package/dist/apps/data/App.js +18 -18
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/ZoneSelection.d.ts +8 -8
- package/dist/apps/data/ZoneSelection.d.ts.map +1 -1
- package/dist/apps/data/ZoneSelection.js +1 -1
- package/dist/apps/data/ZoneSelection.js.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +588 -584
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +1561 -1239
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/balances.d.ts +26 -26
- package/dist/apps/data/routes/balances.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.js +43 -16
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +44 -44
- package/dist/apps/data/routes/blocks.d.ts.map +1 -1
- package/dist/apps/data/routes/blocks.js +21 -11
- package/dist/apps/data/routes/blocks.js.map +1 -1
- package/dist/apps/data/routes/coingecko.d.ts +3 -3
- package/dist/apps/data/routes/earn.d.ts +18 -18
- package/dist/apps/data/routes/earn.js +13 -13
- package/dist/apps/data/routes/exchanges.d.ts +145 -145
- package/dist/apps/data/routes/fee-amm.d.ts +2 -2
- package/dist/apps/data/routes/receipts.d.ts +155 -55
- package/dist/apps/data/routes/receipts.d.ts.map +1 -1
- package/dist/apps/data/routes/receipts.js +28 -10
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/tokenlist.d.ts +13 -13
- package/dist/apps/data/routes/tokens.d.ts +98 -98
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +51 -20
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.d.ts +7 -2
- package/dist/apps/data/routes/transactions.d.ts.map +1 -1
- package/dist/apps/data/routes/transactions.js +37 -17
- package/dist/apps/data/routes/transactions.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +1 -1
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +18 -12
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/valuation.d.ts +1 -1
- package/dist/apps/data/routes/valuation.d.ts.map +1 -1
- package/dist/apps/data/routes/valuation.js +12 -7
- package/dist/apps/data/routes/valuation.js.map +1 -1
- package/dist/apps/data/routes/verified-tokens.d.ts +3 -3
- package/dist/apps/data/routes/webhooks.d.ts +11 -11
- package/dist/apps/data/routes/zones.d.ts +14 -14
- package/dist/apps/data/routes/zones.js +1 -1
- package/dist/apps/funding/App.d.ts +11 -0
- package/dist/apps/funding/App.d.ts.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.js +16 -11
- package/dist/apps/funding/routes/deposit-addresses.js.map +1 -1
- package/dist/apps/funding/routes/transfers.d.ts +60 -48
- package/dist/apps/funding/routes/transfers.d.ts.map +1 -1
- package/dist/apps/funding/routes/transfers.js +27 -19
- package/dist/apps/funding/routes/transfers.js.map +1 -1
- package/dist/apps/management/App.d.ts +4487 -3963
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +710 -159
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +236 -4
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/faucet.d.ts +6 -6
- package/dist/apps/management/routes/invite-links.d.ts +42 -42
- package/dist/apps/management/routes/members.d.ts +30 -30
- package/dist/apps/management/routes/projects.d.ts +40 -40
- package/dist/apps/management/routes/usage.d.ts +24 -24
- package/dist/apps/management/routes/verified-token-requests.d.ts +1 -1
- package/dist/apps/management/routes/webhooks.d.ts +55 -55
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +12 -1
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +3 -2
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +5 -2
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/fundingCatalog.d.ts +4 -2
- package/dist/db/tables/fundingCatalog.d.ts.map +1 -1
- package/dist/db/tables/fundingCatalog.js +5 -1
- package/dist/db/tables/fundingCatalog.js.map +1 -1
- package/dist/handlers/internal/utils.d.ts.map +1 -1
- package/dist/handlers/internal/utils.js +9 -0
- package/dist/handlers/internal/utils.js.map +1 -1
- package/dist/internal/Auth.d.ts +3 -1
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +6 -3
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/EarnVaults.d.ts +3 -3
- package/dist/internal/EarnVaults.js +3 -3
- package/dist/internal/Fetch.d.ts +23 -0
- package/dist/internal/Fetch.d.ts.map +1 -0
- package/dist/internal/Fetch.js +26 -0
- package/dist/internal/Fetch.js.map +1 -0
- package/dist/internal/Log.d.ts +3 -1
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +16 -3
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +5 -3
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +13 -3
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/Response.d.ts +1 -1
- package/dist/internal/Response.d.ts.map +1 -1
- package/dist/internal/Schema.d.ts +6 -3
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +8 -2
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/Store.d.ts +16 -3
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +82 -16
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/Tidx.d.ts.map +1 -1
- package/dist/internal/Tidx.js +7 -2
- package/dist/internal/Tidx.js.map +1 -1
- package/dist/internal/Timeout.d.ts +36 -0
- package/dist/internal/Timeout.d.ts.map +1 -0
- package/dist/internal/Timeout.js +37 -0
- package/dist/internal/Timeout.js.map +1 -0
- package/dist/internal/Timing.d.ts +9 -0
- package/dist/internal/Timing.d.ts.map +1 -1
- package/dist/internal/Timing.js +7 -0
- package/dist/internal/Timing.js.map +1 -1
- package/dist/internal/WebhookDestination.d.ts.map +1 -1
- package/dist/internal/WebhookDestination.js +3 -0
- package/dist/internal/WebhookDestination.js.map +1 -1
- package/dist/internal/funding/Action.d.ts +9 -0
- package/dist/internal/funding/Action.d.ts.map +1 -1
- package/dist/internal/funding/Action.js +16 -8
- package/dist/internal/funding/Action.js.map +1 -1
- package/dist/internal/funding/Catalog.d.ts +9 -2
- package/dist/internal/funding/Catalog.d.ts.map +1 -1
- package/dist/internal/funding/Catalog.js +19 -8
- package/dist/internal/funding/Catalog.js.map +1 -1
- package/dist/internal/funding/Provider.d.ts +68 -13
- package/dist/internal/funding/Provider.d.ts.map +1 -1
- package/dist/internal/funding/Provider.js +29 -8
- package/dist/internal/funding/Provider.js.map +1 -1
- package/dist/internal/funding/Transfer.d.ts +13 -12
- package/dist/internal/funding/Transfer.d.ts.map +1 -1
- package/dist/internal/funding/Transfer.js +23 -21
- package/dist/internal/funding/Transfer.js.map +1 -1
- package/dist/internal/funding/providers/stargate.d.ts +28 -9
- package/dist/internal/funding/providers/stargate.d.ts.map +1 -1
- package/dist/internal/funding/providers/stargate.js +251 -117
- package/dist/internal/funding/providers/stargate.js.map +1 -1
- package/dist/internal/index.d.ts +1 -0
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +1 -0
- package/dist/internal/index.js.map +1 -1
- package/package.json +2 -2
- package/src/App.test.ts +100 -0
- package/src/App.ts +42 -3
- package/src/Client.test-d.ts +46 -0
- package/src/Scope.test.ts +20 -0
- package/src/Scope.ts +16 -0
- package/src/admin/apps/api-keys.test.ts +75 -0
- package/src/admin/apps/api-keys.ts +64 -0
- package/src/admin/apps/earn-vaults.test.ts +1 -1
- package/src/admin/apps/earn-vaults.ts +1 -1
- package/src/admin/ui/src/lib/api-keys.ts +19 -0
- package/src/admin/ui/src/routes/api-keys.tsx +89 -2
- package/src/admin/ui.generated.ts +189 -151
- package/src/apps/Zones.test.ts +4 -4
- package/src/apps/Zones.ts +4 -4
- package/src/apps/composition.test.ts +1 -1
- package/src/apps/data/App.test.ts +41 -0
- package/src/apps/data/App.ts +18 -18
- package/src/apps/data/ZoneSelection.test.ts +2 -2
- package/src/apps/data/ZoneSelection.ts +8 -8
- package/src/apps/data/routes/activities.test.ts +1526 -12
- package/src/apps/data/routes/activities.ts +1774 -1356
- package/src/apps/data/routes/balances.ts +133 -97
- package/src/apps/data/routes/blocks.test.ts +533 -0
- package/src/apps/data/routes/blocks.ts +35 -16
- package/src/apps/data/routes/earn.test.ts +4 -2
- package/src/apps/data/routes/earn.ts +13 -13
- package/src/apps/data/routes/earn.zone-access.test.ts +6 -6
- package/src/apps/data/routes/receipts.ts +47 -16
- package/src/apps/data/routes/tokens.test.ts +578 -0
- package/src/apps/data/routes/tokens.ts +283 -225
- package/src/apps/data/routes/transactions.ts +68 -29
- package/src/apps/data/routes/transfers.test.ts +421 -0
- package/src/apps/data/routes/transfers.ts +45 -27
- package/src/apps/data/routes/valuation.ts +94 -78
- package/src/apps/data/routes/zones.test.ts +2 -2
- package/src/apps/data/routes/zones.ts +1 -1
- package/src/apps/funding/routes/deposit-addresses.test.ts +25 -3
- package/src/apps/funding/routes/deposit-addresses.ts +17 -12
- package/src/apps/funding/routes/quotes.test.ts +5 -9
- package/src/apps/funding/routes/transfers.test.ts +395 -8
- package/src/apps/funding/routes/transfers.ts +76 -59
- package/src/apps/management/routes/api-keys.test.ts +220 -0
- package/src/apps/management/routes/api-keys.ts +280 -3
- package/src/db/Db.ts +13 -1
- package/src/db/Schema.ts +5 -2
- package/src/db/tables/earnVaults.test.ts +9 -9
- package/src/db/tables/fundingCatalog.test.ts +16 -2
- package/src/db/tables/fundingCatalog.ts +9 -3
- package/src/handlers/internal/utils.test.ts +53 -0
- package/src/handlers/internal/utils.ts +15 -0
- package/src/internal/Auth.ts +12 -4
- package/src/internal/EarnVaults.capabilities.test.ts +2 -2
- package/src/internal/EarnVaults.test.ts +1 -1
- package/src/internal/EarnVaults.ts +3 -3
- package/src/internal/Fetch.test.ts +46 -0
- package/src/internal/Fetch.ts +56 -0
- package/src/internal/Log.test.ts +21 -0
- package/src/internal/Log.ts +20 -5
- package/src/internal/OpenApi.ts +14 -4
- package/src/internal/Response.ts +1 -1
- package/src/internal/Schema.test.ts +2 -0
- package/src/internal/Schema.ts +12 -2
- package/src/internal/Store.test.ts +178 -0
- package/src/internal/Store.ts +104 -18
- package/src/internal/Tidx.test.ts +2 -1
- package/src/internal/Tidx.ts +7 -2
- package/src/internal/Timeout.test.ts +35 -0
- package/src/internal/Timeout.ts +73 -0
- package/src/internal/Timing.ts +16 -0
- package/src/internal/WebhookDestination.ts +3 -0
- package/src/internal/funding/Action.test.ts +41 -1
- package/src/internal/funding/Action.ts +69 -41
- package/src/internal/funding/Catalog.test.ts +34 -0
- package/src/internal/funding/Catalog.ts +28 -11
- package/src/internal/funding/Provider.test.ts +73 -0
- package/src/internal/funding/Provider.ts +82 -28
- package/src/internal/funding/Transfer.ts +133 -110
- package/src/internal/funding/providers/index.test.ts +4 -167
- package/src/internal/funding/providers/relay.test.ts +2 -2
- package/src/internal/funding/providers/stargate.test.ts +163 -0
- package/src/internal/funding/providers/stargate.ts +359 -134
- package/src/internal/index.test.ts +1 -0
- package/src/internal/index.ts +1 -0
|
@@ -16,6 +16,8 @@ import * as Idempotency from '../../../internal/Idempotency.js'
|
|
|
16
16
|
|
|
17
17
|
import * as Relay from '../../../internal/funding/providers/relay.js'
|
|
18
18
|
|
|
19
|
+
import * as Stargate from '../../../internal/funding/providers/stargate.js'
|
|
20
|
+
|
|
19
21
|
import * as TestApp from '../../../../test/App.js'
|
|
20
22
|
|
|
21
23
|
import * as TestFunding from '../../../../test/Funding.js'
|
|
@@ -29,8 +31,14 @@ const executableProviders = [
|
|
|
29
31
|
{
|
|
30
32
|
create: (_sender: string) =>
|
|
31
33
|
Relay.relay(process.env.RELAY_API_KEY ? { apiKey: process.env.RELAY_API_KEY } : {}),
|
|
34
|
+
destinationToken: 'pathusd',
|
|
32
35
|
id: 'relay',
|
|
33
36
|
},
|
|
37
|
+
{
|
|
38
|
+
create: (_sender: string) => Stargate.stargate(),
|
|
39
|
+
destinationToken: 'usdce',
|
|
40
|
+
id: 'stargate',
|
|
41
|
+
},
|
|
34
42
|
] as const
|
|
35
43
|
|
|
36
44
|
beforeAll(() => TestFunding.publish(db))
|
|
@@ -39,6 +47,11 @@ function create(options: TestApp.create.Options = {}) {
|
|
|
39
47
|
return TestApp.create({ ...options, db })
|
|
40
48
|
}
|
|
41
49
|
|
|
50
|
+
type ContractResponse = {
|
|
51
|
+
$ref?: string | undefined
|
|
52
|
+
content?: Record<string, { schema: unknown }> | undefined
|
|
53
|
+
}
|
|
54
|
+
|
|
42
55
|
type JsonSchema = {
|
|
43
56
|
$ref?: string | undefined
|
|
44
57
|
additionalProperties?: boolean | undefined
|
|
@@ -377,6 +390,69 @@ describe('POST /funding/transfers', () => {
|
|
|
377
390
|
expect(row.providerState).toEqual({ requestId: `0x${'ab'.repeat(32)}` })
|
|
378
391
|
})
|
|
379
392
|
|
|
393
|
+
test('creates a transfer with the requested provider', async () => {
|
|
394
|
+
const app = transfersApp({ providers: [provider()] })
|
|
395
|
+
const response = await postTransfer(app, {
|
|
396
|
+
body: { ...createBody, provider: 'relay' },
|
|
397
|
+
idempotencyKey: nextIdempotencyKey(),
|
|
398
|
+
})
|
|
399
|
+
|
|
400
|
+
expect(response.status).toBe(200)
|
|
401
|
+
const body = await TestApp.json(response, Funding.schema.createFundingTransfer.Response)
|
|
402
|
+
expect(body.provider.id).toBe('relay')
|
|
403
|
+
})
|
|
404
|
+
|
|
405
|
+
test('rejects an unsupported provider', async () => {
|
|
406
|
+
const app = transfersApp({ providers: [provider()] })
|
|
407
|
+
const response = await postTransfer(app, {
|
|
408
|
+
body: { ...createBody, provider: 'bridge' },
|
|
409
|
+
idempotencyKey: nextIdempotencyKey(),
|
|
410
|
+
})
|
|
411
|
+
|
|
412
|
+
expect(response.status).toBe(400)
|
|
413
|
+
expect(((await response.json()) as { error: { code: string } }).error.code).toBe('body_invalid')
|
|
414
|
+
})
|
|
415
|
+
|
|
416
|
+
test('preserves a provider-specified native fee token', async () => {
|
|
417
|
+
const app = transfersApp({
|
|
418
|
+
providers: [
|
|
419
|
+
provider(async () => ({
|
|
420
|
+
...providerResponse(),
|
|
421
|
+
fees: [
|
|
422
|
+
{
|
|
423
|
+
amount: '1000000000000000',
|
|
424
|
+
side: 'source',
|
|
425
|
+
token: {
|
|
426
|
+
address: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
|
|
427
|
+
currency: 'ETH',
|
|
428
|
+
decimals: 18,
|
|
429
|
+
name: 'Ether',
|
|
430
|
+
standard: 'native',
|
|
431
|
+
symbol: 'ETH',
|
|
432
|
+
tokenKey: 'eip155:8453/slip44:60',
|
|
433
|
+
verified: true,
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
],
|
|
437
|
+
})),
|
|
438
|
+
],
|
|
439
|
+
})
|
|
440
|
+
const response = await postTransfer(app, {
|
|
441
|
+
body: { ...createBody, destinationToken: 'pathusd', sourceToken: 'usdc' },
|
|
442
|
+
idempotencyKey: nextIdempotencyKey(),
|
|
443
|
+
})
|
|
444
|
+
expect(response.status).toBe(200)
|
|
445
|
+
const body = await TestApp.json(response, Funding.schema.createFundingTransfer.Response)
|
|
446
|
+
|
|
447
|
+
expect(body.fees).toMatchObject([
|
|
448
|
+
{
|
|
449
|
+
amount: { baseUnits: '1000000000000000', formatted: '0.001' },
|
|
450
|
+
side: 'source',
|
|
451
|
+
token: { standard: 'native', symbol: 'ETH' },
|
|
452
|
+
},
|
|
453
|
+
])
|
|
454
|
+
})
|
|
455
|
+
|
|
380
456
|
test('resolves token identifiers through the composed route', async () => {
|
|
381
457
|
const app = transfersApp({ providers: [provider()] })
|
|
382
458
|
const identifiers = [
|
|
@@ -608,7 +684,7 @@ describe.skipIf(!Anvil.available)('POST /funding/transfers (forked localnet)', (
|
|
|
608
684
|
(entry) =>
|
|
609
685
|
entry.route.source.chain.id === `eip155:${base.id}` &&
|
|
610
686
|
entry.route.source.symbol === 'USDC' &&
|
|
611
|
-
entry.route.destination.slug ===
|
|
687
|
+
entry.route.destination.slug === executable.destinationToken,
|
|
612
688
|
)!
|
|
613
689
|
const usdc = route.route.source
|
|
614
690
|
const amount = Value.from('10', usdc.decimals)
|
|
@@ -627,7 +703,12 @@ describe.skipIf(!Anvil.available)('POST /funding/transfers (forked localnet)', (
|
|
|
627
703
|
function createTransfer(idempotencyKey: string) {
|
|
628
704
|
const app = transfersApp({ providers: [executable.create(sender.address)] })
|
|
629
705
|
return postTransfer(app, {
|
|
630
|
-
body: {
|
|
706
|
+
body: {
|
|
707
|
+
...createBody,
|
|
708
|
+
amount: amount.toString(),
|
|
709
|
+
destinationToken: executable.destinationToken,
|
|
710
|
+
sender: sender.address,
|
|
711
|
+
},
|
|
631
712
|
idempotencyKey,
|
|
632
713
|
})
|
|
633
714
|
}
|
|
@@ -647,6 +728,14 @@ describe.skipIf(!Anvil.available)('POST /funding/transfers (forked localnet)', (
|
|
|
647
728
|
expect(transfer.action.type).toBe('evm:calls')
|
|
648
729
|
if (transfer.action.type !== 'evm:calls') return
|
|
649
730
|
expect(transfer.action.calls.length).toBeGreaterThan(0)
|
|
731
|
+
if (executable.id === 'stargate')
|
|
732
|
+
expect(transfer.fees).toMatchObject([
|
|
733
|
+
{
|
|
734
|
+
amount: { baseUnits: BigInt(transfer.action.calls.at(-1)!.value).toString() },
|
|
735
|
+
side: 'source',
|
|
736
|
+
token: { standard: 'native', symbol: 'ETH' },
|
|
737
|
+
},
|
|
738
|
+
])
|
|
650
739
|
|
|
651
740
|
const receipts = []
|
|
652
741
|
for (const call of transfer.action.calls) {
|
|
@@ -756,24 +845,318 @@ describe('POST /funding/transfers/{destination}', () => {
|
|
|
756
845
|
})
|
|
757
846
|
|
|
758
847
|
describe('funding transfers OpenAPI', () => {
|
|
848
|
+
test('publishes generator-ready transfer contracts', async () => {
|
|
849
|
+
const spec = await (await create({ auth: false }).request('/openapi.json')).json()
|
|
850
|
+
const detailPath = Object.keys(spec.paths).find((path) =>
|
|
851
|
+
path.includes('/v1/funding/transfers/{'),
|
|
852
|
+
)!
|
|
853
|
+
const operations = {
|
|
854
|
+
create: spec.paths['/v1/funding/transfers'].post,
|
|
855
|
+
createVault: spec.paths['/v1/funding/transfers/vault'].post,
|
|
856
|
+
createZone: spec.paths['/v1/funding/transfers/zone'].post,
|
|
857
|
+
get: spec.paths[detailPath].get,
|
|
858
|
+
list: spec.paths['/v1/funding/transfers'].get,
|
|
859
|
+
}
|
|
860
|
+
const summarize = (operation: (typeof operations)[keyof typeof operations]) => ({
|
|
861
|
+
errors: Object.fromEntries(
|
|
862
|
+
(Object.entries(operation.responses) as [string, ContractResponse][])
|
|
863
|
+
.filter(([status]) => Number(status) >= 400)
|
|
864
|
+
.map(([status, response]) => [
|
|
865
|
+
status,
|
|
866
|
+
response.$ref ?? response.content?.['application/json']?.schema,
|
|
867
|
+
]),
|
|
868
|
+
),
|
|
869
|
+
operationId: operation.operationId,
|
|
870
|
+
request: operation.requestBody?.content['application/json'].schema,
|
|
871
|
+
response: operation.responses[200]?.content?.['application/json']?.schema,
|
|
872
|
+
})
|
|
873
|
+
|
|
874
|
+
expect({
|
|
875
|
+
components: [
|
|
876
|
+
'CreateFundingTransferRequest',
|
|
877
|
+
'CreateFundingTransferVaultRequest',
|
|
878
|
+
'CreateFundingTransferZoneRequest',
|
|
879
|
+
'CreatedFundingTransfer',
|
|
880
|
+
'FundingAction',
|
|
881
|
+
'FundingActionCall',
|
|
882
|
+
'FundingEvmCallsAction',
|
|
883
|
+
'FundingTransfer',
|
|
884
|
+
'FundingTransferFee',
|
|
885
|
+
'FundingTransferList',
|
|
886
|
+
'FundingTransferQuote',
|
|
887
|
+
'FundingTransferStatusReason',
|
|
888
|
+
].filter((name) => spec.components.schemas[name]),
|
|
889
|
+
formats: {
|
|
890
|
+
createdAt: spec.components.schemas.FundingTransfer.properties.createdAt.format,
|
|
891
|
+
quoteExpiresAt: spec.components.schemas.FundingTransferQuote.properties.expiresAt.format,
|
|
892
|
+
quoteSampledAt: spec.components.schemas.FundingTransferQuote.properties.sampledAt.format,
|
|
893
|
+
updatedAt: spec.components.schemas.FundingTransfer.properties.updatedAt.format,
|
|
894
|
+
},
|
|
895
|
+
models: {
|
|
896
|
+
action: spec.components.schemas.FundingAction.oneOf,
|
|
897
|
+
createdAction: spec.components.schemas.CreatedFundingTransfer.properties.action,
|
|
898
|
+
evmCall: spec.components.schemas.FundingEvmCallsAction.properties.calls.items,
|
|
899
|
+
feeToken: spec.components.schemas.FundingTransferFee.properties.token,
|
|
900
|
+
list: spec.components.schemas.FundingTransferList.properties.data.items,
|
|
901
|
+
quote: spec.components.schemas.FundingTransfer.properties.quote,
|
|
902
|
+
statusReason: spec.components.schemas.FundingTransfer.properties.statusReason,
|
|
903
|
+
},
|
|
904
|
+
operations: {
|
|
905
|
+
create: summarize(operations.create),
|
|
906
|
+
createVault: summarize(operations.createVault),
|
|
907
|
+
createZone: summarize(operations.createZone),
|
|
908
|
+
get: summarize(operations.get),
|
|
909
|
+
list: summarize(operations.list),
|
|
910
|
+
},
|
|
911
|
+
operationErrorCodes: {
|
|
912
|
+
createInvalid:
|
|
913
|
+
spec.components.schemas.ApiKeyMalformedOrBodyInvalidOrIdempotencyKeyRequiredError
|
|
914
|
+
.properties.error.properties.code.enum,
|
|
915
|
+
idempotencyConflict:
|
|
916
|
+
spec.components.schemas.IdempotencyConflictOrIdempotencyInProgressError.properties.error
|
|
917
|
+
.properties.code.enum,
|
|
918
|
+
notImplemented:
|
|
919
|
+
spec.components.schemas.NotImplemented501Error.properties.error.properties.code.enum,
|
|
920
|
+
parametersInvalid:
|
|
921
|
+
spec.components.schemas.ApiKeyMalformedOrParamInvalidError.properties.error.properties
|
|
922
|
+
.code.enum,
|
|
923
|
+
queryInvalid:
|
|
924
|
+
spec.components.schemas.ApiKeyMalformedOrQueryInvalidError.properties.error.properties
|
|
925
|
+
.code.enum,
|
|
926
|
+
quoteNotAvailable:
|
|
927
|
+
spec.components.schemas.QuoteNotAvailableError.properties.error.properties.code.enum,
|
|
928
|
+
transferNotFound:
|
|
929
|
+
spec.components.schemas.FundingTransferNotFoundError.properties.error.properties.code
|
|
930
|
+
.enum,
|
|
931
|
+
},
|
|
932
|
+
}).toMatchInlineSnapshot(`
|
|
933
|
+
{
|
|
934
|
+
"components": [
|
|
935
|
+
"CreateFundingTransferRequest",
|
|
936
|
+
"CreateFundingTransferVaultRequest",
|
|
937
|
+
"CreateFundingTransferZoneRequest",
|
|
938
|
+
"CreatedFundingTransfer",
|
|
939
|
+
"FundingAction",
|
|
940
|
+
"FundingActionCall",
|
|
941
|
+
"FundingEvmCallsAction",
|
|
942
|
+
"FundingTransfer",
|
|
943
|
+
"FundingTransferFee",
|
|
944
|
+
"FundingTransferList",
|
|
945
|
+
"FundingTransferQuote",
|
|
946
|
+
"FundingTransferStatusReason",
|
|
947
|
+
],
|
|
948
|
+
"formats": {
|
|
949
|
+
"createdAt": "date-time",
|
|
950
|
+
"quoteExpiresAt": "date-time",
|
|
951
|
+
"quoteSampledAt": "date-time",
|
|
952
|
+
"updatedAt": "date-time",
|
|
953
|
+
},
|
|
954
|
+
"models": {
|
|
955
|
+
"action": [
|
|
956
|
+
{
|
|
957
|
+
"$ref": "#/components/schemas/FundingEvmCallsAction",
|
|
958
|
+
},
|
|
959
|
+
],
|
|
960
|
+
"createdAction": {
|
|
961
|
+
"$ref": "#/components/schemas/FundingAction",
|
|
962
|
+
},
|
|
963
|
+
"evmCall": {
|
|
964
|
+
"$ref": "#/components/schemas/FundingActionCall",
|
|
965
|
+
},
|
|
966
|
+
"feeToken": {
|
|
967
|
+
"$ref": "#/components/schemas/FundingToken",
|
|
968
|
+
},
|
|
969
|
+
"list": {
|
|
970
|
+
"$ref": "#/components/schemas/FundingTransfer",
|
|
971
|
+
},
|
|
972
|
+
"quote": {
|
|
973
|
+
"$ref": "#/components/schemas/FundingTransferQuote",
|
|
974
|
+
},
|
|
975
|
+
"statusReason": {
|
|
976
|
+
"$ref": "#/components/schemas/FundingTransferStatusReason",
|
|
977
|
+
},
|
|
978
|
+
},
|
|
979
|
+
"operationErrorCodes": {
|
|
980
|
+
"createInvalid": [
|
|
981
|
+
"api_key_malformed",
|
|
982
|
+
"body_invalid",
|
|
983
|
+
"idempotency_key_required",
|
|
984
|
+
],
|
|
985
|
+
"idempotencyConflict": [
|
|
986
|
+
"idempotency_conflict",
|
|
987
|
+
"idempotency_in_progress",
|
|
988
|
+
],
|
|
989
|
+
"notImplemented": [
|
|
990
|
+
"not_implemented",
|
|
991
|
+
],
|
|
992
|
+
"parametersInvalid": [
|
|
993
|
+
"api_key_malformed",
|
|
994
|
+
"param_invalid",
|
|
995
|
+
],
|
|
996
|
+
"queryInvalid": [
|
|
997
|
+
"api_key_malformed",
|
|
998
|
+
"query_invalid",
|
|
999
|
+
],
|
|
1000
|
+
"quoteNotAvailable": [
|
|
1001
|
+
"quote_not_available",
|
|
1002
|
+
],
|
|
1003
|
+
"transferNotFound": [
|
|
1004
|
+
"funding_transfer_not_found",
|
|
1005
|
+
],
|
|
1006
|
+
},
|
|
1007
|
+
"operations": {
|
|
1008
|
+
"create": {
|
|
1009
|
+
"errors": {
|
|
1010
|
+
"400": {
|
|
1011
|
+
"$ref": "#/components/schemas/ApiKeyMalformedOrBodyInvalidOrIdempotencyKeyRequiredError",
|
|
1012
|
+
},
|
|
1013
|
+
"401": {
|
|
1014
|
+
"$ref": "#/components/schemas/AuthenticationError",
|
|
1015
|
+
},
|
|
1016
|
+
"403": {
|
|
1017
|
+
"$ref": "#/components/schemas/ForbiddenError",
|
|
1018
|
+
},
|
|
1019
|
+
"404": {
|
|
1020
|
+
"$ref": "#/components/schemas/QuoteNotAvailableError",
|
|
1021
|
+
},
|
|
1022
|
+
"409": {
|
|
1023
|
+
"$ref": "#/components/schemas/IdempotencyConflictOrIdempotencyInProgressError",
|
|
1024
|
+
},
|
|
1025
|
+
"429": "#/components/responses/RateLimited",
|
|
1026
|
+
"500": "#/components/responses/InternalError",
|
|
1027
|
+
"502": {
|
|
1028
|
+
"$ref": "#/components/schemas/UpstreamError",
|
|
1029
|
+
},
|
|
1030
|
+
"504": "#/components/responses/RequestTimeout",
|
|
1031
|
+
},
|
|
1032
|
+
"operationId": "createFundingTransfer",
|
|
1033
|
+
"request": {
|
|
1034
|
+
"$ref": "#/components/schemas/CreateFundingTransferRequest",
|
|
1035
|
+
},
|
|
1036
|
+
"response": {
|
|
1037
|
+
"$ref": "#/components/schemas/CreatedFundingTransfer",
|
|
1038
|
+
},
|
|
1039
|
+
},
|
|
1040
|
+
"createVault": {
|
|
1041
|
+
"errors": {
|
|
1042
|
+
"400": {
|
|
1043
|
+
"$ref": "#/components/schemas/ApiKeyMalformedOrBodyInvalidOrIdempotencyKeyRequiredError",
|
|
1044
|
+
},
|
|
1045
|
+
"401": {
|
|
1046
|
+
"$ref": "#/components/schemas/AuthenticationError",
|
|
1047
|
+
},
|
|
1048
|
+
"403": {
|
|
1049
|
+
"$ref": "#/components/schemas/ForbiddenError",
|
|
1050
|
+
},
|
|
1051
|
+
"429": "#/components/responses/RateLimited",
|
|
1052
|
+
"500": "#/components/responses/InternalError",
|
|
1053
|
+
"501": {
|
|
1054
|
+
"$ref": "#/components/schemas/NotImplemented501Error",
|
|
1055
|
+
},
|
|
1056
|
+
"504": "#/components/responses/RequestTimeout",
|
|
1057
|
+
},
|
|
1058
|
+
"operationId": "createFundingTransferVault",
|
|
1059
|
+
"request": {
|
|
1060
|
+
"$ref": "#/components/schemas/CreateFundingTransferVaultRequest",
|
|
1061
|
+
},
|
|
1062
|
+
"response": undefined,
|
|
1063
|
+
},
|
|
1064
|
+
"createZone": {
|
|
1065
|
+
"errors": {
|
|
1066
|
+
"400": {
|
|
1067
|
+
"$ref": "#/components/schemas/ApiKeyMalformedOrBodyInvalidOrIdempotencyKeyRequiredError",
|
|
1068
|
+
},
|
|
1069
|
+
"401": {
|
|
1070
|
+
"$ref": "#/components/schemas/AuthenticationError",
|
|
1071
|
+
},
|
|
1072
|
+
"403": {
|
|
1073
|
+
"$ref": "#/components/schemas/ForbiddenError",
|
|
1074
|
+
},
|
|
1075
|
+
"429": "#/components/responses/RateLimited",
|
|
1076
|
+
"500": "#/components/responses/InternalError",
|
|
1077
|
+
"501": {
|
|
1078
|
+
"$ref": "#/components/schemas/NotImplemented501Error",
|
|
1079
|
+
},
|
|
1080
|
+
"504": "#/components/responses/RequestTimeout",
|
|
1081
|
+
},
|
|
1082
|
+
"operationId": "createFundingTransferZone",
|
|
1083
|
+
"request": {
|
|
1084
|
+
"$ref": "#/components/schemas/CreateFundingTransferZoneRequest",
|
|
1085
|
+
},
|
|
1086
|
+
"response": undefined,
|
|
1087
|
+
},
|
|
1088
|
+
"get": {
|
|
1089
|
+
"errors": {
|
|
1090
|
+
"400": {
|
|
1091
|
+
"$ref": "#/components/schemas/ApiKeyMalformedOrParamInvalidError",
|
|
1092
|
+
},
|
|
1093
|
+
"401": {
|
|
1094
|
+
"$ref": "#/components/schemas/AuthenticationError",
|
|
1095
|
+
},
|
|
1096
|
+
"403": {
|
|
1097
|
+
"$ref": "#/components/schemas/ForbiddenError",
|
|
1098
|
+
},
|
|
1099
|
+
"404": {
|
|
1100
|
+
"$ref": "#/components/schemas/FundingTransferNotFoundError",
|
|
1101
|
+
},
|
|
1102
|
+
"429": "#/components/responses/RateLimited",
|
|
1103
|
+
"500": "#/components/responses/InternalError",
|
|
1104
|
+
"502": {
|
|
1105
|
+
"$ref": "#/components/schemas/UpstreamError",
|
|
1106
|
+
},
|
|
1107
|
+
"504": "#/components/responses/RequestTimeout",
|
|
1108
|
+
},
|
|
1109
|
+
"operationId": "getFundingTransfer",
|
|
1110
|
+
"request": undefined,
|
|
1111
|
+
"response": {
|
|
1112
|
+
"$ref": "#/components/schemas/FundingTransfer",
|
|
1113
|
+
},
|
|
1114
|
+
},
|
|
1115
|
+
"list": {
|
|
1116
|
+
"errors": {
|
|
1117
|
+
"400": {
|
|
1118
|
+
"$ref": "#/components/schemas/ApiKeyMalformedOrQueryInvalidError",
|
|
1119
|
+
},
|
|
1120
|
+
"401": {
|
|
1121
|
+
"$ref": "#/components/schemas/AuthenticationError",
|
|
1122
|
+
},
|
|
1123
|
+
"403": {
|
|
1124
|
+
"$ref": "#/components/schemas/ForbiddenError",
|
|
1125
|
+
},
|
|
1126
|
+
"429": "#/components/responses/RateLimited",
|
|
1127
|
+
"500": "#/components/responses/InternalError",
|
|
1128
|
+
"502": {
|
|
1129
|
+
"$ref": "#/components/schemas/UpstreamError",
|
|
1130
|
+
},
|
|
1131
|
+
"504": "#/components/responses/RequestTimeout",
|
|
1132
|
+
},
|
|
1133
|
+
"operationId": "listFundingTransfers",
|
|
1134
|
+
"request": undefined,
|
|
1135
|
+
"response": {
|
|
1136
|
+
"$ref": "#/components/schemas/FundingTransferList",
|
|
1137
|
+
},
|
|
1138
|
+
},
|
|
1139
|
+
},
|
|
1140
|
+
}
|
|
1141
|
+
`)
|
|
1142
|
+
})
|
|
1143
|
+
|
|
759
1144
|
test('publishes an executable account transfer example', async () => {
|
|
760
1145
|
const app = create({ auth: false })
|
|
761
|
-
type TokenSchema = { examples: string[] }
|
|
762
1146
|
type TransferExample = { destinationToken: { address: string } }
|
|
763
1147
|
type Operation = {
|
|
764
1148
|
requestBody: {
|
|
765
|
-
content: Record<string, { schema:
|
|
1149
|
+
content: Record<string, { schema: JsonSchema }>
|
|
766
1150
|
}
|
|
767
1151
|
responses: Record<string, { content: Record<string, { example: TransferExample }> }>
|
|
768
1152
|
}
|
|
769
|
-
type Spec = { paths: Record<string, { post: Operation }> }
|
|
1153
|
+
type Spec = ComponentSpec & { paths: Record<string, { post: Operation }> }
|
|
770
1154
|
const spec = (await (await app.request('/openapi.json')).json()) as Spec
|
|
771
1155
|
const operation = spec.paths['/v1/funding/transfers']!.post
|
|
1156
|
+
const request = dereference(spec, operation.requestBody.content['application/json']!.schema)
|
|
772
1157
|
|
|
773
1158
|
expect({
|
|
774
|
-
request:
|
|
775
|
-
operation.requestBody.content['application/json']!.schema.properties.destinationToken
|
|
776
|
-
.examples,
|
|
1159
|
+
request: request.properties!['destinationToken']!.examples,
|
|
777
1160
|
response:
|
|
778
1161
|
operation.responses['200']!.content['application/json']!.example.destinationToken.address,
|
|
779
1162
|
}).toEqual({
|
|
@@ -1002,6 +1385,7 @@ describe('funding transfers OpenAPI', () => {
|
|
|
1002
1385
|
"amount",
|
|
1003
1386
|
"destinationToken",
|
|
1004
1387
|
"mode",
|
|
1388
|
+
"provider",
|
|
1005
1389
|
"recipient",
|
|
1006
1390
|
"sender",
|
|
1007
1391
|
"slippageBps",
|
|
@@ -1031,6 +1415,7 @@ describe('funding transfers OpenAPI', () => {
|
|
|
1031
1415
|
"429",
|
|
1032
1416
|
"500",
|
|
1033
1417
|
"502",
|
|
1418
|
+
"504",
|
|
1034
1419
|
],
|
|
1035
1420
|
"vault": {
|
|
1036
1421
|
"additionalProperties": false,
|
|
@@ -1052,6 +1437,7 @@ describe('funding transfers OpenAPI', () => {
|
|
|
1052
1437
|
"429",
|
|
1053
1438
|
"500",
|
|
1054
1439
|
"501",
|
|
1440
|
+
"504",
|
|
1055
1441
|
],
|
|
1056
1442
|
"zone": {
|
|
1057
1443
|
"additionalProperties": false,
|
|
@@ -1075,6 +1461,7 @@ describe('funding transfers OpenAPI', () => {
|
|
|
1075
1461
|
"429",
|
|
1076
1462
|
"500",
|
|
1077
1463
|
"501",
|
|
1464
|
+
"504",
|
|
1078
1465
|
],
|
|
1079
1466
|
}
|
|
1080
1467
|
`)
|
|
@@ -36,15 +36,20 @@ export namespace schema {
|
|
|
36
36
|
.check(z.describe('Query parameters for listing funding transfers.'))
|
|
37
37
|
|
|
38
38
|
/** Paginated funding transfer list. */
|
|
39
|
-
export const Response =
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
export const Response = OpenApi.component(
|
|
40
|
+
z
|
|
41
|
+
.object({
|
|
42
|
+
data: z
|
|
43
|
+
.array(Transfer)
|
|
44
|
+
.check(z.describe('Funding transfers on this page, newest first.')),
|
|
45
|
+
meta: z
|
|
46
|
+
.optional(Schema.CountMeta)
|
|
47
|
+
.check(z.describe('Extra response metadata requested with `include`.')),
|
|
48
|
+
nextCursor: Schema.NextCursor,
|
|
49
|
+
})
|
|
50
|
+
.check(z.describe('A page of funding transfers.')),
|
|
51
|
+
'FundingTransferList',
|
|
52
|
+
)
|
|
48
53
|
}
|
|
49
54
|
|
|
50
55
|
/** Schemas for the createFundingTransfer operation. */
|
|
@@ -82,18 +87,21 @@ export namespace schema {
|
|
|
82
87
|
/** Schemas for the createFundingTransferVault operation. */
|
|
83
88
|
export namespace createFundingTransferVault {
|
|
84
89
|
/** Funding transfer creation request for an Earn vault destination. */
|
|
85
|
-
export const Body =
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
90
|
+
export const Body = OpenApi.component(
|
|
91
|
+
z
|
|
92
|
+
.strictObject({
|
|
93
|
+
...destinationCreateFields,
|
|
94
|
+
vaultAddress: z
|
|
95
|
+
.string()
|
|
96
|
+
.check(
|
|
97
|
+
z.regex(/^0x[0-9a-fA-F]{40}$/),
|
|
98
|
+
z.describe('Tempo Earn vault contract address.'),
|
|
99
|
+
z.meta({ examples: [`0x${'f4'.repeat(20)}`] }),
|
|
100
|
+
),
|
|
101
|
+
})
|
|
102
|
+
.check(z.describe('Vault funding transfer creation request.')),
|
|
103
|
+
'CreateFundingTransferVaultRequest',
|
|
104
|
+
)
|
|
97
105
|
|
|
98
106
|
/** Required headers for vault funding transfer creation. */
|
|
99
107
|
export const Headers = createFundingTransfer.Headers
|
|
@@ -102,32 +110,35 @@ export namespace schema {
|
|
|
102
110
|
/** Schemas for the createFundingTransferZone operation. */
|
|
103
111
|
export namespace createFundingTransferZone {
|
|
104
112
|
/** Funding transfer creation request for a Zone destination. */
|
|
105
|
-
export const Body =
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
113
|
+
export const Body = OpenApi.component(
|
|
114
|
+
z
|
|
115
|
+
.strictObject({
|
|
116
|
+
amount: destinationCreateFields.amount,
|
|
117
|
+
destinationChain: z
|
|
118
|
+
.string()
|
|
119
|
+
.check(
|
|
120
|
+
z.regex(/^eip155:\d+$/),
|
|
121
|
+
z.describe('Configured Zone CAIP-2 id.'),
|
|
122
|
+
z.meta({ examples: ['eip155:1424310003'] }),
|
|
123
|
+
),
|
|
124
|
+
destinationToken: FundingTransfer.schema.CreateRequest.shape.destinationToken,
|
|
125
|
+
mode: destinationCreateFields.mode,
|
|
126
|
+
recipient: destinationCreateFields.recipient,
|
|
127
|
+
recipientFallback: z
|
|
128
|
+
.string()
|
|
129
|
+
.check(
|
|
130
|
+
z.regex(/^0x[0-9a-fA-F]{40}$/),
|
|
131
|
+
z.describe('Public Tempo recipient used if the Zone credit cannot complete.'),
|
|
132
|
+
z.meta({ examples: [`0x${'22'.repeat(20)}`] }),
|
|
133
|
+
),
|
|
134
|
+
sender: destinationCreateFields.sender,
|
|
135
|
+
slippageBps: destinationCreateFields.slippageBps,
|
|
136
|
+
sourceChain: destinationCreateFields.sourceChain,
|
|
137
|
+
sourceToken: destinationCreateFields.sourceToken,
|
|
138
|
+
})
|
|
139
|
+
.check(z.describe('Zone funding transfer creation request.')),
|
|
140
|
+
'CreateFundingTransferZoneRequest',
|
|
141
|
+
)
|
|
131
142
|
|
|
132
143
|
/** Required headers for Zone funding transfer creation. */
|
|
133
144
|
export const Headers = createFundingTransfer.Headers
|
|
@@ -516,6 +527,7 @@ export function transfers() {
|
|
|
516
527
|
method: 'transaction',
|
|
517
528
|
mode: body.mode,
|
|
518
529
|
onAttempt: (attempt) => attempts.push(attempt),
|
|
530
|
+
provider: body.provider,
|
|
519
531
|
providers,
|
|
520
532
|
recipient: body.recipient,
|
|
521
533
|
sender: body.sender,
|
|
@@ -532,8 +544,6 @@ export function transfers() {
|
|
|
532
544
|
}
|
|
533
545
|
|
|
534
546
|
const { candidate, result } = selected
|
|
535
|
-
const feeToken = (side: 'destination' | 'source') =>
|
|
536
|
-
side === 'source' ? candidate.sourceToken : candidate.destinationToken
|
|
537
547
|
const snapshot: FundingTransfer.Snapshot = {
|
|
538
548
|
destinationAmount: Value.tokenAmount({
|
|
539
549
|
baseUnits: result.destinationAmount,
|
|
@@ -547,16 +557,21 @@ export function transfers() {
|
|
|
547
557
|
}),
|
|
548
558
|
destinationChain: candidate.destinationChain,
|
|
549
559
|
destinationToken: candidate.destinationToken,
|
|
550
|
-
fees: result.fees.map((fee) =>
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
+
fees: result.fees.map((fee) => {
|
|
561
|
+
const token =
|
|
562
|
+
fee.token ??
|
|
563
|
+
(fee.side === 'source' ? candidate.sourceToken : candidate.destinationToken)
|
|
564
|
+
return {
|
|
565
|
+
amount: Value.tokenAmount({
|
|
566
|
+
baseUnits: fee.amount,
|
|
567
|
+
currency: token.currency,
|
|
568
|
+
decimals: token.decimals,
|
|
569
|
+
}),
|
|
570
|
+
side: fee.side,
|
|
571
|
+
token,
|
|
572
|
+
type: 'provider',
|
|
573
|
+
}
|
|
574
|
+
}),
|
|
560
575
|
method: 'transaction',
|
|
561
576
|
mode: body.mode,
|
|
562
577
|
provider: candidate.provider,
|
|
@@ -604,6 +619,8 @@ export function transfers() {
|
|
|
604
619
|
await release()
|
|
605
620
|
if (cause instanceof FundingProvider.InvalidAmountError)
|
|
606
621
|
return Response.error(c, { code: 'body_invalid', message: 'Invalid `amount`.', status: 400 }) // prettier-ignore
|
|
622
|
+
if (cause instanceof FundingProvider.UnsupportedProviderError)
|
|
623
|
+
return Response.error(c, { code: 'body_invalid', message: 'Unsupported `provider`.', status: 400 }) // prettier-ignore
|
|
607
624
|
if (cause instanceof FundingProvider.UnsupportedSourceChainError)
|
|
608
625
|
return quoteNotAvailable(c)
|
|
609
626
|
if (cause instanceof FundingProvider.ProviderQuoteError) {
|