tapimo 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -16
- package/dist/ApiKey.d.ts +4 -1
- package/dist/ApiKey.d.ts.map +1 -1
- package/dist/ApiKey.js +6 -2
- package/dist/ApiKey.js.map +1 -1
- package/dist/ApiKeys.d.ts +98 -3
- package/dist/ApiKeys.d.ts.map +1 -1
- package/dist/ApiKeys.js +150 -1
- package/dist/ApiKeys.js.map +1 -1
- package/dist/App.d.ts +7917 -2315
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +141 -329
- package/dist/App.js.map +1 -1
- package/dist/Scope.d.ts +20 -4
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +23 -4
- package/dist/Scope.js.map +1 -1
- package/dist/Webhooks.d.ts +2 -2
- package/dist/Webhooks.d.ts.map +1 -1
- package/dist/Webhooks.js +2 -2
- package/dist/Webhooks.js.map +1 -1
- package/dist/admin/App.d.ts +203 -120
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +111 -6
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +67 -0
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/scopes.d.ts +12 -1
- package/dist/admin/apps/scopes.d.ts.map +1 -1
- package/dist/admin/apps/scopes.js +3 -0
- package/dist/admin/apps/scopes.js.map +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +116 -116
- package/dist/admin/apps/verified-tokens.js +1 -1
- package/dist/admin/apps/verified-tokens.js.map +1 -1
- package/dist/admin/ui.generated.d.ts +1 -1
- package/dist/admin/ui.generated.js +13 -13
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/analytics/Analytics.d.ts +151 -0
- package/dist/analytics/Analytics.d.ts.map +1 -0
- package/dist/analytics/Analytics.js +212 -0
- package/dist/analytics/Analytics.js.map +1 -0
- package/dist/analytics/tables/requestEvents.d.ts +215 -0
- package/dist/analytics/tables/requestEvents.d.ts.map +1 -0
- package/dist/analytics/tables/requestEvents.js +264 -0
- package/dist/analytics/tables/requestEvents.js.map +1 -0
- package/dist/apps/data/App.d.ts +19576 -0
- package/dist/apps/data/App.d.ts.map +1 -0
- package/dist/apps/data/App.js +272 -0
- package/dist/apps/data/App.js.map +1 -0
- package/dist/apps/data/index.d.ts +3 -0
- package/dist/apps/data/index.d.ts.map +1 -0
- package/dist/apps/data/index.js +3 -0
- package/dist/apps/data/index.js.map +1 -0
- package/dist/apps/{activities.d.ts → data/routes/activities.d.ts} +32 -32
- package/dist/apps/{activities.d.ts.map → data/routes/activities.d.ts.map} +1 -1
- package/dist/apps/{activities.js → data/routes/activities.js} +13 -13
- package/dist/apps/data/routes/activities.js.map +1 -0
- package/dist/apps/{addresses.d.ts → data/routes/addresses.d.ts} +22 -22
- package/dist/apps/{addresses.d.ts.map → data/routes/addresses.d.ts.map} +1 -1
- package/dist/apps/{addresses.js → data/routes/addresses.js} +5 -5
- package/dist/apps/data/routes/addresses.js.map +1 -0
- package/dist/apps/{balances.d.ts → data/routes/balances.d.ts} +4 -4
- package/dist/apps/data/routes/balances.d.ts.map +1 -0
- package/dist/apps/{balances.js → data/routes/balances.js} +42 -11
- package/dist/apps/data/routes/balances.js.map +1 -0
- package/dist/apps/{blocks.d.ts → data/routes/blocks.d.ts} +47 -47
- package/dist/apps/data/routes/blocks.d.ts.map +1 -0
- package/dist/apps/{blocks.js → data/routes/blocks.js} +13 -13
- package/dist/apps/data/routes/blocks.js.map +1 -0
- package/dist/apps/{coingecko.d.ts → data/routes/coingecko.d.ts} +8 -8
- package/dist/apps/data/routes/coingecko.d.ts.map +1 -0
- package/dist/apps/{coingecko.js → data/routes/coingecko.js} +13 -13
- package/dist/apps/data/routes/coingecko.js.map +1 -0
- package/dist/apps/{exchanges.d.ts → data/routes/exchanges.d.ts} +108 -108
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -0
- package/dist/apps/{exchanges.js → data/routes/exchanges.js} +19 -19
- package/dist/apps/data/routes/exchanges.js.map +1 -0
- package/dist/apps/{fee-amm.d.ts → data/routes/fee-amm.d.ts} +39 -39
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -0
- package/dist/apps/{fee-amm.js → data/routes/fee-amm.js} +17 -17
- package/dist/apps/data/routes/fee-amm.js.map +1 -0
- package/dist/apps/data/routes/funding.d.ts +765 -0
- package/dist/apps/data/routes/funding.d.ts.map +1 -0
- package/dist/apps/data/routes/funding.js +383 -0
- package/dist/apps/data/routes/funding.js.map +1 -0
- package/dist/apps/{indexer.d.ts → data/routes/indexer.d.ts} +4 -4
- package/dist/apps/data/routes/indexer.d.ts.map +1 -0
- package/dist/apps/{indexer.js → data/routes/indexer.js} +13 -9
- package/dist/apps/data/routes/indexer.js.map +1 -0
- package/dist/apps/{receipts.d.ts → data/routes/receipts.d.ts} +49 -49
- package/dist/apps/data/routes/receipts.d.ts.map +1 -0
- package/dist/apps/{receipts.js → data/routes/receipts.js} +14 -20
- package/dist/apps/data/routes/receipts.js.map +1 -0
- package/dist/apps/{rpc.d.ts → data/routes/rpc.d.ts} +33 -40
- package/dist/apps/data/routes/rpc.d.ts.map +1 -0
- package/dist/apps/{rpc.js → data/routes/rpc.js} +35 -7
- package/dist/apps/data/routes/rpc.js.map +1 -0
- package/dist/apps/{tokenlist.d.ts → data/routes/tokenlist.d.ts} +40 -40
- package/dist/apps/data/routes/tokenlist.d.ts.map +1 -0
- package/dist/apps/{tokenlist.js → data/routes/tokenlist.js} +8 -8
- package/dist/apps/data/routes/tokenlist.js.map +1 -0
- package/dist/apps/{tokens.d.ts → data/routes/tokens.d.ts} +468 -468
- package/dist/apps/data/routes/tokens.d.ts.map +1 -0
- package/dist/apps/{tokens.js → data/routes/tokens.js} +19 -19
- package/dist/apps/data/routes/tokens.js.map +1 -0
- package/dist/apps/{transactions.d.ts → data/routes/transactions.d.ts} +304 -304
- package/dist/apps/data/routes/transactions.d.ts.map +1 -0
- package/dist/apps/{transactions.js → data/routes/transactions.js} +13 -13
- package/dist/apps/data/routes/transactions.js.map +1 -0
- package/dist/apps/{transfers.d.ts → data/routes/transfers.d.ts} +62 -62
- package/dist/apps/data/routes/transfers.d.ts.map +1 -0
- package/dist/apps/{transfers.js → data/routes/transfers.js} +13 -13
- package/dist/apps/data/routes/transfers.js.map +1 -0
- package/dist/apps/{verified-tokens.d.ts → data/routes/verified-tokens.d.ts} +6 -6
- package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -0
- package/dist/apps/{verified-tokens.js → data/routes/verified-tokens.js} +9 -9
- package/dist/apps/data/routes/verified-tokens.js.map +1 -0
- package/dist/apps/{webhooks.d.ts → data/routes/webhooks.d.ts} +17 -17
- package/dist/apps/{webhooks.d.ts.map → data/routes/webhooks.d.ts.map} +1 -1
- package/dist/apps/{webhooks.js → data/routes/webhooks.js} +38 -34
- package/dist/apps/data/routes/webhooks.js.map +1 -0
- package/dist/apps/docs/App.d.ts +29 -0
- package/dist/apps/docs/App.d.ts.map +1 -0
- package/dist/apps/docs/App.js +54 -0
- package/dist/apps/docs/App.js.map +1 -0
- package/dist/{internal/OpenApi.fonts.d.ts → apps/docs/fonts.d.ts} +1 -1
- package/dist/apps/docs/fonts.d.ts.map +1 -0
- package/dist/{internal/OpenApi.fonts.js → apps/docs/fonts.js} +1 -1
- package/dist/apps/docs/fonts.js.map +1 -0
- package/dist/apps/docs/index.d.ts +2 -0
- package/dist/apps/docs/index.d.ts.map +1 -0
- package/dist/apps/docs/index.js +2 -0
- package/dist/apps/docs/index.js.map +1 -0
- package/dist/{internal/OpenApi.logo.d.ts → apps/docs/logo.d.ts} +1 -1
- package/dist/apps/docs/logo.d.ts.map +1 -0
- package/dist/{internal/OpenApi.logo.js → apps/docs/logo.js} +1 -1
- package/dist/apps/docs/logo.js.map +1 -0
- package/dist/apps/docs/reference.d.ts +21 -0
- package/dist/apps/docs/reference.d.ts.map +1 -0
- package/dist/apps/docs/reference.js +112 -0
- package/dist/apps/docs/reference.js.map +1 -0
- package/dist/apps/index.d.ts +5 -0
- package/dist/apps/index.d.ts.map +1 -0
- package/dist/apps/index.js +5 -0
- package/dist/apps/index.js.map +1 -0
- package/dist/apps/mcp.d.ts +76 -0
- package/dist/apps/mcp.d.ts.map +1 -0
- package/dist/apps/mcp.js +188 -0
- package/dist/apps/mcp.js.map +1 -0
- package/dist/apps/metadata.d.ts +7 -0
- package/dist/apps/metadata.d.ts.map +1 -0
- package/dist/apps/metadata.js +15 -0
- package/dist/apps/metadata.js.map +1 -0
- package/dist/apps/platform/App.d.ts +5262 -0
- package/dist/apps/platform/App.d.ts.map +1 -0
- package/dist/apps/platform/App.js +84 -0
- package/dist/apps/platform/App.js.map +1 -0
- package/dist/apps/platform/Billing.d.ts +279 -0
- package/dist/apps/platform/Billing.d.ts.map +1 -0
- package/dist/apps/platform/Billing.js +477 -0
- package/dist/apps/platform/Billing.js.map +1 -0
- package/dist/apps/platform/index.d.ts +3 -0
- package/dist/apps/platform/index.d.ts.map +1 -0
- package/dist/apps/platform/index.js +3 -0
- package/dist/apps/platform/index.js.map +1 -0
- package/dist/apps/platform/routes/api-keys.d.ts +973 -0
- package/dist/apps/platform/routes/api-keys.d.ts.map +1 -0
- package/dist/apps/platform/routes/api-keys.js +430 -0
- package/dist/apps/platform/routes/api-keys.js.map +1 -0
- package/dist/apps/platform/routes/billing.d.ts +1520 -0
- package/dist/apps/platform/routes/billing.d.ts.map +1 -0
- package/dist/apps/platform/routes/billing.js +795 -0
- package/dist/apps/platform/routes/billing.js.map +1 -0
- package/dist/apps/platform/routes/invitations.d.ts +851 -0
- package/dist/apps/platform/routes/invitations.d.ts.map +1 -0
- package/dist/apps/platform/routes/invitations.js +471 -0
- package/dist/apps/platform/routes/invitations.js.map +1 -0
- package/dist/apps/platform/routes/me.d.ts +95 -0
- package/dist/apps/platform/routes/me.d.ts.map +1 -0
- package/dist/apps/platform/routes/me.js +81 -0
- package/dist/apps/platform/routes/me.js.map +1 -0
- package/dist/apps/platform/routes/members.d.ts +554 -0
- package/dist/apps/platform/routes/members.d.ts.map +1 -0
- package/dist/apps/platform/routes/members.js +251 -0
- package/dist/apps/platform/routes/members.js.map +1 -0
- package/dist/apps/platform/routes/orgs.d.ts +596 -0
- package/dist/apps/platform/routes/orgs.d.ts.map +1 -0
- package/dist/apps/platform/routes/orgs.js +276 -0
- package/dist/apps/platform/routes/orgs.js.map +1 -0
- package/dist/apps/platform/routes/projects.d.ts +740 -0
- package/dist/apps/platform/routes/projects.d.ts.map +1 -0
- package/dist/apps/platform/routes/projects.js +286 -0
- package/dist/apps/platform/routes/projects.js.map +1 -0
- package/dist/apps/platform/routes/scopes.d.ts +107 -0
- package/dist/apps/platform/routes/scopes.d.ts.map +1 -0
- package/dist/apps/platform/routes/scopes.js +66 -0
- package/dist/apps/platform/routes/scopes.js.map +1 -0
- package/dist/apps/platform/routes/usage.d.ts +588 -0
- package/dist/apps/platform/routes/usage.d.ts.map +1 -0
- package/dist/apps/platform/routes/usage.js +391 -0
- package/dist/apps/platform/routes/usage.js.map +1 -0
- package/dist/apps/relay/App.d.ts +44 -0
- package/dist/apps/relay/App.d.ts.map +1 -0
- package/dist/apps/relay/App.js +211 -0
- package/dist/apps/relay/App.js.map +1 -0
- package/dist/apps/relay/Sponsorships.d.ts +107 -0
- package/dist/apps/relay/Sponsorships.d.ts.map +1 -0
- package/dist/apps/relay/Sponsorships.js +194 -0
- package/dist/apps/relay/Sponsorships.js.map +1 -0
- package/dist/apps/relay/index.d.ts +3 -0
- package/dist/apps/relay/index.d.ts.map +1 -0
- package/dist/apps/relay/index.js +3 -0
- package/dist/apps/relay/index.js.map +1 -0
- package/dist/cli/Cli.d.ts +9 -2
- package/dist/cli/Cli.d.ts.map +1 -1
- package/dist/cli/Cli.js +12 -4
- package/dist/cli/Cli.js.map +1 -1
- package/dist/cli/commands/admin.d.ts +5 -1
- package/dist/cli/commands/admin.d.ts.map +1 -1
- package/dist/cli/commands/admin.js +82 -3
- package/dist/cli/commands/admin.js.map +1 -1
- package/dist/db/Db.d.ts +17 -0
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +254 -0
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +159 -0
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +187 -2
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/billingSettings.d.ts +55 -0
- package/dist/db/tables/billingSettings.d.ts.map +1 -0
- package/dist/db/tables/billingSettings.js +70 -0
- package/dist/db/tables/billingSettings.js.map +1 -0
- package/dist/db/tables/invitations.d.ts +84 -0
- package/dist/db/tables/invitations.d.ts.map +1 -0
- package/dist/db/tables/invitations.js +165 -0
- package/dist/db/tables/invitations.js.map +1 -0
- package/dist/db/tables/memberships.d.ts +108 -0
- package/dist/db/tables/memberships.d.ts.map +1 -0
- package/dist/db/tables/memberships.js +153 -0
- package/dist/db/tables/memberships.js.map +1 -0
- package/dist/db/tables/organizations.d.ts +48 -0
- package/dist/db/tables/organizations.d.ts.map +1 -1
- package/dist/db/tables/organizations.js +97 -2
- package/dist/db/tables/organizations.js.map +1 -1
- package/dist/db/tables/projects.d.ts +65 -0
- package/dist/db/tables/projects.d.ts.map +1 -0
- package/dist/db/tables/projects.js +75 -0
- package/dist/db/tables/projects.js.map +1 -0
- package/dist/db/tables/requestUsage.d.ts +121 -0
- package/dist/db/tables/requestUsage.d.ts.map +1 -0
- package/dist/db/tables/requestUsage.js +150 -0
- package/dist/db/tables/requestUsage.js.map +1 -0
- package/dist/db/tables/sponsoredTransactions.d.ts +239 -0
- package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -0
- package/dist/db/tables/sponsoredTransactions.js +314 -0
- package/dist/db/tables/sponsoredTransactions.js.map +1 -0
- package/dist/db/tables/stripeCustomers.d.ts +81 -0
- package/dist/db/tables/stripeCustomers.d.ts.map +1 -0
- package/dist/db/tables/stripeCustomers.js +120 -0
- package/dist/db/tables/stripeCustomers.js.map +1 -0
- package/dist/db/tables/users.d.ts +48 -0
- package/dist/db/tables/users.d.ts.map +1 -0
- package/dist/db/tables/users.js +65 -0
- package/dist/db/tables/users.js.map +1 -0
- package/dist/handlers/internal/executionError.d.ts.map +1 -1
- package/dist/handlers/internal/executionError.js +2 -0
- package/dist/handlers/internal/executionError.js.map +1 -1
- package/dist/handlers/internal/multisig.d.ts +2 -6
- package/dist/handlers/internal/multisig.d.ts.map +1 -1
- package/dist/handlers/internal/multisig.js +11 -36
- package/dist/handlers/internal/multisig.js.map +1 -1
- package/dist/handlers/internal/sponsorship.d.ts +35 -2
- package/dist/handlers/internal/sponsorship.d.ts.map +1 -1
- package/dist/handlers/internal/sponsorship.js +53 -14
- package/dist/handlers/internal/sponsorship.js.map +1 -1
- package/dist/handlers/internal/utils.d.ts +10 -3
- package/dist/handlers/internal/utils.d.ts.map +1 -1
- package/dist/handlers/internal/utils.js +14 -6
- package/dist/handlers/internal/utils.js.map +1 -1
- package/dist/handlers/relay.d.ts +6 -2
- package/dist/handlers/relay.d.ts.map +1 -1
- package/dist/handlers/relay.js +16 -2
- package/dist/handlers/relay.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/Auth.d.ts +222 -6
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +625 -74
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/Cache.d.ts.map +1 -1
- package/dist/internal/Cache.js +4 -1
- package/dist/internal/Cache.js.map +1 -1
- package/dist/internal/EdgeCache.d.ts +10 -0
- package/dist/internal/EdgeCache.d.ts.map +1 -1
- package/dist/internal/EdgeCache.js +39 -8
- package/dist/internal/EdgeCache.js.map +1 -1
- package/dist/internal/Fees.d.ts +27 -0
- package/dist/internal/Fees.d.ts.map +1 -0
- package/dist/internal/Fees.js +48 -0
- package/dist/internal/Fees.js.map +1 -0
- package/dist/internal/FundingRoutes.d.ts +183 -0
- package/dist/internal/FundingRoutes.d.ts.map +1 -0
- package/dist/internal/FundingRoutes.js +490 -0
- package/dist/internal/FundingRoutes.js.map +1 -0
- package/dist/internal/Id.d.ts +15 -0
- package/dist/internal/Id.d.ts.map +1 -0
- package/dist/internal/Id.js +22 -0
- package/dist/internal/Id.js.map +1 -0
- package/dist/internal/Log.d.ts +9 -3
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +7 -0
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +10 -20
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +8 -58
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/RateLimit.d.ts +25 -0
- package/dist/internal/RateLimit.d.ts.map +1 -1
- package/dist/internal/RateLimit.js +51 -0
- package/dist/internal/RateLimit.js.map +1 -1
- package/dist/internal/Response.d.ts +1 -1
- package/dist/internal/Response.d.ts.map +1 -1
- package/dist/internal/Schema.d.ts +8 -0
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +7 -0
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/Store.d.ts +7 -1
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +16 -2
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/Viem.d.ts +84 -0
- package/dist/internal/Viem.d.ts.map +1 -1
- package/dist/internal/Webhooks.d.ts +1 -1
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +3 -3
- package/dist/internal/Webhooks.js.map +1 -1
- package/package.json +33 -6
- package/src/ApiKey.ts +10 -2
- package/src/ApiKeys.test.ts +155 -1
- package/src/ApiKeys.ts +203 -1
- package/src/App.test.ts +64 -75741
- package/src/App.ts +218 -420
- package/src/Client.test-d.ts +657 -15
- package/src/Scope.ts +26 -4
- package/src/Webhooks.ts +2 -2
- package/src/admin/apps/api-keys.test.ts +51 -0
- package/src/admin/apps/api-keys.ts +84 -0
- package/src/admin/apps/scopes.test.ts +11 -1
- package/src/admin/apps/scopes.ts +3 -0
- package/src/admin/apps/verified-tokens.ts +1 -1
- package/src/admin/ui/src/components/Page.tsx +2 -3
- package/src/admin/ui/src/routes/__root.tsx +2 -2
- package/src/admin/ui/src/routes/api-keys.tsx +2 -2
- package/src/admin/ui.generated.ts +13 -13
- package/src/analytics/Analytics.test.ts +527 -0
- package/src/analytics/Analytics.ts +318 -0
- package/src/analytics/tables/requestEvents.ts +523 -0
- package/src/apps/composition.test.ts +66 -0
- package/src/apps/data/App.test.ts +72 -0
- package/src/apps/data/App.ts +330 -0
- package/src/apps/data/index.ts +2 -0
- package/src/apps/{activities.test.ts → data/routes/activities.test.ts} +3 -3
- package/src/apps/{activities.ts → data/routes/activities.ts} +15 -15
- package/src/apps/{addresses.ts → data/routes/addresses.ts} +6 -6
- package/src/apps/{balances.test.ts → data/routes/balances.test.ts} +2 -2
- package/src/apps/{balances.ts → data/routes/balances.ts} +46 -12
- package/src/apps/{blocks.test.ts → data/routes/blocks.test.ts} +3 -3
- package/src/apps/{blocks.ts → data/routes/blocks.ts} +14 -14
- package/src/apps/{coingecko.test.ts → data/routes/coingecko.test.ts} +2 -2
- package/src/apps/{coingecko.ts → data/routes/coingecko.ts} +14 -14
- package/src/apps/{exchanges.test.ts → data/routes/exchanges.test.ts} +1 -1
- package/src/apps/{exchanges.ts → data/routes/exchanges.ts} +20 -20
- package/src/apps/{fee-amm.test.ts → data/routes/fee-amm.test.ts} +3 -3
- package/src/apps/{fee-amm.ts → data/routes/fee-amm.ts} +18 -18
- package/src/apps/data/routes/funding.test.ts +214 -0
- package/src/apps/data/routes/funding.ts +584 -0
- package/src/apps/{indexer.test.ts → data/routes/indexer.test.ts} +26 -5
- package/src/apps/{indexer.ts → data/routes/indexer.ts} +13 -10
- package/src/apps/{receipts.test.ts → data/routes/receipts.test.ts} +3 -3
- package/src/apps/{receipts.ts → data/routes/receipts.ts} +15 -22
- package/src/apps/{rpc.test.ts → data/routes/rpc.test.ts} +122 -7
- package/src/apps/{rpc.ts → data/routes/rpc.ts} +38 -8
- package/src/apps/{tokenlist.test.ts → data/routes/tokenlist.test.ts} +3 -3
- package/src/apps/{tokenlist.ts → data/routes/tokenlist.ts} +9 -9
- package/src/apps/{tokens.test.ts → data/routes/tokens.test.ts} +2 -2
- package/src/apps/{tokens.ts → data/routes/tokens.ts} +20 -20
- package/src/apps/{transactions.test.ts → data/routes/transactions.test.ts} +3 -3
- package/src/apps/{transactions.ts → data/routes/transactions.ts} +15 -15
- package/src/apps/{transfers.test.ts → data/routes/transfers.test.ts} +2 -2
- package/src/apps/{transfers.ts → data/routes/transfers.ts} +15 -15
- package/src/apps/{verified-tokens.test.ts → data/routes/verified-tokens.test.ts} +3 -3
- package/src/apps/{verified-tokens.ts → data/routes/verified-tokens.ts} +10 -10
- package/src/apps/{webhooks.test.ts → data/routes/webhooks.test.ts} +7 -7
- package/src/apps/{webhooks.ts → data/routes/webhooks.ts} +50 -43
- package/src/apps/docs/App.ts +65 -0
- package/src/apps/docs/index.ts +1 -0
- package/src/apps/docs/reference.ts +132 -0
- package/src/apps/index.ts +4 -0
- package/src/apps/mcp.test.ts +206 -0
- package/src/apps/mcp.ts +250 -0
- package/src/apps/metadata.ts +23 -0
- package/src/apps/platform/App.ts +169 -0
- package/src/apps/platform/Billing.test.ts +530 -0
- package/src/apps/platform/Billing.ts +682 -0
- package/src/apps/platform/index.ts +2 -0
- package/src/apps/platform/routes/api-keys.test.ts +493 -0
- package/src/apps/platform/routes/api-keys.ts +543 -0
- package/src/apps/platform/routes/billing.test.ts +1100 -0
- package/src/apps/platform/routes/billing.ts +966 -0
- package/src/apps/platform/routes/invitations.test.ts +409 -0
- package/src/apps/platform/routes/invitations.ts +587 -0
- package/src/apps/platform/routes/me.test.ts +351 -0
- package/src/apps/platform/routes/me.ts +106 -0
- package/src/apps/platform/routes/members.test.ts +195 -0
- package/src/apps/platform/routes/members.ts +313 -0
- package/src/apps/platform/routes/orgs.test.ts +313 -0
- package/src/apps/platform/routes/orgs.ts +365 -0
- package/src/apps/platform/routes/projects.test.ts +181 -0
- package/src/apps/platform/routes/projects.ts +367 -0
- package/src/apps/platform/routes/scopes.test.ts +29 -0
- package/src/apps/platform/routes/scopes.ts +85 -0
- package/src/apps/platform/routes/usage.test.ts +422 -0
- package/src/apps/platform/routes/usage.ts +527 -0
- package/src/apps/relay/App.test.ts +933 -0
- package/src/apps/relay/App.ts +236 -0
- package/src/apps/relay/Sponsorships.test.ts +375 -0
- package/src/apps/relay/Sponsorships.ts +306 -0
- package/src/apps/relay/index.ts +2 -0
- package/src/cli/Cli.test.ts +25 -2
- package/src/cli/Cli.ts +18 -3
- package/src/cli/commands/admin.test.ts +83 -0
- package/src/cli/commands/admin.ts +91 -3
- package/src/db/Db.ts +296 -0
- package/src/db/Schema.ts +241 -2
- package/src/db/tables/billingSettings.test.ts +87 -0
- package/src/db/tables/billingSettings.ts +108 -0
- package/src/db/tables/invitations.ts +198 -0
- package/src/db/tables/memberships.ts +208 -0
- package/src/db/tables/organizations.test.ts +38 -2
- package/src/db/tables/organizations.ts +117 -2
- package/src/db/tables/projects.ts +107 -0
- package/src/db/tables/requestUsage.ts +231 -0
- package/src/db/tables/sponsoredTransactions.test.ts +325 -0
- package/src/db/tables/sponsoredTransactions.ts +464 -0
- package/src/db/tables/stripeCustomers.test.ts +109 -0
- package/src/db/tables/stripeCustomers.ts +162 -0
- package/src/db/tables/users.ts +85 -0
- package/src/handlers/internal/executionError.ts +2 -0
- package/src/handlers/internal/multisig.test.ts +84 -10
- package/src/handlers/internal/multisig.ts +15 -50
- package/src/handlers/internal/sponsorship.ts +106 -20
- package/src/handlers/internal/utils.ts +19 -7
- package/src/handlers/{internal/relay.localnet.test.ts → relay.test.ts} +2 -2
- package/src/handlers/relay.ts +23 -5
- package/src/index.ts +1 -0
- package/src/internal/Auth.test.ts +491 -25
- package/src/internal/Auth.ts +839 -84
- package/src/internal/Cache.ts +5 -1
- package/src/internal/Cursor.test.ts +3 -2
- package/src/internal/EdgeCache.test.ts +27 -4
- package/src/internal/EdgeCache.ts +47 -9
- package/src/internal/Fees.test.ts +32 -0
- package/src/internal/Fees.ts +51 -0
- package/src/internal/FundingRoutes.ts +583 -0
- package/src/internal/Id.test.ts +17 -0
- package/src/internal/Id.ts +24 -0
- package/src/internal/Log.test.ts +2 -1
- package/src/internal/Log.ts +16 -3
- package/src/internal/MetricSink.ts +1 -1
- package/src/internal/OpenApi.ts +12 -60
- package/src/internal/RateLimit.test.ts +84 -0
- package/src/internal/RateLimit.ts +70 -0
- package/src/internal/Response.ts +1 -1
- package/src/internal/Schema.ts +8 -0
- package/src/internal/Store.test.ts +52 -0
- package/src/internal/Store.ts +24 -5
- package/src/internal/Tidx.local.test.ts +1 -1
- package/src/internal/VerifiedTokens.test.ts +1 -1
- package/src/internal/WebhookDestination.test.ts +1 -1
- package/src/internal/Webhooks.test.ts +7 -7
- package/src/internal/Webhooks.ts +4 -4
- package/dist/apps/activities.js.map +0 -1
- package/dist/apps/addresses.js.map +0 -1
- package/dist/apps/balances.d.ts.map +0 -1
- package/dist/apps/balances.js.map +0 -1
- package/dist/apps/blocks.d.ts.map +0 -1
- package/dist/apps/blocks.js.map +0 -1
- package/dist/apps/coingecko.d.ts.map +0 -1
- package/dist/apps/coingecko.js.map +0 -1
- package/dist/apps/exchanges.d.ts.map +0 -1
- package/dist/apps/exchanges.js.map +0 -1
- package/dist/apps/fee-amm.d.ts.map +0 -1
- package/dist/apps/fee-amm.js.map +0 -1
- package/dist/apps/indexer.d.ts.map +0 -1
- package/dist/apps/indexer.js.map +0 -1
- package/dist/apps/receipts.d.ts.map +0 -1
- package/dist/apps/receipts.js.map +0 -1
- package/dist/apps/rpc.d.ts.map +0 -1
- package/dist/apps/rpc.js.map +0 -1
- package/dist/apps/tokenlist.d.ts.map +0 -1
- package/dist/apps/tokenlist.js.map +0 -1
- package/dist/apps/tokens.d.ts.map +0 -1
- package/dist/apps/tokens.js.map +0 -1
- package/dist/apps/transactions.d.ts.map +0 -1
- package/dist/apps/transactions.js.map +0 -1
- package/dist/apps/transfers.d.ts.map +0 -1
- package/dist/apps/transfers.js.map +0 -1
- package/dist/apps/verified-tokens.d.ts.map +0 -1
- package/dist/apps/verified-tokens.js.map +0 -1
- package/dist/apps/webhooks.js.map +0 -1
- package/dist/internal/OpenApi.fonts.d.ts.map +0 -1
- package/dist/internal/OpenApi.fonts.js.map +0 -1
- package/dist/internal/OpenApi.logo.d.ts.map +0 -1
- package/dist/internal/OpenApi.logo.js.map +0 -1
- package/src/handlers/internal/multisig.localnet.test.ts +0 -146
- /package/src/{internal/OpenApi.fonts.ts → apps/docs/fonts.ts} +0 -0
- /package/src/{internal/OpenApi.logo.ts → apps/docs/logo.ts} +0 -0
package/src/db/Db.ts
CHANGED
|
@@ -5,11 +5,20 @@ import {
|
|
|
5
5
|
type Dialect,
|
|
6
6
|
Kysely,
|
|
7
7
|
PostgresDialect,
|
|
8
|
+
type RawBuilder,
|
|
8
9
|
sql,
|
|
9
10
|
} from 'kysely'
|
|
10
11
|
import * as pg from 'pg'
|
|
11
12
|
|
|
13
|
+
import type * as BillingSettings from './tables/billingSettings.js'
|
|
14
|
+
import type * as Invitations from './tables/invitations.js'
|
|
15
|
+
import type * as Memberships from './tables/memberships.js'
|
|
12
16
|
import type * as Organizations from './tables/organizations.js'
|
|
17
|
+
import type * as Projects from './tables/projects.js'
|
|
18
|
+
import type * as RequestUsage from './tables/requestUsage.js'
|
|
19
|
+
import type * as SponsoredTransactions from './tables/sponsoredTransactions.js'
|
|
20
|
+
import type * as StripeCustomers from './tables/stripeCustomers.js'
|
|
21
|
+
import type * as Users from './tables/users.js'
|
|
13
22
|
import type * as VerifiedTokens from './tables/verifiedTokens.js'
|
|
14
23
|
import type * as WebhookDeliveries from './tables/webhookDeliveries.js'
|
|
15
24
|
import type * as WebhookSubscriptions from './tables/webhookSubscriptions.js'
|
|
@@ -26,7 +35,16 @@ export type Database = {
|
|
|
26
35
|
/** SQL as applied; null on rows written before the column existed. */
|
|
27
36
|
sql: string | null
|
|
28
37
|
}
|
|
38
|
+
billing_settings: BillingSettings.Table
|
|
39
|
+
invitations: Invitations.Table
|
|
40
|
+
memberships: Memberships.Table
|
|
29
41
|
organizations: Organizations.Table
|
|
42
|
+
projects: Projects.Table
|
|
43
|
+
request_usage_buckets: RequestUsage.BucketTable
|
|
44
|
+
request_usage_meter_events: RequestUsage.MeterEventTable
|
|
45
|
+
sponsored_transactions: SponsoredTransactions.Table
|
|
46
|
+
stripe_customers: StripeCustomers.Table
|
|
47
|
+
users: Users.Table
|
|
30
48
|
verified_token_lists: VerifiedTokens.ListTable
|
|
31
49
|
verified_tokens: VerifiedTokens.Table
|
|
32
50
|
webhook_deliveries: WebhookDeliveries.Table
|
|
@@ -235,8 +253,286 @@ export const migrations: readonly Migration[] = [
|
|
|
235
253
|
.on('webhookDeliveries')
|
|
236
254
|
.column('expiresAt'),
|
|
237
255
|
},
|
|
256
|
+
{
|
|
257
|
+
name: '0012_users',
|
|
258
|
+
up: (db) =>
|
|
259
|
+
db.schema
|
|
260
|
+
.createTable('users')
|
|
261
|
+
.ifNotExists()
|
|
262
|
+
.addColumn('id', 'text', (c) => c.primaryKey())
|
|
263
|
+
.addColumn('address', 'text', (c) => c.notNull().unique())
|
|
264
|
+
.addColumn('email', 'text')
|
|
265
|
+
.addColumn('createdAt', 'text', (c) => c.notNull())
|
|
266
|
+
.addColumn('updatedAt', 'text', (c) => c.notNull()),
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
name: '0013_organizations_user_id',
|
|
270
|
+
// The schema builder cannot express `ADD COLUMN IF NOT EXISTS`; raw SQL
|
|
271
|
+
// (snake_case: the CamelCase plugin does not map raw statements).
|
|
272
|
+
up: (db) => raw(db, sql`ALTER TABLE organizations ADD COLUMN IF NOT EXISTS user_id text`),
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
name: '0014_projects',
|
|
276
|
+
up: (db) =>
|
|
277
|
+
db.schema
|
|
278
|
+
.createTable('projects')
|
|
279
|
+
.ifNotExists()
|
|
280
|
+
.addColumn('id', 'text', (c) => c.primaryKey())
|
|
281
|
+
.addColumn('orgId', 'text', (c) => c.notNull())
|
|
282
|
+
.addColumn('name', 'text', (c) => c.notNull())
|
|
283
|
+
.addColumn('createdAt', 'text', (c) => c.notNull())
|
|
284
|
+
.addColumn('updatedAt', 'text', (c) => c.notNull()),
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
name: '0015_projects_org_index',
|
|
288
|
+
up: (db) =>
|
|
289
|
+
db.schema.createIndex('projects_org_idx').ifNotExists().on('projects').column('orgId'),
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
name: '0016_memberships',
|
|
293
|
+
up: (db) =>
|
|
294
|
+
db.schema
|
|
295
|
+
.createTable('memberships')
|
|
296
|
+
.ifNotExists()
|
|
297
|
+
.addColumn('orgId', 'text', (c) => c.notNull())
|
|
298
|
+
.addColumn('userId', 'text', (c) => c.notNull())
|
|
299
|
+
.addColumn('role', 'text', (c) => c.notNull())
|
|
300
|
+
.addColumn('createdAt', 'text', (c) => c.notNull())
|
|
301
|
+
.addColumn('updatedAt', 'text', (c) => c.notNull())
|
|
302
|
+
.addPrimaryKeyConstraint('memberships_pk', ['orgId', 'userId']),
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
name: '0017_memberships_user_index',
|
|
306
|
+
up: (db) =>
|
|
307
|
+
db.schema.createIndex('memberships_user_idx').ifNotExists().on('memberships').column('userId'), // prettier-ignore
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
name: '0018_memberships_owner_backfill',
|
|
311
|
+
// Raw SQL (snake_case: the CamelCase plugin does not map raw statements).
|
|
312
|
+
up: (db) =>
|
|
313
|
+
raw(
|
|
314
|
+
db,
|
|
315
|
+
sql`INSERT INTO memberships (org_id, user_id, role, created_at, updated_at) SELECT id, user_id, 'owner', created_at, updated_at FROM organizations WHERE user_id IS NOT NULL ON CONFLICT DO NOTHING`,
|
|
316
|
+
),
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
name: '0019_invitations',
|
|
320
|
+
up: (db) =>
|
|
321
|
+
db.schema
|
|
322
|
+
.createTable('invitations')
|
|
323
|
+
.ifNotExists()
|
|
324
|
+
.addColumn('id', 'text', (c) => c.primaryKey())
|
|
325
|
+
.addColumn('orgId', 'text', (c) => c.notNull())
|
|
326
|
+
.addColumn('email', 'text', (c) => c.notNull())
|
|
327
|
+
.addColumn('role', 'text', (c) => c.notNull())
|
|
328
|
+
.addColumn('invitedBy', 'text', (c) => c.notNull())
|
|
329
|
+
.addColumn('createdAt', 'text', (c) => c.notNull())
|
|
330
|
+
.addColumn('expiresAt', 'text', (c) => c.notNull())
|
|
331
|
+
.addColumn('acceptedAt', 'text')
|
|
332
|
+
.addColumn('revokedAt', 'text'),
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
name: '0020_invitations_org_index',
|
|
336
|
+
up: (db) =>
|
|
337
|
+
db.schema.createIndex('invitations_org_idx').ifNotExists().on('invitations').column('orgId'),
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
name: '0021_invitations_email_index',
|
|
341
|
+
up: (db) =>
|
|
342
|
+
db.schema.createIndex('invitations_email_idx').ifNotExists().on('invitations').column('email'), // prettier-ignore
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
name: '0022_users_address_nullable',
|
|
346
|
+
// Raw SQL; a no-op when the column is already nullable.
|
|
347
|
+
up: (db) => raw(db, sql`ALTER TABLE users ALTER COLUMN address DROP NOT NULL`),
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
name: '0023_invitations_pending_unique',
|
|
351
|
+
// Raw SQL: a partial unique index (snake_case; the CamelCase plugin does
|
|
352
|
+
// not map raw statements). At most one live (unaccepted, unrevoked)
|
|
353
|
+
// invitation per (org, email); a re-invite upserts the existing row.
|
|
354
|
+
up: (db) =>
|
|
355
|
+
raw(
|
|
356
|
+
db,
|
|
357
|
+
sql`CREATE UNIQUE INDEX IF NOT EXISTS invitations_pending_unique ON invitations (org_id, email) WHERE accepted_at IS NULL AND revoked_at IS NULL`,
|
|
358
|
+
),
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
name: '0024_sponsored_transactions',
|
|
362
|
+
up: (db) =>
|
|
363
|
+
db.schema
|
|
364
|
+
.createTable('sponsoredTransactions')
|
|
365
|
+
.ifNotExists()
|
|
366
|
+
.addColumn('id', 'text', (c) => c.primaryKey())
|
|
367
|
+
.addColumn('orgId', 'text', (c) => c.notNull())
|
|
368
|
+
.addColumn('projectId', 'text', (c) => c.notNull())
|
|
369
|
+
.addColumn('apiKeyId', 'text', (c) => c.notNull())
|
|
370
|
+
.addColumn('environment', 'text', (c) => c.notNull())
|
|
371
|
+
.addColumn('chainId', 'integer', (c) => c.notNull())
|
|
372
|
+
.addColumn('transactionHash', 'text')
|
|
373
|
+
.addColumn('signPayload', 'text', (c) => c.notNull())
|
|
374
|
+
.addColumn('transaction', 'text', (c) => c.notNull())
|
|
375
|
+
.addColumn('status', 'text', (c) => c.notNull())
|
|
376
|
+
.addColumn('feeAmount', 'text')
|
|
377
|
+
.addColumn('feeToken', 'text')
|
|
378
|
+
.addColumn('billable', 'boolean', (c) => c.notNull())
|
|
379
|
+
.addColumn('createdAt', 'text', (c) => c.notNull())
|
|
380
|
+
.addColumn('finalizedAt', 'text')
|
|
381
|
+
.addUniqueConstraint('sponsored_transactions_sign_payload_key', ['signPayload']),
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
name: '0025_sponsored_transactions_status_index',
|
|
385
|
+
up: (db) =>
|
|
386
|
+
db.schema.createIndex('sponsored_transactions_status_idx').ifNotExists().on('sponsoredTransactions').columns(['status', 'createdAt']), // prettier-ignore
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
name: '0026_sponsored_transactions_org_index',
|
|
390
|
+
up: (db) =>
|
|
391
|
+
db.schema.createIndex('sponsored_transactions_org_idx').ifNotExists().on('sponsoredTransactions').columns(['orgId', 'createdAt']), // prettier-ignore
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
name: '0027_stripe_customers',
|
|
395
|
+
up: (db) =>
|
|
396
|
+
db.schema
|
|
397
|
+
.createTable('stripeCustomers')
|
|
398
|
+
.ifNotExists()
|
|
399
|
+
.addColumn('orgId', 'text', (c) => c.primaryKey())
|
|
400
|
+
.addColumn('stripeCustomerId', 'text', (c) => c.notNull())
|
|
401
|
+
.addColumn('status', 'text', (c) => c.notNull())
|
|
402
|
+
.addColumn('createdAt', 'text', (c) => c.notNull())
|
|
403
|
+
.addColumn('updatedAt', 'text', (c) => c.notNull())
|
|
404
|
+
.addUniqueConstraint('stripe_customers_stripe_customer_id_key', ['stripeCustomerId']),
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
name: '0028_billing_settings',
|
|
408
|
+
up: (db) =>
|
|
409
|
+
db.schema
|
|
410
|
+
.createTable('billingSettings')
|
|
411
|
+
.ifNotExists()
|
|
412
|
+
.addColumn('orgId', 'text', (c) => c.primaryKey())
|
|
413
|
+
.addColumn('spendLimit', 'text')
|
|
414
|
+
.addColumn('txFeeLimit', 'text')
|
|
415
|
+
.addColumn('currency', 'text', (c) => c.notNull().defaultTo('usd'))
|
|
416
|
+
.addColumn('period', 'text', (c) => c.notNull().defaultTo('month'))
|
|
417
|
+
.addColumn('createdAt', 'text', (c) => c.notNull())
|
|
418
|
+
.addColumn('updatedAt', 'text', (c) => c.notNull()),
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
name: '0029_sponsored_transactions_fee_max',
|
|
422
|
+
up: (db) => raw(db, sql`ALTER TABLE sponsored_transactions ADD COLUMN IF NOT EXISTS fee_max text`), // prettier-ignore
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
name: '0030_sponsored_transactions_meter_reported_at',
|
|
426
|
+
up: (db) => raw(db, sql`ALTER TABLE sponsored_transactions ADD COLUMN IF NOT EXISTS meter_reported_at text`), // prettier-ignore
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
name: '0031_sponsored_transactions_billing_index',
|
|
430
|
+
// Partial: the spend-limit aggregate only ever scans billable rows.
|
|
431
|
+
up: (db) => raw(db, sql`CREATE INDEX IF NOT EXISTS sponsored_transactions_billing_idx ON sponsored_transactions (org_id, status, created_at) WHERE billable`), // prettier-ignore
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
name: '0032_sponsored_transactions_fee_amount_rescale',
|
|
435
|
+
// Rows finalized before fee scaling shipped stored attodollars (1e12× the
|
|
436
|
+
// token unit); `div` is exact ceiling division (`Fees.fromGas`). The
|
|
437
|
+
// threshold keeps re-runs idempotent: real scaled fees sit far below
|
|
438
|
+
// 1e9 ($1,000); attodollar values far above.
|
|
439
|
+
up: (db) => raw(db, sql`UPDATE sponsored_transactions SET fee_amount = div(fee_amount::numeric + 999999999999, 1000000000000)::text WHERE status = 'finalized' AND fee_amount IS NOT NULL AND fee_amount::numeric >= 1000000000`), // prettier-ignore
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
name: '0033_sponsored_transactions_unreported_index',
|
|
443
|
+
// Partial queue index: the per-minute reporter scans only unreported
|
|
444
|
+
// finalized billable rows, which marking immediately evicts.
|
|
445
|
+
up: (db) => raw(db, sql`CREATE INDEX IF NOT EXISTS sponsored_transactions_unreported_idx ON sponsored_transactions (finalized_at, id) WHERE billable AND status = 'finalized' AND meter_reported_at IS NULL`), // prettier-ignore
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
name: '0034_sponsored_transactions_currency',
|
|
449
|
+
up: (db) => raw(db, sql`ALTER TABLE sponsored_transactions ADD COLUMN IF NOT EXISTS currency text`), // prettier-ignore
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
name: '0035_sponsored_transactions_currency_backfill',
|
|
453
|
+
// Every fee payer to date sponsors in pathUSD, so rows predating the
|
|
454
|
+
// currency snapshot are USD. The predicate keeps re-runs idempotent.
|
|
455
|
+
up: (db) => raw(db, sql`UPDATE sponsored_transactions SET currency = 'usd' WHERE currency IS NULL`), // prettier-ignore
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
name: '0036_stripe_customers_environment',
|
|
459
|
+
up: (db) => raw(db, sql`ALTER TABLE stripe_customers ADD COLUMN IF NOT EXISTS environment text NOT NULL DEFAULT 'production'`), // prettier-ignore
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
name: '0037_stripe_customers_org_environment_key',
|
|
463
|
+
// Enables a second (sandbox) row per org; targeted by the upsert conflict
|
|
464
|
+
// arbiter so it survives the org pkey drop in the follow-up release.
|
|
465
|
+
up: (db) => raw(db, sql`CREATE UNIQUE INDEX IF NOT EXISTS stripe_customers_org_environment_key ON stripe_customers (org_id, environment)`), // prettier-ignore
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
name: '0038_billing_settings_environment',
|
|
469
|
+
up: (db) => raw(db, sql`ALTER TABLE billing_settings ADD COLUMN IF NOT EXISTS environment text NOT NULL DEFAULT 'production'`), // prettier-ignore
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
name: '0039_billing_settings_org_environment_key',
|
|
473
|
+
up: (db) => raw(db, sql`CREATE UNIQUE INDEX IF NOT EXISTS billing_settings_org_environment_key ON billing_settings (org_id, environment)`), // prettier-ignore
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
name: '0040_stripe_customers_drop_org_pkey',
|
|
477
|
+
// Release B: the `(org_id, environment)` unique index now guards uniqueness,
|
|
478
|
+
// so dropping the org pkey unblocks a second (sandbox) row per org.
|
|
479
|
+
up: (db) => raw(db, sql`ALTER TABLE stripe_customers DROP CONSTRAINT IF EXISTS stripe_customers_pkey`), // prettier-ignore
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
name: '0041_billing_settings_drop_org_pkey',
|
|
483
|
+
up: (db) => raw(db, sql`ALTER TABLE billing_settings DROP CONSTRAINT IF EXISTS billing_settings_pkey`), // prettier-ignore
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
name: '0042_request_usage_buckets',
|
|
487
|
+
up: (db) =>
|
|
488
|
+
db.schema
|
|
489
|
+
.createTable('requestUsageBuckets')
|
|
490
|
+
.ifNotExists()
|
|
491
|
+
.addColumn('orgId', 'text', (c) => c.notNull())
|
|
492
|
+
.addColumn('environment', 'text', (c) => c.notNull())
|
|
493
|
+
.addColumn('bucketStart', 'text', (c) => c.notNull())
|
|
494
|
+
.addColumn('reportedCount', 'bigint', (c) => c.notNull().defaultTo(0))
|
|
495
|
+
.addColumn('updatedAt', 'text', (c) => c.notNull())
|
|
496
|
+
.addPrimaryKeyConstraint('request_usage_buckets_pkey', ['orgId', 'environment', 'bucketStart']), // prettier-ignore
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
name: '0043_request_usage_meter_events',
|
|
500
|
+
up: (db) =>
|
|
501
|
+
db.schema
|
|
502
|
+
.createTable('requestUsageMeterEvents')
|
|
503
|
+
.ifNotExists()
|
|
504
|
+
.addColumn('identifier', 'text', (c) => c.primaryKey())
|
|
505
|
+
.addColumn('orgId', 'text', (c) => c.notNull())
|
|
506
|
+
.addColumn('environment', 'text', (c) => c.notNull())
|
|
507
|
+
.addColumn('bucketStart', 'text', (c) => c.notNull())
|
|
508
|
+
.addColumn('sequence', 'integer', (c) => c.notNull())
|
|
509
|
+
.addColumn('deltaCount', 'bigint', (c) => c.notNull())
|
|
510
|
+
.addColumn('stripeCustomerId', 'text', (c) => c.notNull())
|
|
511
|
+
.addColumn('state', 'text', (c) => c.notNull())
|
|
512
|
+
.addColumn('reason', 'text')
|
|
513
|
+
.addColumn('error', 'text')
|
|
514
|
+
.addColumn('firstAttemptedAt', 'text', (c) => c.notNull())
|
|
515
|
+
.addColumn('reportedAt', 'text')
|
|
516
|
+
.addUniqueConstraint('request_usage_meter_events_bucket_sequence_key', ['orgId', 'environment', 'bucketStart', 'sequence']), // prettier-ignore
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
name: '0044_request_usage_meter_events_pending_index',
|
|
520
|
+
// Partial: the reporter scans only unreported (pending) rows.
|
|
521
|
+
up: (db) => raw(db, sql`CREATE INDEX IF NOT EXISTS request_usage_meter_events_pending_idx ON request_usage_meter_events (first_attempted_at, identifier) WHERE state = 'pending'`), // prettier-ignore
|
|
522
|
+
},
|
|
238
523
|
]
|
|
239
524
|
|
|
525
|
+
/**
|
|
526
|
+
* Adapts a raw statement to the migration contract (argument-less
|
|
527
|
+
* `compile`/`execute`) for DDL the schema builders cannot express.
|
|
528
|
+
*/
|
|
529
|
+
function raw(db: Kysely<Database>, statement: RawBuilder<unknown>) {
|
|
530
|
+
return {
|
|
531
|
+
compile: () => statement.compile(db),
|
|
532
|
+
execute: () => statement.execute(db),
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
240
536
|
/**
|
|
241
537
|
* Builds a {@link Db} for any Kysely {@link Dialect}. All backends share
|
|
242
538
|
* migrations, repositories, and the required {@link CamelCasePlugin} mapping.
|
package/src/db/Schema.ts
CHANGED
|
@@ -8,6 +8,74 @@ import type * as Webhooks from '../internal/Webhooks.js'
|
|
|
8
8
|
// Domain-owned unions and jsonb values stay typed by their owning module via
|
|
9
9
|
// `z.custom` (type-only imports) so the two cannot drift.
|
|
10
10
|
|
|
11
|
+
/** An organization's billing configuration; source-agnostic (limits apply to any billing source). */
|
|
12
|
+
export const BillingSettings = z.object({
|
|
13
|
+
createdAt: z.string().check(z.describe('When the settings row was created (ISO 8601).')),
|
|
14
|
+
currency: z
|
|
15
|
+
.enum(['usd'])
|
|
16
|
+
.check(z.describe('ISO 4217 currency (lowercase) both limits are denominated in.')),
|
|
17
|
+
environment: z
|
|
18
|
+
.enum(['production', 'sandbox'])
|
|
19
|
+
.check(z.describe('Environment these settings apply to; `production` or `sandbox`.')),
|
|
20
|
+
orgId: z.string().check(z.describe('Organization id (`org_…`) these settings belong to.')),
|
|
21
|
+
period: z
|
|
22
|
+
.enum(['month'])
|
|
23
|
+
.check(z.describe('Window the spend limit applies over; `month` is a UTC calendar month.')),
|
|
24
|
+
spendLimit: z
|
|
25
|
+
.nullable(z.string())
|
|
26
|
+
.check(z.describe('Spend limit per period as a decimal string in `currency` units, or null for no limit.')), // prettier-ignore
|
|
27
|
+
txFeeLimit: z
|
|
28
|
+
.nullable(z.string())
|
|
29
|
+
.check(z.describe('Per-transaction fee cap as a decimal string in `currency` units, or null for the platform default.')), // prettier-ignore
|
|
30
|
+
updatedAt: z.string().check(z.describe('When the settings last changed (ISO 8601).')),
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
/** Columns of the `billing_settings` table. */
|
|
34
|
+
export type BillingSettings = z.output<typeof BillingSettings>
|
|
35
|
+
|
|
36
|
+
/** A pending, expiring offer of organization membership. */
|
|
37
|
+
export const Invitation = z.object({
|
|
38
|
+
acceptedAt: z
|
|
39
|
+
.nullable(z.string())
|
|
40
|
+
.check(z.describe('When the invitation was accepted (ISO 8601), or null while pending.')),
|
|
41
|
+
createdAt: z.string().check(z.describe('When the invitation was created (ISO 8601).')),
|
|
42
|
+
email: z
|
|
43
|
+
.string()
|
|
44
|
+
.check(z.describe('Invitee email (stored lowercase); matched against verified emails.')),
|
|
45
|
+
expiresAt: z.string().check(z.describe('When the invitation expires (ISO 8601).')),
|
|
46
|
+
id: z
|
|
47
|
+
.string()
|
|
48
|
+
.check(
|
|
49
|
+
z.describe('Opaque invitation id (`inv_…`).'),
|
|
50
|
+
z.meta({ examples: ['inv_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
|
|
51
|
+
),
|
|
52
|
+
invitedBy: z.string().check(z.describe('User id (`usr_…`) that created the invitation.')),
|
|
53
|
+
orgId: z.string().check(z.describe('Organization id (`org_…`) the invitation joins.')),
|
|
54
|
+
revokedAt: z
|
|
55
|
+
.nullable(z.string())
|
|
56
|
+
.check(z.describe('When the invitation was revoked (ISO 8601), or null.')),
|
|
57
|
+
role: z
|
|
58
|
+
.enum(['admin', 'member', 'owner'])
|
|
59
|
+
.check(z.describe('Role granted when the invitation is accepted.')),
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
/** Columns of the `invitations` table. */
|
|
63
|
+
export type Invitation = z.output<typeof Invitation>
|
|
64
|
+
|
|
65
|
+
/** A user's role within an organization. */
|
|
66
|
+
export const Membership = z.object({
|
|
67
|
+
createdAt: z.string().check(z.describe('When the membership was created (ISO 8601).')),
|
|
68
|
+
orgId: z.string().check(z.describe('Organization id (`org_…`).')),
|
|
69
|
+
role: z
|
|
70
|
+
.enum(['admin', 'member', 'owner'])
|
|
71
|
+
.check(z.describe("The member's role within the organization.")),
|
|
72
|
+
updatedAt: z.string().check(z.describe('When the membership was last updated (ISO 8601).')),
|
|
73
|
+
userId: z.string().check(z.describe('Member user id (`usr_…`).')),
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
/** Columns of the `memberships` table. */
|
|
77
|
+
export type Membership = z.output<typeof Membership>
|
|
78
|
+
|
|
11
79
|
/** An organization, the top-level tenant that owns API keys. */
|
|
12
80
|
export const Organization = z.object({
|
|
13
81
|
createdAt: z.string().check(z.describe('When the organization was created (ISO 8601).')),
|
|
@@ -24,11 +92,182 @@ export const Organization = z.object({
|
|
|
24
92
|
.string()
|
|
25
93
|
.check(z.describe('Human-readable organization name.'), z.meta({ examples: ['Acme, Inc.'] })),
|
|
26
94
|
updatedAt: z.string().check(z.describe('When the organization was last updated (ISO 8601).')),
|
|
95
|
+
userId: z
|
|
96
|
+
.nullable(z.string())
|
|
97
|
+
.check(
|
|
98
|
+
z.describe('Owning user id (`usr_…`), or null for organizations created by the super admin.'),
|
|
99
|
+
),
|
|
27
100
|
})
|
|
28
101
|
|
|
29
102
|
/** Columns of the `organizations` table. */
|
|
30
103
|
export type Organization = z.output<typeof Organization>
|
|
31
104
|
|
|
105
|
+
/** A project: an app or integration within an organization. */
|
|
106
|
+
export const Project = z.object({
|
|
107
|
+
createdAt: z.string().check(z.describe('When the project was created (ISO 8601).')),
|
|
108
|
+
id: z
|
|
109
|
+
.string()
|
|
110
|
+
.check(
|
|
111
|
+
z.describe('Opaque project id (`prj_…`).'),
|
|
112
|
+
z.meta({ examples: ['prj_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
|
|
113
|
+
),
|
|
114
|
+
name: z
|
|
115
|
+
.string()
|
|
116
|
+
.check(z.describe('Human-readable project name.'), z.meta({ examples: ['Checkout'] })),
|
|
117
|
+
orgId: z.string().check(z.describe('Owning organization id (`org_…`).')),
|
|
118
|
+
updatedAt: z.string().check(z.describe('When the project was last updated (ISO 8601).')),
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
/** Columns of the `projects` table. */
|
|
122
|
+
export type Project = z.output<typeof Project>
|
|
123
|
+
|
|
124
|
+
/** A transaction sponsored by the managed fee payer — the billable unit of fee payer spend. */
|
|
125
|
+
export const SponsoredTransaction = z.object({
|
|
126
|
+
apiKeyId: z.string().check(z.describe('API key id (`key_…`) that requested sponsorship.')),
|
|
127
|
+
billable: z
|
|
128
|
+
.boolean()
|
|
129
|
+
.check(z.describe('Whether the sponsorship accrues billable spend; false for sandbox.')),
|
|
130
|
+
chainId: z.number().check(z.describe('Chain the sponsored transaction targets.')),
|
|
131
|
+
createdAt: z.string().check(z.describe('When the sponsorship was recorded (ISO 8601).')),
|
|
132
|
+
currency: z
|
|
133
|
+
.nullable(z.string())
|
|
134
|
+
.check(z.describe('Lowercase fee currency the sponsorship settles in (`usd`), or null when the fee token is unverified.')), // prettier-ignore
|
|
135
|
+
environment: z
|
|
136
|
+
.enum(['production', 'sandbox'])
|
|
137
|
+
.check(z.describe('Key environment the sponsorship was requested under.')),
|
|
138
|
+
feeAmount: z
|
|
139
|
+
.nullable(z.string())
|
|
140
|
+
.check(z.describe('Actual fee paid in fee-token base units, or null until finalized.')),
|
|
141
|
+
feeMax: z
|
|
142
|
+
.nullable(z.string())
|
|
143
|
+
.check(z.describe('Signed fee cap (`gas × maxFeePerGas`) in base units; pending rows count it against spend limits.')), // prettier-ignore
|
|
144
|
+
feeToken: z
|
|
145
|
+
.nullable(z.string())
|
|
146
|
+
.check(z.describe('Fee token address, or null when the chain default applied.')),
|
|
147
|
+
finalizedAt: z
|
|
148
|
+
.nullable(z.string())
|
|
149
|
+
.check(z.describe('When the sponsorship reached a terminal status (ISO 8601), or null.')),
|
|
150
|
+
id: z
|
|
151
|
+
.string()
|
|
152
|
+
.check(
|
|
153
|
+
z.describe('Opaque sponsored-transaction id (`stx_…`).'),
|
|
154
|
+
z.meta({ examples: ['stx_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
|
|
155
|
+
),
|
|
156
|
+
meterReportedAt: z
|
|
157
|
+
.nullable(z.string())
|
|
158
|
+
.check(z.describe('When the row was reported to the billing meter (ISO 8601), or null; exactly-once marker.')), // prettier-ignore
|
|
159
|
+
orgId: z.string().check(z.describe('Organization id (`org_…`) the spend attributes to.')),
|
|
160
|
+
projectId: z.string().check(z.describe('Project id (`prj_…`) the spend attributes to.')),
|
|
161
|
+
signPayload: z
|
|
162
|
+
.string()
|
|
163
|
+
.check(z.describe('Fee-payer sign payload — a stable identity for the sponsored envelope.')),
|
|
164
|
+
status: z
|
|
165
|
+
.enum(['failed', 'finalized', 'pending'])
|
|
166
|
+
.check(z.describe('Pending until a receipt finalizes it or the pending TTL fails it.')),
|
|
167
|
+
transaction: z
|
|
168
|
+
.string()
|
|
169
|
+
.check(z.describe('Serialized sponsored transaction, kept for durable observability.')),
|
|
170
|
+
transactionHash: z
|
|
171
|
+
.nullable(z.string())
|
|
172
|
+
.check(z.describe('Transaction hash, or null for fill intents until reconciled.')),
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
/** Columns of the `sponsored_transactions` table. */
|
|
176
|
+
export type SponsoredTransaction = z.output<typeof SponsoredTransaction>
|
|
177
|
+
|
|
178
|
+
/** A per-hour request-count watermark: the running total already reported to the meter. */
|
|
179
|
+
export const RequestUsageBucket = z.object({
|
|
180
|
+
bucketStart: z.string().check(z.describe('UTC hour start this bucket covers (ISO 8601).')),
|
|
181
|
+
environment: z
|
|
182
|
+
.enum(['production', 'sandbox'])
|
|
183
|
+
.check(z.describe('Environment the requests were served under; `production` or `sandbox`.')),
|
|
184
|
+
orgId: z.string().check(z.describe('Organization id (`org_…`) the requests attribute to.')),
|
|
185
|
+
reportedCount: z
|
|
186
|
+
.number()
|
|
187
|
+
.check(z.describe('Cumulative request count already reported to the meter for this bucket.')),
|
|
188
|
+
updatedAt: z.string().check(z.describe('When the watermark last advanced (ISO 8601).')),
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
/** Columns of the `request_usage_buckets` table. */
|
|
192
|
+
export type RequestUsageBucket = z.output<typeof RequestUsageBucket>
|
|
193
|
+
|
|
194
|
+
/** One request-count meter event: a frozen additive delta with its exactly-once state. */
|
|
195
|
+
export const RequestUsageMeterEvent = z.object({
|
|
196
|
+
bucketStart: z.string().check(z.describe('UTC hour start this event bills for (ISO 8601).')),
|
|
197
|
+
deltaCount: z
|
|
198
|
+
.number()
|
|
199
|
+
.check(z.describe('Frozen request count this event bills; a positive additive delta.')),
|
|
200
|
+
environment: z
|
|
201
|
+
.enum(['production', 'sandbox'])
|
|
202
|
+
.check(z.describe('Environment the requests were served under; `production` or `sandbox`.')),
|
|
203
|
+
error: z.nullable(z.string()).check(z.describe('Last failure detail while `pending`, or null.')),
|
|
204
|
+
firstAttemptedAt: z.string().check(z.describe('When this event was first claimed (ISO 8601).')),
|
|
205
|
+
identifier: z
|
|
206
|
+
.string()
|
|
207
|
+
.check(z.describe('Deterministic id; also the Stripe meter-event identifier and idempotency key.')), // prettier-ignore
|
|
208
|
+
orgId: z.string().check(z.describe('Organization id (`org_…`) the requests attribute to.')),
|
|
209
|
+
reason: z
|
|
210
|
+
.nullable(z.string())
|
|
211
|
+
.check(z.describe('Skip reason when `state` is `skipped` (`no_customer` | `customer_canceled`), or null.')), // prettier-ignore
|
|
212
|
+
reportedAt: z
|
|
213
|
+
.nullable(z.string())
|
|
214
|
+
.check(z.describe('When Stripe acknowledged the event (ISO 8601), or null.')),
|
|
215
|
+
sequence: z
|
|
216
|
+
.number()
|
|
217
|
+
.check(z.describe('Delta sequence within the bucket; `0` is the initial seal, `1..n` later deltas.')), // prettier-ignore
|
|
218
|
+
state: z
|
|
219
|
+
.enum(['pending', 'reported', 'skipped'])
|
|
220
|
+
.check(z.describe('Exactly-once state: `pending` retries, `reported` is done, `skipped` is audited.')), // prettier-ignore
|
|
221
|
+
stripeCustomerId: z.string().check(z.describe('Stripe customer id the event bills against.')),
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
/** Columns of the `request_usage_meter_events` table. */
|
|
225
|
+
export type RequestUsageMeterEvent = z.output<typeof RequestUsageMeterEvent>
|
|
226
|
+
|
|
227
|
+
/** An organization's Stripe billing source: the customer link and derived status. */
|
|
228
|
+
export const StripeCustomer = z.object({
|
|
229
|
+
createdAt: z.string().check(z.describe('When the Stripe source was connected (ISO 8601).')),
|
|
230
|
+
environment: z
|
|
231
|
+
.enum(['production', 'sandbox'])
|
|
232
|
+
.check(z.describe('Environment this Stripe source backs; `production` (live) or `sandbox` (test).')), // prettier-ignore
|
|
233
|
+
orgId: z.string().check(z.describe('Organization id (`org_…`) this Stripe source belongs to.')),
|
|
234
|
+
status: z
|
|
235
|
+
.enum(['active', 'canceled', 'none', 'past_due'])
|
|
236
|
+
.check(z.describe('Billing status derived from Stripe state; gates production sponsorship.')),
|
|
237
|
+
stripeCustomerId: z
|
|
238
|
+
.string()
|
|
239
|
+
.check(z.describe('Stripe customer id backing this source; never deleted by us.')),
|
|
240
|
+
updatedAt: z.string().check(z.describe('When the billing status last changed (ISO 8601).')),
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
/** Columns of the `stripe_customers` table. */
|
|
244
|
+
export type StripeCustomer = z.output<typeof StripeCustomer>
|
|
245
|
+
|
|
246
|
+
/** A developer identity. */
|
|
247
|
+
export const User = z.object({
|
|
248
|
+
address: z
|
|
249
|
+
.nullable(z.string())
|
|
250
|
+
.check(
|
|
251
|
+
z.describe(
|
|
252
|
+
'Wallet address that signs in as this user (stored lowercase), or null for non-wallet identities.',
|
|
253
|
+
),
|
|
254
|
+
),
|
|
255
|
+
createdAt: z.string().check(z.describe('When the user was created (ISO 8601).')),
|
|
256
|
+
email: z
|
|
257
|
+
.nullable(z.string())
|
|
258
|
+
.check(z.describe('Verified email from the wallet identity token, or null.')),
|
|
259
|
+
id: z
|
|
260
|
+
.string()
|
|
261
|
+
.check(
|
|
262
|
+
z.describe('Opaque user id (`usr_…`).'),
|
|
263
|
+
z.meta({ examples: ['usr_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
|
|
264
|
+
),
|
|
265
|
+
updatedAt: z.string().check(z.describe('When the user was last updated (ISO 8601).')),
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
/** Columns of the `users` table. */
|
|
269
|
+
export type User = z.output<typeof User>
|
|
270
|
+
|
|
32
271
|
/**
|
|
33
272
|
* A verified token: one row per curated token, ordered by `position` (list
|
|
34
273
|
* order is canonical and surfaced to clients). Addresses are stored lowercase;
|
|
@@ -96,7 +335,7 @@ export const WebhookSubscription = z.object({
|
|
|
96
335
|
.string()
|
|
97
336
|
.check(
|
|
98
337
|
z.describe('Subscription id (`wh_…`, lexically time-ordered).'),
|
|
99
|
-
z.meta({ examples: ['
|
|
338
|
+
z.meta({ examples: ['wh_001718668800000_2ZPE2gvateYEQ0dQslgvkhjx'] }),
|
|
100
339
|
),
|
|
101
340
|
lastDeliveryAt: z
|
|
102
341
|
.nullable(z.string())
|
|
@@ -145,7 +384,7 @@ export const WebhookDelivery = z.object({
|
|
|
145
384
|
.string()
|
|
146
385
|
.check(
|
|
147
386
|
z.describe('Delivery id (`whd_…`, lexically time-ordered).'),
|
|
148
|
-
z.meta({ examples: ['
|
|
387
|
+
z.meta({ examples: ['whd_001718668800000_C1yJkk7CuML98HFthEDk9PsY'] }),
|
|
149
388
|
),
|
|
150
389
|
requestUrl: z.string().check(z.describe('Subscriber callback URL the attempt targeted.')),
|
|
151
390
|
responseMs: z
|