tapimo 0.15.1 → 0.18.1
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 +137 -0
- package/dist/ApiKey.d.ts +1 -0
- package/dist/ApiKey.d.ts.map +1 -1
- package/dist/ApiKey.js +4 -2
- package/dist/ApiKey.js.map +1 -1
- package/dist/ApiKeys.d.ts +37 -11
- package/dist/ApiKeys.d.ts.map +1 -1
- package/dist/ApiKeys.js +163 -10
- package/dist/ApiKeys.js.map +1 -1
- package/dist/App.d.ts +13085 -11974
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +46 -15
- package/dist/App.js.map +1 -1
- package/dist/Scope.d.ts +1 -1
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +1 -1
- package/dist/Scope.js.map +1 -1
- package/dist/admin/App.d.ts +893 -191
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/App.js +5 -1
- package/dist/admin/App.js.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +70 -70
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +8 -3
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/earn-vaults.d.ts +66 -27
- package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
- package/dist/admin/apps/earn-vaults.js +36 -7
- package/dist/admin/apps/earn-vaults.js.map +1 -1
- package/dist/admin/apps/organizations.d.ts +25 -25
- package/dist/admin/apps/organizations.d.ts.map +1 -1
- package/dist/admin/apps/organizations.js +5 -4
- package/dist/admin/apps/organizations.js.map +1 -1
- package/dist/admin/apps/route-policies.d.ts +632 -0
- package/dist/admin/apps/route-policies.d.ts.map +1 -0
- package/dist/admin/apps/route-policies.js +257 -0
- package/dist/admin/apps/route-policies.js.map +1 -0
- package/dist/admin/apps/routes-support.js +39 -3
- package/dist/admin/apps/routes-support.js.map +1 -1
- package/dist/admin/apps/routes.d.ts +529 -76
- package/dist/admin/apps/routes.d.ts.map +1 -1
- package/dist/admin/apps/routes.js +82 -1
- package/dist/admin/apps/routes.js.map +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +157 -157
- package/dist/admin/index.d.ts +0 -1
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +0 -1
- package/dist/admin/index.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 +205 -201
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/analytics/Analytics.d.ts.map +1 -1
- package/dist/analytics/Analytics.js +65 -1
- package/dist/analytics/Analytics.js.map +1 -1
- package/dist/analytics/tables/requestEvents.d.ts +1 -1
- package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
- package/dist/analytics/tables/requestEvents.js +58 -59
- package/dist/analytics/tables/requestEvents.js.map +1 -1
- package/dist/apps/data/App.d.ts +2709 -2670
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +357 -357
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +50 -0
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +248 -248
- package/dist/apps/data/routes/balances.d.ts +22 -22
- package/dist/apps/data/routes/balances.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.js +5 -7
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +125 -125
- package/dist/apps/data/routes/coingecko.d.ts +54 -54
- package/dist/apps/data/routes/earn.d.ts +103 -12
- package/dist/apps/data/routes/earn.d.ts.map +1 -1
- package/dist/apps/data/routes/earn.js +456 -220
- package/dist/apps/data/routes/earn.js.map +1 -1
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
- package/dist/apps/data/routes/exchanges.js +267 -97
- package/dist/apps/data/routes/exchanges.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts +109 -127
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
- package/dist/apps/data/routes/fee-amm.js +83 -54
- package/dist/apps/data/routes/fee-amm.js.map +1 -1
- package/dist/apps/data/routes/indexer.d.ts +43 -43
- package/dist/apps/data/routes/receipts.d.ts +235 -235
- package/dist/apps/data/routes/rpc.d.ts +30 -30
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +11 -6
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.d.ts +2 -0
- package/dist/apps/data/routes/transactions.d.ts.map +1 -1
- package/dist/apps/data/routes/transactions.js +30 -22
- package/dist/apps/data/routes/transactions.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +77 -77
- package/dist/apps/data/routes/valuation.d.ts +32 -32
- package/dist/apps/data/routes/verified-tokens.d.ts +86 -86
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +1 -1
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/data/routes/zones.d.ts +31 -31
- package/dist/apps/management/App.d.ts +2909 -2064
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/App.js +2 -0
- package/dist/apps/management/App.js.map +1 -1
- package/dist/apps/management/Billing.d.ts +2 -4
- package/dist/apps/management/Billing.d.ts.map +1 -1
- package/dist/apps/management/Billing.js +65 -26
- package/dist/apps/management/Billing.js.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +257 -245
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +70 -11
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +84 -84
- package/dist/apps/management/routes/cli.d.ts +912 -0
- package/dist/apps/management/routes/cli.d.ts.map +1 -0
- package/dist/apps/management/routes/cli.js +416 -0
- package/dist/apps/management/routes/cli.js.map +1 -0
- package/dist/apps/management/routes/faucet.d.ts +8 -8
- package/dist/apps/management/routes/invitations.d.ts +138 -138
- package/dist/apps/management/routes/invite-links.d.ts +172 -172
- package/dist/apps/management/routes/members.d.ts +16 -16
- package/dist/apps/management/routes/orgs.d.ts +104 -104
- package/dist/apps/management/routes/orgs.d.ts.map +1 -1
- package/dist/apps/management/routes/orgs.js +8 -2
- package/dist/apps/management/routes/orgs.js.map +1 -1
- package/dist/apps/management/routes/projects.d.ts +125 -125
- package/dist/apps/management/routes/usage.d.ts +8 -8
- package/dist/apps/management/routes/verified-token-requests.d.ts +86 -86
- package/dist/apps/management/routes/webhooks.d.ts +485 -485
- package/dist/apps/mpp/App.d.ts +44 -44
- package/dist/apps/mpp/internal/Policy.d.ts.map +1 -1
- package/dist/apps/mpp/internal/Policy.js +4 -2
- package/dist/apps/mpp/internal/Policy.js.map +1 -1
- package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -1
- package/dist/apps/mpp/internal/Sponsorship.js +6 -4
- package/dist/apps/mpp/internal/Sponsorship.js.map +1 -1
- package/dist/apps/relay/App.d.ts +8 -0
- package/dist/apps/relay/App.d.ts.map +1 -1
- package/dist/apps/relay/App.js +16 -4
- package/dist/apps/relay/App.js.map +1 -1
- package/dist/apps/relay/Sponsorships.d.ts +4 -6
- package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
- package/dist/apps/relay/Sponsorships.js +71 -60
- package/dist/apps/relay/Sponsorships.js.map +1 -1
- package/dist/apps/routes/Access.d.ts +53 -0
- package/dist/apps/routes/Access.d.ts.map +1 -1
- package/dist/apps/routes/Access.js +121 -0
- package/dist/apps/routes/Access.js.map +1 -1
- package/dist/apps/routes/App.d.ts +397 -158
- package/dist/apps/routes/App.d.ts.map +1 -1
- package/dist/apps/routes/App.js.map +1 -1
- package/dist/apps/routes/routes/chains.d.ts +25 -25
- package/dist/apps/routes/routes/deposit-addresses.d.ts +169 -61
- package/dist/apps/routes/routes/deposit-addresses.d.ts.map +1 -1
- package/dist/apps/routes/routes/deposit-addresses.js +217 -32
- package/dist/apps/routes/routes/deposit-addresses.js.map +1 -1
- package/dist/apps/routes/routes/quotes.d.ts +171 -81
- package/dist/apps/routes/routes/quotes.d.ts.map +1 -1
- package/dist/apps/routes/routes/quotes.js +101 -27
- package/dist/apps/routes/routes/quotes.js.map +1 -1
- package/dist/apps/routes/routes/transfers.d.ts +532 -480
- package/dist/apps/routes/routes/transfers.d.ts.map +1 -1
- package/dist/apps/routes/routes/transfers.js +182 -37
- package/dist/apps/routes/routes/transfers.js.map +1 -1
- package/dist/cli/ApiKeys.d.ts +120 -0
- package/dist/cli/ApiKeys.d.ts.map +1 -0
- package/dist/cli/ApiKeys.js +138 -0
- package/dist/cli/ApiKeys.js.map +1 -0
- package/dist/cli/Cli.d.ts +92 -34
- package/dist/cli/Cli.d.ts.map +1 -1
- package/dist/cli/Cli.js +188 -11
- package/dist/cli/Cli.js.map +1 -1
- package/dist/cli/Credentials.d.ts +95 -0
- package/dist/cli/Credentials.d.ts.map +1 -0
- package/dist/cli/Credentials.js +110 -0
- package/dist/cli/Credentials.js.map +1 -0
- package/dist/cli/Spec.d.ts +59 -0
- package/dist/cli/Spec.d.ts.map +1 -0
- package/dist/cli/Spec.js +77 -0
- package/dist/cli/Spec.js.map +1 -0
- package/dist/cli/bin.js +5 -1
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/commands/admin.d.ts +5 -5
- package/dist/cli/commands/admin.d.ts.map +1 -1
- package/dist/cli/commands/auth.d.ts +73 -0
- package/dist/cli/commands/auth.d.ts.map +1 -0
- package/dist/cli/commands/auth.js +204 -0
- package/dist/cli/commands/auth.js.map +1 -0
- package/dist/cli/commands/keys.d.ts +17 -0
- package/dist/cli/commands/keys.d.ts.map +1 -0
- package/dist/cli/commands/keys.js +109 -0
- package/dist/cli/commands/keys.js.map +1 -0
- package/dist/cloudflare.d.ts +27 -2
- package/dist/cloudflare.d.ts.map +1 -1
- package/dist/cloudflare.js +144 -17
- package/dist/cloudflare.js.map +1 -1
- package/dist/db/Db.d.ts +23 -0
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +413 -1
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +44 -1
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +56 -3
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/apiKeyAdmissions.d.ts +28 -2
- package/dist/db/tables/apiKeyAdmissions.d.ts.map +1 -1
- package/dist/db/tables/apiKeyAdmissions.js +65 -9
- package/dist/db/tables/apiKeyAdmissions.js.map +1 -1
- package/dist/db/tables/apiKeyOwnerTombstones.d.ts +2 -0
- package/dist/db/tables/apiKeyOwnerTombstones.d.ts.map +1 -1
- package/dist/db/tables/apiKeyOwnerTombstones.js +2 -2
- package/dist/db/tables/apiKeyOwnerTombstones.js.map +1 -1
- package/dist/db/tables/authAccounts.d.ts.map +1 -1
- package/dist/db/tables/authAccounts.js +1 -0
- package/dist/db/tables/authAccounts.js.map +1 -1
- package/dist/db/tables/earnVaults.d.ts +5 -1
- package/dist/db/tables/earnVaults.d.ts.map +1 -1
- package/dist/db/tables/earnVaults.js +12 -1
- package/dist/db/tables/earnVaults.js.map +1 -1
- package/dist/db/tables/organizations.d.ts +4 -2
- package/dist/db/tables/organizations.d.ts.map +1 -1
- package/dist/db/tables/organizations.js +8 -34
- package/dist/db/tables/organizations.js.map +1 -1
- package/dist/db/tables/requestUsage.d.ts +5 -1
- package/dist/db/tables/requestUsage.d.ts.map +1 -1
- package/dist/db/tables/requestUsage.js +10 -2
- package/dist/db/tables/requestUsage.js.map +1 -1
- package/dist/db/tables/rewardEligibilityAssociations.d.ts +13 -0
- package/dist/db/tables/rewardEligibilityAssociations.d.ts.map +1 -1
- package/dist/db/tables/rewardEligibilityAssociations.js +11 -0
- package/dist/db/tables/rewardEligibilityAssociations.js.map +1 -1
- package/dist/db/tables/rewardRuns.d.ts.map +1 -1
- package/dist/db/tables/rewardRuns.js +4 -0
- package/dist/db/tables/rewardRuns.js.map +1 -1
- package/dist/db/tables/rewardTransactionAttempts.d.ts.map +1 -1
- package/dist/db/tables/rewardTransactionAttempts.js +2 -0
- package/dist/db/tables/rewardTransactionAttempts.js.map +1 -1
- package/dist/db/tables/routesDepositAddresses.d.ts +29 -0
- package/dist/db/tables/routesDepositAddresses.d.ts.map +1 -1
- package/dist/db/tables/routesDepositAddresses.js +84 -31
- package/dist/db/tables/routesDepositAddresses.js.map +1 -1
- package/dist/db/tables/routesDeposits.d.ts.map +1 -1
- package/dist/db/tables/routesDeposits.js +31 -21
- package/dist/db/tables/routesDeposits.js.map +1 -1
- package/dist/db/tables/routesIdempotency.d.ts.map +1 -1
- package/dist/db/tables/routesIdempotency.js +2 -0
- package/dist/db/tables/routesIdempotency.js.map +1 -1
- package/dist/db/tables/routesPolicies.d.ts +58 -0
- package/dist/db/tables/routesPolicies.d.ts.map +1 -0
- package/dist/db/tables/routesPolicies.js +198 -0
- package/dist/db/tables/routesPolicies.js.map +1 -0
- package/dist/db/tables/routesTransferSubsidies.d.ts +22 -0
- package/dist/db/tables/routesTransferSubsidies.d.ts.map +1 -1
- package/dist/db/tables/routesTransferSubsidies.js +41 -0
- package/dist/db/tables/routesTransferSubsidies.js.map +1 -1
- package/dist/db/tables/routesTransferSubsidyNonces.d.ts.map +1 -1
- package/dist/db/tables/routesTransferSubsidyNonces.js +12 -4
- package/dist/db/tables/routesTransferSubsidyNonces.js.map +1 -1
- package/dist/db/tables/routesTransfers.d.ts +26 -1
- package/dist/db/tables/routesTransfers.d.ts.map +1 -1
- package/dist/db/tables/routesTransfers.js +36 -6
- package/dist/db/tables/routesTransfers.js.map +1 -1
- package/dist/db/tables/sponsoredTransactions.d.ts +45 -13
- package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
- package/dist/db/tables/sponsoredTransactions.js +144 -33
- package/dist/db/tables/sponsoredTransactions.js.map +1 -1
- package/dist/db/tables/users.d.ts +2 -0
- package/dist/db/tables/users.d.ts.map +1 -1
- package/dist/db/tables/users.js +11 -0
- package/dist/db/tables/users.js.map +1 -1
- package/dist/handlers/internal/multisig.d.ts +1 -1
- package/dist/handlers/internal/multisig.d.ts.map +1 -1
- package/dist/handlers/internal/multisig.js +3 -2
- package/dist/handlers/internal/multisig.js.map +1 -1
- package/dist/handlers/relay.d.ts +2 -0
- package/dist/handlers/relay.d.ts.map +1 -1
- package/dist/handlers/relay.js +34 -15
- package/dist/handlers/relay.js.map +1 -1
- package/dist/internal/Auth.d.ts +57 -6
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +182 -78
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/BetterAuth.d.ts +22 -0
- package/dist/internal/BetterAuth.d.ts.map +1 -1
- package/dist/internal/BetterAuth.js +17 -14
- package/dist/internal/BetterAuth.js.map +1 -1
- package/dist/internal/Cache.d.ts +5 -0
- package/dist/internal/Cache.d.ts.map +1 -1
- package/dist/internal/Cache.js +3 -1
- package/dist/internal/Cache.js.map +1 -1
- package/dist/internal/CliAuth.d.ts +243 -0
- package/dist/internal/CliAuth.d.ts.map +1 -0
- package/dist/internal/CliAuth.js +249 -0
- package/dist/internal/CliAuth.js.map +1 -0
- package/dist/internal/EarnSharePrices.d.ts +1 -1
- package/dist/internal/EarnSharePrices.d.ts.map +1 -1
- package/dist/internal/EarnSharePrices.js +7 -3
- package/dist/internal/EarnSharePrices.js.map +1 -1
- package/dist/internal/EarnVaults.d.ts +47 -0
- package/dist/internal/EarnVaults.d.ts.map +1 -1
- package/dist/internal/EarnVaults.js +188 -4
- package/dist/internal/EarnVaults.js.map +1 -1
- package/dist/internal/EarnWithdrawals.d.ts +73 -0
- package/dist/internal/EarnWithdrawals.d.ts.map +1 -0
- package/dist/internal/EarnWithdrawals.js +189 -0
- package/dist/internal/EarnWithdrawals.js.map +1 -0
- package/dist/internal/ExecutionContext.d.ts +21 -0
- package/dist/internal/ExecutionContext.d.ts.map +1 -0
- package/dist/internal/ExecutionContext.js +16 -0
- package/dist/internal/ExecutionContext.js.map +1 -0
- package/dist/internal/Log.d.ts +7 -3
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +163 -130
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/MetricSink.d.ts.map +1 -1
- package/dist/internal/MetricSink.js +26 -1
- package/dist/internal/MetricSink.js.map +1 -1
- package/dist/internal/RateLimit.d.ts +67 -0
- package/dist/internal/RateLimit.d.ts.map +1 -1
- package/dist/internal/RateLimit.js +174 -27
- package/dist/internal/RateLimit.js.map +1 -1
- package/dist/internal/Store.d.ts +6 -0
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +4 -5
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/Timing.d.ts +6 -0
- package/dist/internal/Timing.d.ts.map +1 -1
- package/dist/internal/Timing.js +21 -1
- package/dist/internal/Timing.js.map +1 -1
- package/dist/internal/Tron.d.ts +124 -0
- package/dist/internal/Tron.d.ts.map +1 -0
- package/dist/internal/Tron.js +202 -0
- package/dist/internal/Tron.js.map +1 -0
- package/dist/internal/Viem.d.ts +4 -0
- package/dist/internal/Viem.d.ts.map +1 -1
- package/dist/internal/Viem.js +25 -6
- package/dist/internal/Viem.js.map +1 -1
- package/dist/internal/rewards/Read.d.ts +2 -2
- package/dist/internal/rewards/Read.d.ts.map +1 -1
- package/dist/internal/rewards/Read.js +11 -2
- package/dist/internal/rewards/Read.js.map +1 -1
- package/dist/internal/routes/Action.d.ts +27 -0
- package/dist/internal/routes/Action.d.ts.map +1 -1
- package/dist/internal/routes/Action.js +49 -1
- package/dist/internal/routes/Action.js.map +1 -1
- package/dist/internal/routes/Chain.d.ts +2 -0
- package/dist/internal/routes/Chain.d.ts.map +1 -1
- package/dist/internal/routes/Chain.js +4 -0
- package/dist/internal/routes/Chain.js.map +1 -1
- package/dist/internal/routes/DepositAddress.d.ts.map +1 -1
- package/dist/internal/routes/DepositAddress.js +5 -0
- package/dist/internal/routes/DepositAddress.js.map +1 -1
- package/dist/internal/routes/Evidence.d.ts.map +1 -1
- package/dist/internal/routes/Evidence.js +6 -2
- package/dist/internal/routes/Evidence.js.map +1 -1
- package/dist/internal/routes/EvmTransferSettlement.d.ts +17 -0
- package/dist/internal/routes/EvmTransferSettlement.d.ts.map +1 -0
- package/dist/internal/routes/EvmTransferSettlement.js +196 -0
- package/dist/internal/routes/EvmTransferSettlement.js.map +1 -0
- package/dist/internal/routes/Policy.d.ts +161 -0
- package/dist/internal/routes/Policy.d.ts.map +1 -0
- package/dist/internal/routes/Policy.js +249 -0
- package/dist/internal/routes/Policy.js.map +1 -0
- package/dist/internal/routes/Provider.d.ts +66 -3
- package/dist/internal/routes/Provider.d.ts.map +1 -1
- package/dist/internal/routes/Provider.js +106 -27
- package/dist/internal/routes/Provider.js.map +1 -1
- package/dist/internal/routes/Quota.d.ts +57 -0
- package/dist/internal/routes/Quota.d.ts.map +1 -0
- package/dist/internal/routes/Quota.js +144 -0
- package/dist/internal/routes/Quota.js.map +1 -0
- package/dist/internal/routes/Reconciliation.d.ts.map +1 -1
- package/dist/internal/routes/Reconciliation.js +163 -47
- package/dist/internal/routes/Reconciliation.js.map +1 -1
- package/dist/internal/routes/SolanaTransferSettlement.d.ts +12 -0
- package/dist/internal/routes/SolanaTransferSettlement.d.ts.map +1 -0
- package/dist/internal/routes/SolanaTransferSettlement.js +220 -0
- package/dist/internal/routes/SolanaTransferSettlement.js.map +1 -0
- package/dist/internal/routes/SolanaTransferSubsidy.d.ts +172 -0
- package/dist/internal/routes/SolanaTransferSubsidy.d.ts.map +1 -0
- package/dist/internal/routes/SolanaTransferSubsidy.js +564 -0
- package/dist/internal/routes/SolanaTransferSubsidy.js.map +1 -0
- package/dist/internal/routes/Subsidy.d.ts +2 -2
- package/dist/internal/routes/Subsidy.d.ts.map +1 -1
- package/dist/internal/routes/Subsidy.js +2 -2
- package/dist/internal/routes/Subsidy.js.map +1 -1
- package/dist/internal/routes/Transfer.d.ts +229 -1
- package/dist/internal/routes/Transfer.d.ts.map +1 -1
- package/dist/internal/routes/Transfer.js +644 -7
- package/dist/internal/routes/Transfer.js.map +1 -1
- package/dist/internal/routes/TransferReconciliation.d.ts +6 -0
- package/dist/internal/routes/TransferReconciliation.d.ts.map +1 -1
- package/dist/internal/routes/TransferReconciliation.js +83 -159
- package/dist/internal/routes/TransferReconciliation.js.map +1 -1
- package/dist/internal/routes/TransferSettlement.d.ts +45 -0
- package/dist/internal/routes/TransferSettlement.d.ts.map +1 -0
- package/dist/internal/routes/TransferSettlement.js +2 -0
- package/dist/internal/routes/TransferSettlement.js.map +1 -0
- package/dist/internal/routes/TransferSubsidy.d.ts +23 -8
- package/dist/internal/routes/TransferSubsidy.d.ts.map +1 -1
- package/dist/internal/routes/TransferSubsidy.js +64 -5
- package/dist/internal/routes/TransferSubsidy.js.map +1 -1
- package/dist/internal/routes/TronTransferSettlement.d.ts +12 -0
- package/dist/internal/routes/TronTransferSettlement.d.ts.map +1 -0
- package/dist/internal/routes/TronTransferSettlement.js +201 -0
- package/dist/internal/routes/TronTransferSettlement.js.map +1 -0
- package/dist/internal/routes/TronTransferSubsidy.d.ts +174 -0
- package/dist/internal/routes/TronTransferSubsidy.d.ts.map +1 -0
- package/dist/internal/routes/TronTransferSubsidy.js +439 -0
- package/dist/internal/routes/TronTransferSubsidy.js.map +1 -0
- package/dist/internal/routes/index.d.ts +3 -0
- package/dist/internal/routes/index.d.ts.map +1 -1
- package/dist/internal/routes/index.js +3 -0
- package/dist/internal/routes/index.js.map +1 -1
- package/dist/internal/routes/providers/across.d.ts +3 -0
- package/dist/internal/routes/providers/across.d.ts.map +1 -1
- package/dist/internal/routes/providers/across.js +11 -0
- package/dist/internal/routes/providers/across.js.map +1 -1
- package/dist/internal/routes/providers/legacyMesh.d.ts +29 -0
- package/dist/internal/routes/providers/legacyMesh.d.ts.map +1 -0
- package/dist/internal/routes/providers/legacyMesh.js +474 -0
- package/dist/internal/routes/providers/legacyMesh.js.map +1 -0
- package/dist/internal/routes/providers/legacyMeshDelivery.d.ts +59 -0
- package/dist/internal/routes/providers/legacyMeshDelivery.d.ts.map +1 -0
- package/dist/internal/routes/providers/legacyMeshDelivery.js +229 -0
- package/dist/internal/routes/providers/legacyMeshDelivery.js.map +1 -0
- package/dist/internal/routes/providers/legacyMeshOutbound.d.ts +19 -0
- package/dist/internal/routes/providers/legacyMeshOutbound.d.ts.map +1 -0
- package/dist/internal/routes/providers/legacyMeshOutbound.js +457 -0
- package/dist/internal/routes/providers/legacyMeshOutbound.js.map +1 -0
- package/dist/internal/routes/providers/legacyMeshOutboundDelivery.d.ts +123 -0
- package/dist/internal/routes/providers/legacyMeshOutboundDelivery.d.ts.map +1 -0
- package/dist/internal/routes/providers/legacyMeshOutboundDelivery.js +333 -0
- package/dist/internal/routes/providers/legacyMeshOutboundDelivery.js.map +1 -0
- package/dist/internal/routes/providers/propAmm.d.ts +70 -0
- package/dist/internal/routes/providers/propAmm.d.ts.map +1 -0
- package/dist/internal/routes/providers/propAmm.js +524 -0
- package/dist/internal/routes/providers/propAmm.js.map +1 -0
- package/dist/internal/routes/providers/relay.d.ts +3 -0
- package/dist/internal/routes/providers/relay.d.ts.map +1 -1
- package/dist/internal/routes/providers/relay.js +352 -41
- package/dist/internal/routes/providers/relay.js.map +1 -1
- package/dist/internal/routes/providers/rhino.d.ts +3 -0
- package/dist/internal/routes/providers/rhino.d.ts.map +1 -1
- package/dist/internal/routes/providers/rhino.js +11 -0
- package/dist/internal/routes/providers/rhino.js.map +1 -1
- package/dist/internal/routes/providers/squid.d.ts +3 -0
- package/dist/internal/routes/providers/squid.d.ts.map +1 -1
- package/dist/internal/routes/providers/squid.js +19 -0
- package/dist/internal/routes/providers/squid.js.map +1 -1
- package/dist/internal/routes/providers/stargate.d.ts.map +1 -1
- package/dist/internal/routes/providers/stargate.js +22 -9
- package/dist/internal/routes/providers/stargate.js.map +1 -1
- package/dist/internal/routes/providers/symbiosis.d.ts.map +1 -1
- package/dist/internal/routes/providers/symbiosis.js +13 -17
- package/dist/internal/routes/providers/symbiosis.js.map +1 -1
- package/dist/providers/index.d.ts +14 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +6 -0
- package/dist/providers/index.js.map +1 -1
- package/package.json +16 -6
- package/src/ApiKey.ts +7 -3
- package/src/ApiKeys.test.ts +652 -8
- package/src/ApiKeys.ts +191 -11
- package/src/App.test.ts +405 -18
- package/src/App.ts +51 -15
- package/src/Client.test-d.ts +157 -10
- package/src/Client.test.ts +4 -4
- package/src/Scope.ts +1 -2
- package/src/admin/App.ts +11 -5
- package/src/admin/apps/api-keys.test.ts +98 -2
- package/src/admin/apps/api-keys.ts +21 -12
- package/src/admin/apps/earn-vaults.test.ts +76 -7
- package/src/admin/apps/earn-vaults.ts +47 -8
- package/src/admin/apps/organizations.test.ts +147 -31
- package/src/admin/apps/organizations.ts +5 -4
- package/src/admin/apps/route-policies.test.ts +220 -0
- package/src/admin/apps/route-policies.ts +322 -0
- package/src/admin/apps/routes-support.test.ts +107 -2
- package/src/admin/apps/routes-support.ts +43 -3
- package/src/admin/apps/routes.test.ts +150 -0
- package/src/admin/apps/routes.ts +97 -1
- package/src/admin/apps/scopes.test.ts +1 -1
- package/src/admin/index.ts +0 -1
- package/src/admin/ui/plugin.ts +2 -1
- package/src/admin/ui/src/components/Dialog.tsx +1 -1
- package/src/admin/ui/src/components/EarnVaultForm.tsx +45 -0
- package/src/admin/ui/src/components/RoutePicker.tsx +79 -0
- package/src/admin/ui/src/lib/earn-vaults.ts +1 -1
- package/src/admin/ui/src/lib/route-policies.test.ts +452 -0
- package/src/admin/ui/src/lib/route-policies.ts +232 -0
- package/src/admin/ui/src/lib/routes.ts +34 -0
- package/src/admin/ui/src/routeTree.gen.ts +21 -0
- package/src/admin/ui/src/routes/api-keys.tsx +21 -2
- package/src/admin/ui/src/routes/early-access.tsx +1 -0
- package/src/admin/ui/src/routes/earn.vaults.tsx +1 -0
- package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +22 -0
- package/src/admin/ui/src/routes/earn.vaults_.new.tsx +10 -0
- package/src/admin/ui/src/routes/organizations.tsx +1 -0
- package/src/admin/ui/src/routes/organizations_.$orgId.tsx +18 -3
- package/src/admin/ui/src/routes/route-policies.tsx +678 -0
- package/src/admin/ui/src/routes/routes.tsx +85 -2
- package/src/admin/ui/src/routes/routes_.support.tsx +6 -22
- package/src/admin/ui/src/routes/subsidies.tsx +1 -0
- package/src/admin/ui/src/routes/verified-tokens.tsx +1 -0
- package/src/admin/ui.generated.ts +258 -202
- package/src/analytics/Analytics.test.ts +4 -50
- package/src/analytics/Analytics.ts +65 -1
- package/src/analytics/tables/requestEvents.test.ts +402 -1
- package/src/analytics/tables/requestEvents.ts +62 -93
- package/src/apps/data/routes/activities.test.ts +315 -14
- package/src/apps/data/routes/activities.ts +60 -0
- package/src/apps/data/routes/balances.ts +5 -7
- package/src/apps/data/routes/earn.bench.ts +18 -0
- package/src/apps/data/routes/earn.local.test.ts +507 -0
- package/src/apps/data/routes/earn.test.ts +405 -127
- package/src/apps/data/routes/earn.ts +660 -270
- package/src/apps/data/routes/exchanges.bench.ts +3 -1
- package/src/apps/data/routes/exchanges.test.ts +166 -2
- package/src/apps/data/routes/exchanges.ts +308 -101
- package/src/apps/data/routes/fee-amm.test.ts +134 -2
- package/src/apps/data/routes/fee-amm.ts +122 -60
- package/src/apps/data/routes/receipts.test.ts +21 -18
- package/src/apps/data/routes/rpc.test.ts +2 -2
- package/src/apps/data/routes/tokens.provenance.test.ts +157 -0
- package/src/apps/data/routes/tokens.test.ts +4 -4
- package/src/apps/data/routes/tokens.ts +11 -6
- package/src/apps/data/routes/transactions.test.ts +29 -0
- package/src/apps/data/routes/transactions.ts +33 -22
- package/src/apps/data/routes/webhooks.test.ts +12 -3
- package/src/apps/data/routes/webhooks.ts +2 -1
- package/src/apps/management/App.ts +4 -0
- package/src/apps/management/Billing.test.ts +253 -27
- package/src/apps/management/Billing.ts +83 -29
- package/src/apps/management/routes/api-keys.test.ts +1 -1
- package/src/apps/management/routes/api-keys.ts +85 -11
- package/src/apps/management/routes/billing.test.ts +68 -4
- package/src/apps/management/routes/cli.test.ts +370 -0
- package/src/apps/management/routes/cli.ts +533 -0
- package/src/apps/management/routes/me.test.ts +14 -4
- package/src/apps/management/routes/orgs.test.ts +108 -4
- package/src/apps/management/routes/orgs.ts +7 -2
- package/src/apps/management/routes/usage.test.ts +2 -2
- package/src/apps/mpp/internal/Policy.test.ts +51 -4
- package/src/apps/mpp/internal/Policy.ts +6 -2
- package/src/apps/mpp/internal/Sponsorship.test.ts +29 -0
- package/src/apps/mpp/internal/Sponsorship.ts +6 -4
- package/src/apps/relay/App.test.ts +85 -1
- package/src/apps/relay/App.ts +28 -4
- package/src/apps/relay/Sponsorships.test.ts +97 -1
- package/src/apps/relay/Sponsorships.ts +77 -66
- package/src/apps/routes/Access.test.ts +319 -0
- package/src/apps/routes/Access.ts +147 -0
- package/src/apps/routes/App.ts +10 -0
- package/src/apps/routes/routes/chains.test.ts +3 -2
- package/src/apps/routes/routes/deposit-addresses.test.ts +978 -34
- package/src/apps/routes/routes/deposit-addresses.ts +243 -32
- package/src/apps/routes/routes/propAmm.local.test.ts +951 -0
- package/src/apps/routes/routes/quotes.test.ts +81 -8
- package/src/apps/routes/routes/quotes.ts +109 -27
- package/src/apps/routes/routes/transfers.test.ts +252 -15
- package/src/apps/routes/routes/transfers.ts +212 -33
- package/src/cli/ApiKeys.test.ts +265 -0
- package/src/cli/ApiKeys.ts +189 -0
- package/src/cli/Cli.test.ts +188 -0
- package/src/cli/Cli.ts +280 -12
- package/src/cli/Credentials.test.ts +122 -0
- package/src/cli/Credentials.ts +144 -0
- package/src/cli/Spec.test.ts +133 -0
- package/src/cli/Spec.ts +132 -0
- package/src/cli/bin.test.ts +49 -0
- package/src/cli/bin.ts +5 -1
- package/src/cli/commands/auth.test.ts +138 -0
- package/src/cli/commands/auth.ts +254 -0
- package/src/cli/commands/keys.test.ts +68 -0
- package/src/cli/commands/keys.ts +125 -0
- package/src/cloudflare.ts +184 -36
- package/src/db/Db.test.ts +877 -0
- package/src/db/Db.ts +498 -1
- package/src/db/Schema.ts +75 -4
- package/src/db/tables/apiKeyAdmissions.test.ts +57 -0
- package/src/db/tables/apiKeyAdmissions.ts +101 -11
- package/src/db/tables/apiKeyOwnerTombstones.ts +2 -2
- package/src/db/tables/authAccounts.test.ts +30 -0
- package/src/db/tables/authAccounts.ts +1 -0
- package/src/db/tables/earnVaults.test.ts +34 -0
- package/src/db/tables/earnVaults.ts +17 -2
- package/src/db/tables/organizations.test.ts +148 -84
- package/src/db/tables/organizations.ts +11 -43
- package/src/db/tables/requestUsage.ts +13 -2
- package/src/db/tables/rewardCampaigns.test.ts +163 -0
- package/src/db/tables/rewardEligibilityAssociations.test.ts +14 -0
- package/src/db/tables/rewardEligibilityAssociations.ts +24 -0
- package/src/db/tables/rewardRuns.ts +4 -0
- package/src/db/tables/rewardTransactionAttempts.ts +2 -0
- package/src/db/tables/routesDepositAddresses.test.ts +263 -0
- package/src/db/tables/routesDepositAddresses.ts +118 -34
- package/src/db/tables/routesDeposits.test.ts +66 -5
- package/src/db/tables/routesDeposits.ts +47 -26
- package/src/db/tables/routesIdempotency.test.ts +80 -0
- package/src/db/tables/routesIdempotency.ts +2 -0
- package/src/db/tables/routesPolicies.test.ts +143 -0
- package/src/db/tables/routesPolicies.ts +251 -0
- package/src/db/tables/routesTransferSubsidies.ts +64 -0
- package/src/db/tables/routesTransferSubsidyNonces.ts +16 -4
- package/src/db/tables/routesTransfers.test.ts +183 -2
- package/src/db/tables/routesTransfers.ts +65 -6
- package/src/db/tables/sponsoredTransactions.test.ts +351 -76
- package/src/db/tables/sponsoredTransactions.ts +182 -38
- package/src/db/tables/users.test.ts +51 -0
- package/src/db/tables/users.ts +12 -0
- package/src/handlers/internal/multisig.store.test.ts +120 -0
- package/src/handlers/internal/multisig.test.ts +389 -0
- package/src/handlers/internal/multisig.ts +13 -10
- package/src/handlers/relay.test.ts +259 -83
- package/src/handlers/relay.ts +36 -17
- package/src/internal/Auth.test.ts +291 -8
- package/src/internal/Auth.ts +227 -96
- package/src/internal/BetterAuth.test.ts +58 -22
- package/src/internal/BetterAuth.ts +23 -17
- package/src/internal/Cache.ts +3 -1
- package/src/internal/CliAuth.test.ts +279 -0
- package/src/internal/CliAuth.ts +319 -0
- package/src/internal/EarnSharePrices.test.ts +25 -0
- package/src/internal/EarnSharePrices.ts +9 -2
- package/src/internal/EarnVaults.test.ts +67 -0
- package/src/internal/EarnVaults.ts +299 -4
- package/src/internal/EarnWithdrawals.test.ts +315 -0
- package/src/internal/EarnWithdrawals.ts +266 -0
- package/src/internal/ExecutionContext.ts +31 -0
- package/src/internal/Log.test.ts +210 -0
- package/src/internal/Log.ts +180 -142
- package/src/internal/MetricSink.test.ts +190 -15
- package/src/internal/MetricSink.ts +27 -1
- package/src/internal/RateLimit.test.ts +144 -8
- package/src/internal/RateLimit.ts +254 -26
- package/src/internal/Store.ts +4 -5
- package/src/internal/Timing.test.ts +32 -0
- package/src/internal/Timing.ts +20 -1
- package/src/internal/Tron.test-d.ts +22 -0
- package/src/internal/Tron.test.ts +94 -0
- package/src/internal/Tron.ts +289 -0
- package/src/internal/Viem.rpc.test.ts +76 -0
- package/src/internal/Viem.ts +29 -6
- package/src/internal/rewards/Read.test.ts +109 -0
- package/src/internal/rewards/Read.ts +13 -4
- package/src/internal/routes/Action.test.ts +70 -0
- package/src/internal/routes/Action.ts +76 -1
- package/src/internal/routes/Chain.test.ts +18 -0
- package/src/internal/routes/Chain.ts +5 -0
- package/src/internal/routes/DepositAddress.ts +5 -0
- package/src/internal/routes/Evidence.test.ts +64 -0
- package/src/internal/routes/Evidence.ts +11 -3
- package/src/internal/routes/EvmTransferSettlement.ts +213 -0
- package/src/internal/routes/Policy.test.ts +316 -0
- package/src/internal/routes/Policy.ts +399 -0
- package/src/internal/routes/Provider.test.ts +103 -2
- package/src/internal/routes/Provider.ts +149 -27
- package/src/internal/routes/Quota.test.ts +149 -0
- package/src/internal/routes/Quota.ts +226 -0
- package/src/internal/routes/Reconciliation.local.test.ts +285 -0
- package/src/internal/routes/Reconciliation.test.ts +371 -13
- package/src/internal/routes/Reconciliation.ts +193 -42
- package/src/internal/routes/SolanaTransferSettlement.ts +232 -0
- package/src/internal/routes/SolanaTransferSubsidy.test.ts +471 -0
- package/src/internal/routes/SolanaTransferSubsidy.ts +760 -0
- package/src/internal/routes/SourceObservation.test.ts +221 -0
- package/src/internal/routes/Subsidy.local.test.ts +46 -0
- package/src/internal/routes/Subsidy.ts +4 -2
- package/src/internal/routes/Transfer.solana.test.ts +389 -0
- package/src/internal/routes/Transfer.test.ts +130 -1
- package/src/internal/routes/Transfer.tron.test.ts +172 -0
- package/src/internal/routes/Transfer.ts +866 -8
- package/src/internal/routes/TransferReconciliation.test.ts +26 -4
- package/src/internal/routes/TransferReconciliation.ts +91 -166
- package/src/internal/routes/TransferSettlement.ts +48 -0
- package/src/internal/routes/TransferSubsidy.local.test.ts +143 -0
- package/src/internal/routes/TransferSubsidy.test.ts +34 -4
- package/src/internal/routes/TransferSubsidy.ts +87 -12
- package/src/internal/routes/TronTransferSettlement.ts +212 -0
- package/src/internal/routes/TronTransferSubsidy.test.ts +109 -0
- package/src/internal/routes/TronTransferSubsidy.ts +619 -0
- package/src/internal/routes/index.test.ts +3 -0
- package/src/internal/routes/index.ts +3 -0
- package/src/internal/routes/providers/across.ts +13 -0
- package/src/internal/routes/providers/index.test.ts +141 -0
- package/src/internal/routes/providers/legacyMesh.test.ts +484 -0
- package/src/internal/routes/providers/legacyMesh.ts +633 -0
- package/src/internal/routes/providers/legacyMeshDelivery.test.ts +306 -0
- package/src/internal/routes/providers/legacyMeshDelivery.ts +320 -0
- package/src/internal/routes/providers/legacyMeshOutbound.test.ts +401 -0
- package/src/internal/routes/providers/legacyMeshOutbound.ts +566 -0
- package/src/internal/routes/providers/legacyMeshOutboundDelivery.ts +473 -0
- package/src/internal/routes/providers/propAmm.ts +640 -0
- package/src/internal/routes/providers/relay.test.ts +1263 -41
- package/src/internal/routes/providers/relay.ts +423 -38
- package/src/internal/routes/providers/rhino.ts +14 -1
- package/src/internal/routes/providers/squid.ts +21 -0
- package/src/internal/routes/providers/stargate.test.ts +105 -1
- package/src/internal/routes/providers/stargate.ts +22 -9
- package/src/internal/routes/providers/symbiosis.ts +13 -47
- package/src/providers/index.test.ts +2 -0
- package/src/providers/index.ts +18 -0
- package/dist/admin/Access.d.ts +0 -39
- package/dist/admin/Access.d.ts.map +0 -1
- package/dist/admin/Access.js +0 -73
- package/dist/admin/Access.js.map +0 -1
- package/src/admin/Access.test.ts +0 -130
- package/src/admin/Access.ts +0 -85
|
@@ -1,24 +1,51 @@
|
|
|
1
|
-
import { AbiEvent, AbiFunction, Address, Base58, Bytes, Hash, Hex } from 'ox'
|
|
1
|
+
import { AbiEvent, AbiFunction, Address, Base58, Bytes, Hash, Hex, Value as core_Value } from 'ox'
|
|
2
2
|
import { getBlockNumber, getLogs, getTransaction, getTransactionReceipt } from 'viem/actions'
|
|
3
3
|
import * as z from 'zod/mini'
|
|
4
4
|
|
|
5
5
|
import * as Db from '../../../db/Db.js'
|
|
6
6
|
import * as RoutesDepositAddresses from '../../../db/tables/routesDepositAddresses.js'
|
|
7
7
|
import * as RoutesDepositRequestObservations from '../../../db/tables/routesDepositRequestObservations.js'
|
|
8
|
+
import * as Store from '../../Store.js'
|
|
8
9
|
import * as Value from '../../Value.js'
|
|
9
10
|
import * as Viem from '../../Viem.js'
|
|
10
11
|
import * as RoutesCatalog from '../Catalog.js'
|
|
11
12
|
import * as RoutesChain from '../Chain.js'
|
|
12
13
|
import * as Evidence from '../Evidence.js'
|
|
13
14
|
import * as RoutesProvider from '../Provider.js'
|
|
15
|
+
import * as ProviderQuota from '../Quota.js'
|
|
14
16
|
import * as Subsidy from '../Subsidy.js'
|
|
15
17
|
|
|
16
18
|
const defaultBaseUrl = 'https://api.relay.link'
|
|
17
19
|
const defaultFetch: RoutesProvider.Fetch = (input, init) => globalThis.fetch(input, init)
|
|
18
20
|
const deliveryBackfillBlocks = 256n
|
|
21
|
+
// Quote-time fee insufficiency is an expected rejection, not a provider outage.
|
|
22
|
+
const quoteUnavailableCodes = ['AMOUNT_TOO_LOW', 'NO_QUOTES', 'NO_ROUTE', 'UNSUPPORTED_ROUTE']
|
|
23
|
+
// Recheck the Relay key dashboard before changing account-specific quotas.
|
|
24
|
+
// Treat /quote/v2 as generic /quote until Relay confirms its bridge classification.
|
|
25
|
+
const quoteRateLimit = 10
|
|
26
|
+
// Reserve two requests for operations that must turn an accepted quote into work.
|
|
27
|
+
const quoteReadRateLimit = 8
|
|
28
|
+
const quoteRateLimitWindowMs = 1_000
|
|
29
|
+
const quoteQuotaStoreKey = 'routes:relay:quote-v2'
|
|
19
30
|
const relayChainsCacheTtlMs = 60_000
|
|
20
31
|
const relayRefundStatuses = ['refund', 'refunded'] as const
|
|
21
32
|
const relayRequestPageLimit = 100
|
|
33
|
+
const requestsRateLimit = 20
|
|
34
|
+
const requestsRateLimitWindowMs = 1_000
|
|
35
|
+
const requestsQuotaStoreKey = 'routes:relay:requests-v3'
|
|
36
|
+
const chainsTimeoutMs = 10_000
|
|
37
|
+
const requestsTimeoutMs = 10_000
|
|
38
|
+
// Relay app-balance sponsorship can settle in Base USDC even when neither route leg uses it.
|
|
39
|
+
const sponsorToken = {
|
|
40
|
+
address: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913',
|
|
41
|
+
currency: 'USD',
|
|
42
|
+
decimals: 6,
|
|
43
|
+
name: 'USD Coin',
|
|
44
|
+
standard: 'ERC-20',
|
|
45
|
+
symbol: 'USDC',
|
|
46
|
+
tokenKey: 'eip155:8453/erc20:0x833589fcd6edb6e08f4c7c32d4f71b54bda02913',
|
|
47
|
+
verified: true,
|
|
48
|
+
} satisfies RoutesProvider.TokenRef
|
|
22
49
|
const sourceSweepForwardBlocks = 256n
|
|
23
50
|
const depositErc20FullAllowance = AbiFunction.from(
|
|
24
51
|
'function depositErc20(address depositor,address token,bytes32 id)',
|
|
@@ -124,7 +151,9 @@ namespace schema {
|
|
|
124
151
|
})
|
|
125
152
|
|
|
126
153
|
export const DepositAddress = z.object({
|
|
127
|
-
details: PreparedQuote.shape.details,
|
|
154
|
+
details: z.extend(PreparedQuote.shape.details, {
|
|
155
|
+
isFixedRate: z.optional(z.boolean()),
|
|
156
|
+
}),
|
|
128
157
|
fees: PreparedQuote.shape.fees,
|
|
129
158
|
steps: z.array(
|
|
130
159
|
z.object({
|
|
@@ -250,6 +279,64 @@ namespace schema {
|
|
|
250
279
|
),
|
|
251
280
|
})
|
|
252
281
|
|
|
282
|
+
const TransferCurrency = z.object({
|
|
283
|
+
amount: Decimal,
|
|
284
|
+
currency: z.object({
|
|
285
|
+
address: z.string(),
|
|
286
|
+
chainId: Integer,
|
|
287
|
+
}),
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
const TransferTransaction = z.object({
|
|
291
|
+
chainId: Integer,
|
|
292
|
+
status: z.string(),
|
|
293
|
+
txHash: z.nullish(z.string()),
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
export const TransferRequests = z.object({
|
|
297
|
+
requests: z.array(
|
|
298
|
+
z.object({
|
|
299
|
+
data: z.optional(
|
|
300
|
+
z.object({
|
|
301
|
+
inTxs: z.optional(z.array(TransferTransaction)),
|
|
302
|
+
outTxs: z.optional(z.array(TransferTransaction)),
|
|
303
|
+
route: z.optional(
|
|
304
|
+
z.object({
|
|
305
|
+
actual: z.optional(
|
|
306
|
+
z.object({
|
|
307
|
+
destination: z.optional(z.object({ outputCurrency: TransferCurrency })),
|
|
308
|
+
origin: z.optional(z.object({ inputCurrency: TransferCurrency })),
|
|
309
|
+
}),
|
|
310
|
+
),
|
|
311
|
+
}),
|
|
312
|
+
),
|
|
313
|
+
}),
|
|
314
|
+
),
|
|
315
|
+
id: z.string().check(z.minLength(1)),
|
|
316
|
+
protocol: z.nullish(
|
|
317
|
+
z.object({
|
|
318
|
+
deposit: z.optional(
|
|
319
|
+
z.object({
|
|
320
|
+
origin: z.optional(
|
|
321
|
+
z.object({
|
|
322
|
+
depository: z.optional(z.string()),
|
|
323
|
+
}),
|
|
324
|
+
),
|
|
325
|
+
}),
|
|
326
|
+
),
|
|
327
|
+
}),
|
|
328
|
+
),
|
|
329
|
+
recipient: z.optional(z.string()),
|
|
330
|
+
sender: z.optional(z.string()),
|
|
331
|
+
status: z.string().check(z.minLength(1)),
|
|
332
|
+
}),
|
|
333
|
+
),
|
|
334
|
+
})
|
|
335
|
+
|
|
336
|
+
export const TransferCorrelation = z.object({
|
|
337
|
+
requestId: z.string().check(z.minLength(1)),
|
|
338
|
+
})
|
|
339
|
+
|
|
253
340
|
export const WebhookPayload = z.object({
|
|
254
341
|
data: z.object({
|
|
255
342
|
depositAddress: z.nullable(z.object({ address: z.string().check(z.minLength(1)) })),
|
|
@@ -279,6 +366,84 @@ export function relay(options: relay.Options = {}): RoutesProvider.Provider<'rel
|
|
|
279
366
|
const endpoint = quoteEndpoint(options)
|
|
280
367
|
const fetch = options.fetch ?? defaultFetch
|
|
281
368
|
const now = options.now ?? (() => new Date())
|
|
369
|
+
const rateLimitStore = options.rateLimitStore ?? Store.memory()
|
|
370
|
+
const verifyTransfers = options.observation
|
|
371
|
+
? Evidence.createVerifier({
|
|
372
|
+
...options.observation,
|
|
373
|
+
fetch,
|
|
374
|
+
})
|
|
375
|
+
: undefined
|
|
376
|
+
let transferChainsExpiresAt = 0
|
|
377
|
+
let transferChainsPromise: Promise<readonly RelayChain[]> | undefined
|
|
378
|
+
const getTransferChains = (signal: AbortSignal) => {
|
|
379
|
+
if (transferChainsPromise && now().getTime() < transferChainsExpiresAt)
|
|
380
|
+
return transferChainsPromise
|
|
381
|
+
transferChainsExpiresAt = now().getTime() + relayChainsCacheTtlMs
|
|
382
|
+
transferChainsPromise = RoutesProvider.requestJson(chainsEndpoint(options), {
|
|
383
|
+
fetch,
|
|
384
|
+
headers: options.apiKey ? { 'x-api-key': options.apiKey } : undefined,
|
|
385
|
+
signal: AbortSignal.any([signal, AbortSignal.timeout(chainsTimeoutMs)]),
|
|
386
|
+
})
|
|
387
|
+
.then((value) => schema.Chains.parse(value).chains)
|
|
388
|
+
.catch((cause) => {
|
|
389
|
+
transferChainsExpiresAt = 0
|
|
390
|
+
transferChainsPromise = undefined
|
|
391
|
+
if (cause instanceof DOMException && cause.name === 'TimeoutError')
|
|
392
|
+
throw new RoutesProvider.ProviderTimeoutError()
|
|
393
|
+
throw cause
|
|
394
|
+
})
|
|
395
|
+
return transferChainsPromise
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const consumeQuoteQuota = (limit: number) =>
|
|
399
|
+
ProviderQuota.consume(rateLimitStore, {
|
|
400
|
+
key: quoteQuotaStoreKey,
|
|
401
|
+
limit,
|
|
402
|
+
now: now(),
|
|
403
|
+
windowMs: quoteRateLimitWindowMs,
|
|
404
|
+
})
|
|
405
|
+
const consumeRequestsQuota = () =>
|
|
406
|
+
ProviderQuota.consume(rateLimitStore, {
|
|
407
|
+
key: requestsQuotaStoreKey,
|
|
408
|
+
limit: requestsRateLimit,
|
|
409
|
+
now: now(),
|
|
410
|
+
windowMs: requestsRateLimitWindowMs,
|
|
411
|
+
})
|
|
412
|
+
const blockQuoteOnRateLimit = (cause: unknown) =>
|
|
413
|
+
ProviderQuota.blockOnRateLimit(rateLimitStore, cause, {
|
|
414
|
+
key: quoteQuotaStoreKey,
|
|
415
|
+
now: now(),
|
|
416
|
+
windowMs: quoteRateLimitWindowMs,
|
|
417
|
+
})
|
|
418
|
+
const blockRequestsOnRateLimit = (cause: unknown) =>
|
|
419
|
+
ProviderQuota.blockOnRateLimit(rateLimitStore, cause, {
|
|
420
|
+
key: requestsQuotaStoreKey,
|
|
421
|
+
now: now(),
|
|
422
|
+
windowMs: requestsRateLimitWindowMs,
|
|
423
|
+
})
|
|
424
|
+
|
|
425
|
+
const getTransferRequest = async (requestId: string, signal: AbortSignal) => {
|
|
426
|
+
const url = requestsEndpoint(options)
|
|
427
|
+
url.searchParams.set('id', requestId)
|
|
428
|
+
await consumeRequestsQuota()
|
|
429
|
+
const response = await RoutesProvider.requestJson(url, {
|
|
430
|
+
fetch,
|
|
431
|
+
headers: { 'x-api-key': options.apiKey! },
|
|
432
|
+
method: 'GET',
|
|
433
|
+
signal: AbortSignal.any([signal, AbortSignal.timeout(requestsTimeoutMs)]),
|
|
434
|
+
}).catch(async (cause) => {
|
|
435
|
+
await blockRequestsOnRateLimit(cause)
|
|
436
|
+
if (cause instanceof DOMException && cause.name === 'TimeoutError')
|
|
437
|
+
throw new RoutesProvider.ProviderTimeoutError()
|
|
438
|
+
throw cause
|
|
439
|
+
})
|
|
440
|
+
const requests = schema.TransferRequests.safeParse(response)
|
|
441
|
+
if (!requests.success) throw new RoutesProvider.ProviderPayloadError()
|
|
442
|
+
if (requests.data.requests.some((request) => request.id !== requestId))
|
|
443
|
+
throw new RoutesProvider.ProviderPayloadError()
|
|
444
|
+
if (requests.data.requests.length > 1) throw new RoutesProvider.ProviderPayloadError()
|
|
445
|
+
return requests.data.requests[0]
|
|
446
|
+
}
|
|
282
447
|
|
|
283
448
|
async function listDepositAddressRequests(
|
|
284
449
|
parameters: RoutesProvider.listDepositAddressRequests.Parameters,
|
|
@@ -293,12 +458,22 @@ export function relay(options: relay.Options = {}): RoutesProvider.Provider<'rel
|
|
|
293
458
|
requestUrl.searchParams.set('sortDirection', 'desc')
|
|
294
459
|
if (parameters.continuation)
|
|
295
460
|
requestUrl.searchParams.set('continuation', parameters.continuation)
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
461
|
+
await consumeRequestsQuota()
|
|
462
|
+
const response = await (async () => {
|
|
463
|
+
try {
|
|
464
|
+
return await RoutesProvider.requestJson(requestUrl, {
|
|
465
|
+
fetch,
|
|
466
|
+
headers: options.apiKey ? { 'x-api-key': options.apiKey } : undefined,
|
|
467
|
+
method: 'GET',
|
|
468
|
+
signal: AbortSignal.any([signal, AbortSignal.timeout(requestsTimeoutMs)]),
|
|
469
|
+
})
|
|
470
|
+
} catch (cause) {
|
|
471
|
+
await blockRequestsOnRateLimit(cause)
|
|
472
|
+
if (cause instanceof DOMException && cause.name === 'TimeoutError')
|
|
473
|
+
throw new RoutesProvider.ProviderTimeoutError()
|
|
474
|
+
throw cause
|
|
475
|
+
}
|
|
476
|
+
})()
|
|
302
477
|
const parsed = parseDepositAddressRequests(response)
|
|
303
478
|
return {
|
|
304
479
|
...(parsed.continuation ? { continuation: parsed.continuation } : {}),
|
|
@@ -311,7 +486,7 @@ export function relay(options: relay.Options = {}): RoutesProvider.Provider<'rel
|
|
|
311
486
|
const payment = request.data?.feeSponsorship?.actual?.sponsorPayment
|
|
312
487
|
if (!payment || BigInt(payment.amount) === 0n) return undefined
|
|
313
488
|
const chainId = `eip155:${payment.chainId}/`
|
|
314
|
-
const token = [parameters.destinationToken, parameters.sourceToken].find(
|
|
489
|
+
const token = [parameters.destinationToken, parameters.sourceToken, sponsorToken].find(
|
|
315
490
|
(token) =>
|
|
316
491
|
token?.tokenKey.startsWith(chainId) &&
|
|
317
492
|
token.address.toLowerCase() === payment.address.toLowerCase(),
|
|
@@ -450,9 +625,23 @@ export function relay(options: relay.Options = {}): RoutesProvider.Provider<'rel
|
|
|
450
625
|
id: 'relay',
|
|
451
626
|
name: 'Relay',
|
|
452
627
|
...(webhook ? { webhook } : {}),
|
|
453
|
-
async createDepositAddress(
|
|
628
|
+
async createDepositAddress(
|
|
629
|
+
{ amount, candidate, recipient, refundAddress, subsidize, subsidyMaxAmount },
|
|
630
|
+
signal,
|
|
631
|
+
) {
|
|
632
|
+
if (
|
|
633
|
+
subsidize &&
|
|
634
|
+
subsidyMaxAmount !== undefined &&
|
|
635
|
+
(candidate.sourceToken.currency !== 'USD' ||
|
|
636
|
+
!Subsidy.supportsGap(
|
|
637
|
+
{ maxAmount: subsidyMaxAmount },
|
|
638
|
+
{ amount: 0n, destinationToken: candidate.destinationToken },
|
|
639
|
+
))
|
|
640
|
+
)
|
|
641
|
+
throw new RoutesProvider.ProviderUnavailableError()
|
|
454
642
|
if (
|
|
455
643
|
subsidize &&
|
|
644
|
+
subsidyMaxAmount === undefined &&
|
|
456
645
|
(!options.subsidies ||
|
|
457
646
|
!Subsidy.supports(options.subsidies, {
|
|
458
647
|
amount,
|
|
@@ -463,11 +652,17 @@ export function relay(options: relay.Options = {}): RoutesProvider.Provider<'rel
|
|
|
463
652
|
throw new RoutesProvider.ProviderUnavailableError()
|
|
464
653
|
const quote = await (async () => {
|
|
465
654
|
try {
|
|
655
|
+
await consumeQuoteQuota(quoteRateLimit)
|
|
656
|
+
const maximum = subsidyMaxAmount ?? options.subsidies?.maxAmount
|
|
466
657
|
return await RoutesProvider.requestJson(endpoint, {
|
|
467
658
|
body: {
|
|
468
659
|
amount,
|
|
469
660
|
destinationChainId: relayChainId(candidate.route.destination.chain),
|
|
470
661
|
destinationCurrency: candidate.destinationToken.address,
|
|
662
|
+
...(subsidize ? { fixedRate: '1:1' } : {}),
|
|
663
|
+
...(subsidize && maximum !== undefined
|
|
664
|
+
? { maxSubsidizationAmount: core_Value.from(maximum, 6).toString() }
|
|
665
|
+
: {}),
|
|
471
666
|
originChainId: relayChainId(candidate.route.source.chain),
|
|
472
667
|
originCurrency: candidate.sourceToken.address,
|
|
473
668
|
recipient,
|
|
@@ -483,8 +678,11 @@ export function relay(options: relay.Options = {}): RoutesProvider.Provider<'rel
|
|
|
483
678
|
signal,
|
|
484
679
|
})
|
|
485
680
|
} catch (cause) {
|
|
486
|
-
|
|
487
|
-
|
|
681
|
+
await blockQuoteOnRateLimit(cause)
|
|
682
|
+
const unavailable = RoutesProvider.unavailable(cause, quoteUnavailableCodes)
|
|
683
|
+
if (unavailable === 'AMOUNT_TOO_LOW')
|
|
684
|
+
throw new RoutesProvider.AmountTooLowError(unavailable, { cause })
|
|
685
|
+
if (unavailable) throw new RoutesProvider.ProviderUnavailableError(unavailable, { cause })
|
|
488
686
|
throw cause
|
|
489
687
|
}
|
|
490
688
|
})()
|
|
@@ -492,6 +690,21 @@ export function relay(options: relay.Options = {}): RoutesProvider.Provider<'rel
|
|
|
492
690
|
if (!parsed.success) throw new RoutesProvider.ProviderPayloadError()
|
|
493
691
|
if (parsed.data.details.currencyIn.amount !== amount)
|
|
494
692
|
throw new RoutesProvider.ProviderPayloadError()
|
|
693
|
+
if (subsidize) {
|
|
694
|
+
const expected =
|
|
695
|
+
(BigInt(amount) * 10n ** BigInt(candidate.destinationToken.decimals)) /
|
|
696
|
+
10n ** BigInt(candidate.sourceToken.decimals)
|
|
697
|
+
// Relay can quote 1:1 with isFixedRate=false and a slippage-adjusted minimum; validate the quoted output.
|
|
698
|
+
if (BigInt(parsed.data.details.currencyOut.amount) !== expected)
|
|
699
|
+
// Relay may have issued an address already; retain the irrevocable claim on invalid terms.
|
|
700
|
+
throw new RoutesProvider.ProviderPayloadError(
|
|
701
|
+
`FIXED_RATE_MISMATCH: ${JSON.stringify({
|
|
702
|
+
amount: parsed.data.details.currencyOut.amount,
|
|
703
|
+
expected: expected.toString(),
|
|
704
|
+
isFixedRate: parsed.data.details.isFixedRate ?? null,
|
|
705
|
+
})}`,
|
|
706
|
+
)
|
|
707
|
+
}
|
|
495
708
|
const step = parsed.data.steps.find(
|
|
496
709
|
(candidate) => candidate.depositAddress && candidate.requestId,
|
|
497
710
|
)
|
|
@@ -502,6 +715,7 @@ export function relay(options: relay.Options = {}): RoutesProvider.Provider<'rel
|
|
|
502
715
|
address: step.depositAddress,
|
|
503
716
|
correlation: {
|
|
504
717
|
...(checkEndpoint ? { checkEndpoint } : {}),
|
|
718
|
+
...(subsidize ? { fixedRate: '1:1' as const } : {}),
|
|
505
719
|
requestId: step.requestId,
|
|
506
720
|
},
|
|
507
721
|
destinationAmount: parsed.data.details.currencyOut.amount,
|
|
@@ -531,6 +745,7 @@ export function relay(options: relay.Options = {}): RoutesProvider.Provider<'rel
|
|
|
531
745
|
const destinationChainId = relayChainId(route.destination.chain)
|
|
532
746
|
const sourceChainId = relayChainId(route.source.chain)
|
|
533
747
|
try {
|
|
748
|
+
await consumeQuoteQuota(quoteReadRateLimit)
|
|
534
749
|
const quote = await RoutesProvider.requestJson(endpoint, {
|
|
535
750
|
body: {
|
|
536
751
|
amount: candidate.sourceAmount.amount,
|
|
@@ -567,11 +782,8 @@ export function relay(options: relay.Options = {}): RoutesProvider.Provider<'rel
|
|
|
567
782
|
status: status.status,
|
|
568
783
|
}
|
|
569
784
|
} catch (cause) {
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
'NO_ROUTE',
|
|
573
|
-
'UNSUPPORTED_ROUTE',
|
|
574
|
-
])
|
|
785
|
+
await blockQuoteOnRateLimit(cause)
|
|
786
|
+
const unavailable = RoutesProvider.unavailable(cause, quoteUnavailableCodes)
|
|
575
787
|
if (!unavailable) throw cause
|
|
576
788
|
return RoutesProvider.unavailableResult({
|
|
577
789
|
detail: 'relay:quote-v2',
|
|
@@ -590,12 +802,13 @@ export function relay(options: relay.Options = {}): RoutesProvider.Provider<'rel
|
|
|
590
802
|
throw new RoutesProvider.ProviderConfigurationError()
|
|
591
803
|
const quote = await (async () => {
|
|
592
804
|
try {
|
|
805
|
+
await consumeQuoteQuota(quoteRateLimit)
|
|
593
806
|
return await RoutesProvider.requestJson(endpoint, {
|
|
594
807
|
body: {
|
|
595
808
|
amount: candidate.sourceAmount.amount,
|
|
596
|
-
destinationChainId:
|
|
809
|
+
destinationChainId: relayChainId(candidate.route.destination.chain),
|
|
597
810
|
destinationCurrency: candidate.destinationToken.address,
|
|
598
|
-
originChainId:
|
|
811
|
+
originChainId: relayChainId(candidate.route.source.chain),
|
|
599
812
|
originCurrency: candidate.sourceToken.address,
|
|
600
813
|
recipient,
|
|
601
814
|
...(slippageBps !== undefined ? { slippageTolerance: String(slippageBps) } : {}),
|
|
@@ -608,8 +821,9 @@ export function relay(options: relay.Options = {}): RoutesProvider.Provider<'rel
|
|
|
608
821
|
signal,
|
|
609
822
|
})
|
|
610
823
|
} catch (cause) {
|
|
611
|
-
|
|
612
|
-
|
|
824
|
+
await blockQuoteOnRateLimit(cause)
|
|
825
|
+
const unavailable = RoutesProvider.unavailable(cause, quoteUnavailableCodes)
|
|
826
|
+
if (unavailable) throw new RoutesProvider.ProviderUnavailableError(unavailable, { cause })
|
|
613
827
|
throw cause
|
|
614
828
|
}
|
|
615
829
|
})()
|
|
@@ -626,7 +840,7 @@ export function relay(options: relay.Options = {}): RoutesProvider.Provider<'rel
|
|
|
626
840
|
.flatMap((step) => step.items ?? [])
|
|
627
841
|
const requestId = steps.find((step) => step.requestId)?.requestId
|
|
628
842
|
if (items.length === 0 || !requestId) throw new RoutesProvider.ProviderPayloadError()
|
|
629
|
-
const sourceChainId =
|
|
843
|
+
const sourceChainId = relayChainId(candidate.route.source.chain)
|
|
630
844
|
for (const item of items)
|
|
631
845
|
if (
|
|
632
846
|
item.data.chainId !== sourceChainId ||
|
|
@@ -661,6 +875,138 @@ export function relay(options: relay.Options = {}): RoutesProvider.Provider<'rel
|
|
|
661
875
|
sampledAt: now().toISOString(),
|
|
662
876
|
}
|
|
663
877
|
},
|
|
878
|
+
...(verifyTransfers && options.apiKey
|
|
879
|
+
? {
|
|
880
|
+
async verifySourceTransaction(
|
|
881
|
+
{ destinationChain, providerState, sourceChain, transactionHash, transfer },
|
|
882
|
+
signal,
|
|
883
|
+
) {
|
|
884
|
+
const correlation = schema.TransferCorrelation.safeParse(providerState)
|
|
885
|
+
if (
|
|
886
|
+
!correlation.success ||
|
|
887
|
+
sourceChain.kind !== 'evm' ||
|
|
888
|
+
(destinationChain.kind !== 'evm' && destinationChain.kind !== 'solana') ||
|
|
889
|
+
!transfer.sender ||
|
|
890
|
+
transfer.method !== 'transaction' ||
|
|
891
|
+
transfer.mode !== 'exactSource'
|
|
892
|
+
)
|
|
893
|
+
return { type: 'invalid' as const }
|
|
894
|
+
const request = await getTransferRequest(correlation.data.requestId, signal)
|
|
895
|
+
if (!request) return { type: 'pending' as const }
|
|
896
|
+
if (!transferRequestMatches(request, { destinationChain, sourceChain, transfer }))
|
|
897
|
+
return { type: 'invalid' as const }
|
|
898
|
+
const source = request.data?.inTxs?.find(
|
|
899
|
+
(entry) =>
|
|
900
|
+
entry.chainId === relayChainId(sourceChain) &&
|
|
901
|
+
entry.txHash?.toLowerCase() === transactionHash.toLowerCase(),
|
|
902
|
+
)
|
|
903
|
+
if (!source) return { type: 'pending' as const }
|
|
904
|
+
if (
|
|
905
|
+
source.status === 'failure' ||
|
|
906
|
+
source.status === 'failed' ||
|
|
907
|
+
source.status === 'cancelled' ||
|
|
908
|
+
source.status === 'canceled'
|
|
909
|
+
)
|
|
910
|
+
return { type: 'invalid' as const }
|
|
911
|
+
if (source.status !== 'success') return { type: 'pending' as const }
|
|
912
|
+
const chains = await getTransferChains(signal)
|
|
913
|
+
const depository = relayEvmChain(chains, sourceChain)?.protocol?.v2?.depository
|
|
914
|
+
if (!depository || !Address.validate(depository, { strict: false }))
|
|
915
|
+
throw new RoutesProvider.ProviderConfigurationError()
|
|
916
|
+
const reportedDepository = request.protocol?.deposit?.origin?.depository
|
|
917
|
+
if (
|
|
918
|
+
reportedDepository &&
|
|
919
|
+
(!Address.validate(reportedDepository, { strict: false }) ||
|
|
920
|
+
!Address.isEqual(
|
|
921
|
+
reportedDepository as Address.Address,
|
|
922
|
+
depository as Address.Address,
|
|
923
|
+
))
|
|
924
|
+
)
|
|
925
|
+
return { type: 'invalid' as const }
|
|
926
|
+
const evidence = await verifyTransfers({
|
|
927
|
+
chain: sourceChain,
|
|
928
|
+
recipient: depository,
|
|
929
|
+
token: transfer.sourceToken,
|
|
930
|
+
transactionHash,
|
|
931
|
+
})
|
|
932
|
+
const amount = evidence
|
|
933
|
+
.filter((entry) => entry.sender?.toLowerCase() === transfer.sender!.toLowerCase())
|
|
934
|
+
.reduce((total, entry) => total + BigInt(entry.amount), 0n)
|
|
935
|
+
if (amount === 0n) return { type: 'pending' as const }
|
|
936
|
+
if (amount !== BigInt(transfer.sourceAmount.baseUnits))
|
|
937
|
+
return { type: 'invalid' as const }
|
|
938
|
+
return { type: 'verified' as const }
|
|
939
|
+
},
|
|
940
|
+
async verifyDestinationDelivery(
|
|
941
|
+
{ destinationChain, providerState, sourceChain, transfer },
|
|
942
|
+
signal,
|
|
943
|
+
) {
|
|
944
|
+
const correlation = schema.TransferCorrelation.safeParse(providerState)
|
|
945
|
+
if (
|
|
946
|
+
!correlation.success ||
|
|
947
|
+
sourceChain.kind !== 'evm' ||
|
|
948
|
+
(destinationChain.kind !== 'evm' && destinationChain.kind !== 'solana')
|
|
949
|
+
)
|
|
950
|
+
return { type: 'invalid' as const }
|
|
951
|
+
const request = await getTransferRequest(correlation.data.requestId, signal)
|
|
952
|
+
if (!request) return { type: 'pending' as const }
|
|
953
|
+
if (!transferRequestMatches(request, { destinationChain, sourceChain, transfer }))
|
|
954
|
+
return { type: 'invalid' as const }
|
|
955
|
+
if (
|
|
956
|
+
request.status === 'failure' ||
|
|
957
|
+
request.status === 'fallback' ||
|
|
958
|
+
request.status === 'refund' ||
|
|
959
|
+
request.status === 'refunded'
|
|
960
|
+
)
|
|
961
|
+
return {
|
|
962
|
+
statusReason: {
|
|
963
|
+
code: 'manual_recovery_required' as const,
|
|
964
|
+
message: 'Relay could not complete the destination transfer.',
|
|
965
|
+
},
|
|
966
|
+
type: 'action-required' as const,
|
|
967
|
+
}
|
|
968
|
+
if (request.status !== 'success') return { type: 'pending' as const }
|
|
969
|
+
const destination = request.data?.route?.actual?.destination?.outputCurrency
|
|
970
|
+
const outputs = request.data?.outTxs?.filter(
|
|
971
|
+
(entry) => entry.chainId === relayChainId(destinationChain),
|
|
972
|
+
)
|
|
973
|
+
if (
|
|
974
|
+
!destination ||
|
|
975
|
+
!outputs ||
|
|
976
|
+
outputs.length !== 1 ||
|
|
977
|
+
outputs[0]?.status !== 'success' ||
|
|
978
|
+
!outputs[0].txHash
|
|
979
|
+
)
|
|
980
|
+
return { type: 'pending' as const }
|
|
981
|
+
const transactionHash = outputs[0].txHash
|
|
982
|
+
const evidence = await verifyTransfers({
|
|
983
|
+
chain: destinationChain,
|
|
984
|
+
recipient: transfer.recipient,
|
|
985
|
+
token: transfer.destinationToken,
|
|
986
|
+
transactionHash,
|
|
987
|
+
})
|
|
988
|
+
const amount = evidence.reduce((total, entry) => total + BigInt(entry.amount), 0n)
|
|
989
|
+
if (amount === 0n) return { type: 'pending' as const }
|
|
990
|
+
if (amount !== BigInt(destination.amount)) return { type: 'invalid' as const }
|
|
991
|
+
if (
|
|
992
|
+
transfer.destinationAmountMin &&
|
|
993
|
+
amount < BigInt(transfer.destinationAmountMin.baseUnits)
|
|
994
|
+
)
|
|
995
|
+
return {
|
|
996
|
+
statusReason: {
|
|
997
|
+
code: 'manual_recovery_required' as const,
|
|
998
|
+
message: 'Relay delivered less than the quoted minimum destination amount.',
|
|
999
|
+
},
|
|
1000
|
+
type: 'action-required' as const,
|
|
1001
|
+
}
|
|
1002
|
+
return {
|
|
1003
|
+
destinationAmount: amount.toString(),
|
|
1004
|
+
transactionHash,
|
|
1005
|
+
type: 'verified' as const,
|
|
1006
|
+
}
|
|
1007
|
+
},
|
|
1008
|
+
}
|
|
1009
|
+
: {}),
|
|
664
1010
|
})
|
|
665
1011
|
}
|
|
666
1012
|
|
|
@@ -677,6 +1023,8 @@ export declare namespace relay {
|
|
|
677
1023
|
now?: (() => Date) | undefined
|
|
678
1024
|
/** EVM chain evidence used to accelerate authenticated provider delivery. */
|
|
679
1025
|
observation?: Observation | undefined
|
|
1026
|
+
/** Atomic store used to enforce the shared Relay `/quote/v2` quota. */
|
|
1027
|
+
rateLimitStore?: Store.Store | undefined
|
|
680
1028
|
/** Deposit subsidy policy enabled for this integration. */
|
|
681
1029
|
subsidies?: Subsidy.Policy | undefined
|
|
682
1030
|
/** Optional source and destination quote wallets keyed by CAIP-2 chain id. */
|
|
@@ -988,13 +1336,8 @@ function createDepositAddressObserver(
|
|
|
988
1336
|
(address) => address as Address.Address,
|
|
989
1337
|
)
|
|
990
1338
|
const correlatedTransactionHashes: Hex.Hex[] = []
|
|
991
|
-
const uncorrelatedTransactionHashes: Hex.Hex[] = []
|
|
992
1339
|
for (const log of destinationLogs) {
|
|
993
|
-
if (
|
|
994
|
-
!log.transactionHash ||
|
|
995
|
-
correlatedTransactionHashes.includes(log.transactionHash) ||
|
|
996
|
-
uncorrelatedTransactionHashes.includes(log.transactionHash)
|
|
997
|
-
)
|
|
1340
|
+
if (!log.transactionHash || correlatedTransactionHashes.includes(log.transactionHash))
|
|
998
1341
|
continue
|
|
999
1342
|
const event = decodeEvent(transferEvent, log)
|
|
1000
1343
|
if (
|
|
@@ -1014,19 +1357,13 @@ function createDepositAddressObserver(
|
|
|
1014
1357
|
!Address.isEqual(transaction.to, parameters.destinationToken.address as Address.Address) ||
|
|
1015
1358
|
!Address.isEqual(call.recipient, event.to) ||
|
|
1016
1359
|
call.amount !== event.value ||
|
|
1017
|
-
|
|
1360
|
+
!call.orderId ||
|
|
1361
|
+
!Hex.isEqual(call.orderId, sourceObservation.orderId as Hex.Hex)
|
|
1018
1362
|
)
|
|
1019
1363
|
continue
|
|
1020
|
-
|
|
1021
|
-
else uncorrelatedTransactionHashes.push(log.transactionHash)
|
|
1364
|
+
correlatedTransactionHashes.push(log.transactionHash)
|
|
1022
1365
|
}
|
|
1023
|
-
const destinationTransactionHashes =
|
|
1024
|
-
if (correlatedTransactionHashes.length > 0) return correlatedTransactionHashes
|
|
1025
|
-
// Provider-independent completion requires the Relay order id to bind both chain legs.
|
|
1026
|
-
if (!parameters.request) return []
|
|
1027
|
-
if (uncorrelatedTransactionHashes.length === 1) return uncorrelatedTransactionHashes
|
|
1028
|
-
return []
|
|
1029
|
-
})()
|
|
1366
|
+
const destinationTransactionHashes = correlatedTransactionHashes
|
|
1030
1367
|
const providerState = { relay: sourceObservation }
|
|
1031
1368
|
if (destinationTransactionHashes.length === 0)
|
|
1032
1369
|
return {
|
|
@@ -1208,6 +1545,54 @@ function relayChainId(chain: RoutesProvider.Chain): number {
|
|
|
1208
1545
|
throw new RoutesProvider.ProviderConfigurationError()
|
|
1209
1546
|
}
|
|
1210
1547
|
|
|
1548
|
+
function transferRequestMatches(
|
|
1549
|
+
request: z.output<typeof schema.TransferRequests>['requests'][number],
|
|
1550
|
+
options: Pick<
|
|
1551
|
+
RoutesProvider.verifySourceTransaction.Parameters,
|
|
1552
|
+
'destinationChain' | 'sourceChain' | 'transfer'
|
|
1553
|
+
>,
|
|
1554
|
+
): boolean {
|
|
1555
|
+
const { destinationChain, sourceChain, transfer } = options
|
|
1556
|
+
const actual = request.data?.route?.actual
|
|
1557
|
+
if (
|
|
1558
|
+
!transfer.sender ||
|
|
1559
|
+
!request.sender ||
|
|
1560
|
+
!request.recipient ||
|
|
1561
|
+
!Address.validate(request.sender, { strict: false }) ||
|
|
1562
|
+
!Address.isEqual(request.sender as Address.Address, transfer.sender as Address.Address) ||
|
|
1563
|
+
(destinationChain.kind === 'evm'
|
|
1564
|
+
? !Address.validate(request.recipient, { strict: false }) ||
|
|
1565
|
+
!Address.isEqual(
|
|
1566
|
+
request.recipient as Address.Address,
|
|
1567
|
+
transfer.recipient as Address.Address,
|
|
1568
|
+
)
|
|
1569
|
+
: request.recipient !== transfer.recipient)
|
|
1570
|
+
)
|
|
1571
|
+
return false
|
|
1572
|
+
if (!actual) return true
|
|
1573
|
+
const source = actual.origin?.inputCurrency
|
|
1574
|
+
const destination = actual.destination?.outputCurrency
|
|
1575
|
+
return (
|
|
1576
|
+
(!source ||
|
|
1577
|
+
(source.currency.chainId === relayChainId(sourceChain) &&
|
|
1578
|
+
Address.validate(source.currency.address, { strict: false }) &&
|
|
1579
|
+
Address.isEqual(
|
|
1580
|
+
source.currency.address as Address.Address,
|
|
1581
|
+
transfer.sourceToken.address as Address.Address,
|
|
1582
|
+
) &&
|
|
1583
|
+
source.amount === transfer.sourceAmount.baseUnits)) &&
|
|
1584
|
+
(!destination ||
|
|
1585
|
+
(destination.currency.chainId === relayChainId(destinationChain) &&
|
|
1586
|
+
(destinationChain.kind === 'evm'
|
|
1587
|
+
? Address.validate(destination.currency.address, { strict: false }) &&
|
|
1588
|
+
Address.isEqual(
|
|
1589
|
+
destination.currency.address as Address.Address,
|
|
1590
|
+
transfer.destinationToken.address as Address.Address,
|
|
1591
|
+
)
|
|
1592
|
+
: destination.currency.address === transfer.destinationToken.address)))
|
|
1593
|
+
)
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1211
1596
|
/** Relay webhook signature is missing, stale, or invalid. */
|
|
1212
1597
|
export class WebhookSignatureError extends RoutesProvider.WebhookAuthenticationError {
|
|
1213
1598
|
override name = 'Routes.Provider.Relay.WebhookSignatureError'
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { Value as core_Value } from 'ox'
|
|
2
2
|
import * as z from 'zod/mini'
|
|
3
3
|
|
|
4
|
+
import * as Store from '../../Store.js'
|
|
4
5
|
import type * as RoutesChain from '../Chain.js'
|
|
5
|
-
import type * as RoutesToken from '../Token.js'
|
|
6
6
|
import * as RoutesProvider from '../Provider.js'
|
|
7
|
+
import * as ProviderQuota from '../Quota.js'
|
|
8
|
+
import type * as RoutesToken from '../Token.js'
|
|
7
9
|
|
|
8
10
|
const defaultBaseUrl = 'https://api.rhino.fi/bridge'
|
|
9
11
|
const defaultFetch: RoutesProvider.Fetch = (input, init) => globalThis.fetch(input, init)
|
|
12
|
+
const rateLimitWindowMs = 1_000
|
|
13
|
+
const quotaStoreKey = 'routes:rhino:bridge-swap-public'
|
|
10
14
|
|
|
11
15
|
const chainIds = {
|
|
12
16
|
'eip155:4217': 'TEMPO',
|
|
@@ -38,6 +42,7 @@ export function rhino(options: rhino.Options = {}) {
|
|
|
38
42
|
endpoint.pathname = `${endpoint.pathname.replace(/\/+$/, '')}/quote/bridge-swap/public`
|
|
39
43
|
const fetch = options.fetch ?? defaultFetch
|
|
40
44
|
const now = options.now ?? (() => new Date())
|
|
45
|
+
const rateLimitStore = options.rateLimitStore ?? Store.memory()
|
|
41
46
|
|
|
42
47
|
return RoutesProvider.from({
|
|
43
48
|
id: 'rhino',
|
|
@@ -58,6 +63,7 @@ export function rhino(options: rhino.Options = {}) {
|
|
|
58
63
|
}).toString()
|
|
59
64
|
|
|
60
65
|
try {
|
|
66
|
+
await ProviderQuota.check(rateLimitStore, { key: quotaStoreKey, now: now() })
|
|
61
67
|
const quote = await RoutesProvider.requestJson(url, {
|
|
62
68
|
fetch,
|
|
63
69
|
headers: cache.bypass ? { 'cache-control': 'no-cache' } : undefined,
|
|
@@ -95,6 +101,11 @@ export function rhino(options: rhino.Options = {}) {
|
|
|
95
101
|
status: 'available',
|
|
96
102
|
}
|
|
97
103
|
} catch (cause) {
|
|
104
|
+
await ProviderQuota.blockOnRateLimit(rateLimitStore, cause, {
|
|
105
|
+
key: quotaStoreKey,
|
|
106
|
+
now: now(),
|
|
107
|
+
windowMs: rateLimitWindowMs,
|
|
108
|
+
})
|
|
98
109
|
const unavailable = RoutesProvider.unavailable(cause, ['NoRouteFoundError'])
|
|
99
110
|
if (!unavailable) throw cause
|
|
100
111
|
return RoutesProvider.unavailableResult({
|
|
@@ -117,6 +128,8 @@ export declare namespace rhino {
|
|
|
117
128
|
fetch?: RoutesProvider.Fetch | undefined
|
|
118
129
|
/** Clock override for deterministic tests. */
|
|
119
130
|
now?: (() => Date) | undefined
|
|
131
|
+
/** Store used to coordinate provider-reported cooldowns. */
|
|
132
|
+
rateLimitStore?: Store.Store | undefined
|
|
120
133
|
}
|
|
121
134
|
}
|
|
122
135
|
|