tapimo 0.5.2 → 0.6.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 +13987 -5755
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js.map +1 -1
- package/dist/admin/App.d.ts +910 -412
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/App.js +4 -0
- package/dist/admin/App.js.map +1 -1
- package/dist/admin/apps/early-access.d.ts +148 -0
- package/dist/admin/apps/early-access.d.ts.map +1 -0
- package/dist/admin/apps/early-access.js +133 -0
- package/dist/admin/apps/early-access.js.map +1 -0
- package/dist/admin/apps/verified-tokens.d.ts +643 -118
- package/dist/admin/apps/verified-tokens.d.ts.map +1 -1
- package/dist/admin/apps/verified-tokens.js +214 -1
- package/dist/admin/apps/verified-tokens.js.map +1 -1
- 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 +45 -33
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/apps/data/App.d.ts +3733 -2428
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +11 -6
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/FundingQuoteProviders.d.ts +34 -1
- package/dist/apps/data/FundingQuoteProviders.d.ts.map +1 -1
- package/dist/apps/data/FundingQuoteProviders.js +193 -2
- package/dist/apps/data/FundingQuoteProviders.js.map +1 -1
- package/dist/apps/data/FxOracle.d.ts +71 -0
- package/dist/apps/data/FxOracle.d.ts.map +1 -0
- package/dist/apps/data/FxOracle.js +97 -0
- package/dist/apps/data/FxOracle.js.map +1 -0
- package/dist/apps/data/index.d.ts +1 -0
- package/dist/apps/data/index.d.ts.map +1 -1
- package/dist/apps/data/index.js +1 -0
- package/dist/apps/data/index.js.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +3575 -1358
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +230 -88
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +963 -342
- package/dist/apps/data/routes/addresses.d.ts.map +1 -1
- package/dist/apps/data/routes/addresses.js +11 -9
- package/dist/apps/data/routes/addresses.js.map +1 -1
- package/dist/apps/data/routes/balances.d.ts +108 -57
- package/dist/apps/data/routes/balances.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.js +88 -45
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/coingecko.d.ts +169 -169
- package/dist/apps/data/routes/exchanges.d.ts +952 -201
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
- package/dist/apps/data/routes/exchanges.js +518 -76
- package/dist/apps/data/routes/exchanges.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts +24 -24
- package/dist/apps/data/routes/funding.d.ts +8 -2
- package/dist/apps/data/routes/funding.d.ts.map +1 -1
- package/dist/apps/data/routes/funding.js +32 -6
- package/dist/apps/data/routes/funding.js.map +1 -1
- package/dist/apps/data/routes/indexer.d.ts +5 -5
- package/dist/apps/data/routes/receipts.d.ts +392 -315
- package/dist/apps/data/routes/receipts.d.ts.map +1 -1
- package/dist/apps/data/routes/receipts.js +152 -77
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/tokens.d.ts +166 -173
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +14 -12
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.d.ts +277 -536
- package/dist/apps/data/routes/transactions.d.ts.map +1 -1
- package/dist/apps/data/routes/transactions.js +96 -77
- package/dist/apps/data/routes/transactions.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +82 -17
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +70 -13
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/valuation.d.ts +307 -0
- package/dist/apps/data/routes/valuation.d.ts.map +1 -0
- package/dist/apps/data/routes/valuation.js +292 -0
- package/dist/apps/data/routes/valuation.js.map +1 -0
- package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/verified-tokens.js +7 -5
- package/dist/apps/data/routes/verified-tokens.js.map +1 -1
- package/dist/apps/data/routes/webhooks.d.ts +459 -479
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +124 -25
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/index.d.ts +1 -1
- package/dist/apps/index.d.ts.map +1 -1
- package/dist/apps/index.js +1 -1
- package/dist/apps/index.js.map +1 -1
- package/dist/apps/management/App.d.ts +8606 -1681
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/App.js +12 -1
- package/dist/apps/management/App.js.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +23 -0
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +5 -3
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +88 -48
- package/dist/apps/management/routes/billing.d.ts.map +1 -1
- package/dist/apps/management/routes/billing.js +10 -2
- package/dist/apps/management/routes/billing.js.map +1 -1
- package/dist/apps/management/routes/faucet.d.ts +218 -0
- package/dist/apps/management/routes/faucet.d.ts.map +1 -0
- package/dist/apps/management/routes/faucet.js +139 -0
- package/dist/apps/management/routes/faucet.js.map +1 -0
- package/dist/apps/management/routes/invitations.d.ts +121 -121
- package/dist/apps/management/routes/invitations.d.ts.map +1 -1
- package/dist/apps/management/routes/invitations.js +3 -0
- package/dist/apps/management/routes/invitations.js.map +1 -1
- package/dist/apps/management/routes/invite-links.d.ts +197 -168
- package/dist/apps/management/routes/invite-links.d.ts.map +1 -1
- package/dist/apps/management/routes/invite-links.js +26 -1
- package/dist/apps/management/routes/invite-links.js.map +1 -1
- package/dist/apps/management/routes/me.d.ts +2 -0
- package/dist/apps/management/routes/me.d.ts.map +1 -1
- package/dist/apps/management/routes/me.js +4 -0
- package/dist/apps/management/routes/me.js.map +1 -1
- package/dist/apps/management/routes/members.d.ts +49 -49
- package/dist/apps/management/routes/orgs.d.ts +91 -91
- package/dist/apps/management/routes/projects.d.ts +115 -115
- package/dist/apps/management/routes/usage.d.ts +35 -32
- package/dist/apps/management/routes/usage.d.ts.map +1 -1
- package/dist/apps/management/routes/usage.js +4 -0
- package/dist/apps/management/routes/usage.js.map +1 -1
- package/dist/apps/management/routes/verified-token-requests.d.ts +697 -0
- package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -0
- package/dist/apps/management/routes/verified-token-requests.js +271 -0
- package/dist/apps/management/routes/verified-token-requests.js.map +1 -0
- package/dist/apps/management/routes/webhooks.d.ts +6977 -0
- package/dist/apps/management/routes/webhooks.d.ts.map +1 -0
- package/dist/apps/management/routes/webhooks.js +573 -0
- package/dist/apps/management/routes/webhooks.js.map +1 -0
- package/dist/apps/mcp.d.ts +9 -2
- package/dist/apps/mcp.d.ts.map +1 -1
- package/dist/apps/mcp.js +9 -4
- package/dist/apps/mcp.js.map +1 -1
- package/dist/cli/Cli.d.ts.map +1 -1
- package/dist/cli/Cli.js +7 -2
- package/dist/cli/Cli.js.map +1 -1
- package/dist/db/Db.d.ts +4 -0
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +83 -0
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +41 -0
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +45 -0
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/earlyAccess.d.ts +50 -0
- package/dist/db/tables/earlyAccess.d.ts.map +1 -0
- package/dist/db/tables/earlyAccess.js +63 -0
- package/dist/db/tables/earlyAccess.js.map +1 -0
- package/dist/db/tables/invitations.d.ts +12 -1
- package/dist/db/tables/invitations.d.ts.map +1 -1
- package/dist/db/tables/invitations.js +23 -0
- package/dist/db/tables/invitations.js.map +1 -1
- package/dist/db/tables/inviteLinks.d.ts +10 -2
- package/dist/db/tables/inviteLinks.d.ts.map +1 -1
- package/dist/db/tables/inviteLinks.js +10 -1
- package/dist/db/tables/inviteLinks.js.map +1 -1
- package/dist/db/tables/sponsoredTransactions.d.ts +2 -0
- package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
- package/dist/db/tables/sponsoredTransactions.js +2 -0
- package/dist/db/tables/sponsoredTransactions.js.map +1 -1
- package/dist/db/tables/verifiedTokenRequests.d.ts +94 -0
- package/dist/db/tables/verifiedTokenRequests.d.ts.map +1 -0
- package/dist/db/tables/verifiedTokenRequests.js +120 -0
- package/dist/db/tables/verifiedTokenRequests.js.map +1 -0
- package/dist/db/tables/webhookSubscriptions.d.ts +14 -0
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
- package/dist/db/tables/webhookSubscriptions.js +16 -0
- package/dist/db/tables/webhookSubscriptions.js.map +1 -1
- package/dist/internal/Auth.d.ts +43 -2
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +60 -45
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/FundingQuotes.d.ts +69 -15
- package/dist/internal/FundingQuotes.d.ts.map +1 -1
- package/dist/internal/FundingQuotes.js +74 -25
- package/dist/internal/FundingQuotes.js.map +1 -1
- package/dist/internal/Log.d.ts +19 -1
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +2 -0
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/MetricSink.d.ts.map +1 -1
- package/dist/internal/MetricSink.js +9 -0
- package/dist/internal/MetricSink.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +2 -2
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +3 -0
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/Schema.d.ts +14 -5
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +23 -5
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/Value.d.ts +18 -0
- package/dist/internal/Value.d.ts.map +1 -1
- package/dist/internal/Value.js +11 -1
- package/dist/internal/Value.js.map +1 -1
- package/dist/internal/VerifiedTokens.d.ts.map +1 -1
- package/dist/internal/VerifiedTokens.js +10 -1
- package/dist/internal/VerifiedTokens.js.map +1 -1
- package/dist/internal/Viem.d.ts +1 -1
- package/dist/internal/Webhooks.d.ts +24 -3
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +34 -8
- package/dist/internal/Webhooks.js.map +1 -1
- package/package.json +2 -2
- package/src/App.ts +9 -1
- package/src/Client.test-d.ts +638 -6
- package/src/admin/App.ts +4 -0
- package/src/admin/apps/early-access.test.ts +125 -0
- package/src/admin/apps/early-access.ts +175 -0
- package/src/admin/apps/verified-tokens.test.ts +201 -0
- package/src/admin/apps/verified-tokens.ts +532 -286
- package/src/admin/ui/plugin.ts +2 -1
- package/src/admin/ui/src/lib/early-access.ts +63 -0
- package/src/admin/ui/src/lib/verified-tokens.ts +79 -0
- package/src/admin/ui/src/routeTree.gen.ts +33 -2
- package/src/admin/ui/src/routes/__root.tsx +2 -1
- package/src/admin/ui/src/routes/early-access.tsx +157 -0
- package/src/admin/ui/src/routes/verified-tokens.tsx +230 -19
- package/src/admin/ui.generated.ts +48 -33
- package/src/apps/data/App.ts +22 -14
- package/src/apps/data/FundingQuoteProviders.test.ts +298 -0
- package/src/apps/data/FundingQuoteProviders.ts +257 -4
- package/src/apps/data/FxOracle.test.ts +118 -0
- package/src/apps/data/FxOracle.ts +153 -0
- package/src/apps/data/index.ts +1 -0
- package/src/apps/data/routes/activities.test.ts +173 -3
- package/src/apps/data/routes/activities.ts +403 -132
- package/src/apps/data/routes/addresses.ts +19 -9
- package/src/apps/data/routes/balances.test.ts +144 -11
- package/src/apps/data/routes/balances.ts +140 -51
- package/src/apps/data/routes/exchanges.test.ts +540 -9
- package/src/apps/data/routes/exchanges.ts +690 -103
- package/src/apps/data/routes/funding.test.ts +84 -0
- package/src/apps/data/routes/funding.ts +38 -6
- package/src/apps/data/routes/receipts.test.ts +125 -23
- package/src/apps/data/routes/receipts.ts +205 -100
- package/src/apps/data/routes/tokens.test.ts +43 -0
- package/src/apps/data/routes/tokens.ts +27 -12
- package/src/apps/data/routes/transactions.test.ts +72 -19
- package/src/apps/data/routes/transactions.ts +162 -92
- package/src/apps/data/routes/transfers.test.ts +146 -4
- package/src/apps/data/routes/transfers.ts +91 -13
- package/src/apps/data/routes/valuation.test.ts +422 -0
- package/src/apps/data/routes/valuation.ts +423 -0
- package/src/apps/data/routes/verified-tokens.ts +14 -2
- package/src/apps/data/routes/webhooks.test.ts +56 -8
- package/src/apps/data/routes/webhooks.ts +144 -27
- package/src/apps/index.ts +1 -1
- package/src/apps/management/App.ts +13 -0
- package/src/apps/management/routes/api-keys.test.ts +87 -0
- package/src/apps/management/routes/api-keys.ts +4 -3
- package/src/apps/management/routes/billing.test.ts +112 -1
- package/src/apps/management/routes/billing.ts +7 -2
- package/src/apps/management/routes/faucet.test.ts +79 -0
- package/src/apps/management/routes/faucet.ts +185 -0
- package/src/apps/management/routes/invitations.test.ts +172 -0
- package/src/apps/management/routes/invitations.ts +3 -0
- package/src/apps/management/routes/invite-links.test.ts +117 -0
- package/src/apps/management/routes/invite-links.ts +43 -1
- package/src/apps/management/routes/me.test.ts +140 -88
- package/src/apps/management/routes/me.ts +6 -0
- package/src/apps/management/routes/usage.test.ts +6 -0
- package/src/apps/management/routes/usage.ts +7 -0
- package/src/apps/management/routes/verified-token-requests.test.ts +377 -0
- package/src/apps/management/routes/verified-token-requests.ts +397 -0
- package/src/apps/management/routes/webhooks.test.ts +426 -0
- package/src/apps/management/routes/webhooks.ts +672 -0
- package/src/apps/mcp.test.ts +13 -0
- package/src/apps/mcp.ts +18 -5
- package/src/cli/Cli.test.ts +36 -0
- package/src/cli/Cli.ts +7 -2
- package/src/db/Db.test.ts +19 -0
- package/src/db/Db.ts +95 -0
- package/src/db/Schema.ts +53 -0
- package/src/db/tables/earlyAccess.ts +86 -0
- package/src/db/tables/invitations.ts +26 -1
- package/src/db/tables/inviteLinks.ts +22 -3
- package/src/db/tables/sponsoredTransactions.ts +4 -0
- package/src/db/tables/verifiedTokenRequests.test.ts +200 -0
- package/src/db/tables/verifiedTokenRequests.ts +182 -0
- package/src/db/tables/webhookSubscriptions.ts +31 -0
- package/src/internal/Auth.ts +73 -45
- package/src/internal/FundingQuotes.test.ts +143 -1
- package/src/internal/FundingQuotes.ts +95 -28
- package/src/internal/Log.test-d.ts +21 -0
- package/src/internal/Log.test.ts +50 -0
- package/src/internal/Log.ts +24 -1
- package/src/internal/MetricSink.test.ts +160 -0
- package/src/internal/MetricSink.ts +10 -0
- package/src/internal/OpenApi.ts +3 -0
- package/src/internal/Schema.ts +50 -5
- package/src/internal/Value.test.ts +20 -0
- package/src/internal/Value.ts +24 -1
- package/src/internal/VerifiedTokens.ts +9 -1
- package/src/internal/Webhooks.test.ts +140 -0
- package/src/internal/Webhooks.ts +53 -9
package/src/apps/data/App.ts
CHANGED
|
@@ -14,6 +14,7 @@ import * as Tidx from '../../internal/Tidx.js'
|
|
|
14
14
|
import * as Viem from '../../internal/Viem.js'
|
|
15
15
|
import * as Scope from '../../Scope.js'
|
|
16
16
|
import * as Metadata from '../metadata.js'
|
|
17
|
+
import type * as FxOracle from './FxOracle.js'
|
|
17
18
|
|
|
18
19
|
import { transactions as transactionActivities } from './routes/activities.js'
|
|
19
20
|
import { addresses } from './routes/addresses.js'
|
|
@@ -42,6 +43,12 @@ import { schema as webhookSchema, webhooks } from './routes/webhooks.js'
|
|
|
42
43
|
*/
|
|
43
44
|
export function data(options: data.Options = {}) {
|
|
44
45
|
const { assets, tidx } = options
|
|
46
|
+
const webhook =
|
|
47
|
+
options.webhook === false
|
|
48
|
+
? undefined
|
|
49
|
+
: (options.webhook ?? {
|
|
50
|
+
supportedChainIds: [Viem.chainId.mainnet, Viem.chainId.testnet],
|
|
51
|
+
})
|
|
45
52
|
|
|
46
53
|
// Zone endpoints are explicit trust boundaries; the API never derives them.
|
|
47
54
|
const zones = new Map((options.zones ?? []).map((zone) => [zone.chainId, zone]))
|
|
@@ -66,7 +73,7 @@ export function data(options: data.Options = {}) {
|
|
|
66
73
|
c.set('supportedChainIds', supportedChainIds)
|
|
67
74
|
c.set('tidx', tidx)
|
|
68
75
|
c.set('verifiedTokens', options.verifiedTokens === false ? undefined : (options.verifiedTokens ?? {})) // prettier-ignore
|
|
69
|
-
c.set('webhook',
|
|
76
|
+
c.set('webhook', webhook)
|
|
70
77
|
c.set('zones', zones)
|
|
71
78
|
await next()
|
|
72
79
|
})
|
|
@@ -158,18 +165,18 @@ export function data(options: data.Options = {}) {
|
|
|
158
165
|
'Content-Type': asset.contentType,
|
|
159
166
|
})
|
|
160
167
|
})
|
|
161
|
-
.route('/', addresses())
|
|
168
|
+
.route('/', addresses({ fx: options.fx }))
|
|
162
169
|
.route('/', blocks())
|
|
163
|
-
.route('/', exchanges())
|
|
170
|
+
.route('/', exchanges({ fx: options.fx }))
|
|
164
171
|
.route('/', feeAmm())
|
|
165
172
|
.route('/', funding(options.funding))
|
|
166
173
|
.route('/', indexer())
|
|
167
|
-
.route('/', receipts())
|
|
174
|
+
.route('/', receipts({ fx: options.fx }))
|
|
168
175
|
.route('/', tokenlist())
|
|
169
176
|
.route('/', tokens())
|
|
170
177
|
.route('/', transactions())
|
|
171
|
-
.route('/', transactionActivities())
|
|
172
|
-
.route('/', transfers())
|
|
178
|
+
.route('/', transactionActivities({ fx: options.fx }))
|
|
179
|
+
.route('/', transfers({ fx: options.fx }))
|
|
173
180
|
.route('/', verifiedTokens())
|
|
174
181
|
.route('/', webhooks({ enabled: options.webhook !== false }))
|
|
175
182
|
.route('/', rpc())
|
|
@@ -206,6 +213,8 @@ export declare namespace data {
|
|
|
206
213
|
assets?: Assets.Assets | undefined
|
|
207
214
|
/** Funding quote provider configuration. */
|
|
208
215
|
funding?: funding.Options | undefined
|
|
216
|
+
/** FX configuration for the valuation endpoint. */
|
|
217
|
+
fx?: Fx | undefined
|
|
209
218
|
/** TIDX query client options. */
|
|
210
219
|
tidx?: Tidx.getClient.Tidx | undefined
|
|
211
220
|
/** Verified-token feature configuration. Enabled by default (token rows live in `db`; empty until published); pass `false` to always serve an empty verified list. */
|
|
@@ -219,6 +228,12 @@ export declare namespace data {
|
|
|
219
228
|
zones?: readonly Zone[] | undefined
|
|
220
229
|
}
|
|
221
230
|
|
|
231
|
+
/** FX configuration for the valuation endpoint. */
|
|
232
|
+
type Fx = {
|
|
233
|
+
/** FX rate oracle backing currency conversion. Defaults to the ECB daily reference rates (`FxOracle.ecb()`). */
|
|
234
|
+
oracle?: FxOracle.Oracle | undefined
|
|
235
|
+
}
|
|
236
|
+
|
|
222
237
|
/** One zone chain served by this deployment. */
|
|
223
238
|
type Zone = {
|
|
224
239
|
/** Zone chain id. Consumer-supplied literal; the API never derives zone chain ids. */
|
|
@@ -238,14 +253,7 @@ export declare namespace data {
|
|
|
238
253
|
}
|
|
239
254
|
|
|
240
255
|
/** Webhook feature configuration. */
|
|
241
|
-
type Webhook =
|
|
242
|
-
/**
|
|
243
|
-
* Maximum active subscriptions per owner; creation is rejected with
|
|
244
|
-
* `403 limit_exceeded` once reached. Defaults to 100, bounding the spam/SSRF
|
|
245
|
-
* and delivery-cost surface per owner.
|
|
246
|
-
*/
|
|
247
|
-
maxPerOwner?: number | undefined
|
|
248
|
-
}
|
|
256
|
+
type Webhook = App.Webhook
|
|
249
257
|
}
|
|
250
258
|
|
|
251
259
|
function resolveChainSelector(options: {
|
|
@@ -38,6 +38,15 @@ describe('FundingQuoteProviders', () => {
|
|
|
38
38
|
})
|
|
39
39
|
})
|
|
40
40
|
|
|
41
|
+
test('configures Symbiosis only when its quote user is present', () => {
|
|
42
|
+
expect(FundingQuoteProviders.configureSymbiosis()).toBeUndefined()
|
|
43
|
+
expect(
|
|
44
|
+
FundingQuoteProviders.configureSymbiosis({
|
|
45
|
+
userAddress: '0x1111111111111111111111111111111111111111',
|
|
46
|
+
}),
|
|
47
|
+
).toEqual({ userAddress: '0x1111111111111111111111111111111111111111' })
|
|
48
|
+
})
|
|
49
|
+
|
|
41
50
|
test('maps successful Across quotes to available quote probes', async () => {
|
|
42
51
|
const requests: RecordedRequest[] = []
|
|
43
52
|
const candidate = quoteCandidate('across')
|
|
@@ -262,6 +271,180 @@ describe('FundingQuoteProviders', () => {
|
|
|
262
271
|
})
|
|
263
272
|
})
|
|
264
273
|
|
|
274
|
+
test('maps successful Symbiosis quotes to available quote probes', async () => {
|
|
275
|
+
const requests: RecordedRequest[] = []
|
|
276
|
+
const candidate = quoteCandidate('symbiosis')
|
|
277
|
+
const fetch = recordingFetch(requests, async () => jsonResponse(symbiosisQuote(candidate)))
|
|
278
|
+
const adapter = FundingQuoteProviders.symbiosis({
|
|
279
|
+
baseUrl: 'https://symbiosis.test/crosschain/',
|
|
280
|
+
fetch,
|
|
281
|
+
now,
|
|
282
|
+
userAddress: '0x1111111111111111111111111111111111111111',
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
const result = await adapter.probeQuote(probeInput(candidate), new AbortController().signal)
|
|
286
|
+
|
|
287
|
+
expect(requests).toHaveLength(1)
|
|
288
|
+
expect(requests[0]?.url.pathname).toBe('/crosschain/v2/quote')
|
|
289
|
+
expect(new Headers(requests[0]?.init?.headers).get('x-partner-id')).toBe('tempo')
|
|
290
|
+
expect(jsonRequestBody(requests[0])).toEqual({
|
|
291
|
+
from: '0x1111111111111111111111111111111111111111',
|
|
292
|
+
slippage: 100,
|
|
293
|
+
to: '0x1111111111111111111111111111111111111111',
|
|
294
|
+
tokenAmountIn: {
|
|
295
|
+
address: candidate.sourceToken.address,
|
|
296
|
+
amount: '1000000',
|
|
297
|
+
chainId: 8453,
|
|
298
|
+
decimals: 6,
|
|
299
|
+
symbol: 'USDC',
|
|
300
|
+
},
|
|
301
|
+
tokenOut: {
|
|
302
|
+
address: candidate.destinationToken.address,
|
|
303
|
+
chainId: 4217,
|
|
304
|
+
decimals: 6,
|
|
305
|
+
symbol: 'USDC.e',
|
|
306
|
+
},
|
|
307
|
+
})
|
|
308
|
+
expect(result).toEqual({
|
|
309
|
+
minimumOutputAmount: '979000',
|
|
310
|
+
outputAmount: '989000',
|
|
311
|
+
outputAmountFormatted: '0.989',
|
|
312
|
+
quality: {
|
|
313
|
+
estimatedSeconds: 18,
|
|
314
|
+
liquiditySource: 'providerQuote',
|
|
315
|
+
sourceDetail: 'symbiosis:quote-v2',
|
|
316
|
+
tier: 'liquid',
|
|
317
|
+
},
|
|
318
|
+
sampledAt: '2026-01-01T00:00:00.000Z',
|
|
319
|
+
status: 'available',
|
|
320
|
+
})
|
|
321
|
+
})
|
|
322
|
+
|
|
323
|
+
test('maps Tron identifiers into Symbiosis quote requests', async () => {
|
|
324
|
+
const requests: RecordedRequest[] = []
|
|
325
|
+
const candidate = quoteCandidate('symbiosis', {
|
|
326
|
+
destinationToken: 'USDT0',
|
|
327
|
+
sourceChain: 'tron',
|
|
328
|
+
sourceToken: 'USDT',
|
|
329
|
+
})
|
|
330
|
+
const fetch = recordingFetch(requests, async () => jsonResponse(symbiosisQuote(candidate)))
|
|
331
|
+
const adapter = FundingQuoteProviders.symbiosis({
|
|
332
|
+
fetch,
|
|
333
|
+
now,
|
|
334
|
+
userAddress: '0x1111111111111111111111111111111111111111',
|
|
335
|
+
})
|
|
336
|
+
|
|
337
|
+
await adapter.probeQuote(probeInput(candidate), new AbortController().signal)
|
|
338
|
+
|
|
339
|
+
expect(jsonRequestBody(requests[0])).toMatchObject({
|
|
340
|
+
tokenAmountIn: {
|
|
341
|
+
address: '0xa614f803b6fd780986a42c78ec9c7f77e6ded13c',
|
|
342
|
+
chainId: 728126428,
|
|
343
|
+
decimals: 6,
|
|
344
|
+
symbol: 'USDT',
|
|
345
|
+
},
|
|
346
|
+
tokenOut: {
|
|
347
|
+
address: candidate.destinationToken.address,
|
|
348
|
+
chainId: 4217,
|
|
349
|
+
decimals: 6,
|
|
350
|
+
symbol: 'USDT0',
|
|
351
|
+
},
|
|
352
|
+
})
|
|
353
|
+
})
|
|
354
|
+
|
|
355
|
+
test('rejects Symbiosis responses without route identity fields', async () => {
|
|
356
|
+
const candidate = quoteCandidate('symbiosis')
|
|
357
|
+
const quote = symbiosisQuote(candidate)
|
|
358
|
+
const response = {
|
|
359
|
+
tokenAmountOut: quote.tokenAmountOut,
|
|
360
|
+
tokenAmountOutMin: quote.tokenAmountOutMin,
|
|
361
|
+
}
|
|
362
|
+
const adapter = FundingQuoteProviders.symbiosis({
|
|
363
|
+
fetch: recordingFetch([], async () => jsonResponse(response)),
|
|
364
|
+
now,
|
|
365
|
+
userAddress: '0x1111111111111111111111111111111111111111',
|
|
366
|
+
})
|
|
367
|
+
|
|
368
|
+
await expect(
|
|
369
|
+
adapter.probeQuote(probeInput(candidate), new AbortController().signal),
|
|
370
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`[FundingQuoteProviders.ProviderPayloadError]`)
|
|
371
|
+
})
|
|
372
|
+
|
|
373
|
+
test('enforces the Symbiosis provider quota before fetching', async () => {
|
|
374
|
+
const requests: RecordedRequest[] = []
|
|
375
|
+
const candidate = quoteCandidate('symbiosis')
|
|
376
|
+
const adapter = FundingQuoteProviders.symbiosis({
|
|
377
|
+
fetch: recordingFetch(requests, async () => jsonResponse(symbiosisQuote(candidate))),
|
|
378
|
+
now,
|
|
379
|
+
userAddress: '0x1111111111111111111111111111111111111111',
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
await Promise.all(
|
|
383
|
+
Array.from({ length: 4 }, () =>
|
|
384
|
+
adapter.probeQuote(probeInput(candidate), new AbortController().signal),
|
|
385
|
+
),
|
|
386
|
+
)
|
|
387
|
+
const cause = await adapter
|
|
388
|
+
.probeQuote(probeInput(candidate), new AbortController().signal)
|
|
389
|
+
.catch((error: unknown) => error)
|
|
390
|
+
|
|
391
|
+
expect(requests).toHaveLength(4)
|
|
392
|
+
expect(cause).toMatchObject({
|
|
393
|
+
name: 'FundingQuoteProviders.ProviderRateLimitError',
|
|
394
|
+
})
|
|
395
|
+
expect(FundingQuoteProviders.providerFailure({ cause, provider: 'symbiosis' })).toEqual({
|
|
396
|
+
failure: 'rate_limit',
|
|
397
|
+
id: 'symbiosis',
|
|
398
|
+
operation: 'v2/quote',
|
|
399
|
+
})
|
|
400
|
+
})
|
|
401
|
+
|
|
402
|
+
test('maps unavailable Symbiosis routes to unavailable quote probes', async () => {
|
|
403
|
+
const candidate = quoteCandidate('symbiosis')
|
|
404
|
+
const adapter = FundingQuoteProviders.symbiosis({
|
|
405
|
+
fetch: recordingFetch([], async () => jsonResponse({ code: 'NO_ROUTE' }, 400)),
|
|
406
|
+
now,
|
|
407
|
+
userAddress: '0x1111111111111111111111111111111111111111',
|
|
408
|
+
})
|
|
409
|
+
|
|
410
|
+
await expect(
|
|
411
|
+
adapter.probeQuote(probeInput(candidate), new AbortController().signal),
|
|
412
|
+
).resolves.toMatchObject({
|
|
413
|
+
quality: {
|
|
414
|
+
sourceDetail: 'symbiosis:quote-v2:NO_ROUTE',
|
|
415
|
+
tier: 'unavailable',
|
|
416
|
+
},
|
|
417
|
+
status: 'unavailable',
|
|
418
|
+
})
|
|
419
|
+
})
|
|
420
|
+
|
|
421
|
+
test('maps Symbiosis fee-floor errors to unavailable quote probes', async () => {
|
|
422
|
+
const candidate = quoteCandidate('symbiosis')
|
|
423
|
+
const adapter = FundingQuoteProviders.symbiosis({
|
|
424
|
+
fetch: recordingFetch([], async () =>
|
|
425
|
+
jsonResponse({ code: 0, message: 'Amount is too low to cover fees' }, 400),
|
|
426
|
+
),
|
|
427
|
+
now,
|
|
428
|
+
userAddress: '0x1111111111111111111111111111111111111111',
|
|
429
|
+
})
|
|
430
|
+
|
|
431
|
+
await expect(
|
|
432
|
+
adapter.probeQuote(probeInput(candidate), new AbortController().signal),
|
|
433
|
+
).resolves.toMatchObject({
|
|
434
|
+
quality: {
|
|
435
|
+
sourceDetail: 'symbiosis:quote-v2:AMOUNT_TOO_LOW',
|
|
436
|
+
tier: 'unavailable',
|
|
437
|
+
},
|
|
438
|
+
status: 'unavailable',
|
|
439
|
+
})
|
|
440
|
+
})
|
|
441
|
+
|
|
442
|
+
test('rejects invalid Symbiosis configuration', () => {
|
|
443
|
+
expect(() =>
|
|
444
|
+
FundingQuoteProviders.symbiosis({ userAddress: 'invalid' }),
|
|
445
|
+
).toThrowErrorMatchingInlineSnapshot(`[FundingQuoteProviders.ProviderConfigurationError]`)
|
|
446
|
+
})
|
|
447
|
+
|
|
265
448
|
test('maps successful Rhino quotes to available quote probes', async () => {
|
|
266
449
|
const requests: RecordedRequest[] = []
|
|
267
450
|
const candidate = quoteCandidate('rhino')
|
|
@@ -585,6 +768,73 @@ describe('FundingQuoteProviders', () => {
|
|
|
585
768
|
).rejects.toThrowErrorMatchingInlineSnapshot(`[FundingQuoteProviders.ProviderPayloadError]`)
|
|
586
769
|
})
|
|
587
770
|
|
|
771
|
+
const invalidSymbiosisQuotes = [
|
|
772
|
+
[
|
|
773
|
+
'unsupported route kinds',
|
|
774
|
+
(body: ReturnType<typeof symbiosisQuote>) => (body.kind = 'onchain-swap' as never),
|
|
775
|
+
],
|
|
776
|
+
[
|
|
777
|
+
'mismatched execution types',
|
|
778
|
+
(body: ReturnType<typeof symbiosisQuote>) => (body.type = 'tron'),
|
|
779
|
+
],
|
|
780
|
+
[
|
|
781
|
+
'mismatched transaction chains',
|
|
782
|
+
(body: ReturnType<typeof symbiosisQuote>) => (body.tx.chainId = 1),
|
|
783
|
+
],
|
|
784
|
+
['empty routes', (body: ReturnType<typeof symbiosisQuote>) => (body.routes = [])],
|
|
785
|
+
[
|
|
786
|
+
'mismatched source token addresses',
|
|
787
|
+
(body: ReturnType<typeof symbiosisQuote>) =>
|
|
788
|
+
(body.routes[0]!.tokens[0]!.address = '0xfde4c96c8593536e31f229ea8f37b2ada2699bb2'),
|
|
789
|
+
],
|
|
790
|
+
[
|
|
791
|
+
'mismatched source chains',
|
|
792
|
+
(body: ReturnType<typeof symbiosisQuote>) => (body.routes[0]!.tokens[0]!.chainId = 1),
|
|
793
|
+
],
|
|
794
|
+
[
|
|
795
|
+
'mismatched route destination tokens',
|
|
796
|
+
(body: ReturnType<typeof symbiosisQuote>) =>
|
|
797
|
+
(body.routes[0]!.tokens[1]!.address = '0x20c00000000000000000000014f22ca97301eb73'),
|
|
798
|
+
],
|
|
799
|
+
[
|
|
800
|
+
'mismatched output token addresses',
|
|
801
|
+
(body: ReturnType<typeof symbiosisQuote>) =>
|
|
802
|
+
(body.tokenAmountOut.address = '0x20c00000000000000000000014f22ca97301eb73'),
|
|
803
|
+
],
|
|
804
|
+
[
|
|
805
|
+
'mismatched minimum output chains',
|
|
806
|
+
(body: ReturnType<typeof symbiosisQuote>) => (body.tokenAmountOutMin.chainId = 1),
|
|
807
|
+
],
|
|
808
|
+
[
|
|
809
|
+
'mismatched output decimals',
|
|
810
|
+
(body: ReturnType<typeof symbiosisQuote>) => (body.tokenAmountOut.decimals = 18 as never),
|
|
811
|
+
],
|
|
812
|
+
[
|
|
813
|
+
'zero output amounts',
|
|
814
|
+
(body: ReturnType<typeof symbiosisQuote>) => (body.tokenAmountOut.amount = '0'),
|
|
815
|
+
],
|
|
816
|
+
[
|
|
817
|
+
'invalid output bounds',
|
|
818
|
+
(body: ReturnType<typeof symbiosisQuote>) => (body.tokenAmountOutMin.amount = '990000'),
|
|
819
|
+
],
|
|
820
|
+
] as const
|
|
821
|
+
|
|
822
|
+
for (const [name, mutate] of invalidSymbiosisQuotes)
|
|
823
|
+
test(`rejects Symbiosis quotes with ${name}`, async () => {
|
|
824
|
+
const candidate = quoteCandidate('symbiosis')
|
|
825
|
+
const body = symbiosisQuote(candidate)
|
|
826
|
+
mutate(body)
|
|
827
|
+
const adapter = FundingQuoteProviders.symbiosis({
|
|
828
|
+
fetch: recordingFetch([], async () => jsonResponse(body)),
|
|
829
|
+
now,
|
|
830
|
+
userAddress: '0x1111111111111111111111111111111111111111',
|
|
831
|
+
})
|
|
832
|
+
|
|
833
|
+
await expect(
|
|
834
|
+
adapter.probeQuote(probeInput(candidate), new AbortController().signal),
|
|
835
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`[FundingQuoteProviders.ProviderPayloadError]`)
|
|
836
|
+
})
|
|
837
|
+
|
|
588
838
|
test('returns bounded Across failure diagnostics', async () => {
|
|
589
839
|
const candidate = quoteCandidate('across')
|
|
590
840
|
const adapter = FundingQuoteProviders.across({
|
|
@@ -634,6 +884,19 @@ describe('FundingQuoteProviders', () => {
|
|
|
634
884
|
operation: 'v2/route',
|
|
635
885
|
})
|
|
636
886
|
})
|
|
887
|
+
|
|
888
|
+
test('returns bounded Symbiosis failure diagnostics', () => {
|
|
889
|
+
expect(
|
|
890
|
+
FundingQuoteProviders.providerFailure({
|
|
891
|
+
cause: new TypeError('network failure'),
|
|
892
|
+
provider: 'symbiosis',
|
|
893
|
+
}),
|
|
894
|
+
).toEqual({
|
|
895
|
+
failure: 'network',
|
|
896
|
+
id: 'symbiosis',
|
|
897
|
+
operation: 'v2/quote',
|
|
898
|
+
})
|
|
899
|
+
})
|
|
637
900
|
})
|
|
638
901
|
|
|
639
902
|
type RecordedRequest = {
|
|
@@ -711,6 +974,41 @@ function squidQuote(candidate: FundingQuotes.QuoteProbeInput['candidate']) {
|
|
|
711
974
|
}
|
|
712
975
|
}
|
|
713
976
|
|
|
977
|
+
function symbiosisQuote(candidate: FundingQuotes.QuoteProbeInput['candidate']) {
|
|
978
|
+
const source =
|
|
979
|
+
candidate.sourceChain.kind === 'tron'
|
|
980
|
+
? {
|
|
981
|
+
address: '0xa614f803b6fd780986a42c78ec9c7f77e6ded13c',
|
|
982
|
+
chainId: 728126428,
|
|
983
|
+
decimals: candidate.sourceToken.decimals,
|
|
984
|
+
}
|
|
985
|
+
: {
|
|
986
|
+
address: candidate.sourceToken.address,
|
|
987
|
+
chainId: Number(candidate.sourceChain.id.replace('eip155:', '')),
|
|
988
|
+
decimals: candidate.sourceToken.decimals,
|
|
989
|
+
}
|
|
990
|
+
const destination = {
|
|
991
|
+
address: candidate.destinationToken.address,
|
|
992
|
+
chainId: 4217,
|
|
993
|
+
decimals: candidate.destinationToken.decimals,
|
|
994
|
+
}
|
|
995
|
+
return {
|
|
996
|
+
estimatedTime: 17.2,
|
|
997
|
+
kind: 'crosschain-swap' as const,
|
|
998
|
+
routes: [{ tokens: [source, destination] }],
|
|
999
|
+
tokenAmountOut: {
|
|
1000
|
+
...destination,
|
|
1001
|
+
amount: '989000',
|
|
1002
|
+
},
|
|
1003
|
+
tokenAmountOutMin: {
|
|
1004
|
+
...destination,
|
|
1005
|
+
amount: '979000',
|
|
1006
|
+
},
|
|
1007
|
+
tx: { chainId: source.chainId },
|
|
1008
|
+
type: candidate.sourceChain.kind,
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
|
|
714
1012
|
function probeInput(
|
|
715
1013
|
candidate: FundingQuotes.QuoteProbeInput['candidate'],
|
|
716
1014
|
): FundingQuotes.QuoteProbeInput {
|