tapimo 0.0.2 → 0.2.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 +38 -16
- package/dist/ApiKey.d.ts +14 -11
- package/dist/ApiKey.d.ts.map +1 -1
- package/dist/ApiKey.js +11 -12
- package/dist/ApiKey.js.map +1 -1
- package/dist/ApiKeys.d.ts +207 -0
- package/dist/ApiKeys.d.ts.map +1 -0
- package/dist/ApiKeys.js +282 -0
- package/dist/ApiKeys.js.map +1 -0
- package/dist/App.d.ts +6771 -3819
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +145 -317
- package/dist/App.js.map +1 -1
- package/dist/Handler.d.ts +86 -0
- package/dist/Handler.d.ts.map +1 -0
- package/dist/Handler.js +83 -0
- package/dist/Handler.js.map +1 -0
- package/dist/Scope.d.ts +14 -4
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +16 -4
- package/dist/Scope.js.map +1 -1
- package/dist/Webhooks.d.ts +5 -7
- package/dist/Webhooks.d.ts.map +1 -1
- package/dist/Webhooks.js +11 -4
- package/dist/Webhooks.js.map +1 -1
- package/dist/admin/Access.d.ts +1 -3
- package/dist/admin/Access.d.ts.map +1 -1
- package/dist/admin/Access.js +1 -3
- package/dist/admin/Access.js.map +1 -1
- package/dist/admin/App.d.ts +167 -205
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/App.js +2 -4
- package/dist/admin/App.js.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +105 -5
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +75 -9
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/scopes.d.ts +6 -0
- package/dist/admin/apps/scopes.d.ts.map +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +35 -149
- package/dist/admin/apps/verified-tokens.d.ts.map +1 -1
- package/dist/admin/apps/verified-tokens.js +18 -39
- 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 +1 -1
- package/dist/apps/data/App.d.ts +19176 -0
- package/dist/apps/data/App.d.ts.map +1 -0
- package/dist/apps/data/App.js +236 -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} +49 -49
- 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} +183 -183
- 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} +460 -460
- 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} +94 -94
- 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/{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} +6 -6
- package/dist/apps/data/routes/receipts.d.ts.map +1 -0
- package/dist/apps/{receipts.js → data/routes/receipts.js} +12 -12
- package/dist/apps/data/routes/receipts.js.map +1 -0
- package/dist/apps/{rpc.d.ts → data/routes/rpc.d.ts} +4 -4
- package/dist/apps/data/routes/rpc.d.ts.map +1 -0
- package/dist/apps/{rpc.js → data/routes/rpc.js} +6 -6
- package/dist/apps/data/routes/rpc.js.map +1 -0
- package/dist/apps/{tokenlist.d.ts → data/routes/tokenlist.d.ts} +4 -4
- 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} +11 -11
- 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} +288 -288
- 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} +35 -35
- 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} +42 -42
- 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} +66 -63
- package/dist/apps/{webhooks.d.ts.map → data/routes/webhooks.d.ts.map} +1 -1
- package/dist/apps/{webhooks.js → data/routes/webhooks.js} +67 -59
- package/dist/apps/data/routes/webhooks.js.map +1 -0
- package/dist/apps/docs/App.d.ts +27 -0
- package/dist/apps/docs/App.d.ts.map +1 -0
- package/dist/apps/docs/App.js +122 -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/index.d.ts +4 -0
- package/dist/apps/index.d.ts.map +1 -0
- package/dist/apps/index.js +4 -0
- package/dist/apps/index.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 +2985 -0
- package/dist/apps/platform/App.d.ts.map +1 -0
- package/dist/apps/platform/App.js +74 -0
- package/dist/apps/platform/App.js.map +1 -0
- package/dist/apps/platform/index.d.ts +2 -0
- package/dist/apps/platform/index.d.ts.map +1 -0
- package/dist/apps/platform/index.js +2 -0
- package/dist/apps/platform/index.js.map +1 -0
- package/dist/apps/platform/routes/api-keys.d.ts +681 -0
- package/dist/apps/platform/routes/api-keys.d.ts.map +1 -0
- package/dist/apps/platform/routes/api-keys.js +328 -0
- package/dist/apps/platform/routes/api-keys.js.map +1 -0
- package/dist/apps/platform/routes/invitations.d.ts +733 -0
- package/dist/apps/platform/routes/invitations.d.ts.map +1 -0
- package/dist/apps/platform/routes/invitations.js +413 -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 +582 -0
- package/dist/apps/platform/routes/orgs.d.ts.map +1 -0
- package/dist/apps/platform/routes/orgs.js +265 -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/relay/App.d.ts +41 -0
- package/dist/apps/relay/App.d.ts.map +1 -0
- package/dist/apps/relay/App.js +103 -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 +193 -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.d.ts → cli/Cli.d.ts} +13 -2
- package/dist/cli/Cli.d.ts.map +1 -0
- package/dist/cli/Cli.js +19 -0
- package/dist/cli/Cli.js.map +1 -0
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +4 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/commands/admin.d.ts +15 -0
- package/dist/cli/commands/admin.d.ts.map +1 -0
- package/dist/cli/commands/admin.js +60 -0
- package/dist/cli/commands/admin.js.map +1 -0
- package/dist/cloudflare.d.ts +7 -0
- package/dist/cloudflare.d.ts.map +1 -1
- package/dist/cloudflare.js +9 -0
- package/dist/cloudflare.js.map +1 -1
- package/dist/db/Db.d.ts +113 -0
- package/dist/db/Db.d.ts.map +1 -0
- package/dist/db/Db.js +402 -0
- package/dist/db/Db.js.map +1 -0
- package/dist/db/Schema.d.ts +168 -0
- package/dist/db/Schema.d.ts.map +1 -0
- package/dist/db/Schema.js +229 -0
- package/dist/db/Schema.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 +123 -0
- package/dist/db/tables/organizations.d.ts.map +1 -0
- package/dist/db/tables/organizations.js +170 -0
- package/dist/db/tables/organizations.js.map +1 -0
- 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/sponsoredTransactions.d.ts +120 -0
- package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -0
- package/dist/db/tables/sponsoredTransactions.js +161 -0
- package/dist/db/tables/sponsoredTransactions.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/db/tables/verifiedTokens.d.ts +53 -0
- package/dist/db/tables/verifiedTokens.d.ts.map +1 -0
- package/dist/db/tables/verifiedTokens.js +74 -0
- package/dist/db/tables/verifiedTokens.js.map +1 -0
- package/dist/db/tables/webhookDeliveries.d.ts +71 -0
- package/dist/db/tables/webhookDeliveries.d.ts.map +1 -0
- package/dist/db/tables/webhookDeliveries.js +119 -0
- package/dist/db/tables/webhookDeliveries.js.map +1 -0
- package/dist/db/tables/webhookSubscriptions.d.ts +158 -0
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -0
- package/dist/db/tables/webhookSubscriptions.js +272 -0
- package/dist/db/tables/webhookSubscriptions.js.map +1 -0
- package/dist/handlers/internal/executionError.d.ts +25 -0
- package/dist/handlers/internal/executionError.d.ts.map +1 -0
- package/dist/handlers/internal/executionError.js +186 -0
- package/dist/handlers/internal/executionError.js.map +1 -0
- package/dist/handlers/internal/multisig.d.ts +233 -0
- package/dist/handlers/internal/multisig.d.ts.map +1 -0
- package/dist/handlers/internal/multisig.js +542 -0
- package/dist/handlers/internal/multisig.js.map +1 -0
- package/dist/handlers/internal/requestListener.d.ts +124 -0
- package/dist/handlers/internal/requestListener.d.ts.map +1 -0
- package/dist/handlers/internal/requestListener.js +173 -0
- package/dist/handlers/internal/requestListener.js.map +1 -0
- package/dist/handlers/internal/sponsorship.d.ts +113 -0
- package/dist/handlers/internal/sponsorship.d.ts.map +1 -0
- package/dist/handlers/internal/sponsorship.js +128 -0
- package/dist/handlers/internal/sponsorship.js.map +1 -0
- package/dist/handlers/internal/types.d.ts +284 -0
- package/dist/handlers/internal/types.d.ts.map +1 -0
- package/dist/handlers/internal/types.js +2 -0
- package/dist/handlers/internal/types.js.map +1 -0
- package/dist/handlers/internal/utils.d.ts +34 -0
- package/dist/handlers/internal/utils.d.ts.map +1 -0
- package/dist/handlers/internal/utils.js +131 -0
- package/dist/handlers/internal/utils.js.map +1 -0
- package/dist/handlers/relay.d.ts +123 -0
- package/dist/handlers/relay.d.ts.map +1 -0
- package/dist/handlers/relay.js +1278 -0
- package/dist/handlers/relay.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/internal/Auth.d.ts +224 -16
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +572 -33
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/Log.d.ts +7 -3
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +4 -0
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +0 -19
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +0 -57
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/RpcSchema.d.ts +10 -0
- package/dist/internal/RpcSchema.d.ts.map +1 -0
- package/dist/internal/RpcSchema.js +2 -0
- package/dist/internal/RpcSchema.js.map +1 -0
- package/dist/internal/Store.d.ts +49 -4
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +81 -5
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/VerifiedTokens.d.ts +15 -34
- package/dist/internal/VerifiedTokens.d.ts.map +1 -1
- package/dist/internal/VerifiedTokens.js +115 -159
- package/dist/internal/VerifiedTokens.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 +50 -36
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +92 -205
- package/dist/internal/Webhooks.js.map +1 -1
- package/package.json +37 -6
- package/src/ApiKey.test.ts +3 -3
- package/src/ApiKey.ts +11 -12
- package/src/ApiKeys.test.ts +278 -0
- package/src/ApiKeys.ts +358 -0
- package/src/App.test-d.ts +1 -1
- package/src/App.test.ts +40508 -19083
- package/src/App.ts +239 -416
- package/src/Client.test-d.ts +307 -16
- package/src/Handler.ts +154 -0
- package/src/Scope.ts +17 -4
- package/src/Webhooks.test.ts +8 -7
- package/src/Webhooks.ts +13 -7
- package/src/admin/Access.ts +1 -3
- package/src/admin/App.ts +19 -24
- package/src/admin/apps/api-keys.test.ts +70 -18
- package/src/admin/apps/api-keys.ts +92 -9
- package/src/admin/apps/scopes.test.ts +8 -0
- package/src/admin/apps/verified-tokens.test.ts +3 -30
- package/src/admin/apps/verified-tokens.ts +18 -37
- package/src/admin/ui.generated.ts +1 -1
- package/src/apps/composition.test.ts +66 -0
- package/src/apps/data/App.ts +295 -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} +6 -5
- package/src/apps/{balances.ts → data/routes/balances.ts} +46 -12
- package/src/apps/{blocks.test.ts → data/routes/blocks.test.ts} +4 -4
- 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} +2 -2
- 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/{indexer.test.ts → data/routes/indexer.test.ts} +27 -6
- package/src/apps/{indexer.ts → data/routes/indexer.ts} +13 -10
- package/src/apps/{receipts.test.ts → data/routes/receipts.test.ts} +4 -4
- package/src/apps/{receipts.ts → data/routes/receipts.ts} +13 -13
- package/src/apps/{rpc.test.ts → data/routes/rpc.test.ts} +142 -13
- package/src/apps/{rpc.ts → data/routes/rpc.ts} +7 -7
- package/src/apps/{tokenlist.test.ts → data/routes/tokenlist.test.ts} +8 -10
- package/src/apps/{tokenlist.ts → data/routes/tokenlist.ts} +9 -9
- package/src/apps/{tokens.test.ts → data/routes/tokens.test.ts} +6 -5
- package/src/apps/{tokens.ts → data/routes/tokens.ts} +20 -20
- package/src/apps/{transactions.test.ts → data/routes/transactions.test.ts} +4 -4
- package/src/apps/{transactions.ts → data/routes/transactions.ts} +15 -15
- package/src/apps/{transfers.test.ts → data/routes/transfers.test.ts} +3 -3
- package/src/apps/{transfers.ts → data/routes/transfers.ts} +15 -15
- package/src/apps/{verified-tokens.test.ts → data/routes/verified-tokens.test.ts} +27 -15
- package/src/apps/{verified-tokens.ts → data/routes/verified-tokens.ts} +10 -10
- package/src/apps/{webhooks.test.ts → data/routes/webhooks.test.ts} +137 -150
- package/src/apps/{webhooks.ts → data/routes/webhooks.ts} +83 -81
- package/src/apps/docs/App.ts +136 -0
- package/src/apps/docs/index.ts +1 -0
- package/src/apps/index.ts +3 -0
- package/src/apps/metadata.ts +23 -0
- package/src/apps/platform/App.ts +130 -0
- package/src/apps/platform/index.ts +1 -0
- package/src/apps/platform/routes/api-keys.test.ts +330 -0
- package/src/apps/platform/routes/api-keys.ts +427 -0
- package/src/apps/platform/routes/invitations.test.ts +361 -0
- package/src/apps/platform/routes/invitations.ts +519 -0
- package/src/apps/platform/routes/me.test.ts +121 -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 +343 -0
- package/src/apps/platform/routes/projects.test.ts +181 -0
- package/src/apps/platform/routes/projects.ts +367 -0
- package/src/apps/relay/App.test.ts +484 -0
- package/src/apps/relay/App.ts +128 -0
- package/src/apps/relay/Sponsorships.test.ts +375 -0
- package/src/apps/relay/Sponsorships.ts +305 -0
- package/src/apps/relay/index.ts +2 -0
- package/src/{Cli.test.ts → cli/Cli.test.ts} +10 -9
- package/src/{Cli.ts → cli/Cli.ts} +16 -9
- package/src/cli/bin.ts +4 -0
- package/src/cli/commands/admin.test.ts +71 -0
- package/src/cli/commands/admin.ts +60 -0
- package/src/cloudflare.ts +10 -0
- package/src/db/Db.test.ts +84 -0
- package/src/db/Db.ts +542 -0
- package/src/db/Schema.ts +301 -0
- package/src/db/tables/invitations.ts +198 -0
- package/src/db/tables/memberships.ts +208 -0
- package/src/db/tables/organizations.test.ts +160 -0
- package/src/db/tables/organizations.ts +232 -0
- package/src/db/tables/projects.ts +107 -0
- package/src/db/tables/sponsoredTransactions.test.ts +218 -0
- package/src/db/tables/sponsoredTransactions.ts +236 -0
- package/src/db/tables/users.ts +85 -0
- package/src/db/tables/verifiedTokens.ts +111 -0
- package/src/db/tables/webhookDeliveries.ts +159 -0
- package/src/db/tables/webhookSubscriptions.ts +358 -0
- package/src/handlers/internal/executionError.ts +207 -0
- package/src/handlers/internal/multisig.test.ts +818 -0
- package/src/handlers/internal/multisig.ts +823 -0
- package/src/handlers/internal/requestListener.ts +273 -0
- package/src/handlers/internal/sponsorship.ts +245 -0
- package/src/handlers/internal/types.ts +378 -0
- package/src/handlers/internal/utils.ts +153 -0
- package/src/handlers/relay.test.ts +2035 -0
- package/src/handlers/relay.ts +1623 -0
- package/src/index.ts +4 -2
- package/src/internal/Auth.test.ts +337 -21
- package/src/internal/Auth.ts +783 -44
- package/src/internal/Cursor.test.ts +3 -2
- package/src/internal/Log.test.ts +1 -1
- package/src/internal/Log.ts +11 -3
- package/src/internal/MetricSink.ts +1 -1
- package/src/internal/OpenApi.ts +0 -59
- package/src/internal/RateLimit.test.ts +1 -1
- package/src/internal/RpcSchema.ts +10 -0
- package/src/internal/Store.test.ts +150 -10
- package/src/internal/Store.ts +136 -11
- package/src/internal/Tidx.local.test.ts +1 -1
- package/src/internal/VerifiedTokens.test.ts +99 -115
- package/src/internal/VerifiedTokens.ts +123 -175
- package/src/internal/WebhookDestination.test.ts +1 -1
- package/src/internal/Webhooks.test.ts +111 -111
- package/src/internal/Webhooks.ts +103 -221
- package/dist/ApiKeySource.d.ts +0 -166
- package/dist/ApiKeySource.d.ts.map +0 -1
- package/dist/ApiKeySource.js +0 -234
- package/dist/ApiKeySource.js.map +0 -1
- package/dist/Cli.d.ts.map +0 -1
- package/dist/Cli.js +0 -13
- package/dist/Cli.js.map +0 -1
- 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/seeds/31318/icons/0x20c0000000000000000000000000000000000000.svg +0 -1
- package/seeds/31318/icons/0x20c0000000000000000000000000000000000001.svg +0 -1
- package/seeds/31318/icons/0x20c0000000000000000000000000000000000002.svg +0 -1
- package/seeds/31318/icons/0x20c0000000000000000000000000000000000003.svg +0 -1
- package/seeds/31318/verified-tokens.json +0 -30
- package/seeds/4217/icons/0x20c0000000000000000000000000000000000000.svg +0 -25
- package/seeds/4217/icons/0x20c000000000000000000000048c8f36df1c9a4a.svg +0 -1
- package/seeds/4217/icons/0x20c0000000000000000000000520792dcccccccc.svg +0 -1
- package/seeds/4217/icons/0x20c0000000000000000000000a6da882d075a4c3.svg +0 -4
- package/seeds/4217/icons/0x20c000000000000000000000111111111e910f0f.svg +0 -30
- package/seeds/4217/icons/0x20c00000000000000000000014f22ca97301eb73.svg +0 -1
- package/seeds/4217/icons/0x20c0000000000000000000001621e21f71cf12fb.svg +0 -1
- package/seeds/4217/icons/0x20c0000000000000000000002f52d5cc21a3207b.svg +0 -1
- package/seeds/4217/icons/0x20c0000000000000000000003158081efd85bfc2.svg +0 -11
- package/seeds/4217/icons/0x20c0000000000000000000003554d28269e0f3c2.svg +0 -1
- package/seeds/4217/icons/0x20c000000000000000000000383a23bacb546ab9.svg +0 -1
- package/seeds/4217/icons/0x20c00000000000000000000042109aef2f8b28e1.png +0 -0
- package/seeds/4217/icons/0x20c0000000000000000000005c0bac7cef389a11.svg +0 -1
- package/seeds/4217/icons/0x20c0000000000000000000006fd9a167923ba194.png +0 -0
- package/seeds/4217/icons/0x20c0000000000000000000007f7ba549dd0251b9.svg +0 -1
- package/seeds/4217/icons/0x20c0000000000000000000008191667423f70e67.svg +0 -5
- package/seeds/4217/icons/0x20c0000000000000000000008ee4fcff88888888.svg +0 -1
- package/seeds/4217/icons/0x20c0000000000000000000009a4a4b17e0dc6651.svg +0 -1
- package/seeds/4217/icons/0x20c000000000000000000000ab02d39df30bd17e.svg +0 -1
- package/seeds/4217/icons/0x20c000000000000000000000ae247a1130450f09.svg +0 -1
- package/seeds/4217/icons/0x20c000000000000000000000aeed2ec36a54d0e5.svg +0 -1
- package/seeds/4217/icons/0x20c000000000000000000000b9537d11c60e8b50.svg +0 -1
- package/seeds/4217/icons/0x20c000000000000000000000bd95bfb69fbe6ce3.svg +0 -1
- package/seeds/4217/icons/0x20c000000000000000000000c412ec89d0c08be5.svg +0 -1
- package/seeds/4217/icons/0x20c000000000000000000000f047dd7018e50367.png +0 -0
- package/seeds/4217/verified-tokens.json +0 -177
- package/seeds/42431/icons/0x20c0000000000000000000000000000000000000.svg +0 -25
- package/seeds/42431/icons/0x20c0000000000000000000000000000000000001.svg +0 -1
- package/seeds/42431/icons/0x20c0000000000000000000000000000000000002.svg +0 -1
- package/seeds/42431/icons/0x20c0000000000000000000000000000000000003.svg +0 -1
- package/seeds/42431/icons/0x20c0000000000000000000009e8d7eb59b783726.svg +0 -1
- package/seeds/42431/icons/0x20c000000000000000000000d72572838bbee59c.svg +0 -1
- package/seeds/42431/verified-tokens.json +0 -44
- package/seeds/openrpc/README.md +0 -27
- package/seeds/openrpc/execution-apis.json +0 -8989
- package/src/ApiKeySource.test-d.ts +0 -11
- package/src/ApiKeySource.test.ts +0 -295
- package/src/ApiKeySource.ts +0 -303
- /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
ADDED
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CamelCasePlugin,
|
|
3
|
+
type Compilable,
|
|
4
|
+
CompiledQuery,
|
|
5
|
+
type Dialect,
|
|
6
|
+
Kysely,
|
|
7
|
+
PostgresDialect,
|
|
8
|
+
type RawBuilder,
|
|
9
|
+
sql,
|
|
10
|
+
} from 'kysely'
|
|
11
|
+
import * as pg from 'pg'
|
|
12
|
+
|
|
13
|
+
import type * as Invitations from './tables/invitations.js'
|
|
14
|
+
import type * as Memberships from './tables/memberships.js'
|
|
15
|
+
import type * as Organizations from './tables/organizations.js'
|
|
16
|
+
import type * as Projects from './tables/projects.js'
|
|
17
|
+
import type * as SponsoredTransactions from './tables/sponsoredTransactions.js'
|
|
18
|
+
import type * as Users from './tables/users.js'
|
|
19
|
+
import type * as VerifiedTokens from './tables/verifiedTokens.js'
|
|
20
|
+
import type * as WebhookDeliveries from './tables/webhookDeliveries.js'
|
|
21
|
+
import type * as WebhookSubscriptions from './tables/webhookSubscriptions.js'
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Kysely schema with camelCase columns. {@link CamelCasePlugin} maps table
|
|
25
|
+
* records, queries, and {@link migrations} DDL to snake_case storage columns.
|
|
26
|
+
*/
|
|
27
|
+
export type Database = {
|
|
28
|
+
migrations: {
|
|
29
|
+
appliedAt: string
|
|
30
|
+
checksum: string
|
|
31
|
+
name: string
|
|
32
|
+
/** SQL as applied; null on rows written before the column existed. */
|
|
33
|
+
sql: string | null
|
|
34
|
+
}
|
|
35
|
+
invitations: Invitations.Table
|
|
36
|
+
memberships: Memberships.Table
|
|
37
|
+
organizations: Organizations.Table
|
|
38
|
+
projects: Projects.Table
|
|
39
|
+
sponsored_transactions: SponsoredTransactions.Table
|
|
40
|
+
users: Users.Table
|
|
41
|
+
verified_token_lists: VerifiedTokens.ListTable
|
|
42
|
+
verified_tokens: VerifiedTokens.Table
|
|
43
|
+
webhook_deliveries: WebhookDeliveries.Table
|
|
44
|
+
webhook_subscriptions: WebhookSubscriptions.Table
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* A SQL-backed authoritative store: the underlying Kysely handle (table
|
|
49
|
+
* repository modules query through it), schema migrations, and transactions.
|
|
50
|
+
*/
|
|
51
|
+
export type Db = {
|
|
52
|
+
/** Closes the underlying connection/pool. */
|
|
53
|
+
close(): Promise<void>
|
|
54
|
+
/**
|
|
55
|
+
* Underlying Kysely handle. Transaction-scoped {@link Db} values carry the
|
|
56
|
+
* transaction handle, so repositories called with `tx` run inside it. */
|
|
57
|
+
kysely: Kysely<Database>
|
|
58
|
+
/** Applies any pending schema migrations; safe to call repeatedly and concurrently. */
|
|
59
|
+
migrate(): Promise<void>
|
|
60
|
+
/**
|
|
61
|
+
* Runs `fn` in a transaction — commits on return, rolls back on throw. `fn`
|
|
62
|
+
* receives a transaction-scoped {@link Db}; pass it (not the outer `Db`) to
|
|
63
|
+
* repositories so every query inside runs in the transaction.
|
|
64
|
+
*/
|
|
65
|
+
transaction<value>(fn: (tx: Db) => Promise<value>): Promise<value>
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* A {@link Db}, or a factory for per-request Workers/Hyperdrive connections.
|
|
70
|
+
* Node can pass a long-lived singleton. Resolve at the leaf with {@link get}.
|
|
71
|
+
*/
|
|
72
|
+
export type Source = Db | (() => Db)
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Resolves a {@link Source} to a {@link Db}. Call at the request leaf so
|
|
76
|
+
* factories create per-request instances; singletons resolve to themselves.
|
|
77
|
+
*
|
|
78
|
+
* @param source - The database or factory.
|
|
79
|
+
* @returns The resolved {@link Db}.
|
|
80
|
+
*/
|
|
81
|
+
export function get(source: Source): Db {
|
|
82
|
+
return typeof source === 'function' ? source() : source
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* One schema migration. `up` builds a single idempotent Kysely DDL statement;
|
|
87
|
+
* {@link Db.migrate} compiles it for the checksum, then applies it.
|
|
88
|
+
*/
|
|
89
|
+
type Migration = {
|
|
90
|
+
/** Unique, ordered migration name (e.g. `0001_organizations`). */
|
|
91
|
+
name: string
|
|
92
|
+
/**
|
|
93
|
+
* Builds the migration's DDL against `db`. Use `.ifNotExists()` so the
|
|
94
|
+
* statement is safe to re-run without a wrapping transaction. */
|
|
95
|
+
up: (db: Kysely<Database>) => Compilable & { execute(): Promise<unknown> }
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Ordered schema migrations for {@link Db.migrate}. Each `up` is one
|
|
100
|
+
* idempotent statement; compiled-SQL FNV-1a checksums reject edited applied
|
|
101
|
+
* migrations.
|
|
102
|
+
*/
|
|
103
|
+
export const migrations: readonly Migration[] = [
|
|
104
|
+
{
|
|
105
|
+
name: '0001_organizations',
|
|
106
|
+
up: (db) =>
|
|
107
|
+
db.schema
|
|
108
|
+
.createTable('organizations')
|
|
109
|
+
.ifNotExists()
|
|
110
|
+
.addColumn('id', 'text', (c) => c.primaryKey())
|
|
111
|
+
.addColumn('name', 'text', (c) => c.notNull())
|
|
112
|
+
.addColumn('createdBy', 'text')
|
|
113
|
+
.addColumn('createdAt', 'text', (c) => c.notNull())
|
|
114
|
+
.addColumn('updatedAt', 'text', (c) => c.notNull()),
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
name: '0002_webhook_subscriptions',
|
|
118
|
+
up: (db) =>
|
|
119
|
+
db.schema
|
|
120
|
+
.createTable('webhookSubscriptions')
|
|
121
|
+
.ifNotExists()
|
|
122
|
+
.addColumn('id', 'text', (c) => c.primaryKey())
|
|
123
|
+
.addColumn('ownerType', 'text', (c) => c.notNull())
|
|
124
|
+
.addColumn('ownerId', 'text', (c) => c.notNull())
|
|
125
|
+
.addColumn('chainId', 'integer', (c) => c.notNull())
|
|
126
|
+
.addColumn('eventType', 'text', (c) => c.notNull())
|
|
127
|
+
.addColumn('status', 'text', (c) => c.notNull().defaultTo('active'))
|
|
128
|
+
.addColumn('destination', 'jsonb', (c) => c.notNull())
|
|
129
|
+
.addColumn('filters', 'jsonb', (c) => c.notNull().defaultTo(sql`'{}'::jsonb`))
|
|
130
|
+
.addColumn('context', 'jsonb')
|
|
131
|
+
.addColumn('secret', 'text', (c) => c.notNull())
|
|
132
|
+
.addColumn('failureCount', 'integer', (c) => c.notNull().defaultTo(0))
|
|
133
|
+
.addColumn('lastDeliveryAt', 'text')
|
|
134
|
+
.addColumn('pollerCursor', 'text')
|
|
135
|
+
.addColumn('expiresAt', 'text')
|
|
136
|
+
.addColumn('createdAt', 'text', (c) => c.notNull())
|
|
137
|
+
.addColumn('updatedAt', 'text', (c) => c.notNull()),
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: '0003_webhook_deliveries',
|
|
141
|
+
up: (db) =>
|
|
142
|
+
db.schema
|
|
143
|
+
.createTable('webhookDeliveries')
|
|
144
|
+
.ifNotExists()
|
|
145
|
+
.addColumn('id', 'text', (c) => c.primaryKey())
|
|
146
|
+
.addColumn('subscriptionId', 'text', (c) =>
|
|
147
|
+
c.notNull().references('webhookSubscriptions.id').onDelete('cascade'),
|
|
148
|
+
)
|
|
149
|
+
.addColumn('eventId', 'text', (c) => c.notNull())
|
|
150
|
+
.addColumn('attempt', 'integer', (c) => c.notNull())
|
|
151
|
+
.addColumn('status', 'text', (c) => c.notNull())
|
|
152
|
+
.addColumn('requestUrl', 'text', (c) => c.notNull())
|
|
153
|
+
.addColumn('responseStatus', 'integer')
|
|
154
|
+
.addColumn('responseMs', 'integer')
|
|
155
|
+
.addColumn('error', 'text')
|
|
156
|
+
.addColumn('envelope', 'jsonb', (c) => c.notNull())
|
|
157
|
+
.addColumn('createdAt', 'text', (c) => c.notNull())
|
|
158
|
+
.addColumn('expiresAt', 'text', (c) => c.notNull()),
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: '0004_verified_token_lists',
|
|
162
|
+
up: (db) =>
|
|
163
|
+
db.schema
|
|
164
|
+
.createTable('verifiedTokenLists')
|
|
165
|
+
.ifNotExists()
|
|
166
|
+
.addColumn('chainId', 'integer', (c) => c.primaryKey())
|
|
167
|
+
.addColumn('version', 'text', (c) => c.notNull())
|
|
168
|
+
.addColumn('updatedAt', 'text', (c) => c.notNull()),
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
name: '0005_verified_tokens',
|
|
172
|
+
up: (db) =>
|
|
173
|
+
db.schema
|
|
174
|
+
.createTable('verifiedTokens')
|
|
175
|
+
.ifNotExists()
|
|
176
|
+
.addColumn('chainId', 'integer', (c) => c.notNull())
|
|
177
|
+
.addColumn('address', 'text', (c) => c.notNull())
|
|
178
|
+
.addColumn('symbol', 'text', (c) => c.notNull())
|
|
179
|
+
.addColumn('name', 'text', (c) => c.notNull())
|
|
180
|
+
.addColumn('currency', 'text', (c) => c.notNull())
|
|
181
|
+
.addColumn('decimals', 'integer', (c) => c.notNull())
|
|
182
|
+
.addColumn('logoUri', 'text')
|
|
183
|
+
.addColumn('position', 'integer', (c) => c.notNull())
|
|
184
|
+
.addPrimaryKeyConstraint('verified_tokens_pkey', ['chainId', 'address']),
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
// Case-insensitive symbol uniqueness per chain (`GET /tokens/:symbol`
|
|
188
|
+
// would otherwise be ambiguous).
|
|
189
|
+
name: '0006_verified_tokens_symbol_index',
|
|
190
|
+
up: (db) =>
|
|
191
|
+
db.schema
|
|
192
|
+
.createIndex('verified_tokens_symbol_idx')
|
|
193
|
+
.ifNotExists()
|
|
194
|
+
.unique()
|
|
195
|
+
.on('verifiedTokens')
|
|
196
|
+
.expression(sql`chain_id, lower(symbol)`),
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
// Owner list/count/cap scans and `id <` keyset paging.
|
|
200
|
+
name: '0007_webhook_subscriptions_owner_index',
|
|
201
|
+
up: (db) =>
|
|
202
|
+
db.schema
|
|
203
|
+
.createIndex('webhook_subscriptions_owner_idx')
|
|
204
|
+
.ifNotExists()
|
|
205
|
+
.on('webhookSubscriptions')
|
|
206
|
+
.columns(['ownerType', 'ownerId', 'id']),
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
// Partial index over active subscriptions: the poller's per-stream lookup.
|
|
210
|
+
// `sql.lit` keeps the predicate literal — DDL cannot carry parameters.
|
|
211
|
+
name: '0008_webhook_subscriptions_active_index',
|
|
212
|
+
up: (db) =>
|
|
213
|
+
db.schema
|
|
214
|
+
.createIndex('webhook_subscriptions_active_idx')
|
|
215
|
+
.ifNotExists()
|
|
216
|
+
.on('webhookSubscriptions')
|
|
217
|
+
.columns(['chainId', 'eventType'])
|
|
218
|
+
.where(sql.ref('status'), '=', sql.lit('active')),
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
name: '0009_webhook_subscriptions_expires_index',
|
|
222
|
+
up: (db) =>
|
|
223
|
+
db.schema
|
|
224
|
+
.createIndex('webhook_subscriptions_expires_idx')
|
|
225
|
+
.ifNotExists()
|
|
226
|
+
.on('webhookSubscriptions')
|
|
227
|
+
.column('expiresAt')
|
|
228
|
+
.where('expiresAt', 'is not', null),
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
// Per-subscription delivery-log paging.
|
|
232
|
+
name: '0010_webhook_deliveries_subscription_index',
|
|
233
|
+
up: (db) =>
|
|
234
|
+
db.schema
|
|
235
|
+
.createIndex('webhook_deliveries_subscription_idx')
|
|
236
|
+
.ifNotExists()
|
|
237
|
+
.on('webhookDeliveries')
|
|
238
|
+
.columns(['subscriptionId', 'id']),
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
name: '0011_webhook_deliveries_expires_index',
|
|
242
|
+
up: (db) =>
|
|
243
|
+
db.schema
|
|
244
|
+
.createIndex('webhook_deliveries_expires_idx')
|
|
245
|
+
.ifNotExists()
|
|
246
|
+
.on('webhookDeliveries')
|
|
247
|
+
.column('expiresAt'),
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
name: '0012_users',
|
|
251
|
+
up: (db) =>
|
|
252
|
+
db.schema
|
|
253
|
+
.createTable('users')
|
|
254
|
+
.ifNotExists()
|
|
255
|
+
.addColumn('id', 'text', (c) => c.primaryKey())
|
|
256
|
+
.addColumn('address', 'text', (c) => c.notNull().unique())
|
|
257
|
+
.addColumn('email', 'text')
|
|
258
|
+
.addColumn('createdAt', 'text', (c) => c.notNull())
|
|
259
|
+
.addColumn('updatedAt', 'text', (c) => c.notNull()),
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: '0013_organizations_user_id',
|
|
263
|
+
// The schema builder cannot express `ADD COLUMN IF NOT EXISTS`; raw SQL
|
|
264
|
+
// (snake_case: the CamelCase plugin does not map raw statements).
|
|
265
|
+
up: (db) => raw(db, sql`ALTER TABLE organizations ADD COLUMN IF NOT EXISTS user_id text`),
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: '0014_projects',
|
|
269
|
+
up: (db) =>
|
|
270
|
+
db.schema
|
|
271
|
+
.createTable('projects')
|
|
272
|
+
.ifNotExists()
|
|
273
|
+
.addColumn('id', 'text', (c) => c.primaryKey())
|
|
274
|
+
.addColumn('orgId', 'text', (c) => c.notNull())
|
|
275
|
+
.addColumn('name', 'text', (c) => c.notNull())
|
|
276
|
+
.addColumn('createdAt', 'text', (c) => c.notNull())
|
|
277
|
+
.addColumn('updatedAt', 'text', (c) => c.notNull()),
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
name: '0015_projects_org_index',
|
|
281
|
+
up: (db) =>
|
|
282
|
+
db.schema.createIndex('projects_org_idx').ifNotExists().on('projects').column('orgId'),
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
name: '0016_memberships',
|
|
286
|
+
up: (db) =>
|
|
287
|
+
db.schema
|
|
288
|
+
.createTable('memberships')
|
|
289
|
+
.ifNotExists()
|
|
290
|
+
.addColumn('orgId', 'text', (c) => c.notNull())
|
|
291
|
+
.addColumn('userId', 'text', (c) => c.notNull())
|
|
292
|
+
.addColumn('role', 'text', (c) => c.notNull())
|
|
293
|
+
.addColumn('createdAt', 'text', (c) => c.notNull())
|
|
294
|
+
.addColumn('updatedAt', 'text', (c) => c.notNull())
|
|
295
|
+
.addPrimaryKeyConstraint('memberships_pk', ['orgId', 'userId']),
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
name: '0017_memberships_user_index',
|
|
299
|
+
up: (db) =>
|
|
300
|
+
db.schema.createIndex('memberships_user_idx').ifNotExists().on('memberships').column('userId'), // prettier-ignore
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
name: '0018_memberships_owner_backfill',
|
|
304
|
+
// Raw SQL (snake_case: the CamelCase plugin does not map raw statements).
|
|
305
|
+
up: (db) =>
|
|
306
|
+
raw(
|
|
307
|
+
db,
|
|
308
|
+
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`,
|
|
309
|
+
),
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
name: '0019_invitations',
|
|
313
|
+
up: (db) =>
|
|
314
|
+
db.schema
|
|
315
|
+
.createTable('invitations')
|
|
316
|
+
.ifNotExists()
|
|
317
|
+
.addColumn('id', 'text', (c) => c.primaryKey())
|
|
318
|
+
.addColumn('orgId', 'text', (c) => c.notNull())
|
|
319
|
+
.addColumn('email', 'text', (c) => c.notNull())
|
|
320
|
+
.addColumn('role', 'text', (c) => c.notNull())
|
|
321
|
+
.addColumn('invitedBy', 'text', (c) => c.notNull())
|
|
322
|
+
.addColumn('createdAt', 'text', (c) => c.notNull())
|
|
323
|
+
.addColumn('expiresAt', 'text', (c) => c.notNull())
|
|
324
|
+
.addColumn('acceptedAt', 'text')
|
|
325
|
+
.addColumn('revokedAt', 'text'),
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
name: '0020_invitations_org_index',
|
|
329
|
+
up: (db) =>
|
|
330
|
+
db.schema.createIndex('invitations_org_idx').ifNotExists().on('invitations').column('orgId'),
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
name: '0021_invitations_email_index',
|
|
334
|
+
up: (db) =>
|
|
335
|
+
db.schema.createIndex('invitations_email_idx').ifNotExists().on('invitations').column('email'), // prettier-ignore
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
name: '0022_users_address_nullable',
|
|
339
|
+
// Raw SQL; a no-op when the column is already nullable.
|
|
340
|
+
up: (db) => raw(db, sql`ALTER TABLE users ALTER COLUMN address DROP NOT NULL`),
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
name: '0023_invitations_pending_unique',
|
|
344
|
+
// Raw SQL: a partial unique index (snake_case; the CamelCase plugin does
|
|
345
|
+
// not map raw statements). At most one live (unaccepted, unrevoked)
|
|
346
|
+
// invitation per (org, email); a re-invite upserts the existing row.
|
|
347
|
+
up: (db) =>
|
|
348
|
+
raw(
|
|
349
|
+
db,
|
|
350
|
+
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`,
|
|
351
|
+
),
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
name: '0024_sponsored_transactions',
|
|
355
|
+
up: (db) =>
|
|
356
|
+
db.schema
|
|
357
|
+
.createTable('sponsoredTransactions')
|
|
358
|
+
.ifNotExists()
|
|
359
|
+
.addColumn('id', 'text', (c) => c.primaryKey())
|
|
360
|
+
.addColumn('orgId', 'text', (c) => c.notNull())
|
|
361
|
+
.addColumn('projectId', 'text', (c) => c.notNull())
|
|
362
|
+
.addColumn('apiKeyId', 'text', (c) => c.notNull())
|
|
363
|
+
.addColumn('environment', 'text', (c) => c.notNull())
|
|
364
|
+
.addColumn('chainId', 'integer', (c) => c.notNull())
|
|
365
|
+
.addColumn('transactionHash', 'text')
|
|
366
|
+
.addColumn('signPayload', 'text', (c) => c.notNull())
|
|
367
|
+
.addColumn('transaction', 'text', (c) => c.notNull())
|
|
368
|
+
.addColumn('status', 'text', (c) => c.notNull())
|
|
369
|
+
.addColumn('feeAmount', 'text')
|
|
370
|
+
.addColumn('feeToken', 'text')
|
|
371
|
+
.addColumn('billable', 'boolean', (c) => c.notNull())
|
|
372
|
+
.addColumn('createdAt', 'text', (c) => c.notNull())
|
|
373
|
+
.addColumn('finalizedAt', 'text')
|
|
374
|
+
.addUniqueConstraint('sponsored_transactions_sign_payload_key', ['signPayload']),
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
name: '0025_sponsored_transactions_status_index',
|
|
378
|
+
up: (db) =>
|
|
379
|
+
db.schema.createIndex('sponsored_transactions_status_idx').ifNotExists().on('sponsoredTransactions').columns(['status', 'createdAt']), // prettier-ignore
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
name: '0026_sponsored_transactions_org_index',
|
|
383
|
+
up: (db) =>
|
|
384
|
+
db.schema.createIndex('sponsored_transactions_org_idx').ifNotExists().on('sponsoredTransactions').columns(['orgId', 'createdAt']), // prettier-ignore
|
|
385
|
+
},
|
|
386
|
+
]
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Adapts a raw statement to the migration contract (argument-less
|
|
390
|
+
* `compile`/`execute`) for DDL the schema builders cannot express.
|
|
391
|
+
*/
|
|
392
|
+
function raw(db: Kysely<Database>, statement: RawBuilder<unknown>) {
|
|
393
|
+
return {
|
|
394
|
+
compile: () => statement.compile(db),
|
|
395
|
+
execute: () => statement.execute(db),
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Builds a {@link Db} for any Kysely {@link Dialect}. All backends share
|
|
401
|
+
* migrations, repositories, and the required {@link CamelCasePlugin} mapping.
|
|
402
|
+
*
|
|
403
|
+
* @param dialect - The Kysely dialect for the target backend.
|
|
404
|
+
* @returns The database.
|
|
405
|
+
*/
|
|
406
|
+
export function from(dialect: Dialect): Db {
|
|
407
|
+
// Builds Db over a top-level Kysely handle or transaction-scoped Kysely handle.
|
|
408
|
+
function build(kysely: Kysely<Database>): Db {
|
|
409
|
+
// Prevents same-handle nested transactions from deadlocking capped pools.
|
|
410
|
+
// Nested work must use the callback's scoped `tx`.
|
|
411
|
+
let active = false
|
|
412
|
+
return {
|
|
413
|
+
async close() {
|
|
414
|
+
await kysely.destroy()
|
|
415
|
+
},
|
|
416
|
+
kysely,
|
|
417
|
+
async migrate() {
|
|
418
|
+
// A session advisory lock serializes the full run, including bootstrap
|
|
419
|
+
// DDL and ledger inserts. Pin one connection and unlock in `finally`.
|
|
420
|
+
await kysely.connection().execute(async (db) => {
|
|
421
|
+
await sql`SELECT pg_advisory_lock(${migrateLockKey})`.execute(db)
|
|
422
|
+
try {
|
|
423
|
+
await sql`CREATE TABLE IF NOT EXISTS migrations (name TEXT PRIMARY KEY, checksum TEXT NOT NULL, applied_at TEXT NOT NULL)`.execute(
|
|
424
|
+
db,
|
|
425
|
+
)
|
|
426
|
+
await sql`ALTER TABLE migrations ADD COLUMN IF NOT EXISTS sql TEXT`.execute(db)
|
|
427
|
+
const applied = new Map(
|
|
428
|
+
(await db.selectFrom('migrations').select(['name', 'checksum', 'sql']).execute()).map(
|
|
429
|
+
(row) => [row.name, row] as const,
|
|
430
|
+
),
|
|
431
|
+
)
|
|
432
|
+
for (const migration of migrations) {
|
|
433
|
+
// Build once: compile (no I/O) for the checksum, execute to apply.
|
|
434
|
+
const statement = migration.up(db)
|
|
435
|
+
const compiled = statement.compile().sql
|
|
436
|
+
const digest = checksum(compiled)
|
|
437
|
+
const existing = applied.get(migration.name)
|
|
438
|
+
if (existing !== undefined) {
|
|
439
|
+
// The digest hashes kysely's rendered SQL, so a kysely upgrade
|
|
440
|
+
// can flip it with unchanged sources. The stored `sql` is what
|
|
441
|
+
// actually ran — diff it against the new render to tell render
|
|
442
|
+
// drift from a real edit (re-baseline procedure in AGENTS.md).
|
|
443
|
+
if (existing.checksum !== digest)
|
|
444
|
+
throw new Error(
|
|
445
|
+
`Migration "${migration.name}" was modified after being applied (checksum mismatch). Diff the migrations table's stored sql against the current render before re-baselining.`,
|
|
446
|
+
)
|
|
447
|
+
// Backfill rows from before the column existed; the matching
|
|
448
|
+
// checksum proves the current render is what was applied.
|
|
449
|
+
if (existing.sql === null)
|
|
450
|
+
await db
|
|
451
|
+
.updateTable('migrations')
|
|
452
|
+
.set({ sql: compiled })
|
|
453
|
+
.where('name', '=', migration.name)
|
|
454
|
+
.execute()
|
|
455
|
+
continue
|
|
456
|
+
}
|
|
457
|
+
await statement.execute()
|
|
458
|
+
await db
|
|
459
|
+
.insertInto('migrations')
|
|
460
|
+
.values({
|
|
461
|
+
appliedAt: new Date().toISOString(),
|
|
462
|
+
checksum: digest,
|
|
463
|
+
name: migration.name,
|
|
464
|
+
sql: compiled,
|
|
465
|
+
})
|
|
466
|
+
.execute()
|
|
467
|
+
}
|
|
468
|
+
} finally {
|
|
469
|
+
await sql`SELECT pg_advisory_unlock(${migrateLockKey})`.execute(db)
|
|
470
|
+
}
|
|
471
|
+
})
|
|
472
|
+
},
|
|
473
|
+
async transaction(fn) {
|
|
474
|
+
if (active) throw new Error('Db.transaction does not support nesting.')
|
|
475
|
+
active = true
|
|
476
|
+
try {
|
|
477
|
+
return await kysely.transaction().execute((trx) => fn(build(trx)))
|
|
478
|
+
} finally {
|
|
479
|
+
active = false
|
|
480
|
+
}
|
|
481
|
+
},
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
return build(new Kysely<Database>({ dialect, plugins: [new CamelCasePlugin()] }))
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Creates a Postgres-backed {@link Db} via Kysely's `PostgresDialect`. Optional
|
|
489
|
+
* `schema` scopes every pooled connection and caps the pool for test isolation.
|
|
490
|
+
*
|
|
491
|
+
* @param options - Postgres options.
|
|
492
|
+
* @returns The database.
|
|
493
|
+
*/
|
|
494
|
+
export function postgres(options: postgres.Options): Db {
|
|
495
|
+
const { connectionString, schema } = options
|
|
496
|
+
const pool = new pg.Pool(schema ? { connectionString, max: 1 } : { connectionString })
|
|
497
|
+
return from(
|
|
498
|
+
new PostgresDialect({
|
|
499
|
+
pool,
|
|
500
|
+
...(schema
|
|
501
|
+
? {
|
|
502
|
+
onCreateConnection: async (connection) => {
|
|
503
|
+
await connection.executeQuery(
|
|
504
|
+
CompiledQuery.raw(`CREATE SCHEMA IF NOT EXISTS "${schema}"`),
|
|
505
|
+
)
|
|
506
|
+
await connection.executeQuery(CompiledQuery.raw(`SET search_path TO "${schema}"`))
|
|
507
|
+
},
|
|
508
|
+
}
|
|
509
|
+
: {}),
|
|
510
|
+
}),
|
|
511
|
+
)
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
export declare namespace postgres {
|
|
515
|
+
/** Options for {@link postgres}. */
|
|
516
|
+
type Options = {
|
|
517
|
+
/** Postgres connection string (`postgresql://…`). */
|
|
518
|
+
connectionString: string
|
|
519
|
+
/** Schema to create and scope the session to (isolates concurrent tests). */
|
|
520
|
+
schema?: string | undefined
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Fixed key for the {@link Db.migrate} Postgres session advisory lock: the
|
|
526
|
+
* ASCII bytes of `"tapi"`, making all migrators serialize together.
|
|
527
|
+
*/
|
|
528
|
+
const migrateLockKey = 0x74617069
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Deterministic FNV-1a hash of migration SQL, so an applied migration whose
|
|
532
|
+
* source later changes is rejected (instead of silently diverging). Not
|
|
533
|
+
* cryptographic — only needs collision resistance for typos.
|
|
534
|
+
*/
|
|
535
|
+
function checksum(sql: string): string {
|
|
536
|
+
let hash = 0x811c9dc5
|
|
537
|
+
for (let i = 0; i < sql.length; i++) {
|
|
538
|
+
hash ^= sql.charCodeAt(i)
|
|
539
|
+
hash = Math.imul(hash, 0x01000193)
|
|
540
|
+
}
|
|
541
|
+
return (hash >>> 0).toString(16).padStart(8, '0')
|
|
542
|
+
}
|