tapimo 0.2.0 → 0.4.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/README.md +36 -8
- package/dist/ApiKey.d.ts +1 -0
- package/dist/ApiKey.d.ts.map +1 -1
- package/dist/ApiKey.js +5 -2
- package/dist/ApiKey.js.map +1 -1
- package/dist/ApiKeys.d.ts +28 -1
- package/dist/ApiKeys.d.ts.map +1 -1
- package/dist/ApiKeys.js +34 -1
- package/dist/ApiKeys.js.map +1 -1
- package/dist/App.d.ts +7532 -4850
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +11 -3
- package/dist/App.js.map +1 -1
- package/dist/Scope.d.ts +11 -2
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +14 -3
- package/dist/Scope.js.map +1 -1
- package/dist/admin/App.d.ts +63 -53
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +7 -0
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/scopes.d.ts +8 -0
- package/dist/admin/apps/scopes.d.ts.map +1 -1
- package/dist/admin/apps/scopes.js +3 -0
- package/dist/admin/apps/scopes.js.map +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +57 -57
- package/dist/admin/ui.generated.d.ts +1 -1
- package/dist/admin/ui.generated.js +13 -13
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/analytics/Analytics.d.ts +151 -0
- package/dist/analytics/Analytics.d.ts.map +1 -0
- package/dist/analytics/Analytics.js +212 -0
- package/dist/analytics/Analytics.js.map +1 -0
- package/dist/analytics/tables/requestEvents.d.ts +215 -0
- package/dist/analytics/tables/requestEvents.d.ts.map +1 -0
- package/dist/analytics/tables/requestEvents.js +264 -0
- package/dist/analytics/tables/requestEvents.js.map +1 -0
- package/dist/apps/data/App.d.ts +1049 -624
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +36 -0
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/FundingRouteProviders.d.ts +54 -0
- package/dist/apps/data/FundingRouteProviders.d.ts.map +1 -0
- package/dist/apps/data/FundingRouteProviders.js +355 -0
- package/dist/apps/data/FundingRouteProviders.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/balances.d.ts +45 -45
- package/dist/apps/data/routes/coingecko.d.ts +176 -176
- package/dist/apps/data/routes/exchanges.d.ts +455 -455
- package/dist/apps/data/routes/fee-amm.d.ts +101 -101
- package/dist/apps/data/routes/funding.d.ts +843 -0
- package/dist/apps/data/routes/funding.d.ts.map +1 -0
- package/dist/apps/data/routes/funding.js +443 -0
- package/dist/apps/data/routes/funding.js.map +1 -0
- package/dist/apps/data/routes/indexer.d.ts +5 -5
- package/dist/apps/data/routes/receipts.d.ts.map +1 -1
- package/dist/apps/data/routes/receipts.js +2 -8
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/rpc.d.ts +29 -36
- package/dist/apps/data/routes/rpc.d.ts.map +1 -1
- package/dist/apps/data/routes/rpc.js +29 -1
- package/dist/apps/data/routes/rpc.js.map +1 -1
- package/dist/apps/data/routes/tokenlist.d.ts +36 -36
- package/dist/apps/data/routes/transfers.d.ts +56 -56
- package/dist/apps/data/routes/verified-tokens.d.ts +36 -36
- package/dist/apps/data/routes/webhooks.d.ts +45 -45
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +8 -8
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/docs/App.d.ts +5 -3
- package/dist/apps/docs/App.d.ts.map +1 -1
- package/dist/apps/docs/App.js +28 -96
- package/dist/apps/docs/App.js.map +1 -1
- package/dist/apps/docs/reference.d.ts +21 -0
- package/dist/apps/docs/reference.d.ts.map +1 -0
- package/dist/apps/docs/reference.js +112 -0
- package/dist/apps/docs/reference.js.map +1 -0
- package/dist/apps/index.d.ts +3 -2
- package/dist/apps/index.d.ts.map +1 -1
- package/dist/apps/index.js +3 -2
- package/dist/apps/index.js.map +1 -1
- package/dist/apps/{platform → management}/App.d.ts +3015 -738
- package/dist/apps/management/App.d.ts.map +1 -0
- package/dist/apps/{platform → management}/App.js +20 -10
- package/dist/apps/management/App.js.map +1 -0
- package/dist/apps/management/Billing.d.ts +279 -0
- package/dist/apps/management/Billing.d.ts.map +1 -0
- package/dist/apps/management/Billing.js +477 -0
- package/dist/apps/management/Billing.js.map +1 -0
- package/dist/apps/management/index.d.ts +3 -0
- package/dist/apps/management/index.d.ts.map +1 -0
- package/dist/apps/management/index.js +3 -0
- package/dist/apps/management/index.js.map +1 -0
- package/dist/apps/{platform → management}/routes/api-keys.d.ts +341 -49
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -0
- package/dist/apps/{platform → management}/routes/api-keys.js +116 -14
- package/dist/apps/management/routes/api-keys.js.map +1 -0
- package/dist/apps/management/routes/billing.d.ts +1520 -0
- package/dist/apps/management/routes/billing.d.ts.map +1 -0
- package/dist/apps/management/routes/billing.js +795 -0
- package/dist/apps/management/routes/billing.js.map +1 -0
- package/dist/apps/{platform → management}/routes/invitations.d.ts +202 -84
- package/dist/apps/management/routes/invitations.d.ts.map +1 -0
- package/dist/apps/{platform → management}/routes/invitations.js +59 -1
- package/dist/apps/management/routes/invitations.js.map +1 -0
- package/dist/apps/{platform → management}/routes/me.d.ts +17 -17
- package/dist/apps/management/routes/me.d.ts.map +1 -0
- package/dist/apps/management/routes/me.js.map +1 -0
- package/dist/apps/management/routes/members.d.ts.map +1 -0
- package/dist/apps/management/routes/members.js.map +1 -0
- package/dist/apps/{platform → management}/routes/orgs.d.ts +50 -36
- package/dist/apps/management/routes/orgs.d.ts.map +1 -0
- package/dist/apps/{platform → management}/routes/orgs.js +14 -3
- package/dist/apps/management/routes/orgs.js.map +1 -0
- package/dist/apps/{platform → management}/routes/projects.d.ts +97 -97
- package/dist/apps/{platform → management}/routes/projects.d.ts.map +1 -1
- package/dist/apps/management/routes/projects.js.map +1 -0
- package/dist/apps/management/routes/scopes.d.ts +107 -0
- package/dist/apps/management/routes/scopes.d.ts.map +1 -0
- package/dist/apps/management/routes/scopes.js +66 -0
- package/dist/apps/management/routes/scopes.js.map +1 -0
- package/dist/apps/management/routes/usage.d.ts +588 -0
- package/dist/apps/management/routes/usage.d.ts.map +1 -0
- package/dist/apps/management/routes/usage.js +391 -0
- package/dist/apps/management/routes/usage.js.map +1 -0
- package/dist/apps/mcp.d.ts +76 -0
- package/dist/apps/mcp.d.ts.map +1 -0
- package/dist/apps/mcp.js +188 -0
- package/dist/apps/mcp.js.map +1 -0
- package/dist/apps/relay/App.d.ts +4 -1
- package/dist/apps/relay/App.d.ts.map +1 -1
- package/dist/apps/relay/App.js +118 -10
- package/dist/apps/relay/App.js.map +1 -1
- package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
- package/dist/apps/relay/Sponsorships.js +2 -1
- package/dist/apps/relay/Sponsorships.js.map +1 -1
- package/dist/cli/Cli.d.ts +8 -1
- package/dist/cli/Cli.d.ts.map +1 -1
- package/dist/cli/Cli.js +11 -3
- package/dist/cli/Cli.js.map +1 -1
- package/dist/cli/commands/admin.d.ts +4 -0
- package/dist/cli/commands/admin.d.ts.map +1 -1
- package/dist/cli/commands/admin.js +80 -1
- package/dist/cli/commands/admin.js.map +1 -1
- package/dist/db/Db.d.ts +7 -0
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +126 -0
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +79 -0
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +88 -2
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/billingSettings.d.ts +55 -0
- package/dist/db/tables/billingSettings.d.ts.map +1 -0
- package/dist/db/tables/billingSettings.js +70 -0
- package/dist/db/tables/billingSettings.js.map +1 -0
- package/dist/db/tables/invitations.js +2 -2
- package/dist/db/tables/invitations.js.map +1 -1
- package/dist/db/tables/organizations.d.ts +6 -2
- package/dist/db/tables/organizations.d.ts.map +1 -1
- package/dist/db/tables/organizations.js +10 -4
- package/dist/db/tables/organizations.js.map +1 -1
- package/dist/db/tables/projects.js +2 -2
- package/dist/db/tables/projects.js.map +1 -1
- package/dist/db/tables/requestUsage.d.ts +121 -0
- package/dist/db/tables/requestUsage.d.ts.map +1 -0
- package/dist/db/tables/requestUsage.js +150 -0
- package/dist/db/tables/requestUsage.js.map +1 -0
- package/dist/db/tables/sponsoredTransactions.d.ts +119 -0
- package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
- package/dist/db/tables/sponsoredTransactions.js +155 -2
- package/dist/db/tables/sponsoredTransactions.js.map +1 -1
- package/dist/db/tables/stripeCustomers.d.ts +81 -0
- package/dist/db/tables/stripeCustomers.d.ts.map +1 -0
- package/dist/db/tables/stripeCustomers.js +120 -0
- package/dist/db/tables/stripeCustomers.js.map +1 -0
- package/dist/db/tables/users.js +2 -2
- package/dist/db/tables/users.js.map +1 -1
- package/dist/handlers/internal/sponsorship.d.ts +5 -2
- package/dist/handlers/internal/sponsorship.d.ts.map +1 -1
- package/dist/handlers/internal/sponsorship.js +19 -5
- package/dist/handlers/internal/sponsorship.js.map +1 -1
- package/dist/handlers/internal/utils.d.ts +10 -3
- package/dist/handlers/internal/utils.d.ts.map +1 -1
- package/dist/handlers/internal/utils.js +14 -6
- package/dist/handlers/internal/utils.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/Auth.d.ts +18 -4
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +149 -77
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/Cache.d.ts.map +1 -1
- package/dist/internal/Cache.js +4 -1
- package/dist/internal/Cache.js.map +1 -1
- package/dist/internal/EdgeCache.d.ts +10 -0
- package/dist/internal/EdgeCache.d.ts.map +1 -1
- package/dist/internal/EdgeCache.js +39 -8
- package/dist/internal/EdgeCache.js.map +1 -1
- package/dist/internal/Fees.d.ts +27 -0
- package/dist/internal/Fees.d.ts.map +1 -0
- package/dist/internal/Fees.js +48 -0
- package/dist/internal/Fees.js.map +1 -0
- package/dist/internal/FundingRoutes.d.ts +915 -0
- package/dist/internal/FundingRoutes.d.ts.map +1 -0
- package/dist/internal/FundingRoutes.js +625 -0
- package/dist/internal/FundingRoutes.js.map +1 -0
- package/dist/internal/Id.d.ts +15 -0
- package/dist/internal/Id.d.ts.map +1 -0
- package/dist/internal/Id.js +22 -0
- package/dist/internal/Id.js.map +1 -0
- package/dist/internal/Log.d.ts +2 -0
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +3 -0
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +10 -1
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +8 -1
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/RateLimit.d.ts +25 -0
- package/dist/internal/RateLimit.d.ts.map +1 -1
- package/dist/internal/RateLimit.js +51 -0
- package/dist/internal/RateLimit.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 +8 -0
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +7 -0
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +3 -3
- package/dist/internal/Webhooks.js.map +1 -1
- package/package.json +8 -7
- package/src/ApiKey.ts +9 -2
- package/src/ApiKeys.test.ts +51 -0
- package/src/ApiKeys.ts +50 -1
- package/src/App.test.ts +33 -86718
- package/src/App.ts +26 -8
- package/src/Client.test-d.ts +353 -2
- package/src/Scope.ts +16 -3
- package/src/admin/apps/scopes.test.ts +6 -0
- package/src/admin/apps/scopes.ts +3 -0
- package/src/admin/ui/src/components/Page.tsx +2 -3
- package/src/admin/ui/src/routes/__root.tsx +2 -2
- package/src/admin/ui/src/routes/api-keys.tsx +2 -2
- package/src/admin/ui.generated.ts +13 -13
- package/src/analytics/Analytics.test.ts +527 -0
- package/src/analytics/Analytics.ts +318 -0
- package/src/analytics/tables/requestEvents.ts +523 -0
- package/src/apps/composition.test.ts +26 -13
- package/src/apps/data/App.test.ts +72 -0
- package/src/apps/data/App.ts +37 -0
- package/src/apps/data/FundingRouteProviders.test.ts +281 -0
- package/src/apps/data/FundingRouteProviders.ts +459 -0
- package/src/apps/data/index.ts +1 -0
- package/src/apps/data/routes/funding.test.ts +314 -0
- package/src/apps/data/routes/funding.ts +698 -0
- package/src/apps/data/routes/receipts.ts +2 -9
- package/src/apps/data/routes/rpc.test.ts +78 -2
- package/src/apps/data/routes/rpc.ts +31 -1
- package/src/apps/data/routes/webhooks.test.ts +1 -1
- package/src/apps/data/routes/webhooks.ts +11 -8
- package/src/apps/docs/App.ts +30 -101
- package/src/apps/docs/reference.ts +132 -0
- package/src/apps/index.ts +3 -2
- package/src/apps/{platform → management}/App.ts +56 -17
- package/src/apps/management/Billing.test.ts +530 -0
- package/src/apps/management/Billing.ts +682 -0
- package/src/apps/management/index.ts +2 -0
- package/src/apps/{platform → management}/routes/api-keys.test.ts +172 -9
- package/src/apps/{platform → management}/routes/api-keys.ts +137 -21
- package/src/apps/management/routes/billing.test.ts +1100 -0
- package/src/apps/management/routes/billing.ts +966 -0
- package/src/apps/{platform → management}/routes/invitations.test.ts +55 -7
- package/src/apps/{platform → management}/routes/invitations.ts +69 -1
- package/src/apps/management/routes/me.test.ts +351 -0
- package/src/apps/{platform → management}/routes/orgs.ts +26 -4
- package/src/apps/management/routes/scopes.test.ts +29 -0
- package/src/apps/management/routes/scopes.ts +85 -0
- package/src/apps/management/routes/usage.test.ts +422 -0
- package/src/apps/management/routes/usage.ts +527 -0
- package/src/apps/mcp.test.ts +206 -0
- package/src/apps/mcp.ts +250 -0
- package/src/apps/relay/App.test.ts +457 -8
- package/src/apps/relay/App.ts +120 -12
- package/src/apps/relay/Sponsorships.test.ts +1 -1
- package/src/apps/relay/Sponsorships.ts +2 -1
- package/src/cli/Cli.test.ts +25 -2
- package/src/cli/Cli.ts +17 -2
- package/src/cli/commands/admin.test.ts +83 -0
- package/src/cli/commands/admin.ts +89 -1
- package/src/db/Db.ts +137 -0
- package/src/db/Schema.ts +104 -2
- package/src/db/tables/billingSettings.test.ts +87 -0
- package/src/db/tables/billingSettings.ts +108 -0
- package/src/db/tables/invitations.ts +2 -2
- package/src/db/tables/organizations.test.ts +1 -1
- package/src/db/tables/organizations.ts +15 -5
- package/src/db/tables/projects.ts +2 -2
- package/src/db/tables/requestUsage.ts +231 -0
- package/src/db/tables/sponsoredTransactions.test.ts +108 -1
- package/src/db/tables/sponsoredTransactions.ts +230 -2
- package/src/db/tables/stripeCustomers.test.ts +109 -0
- package/src/db/tables/stripeCustomers.ts +162 -0
- package/src/db/tables/users.ts +2 -2
- package/src/handlers/internal/sponsorship.ts +34 -7
- package/src/handlers/internal/utils.ts +19 -7
- package/src/index.ts +1 -0
- package/src/internal/Auth.test.ts +175 -25
- package/src/internal/Auth.ts +176 -87
- package/src/internal/Cache.ts +5 -1
- package/src/internal/EdgeCache.test.ts +27 -4
- package/src/internal/EdgeCache.ts +47 -9
- package/src/internal/Fees.test.ts +32 -0
- package/src/internal/Fees.ts +51 -0
- package/src/internal/FundingRoutes.test.ts +213 -0
- package/src/internal/FundingRoutes.ts +898 -0
- package/src/internal/Id.test.ts +17 -0
- package/src/internal/Id.ts +24 -0
- package/src/internal/Log.test.ts +1 -0
- package/src/internal/Log.ts +5 -0
- package/src/internal/OpenApi.ts +12 -1
- package/src/internal/RateLimit.test.ts +84 -0
- package/src/internal/RateLimit.ts +70 -0
- package/src/internal/Response.ts +1 -1
- package/src/internal/Schema.ts +8 -0
- package/src/internal/Webhooks.test.ts +3 -3
- package/src/internal/Webhooks.ts +3 -3
- package/dist/apps/platform/App.d.ts.map +0 -1
- package/dist/apps/platform/App.js.map +0 -1
- package/dist/apps/platform/index.d.ts +0 -2
- package/dist/apps/platform/index.d.ts.map +0 -1
- package/dist/apps/platform/index.js +0 -2
- package/dist/apps/platform/index.js.map +0 -1
- package/dist/apps/platform/routes/api-keys.d.ts.map +0 -1
- package/dist/apps/platform/routes/api-keys.js.map +0 -1
- package/dist/apps/platform/routes/invitations.d.ts.map +0 -1
- package/dist/apps/platform/routes/invitations.js.map +0 -1
- package/dist/apps/platform/routes/me.d.ts.map +0 -1
- package/dist/apps/platform/routes/me.js.map +0 -1
- package/dist/apps/platform/routes/members.d.ts.map +0 -1
- package/dist/apps/platform/routes/members.js.map +0 -1
- package/dist/apps/platform/routes/orgs.d.ts.map +0 -1
- package/dist/apps/platform/routes/orgs.js.map +0 -1
- package/dist/apps/platform/routes/projects.js.map +0 -1
- package/src/apps/platform/index.ts +0 -1
- package/src/apps/platform/routes/me.test.ts +0 -121
- /package/dist/apps/{platform → management}/routes/me.js +0 -0
- /package/dist/apps/{platform → management}/routes/members.d.ts +0 -0
- /package/dist/apps/{platform → management}/routes/members.js +0 -0
- /package/dist/apps/{platform → management}/routes/projects.js +0 -0
- /package/src/apps/{platform → management}/routes/me.ts +0 -0
- /package/src/apps/{platform → management}/routes/members.test.ts +0 -0
- /package/src/apps/{platform → management}/routes/members.ts +0 -0
- /package/src/apps/{platform → management}/routes/orgs.test.ts +0 -0
- /package/src/apps/{platform → management}/routes/projects.test.ts +0 -0
- /package/src/apps/{platform → management}/routes/projects.ts +0 -0
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
import type * as FundingRoutes from '../../internal/FundingRoutes.js'
|
|
2
|
+
|
|
3
|
+
type Fetch = typeof globalThis.fetch
|
|
4
|
+
|
|
5
|
+
const defaultAcrossBaseUrl = 'https://app.across.to/api'
|
|
6
|
+
const defaultRelayBaseUrl = 'https://api.relay.link'
|
|
7
|
+
|
|
8
|
+
/** Creates the live funding route adapters configured for this deployment. */
|
|
9
|
+
export function createAdapters(options: createAdapters.Options = {}) {
|
|
10
|
+
return {
|
|
11
|
+
...(options.across ? { across: across(options.across) } : {}),
|
|
12
|
+
...(options.relay ? { relay: relay(options.relay) } : {}),
|
|
13
|
+
} satisfies FundingRoutes.ProviderAdapters
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export declare namespace createAdapters {
|
|
17
|
+
/** Provider adapter factory options. Omit a provider to keep its routes static. */
|
|
18
|
+
type Options = {
|
|
19
|
+
/** Across quote adapter options. */
|
|
20
|
+
across?: across.Options | false | undefined
|
|
21
|
+
/** Relay quote adapter options. */
|
|
22
|
+
relay?: relay.Options | false | undefined
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Creates an Across quote adapter backed by `/suggested-fees`. */
|
|
27
|
+
export function across(options: across.Options): FundingRoutes.ProviderAdapter {
|
|
28
|
+
const baseUrl = normalizeBaseUrl(options.baseUrl ?? defaultAcrossBaseUrl)
|
|
29
|
+
const fetcher = options.fetch ?? globalThis.fetch
|
|
30
|
+
const now = options.now ?? (() => new Date())
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
async probeQuote({ route }, signal) {
|
|
34
|
+
const sourceChainId = providerChainId(route.sourceChain, 'across')
|
|
35
|
+
const destinationChainId = eip155ChainId(route.destinationChain)
|
|
36
|
+
const url = new URL(`${baseUrl}/suggested-fees`)
|
|
37
|
+
url.search = new URLSearchParams({
|
|
38
|
+
allowUnmatchedDecimals: 'true',
|
|
39
|
+
amount: route.sourceAmount.amount,
|
|
40
|
+
destinationChainId,
|
|
41
|
+
inputToken: route.sourceToken.address,
|
|
42
|
+
integratorId: options.integratorId,
|
|
43
|
+
originChainId: sourceChainId,
|
|
44
|
+
outputToken: route.destinationToken.address,
|
|
45
|
+
}).toString()
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
const body = await requestJson(url, {
|
|
49
|
+
fetcher,
|
|
50
|
+
headers: { Authorization: `Bearer ${options.apiKey}` },
|
|
51
|
+
signal,
|
|
52
|
+
})
|
|
53
|
+
return formatAcrossResult(route, body, now())
|
|
54
|
+
} catch (cause) {
|
|
55
|
+
const unavailable = providerUnavailable(cause, ['AMOUNT_TOO_HIGH', 'AMOUNT_TOO_LOW'])
|
|
56
|
+
if (!unavailable) throw cause
|
|
57
|
+
return unavailableResult({
|
|
58
|
+
detail: 'across:suggested-fees',
|
|
59
|
+
message: unavailable,
|
|
60
|
+
now: now(),
|
|
61
|
+
source: 'providerLimit',
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export declare namespace across {
|
|
69
|
+
/** Across quote adapter options. */
|
|
70
|
+
type Options = {
|
|
71
|
+
/** Across API key sent as a bearer token. */
|
|
72
|
+
apiKey: string
|
|
73
|
+
/** Across integrator id sent as the required query parameter. */
|
|
74
|
+
integratorId: string
|
|
75
|
+
/** Override for tests or non-production Across environments. */
|
|
76
|
+
baseUrl?: string | undefined
|
|
77
|
+
/** Fetch implementation override for tests. */
|
|
78
|
+
fetch?: Fetch | undefined
|
|
79
|
+
/** Clock override for deterministic tests. */
|
|
80
|
+
now?: (() => Date) | undefined
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Creates a Relay quote adapter backed by `/chains/liquidity` and `/quote/v2`. */
|
|
85
|
+
export function relay(options: relay.Options): FundingRoutes.ProviderAdapter {
|
|
86
|
+
const baseUrl = normalizeBaseUrl(options.baseUrl ?? defaultRelayBaseUrl)
|
|
87
|
+
const fetcher = options.fetch ?? globalThis.fetch
|
|
88
|
+
const now = options.now ?? (() => new Date())
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
async probeQuote({ route }, signal) {
|
|
92
|
+
const originChainId = providerChainId(route.sourceChain, 'relay')
|
|
93
|
+
const destinationChainId = eip155ChainId(route.destinationChain)
|
|
94
|
+
const headers = relayHeaders(options.apiKey)
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
const quote = await requestJson(new URL(`${baseUrl}/quote/v2`), {
|
|
98
|
+
body: {
|
|
99
|
+
amount: route.sourceAmount.amount,
|
|
100
|
+
destinationChainId: Number(destinationChainId),
|
|
101
|
+
destinationCurrency: route.destinationToken.address,
|
|
102
|
+
originChainId: Number(originChainId),
|
|
103
|
+
originCurrency: route.sourceToken.address,
|
|
104
|
+
recipient: options.recipientAddress ?? options.userAddress,
|
|
105
|
+
tradeType: 'EXACT_INPUT',
|
|
106
|
+
user: options.userAddress,
|
|
107
|
+
},
|
|
108
|
+
fetcher,
|
|
109
|
+
headers,
|
|
110
|
+
method: 'POST',
|
|
111
|
+
signal,
|
|
112
|
+
})
|
|
113
|
+
const liquidityUrl = new URL(`${baseUrl}/chains/liquidity`)
|
|
114
|
+
liquidityUrl.searchParams.set('chainId', destinationChainId)
|
|
115
|
+
const liquidity = await requestJson(liquidityUrl, { fetcher, headers, signal }).catch(
|
|
116
|
+
() => undefined,
|
|
117
|
+
)
|
|
118
|
+
return formatRelayResult(route, quote, liquidity, now())
|
|
119
|
+
} catch (cause) {
|
|
120
|
+
const unavailable = providerUnavailable(cause, [
|
|
121
|
+
'NO_QUOTES',
|
|
122
|
+
'NO_ROUTE',
|
|
123
|
+
'UNSUPPORTED_ROUTE',
|
|
124
|
+
])
|
|
125
|
+
if (!unavailable) throw cause
|
|
126
|
+
return unavailableResult({
|
|
127
|
+
detail: 'relay:quote-v2',
|
|
128
|
+
message: unavailable,
|
|
129
|
+
now: now(),
|
|
130
|
+
source: 'providerQuote',
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export declare namespace relay {
|
|
138
|
+
/** Relay quote adapter options. */
|
|
139
|
+
type Options = {
|
|
140
|
+
/** Probe wallet address required by Relay's quote API. */
|
|
141
|
+
userAddress: string
|
|
142
|
+
/** Optional recipient override; defaults to `userAddress`. */
|
|
143
|
+
recipientAddress?: string | undefined
|
|
144
|
+
/** Optional Relay API key for higher rate limits. */
|
|
145
|
+
apiKey?: string | undefined
|
|
146
|
+
/** Override for tests or Relay testnet environments. */
|
|
147
|
+
baseUrl?: string | undefined
|
|
148
|
+
/** Fetch implementation override for tests. */
|
|
149
|
+
fetch?: Fetch | undefined
|
|
150
|
+
/** Clock override for deterministic tests. */
|
|
151
|
+
now?: (() => Date) | undefined
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function formatAcrossResult(
|
|
156
|
+
route: FundingRoutes.RouteCandidate,
|
|
157
|
+
body: unknown,
|
|
158
|
+
now: Date,
|
|
159
|
+
): FundingRoutes.QuoteProbeResult {
|
|
160
|
+
const response = record(body)
|
|
161
|
+
const timestamp = integerString(response['timestamp'])
|
|
162
|
+
const sampledAt = timestamp ? isoFromUnixSeconds(timestamp) : now.toISOString()
|
|
163
|
+
const limits = acrossLimits(response['limits'])
|
|
164
|
+
const amountStatus = statusFromLimits(route.sourceAmount.amount, limits)
|
|
165
|
+
const status = response['isAmountTooLow'] === true ? 'unavailable' : amountStatus.status
|
|
166
|
+
const tier = response['isAmountTooLow'] === true ? 'unavailable' : amountStatus.tier
|
|
167
|
+
const outputAmount = decimalString(response['outputAmount'])
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
expiresAt: timestamp ? isoFromUnixSeconds((BigInt(timestamp) + 600n).toString()) : null,
|
|
171
|
+
limits,
|
|
172
|
+
outputAmount,
|
|
173
|
+
outputAmountFormatted: outputAmount
|
|
174
|
+
? decimalFromBaseUnits(outputAmount, route.destinationToken.decimals)
|
|
175
|
+
: null,
|
|
176
|
+
quality: {
|
|
177
|
+
availableVolumeUsd: stablecoinUsdCapacity(route, limits?.maxSourceAmount),
|
|
178
|
+
estimatedSeconds: nonnegativeInteger(response['estimatedFillTimeSec']),
|
|
179
|
+
feeBps: scaledPctToBps(
|
|
180
|
+
nestedString(response['totalRelayFee'], 'pct') ?? decimalString(response['relayFeePct']),
|
|
181
|
+
),
|
|
182
|
+
historicalVolumeUsd24h: null,
|
|
183
|
+
instantVolumeUsd: stablecoinUsdCapacity(route, limits?.instantSourceAmount),
|
|
184
|
+
liquiditySource: 'providerLimit',
|
|
185
|
+
score: scoreFor(tier),
|
|
186
|
+
sourceDetail: 'across:suggested-fees',
|
|
187
|
+
tier,
|
|
188
|
+
},
|
|
189
|
+
sampledAt,
|
|
190
|
+
status,
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function formatRelayResult(
|
|
195
|
+
route: FundingRoutes.RouteCandidate,
|
|
196
|
+
quote: unknown,
|
|
197
|
+
liquidity: unknown,
|
|
198
|
+
now: Date,
|
|
199
|
+
): FundingRoutes.QuoteProbeResult {
|
|
200
|
+
const details = record(record(quote)['details'])
|
|
201
|
+
const currencyOut = record(details['currencyOut'])
|
|
202
|
+
const outputAmount = decimalString(currencyOut['amount'])
|
|
203
|
+
const liquidityRow = relayLiquidity(liquidity, route)
|
|
204
|
+
const destinationLiquidity = decimalString(liquidityRow?.['balance'])
|
|
205
|
+
const availableVolumeUsd = decimalString(liquidityRow?.['amountUsd']) ?? null
|
|
206
|
+
const liquidityStatus = relayLiquidityStatus({ destinationLiquidity, outputAmount })
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
limits: null,
|
|
210
|
+
minimumOutputAmount: decimalString(currencyOut['minimumAmount']),
|
|
211
|
+
outputAmount,
|
|
212
|
+
outputAmountFormatted: outputAmount
|
|
213
|
+
? decimalFromBaseUnits(outputAmount, route.destinationToken.decimals)
|
|
214
|
+
: null,
|
|
215
|
+
quality: {
|
|
216
|
+
availableVolumeUsd: availableVolumeUsd,
|
|
217
|
+
estimatedSeconds: nonnegativeInteger(details['timeEstimate']),
|
|
218
|
+
feeBps: null,
|
|
219
|
+
historicalVolumeUsd24h: null,
|
|
220
|
+
instantVolumeUsd: availableVolumeUsd,
|
|
221
|
+
liquiditySource: 'providerQuote',
|
|
222
|
+
score: scoreFor(liquidityStatus.tier),
|
|
223
|
+
sourceDetail: 'relay:quote-v2',
|
|
224
|
+
tier: liquidityStatus.tier,
|
|
225
|
+
},
|
|
226
|
+
sampledAt: now.toISOString(),
|
|
227
|
+
status: liquidityStatus.status,
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function relayLiquidityStatus(options: {
|
|
232
|
+
destinationLiquidity: string | undefined
|
|
233
|
+
outputAmount: string | undefined
|
|
234
|
+
}): { status: FundingRoutes.RouteStatus; tier: FundingRoutes.QualityTier } {
|
|
235
|
+
if (!options.outputAmount) return { status: 'unknown', tier: 'unknown' }
|
|
236
|
+
if (!options.destinationLiquidity) return { status: 'unknown', tier: 'unknown' }
|
|
237
|
+
if (compareIntegerStrings(options.destinationLiquidity, options.outputAmount) < 0)
|
|
238
|
+
return { status: 'thin', tier: 'thin' }
|
|
239
|
+
return { status: 'available', tier: 'liquid' }
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function unavailableResult(options: {
|
|
243
|
+
detail: string
|
|
244
|
+
message: string
|
|
245
|
+
now: Date
|
|
246
|
+
source: string
|
|
247
|
+
}): FundingRoutes.QuoteProbeResult {
|
|
248
|
+
return {
|
|
249
|
+
quality: {
|
|
250
|
+
availableVolumeUsd: null,
|
|
251
|
+
estimatedSeconds: null,
|
|
252
|
+
feeBps: null,
|
|
253
|
+
historicalVolumeUsd24h: null,
|
|
254
|
+
instantVolumeUsd: null,
|
|
255
|
+
liquiditySource: options.source,
|
|
256
|
+
score: 0,
|
|
257
|
+
sourceDetail: `${options.detail}:${options.message}`,
|
|
258
|
+
tier: 'unavailable',
|
|
259
|
+
},
|
|
260
|
+
sampledAt: options.now.toISOString(),
|
|
261
|
+
status: 'unavailable',
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function acrossLimits(input: unknown): FundingRoutes.QuoteProbeLimits | null {
|
|
266
|
+
const limits = record(input)
|
|
267
|
+
const minSourceAmount = decimalString(limits['minDeposit'])
|
|
268
|
+
const maxSourceAmount = decimalString(limits['maxDeposit'])
|
|
269
|
+
const instantSourceAmount =
|
|
270
|
+
decimalString(limits['maxDepositInstant']) ?? decimalString(limits['recommendedDepositInstant'])
|
|
271
|
+
return minSourceAmount || maxSourceAmount || instantSourceAmount
|
|
272
|
+
? { instantSourceAmount, maxSourceAmount, minSourceAmount }
|
|
273
|
+
: null
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function statusFromLimits(
|
|
277
|
+
amount: string,
|
|
278
|
+
limits: FundingRoutes.QuoteProbeLimits | null,
|
|
279
|
+
): { status: FundingRoutes.RouteStatus; tier: FundingRoutes.QualityTier } {
|
|
280
|
+
if (!limits) return { status: 'available', tier: 'liquid' }
|
|
281
|
+
if (limits.minSourceAmount && compareIntegerStrings(amount, limits.minSourceAmount) < 0)
|
|
282
|
+
return { status: 'unavailable', tier: 'unavailable' }
|
|
283
|
+
if (limits.maxSourceAmount && compareIntegerStrings(amount, limits.maxSourceAmount) > 0)
|
|
284
|
+
return { status: 'unavailable', tier: 'unavailable' }
|
|
285
|
+
if (limits.instantSourceAmount && compareIntegerStrings(amount, limits.instantSourceAmount) > 0)
|
|
286
|
+
return { status: 'thin', tier: 'thin' }
|
|
287
|
+
return { status: 'available', tier: 'liquid' }
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function relayLiquidity(input: unknown, route: FundingRoutes.RouteCandidate) {
|
|
291
|
+
const response = record(input)
|
|
292
|
+
const rows = Array.isArray(response['liquidity']) ? response['liquidity'] : []
|
|
293
|
+
const destinationChainId = eip155ChainId(route.destinationChain)
|
|
294
|
+
return rows.map(record).find((row) => {
|
|
295
|
+
const rowChainId = integerString(row['chainId'])
|
|
296
|
+
const rowAddress = typeof row['address'] === 'string' ? row['address'].toLowerCase() : undefined
|
|
297
|
+
return (
|
|
298
|
+
rowChainId === destinationChainId &&
|
|
299
|
+
rowAddress === route.destinationToken.address.toLowerCase()
|
|
300
|
+
)
|
|
301
|
+
})
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
async function requestJson(
|
|
305
|
+
url: URL,
|
|
306
|
+
options: {
|
|
307
|
+
body?: unknown
|
|
308
|
+
fetcher: Fetch
|
|
309
|
+
headers?: Record<string, string> | undefined
|
|
310
|
+
method?: string | undefined
|
|
311
|
+
signal: AbortSignal
|
|
312
|
+
},
|
|
313
|
+
) {
|
|
314
|
+
const headers = { accept: 'application/json', ...options.headers }
|
|
315
|
+
const init: RequestInit = {
|
|
316
|
+
headers:
|
|
317
|
+
options.body === undefined ? headers : { ...headers, 'content-type': 'application/json' },
|
|
318
|
+
method: options.method ?? 'GET',
|
|
319
|
+
signal: options.signal,
|
|
320
|
+
}
|
|
321
|
+
if (options.body !== undefined) init.body = JSON.stringify(options.body)
|
|
322
|
+
const response = await options.fetcher(url, init)
|
|
323
|
+
const text = await response.text()
|
|
324
|
+
const body = parseJson(text)
|
|
325
|
+
if (!response.ok) throw new ProviderResponseError(response.status, body)
|
|
326
|
+
return body
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function relayHeaders(apiKey: string | undefined): Record<string, string> | undefined {
|
|
330
|
+
return apiKey ? { 'x-api-key': apiKey } : undefined
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function providerUnavailable(cause: unknown, codes: readonly string[]) {
|
|
334
|
+
if (!(cause instanceof ProviderResponseError) || cause.status < 400 || cause.status >= 500)
|
|
335
|
+
return undefined
|
|
336
|
+
const body = record(cause.body)
|
|
337
|
+
const code = stringValue(body['code']) ?? stringValue(body['errorCode'])
|
|
338
|
+
if (code && codes.includes(code)) return code
|
|
339
|
+
return undefined
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
class ProviderResponseError extends Error {
|
|
343
|
+
override name = 'FundingRouteProviders.ProviderResponseError'
|
|
344
|
+
|
|
345
|
+
constructor(
|
|
346
|
+
readonly status: number,
|
|
347
|
+
readonly body: unknown,
|
|
348
|
+
) {
|
|
349
|
+
super(`Provider request failed with status ${status}`)
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function providerChainId(
|
|
354
|
+
routeChain: FundingRoutes.RouteCandidate['sourceChain'],
|
|
355
|
+
provider: string,
|
|
356
|
+
) {
|
|
357
|
+
const providerIds = routeChain.providerIds as Record<string, string> | undefined
|
|
358
|
+
const id = providerIds?.[provider]
|
|
359
|
+
if (id && /^\d+$/.test(id)) return id
|
|
360
|
+
return eip155ChainId(routeChain)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
function eip155ChainId(chain: { id: string; kind: string }) {
|
|
364
|
+
if (chain.kind !== 'evm') throw new UnsupportedProviderRouteError()
|
|
365
|
+
const match = /^eip155:(\d+)$/.exec(chain.id)
|
|
366
|
+
if (!match?.[1]) throw new UnsupportedProviderRouteError()
|
|
367
|
+
return match[1]
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
class UnsupportedProviderRouteError extends Error {
|
|
371
|
+
override name = 'FundingRouteProviders.UnsupportedProviderRouteError'
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function normalizeBaseUrl(input: string) {
|
|
375
|
+
return input.replace(/\/+$/, '')
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function parseJson(input: string) {
|
|
379
|
+
if (!input) return null
|
|
380
|
+
try {
|
|
381
|
+
return JSON.parse(input) as unknown
|
|
382
|
+
} catch {
|
|
383
|
+
return input
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function record(input: unknown): Record<string, unknown> {
|
|
388
|
+
return input && typeof input === 'object' && !Array.isArray(input)
|
|
389
|
+
? (input as Record<string, unknown>)
|
|
390
|
+
: {}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function stringValue(input: unknown) {
|
|
394
|
+
return typeof input === 'string' && input.length > 0 ? input : undefined
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function decimalString(input: unknown) {
|
|
398
|
+
if (typeof input === 'string' && /^\d+(\.\d+)?$/.test(input)) return input
|
|
399
|
+
if (typeof input === 'number' && Number.isFinite(input) && input >= 0) return String(input)
|
|
400
|
+
return undefined
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
function integerString(input: unknown) {
|
|
404
|
+
if (typeof input === 'string' && /^\d+$/.test(input)) return input
|
|
405
|
+
if (typeof input === 'number' && Number.isSafeInteger(input) && input >= 0) return String(input)
|
|
406
|
+
return undefined
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
function nestedString(input: unknown, key: string) {
|
|
410
|
+
return decimalString(record(input)[key])
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
function nonnegativeInteger(input: unknown) {
|
|
414
|
+
if (typeof input === 'number' && Number.isSafeInteger(input) && input >= 0) return input
|
|
415
|
+
if (typeof input === 'string' && /^\d+$/.test(input)) return Number(input)
|
|
416
|
+
return null
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
function decimalFromBaseUnits(baseUnits: string, decimals: number) {
|
|
420
|
+
const padded = baseUnits.padStart(decimals + 1, '0')
|
|
421
|
+
const whole = decimals === 0 ? padded : padded.slice(0, -decimals)
|
|
422
|
+
const fraction = decimals === 0 ? '' : padded.slice(-decimals).replace(/0+$/, '')
|
|
423
|
+
return fraction ? `${whole}.${fraction}` : whole
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
function compareIntegerStrings(left: string, right: string) {
|
|
427
|
+
return BigInt(left) === BigInt(right) ? 0 : BigInt(left) > BigInt(right) ? 1 : -1
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
function isoFromUnixSeconds(input: string) {
|
|
431
|
+
return new Date(Number(input) * 1_000).toISOString()
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
function stablecoinUsdCapacity(
|
|
435
|
+
route: FundingRoutes.RouteCandidate,
|
|
436
|
+
baseUnits: string | null | undefined,
|
|
437
|
+
) {
|
|
438
|
+
if (!baseUnits || !isDollarStablecoin(route.sourceToken.symbol)) return null
|
|
439
|
+
return decimalFromBaseUnits(baseUnits, route.sourceToken.decimals)
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
function isDollarStablecoin(symbol: string) {
|
|
443
|
+
return ['DAI', 'FRXUSD', 'PYUSD', 'USDC', 'USDC.E', 'USDT', 'USDT0'].includes(
|
|
444
|
+
symbol.toUpperCase(),
|
|
445
|
+
)
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
function scaledPctToBps(input: string | undefined) {
|
|
449
|
+
if (!input || !/^\d+$/.test(input)) return null
|
|
450
|
+
const denominator = 1_000_000_000_000_000_000n
|
|
451
|
+
return Number((BigInt(input) * 10_000n + denominator / 2n) / denominator)
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
function scoreFor(tier: FundingRoutes.QualityTier) {
|
|
455
|
+
if (tier === 'liquid') return 90
|
|
456
|
+
if (tier === 'thin') return 65
|
|
457
|
+
if (tier === 'unavailable') return 0
|
|
458
|
+
return null
|
|
459
|
+
}
|
package/src/apps/data/index.ts
CHANGED