tapimo 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App.d.ts +11333 -9563
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +39 -3
- package/dist/App.js.map +1 -1
- package/dist/Scope.d.ts +2 -0
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +17 -0
- package/dist/Scope.js.map +1 -1
- package/dist/Webhooks.js +2 -2
- package/dist/Webhooks.js.map +1 -1
- package/dist/admin/App.d.ts +1064 -924
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +80 -0
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +54 -0
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/earn-vaults.d.ts +63 -15
- package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
- package/dist/admin/apps/earn-vaults.js +2 -1
- package/dist/admin/apps/earn-vaults.js.map +1 -1
- package/dist/admin/apps/organizations.d.ts +92 -3
- package/dist/admin/apps/organizations.d.ts.map +1 -1
- package/dist/admin/apps/organizations.js +69 -7
- package/dist/admin/apps/organizations.js.map +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +7 -7
- package/dist/admin/ui.generated.d.ts +1 -1
- package/dist/admin/ui.generated.d.ts.map +1 -1
- package/dist/admin/ui.generated.js +151 -151
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/apps/Zones.d.ts +28 -28
- package/dist/apps/Zones.js +7 -7
- package/dist/apps/data/App.d.ts +2909 -2523
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +26 -21
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/ZoneSelection.d.ts +8 -8
- package/dist/apps/data/ZoneSelection.d.ts.map +1 -1
- package/dist/apps/data/ZoneSelection.js +1 -1
- package/dist/apps/data/ZoneSelection.js.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +588 -584
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +1561 -1239
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +22 -22
- package/dist/apps/data/routes/balances.d.ts +26 -26
- package/dist/apps/data/routes/balances.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.js +43 -16
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +44 -44
- package/dist/apps/data/routes/blocks.d.ts.map +1 -1
- package/dist/apps/data/routes/blocks.js +21 -11
- package/dist/apps/data/routes/blocks.js.map +1 -1
- package/dist/apps/data/routes/coingecko.d.ts +3 -3
- package/dist/apps/data/routes/earn.d.ts +201 -25
- package/dist/apps/data/routes/earn.d.ts.map +1 -1
- package/dist/apps/data/routes/earn.js +434 -75
- package/dist/apps/data/routes/earn.js.map +1 -1
- package/dist/apps/data/routes/exchanges.d.ts +160 -145
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
- package/dist/apps/data/routes/exchanges.js +180 -114
- package/dist/apps/data/routes/exchanges.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts +2 -2
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
- package/dist/apps/data/routes/fee-amm.js +18 -19
- package/dist/apps/data/routes/fee-amm.js.map +1 -1
- package/dist/apps/data/routes/receipts.d.ts +155 -55
- package/dist/apps/data/routes/receipts.d.ts.map +1 -1
- package/dist/apps/data/routes/receipts.js +28 -10
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/tokenlist.d.ts +13 -13
- package/dist/apps/data/routes/tokens.d.ts +5 -5
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +51 -20
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.d.ts +7 -2
- package/dist/apps/data/routes/transactions.d.ts.map +1 -1
- package/dist/apps/data/routes/transactions.js +37 -17
- package/dist/apps/data/routes/transactions.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +13 -13
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +18 -12
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/valuation.d.ts +31 -31
- package/dist/apps/data/routes/valuation.d.ts.map +1 -1
- package/dist/apps/data/routes/valuation.js +12 -7
- package/dist/apps/data/routes/valuation.js.map +1 -1
- package/dist/apps/data/routes/verified-tokens.d.ts +8 -8
- package/dist/apps/data/routes/webhooks.d.ts +816 -113
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +47 -5
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/data/routes/zones.d.ts +14 -14
- package/dist/apps/data/routes/zones.js +1 -1
- package/dist/apps/funding/App.d.ts +466 -44
- package/dist/apps/funding/App.d.ts.map +1 -1
- package/dist/apps/funding/App.js +1 -1
- package/dist/apps/funding/App.js.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.d.ts +17 -17
- package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.js +17 -12
- package/dist/apps/funding/routes/deposit-addresses.js.map +1 -1
- package/dist/apps/funding/routes/transfers.d.ts +650 -57
- package/dist/apps/funding/routes/transfers.d.ts.map +1 -1
- package/dist/apps/funding/routes/transfers.js +238 -24
- package/dist/apps/funding/routes/transfers.js.map +1 -1
- package/dist/apps/management/App.d.ts +5120 -4152
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/Billing.d.ts +1 -1
- package/dist/apps/management/Billing.d.ts.map +1 -1
- package/dist/apps/management/Billing.js +17 -1
- package/dist/apps/management/Billing.js.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +632 -81
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +236 -4
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +76 -76
- package/dist/apps/management/routes/faucet.d.ts +6 -6
- package/dist/apps/management/routes/invitations.d.ts +24 -24
- package/dist/apps/management/routes/invite-links.d.ts +4 -4
- package/dist/apps/management/routes/members.d.ts +16 -16
- package/dist/apps/management/routes/orgs.d.ts +20 -20
- package/dist/apps/management/routes/projects.d.ts +4 -4
- package/dist/apps/management/routes/usage.d.ts +8 -8
- package/dist/apps/management/routes/verified-token-requests.d.ts +17 -17
- package/dist/apps/management/routes/webhooks.d.ts +675 -25
- package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/management/routes/webhooks.js +21 -21
- package/dist/apps/management/routes/webhooks.js.map +1 -1
- package/dist/apps/relay/App.d.ts.map +1 -1
- package/dist/apps/relay/App.js +115 -23
- 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 +27 -1
- package/dist/apps/relay/Sponsorships.js.map +1 -1
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +34 -1
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +11 -5
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +21 -3
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/fundingCatalog.d.ts +4 -2
- package/dist/db/tables/fundingCatalog.d.ts.map +1 -1
- package/dist/db/tables/fundingCatalog.js +5 -1
- package/dist/db/tables/fundingCatalog.js.map +1 -1
- package/dist/db/tables/fundingTransferTransactions.d.ts +38 -0
- package/dist/db/tables/fundingTransferTransactions.d.ts.map +1 -1
- package/dist/db/tables/fundingTransferTransactions.js +44 -3
- package/dist/db/tables/fundingTransferTransactions.js.map +1 -1
- package/dist/db/tables/fundingTransfers.d.ts +17 -0
- package/dist/db/tables/fundingTransfers.d.ts.map +1 -1
- package/dist/db/tables/fundingTransfers.js +21 -0
- package/dist/db/tables/fundingTransfers.js.map +1 -1
- package/dist/db/tables/organizations.d.ts +24 -0
- package/dist/db/tables/organizations.d.ts.map +1 -1
- package/dist/db/tables/organizations.js +27 -0
- package/dist/db/tables/organizations.js.map +1 -1
- package/dist/db/tables/projects.d.ts +25 -1
- package/dist/db/tables/projects.d.ts.map +1 -1
- package/dist/db/tables/projects.js +26 -0
- package/dist/db/tables/projects.js.map +1 -1
- package/dist/db/tables/sponsoredTransactions.d.ts +44 -0
- package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
- package/dist/db/tables/sponsoredTransactions.js +146 -13
- package/dist/db/tables/sponsoredTransactions.js.map +1 -1
- package/dist/db/tables/webhookSubscriptions.d.ts +10 -6
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
- package/dist/db/tables/webhookSubscriptions.js +9 -6
- package/dist/db/tables/webhookSubscriptions.js.map +1 -1
- package/dist/handlers/internal/utils.d.ts.map +1 -1
- package/dist/handlers/internal/utils.js +9 -0
- package/dist/handlers/internal/utils.js.map +1 -1
- package/dist/internal/Auth.d.ts +3 -1
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +6 -3
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/EarnVaults.d.ts +3 -3
- package/dist/internal/EarnVaults.js +5 -5
- package/dist/internal/EarnVaults.js.map +1 -1
- package/dist/internal/Fetch.d.ts +23 -0
- package/dist/internal/Fetch.d.ts.map +1 -0
- package/dist/internal/Fetch.js +26 -0
- package/dist/internal/Fetch.js.map +1 -0
- package/dist/internal/Log.d.ts +4 -2
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +16 -3
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +5 -3
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +13 -3
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/Response.d.ts +1 -1
- package/dist/internal/Response.d.ts.map +1 -1
- package/dist/internal/Schema.d.ts +6 -3
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +8 -2
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/Store.d.ts +16 -3
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +82 -16
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/Tidx.d.ts.map +1 -1
- package/dist/internal/Tidx.js +7 -2
- package/dist/internal/Tidx.js.map +1 -1
- package/dist/internal/Timeout.d.ts +36 -0
- package/dist/internal/Timeout.d.ts.map +1 -0
- package/dist/internal/Timeout.js +37 -0
- package/dist/internal/Timeout.js.map +1 -0
- package/dist/internal/Timing.d.ts +9 -0
- package/dist/internal/Timing.d.ts.map +1 -1
- package/dist/internal/Timing.js +7 -0
- package/dist/internal/Timing.js.map +1 -1
- package/dist/internal/Viem.d.ts +16 -1
- package/dist/internal/Viem.d.ts.map +1 -1
- package/dist/internal/Viem.js +12 -2
- package/dist/internal/Viem.js.map +1 -1
- package/dist/internal/WebhookDestination.d.ts.map +1 -1
- package/dist/internal/WebhookDestination.js +3 -0
- package/dist/internal/WebhookDestination.js.map +1 -1
- package/dist/internal/funding/Action.d.ts +9 -0
- package/dist/internal/funding/Action.d.ts.map +1 -1
- package/dist/internal/funding/Action.js +16 -8
- package/dist/internal/funding/Action.js.map +1 -1
- package/dist/internal/funding/Catalog.d.ts +9 -2
- package/dist/internal/funding/Catalog.d.ts.map +1 -1
- package/dist/internal/funding/Catalog.js +19 -8
- package/dist/internal/funding/Catalog.js.map +1 -1
- package/dist/internal/funding/DepositWebhook.d.ts.map +1 -1
- package/dist/internal/funding/DepositWebhook.js +2 -1
- package/dist/internal/funding/DepositWebhook.js.map +1 -1
- package/dist/internal/funding/Evidence.d.ts.map +1 -1
- package/dist/internal/funding/Evidence.js +2 -10
- package/dist/internal/funding/Evidence.js.map +1 -1
- package/dist/internal/funding/Provider.d.ts +108 -13
- package/dist/internal/funding/Provider.d.ts.map +1 -1
- package/dist/internal/funding/Provider.js +34 -8
- package/dist/internal/funding/Provider.js.map +1 -1
- package/dist/internal/funding/SourceObservation.d.ts.map +1 -1
- package/dist/internal/funding/SourceObservation.js +5 -7
- package/dist/internal/funding/SourceObservation.js.map +1 -1
- package/dist/internal/funding/Transfer.d.ts +114 -18
- package/dist/internal/funding/Transfer.d.ts.map +1 -1
- package/dist/internal/funding/Transfer.js +185 -55
- package/dist/internal/funding/Transfer.js.map +1 -1
- package/dist/internal/funding/TransferReconciliation.d.ts +52 -0
- package/dist/internal/funding/TransferReconciliation.d.ts.map +1 -0
- package/dist/internal/funding/TransferReconciliation.js +192 -0
- package/dist/internal/funding/TransferReconciliation.js.map +1 -0
- package/dist/internal/funding/TransferWebhook.d.ts +21 -0
- package/dist/internal/funding/TransferWebhook.d.ts.map +1 -0
- package/dist/internal/funding/TransferWebhook.js +43 -0
- package/dist/internal/funding/TransferWebhook.js.map +1 -0
- package/dist/internal/funding/index.d.ts +1 -0
- package/dist/internal/funding/index.d.ts.map +1 -1
- package/dist/internal/funding/index.js +1 -0
- package/dist/internal/funding/index.js.map +1 -1
- package/dist/internal/funding/providers/relay.d.ts.map +1 -1
- package/dist/internal/funding/providers/relay.js +3 -12
- package/dist/internal/funding/providers/relay.js.map +1 -1
- package/dist/internal/funding/providers/stargate.d.ts +127 -9
- package/dist/internal/funding/providers/stargate.d.ts.map +1 -1
- package/dist/internal/funding/providers/stargate.js +548 -112
- package/dist/internal/funding/providers/stargate.js.map +1 -1
- package/dist/internal/index.d.ts +1 -0
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +1 -0
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/webhookDestinations/slack.d.ts.map +1 -1
- package/dist/internal/webhookDestinations/slack.js +16 -0
- package/dist/internal/webhookDestinations/slack.js.map +1 -1
- package/package.json +2 -2
- package/src/App.test.ts +100 -0
- package/src/App.ts +43 -3
- package/src/Client.test-d.ts +129 -2
- package/src/Scope.test.ts +20 -0
- package/src/Scope.ts +16 -0
- package/src/Webhooks.ts +2 -2
- package/src/admin/apps/api-keys.test.ts +75 -0
- package/src/admin/apps/api-keys.ts +64 -0
- package/src/admin/apps/earn-vaults.test.ts +1 -1
- package/src/admin/apps/earn-vaults.ts +2 -1
- package/src/admin/apps/organizations.test.ts +53 -1
- package/src/admin/apps/organizations.ts +90 -5
- package/src/admin/ui/src/lib/api-keys.ts +19 -0
- package/src/admin/ui/src/lib/organizations.test.ts +112 -1
- package/src/admin/ui/src/lib/organizations.ts +55 -0
- package/src/admin/ui/src/routes/api-keys.tsx +89 -2
- package/src/admin/ui/src/routes/organizations_.$orgId.tsx +116 -0
- package/src/admin/ui.generated.ts +189 -151
- package/src/apps/Zones.test.ts +7 -7
- package/src/apps/Zones.ts +7 -7
- package/src/apps/composition.test.ts +2 -1
- package/src/apps/data/App.test.ts +41 -0
- package/src/apps/data/App.ts +30 -21
- package/src/apps/data/ZoneSelection.test.ts +2 -2
- package/src/apps/data/ZoneSelection.ts +8 -8
- package/src/apps/data/routes/activities.test.ts +1526 -12
- package/src/apps/data/routes/activities.ts +1774 -1356
- package/src/apps/data/routes/balances.ts +133 -97
- package/src/apps/data/routes/blocks.test.ts +533 -0
- package/src/apps/data/routes/blocks.ts +35 -16
- package/src/apps/data/routes/earn.test.ts +373 -16
- package/src/apps/data/routes/earn.ts +548 -79
- package/src/apps/data/routes/earn.zone-access.test.ts +6 -6
- package/src/apps/data/routes/exchanges.test.ts +740 -15
- package/src/apps/data/routes/exchanges.ts +954 -753
- package/src/apps/data/routes/fee-amm.ts +17 -18
- package/src/apps/data/routes/receipts.ts +47 -16
- package/src/apps/data/routes/tokens.test.ts +578 -0
- package/src/apps/data/routes/tokens.ts +283 -225
- package/src/apps/data/routes/transactions.ts +68 -29
- package/src/apps/data/routes/transfers.test.ts +421 -0
- package/src/apps/data/routes/transfers.ts +45 -27
- package/src/apps/data/routes/valuation.ts +94 -78
- package/src/apps/data/routes/webhooks.test.ts +21 -5
- package/src/apps/data/routes/webhooks.ts +63 -8
- package/src/apps/data/routes/zones.test.ts +2 -2
- package/src/apps/data/routes/zones.ts +1 -1
- package/src/apps/funding/App.ts +12 -2
- package/src/apps/funding/routes/deposit-addresses.test.ts +29 -7
- package/src/apps/funding/routes/deposit-addresses.ts +19 -14
- package/src/apps/funding/routes/quotes.test.ts +5 -9
- package/src/apps/funding/routes/transfers.test.ts +901 -23
- package/src/apps/funding/routes/transfers.ts +347 -64
- package/src/apps/management/Billing.ts +18 -5
- package/src/apps/management/routes/api-keys.test.ts +220 -0
- package/src/apps/management/routes/api-keys.ts +280 -3
- package/src/apps/management/routes/webhooks.test.ts +3 -3
- package/src/apps/management/routes/webhooks.ts +24 -25
- package/src/apps/relay/App.test.ts +212 -1
- package/src/apps/relay/App.ts +158 -29
- package/src/apps/relay/Sponsorships.ts +24 -1
- package/src/db/Db.ts +48 -1
- package/src/db/Schema.ts +22 -4
- package/src/db/tables/earnVaults.test.ts +9 -9
- package/src/db/tables/fundingCatalog.test.ts +16 -2
- package/src/db/tables/fundingCatalog.ts +9 -3
- package/src/db/tables/fundingTransferTransactions.test.ts +43 -0
- package/src/db/tables/fundingTransferTransactions.ts +79 -3
- package/src/db/tables/fundingTransfers.test.ts +26 -0
- package/src/db/tables/fundingTransfers.ts +36 -0
- package/src/db/tables/organizations.test.ts +41 -0
- package/src/db/tables/organizations.ts +49 -0
- package/src/db/tables/projects.test.ts +55 -0
- package/src/db/tables/projects.ts +46 -1
- package/src/db/tables/sponsoredTransactions.test.ts +338 -0
- package/src/db/tables/sponsoredTransactions.ts +197 -13
- package/src/db/tables/webhookSubscriptions.ts +18 -11
- package/src/handlers/internal/utils.test.ts +53 -0
- package/src/handlers/internal/utils.ts +15 -0
- package/src/internal/Auth.ts +12 -4
- package/src/internal/EarnVaults.capabilities.test.ts +2 -2
- package/src/internal/EarnVaults.test.ts +1 -1
- package/src/internal/EarnVaults.ts +5 -5
- package/src/internal/Fetch.test.ts +46 -0
- package/src/internal/Fetch.ts +56 -0
- package/src/internal/Log.test-d.ts +2 -0
- package/src/internal/Log.test.ts +21 -0
- package/src/internal/Log.ts +22 -5
- package/src/internal/OpenApi.ts +14 -4
- package/src/internal/Response.ts +1 -1
- package/src/internal/Schema.test.ts +2 -0
- package/src/internal/Schema.ts +12 -2
- package/src/internal/Store.test.ts +178 -0
- package/src/internal/Store.ts +104 -18
- package/src/internal/Tidx.test.ts +2 -1
- package/src/internal/Tidx.ts +7 -2
- package/src/internal/Timeout.test.ts +35 -0
- package/src/internal/Timeout.ts +73 -0
- package/src/internal/Timing.ts +16 -0
- package/src/internal/Viem.ts +39 -3
- package/src/internal/WebhookDestination.ts +3 -0
- package/src/internal/Webhooks.test.ts +45 -0
- package/src/internal/funding/Action.test.ts +41 -1
- package/src/internal/funding/Action.ts +69 -41
- package/src/internal/funding/Catalog.test.ts +34 -0
- package/src/internal/funding/Catalog.ts +28 -11
- package/src/internal/funding/DepositWebhook.ts +2 -1
- package/src/internal/funding/Evidence.ts +2 -13
- package/src/internal/funding/Provider.test.ts +73 -0
- package/src/internal/funding/Provider.ts +125 -28
- package/src/internal/funding/SourceObservation.ts +5 -9
- package/src/internal/funding/Transfer.test.ts +155 -0
- package/src/internal/funding/Transfer.ts +387 -147
- package/src/internal/funding/TransferReconciliation.test.ts +147 -0
- package/src/internal/funding/TransferReconciliation.ts +264 -0
- package/src/internal/funding/TransferWebhook.test.ts +128 -0
- package/src/internal/funding/TransferWebhook.ts +67 -0
- package/src/internal/funding/index.test.ts +1 -0
- package/src/internal/funding/index.ts +1 -0
- package/src/internal/funding/providers/index.test.ts +4 -167
- package/src/internal/funding/providers/relay.test.ts +2 -2
- package/src/internal/funding/providers/relay.ts +3 -15
- package/src/internal/funding/providers/stargate.test.ts +328 -0
- package/src/internal/funding/providers/stargate.ts +807 -135
- package/src/internal/index.test.ts +1 -0
- package/src/internal/index.ts +1 -0
- package/src/internal/webhookDestinations/slack.ts +15 -0
package/src/Client.test-d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Mpp as PublicMpp } from 'tapimo/mpp'
|
|
|
3
3
|
import type * as z from 'zod/mini'
|
|
4
4
|
|
|
5
5
|
import * as Activities from './apps/data/routes/activities.js'
|
|
6
|
+
import * as ApiKeys from './apps/management/routes/api-keys.js'
|
|
6
7
|
import * as Balances from './apps/data/routes/balances.js'
|
|
7
8
|
import * as Billing from './apps/management/routes/billing.js'
|
|
8
9
|
import * as Blocks from './apps/data/routes/blocks.js'
|
|
@@ -82,6 +83,50 @@ test('returns typed client', async () => {
|
|
|
82
83
|
})
|
|
83
84
|
|
|
84
85
|
describe('narrows responses by status', () => {
|
|
86
|
+
test('POST /v1/orgs/:orgId/projects/:projectId/api-keys/:keyId/rotate', async () => {
|
|
87
|
+
const client = Client.create()
|
|
88
|
+
const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}'].projects[
|
|
89
|
+
':projectId{prj_[A-Za-z0-9_-]+}'
|
|
90
|
+
]['api-keys'][':keyId{key_[A-Za-z0-9_-]+}'].rotate.$post({
|
|
91
|
+
param: { keyId: 'key_test', orgId: 'org_test', projectId: 'prj_test' },
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 401 | 403 | 404 | 502>()
|
|
95
|
+
|
|
96
|
+
if (res.status === 200) {
|
|
97
|
+
const json = await res.json()
|
|
98
|
+
expectTypeOf(json).toEqualTypeOf<z.output<typeof ApiKeys.schema.rotateApiKey.Response>>()
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
test('POST /v1/orgs/:orgId/api-keys/:keyId/rotate', async () => {
|
|
103
|
+
const client = Client.create()
|
|
104
|
+
const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['api-keys'][
|
|
105
|
+
':keyId{key_[A-Za-z0-9_-]+}'
|
|
106
|
+
].rotate.$post({ param: { keyId: 'key_test', orgId: 'org_test' } })
|
|
107
|
+
|
|
108
|
+
expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 401 | 403 | 404 | 502>()
|
|
109
|
+
|
|
110
|
+
if (res.status === 200) {
|
|
111
|
+
const json = await res.json()
|
|
112
|
+
expectTypeOf(json).toEqualTypeOf<z.output<typeof ApiKeys.schema.rotateApiKey.Response>>()
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
test('DELETE /v1/orgs/:orgId/api-keys/:keyId', async () => {
|
|
117
|
+
const client = Client.create()
|
|
118
|
+
const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['api-keys'][
|
|
119
|
+
':keyId{key_[A-Za-z0-9_-]+}'
|
|
120
|
+
].$delete({ param: { keyId: 'key_test', orgId: 'org_test' } })
|
|
121
|
+
|
|
122
|
+
expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 401 | 403 | 404 | 429 | 502>()
|
|
123
|
+
|
|
124
|
+
if (res.status === 200) {
|
|
125
|
+
const json = await res.json()
|
|
126
|
+
expectTypeOf(json).toEqualTypeOf<z.output<typeof ApiKeys.schema.revokeApiKey.Response>>()
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
|
|
85
130
|
test('POST /v1/mpp/validate', async () => {
|
|
86
131
|
const client = Client.create()
|
|
87
132
|
const res = await client.v1.mpp.validate.$post({ json: mppInput })
|
|
@@ -196,6 +241,9 @@ describe('narrows responses by status', () => {
|
|
|
196
241
|
expectTypeOf(json.data[0]!.capabilities?.deposit).toEqualTypeOf<boolean | undefined>()
|
|
197
242
|
expectTypeOf(json.data[0]!.engine.type).toEqualTypeOf<'erc4626' | 'veda' | null>()
|
|
198
243
|
expectTypeOf(json.data[0]!.instantLiquidity).toEqualTypeOf<string | null>()
|
|
244
|
+
expectTypeOf(json.data[0]!.instantLiquidityValue).toEqualTypeOf<
|
|
245
|
+
VaultValue | null | undefined
|
|
246
|
+
>()
|
|
199
247
|
expectTypeOf(json.data[0]!.sharePrice?.amount).toEqualTypeOf<string | undefined>()
|
|
200
248
|
expectTypeOf(json.data[0]!.slug).toEqualTypeOf<string | null>()
|
|
201
249
|
expectTypeOf(json.data[0]!.state.openRedeemRequestCount).toEqualTypeOf<number>()
|
|
@@ -271,7 +319,7 @@ describe('narrows responses by status', () => {
|
|
|
271
319
|
const client = Client.create()
|
|
272
320
|
const res = await client.v1.earn.addresses[':address'].positions.$get({
|
|
273
321
|
param: { address: `0x${'bb'.repeat(20)}` },
|
|
274
|
-
query: { 'valuation.currency': 'USD', verified: 'true' },
|
|
322
|
+
query: { include: 'earnings', 'valuation.currency': 'USD', verified: 'true' },
|
|
275
323
|
})
|
|
276
324
|
|
|
277
325
|
expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 502 | PaidAccessStatus>()
|
|
@@ -286,6 +334,13 @@ describe('narrows responses by status', () => {
|
|
|
286
334
|
expectTypeOf(json.data[0]!.assetToken.address).toEqualTypeOf<`0x${string}`>()
|
|
287
335
|
expectTypeOf(json.data[0]!.assetToken.decimals).toEqualTypeOf<number>()
|
|
288
336
|
expectTypeOf(json.data[0]!.id).toEqualTypeOf<`0x${string}`>()
|
|
337
|
+
expectTypeOf(json.data[0]!.lifetimeCashFlows?.status).toEqualTypeOf<
|
|
338
|
+
'complete' | 'incomplete_history' | undefined
|
|
339
|
+
>()
|
|
340
|
+
if (json.data[0]!.lifetimeCashFlows?.status === 'complete') {
|
|
341
|
+
expectTypeOf(json.data[0]!.lifetimeCashFlows.totalDeposited).toEqualTypeOf<string>()
|
|
342
|
+
expectTypeOf(json.data[0]!.lifetimeCashFlows.totalWithdrawn).toEqualTypeOf<string>()
|
|
343
|
+
}
|
|
289
344
|
expectTypeOf(json.data[0]!.shareAmount.amount).toEqualTypeOf<string>()
|
|
290
345
|
expectTypeOf(json.data[0]!.shareAmount.decimals).toEqualTypeOf<number>()
|
|
291
346
|
expectTypeOf(json.data[0]!.shareAmount.formatted).toEqualTypeOf<string>()
|
|
@@ -336,6 +391,7 @@ describe('narrows responses by status', () => {
|
|
|
336
391
|
expectTypeOf(json.assetToken.address).toEqualTypeOf<`0x${string}`>()
|
|
337
392
|
expectTypeOf(json.engine.type).toEqualTypeOf<'erc4626' | 'veda' | null>()
|
|
338
393
|
expectTypeOf(json.instantLiquidity).toEqualTypeOf<string | null>()
|
|
394
|
+
expectTypeOf(json.instantLiquidityValue).toEqualTypeOf<VaultValue | null | undefined>()
|
|
339
395
|
expectTypeOf(json.label).toEqualTypeOf<string>()
|
|
340
396
|
expectTypeOf(json.meta?.valuation?.asOf).toEqualTypeOf<string | undefined>()
|
|
341
397
|
expectTypeOf(json.sharePrice?.decimals).toEqualTypeOf<number | undefined>()
|
|
@@ -374,6 +430,7 @@ describe('narrows responses by status', () => {
|
|
|
374
430
|
address: `0x${'bb'.repeat(20)}`,
|
|
375
431
|
vaultId: `0x${'aa'.repeat(20)}`,
|
|
376
432
|
},
|
|
433
|
+
query: { asOf: '2026-07-21T09:00:00.000Z' },
|
|
377
434
|
})
|
|
378
435
|
|
|
379
436
|
expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 404 | 502 | PaidAccessStatus>()
|
|
@@ -385,6 +442,9 @@ describe('narrows responses by status', () => {
|
|
|
385
442
|
expectTypeOf(json.assetAllowance).toEqualTypeOf<string>()
|
|
386
443
|
expectTypeOf(json.assetBalance).toEqualTypeOf<string>()
|
|
387
444
|
expectTypeOf(json.assetToken).toEqualTypeOf<`0x${string}`>()
|
|
445
|
+
expectTypeOf(json.asOf).toEqualTypeOf<string | undefined>()
|
|
446
|
+
expectTypeOf(json.block?.number).toEqualTypeOf<number | undefined>()
|
|
447
|
+
expectTypeOf(json.block?.timestamp).toEqualTypeOf<string | undefined>()
|
|
388
448
|
expectTypeOf(json.id).toEqualTypeOf<`0x${string}`>()
|
|
389
449
|
expectTypeOf(json.shareAllowance).toEqualTypeOf<string>()
|
|
390
450
|
expectTypeOf(json.shareBalance).toEqualTypeOf<string>()
|
|
@@ -442,7 +502,23 @@ describe('narrows responses by status', () => {
|
|
|
442
502
|
if (json.status === 'complete' && json.period === 'active')
|
|
443
503
|
expectTypeOf(json.activeEarnings).toEqualTypeOf<string>()
|
|
444
504
|
if (json.status === 'complete' && json.period === 'lifetime')
|
|
445
|
-
expectTypeOf(
|
|
505
|
+
expectTypeOf({
|
|
506
|
+
lifetimeEarnings: json.lifetimeEarnings,
|
|
507
|
+
totalDeposited: json.totalDeposited,
|
|
508
|
+
totalWithdrawn: json.totalWithdrawn,
|
|
509
|
+
}).toEqualTypeOf<{
|
|
510
|
+
lifetimeEarnings: string
|
|
511
|
+
totalDeposited: string
|
|
512
|
+
totalWithdrawn: string
|
|
513
|
+
}>()
|
|
514
|
+
if (json.status === 'pending_redemption' && json.period === 'lifetime')
|
|
515
|
+
expectTypeOf({
|
|
516
|
+
totalDeposited: json.totalDeposited,
|
|
517
|
+
totalWithdrawn: json.totalWithdrawn,
|
|
518
|
+
}).toEqualTypeOf<{
|
|
519
|
+
totalDeposited: string
|
|
520
|
+
totalWithdrawn: string
|
|
521
|
+
}>()
|
|
446
522
|
if (json.status === 'complete' && json.period === '30d')
|
|
447
523
|
expectTypeOf(json.windowEarnings).toEqualTypeOf<string>()
|
|
448
524
|
void json
|
|
@@ -2563,6 +2639,7 @@ describe('narrows responses by status', () => {
|
|
|
2563
2639
|
amount: '1000000',
|
|
2564
2640
|
destinationToken: '0x20c000000000000000000000b9537d11c60e8b50',
|
|
2565
2641
|
mode: 'exactSource',
|
|
2642
|
+
provider: 'stargate',
|
|
2566
2643
|
recipient: `0x${'11'.repeat(20)}`,
|
|
2567
2644
|
sender: `0x${'22'.repeat(20)}`,
|
|
2568
2645
|
sourceChain: 'eip155:8453',
|
|
@@ -2692,6 +2769,42 @@ describe('narrows responses by status', () => {
|
|
|
2692
2769
|
}
|
|
2693
2770
|
})
|
|
2694
2771
|
|
|
2772
|
+
test('POST /v1/funding/transfers/:id/source-transactions', async () => {
|
|
2773
|
+
const client = Client.create()
|
|
2774
|
+
const res = await client.v1.funding.transfers[':id{ftr_[A-Za-z0-9_-]+}'][
|
|
2775
|
+
'source-transactions'
|
|
2776
|
+
].$post({
|
|
2777
|
+
json: { transactionHash: `0x${'51'.repeat(32)}` },
|
|
2778
|
+
param: { id: 'ftr_test' },
|
|
2779
|
+
})
|
|
2780
|
+
|
|
2781
|
+
expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 404 | 409 | 501 | 502 | PublicAccessStatus>()
|
|
2782
|
+
|
|
2783
|
+
switch (res.status) {
|
|
2784
|
+
case 200: {
|
|
2785
|
+
const json = await res.json()
|
|
2786
|
+
expectTypeOf(json.sourceTransactionHashes).toEqualTypeOf<string[] | undefined>()
|
|
2787
|
+
expectTypeOf(json.status).toEqualTypeOf<
|
|
2788
|
+
z.output<
|
|
2789
|
+
typeof FundingTransfers.schema.registerFundingTransferSourceTransaction.Response
|
|
2790
|
+
>['status']
|
|
2791
|
+
>()
|
|
2792
|
+
void json
|
|
2793
|
+
return
|
|
2794
|
+
}
|
|
2795
|
+
case 409: {
|
|
2796
|
+
const json = await res.json()
|
|
2797
|
+
expectTypeOf(json.error.code).toEqualTypeOf<
|
|
2798
|
+
| 'funding_transfer_not_awaiting_source'
|
|
2799
|
+
| 'source_transaction_conflict'
|
|
2800
|
+
| 'source_transaction_pending'
|
|
2801
|
+
>()
|
|
2802
|
+
void json
|
|
2803
|
+
return
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2806
|
+
})
|
|
2807
|
+
|
|
2695
2808
|
test('GET /v1/exchange/swaps', async () => {
|
|
2696
2809
|
const client = Client.create()
|
|
2697
2810
|
const res = await client.v1.exchange.swaps.$get()
|
|
@@ -3611,6 +3724,16 @@ describe('narrows responses by status', () => {
|
|
|
3611
3724
|
},
|
|
3612
3725
|
},
|
|
3613
3726
|
})
|
|
3727
|
+
void client.v1.webhooks.$post({
|
|
3728
|
+
json: {
|
|
3729
|
+
destination: { type: 'url', url: 'https://example.com/webhook' },
|
|
3730
|
+
eventType: 'funding:transfer.updated',
|
|
3731
|
+
filters: {
|
|
3732
|
+
id: 'ftr_001785792000000_2ZPE2gvateYEQ0dQslgvkhjx',
|
|
3733
|
+
status: 'completed',
|
|
3734
|
+
},
|
|
3735
|
+
},
|
|
3736
|
+
})
|
|
3614
3737
|
const res = await client.v1.webhooks.$post({
|
|
3615
3738
|
json: {
|
|
3616
3739
|
destination: { type: 'url', url: 'https://example.com/webhook' },
|
|
@@ -3902,6 +4025,10 @@ describe('narrows responses by status', () => {
|
|
|
3902
4025
|
expectTypeOf(json.envelope.data.status).toEqualTypeOf<
|
|
3903
4026
|
z.output<typeof Webhooks.schema.FundingDepositEvent>['status']
|
|
3904
4027
|
>()
|
|
4028
|
+
if (json.envelope.type === 'funding:transfer.updated')
|
|
4029
|
+
expectTypeOf(json.envelope.data.status).toEqualTypeOf<
|
|
4030
|
+
z.output<typeof Webhooks.schema.FundingTransferEvent>['status']
|
|
4031
|
+
>()
|
|
3905
4032
|
expectTypeOf(json.requestUrl).toEqualTypeOf<string>()
|
|
3906
4033
|
void json
|
|
3907
4034
|
}
|
package/src/Scope.test.ts
CHANGED
|
@@ -52,3 +52,23 @@ describe('extend', () => {
|
|
|
52
52
|
).toThrowErrorMatchingInlineSnapshot(`[Error: Duplicate scope \`data:read\`.]`)
|
|
53
53
|
})
|
|
54
54
|
})
|
|
55
|
+
|
|
56
|
+
describe('expandAliases', () => {
|
|
57
|
+
test('adds the current scope for a legacy Zone read scope', () => {
|
|
58
|
+
expect(
|
|
59
|
+
Scope.expandAliases(['data:read', 'zone:1424310001:read', 'zone:1424310001:write']),
|
|
60
|
+
).toEqual([
|
|
61
|
+
'data:read',
|
|
62
|
+
'zone:1424310001:read',
|
|
63
|
+
'zone:1424310001:write',
|
|
64
|
+
'zone:1424310003:read',
|
|
65
|
+
])
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
test('does not duplicate an existing current scope', () => {
|
|
69
|
+
expect(Scope.expandAliases(['zone:1424310001:read', 'zone:1424310003:read'])).toEqual([
|
|
70
|
+
'zone:1424310001:read',
|
|
71
|
+
'zone:1424310003:read',
|
|
72
|
+
])
|
|
73
|
+
})
|
|
74
|
+
})
|
package/src/Scope.ts
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
import * as z from 'zod/mini'
|
|
8
8
|
|
|
9
|
+
import * as Schema from './internal/Schema.js'
|
|
10
|
+
|
|
9
11
|
/**
|
|
10
12
|
* Wildcard scope. A key whose `scopes` contains this value satisfies every
|
|
11
13
|
* required scope, so it never needs re-provisioning when new scopes are added.
|
|
@@ -154,6 +156,20 @@ export function includes(catalog: Catalog, scope: string): scope is Id {
|
|
|
154
156
|
return schema.Zone.safeParse(scope).success || catalog.some((entry) => entry.scope === scope)
|
|
155
157
|
}
|
|
156
158
|
|
|
159
|
+
/** Adds current read scopes granted by legacy Zone read scopes. */
|
|
160
|
+
export function expandAliases(scopes: readonly string[]): readonly string[] {
|
|
161
|
+
const aliases = new Set<string>()
|
|
162
|
+
for (const scope of scopes) {
|
|
163
|
+
const match = /^zone:([1-9]\d*):read$/.exec(scope)
|
|
164
|
+
if (!match) continue
|
|
165
|
+
const chainId = Number(match[1])
|
|
166
|
+
const resolved = Schema.resolveChainId(chainId)
|
|
167
|
+
if (resolved !== chainId) aliases.add(`zone:${resolved}:read`)
|
|
168
|
+
}
|
|
169
|
+
for (const scope of scopes) aliases.delete(scope)
|
|
170
|
+
return aliases.size ? [...scopes, ...aliases] : scopes
|
|
171
|
+
}
|
|
172
|
+
|
|
157
173
|
/** Returns the self-issuable identifiers in a scope catalog. */
|
|
158
174
|
export function selfServeFrom(catalog: Catalog): readonly Id[] {
|
|
159
175
|
return catalog
|
package/src/Webhooks.ts
CHANGED
|
@@ -5,6 +5,6 @@ export * from './internal/Webhooks.js'
|
|
|
5
5
|
|
|
6
6
|
// Re-export the webhook resource's zod schemas so consumers can validate and
|
|
7
7
|
// type delivery bodies: `Webhooks.schema.Envelope` (a discriminated union on
|
|
8
|
-
// `type`), plus the per-event
|
|
9
|
-
//
|
|
8
|
+
// `type`), plus the per-event payload schemas such as `FundingTransferEvent`.
|
|
9
|
+
// Infer a type with `z.infer<typeof Webhooks.schema.Envelope>`.
|
|
10
10
|
export { enrichEventData, eventTypes, scanBlock, schema } from './apps/data/routes/webhooks.js'
|
|
@@ -299,6 +299,81 @@ describe('DELETE /api-keys/:id', () => {
|
|
|
299
299
|
})
|
|
300
300
|
})
|
|
301
301
|
|
|
302
|
+
describe('POST /api-keys/:id/rotate', () => {
|
|
303
|
+
test('mints a replacement with the source access and attribution', async () => {
|
|
304
|
+
const { client, store } = await setup()
|
|
305
|
+
const { record: source, token: sourceToken } = await core_ApiKeys.mint(store, {
|
|
306
|
+
allowedIps: ['203.0.113.0/24'],
|
|
307
|
+
billingActive: true,
|
|
308
|
+
createdBy: 'customer@example.com',
|
|
309
|
+
environment: 'sandbox',
|
|
310
|
+
expiresAt: '2100-01-01T00:00:00.000Z',
|
|
311
|
+
name: 'Privy Zones',
|
|
312
|
+
orgId: 'org_privy',
|
|
313
|
+
projectId: 'prj_privy',
|
|
314
|
+
rateLimits: { '*': { limit: 10_000, period: 'minute' } },
|
|
315
|
+
scopes: ['zone:421700001:read', 'zone:421700001:write'],
|
|
316
|
+
})
|
|
317
|
+
|
|
318
|
+
const response = await client['api-keys'][':id'].rotate.$post({
|
|
319
|
+
param: { id: source.id },
|
|
320
|
+
})
|
|
321
|
+
const body = await TestApp.json(response, ApiKeys.schema.rotateApiKey.Response)
|
|
322
|
+
|
|
323
|
+
expect(response.status).toBe(200)
|
|
324
|
+
expect(body).toMatchObject({
|
|
325
|
+
allowedIps: source.allowedIps,
|
|
326
|
+
billingActive: source.billingActive,
|
|
327
|
+
createdBy: TestAdmin.identity.email,
|
|
328
|
+
environment: source.environment,
|
|
329
|
+
expiresAt: source.expiresAt,
|
|
330
|
+
name: source.name,
|
|
331
|
+
orgId: source.orgId,
|
|
332
|
+
projectId: source.projectId,
|
|
333
|
+
rateLimits: source.rateLimits,
|
|
334
|
+
scopes: source.scopes,
|
|
335
|
+
})
|
|
336
|
+
expect(body.id).not.toBe(source.id)
|
|
337
|
+
expect(body.token).not.toBe(sourceToken)
|
|
338
|
+
expect(await core_ApiKeys.resolve(store, sourceToken)).not.toBeNull()
|
|
339
|
+
expect(await core_ApiKeys.resolve(store, body.token)).toMatchObject({
|
|
340
|
+
id: body.id,
|
|
341
|
+
scopes: source.scopes,
|
|
342
|
+
})
|
|
343
|
+
})
|
|
344
|
+
|
|
345
|
+
test('unknown id → 404', async () => {
|
|
346
|
+
const { client } = await setup()
|
|
347
|
+
const response = await client['api-keys'][':id'].rotate.$post({
|
|
348
|
+
param: { id: 'key_missing' },
|
|
349
|
+
})
|
|
350
|
+
|
|
351
|
+
expect(response.status).toMatchInlineSnapshot(`404`)
|
|
352
|
+
})
|
|
353
|
+
|
|
354
|
+
test('keeps a rotated one-off key assignable to an organization', async () => {
|
|
355
|
+
const { client, db, store } = await setup()
|
|
356
|
+
const organization = await Organizations.create(db, { name: 'Tempo' })
|
|
357
|
+
const { record: source } = await core_ApiKeys.mint(store, {
|
|
358
|
+
name: 'One-off',
|
|
359
|
+
scopes: ['data:read'],
|
|
360
|
+
})
|
|
361
|
+
|
|
362
|
+
const rotateResponse = await client['api-keys'][':id'].rotate.$post({
|
|
363
|
+
param: { id: source.id },
|
|
364
|
+
})
|
|
365
|
+
const replacement = await TestApp.json(rotateResponse, ApiKeys.schema.rotateApiKey.Response)
|
|
366
|
+
expect(replacement.orgId).toBe(replacement.id)
|
|
367
|
+
|
|
368
|
+
const updateResponse = await client['api-keys'][':id'].$patch({
|
|
369
|
+
json: { orgId: organization.id },
|
|
370
|
+
param: { id: replacement.id },
|
|
371
|
+
})
|
|
372
|
+
expect(updateResponse.status).toBe(200)
|
|
373
|
+
expect((await core_ApiKeys.get(store, replacement.id))?.orgId).toBe(organization.id)
|
|
374
|
+
})
|
|
375
|
+
})
|
|
376
|
+
|
|
302
377
|
describe('PATCH /api-keys/:id', () => {
|
|
303
378
|
test('preserves the allowlist when omitted', async () => {
|
|
304
379
|
const { client, store } = TestAdmin.setup()
|
|
@@ -173,6 +173,24 @@ export namespace schema {
|
|
|
173
173
|
.object({ id: z.string().check(z.describe('Revoked key id.')) })
|
|
174
174
|
.check(z.describe('API-key revocation result.'))
|
|
175
175
|
}
|
|
176
|
+
|
|
177
|
+
/** Schemas for the rotateApiKey operation. */
|
|
178
|
+
export namespace rotateApiKey {
|
|
179
|
+
/** Path parameters for rotating a key. */
|
|
180
|
+
export const Params = z
|
|
181
|
+
.object({
|
|
182
|
+
id: z
|
|
183
|
+
.string()
|
|
184
|
+
.check(
|
|
185
|
+
z.describe('Stable id of the key to rotate.'),
|
|
186
|
+
z.meta({ examples: ['key_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
|
|
187
|
+
),
|
|
188
|
+
})
|
|
189
|
+
.check(z.describe('Path parameters for rotating an API key.'))
|
|
190
|
+
|
|
191
|
+
/** Response: the replacement record plus its one-time plaintext token. */
|
|
192
|
+
export const Response = createApiKey.Response
|
|
193
|
+
}
|
|
176
194
|
}
|
|
177
195
|
|
|
178
196
|
/**
|
|
@@ -183,6 +201,7 @@ export namespace schema {
|
|
|
183
201
|
* - `GET /` lists key records (metadata only), optionally filtered by `orgId`.
|
|
184
202
|
* - `DELETE /:id` revokes a key by id (`404` if absent).
|
|
185
203
|
* - `PATCH /:id` updates a key's allowlist, name, or project, or assigns its first organization.
|
|
204
|
+
* - `POST /:id/rotate` mints a replacement with the source key's access and attribution.
|
|
186
205
|
* - `POST /backfill` rebuilds the id and org index entries for every record.
|
|
187
206
|
*/
|
|
188
207
|
export function apiKeys() {
|
|
@@ -315,6 +334,51 @@ export function apiKeys() {
|
|
|
315
334
|
return c.json(Response.validated(schema.revokeApiKey.Response, { id }))
|
|
316
335
|
},
|
|
317
336
|
)
|
|
337
|
+
.post(
|
|
338
|
+
'/:id/rotate',
|
|
339
|
+
OpenApi.validate('param', schema.rotateApiKey.Params, {
|
|
340
|
+
code: 'param_invalid',
|
|
341
|
+
message: 'Invalid path parameters',
|
|
342
|
+
}),
|
|
343
|
+
OpenApi.describeRoute({
|
|
344
|
+
description: 'Create a replacement that preserves the source key access and attribution. The source key remains active.', // prettier-ignore
|
|
345
|
+
operationId: 'rotateAdminApiKey',
|
|
346
|
+
responses: OpenApi.responses({
|
|
347
|
+
errors: { 404: 'API key not found.' },
|
|
348
|
+
success: {
|
|
349
|
+
description: 'Replacement key (includes the one-time token).',
|
|
350
|
+
schema: schema.rotateApiKey.Response,
|
|
351
|
+
},
|
|
352
|
+
}),
|
|
353
|
+
summary: 'Rotate API key',
|
|
354
|
+
tags: ['API keys'],
|
|
355
|
+
}),
|
|
356
|
+
async (c) => {
|
|
357
|
+
const { id } = c.req.valid('param')
|
|
358
|
+
const store = c.get('kv').store
|
|
359
|
+
const source = await ApiKeys.get(store, id)
|
|
360
|
+
if (!source)
|
|
361
|
+
return Response.error(c, {
|
|
362
|
+
code: 'not_found',
|
|
363
|
+
message: 'API key not found.',
|
|
364
|
+
status: 404,
|
|
365
|
+
})
|
|
366
|
+
|
|
367
|
+
const { record, token } = await ApiKeys.mint(store, {
|
|
368
|
+
allowedIps: source.allowedIps,
|
|
369
|
+
createdBy: c.get('identity')!.email,
|
|
370
|
+
environment: source.environment,
|
|
371
|
+
scopes: source.scopes,
|
|
372
|
+
...(source.billingActive === undefined ? {} : { billingActive: source.billingActive }),
|
|
373
|
+
...(source.expiresAt === undefined ? {} : { expiresAt: source.expiresAt }),
|
|
374
|
+
...(source.name === undefined ? {} : { name: source.name }),
|
|
375
|
+
...(source.orgId === source.id ? {} : { orgId: source.orgId }),
|
|
376
|
+
...(source.projectId === undefined ? {} : { projectId: source.projectId }),
|
|
377
|
+
...(source.rateLimits === undefined ? {} : { rateLimits: source.rateLimits }),
|
|
378
|
+
})
|
|
379
|
+
return c.json(Response.validated(schema.rotateApiKey.Response, { ...record, token }), 200)
|
|
380
|
+
},
|
|
381
|
+
)
|
|
318
382
|
.patch(
|
|
319
383
|
'/:id',
|
|
320
384
|
OpenApi.validate('param', schema.updateApiKey.Params, {
|
|
@@ -204,7 +204,7 @@ describe('putVerifiedEarnVault', () => {
|
|
|
204
204
|
expect(await response.json()).toMatchObject({
|
|
205
205
|
error: {
|
|
206
206
|
code: 'body_invalid',
|
|
207
|
-
details: [{ message: 'Zone
|
|
207
|
+
details: [{ message: 'Zone 1424310003 is configured more than once.' }],
|
|
208
208
|
},
|
|
209
209
|
})
|
|
210
210
|
},
|
|
@@ -94,7 +94,7 @@ export namespace schema {
|
|
|
94
94
|
.check(z.describe('Custom vault slug, generated from the label when omitted.')),
|
|
95
95
|
vaultAddress: Schema.Address.check(
|
|
96
96
|
z.describe('Earn vault contract address.'),
|
|
97
|
-
z.meta({ examples: ['
|
|
97
|
+
z.meta({ examples: ['0x4f94590b636f5878bce585e82379de81e1ec174f'] }),
|
|
98
98
|
),
|
|
99
99
|
zones: z
|
|
100
100
|
.optional(z.array(EarnVaults.schema.ZoneRoute))
|
|
@@ -510,6 +510,7 @@ async function serializeVault(
|
|
|
510
510
|
assetToken,
|
|
511
511
|
discovery: options.discovery,
|
|
512
512
|
include: options.include,
|
|
513
|
+
instantLiquidityValue: null,
|
|
513
514
|
record: options.record,
|
|
514
515
|
shareToken,
|
|
515
516
|
tvl: null,
|
|
@@ -181,6 +181,7 @@ describe('GET /organizations/:orgId', () => {
|
|
|
181
181
|
settings: { spendLimit: '1000', txFeeLimit: null },
|
|
182
182
|
source: null,
|
|
183
183
|
})
|
|
184
|
+
expect(body.sponsorshipSubsidy).toEqual({ durationDays: null, projectSpendLimit: null })
|
|
184
185
|
})
|
|
185
186
|
|
|
186
187
|
test('returns empty counts and billing for a memberless organization', async () => {
|
|
@@ -215,6 +216,57 @@ describe('GET /organizations/:orgId', () => {
|
|
|
215
216
|
})
|
|
216
217
|
})
|
|
217
218
|
|
|
219
|
+
describe('PUT /organizations/:orgId/sponsorship', () => {
|
|
220
|
+
test('enables and disables a 90-day per-project policy', async () => {
|
|
221
|
+
const { client, db } = TestAdmin.setup()
|
|
222
|
+
const organization = await Organizations.create(db, { name: 'Privy' })
|
|
223
|
+
|
|
224
|
+
const enabled = await client.organizations[':orgId'].sponsorship.$put({
|
|
225
|
+
json: { enabled: true, projectSpendLimit: '1000' },
|
|
226
|
+
param: { orgId: organization.id },
|
|
227
|
+
})
|
|
228
|
+
expect(
|
|
229
|
+
await TestApp.json(enabled, AdminOrganizations.schema.organizationSponsorship.SetResponse),
|
|
230
|
+
).toEqual({ durationDays: 90, projectSpendLimit: '1000' })
|
|
231
|
+
|
|
232
|
+
const disabled = await client.organizations[':orgId'].sponsorship.$put({
|
|
233
|
+
json: { enabled: false },
|
|
234
|
+
param: { orgId: organization.id },
|
|
235
|
+
})
|
|
236
|
+
expect(
|
|
237
|
+
await TestApp.json(disabled, AdminOrganizations.schema.organizationSponsorship.SetResponse),
|
|
238
|
+
).toEqual({ durationDays: null, projectSpendLimit: null })
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
test('enables an uncapped policy', async () => {
|
|
242
|
+
const { client, db } = TestAdmin.setup()
|
|
243
|
+
const organization = await Organizations.create(db, { name: 'Privy' })
|
|
244
|
+
const response = await client.organizations[':orgId'].sponsorship.$put({
|
|
245
|
+
json: { enabled: true },
|
|
246
|
+
param: { orgId: organization.id },
|
|
247
|
+
})
|
|
248
|
+
expect(
|
|
249
|
+
await TestApp.json(response, AdminOrganizations.schema.organizationSponsorship.SetResponse),
|
|
250
|
+
).toEqual({ durationDays: 90, projectSpendLimit: null })
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
test('rejects invalid limits and unknown organizations', async () => {
|
|
254
|
+
const { app, client } = TestAdmin.setup()
|
|
255
|
+
const invalid = await app.request('/organizations/org_example/sponsorship', {
|
|
256
|
+
body: JSON.stringify({ enabled: true, projectSpendLimit: '-1' }),
|
|
257
|
+
headers: { 'content-type': 'application/json' },
|
|
258
|
+
method: 'PUT',
|
|
259
|
+
})
|
|
260
|
+
expect(invalid.status).toBe(400)
|
|
261
|
+
|
|
262
|
+
const missing = await client.organizations[':orgId'].sponsorship.$put({
|
|
263
|
+
json: { enabled: true, projectSpendLimit: '1000' },
|
|
264
|
+
param: { orgId: 'org_missing' },
|
|
265
|
+
})
|
|
266
|
+
expect(missing.status).toBe(404)
|
|
267
|
+
})
|
|
268
|
+
})
|
|
269
|
+
|
|
218
270
|
describe('PUT/DELETE /organizations/:orgId/billing-sources/:source', () => {
|
|
219
271
|
test('enables and disables sources idempotently', async () => {
|
|
220
272
|
const { client, db } = TestAdmin.setup()
|
|
@@ -425,7 +477,7 @@ describe('GET /organizations/:orgId/sponsorship', () => {
|
|
|
425
477
|
})
|
|
426
478
|
const body = await TestApp.json(
|
|
427
479
|
response,
|
|
428
|
-
AdminOrganizations.schema.
|
|
480
|
+
AdminOrganizations.schema.organizationSponsorship.GetResponse,
|
|
429
481
|
)
|
|
430
482
|
|
|
431
483
|
expect(body.production).toMatchObject({
|