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
|
@@ -8,7 +8,7 @@ import * as OpenApi from '../../../internal/OpenApi.js'
|
|
|
8
8
|
import * as Response from '../../../internal/Response.js'
|
|
9
9
|
import * as WebhookDestination from '../../../internal/WebhookDestination.js'
|
|
10
10
|
import * as Webhooks from '../../../internal/Webhooks.js'
|
|
11
|
-
import
|
|
11
|
+
import * as DataWebhooks from '../../data/routes/webhooks.js'
|
|
12
12
|
import type { Environment } from '../App.js'
|
|
13
13
|
|
|
14
14
|
const defaultMaxPerOwner = 100
|
|
@@ -21,11 +21,11 @@ export namespace schema {
|
|
|
21
21
|
export const Subscription = OpenApi.component(
|
|
22
22
|
z
|
|
23
23
|
.object({
|
|
24
|
-
...
|
|
25
|
-
context:
|
|
24
|
+
...DataWebhooks.schema.Subscription.shape,
|
|
25
|
+
context: DataWebhooks.schema.Subscription.shape.context.check(
|
|
26
26
|
z.meta({ examples: [{ title: 'Production transfers' }] }),
|
|
27
27
|
),
|
|
28
|
-
destination:
|
|
28
|
+
destination: DataWebhooks.schema.Subscription.shape.destination.check(
|
|
29
29
|
z.meta({ examples: [{ type: 'url', url: 'https://example.com/webhooks' }] }),
|
|
30
30
|
),
|
|
31
31
|
})
|
|
@@ -35,7 +35,7 @@ export namespace schema {
|
|
|
35
35
|
|
|
36
36
|
/** Webhook delivery data returned in collection rows. */
|
|
37
37
|
export const Delivery = OpenApi.component(
|
|
38
|
-
|
|
38
|
+
DataWebhooks.schema.Delivery,
|
|
39
39
|
'OrganizationWebhookDeliverySummary',
|
|
40
40
|
)
|
|
41
41
|
|
|
@@ -44,7 +44,7 @@ export namespace schema {
|
|
|
44
44
|
const Environment = z
|
|
45
45
|
.enum(['production', 'sandbox'])
|
|
46
46
|
.check(
|
|
47
|
-
z.describe('API-key environment whose private funding
|
|
47
|
+
z.describe('API-key environment whose private funding resources are delivered.'),
|
|
48
48
|
z.meta({ examples: ['production'] }),
|
|
49
49
|
)
|
|
50
50
|
|
|
@@ -52,24 +52,24 @@ export namespace schema {
|
|
|
52
52
|
export const Body = OpenApi.component(
|
|
53
53
|
z
|
|
54
54
|
.intersection(
|
|
55
|
-
|
|
55
|
+
DataWebhooks.schema.createWebhook.Body,
|
|
56
56
|
z.object({
|
|
57
|
-
chainId:
|
|
57
|
+
chainId: DataWebhooks.schema.Subscription.shape.chainId,
|
|
58
58
|
environment: z.optional(Environment),
|
|
59
59
|
}),
|
|
60
60
|
)
|
|
61
61
|
.check(
|
|
62
62
|
z.refine(
|
|
63
63
|
(body) =>
|
|
64
|
-
body.eventType
|
|
65
|
-
{ error: '`environment` is required for funding
|
|
64
|
+
!DataWebhooks.isFundingEventType(body.eventType) || body.environment !== undefined,
|
|
65
|
+
{ error: '`environment` is required for funding subscriptions.' },
|
|
66
66
|
),
|
|
67
67
|
z.describe('Details for creating an organization webhook subscription.'),
|
|
68
68
|
),
|
|
69
69
|
'CreateOrganizationWebhookRequest',
|
|
70
70
|
)
|
|
71
71
|
|
|
72
|
-
const secret =
|
|
72
|
+
const secret = DataWebhooks.schema.createWebhook.Response.shape.secret
|
|
73
73
|
const urlDestination = z
|
|
74
74
|
.object({
|
|
75
75
|
type: z
|
|
@@ -192,7 +192,7 @@ export namespace schema {
|
|
|
192
192
|
/** Schemas for listing an organization webhook's delivery attempts. */
|
|
193
193
|
export namespace listWebhookDeliveries {
|
|
194
194
|
export const Params = WebhookParams
|
|
195
|
-
export const Query =
|
|
195
|
+
export const Query = DataWebhooks.schema.listWebhookDeliveries.Query
|
|
196
196
|
export const Response = OpenApi.component(
|
|
197
197
|
z
|
|
198
198
|
.object({
|
|
@@ -202,10 +202,10 @@ export namespace schema {
|
|
|
202
202
|
z.describe('Webhook delivery attempts on this page.'),
|
|
203
203
|
z.meta({ examples: [[]] }),
|
|
204
204
|
),
|
|
205
|
-
meta:
|
|
205
|
+
meta: DataWebhooks.schema.listWebhookDeliveries.Response.shape.meta.check(
|
|
206
206
|
z.meta({ examples: [{ totalCount: 1, totalCountCapped: false }] }),
|
|
207
207
|
),
|
|
208
|
-
nextCursor:
|
|
208
|
+
nextCursor: DataWebhooks.schema.listWebhookDeliveries.Response.shape.nextCursor,
|
|
209
209
|
})
|
|
210
210
|
.check(z.describe("A page of an organization's webhook delivery attempts.")),
|
|
211
211
|
'OrganizationWebhookDeliveryList',
|
|
@@ -214,7 +214,7 @@ export namespace schema {
|
|
|
214
214
|
|
|
215
215
|
const DeliveryParams = z
|
|
216
216
|
.object({
|
|
217
|
-
deliveryId:
|
|
217
|
+
deliveryId: DataWebhooks.schema.retryWebhookDelivery.Params.shape.deliveryId,
|
|
218
218
|
id: WebhookParams.shape.id,
|
|
219
219
|
orgId: WebhookParams.shape.orgId,
|
|
220
220
|
})
|
|
@@ -227,7 +227,7 @@ export namespace schema {
|
|
|
227
227
|
z
|
|
228
228
|
.object({
|
|
229
229
|
...Delivery.shape,
|
|
230
|
-
envelope:
|
|
230
|
+
envelope: DataWebhooks.schema.Envelope,
|
|
231
231
|
})
|
|
232
232
|
.check(z.describe('A webhook delivery attempt with the exact JSON payload Tempo sent.')),
|
|
233
233
|
'OrganizationWebhookDelivery',
|
|
@@ -238,7 +238,7 @@ export namespace schema {
|
|
|
238
238
|
export namespace retryWebhookDelivery {
|
|
239
239
|
export const Params = DeliveryParams
|
|
240
240
|
export const Response = OpenApi.component(
|
|
241
|
-
|
|
241
|
+
DataWebhooks.schema.retryWebhookDelivery.Response,
|
|
242
242
|
'RetryOrganizationWebhookDeliveryResponse',
|
|
243
243
|
)
|
|
244
244
|
}
|
|
@@ -261,7 +261,7 @@ export namespace schema {
|
|
|
261
261
|
/** Lifecycle state editable from the console. */
|
|
262
262
|
export const UpdateBody = OpenApi.component(
|
|
263
263
|
z
|
|
264
|
-
.object({ status:
|
|
264
|
+
.object({ status: DataWebhooks.schema.Status })
|
|
265
265
|
.check(z.describe('New delivery state for a webhook subscription.')),
|
|
266
266
|
'UpdateOrganizationWebhookRequest',
|
|
267
267
|
)
|
|
@@ -344,7 +344,7 @@ export function webhooks(options: webhooks.Options = {}) {
|
|
|
344
344
|
|
|
345
345
|
const body = c.req.valid('json')
|
|
346
346
|
if (
|
|
347
|
-
body.eventType
|
|
347
|
+
DataWebhooks.isFundingEventType(body.eventType) &&
|
|
348
348
|
!options.webhook.applicationEventTypes?.includes(body.eventType)
|
|
349
349
|
)
|
|
350
350
|
return Response.error(c, {
|
|
@@ -364,17 +364,16 @@ export function webhooks(options: webhooks.Options = {}) {
|
|
|
364
364
|
const owner_ = owner(Auth.org(c).id)
|
|
365
365
|
if ((await Webhooks.countSubscriptions(db, owner_)) >= maxPerOwner)
|
|
366
366
|
throw new Webhooks.LimitExceededError(maxPerOwner)
|
|
367
|
-
const startBlockNumber =
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
: Number(await c.get('getClient')(chainId).getBlockNumber())
|
|
367
|
+
const startBlockNumber = DataWebhooks.isFundingEventType(body.eventType)
|
|
368
|
+
? undefined
|
|
369
|
+
: Number(await c.get('getClient')(chainId).getBlockNumber())
|
|
371
370
|
const subscription = await Webhooks.createSubscription(
|
|
372
371
|
db,
|
|
373
372
|
{
|
|
374
373
|
chainId,
|
|
375
374
|
...(body.context === undefined ? {} : { context: body.context }),
|
|
376
375
|
destination: body.destination,
|
|
377
|
-
...(body.eventType
|
|
376
|
+
...(DataWebhooks.isFundingEventType(body.eventType) && body.environment !== undefined
|
|
378
377
|
? { environment: body.environment }
|
|
379
378
|
: {}),
|
|
380
379
|
eventType: body.eventType,
|
|
@@ -754,7 +753,7 @@ function publicSubscription(subscription: Webhooks.Subscription) {
|
|
|
754
753
|
...(subscription.context === undefined ? {} : { context: subscription.context }),
|
|
755
754
|
createdAt: subscription.createdAt,
|
|
756
755
|
destination,
|
|
757
|
-
...(subscription.eventType
|
|
756
|
+
...(DataWebhooks.isFundingEventType(subscription.eventType) &&
|
|
758
757
|
subscription.environment !== undefined
|
|
759
758
|
? { environment: subscription.environment }
|
|
760
759
|
: {}),
|
|
@@ -18,6 +18,7 @@ import type * as Db from '../../db/Db.js'
|
|
|
18
18
|
import * as Fees from '../../internal/Fees.js'
|
|
19
19
|
import type * as Log from '../../internal/Log.js'
|
|
20
20
|
import * as Organizations from '../../db/tables/organizations.js'
|
|
21
|
+
import * as Projects from '../../db/tables/projects.js'
|
|
21
22
|
import * as SponsoredTransactions from '../../db/tables/sponsoredTransactions.js'
|
|
22
23
|
import * as StripeCustomers from '../../db/tables/stripeCustomers.js'
|
|
23
24
|
import * as core_Billing from '../management/Billing.js'
|
|
@@ -104,6 +105,13 @@ const keys = [
|
|
|
104
105
|
scopes: ['rpc-relay:sponsor'],
|
|
105
106
|
token: 'secret_unattributed',
|
|
106
107
|
},
|
|
108
|
+
{
|
|
109
|
+
id: 'key_unattributed_prod',
|
|
110
|
+
orgId: 'org_1',
|
|
111
|
+
environment: 'production',
|
|
112
|
+
scopes: ['rpc-relay:sponsor'],
|
|
113
|
+
token: 'secret_unattributed_prod',
|
|
114
|
+
},
|
|
107
115
|
] as const satisfies readonly TestApp.kvStore.Key[]
|
|
108
116
|
|
|
109
117
|
describe('behavior: Zone chain routing', () => {
|
|
@@ -525,7 +533,7 @@ describe.skipIf(runtime.mode !== 'localnet')('behavior: sponsorship', () => {
|
|
|
525
533
|
const body = await relayRequest(app, {
|
|
526
534
|
method: 'eth_signRawTransaction',
|
|
527
535
|
params: [await signSponsorable()],
|
|
528
|
-
token: '
|
|
536
|
+
token: 'secret_unattributed_prod',
|
|
529
537
|
})
|
|
530
538
|
expect(body.error).toBeUndefined()
|
|
531
539
|
expect(Transaction.deserialize(body.result as `0x76${string}`).feePayerSignature).toBeDefined()
|
|
@@ -535,6 +543,28 @@ describe.skipIf(runtime.mode !== 'localnet')('behavior: sponsorship', () => {
|
|
|
535
543
|
expect(row?.projectId).toBeNull()
|
|
536
544
|
})
|
|
537
545
|
|
|
546
|
+
test('behavior: organization-attributed keys use a validated request project', async () => {
|
|
547
|
+
const db = TestApp.database()
|
|
548
|
+
await Organizations.create(db, { id: 'org_1', name: 'One' })
|
|
549
|
+
const project = await Projects.create(db, { name: 'Privy app', orgId: 'org_1' })
|
|
550
|
+
const app = TestApp.create({
|
|
551
|
+
auth: { keys },
|
|
552
|
+
db,
|
|
553
|
+
relay: { feePayer: { account: feePayerAccount } },
|
|
554
|
+
})
|
|
555
|
+
|
|
556
|
+
const body = await relayRequest(app, {
|
|
557
|
+
method: 'eth_signRawTransaction',
|
|
558
|
+
params: [await signSponsorable()],
|
|
559
|
+
projectId: project.id,
|
|
560
|
+
token: 'secret_unattributed_prod',
|
|
561
|
+
})
|
|
562
|
+
expect(body.error).toBeUndefined()
|
|
563
|
+
|
|
564
|
+
const [row] = await SponsoredTransactions.listPending(db)
|
|
565
|
+
expect(row?.projectId).toBe(project.id)
|
|
566
|
+
})
|
|
567
|
+
|
|
538
568
|
test('behavior: batches aggregate sponsorship rejections without retaining payloads', async () => {
|
|
539
569
|
const db = TestApp.database()
|
|
540
570
|
const entries: Log.Entry[] = []
|
|
@@ -948,6 +978,18 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
948
978
|
await TestApp.verifiedSeed(db, Viem.chainId.mainnet)
|
|
949
979
|
}
|
|
950
980
|
|
|
981
|
+
/** Configures one attributed project for Tempo-funded sponsorship. */
|
|
982
|
+
async function configureSubsidy(db: ReturnType<typeof TestApp.database>) {
|
|
983
|
+
await Organizations.create(db, { id: 'org_1', name: 'Privy' })
|
|
984
|
+
await Organizations.setSponsorshipSubsidy(db, 'org_1', {
|
|
985
|
+
durationDays: 90,
|
|
986
|
+
projectSpendLimit: '100.00',
|
|
987
|
+
})
|
|
988
|
+
const project = await Projects.create(db, { name: 'Privy app', orgId: 'org_1' })
|
|
989
|
+
await activate(db)
|
|
990
|
+
return project
|
|
991
|
+
}
|
|
992
|
+
|
|
951
993
|
// Gas prices are attodollars (1e-18 USD) per gas; the signed cap in
|
|
952
994
|
// fee-token units is ceil(gas × maxFeePerGas / 1e12). The helper's default
|
|
953
995
|
// envelope (100k gas × 1e6 atto) caps at 1 microdollar — negligible.
|
|
@@ -956,6 +998,172 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
956
998
|
/** A $2 signed cap, over the `'1.00'` platform default. */
|
|
957
999
|
const overCapFees = { gas: 1_000_000n, maxFeePerGas: 2_000_000_000_000n } as const
|
|
958
1000
|
|
|
1001
|
+
test('behavior: active project promotions waive charges with active billing', async () => {
|
|
1002
|
+
const db = TestApp.database()
|
|
1003
|
+
const project = await configureSubsidy(db)
|
|
1004
|
+
const body = await relayRequest(createMainnetApp({ db }), {
|
|
1005
|
+
method: 'eth_signRawTransaction',
|
|
1006
|
+
params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
|
|
1007
|
+
projectId: project.id,
|
|
1008
|
+
token: 'secret_unattributed_prod',
|
|
1009
|
+
})
|
|
1010
|
+
expect(body.error).toBeUndefined()
|
|
1011
|
+
|
|
1012
|
+
const [row] = await SponsoredTransactions.listPending(db)
|
|
1013
|
+
expect(row).toMatchObject({
|
|
1014
|
+
billable: false,
|
|
1015
|
+
orgId: 'org_1',
|
|
1016
|
+
projectId: project.id,
|
|
1017
|
+
})
|
|
1018
|
+
const updated = await Projects.get(db, project.id)
|
|
1019
|
+
const startsAt = updated?.sponsorshipSubsidyStartsAt
|
|
1020
|
+
const endsAt = updated?.sponsorshipSubsidyEndsAt
|
|
1021
|
+
expect({ endsAt, startsAt }).toMatchObject({ endsAt: expect.any(String), startsAt: expect.any(String) }) // prettier-ignore
|
|
1022
|
+
if (!endsAt || !startsAt) throw new Error('Expected an activated promotion window.')
|
|
1023
|
+
expect(Date.parse(endsAt) - Date.parse(startsAt)).toBe(90 * 86_400_000)
|
|
1024
|
+
})
|
|
1025
|
+
|
|
1026
|
+
test('behavior: exhausted project promotions return to customer billing', async () => {
|
|
1027
|
+
const db = TestApp.database()
|
|
1028
|
+
await Organizations.create(db, { id: 'org_1', name: 'Privy' })
|
|
1029
|
+
await Organizations.setSponsorshipSubsidy(db, 'org_1', {
|
|
1030
|
+
durationDays: 90,
|
|
1031
|
+
projectSpendLimit: '0.000001',
|
|
1032
|
+
})
|
|
1033
|
+
const project = await Projects.create(db, { name: 'Privy app', orgId: 'org_1' })
|
|
1034
|
+
await activate(db)
|
|
1035
|
+
const app = createMainnetApp({ db })
|
|
1036
|
+
|
|
1037
|
+
const subsidized = await relayRequest(app, {
|
|
1038
|
+
method: 'eth_signRawTransaction',
|
|
1039
|
+
params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
|
|
1040
|
+
projectId: project.id,
|
|
1041
|
+
token: 'secret_unattributed_prod',
|
|
1042
|
+
})
|
|
1043
|
+
const billed = await relayRequest(app, {
|
|
1044
|
+
method: 'eth_signRawTransaction',
|
|
1045
|
+
params: [await signSponsorable({ chainId: Viem.chainId.mainnet, nonce: 1 })],
|
|
1046
|
+
projectId: project.id,
|
|
1047
|
+
token: 'secret_unattributed_prod',
|
|
1048
|
+
})
|
|
1049
|
+
|
|
1050
|
+
expect({ billed: billed.error, subsidized: subsidized.error }).toStrictEqual({
|
|
1051
|
+
billed: undefined,
|
|
1052
|
+
subsidized: undefined,
|
|
1053
|
+
})
|
|
1054
|
+
expect(await SponsoredTransactions.listPending(db)).toMatchObject([
|
|
1055
|
+
{ billable: false, projectId: project.id },
|
|
1056
|
+
{ billable: true, projectId: project.id },
|
|
1057
|
+
])
|
|
1058
|
+
})
|
|
1059
|
+
|
|
1060
|
+
test('behavior: uncapped project promotions waive charges with active billing', async () => {
|
|
1061
|
+
const db = TestApp.database()
|
|
1062
|
+
await Organizations.create(db, { id: 'org_1', name: 'Privy' })
|
|
1063
|
+
await Organizations.setSponsorshipSubsidy(db, 'org_1', {
|
|
1064
|
+
durationDays: 90,
|
|
1065
|
+
projectSpendLimit: null,
|
|
1066
|
+
})
|
|
1067
|
+
const project = await Projects.create(db, { name: 'Privy app', orgId: 'org_1' })
|
|
1068
|
+
await activate(db)
|
|
1069
|
+
const body = await relayRequest(createMainnetApp({ db }), {
|
|
1070
|
+
method: 'eth_signRawTransaction',
|
|
1071
|
+
params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
|
|
1072
|
+
projectId: project.id,
|
|
1073
|
+
token: 'secret_unattributed_prod',
|
|
1074
|
+
})
|
|
1075
|
+
expect(body.error).toBeUndefined()
|
|
1076
|
+
expect(await SponsoredTransactions.listPending(db)).toMatchObject([
|
|
1077
|
+
{ billable: false, projectId: project.id },
|
|
1078
|
+
])
|
|
1079
|
+
})
|
|
1080
|
+
|
|
1081
|
+
test('behavior: project promotions still require active billing', async () => {
|
|
1082
|
+
const db = TestApp.database()
|
|
1083
|
+
await Organizations.create(db, { id: 'org_1', name: 'Privy' })
|
|
1084
|
+
await Organizations.setSponsorshipSubsidy(db, 'org_1', {
|
|
1085
|
+
durationDays: 90,
|
|
1086
|
+
projectSpendLimit: null,
|
|
1087
|
+
})
|
|
1088
|
+
const project = await Projects.create(db, { name: 'Privy app', orgId: 'org_1' })
|
|
1089
|
+
await TestApp.verifiedSeed(db, Viem.chainId.mainnet)
|
|
1090
|
+
const body = await relayRequest(createMainnetApp({ db }), {
|
|
1091
|
+
method: 'eth_signRawTransaction',
|
|
1092
|
+
params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
|
|
1093
|
+
projectId: project.id,
|
|
1094
|
+
token: 'secret_unattributed_prod',
|
|
1095
|
+
})
|
|
1096
|
+
expect(body.error?.data).toStrictEqual({ code: 'billing_required' })
|
|
1097
|
+
expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
|
|
1098
|
+
expect(await Projects.get(db, project.id)).toMatchObject({
|
|
1099
|
+
sponsorshipSubsidyEndsAt: null,
|
|
1100
|
+
sponsorshipSubsidyStartsAt: null,
|
|
1101
|
+
})
|
|
1102
|
+
})
|
|
1103
|
+
|
|
1104
|
+
test('behavior: subsidized organization keys without project attribution use customer billing', async () => {
|
|
1105
|
+
const db = TestApp.database()
|
|
1106
|
+
await configureSubsidy(db)
|
|
1107
|
+
const body = await relayRequest(createMainnetApp({ db }), {
|
|
1108
|
+
method: 'eth_signRawTransaction',
|
|
1109
|
+
params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
|
|
1110
|
+
token: 'secret_unattributed_prod',
|
|
1111
|
+
})
|
|
1112
|
+
expect(body.error).toBeUndefined()
|
|
1113
|
+
expect(await SponsoredTransactions.listPending(db)).toMatchObject([
|
|
1114
|
+
{ billable: true, orgId: 'org_1', projectId: null },
|
|
1115
|
+
])
|
|
1116
|
+
})
|
|
1117
|
+
|
|
1118
|
+
test('behavior: expired project promotions return to customer billing', async () => {
|
|
1119
|
+
const db = TestApp.database()
|
|
1120
|
+
const project = await configureSubsidy(db)
|
|
1121
|
+
await Projects.activateSponsorship(db, {
|
|
1122
|
+
at: new Date(Date.now() - 91 * 86_400_000).toISOString(),
|
|
1123
|
+
endsAt: new Date(Date.now() - 86_400_000).toISOString(),
|
|
1124
|
+
id: project.id,
|
|
1125
|
+
orgId: 'org_1',
|
|
1126
|
+
spendLimit: '100000000',
|
|
1127
|
+
})
|
|
1128
|
+
const body = await relayRequest(createMainnetApp({ db }), {
|
|
1129
|
+
method: 'eth_signRawTransaction',
|
|
1130
|
+
params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
|
|
1131
|
+
projectId: project.id,
|
|
1132
|
+
token: 'secret_unattributed_prod',
|
|
1133
|
+
})
|
|
1134
|
+
expect(body.error).toBeUndefined()
|
|
1135
|
+
expect(await SponsoredTransactions.listPending(db)).toMatchObject([
|
|
1136
|
+
{ billable: true, projectId: project.id },
|
|
1137
|
+
])
|
|
1138
|
+
})
|
|
1139
|
+
|
|
1140
|
+
test('behavior: rejects request attribution from project-scoped keys', async () => {
|
|
1141
|
+
const body = await relayRequest(createMainnetApp(), {
|
|
1142
|
+
method: 'eth_signRawTransaction',
|
|
1143
|
+
params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
|
|
1144
|
+
projectId: 'prj_1',
|
|
1145
|
+
token: 'secret_sponsor_prod',
|
|
1146
|
+
})
|
|
1147
|
+
expect(body.error).toStrictEqual({
|
|
1148
|
+
code: -32602,
|
|
1149
|
+
data: { code: 'project_id_invalid' },
|
|
1150
|
+
message: 'Project attribution rejected.',
|
|
1151
|
+
})
|
|
1152
|
+
})
|
|
1153
|
+
|
|
1154
|
+
test('behavior: rejects request attribution outside the key organization', async () => {
|
|
1155
|
+
const db = TestApp.database()
|
|
1156
|
+
await Organizations.create(db, { id: 'org_2', name: 'Two' })
|
|
1157
|
+
const project = await Projects.create(db, { name: 'Other app', orgId: 'org_2' })
|
|
1158
|
+
const body = await relayRequest(createMainnetApp({ db }), {
|
|
1159
|
+
method: 'eth_signRawTransaction',
|
|
1160
|
+
params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
|
|
1161
|
+
projectId: project.id,
|
|
1162
|
+
token: 'secret_unattributed_prod',
|
|
1163
|
+
})
|
|
1164
|
+
expect(body.error?.data).toStrictEqual({ code: 'project_id_invalid' })
|
|
1165
|
+
})
|
|
1166
|
+
|
|
959
1167
|
test('behavior: refuses mainnet sponsorship without a billing source', async () => {
|
|
960
1168
|
const entries: Log.Entry[] = []
|
|
961
1169
|
const body = await relayRequest(
|
|
@@ -1584,6 +1792,7 @@ async function relayRequest(app: ReturnType<typeof TestApp.create>, options: rel
|
|
|
1584
1792
|
body: JSON.stringify({ id: 1, jsonrpc: '2.0', method: options.method, params: options.params }), // prettier-ignore
|
|
1585
1793
|
headers: {
|
|
1586
1794
|
'content-type': 'application/json',
|
|
1795
|
+
...(options.projectId ? { 'tempo-project-id': options.projectId } : {}),
|
|
1587
1796
|
...(options.token ? { 'tempo-api-key': options.token } : {}),
|
|
1588
1797
|
},
|
|
1589
1798
|
method: 'POST',
|
|
@@ -1604,6 +1813,8 @@ declare namespace relayRequest {
|
|
|
1604
1813
|
mount?: 'relay' | 'sponsor' | undefined
|
|
1605
1814
|
/** JSON-RPC parameters. */
|
|
1606
1815
|
params: readonly unknown[]
|
|
1816
|
+
/** Request-level project attribution. */
|
|
1817
|
+
projectId?: string | undefined
|
|
1607
1818
|
/** API-key credential. */
|
|
1608
1819
|
token?: string | undefined
|
|
1609
1820
|
}
|