tapimo 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App.d.ts +2296 -1010
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +2 -2
- package/dist/App.js.map +1 -1
- package/dist/Assets.d.ts +15 -0
- package/dist/Assets.d.ts.map +1 -1
- package/dist/Assets.js +7 -0
- package/dist/Assets.js.map +1 -1
- package/dist/admin/App.d.ts +53 -4
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +4 -4
- package/dist/admin/apps/earn-vaults.d.ts +114 -0
- package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
- package/dist/admin/apps/earn-vaults.js +59 -6
- package/dist/admin/apps/earn-vaults.js.map +1 -1
- package/dist/admin/apps/organizations.d.ts.map +1 -1
- package/dist/admin/apps/organizations.js +4 -2
- package/dist/admin/apps/organizations.js.map +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +9 -9
- package/dist/admin/ui.generated.d.ts +1 -1
- package/dist/admin/ui.generated.d.ts.map +1 -1
- package/dist/admin/ui.generated.js +151 -151
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/apps/data/App.d.ts +1699 -749
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +56 -7
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/ZoneSelection.d.ts +62 -0
- package/dist/apps/data/ZoneSelection.d.ts.map +1 -0
- package/dist/apps/data/ZoneSelection.js +44 -0
- package/dist/apps/data/ZoneSelection.js.map +1 -0
- package/dist/apps/data/routes/activities.d.ts +2367 -4
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +368 -87
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +471 -340
- package/dist/apps/data/routes/addresses.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.d.ts +28 -28
- package/dist/apps/data/routes/balances.js +1 -1
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +4 -4
- package/dist/apps/data/routes/blocks.js +1 -1
- package/dist/apps/data/routes/blocks.js.map +1 -1
- package/dist/apps/data/routes/coingecko.d.ts +176 -176
- package/dist/apps/data/routes/earn.d.ts +131 -6
- package/dist/apps/data/routes/earn.d.ts.map +1 -1
- package/dist/apps/data/routes/earn.js +157 -25
- package/dist/apps/data/routes/earn.js.map +1 -1
- package/dist/apps/data/routes/exchanges.d.ts +825 -119
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
- package/dist/apps/data/routes/exchanges.js +16 -13
- package/dist/apps/data/routes/exchanges.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
- package/dist/apps/data/routes/fee-amm.js +9 -11
- package/dist/apps/data/routes/fee-amm.js.map +1 -1
- package/dist/apps/data/routes/indexer.d.ts +34 -34
- package/dist/apps/data/routes/receipts.d.ts +230 -230
- package/dist/apps/data/routes/receipts.js +1 -1
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/rpc.js +24 -10
- package/dist/apps/data/routes/rpc.js.map +1 -1
- package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
- package/dist/apps/data/routes/tokenlist.js +16 -15
- package/dist/apps/data/routes/tokenlist.js.map +1 -1
- package/dist/apps/data/routes/tokens.d.ts +14 -0
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +34 -15
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.js +1 -1
- package/dist/apps/data/routes/transactions.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +7 -9
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/webhooks.d.ts +4 -4
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +2 -2
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/data/routes/zones.d.ts +30 -30
- package/dist/apps/funding/App.d.ts +27 -27
- package/dist/apps/funding/routes/chains.d.ts.map +1 -1
- package/dist/apps/funding/routes/chains.js +5 -4
- package/dist/apps/funding/routes/chains.js.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.d.ts +16 -16
- package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.js +8 -8
- package/dist/apps/funding/routes/deposit-addresses.js.map +1 -1
- package/dist/apps/funding/routes/providers.d.ts +13 -13
- package/dist/apps/funding/routes/providers.d.ts.map +1 -1
- package/dist/apps/funding/routes/providers.js +3 -2
- package/dist/apps/funding/routes/providers.js.map +1 -1
- package/dist/apps/funding/routes/quotes.d.ts.map +1 -1
- package/dist/apps/funding/routes/quotes.js +2 -2
- package/dist/apps/funding/routes/quotes.js.map +1 -1
- package/dist/apps/management/App.d.ts +627 -293
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/Billing.d.ts.map +1 -1
- package/dist/apps/management/Billing.js +19 -6
- package/dist/apps/management/Billing.js.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +114 -54
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +76 -30
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +103 -30
- package/dist/apps/management/routes/billing.d.ts.map +1 -1
- package/dist/apps/management/routes/billing.js +91 -32
- package/dist/apps/management/routes/billing.js.map +1 -1
- package/dist/apps/management/routes/faucet.d.ts +33 -33
- package/dist/apps/management/routes/faucet.d.ts.map +1 -1
- package/dist/apps/management/routes/faucet.js +23 -12
- package/dist/apps/management/routes/faucet.js.map +1 -1
- package/dist/apps/management/routes/invitations.d.ts +46 -13
- package/dist/apps/management/routes/invitations.d.ts.map +1 -1
- package/dist/apps/management/routes/invitations.js +79 -29
- package/dist/apps/management/routes/invitations.js.map +1 -1
- package/dist/apps/management/routes/invite-links.d.ts +86 -41
- package/dist/apps/management/routes/invite-links.d.ts.map +1 -1
- package/dist/apps/management/routes/invite-links.js +100 -41
- package/dist/apps/management/routes/invite-links.js.map +1 -1
- package/dist/apps/management/routes/me.d.ts +5 -5
- package/dist/apps/management/routes/me.d.ts.map +1 -1
- package/dist/apps/management/routes/me.js +14 -10
- package/dist/apps/management/routes/me.js.map +1 -1
- package/dist/apps/management/routes/members.d.ts +93 -72
- package/dist/apps/management/routes/members.d.ts.map +1 -1
- package/dist/apps/management/routes/members.js +37 -18
- package/dist/apps/management/routes/members.js.map +1 -1
- package/dist/apps/management/routes/orgs.d.ts +48 -8
- package/dist/apps/management/routes/orgs.d.ts.map +1 -1
- package/dist/apps/management/routes/orgs.js +48 -19
- package/dist/apps/management/routes/orgs.js.map +1 -1
- package/dist/apps/management/routes/projects.d.ts +90 -28
- package/dist/apps/management/routes/projects.d.ts.map +1 -1
- package/dist/apps/management/routes/projects.js +72 -21
- package/dist/apps/management/routes/projects.js.map +1 -1
- package/dist/apps/management/routes/scopes.d.ts.map +1 -1
- package/dist/apps/management/routes/scopes.js +8 -5
- package/dist/apps/management/routes/scopes.js.map +1 -1
- package/dist/apps/management/routes/usage.d.ts +78 -78
- package/dist/apps/management/routes/usage.d.ts.map +1 -1
- package/dist/apps/management/routes/usage.js +41 -31
- package/dist/apps/management/routes/usage.js.map +1 -1
- package/dist/apps/management/routes/verified-token-requests.d.ts +34 -6
- package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -1
- package/dist/apps/management/routes/verified-token-requests.js +36 -17
- package/dist/apps/management/routes/verified-token-requests.js.map +1 -1
- package/dist/apps/management/routes/webhooks.d.ts +147 -130
- package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/management/routes/webhooks.js +80 -35
- package/dist/apps/management/routes/webhooks.js.map +1 -1
- package/dist/apps/mpp/internal/Adapter.d.ts +1 -1
- package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -1
- package/dist/apps/mpp/internal/Adapter.js +12 -0
- package/dist/apps/mpp/internal/Adapter.js.map +1 -1
- package/dist/db/Db.d.ts +2 -0
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +40 -0
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +23 -1
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +19 -3
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/earnVaults.d.ts +5 -1
- package/dist/db/tables/earnVaults.d.ts.map +1 -1
- package/dist/db/tables/earnVaults.js +5 -0
- package/dist/db/tables/earnVaults.js.map +1 -1
- package/dist/db/tables/webhookDeliveries.d.ts.map +1 -1
- package/dist/db/tables/webhookDeliveries.js +10 -0
- package/dist/db/tables/webhookDeliveries.js.map +1 -1
- package/dist/db/tables/webhookQueueCompletions.d.ts +15 -0
- package/dist/db/tables/webhookQueueCompletions.d.ts.map +1 -0
- package/dist/db/tables/webhookQueueCompletions.js +32 -0
- package/dist/db/tables/webhookQueueCompletions.js.map +1 -0
- package/dist/db/tables/webhookQueueEvents.d.ts +14 -20
- package/dist/db/tables/webhookQueueEvents.d.ts.map +1 -1
- package/dist/db/tables/webhookQueueEvents.js +68 -47
- package/dist/db/tables/webhookQueueEvents.js.map +1 -1
- package/dist/db/tables/webhookSubscriptions.d.ts +16 -5
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
- package/dist/db/tables/webhookSubscriptions.js +29 -5
- package/dist/db/tables/webhookSubscriptions.js.map +1 -1
- package/dist/internal/Auth.d.ts +8 -1
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +13 -3
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/Cache.d.ts.map +1 -1
- package/dist/internal/Cache.js +11 -7
- package/dist/internal/Cache.js.map +1 -1
- package/dist/internal/EarnVaults.d.ts +41 -2
- package/dist/internal/EarnVaults.d.ts.map +1 -1
- package/dist/internal/EarnVaults.js +167 -0
- package/dist/internal/EarnVaults.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +26 -22
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +128 -39
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/Response.d.ts +13 -8
- package/dist/internal/Response.d.ts.map +1 -1
- package/dist/internal/Response.js +16 -5
- package/dist/internal/Response.js.map +1 -1
- package/dist/internal/Schema.d.ts +5 -7
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +6 -7
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/Store.d.ts +15 -6
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +45 -15
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/Tidx.d.ts +2 -0
- package/dist/internal/Tidx.d.ts.map +1 -1
- package/dist/internal/Tidx.js +16 -4
- package/dist/internal/Tidx.js.map +1 -1
- package/dist/internal/Webhooks.d.ts +29 -12
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +37 -20
- package/dist/internal/Webhooks.js.map +1 -1
- package/dist/internal/funding/Deposit.d.ts +2 -2
- package/dist/internal/funding/Deposit.d.ts.map +1 -1
- package/dist/internal/funding/Deposit.js +9 -8
- package/dist/internal/funding/Deposit.js.map +1 -1
- package/dist/internal/funding/DepositAddress.d.ts +4 -4
- package/dist/internal/funding/DepositAddress.d.ts.map +1 -1
- package/dist/internal/funding/DepositAddress.js +9 -8
- package/dist/internal/funding/DepositAddress.js.map +1 -1
- package/dist/internal/funding/Provider.d.ts.map +1 -1
- package/dist/internal/funding/Provider.js +13 -12
- package/dist/internal/funding/Provider.js.map +1 -1
- package/dist/internal/funding/providers/stargate.d.ts +19 -0
- package/dist/internal/funding/providers/stargate.d.ts.map +1 -0
- package/dist/internal/funding/providers/stargate.js +143 -0
- package/dist/internal/funding/providers/stargate.js.map +1 -0
- package/dist/providers/index.d.ts +7 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +3 -0
- package/dist/providers/index.js.map +1 -1
- package/package.json +2 -2
- package/src/App.test.ts +48 -0
- package/src/App.ts +4 -2
- package/src/Assets.test.ts +18 -0
- package/src/Assets.ts +22 -0
- package/src/Client.test-d.ts +265 -16
- package/src/admin/apps/earn-vaults.test.ts +143 -0
- package/src/admin/apps/earn-vaults.ts +83 -6
- package/src/admin/apps/organizations.ts +6 -2
- package/src/admin/ui/src/routes/api-keys.tsx +36 -0
- package/src/admin/ui.generated.ts +151 -189
- package/src/apps/data/App.test.ts +31 -0
- package/src/apps/data/App.ts +56 -8
- package/src/apps/data/ZoneSelection.test.ts +196 -0
- package/src/apps/data/ZoneSelection.ts +108 -0
- package/src/apps/data/routes/activities.test.ts +328 -1
- package/src/apps/data/routes/activities.ts +498 -93
- package/src/apps/data/routes/balances.ts +1 -1
- package/src/apps/data/routes/blocks.ts +1 -1
- package/src/apps/data/routes/earn.test.ts +183 -23
- package/src/apps/data/routes/earn.ts +225 -29
- package/src/apps/data/routes/earn.zone-access.test.ts +46 -0
- package/src/apps/data/routes/exchanges.test.ts +31 -1
- package/src/apps/data/routes/exchanges.ts +19 -15
- package/src/apps/data/routes/fee-amm.ts +18 -11
- package/src/apps/data/routes/receipts.ts +1 -1
- package/src/apps/data/routes/rpc.test.ts +75 -0
- package/src/apps/data/routes/rpc.ts +23 -9
- package/src/apps/data/routes/tokenlist.ts +21 -18
- package/src/apps/data/routes/tokens.test.ts +29 -0
- package/src/apps/data/routes/tokens.ts +38 -15
- package/src/apps/data/routes/transactions.ts +1 -1
- package/src/apps/data/routes/transfers.test.ts +3 -3
- package/src/apps/data/routes/transfers.ts +12 -9
- package/src/apps/data/routes/webhooks.ts +6 -2
- package/src/apps/data/routes/zones.test.ts +19 -13
- package/src/apps/funding/routes/chains.test.ts +211 -7
- package/src/apps/funding/routes/chains.ts +19 -12
- package/src/apps/funding/routes/deposit-addresses.test.ts +394 -0
- package/src/apps/funding/routes/deposit-addresses.ts +84 -72
- package/src/apps/funding/routes/providers.ts +9 -5
- package/src/apps/funding/routes/quotes.test.ts +46 -0
- package/src/apps/funding/routes/quotes.ts +8 -5
- package/src/apps/funding/routes/transfers.test.ts +35 -32
- package/src/apps/management/Billing.test.ts +26 -0
- package/src/apps/management/Billing.ts +24 -7
- package/src/apps/management/routes/api-keys.test.ts +178 -0
- package/src/apps/management/routes/api-keys.ts +203 -144
- package/src/apps/management/routes/billing.test.ts +209 -0
- package/src/apps/management/routes/billing.ts +254 -177
- package/src/apps/management/routes/faucet.test.ts +39 -0
- package/src/apps/management/routes/faucet.ts +75 -41
- package/src/apps/management/routes/invitations.test.ts +216 -0
- package/src/apps/management/routes/invitations.ts +186 -109
- package/src/apps/management/routes/invite-links.test.ts +263 -1
- package/src/apps/management/routes/invite-links.ts +295 -214
- package/src/apps/management/routes/me.test.ts +49 -0
- package/src/apps/management/routes/me.ts +42 -32
- package/src/apps/management/routes/members.test.ts +124 -1
- package/src/apps/management/routes/members.ts +81 -51
- package/src/apps/management/routes/orgs.test.ts +176 -0
- package/src/apps/management/routes/orgs.ts +101 -59
- package/src/apps/management/routes/projects.test.ts +183 -0
- package/src/apps/management/routes/projects.ts +124 -60
- package/src/apps/management/routes/scopes.test.ts +44 -0
- package/src/apps/management/routes/scopes.ts +37 -28
- package/src/apps/management/routes/usage.test.ts +92 -0
- package/src/apps/management/routes/usage.ts +186 -151
- package/src/apps/management/routes/verified-token-requests.test.ts +114 -0
- package/src/apps/management/routes/verified-token-requests.ts +166 -133
- package/src/apps/management/routes/webhooks.test.ts +234 -0
- package/src/apps/management/routes/webhooks.ts +191 -78
- package/src/apps/mpp/internal/Adapter.ts +13 -1
- package/src/db/Db.test.ts +41 -0
- package/src/db/Db.ts +62 -0
- package/src/db/Schema.ts +28 -3
- package/src/db/tables/earnVaults.test.ts +22 -0
- package/src/db/tables/earnVaults.ts +11 -1
- package/src/db/tables/webhookDeliveries.ts +13 -0
- package/src/db/tables/webhookQueueCompletions.ts +55 -0
- package/src/db/tables/webhookQueueEvents.ts +95 -61
- package/src/db/tables/webhookSubscriptions.ts +45 -6
- package/src/internal/Auth.ts +23 -5
- package/src/internal/Cache.ts +14 -7
- package/src/internal/EarnVaults.capabilities.test.ts +33 -0
- package/src/internal/EarnVaults.test.ts +79 -0
- package/src/internal/EarnVaults.ts +277 -0
- package/src/internal/OpenApi.ts +165 -49
- package/src/internal/Response.test.ts +95 -0
- package/src/internal/Response.ts +40 -2
- package/src/internal/Schema.test.ts +16 -0
- package/src/internal/Schema.ts +7 -7
- package/src/internal/Store.test.ts +186 -0
- package/src/internal/Store.ts +57 -17
- package/src/internal/Tidx.test.ts +19 -0
- package/src/internal/Tidx.ts +16 -4
- package/src/internal/Webhooks.test.ts +122 -8
- package/src/internal/Webhooks.ts +59 -29
- package/src/internal/funding/Deposit.ts +71 -64
- package/src/internal/funding/DepositAddress.ts +50 -43
- package/src/internal/funding/Provider.ts +164 -142
- package/src/internal/funding/providers/index.test.ts +185 -0
- package/src/internal/funding/providers/stargate.ts +184 -0
- package/src/providers/index.test.ts +1 -0
- package/src/providers/index.ts +9 -0
|
@@ -18,7 +18,26 @@ const redactedSlackUrl = 'https://hooks.slack.com/…'
|
|
|
18
18
|
/** OpenAPI schemas owned by console webhook management. */
|
|
19
19
|
export namespace schema {
|
|
20
20
|
/** Public webhook subscription representation. */
|
|
21
|
-
export const Subscription =
|
|
21
|
+
export const Subscription = OpenApi.component(
|
|
22
|
+
z
|
|
23
|
+
.object({
|
|
24
|
+
...webhookSchema.Subscription.shape,
|
|
25
|
+
context: webhookSchema.Subscription.shape.context.check(
|
|
26
|
+
z.meta({ examples: [{ title: 'Production transfers' }] }),
|
|
27
|
+
),
|
|
28
|
+
destination: webhookSchema.Subscription.shape.destination.check(
|
|
29
|
+
z.meta({ examples: [{ type: 'url', url: 'https://example.com/webhooks' }] }),
|
|
30
|
+
),
|
|
31
|
+
})
|
|
32
|
+
.check(z.describe('An organization webhook subscription.')),
|
|
33
|
+
'OrganizationWebhook',
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
/** Webhook delivery data returned in collection rows. */
|
|
37
|
+
export const Delivery = OpenApi.component(
|
|
38
|
+
webhookSchema.Delivery,
|
|
39
|
+
'OrganizationWebhookDeliverySummary',
|
|
40
|
+
)
|
|
22
41
|
|
|
23
42
|
/** Schemas for creating an organization webhook. */
|
|
24
43
|
export namespace createWebhook {
|
|
@@ -30,61 +49,119 @@ export namespace schema {
|
|
|
30
49
|
)
|
|
31
50
|
|
|
32
51
|
/** Organization webhook creation requires an explicit network. */
|
|
33
|
-
export const Body =
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
(
|
|
44
|
-
|
|
52
|
+
export const Body = OpenApi.component(
|
|
53
|
+
z
|
|
54
|
+
.intersection(
|
|
55
|
+
webhookSchema.createWebhook.Body,
|
|
56
|
+
z.object({
|
|
57
|
+
chainId: webhookSchema.Subscription.shape.chainId,
|
|
58
|
+
environment: z.optional(Environment),
|
|
59
|
+
}),
|
|
60
|
+
)
|
|
61
|
+
.check(
|
|
62
|
+
z.refine(
|
|
63
|
+
(body) =>
|
|
64
|
+
body.eventType !== 'funding:deposit.updated' || body.environment !== undefined,
|
|
65
|
+
{ error: '`environment` is required for funding deposit subscriptions.' },
|
|
66
|
+
),
|
|
67
|
+
z.describe('Details for creating an organization webhook subscription.'),
|
|
45
68
|
),
|
|
46
|
-
|
|
47
|
-
|
|
69
|
+
'CreateOrganizationWebhookRequest',
|
|
70
|
+
)
|
|
48
71
|
|
|
49
72
|
const secret = webhookSchema.createWebhook.Response.shape.secret
|
|
50
|
-
const urlDestination = z
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
const urlDestination = z
|
|
74
|
+
.object({
|
|
75
|
+
type: z
|
|
76
|
+
.literal('url')
|
|
77
|
+
.check(z.describe('HTTPS destination.'), z.meta({ examples: ['url'] })),
|
|
78
|
+
url: z
|
|
79
|
+
.url()
|
|
80
|
+
.check(
|
|
81
|
+
z.describe('Your HTTPS endpoint where Tempo sends signed event POSTs.'),
|
|
82
|
+
z.meta({ examples: ['https://example.com/webhooks'] }),
|
|
83
|
+
),
|
|
84
|
+
})
|
|
85
|
+
.check(
|
|
86
|
+
z.describe('HTTPS webhook destination.'),
|
|
87
|
+
z.meta({ examples: [{ type: 'url', url: 'https://example.com/webhooks' }] }),
|
|
88
|
+
)
|
|
89
|
+
const slackDestination = z
|
|
90
|
+
.object({
|
|
91
|
+
type: z
|
|
92
|
+
.literal('slack')
|
|
93
|
+
.check(z.describe('Slack destination.'), z.meta({ examples: ['slack'] })),
|
|
94
|
+
url: z
|
|
95
|
+
.literal(redactedSlackUrl)
|
|
96
|
+
.check(
|
|
97
|
+
z.describe('Redacted Slack webhook URL.'),
|
|
98
|
+
z.meta({ examples: [redactedSlackUrl] }),
|
|
99
|
+
),
|
|
100
|
+
})
|
|
101
|
+
.check(
|
|
102
|
+
z.describe('Slack webhook destination with its URL redacted.'),
|
|
103
|
+
z.meta({ examples: [{ type: 'slack', url: redactedSlackUrl }] }),
|
|
104
|
+
)
|
|
105
|
+
const betterstackDestination = z
|
|
106
|
+
.object({
|
|
107
|
+
token: z
|
|
108
|
+
.literal(redactedBetterstackToken)
|
|
109
|
+
.check(
|
|
110
|
+
z.describe('Redacted Better Stack source token.'),
|
|
111
|
+
z.meta({ examples: [redactedBetterstackToken] }),
|
|
112
|
+
),
|
|
113
|
+
type: z
|
|
114
|
+
.literal('betterstack')
|
|
115
|
+
.check(z.describe('Better Stack destination.'), z.meta({ examples: ['betterstack'] })),
|
|
116
|
+
url: z
|
|
117
|
+
.url()
|
|
118
|
+
.check(
|
|
119
|
+
z.describe('Your Better Stack source ingest host URL.'),
|
|
120
|
+
z.meta({ examples: ['https://s1234567.eu-nbg-2.betterstackdata.com'] }),
|
|
121
|
+
),
|
|
122
|
+
})
|
|
123
|
+
.check(
|
|
124
|
+
z.describe('Better Stack destination with its token redacted.'),
|
|
125
|
+
z.meta({
|
|
126
|
+
examples: [
|
|
127
|
+
{
|
|
128
|
+
token: redactedBetterstackToken,
|
|
129
|
+
type: 'betterstack',
|
|
130
|
+
url: 'https://s1234567.eu-nbg-2.betterstackdata.com',
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
}),
|
|
134
|
+
)
|
|
135
|
+
const UrlResponse = OpenApi.component(
|
|
136
|
+
z
|
|
137
|
+
.object({ ...Subscription.shape, destination: urlDestination, secret })
|
|
138
|
+
.check(z.describe('Created HTTPS webhook with its one-time signing secret.')),
|
|
139
|
+
'CreateOrganizationWebhookUrlResponse',
|
|
140
|
+
)
|
|
141
|
+
const SlackResponse = OpenApi.component(
|
|
142
|
+
z
|
|
143
|
+
.object({ ...Subscription.shape, destination: slackDestination })
|
|
144
|
+
.check(z.describe('Created Slack webhook with its destination redacted.')),
|
|
145
|
+
'CreateOrganizationWebhookSlackResponse',
|
|
146
|
+
)
|
|
147
|
+
const BetterstackResponse = OpenApi.component(
|
|
148
|
+
z
|
|
149
|
+
.object({ ...Subscription.shape, destination: betterstackDestination })
|
|
150
|
+
.check(z.describe('Created Better Stack webhook with its credentials redacted.')),
|
|
151
|
+
'CreateOrganizationWebhookBetterstackResponse',
|
|
152
|
+
)
|
|
75
153
|
|
|
76
154
|
/** Created webhook with transport credentials redacted. */
|
|
77
|
-
export const Response =
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
z.describe(
|
|
85
|
-
'The new webhook subscription. HTTPS endpoints include their one-time signing secret.',
|
|
155
|
+
export const Response = OpenApi.component(
|
|
156
|
+
z
|
|
157
|
+
.union([UrlResponse, SlackResponse, BetterstackResponse])
|
|
158
|
+
.check(
|
|
159
|
+
z.describe(
|
|
160
|
+
'The new webhook subscription. HTTPS endpoints include their one-time signing secret.',
|
|
161
|
+
),
|
|
86
162
|
),
|
|
87
|
-
|
|
163
|
+
'CreateOrganizationWebhookResponse',
|
|
164
|
+
)
|
|
88
165
|
}
|
|
89
166
|
|
|
90
167
|
/** Organization webhook collection parameters. */
|
|
@@ -116,7 +193,23 @@ export namespace schema {
|
|
|
116
193
|
export namespace listWebhookDeliveries {
|
|
117
194
|
export const Params = WebhookParams
|
|
118
195
|
export const Query = webhookSchema.listWebhookDeliveries.Query
|
|
119
|
-
export const Response =
|
|
196
|
+
export const Response = OpenApi.component(
|
|
197
|
+
z
|
|
198
|
+
.object({
|
|
199
|
+
data: z
|
|
200
|
+
.array(Delivery)
|
|
201
|
+
.check(
|
|
202
|
+
z.describe('Webhook delivery attempts on this page.'),
|
|
203
|
+
z.meta({ examples: [[]] }),
|
|
204
|
+
),
|
|
205
|
+
meta: webhookSchema.listWebhookDeliveries.Response.shape.meta.check(
|
|
206
|
+
z.meta({ examples: [{ totalCount: 1, totalCountCapped: false }] }),
|
|
207
|
+
),
|
|
208
|
+
nextCursor: webhookSchema.listWebhookDeliveries.Response.shape.nextCursor,
|
|
209
|
+
})
|
|
210
|
+
.check(z.describe("A page of an organization's webhook delivery attempts.")),
|
|
211
|
+
'OrganizationWebhookDeliveryList',
|
|
212
|
+
)
|
|
120
213
|
}
|
|
121
214
|
|
|
122
215
|
const DeliveryParams = z
|
|
@@ -130,43 +223,63 @@ export namespace schema {
|
|
|
130
223
|
/** Schemas for loading one organization webhook delivery. */
|
|
131
224
|
export namespace getWebhookDelivery {
|
|
132
225
|
export const Params = DeliveryParams
|
|
133
|
-
export const Response =
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
226
|
+
export const Response = OpenApi.component(
|
|
227
|
+
z
|
|
228
|
+
.object({
|
|
229
|
+
...Delivery.shape,
|
|
230
|
+
envelope: webhookSchema.Envelope,
|
|
231
|
+
})
|
|
232
|
+
.check(z.describe('A webhook delivery attempt with the exact JSON payload Tempo sent.')),
|
|
233
|
+
'OrganizationWebhookDelivery',
|
|
234
|
+
)
|
|
139
235
|
}
|
|
140
236
|
|
|
141
237
|
/** Schemas for replaying one organization webhook delivery. */
|
|
142
238
|
export namespace retryWebhookDelivery {
|
|
143
239
|
export const Params = DeliveryParams
|
|
144
|
-
export const Response =
|
|
240
|
+
export const Response = OpenApi.component(
|
|
241
|
+
webhookSchema.retryWebhookDelivery.Response,
|
|
242
|
+
'RetryOrganizationWebhookDeliveryResponse',
|
|
243
|
+
)
|
|
145
244
|
}
|
|
146
245
|
|
|
147
246
|
/** Non-paginated organization webhook list. */
|
|
148
|
-
export const ListResponse =
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
247
|
+
export const ListResponse = OpenApi.component(
|
|
248
|
+
z
|
|
249
|
+
.object({
|
|
250
|
+
data: z
|
|
251
|
+
.array(Subscription)
|
|
252
|
+
.check(
|
|
253
|
+
z.describe("The organization's webhooks, newest first."),
|
|
254
|
+
z.meta({ examples: [[]] }),
|
|
255
|
+
),
|
|
256
|
+
})
|
|
257
|
+
.check(z.describe("An organization's webhook subscriptions.")),
|
|
258
|
+
'OrganizationWebhookList',
|
|
259
|
+
)
|
|
153
260
|
|
|
154
261
|
/** Lifecycle state editable from the console. */
|
|
155
|
-
export const UpdateBody =
|
|
156
|
-
|
|
157
|
-
|
|
262
|
+
export const UpdateBody = OpenApi.component(
|
|
263
|
+
z
|
|
264
|
+
.object({ status: webhookSchema.Status })
|
|
265
|
+
.check(z.describe('New delivery state for a webhook subscription.')),
|
|
266
|
+
'UpdateOrganizationWebhookRequest',
|
|
267
|
+
)
|
|
158
268
|
|
|
159
269
|
/** Webhook deletion confirmation. */
|
|
160
|
-
export const DeleteResponse =
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
270
|
+
export const DeleteResponse = OpenApi.component(
|
|
271
|
+
z
|
|
272
|
+
.object({
|
|
273
|
+
id: z
|
|
274
|
+
.string()
|
|
275
|
+
.check(
|
|
276
|
+
z.describe('Deleted webhook subscription id.'),
|
|
277
|
+
z.meta({ examples: ['wh_001718668800000_2ZPE2gvateYEQ0dQslgvkhjx'] }),
|
|
278
|
+
),
|
|
279
|
+
})
|
|
280
|
+
.check(z.describe('Confirmation that a webhook subscription was deleted.')),
|
|
281
|
+
'DeleteOrganizationWebhookResponse',
|
|
282
|
+
)
|
|
170
283
|
}
|
|
171
284
|
|
|
172
285
|
const bodyValidation = {
|
|
@@ -542,7 +655,7 @@ export function webhooks(options: webhooks.Options = {}) {
|
|
|
542
655
|
},
|
|
543
656
|
success: {
|
|
544
657
|
description: 'Updated webhook.',
|
|
545
|
-
schema:
|
|
658
|
+
schema: schema.Subscription,
|
|
546
659
|
},
|
|
547
660
|
}),
|
|
548
661
|
summary: 'Update webhook',
|
|
@@ -564,7 +677,7 @@ export function webhooks(options: webhooks.Options = {}) {
|
|
|
564
677
|
)
|
|
565
678
|
if (!subscription) return notFound(c)
|
|
566
679
|
return c.json(
|
|
567
|
-
Response.validated(
|
|
680
|
+
Response.validated(schema.Subscription, publicSubscription(subscription)),
|
|
568
681
|
200,
|
|
569
682
|
)
|
|
570
683
|
} catch (cause) {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as Mppx from 'mppx'
|
|
2
2
|
import { tempo } from 'mppx/server'
|
|
3
|
+
import { maxUint256 } from 'viem'
|
|
3
4
|
import type { LocalAccount } from 'viem/accounts'
|
|
4
5
|
|
|
5
|
-
import type * as Viem from '../../../internal/Viem.js'
|
|
6
6
|
import * as Store from '../../../internal/Store.js'
|
|
7
|
+
import * as Viem from '../../../internal/Viem.js'
|
|
7
8
|
import * as Mpp from '../Mpp.js'
|
|
8
9
|
import * as MppError from './Error.js'
|
|
9
10
|
import * as Screening from './Screening.js'
|
|
@@ -37,9 +38,20 @@ export function create(options: create.Options): Adapter {
|
|
|
37
38
|
store: screeningStore,
|
|
38
39
|
ttl: screeningTtl,
|
|
39
40
|
})
|
|
41
|
+
// Moderato fees exceed MPPX defaults; preserve its gas cap and bound each
|
|
42
|
+
// sponsored transaction to $1.
|
|
43
|
+
const feePayerPolicy =
|
|
44
|
+
chainId === Viem.chainId.testnet
|
|
45
|
+
? {
|
|
46
|
+
maxFeePerGas: maxUint256,
|
|
47
|
+
maxPriorityFeePerGas: maxUint256,
|
|
48
|
+
maxTotalFee: 1_000_000_000_000_000_000n,
|
|
49
|
+
}
|
|
50
|
+
: undefined
|
|
40
51
|
const methods = [
|
|
41
52
|
tempo.charge({
|
|
42
53
|
...(feePayer ? { feePayer } : {}),
|
|
54
|
+
...(feePayerPolicy ? { feePayerPolicy } : {}),
|
|
43
55
|
getClient: ({ chainId: chainId_option }) =>
|
|
44
56
|
getClient(chainId_option as Viem.ChainId | undefined),
|
|
45
57
|
store: Utils.mppxStore(state),
|
package/src/db/Db.test.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { nanoid } from 'nanoid'
|
|
|
3
3
|
|
|
4
4
|
import * as Runtime from '../../test/runtime.js'
|
|
5
5
|
import * as Db from './Db.js'
|
|
6
|
+
import * as Webhooks from '../internal/Webhooks.js'
|
|
6
7
|
import * as Invitations from './tables/invitations.js'
|
|
7
8
|
import * as Organizations from './tables/organizations.js'
|
|
8
9
|
import * as WebhookSubscriptions from './tables/webhookSubscriptions.js'
|
|
@@ -35,6 +36,46 @@ describe('postgres', () => {
|
|
|
35
36
|
await db.close()
|
|
36
37
|
})
|
|
37
38
|
|
|
39
|
+
test('behavior: raw webhook staging respects schema scoping', async () => {
|
|
40
|
+
// Exercises the one raw statement against a schema-scoped db whose only
|
|
41
|
+
// qualification is WithSchemaPlugin, matching preview Workers: migrate on
|
|
42
|
+
// one pool (whose session gains a search_path), then query from a fresh
|
|
43
|
+
// pool that never ran it.
|
|
44
|
+
const schema = `t_${nanoid()}`
|
|
45
|
+
const migrator = Db.postgres({ connectionString: Runtime.postgresUrl, schema })
|
|
46
|
+
await migrator.migrate()
|
|
47
|
+
await migrator.close()
|
|
48
|
+
const db = Db.postgres({ connectionString: Runtime.postgresUrl, schema })
|
|
49
|
+
const subscription = await Webhooks.createSubscription(db, {
|
|
50
|
+
chainId: 4217,
|
|
51
|
+
destination: { type: 'url', url: 'https://hooks.example.com/endpoint' },
|
|
52
|
+
eventType: 'token:transfer',
|
|
53
|
+
owner: { orgId: 'org_1', type: 'api_key' },
|
|
54
|
+
})
|
|
55
|
+
const envelope = Webhooks.buildEnvelope({
|
|
56
|
+
blockNumber: 123,
|
|
57
|
+
createdAt: new Date(),
|
|
58
|
+
data: { amount: '1' },
|
|
59
|
+
logIndex: 4,
|
|
60
|
+
subscription,
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const staged = await Webhooks.ensureQueueEvents(db, [{ envelope, subscription }])
|
|
64
|
+
expect(staged.created).toBe(1)
|
|
65
|
+
const claim = await Webhooks.claimQueueEvent(db, staged.references[0]!)
|
|
66
|
+
if (claim.type !== 'claimed') throw new Error(`Unexpected claim: ${claim.type}`)
|
|
67
|
+
await Webhooks.completeQueueEvent(db, staged.references[0]!, {
|
|
68
|
+
claimedAt: claim.record.attemptingAt!,
|
|
69
|
+
status: 'succeeded',
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
// The completion read inside the same raw statement must also resolve
|
|
73
|
+
// inside the schema for the replay to be suppressed.
|
|
74
|
+
const replay = await Webhooks.ensureQueueEvents(db, [{ envelope, subscription }])
|
|
75
|
+
expect(replay.created).toBe(0)
|
|
76
|
+
await db.close()
|
|
77
|
+
})
|
|
78
|
+
|
|
38
79
|
test('behavior: creates a Postgres db without schema scoping', async () => {
|
|
39
80
|
const db = Db.postgres({ connectionString: Runtime.postgresUrl })
|
|
40
81
|
await db.close()
|
package/src/db/Db.ts
CHANGED
|
@@ -36,6 +36,7 @@ import type * as Users from './tables/users.js'
|
|
|
36
36
|
import type * as VerifiedTokenRequests from './tables/verifiedTokenRequests.js'
|
|
37
37
|
import type * as VerifiedTokens from './tables/verifiedTokens.js'
|
|
38
38
|
import type * as WebhookDeliveries from './tables/webhookDeliveries.js'
|
|
39
|
+
import type * as WebhookQueueCompletions from './tables/webhookQueueCompletions.js'
|
|
39
40
|
import type * as WebhookQueueEvents from './tables/webhookQueueEvents.js'
|
|
40
41
|
import type * as WebhookSubscriptions from './tables/webhookSubscriptions.js'
|
|
41
42
|
|
|
@@ -83,6 +84,7 @@ export type Database = {
|
|
|
83
84
|
verified_token_requests: VerifiedTokenRequests.Table
|
|
84
85
|
verified_tokens: VerifiedTokens.Table
|
|
85
86
|
webhook_deliveries: WebhookDeliveries.Table
|
|
87
|
+
webhook_queue_completions: WebhookQueueCompletions.Table
|
|
86
88
|
webhook_queue_events: WebhookQueueEvents.Table
|
|
87
89
|
webhook_subscriptions: WebhookSubscriptions.Table
|
|
88
90
|
}
|
|
@@ -1421,6 +1423,66 @@ export const migrations: readonly Migration[] = [
|
|
|
1421
1423
|
up: (db) =>
|
|
1422
1424
|
raw(db, sql`ALTER TABLE webhook_queue_events ADD COLUMN IF NOT EXISTS observed_at text`),
|
|
1423
1425
|
},
|
|
1426
|
+
{
|
|
1427
|
+
name: '0131_webhook_queue_completions',
|
|
1428
|
+
up: (db) =>
|
|
1429
|
+
db.schema
|
|
1430
|
+
.createTable('webhookQueueCompletions')
|
|
1431
|
+
.ifNotExists()
|
|
1432
|
+
.addColumn('subscriptionId', 'text', (c) =>
|
|
1433
|
+
c.notNull().references('webhookSubscriptions.id').onDelete('cascade'),
|
|
1434
|
+
)
|
|
1435
|
+
.addColumn('eventId', 'text', (c) => c.notNull())
|
|
1436
|
+
.addColumn('status', 'text', (c) => c.notNull())
|
|
1437
|
+
.addColumn('expiresAt', 'text', (c) => c.notNull())
|
|
1438
|
+
.addPrimaryKeyConstraint('webhook_queue_completions_pkey', ['subscriptionId', 'eventId'])
|
|
1439
|
+
.addCheckConstraint(
|
|
1440
|
+
'webhook_queue_completions_status_check',
|
|
1441
|
+
sql`status IN ('failed', 'skipped', 'succeeded')`,
|
|
1442
|
+
),
|
|
1443
|
+
},
|
|
1444
|
+
{
|
|
1445
|
+
name: '0132_webhook_queue_completions_expires_index',
|
|
1446
|
+
up: (db) =>
|
|
1447
|
+
db.schema
|
|
1448
|
+
.createIndex('webhook_queue_completions_expires_idx')
|
|
1449
|
+
.ifNotExists()
|
|
1450
|
+
.on('webhookQueueCompletions')
|
|
1451
|
+
.column('expiresAt'),
|
|
1452
|
+
},
|
|
1453
|
+
{
|
|
1454
|
+
// Stock thresholds let ~2M dead tuples accumulate before vacuuming, then
|
|
1455
|
+
// grind gigabytes at once; frequent small vacuums keep indexes usable.
|
|
1456
|
+
name: '0133_webhook_queue_events_autovacuum',
|
|
1457
|
+
up: (db) =>
|
|
1458
|
+
raw(
|
|
1459
|
+
db,
|
|
1460
|
+
sql`ALTER TABLE webhook_queue_events SET (autovacuum_vacuum_scale_factor = 0.01, autovacuum_vacuum_cost_limit = 2000)`,
|
|
1461
|
+
),
|
|
1462
|
+
},
|
|
1463
|
+
{
|
|
1464
|
+
// New code stops writing queue-event expiry: completions own the dedupe
|
|
1465
|
+
// window, so the column is nullable and inert.
|
|
1466
|
+
name: '0134_webhook_queue_events_expires_nullable',
|
|
1467
|
+
up: (db) =>
|
|
1468
|
+
raw(db, sql`ALTER TABLE webhook_queue_events ALTER COLUMN expires_at DROP NOT NULL`),
|
|
1469
|
+
},
|
|
1470
|
+
{
|
|
1471
|
+
name: '0135_webhook_queue_completions_autovacuum',
|
|
1472
|
+
up: (db) =>
|
|
1473
|
+
raw(
|
|
1474
|
+
db,
|
|
1475
|
+
sql`ALTER TABLE webhook_queue_completions SET (autovacuum_vacuum_scale_factor = 0.01, autovacuum_vacuum_cost_limit = 2000)`,
|
|
1476
|
+
),
|
|
1477
|
+
},
|
|
1478
|
+
{
|
|
1479
|
+
name: '0136_earn_vault_zones',
|
|
1480
|
+
up: (db) =>
|
|
1481
|
+
raw(
|
|
1482
|
+
db,
|
|
1483
|
+
sql`ALTER TABLE earn_vaults ADD COLUMN IF NOT EXISTS zones jsonb NOT NULL DEFAULT '[]'::jsonb`,
|
|
1484
|
+
),
|
|
1485
|
+
},
|
|
1424
1486
|
]
|
|
1425
1487
|
|
|
1426
1488
|
/**
|
package/src/db/Schema.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as z from 'zod/mini'
|
|
2
2
|
import type { Address } from 'viem'
|
|
3
3
|
|
|
4
|
+
import type * as EarnVaults from '../internal/EarnVaults.js'
|
|
4
5
|
import type * as funding_Catalog from '../internal/funding/Catalog.js'
|
|
5
6
|
import type * as funding_Deposit from '../internal/funding/Deposit.js'
|
|
6
7
|
import type * as funding_DepositAddress from '../internal/funding/DepositAddress.js'
|
|
@@ -106,6 +107,9 @@ export const EarnVault = z
|
|
|
106
107
|
slug: z.string().check(z.describe('Stable URL slug assigned when the vault is registered.')),
|
|
107
108
|
updatedAt: z.string().check(z.describe('When the vault registration last changed (ISO 8601).')),
|
|
108
109
|
vaultAddress: z.custom<Address>().check(z.describe('Earn vault address (lowercase).')),
|
|
110
|
+
zones: z
|
|
111
|
+
.custom<readonly EarnVaults.ZoneRoute[]>()
|
|
112
|
+
.check(z.describe('Curated private Zone routes (`jsonb`).')),
|
|
109
113
|
})
|
|
110
114
|
.check(z.describe('One curated Earn vault row.'))
|
|
111
115
|
|
|
@@ -881,6 +885,23 @@ export const WebhookDelivery = z.object({
|
|
|
881
885
|
/** Columns of the `webhook_deliveries` table. */
|
|
882
886
|
export type WebhookDelivery = z.output<typeof WebhookDelivery>
|
|
883
887
|
|
|
888
|
+
/** An insert-only dedupe record marking a delivery obligation terminal. */
|
|
889
|
+
export const WebhookQueueCompletion = z.object({
|
|
890
|
+
eventId: z.string().check(z.describe('Idempotent event id (`evt_...`).')),
|
|
891
|
+
expiresAt: z
|
|
892
|
+
.string()
|
|
893
|
+
.check(z.describe('ISO dedupe retention deadline; rows past it are invisible and pruned.')),
|
|
894
|
+
status: z
|
|
895
|
+
.enum(['failed', 'skipped', 'succeeded'])
|
|
896
|
+
.check(z.describe('Terminal delivery-obligation outcome.')),
|
|
897
|
+
subscriptionId: z
|
|
898
|
+
.string()
|
|
899
|
+
.check(z.describe('Owning subscription id (`wh_...`); FK with `ON DELETE CASCADE`.')),
|
|
900
|
+
})
|
|
901
|
+
|
|
902
|
+
/** Columns of the `webhook_queue_completions` table. */
|
|
903
|
+
export type WebhookQueueCompletion = z.output<typeof WebhookQueueCompletion>
|
|
904
|
+
|
|
884
905
|
/** A durable webhook envelope staged before its compact Queue reference is admitted. */
|
|
885
906
|
export const WebhookQueueEvent = z.object({
|
|
886
907
|
attemptCount: z.number().check(z.describe('Delivery attempts claimed so far.')),
|
|
@@ -893,10 +914,10 @@ export const WebhookQueueEvent = z.object({
|
|
|
893
914
|
.check(z.describe('The full webhook envelope retained outside Cloudflare Queues.')),
|
|
894
915
|
eventId: z.string().check(z.describe('Idempotent event id (`evt_...`).')),
|
|
895
916
|
expiresAt: z
|
|
896
|
-
.string()
|
|
917
|
+
.nullable(z.string())
|
|
897
918
|
.check(
|
|
898
919
|
z.describe(
|
|
899
|
-
'
|
|
920
|
+
'Unwritten since completions took over dedupe; non-null only on rows staged before the split.',
|
|
900
921
|
),
|
|
901
922
|
),
|
|
902
923
|
nextAttemptAt: z
|
|
@@ -911,7 +932,11 @@ export const WebhookQueueEvent = z.object({
|
|
|
911
932
|
),
|
|
912
933
|
status: z
|
|
913
934
|
.enum(['failed', 'pending', 'skipped', 'succeeded'])
|
|
914
|
-
.check(
|
|
935
|
+
.check(
|
|
936
|
+
z.describe(
|
|
937
|
+
'Always `pending` since completions took over terminal state; other values occur only on rows completed before the split.',
|
|
938
|
+
),
|
|
939
|
+
),
|
|
915
940
|
subscriptionId: z
|
|
916
941
|
.string()
|
|
917
942
|
.check(z.describe('Owning subscription id (`wh_...`); FK with `ON DELETE CASCADE`.')),
|
|
@@ -11,6 +11,13 @@ const input = {
|
|
|
11
11
|
],
|
|
12
12
|
privateOutputTokens: ['0x20c00000000000000000000057F242B21a53ae4D'],
|
|
13
13
|
vaultAddress: '0x2f05f4d3625B2eFFb383eFbEDAFd2D8F04371636',
|
|
14
|
+
zones: [
|
|
15
|
+
{
|
|
16
|
+
chainId: 1_424_310_001,
|
|
17
|
+
deploymentBlock: 31_039_238,
|
|
18
|
+
earnRouter: '0x9144086A79dea966d8bf1B52125eBED8919fC45c',
|
|
19
|
+
},
|
|
20
|
+
],
|
|
14
21
|
} as const satisfies EarnVaults.upsert.Options
|
|
15
22
|
|
|
16
23
|
describe('upsert', () => {
|
|
@@ -36,6 +43,13 @@ describe('upsert', () => {
|
|
|
36
43
|
],
|
|
37
44
|
"updatedAt": "2026-01-01T00:00:00.000Z",
|
|
38
45
|
"vaultAddress": "0x2f05f4d3625b2effb383efbedafd2d8f04371636",
|
|
46
|
+
"zones": [
|
|
47
|
+
{
|
|
48
|
+
"chainId": 1424310001,
|
|
49
|
+
"deploymentBlock": 31039238,
|
|
50
|
+
"earnRouter": "0x9144086a79dea966d8bf1b52125ebed8919fc45c",
|
|
51
|
+
},
|
|
52
|
+
],
|
|
39
53
|
}
|
|
40
54
|
`)
|
|
41
55
|
} finally {
|
|
@@ -68,6 +82,7 @@ describe('upsert', () => {
|
|
|
68
82
|
privateInputTokens: stored.privateInputTokens,
|
|
69
83
|
privateOutputTokens: stored.privateOutputTokens,
|
|
70
84
|
updatedAt: stored.updatedAt,
|
|
85
|
+
zones: stored.zones,
|
|
71
86
|
}).toMatchInlineSnapshot(`
|
|
72
87
|
{
|
|
73
88
|
"createdAt": "2026-01-01T00:00:00.000Z",
|
|
@@ -76,6 +91,13 @@ describe('upsert', () => {
|
|
|
76
91
|
"privateInputTokens": [],
|
|
77
92
|
"privateOutputTokens": [],
|
|
78
93
|
"updatedAt": "2026-01-02T00:00:00.000Z",
|
|
94
|
+
"zones": [
|
|
95
|
+
{
|
|
96
|
+
"chainId": 1424310001,
|
|
97
|
+
"deploymentBlock": 31039238,
|
|
98
|
+
"earnRouter": "0x9144086a79dea966d8bf1b52125ebed8919fc45c",
|
|
99
|
+
},
|
|
100
|
+
],
|
|
79
101
|
}
|
|
80
102
|
`)
|
|
81
103
|
|
|
@@ -10,7 +10,7 @@ const slugSuffix = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 8)
|
|
|
10
10
|
/** Columns of the `earn_vaults` table. */
|
|
11
11
|
export type Table = Omit<
|
|
12
12
|
db_Schema.EarnVault,
|
|
13
|
-
'chainId' | 'privateInputTokens' | 'privateOutputTokens'
|
|
13
|
+
'chainId' | 'privateInputTokens' | 'privateOutputTokens' | 'zones'
|
|
14
14
|
> & {
|
|
15
15
|
/** Bigint chain id, read as a string from pg and written as a number. */
|
|
16
16
|
chainId: ColumnType<string, number, number>
|
|
@@ -18,6 +18,8 @@ export type Table = Omit<
|
|
|
18
18
|
privateInputTokens: JSONColumnType<db_Schema.EarnVault['privateInputTokens'], string, string>
|
|
19
19
|
/** Tokens supported for private redemptions. */
|
|
20
20
|
privateOutputTokens: JSONColumnType<db_Schema.EarnVault['privateOutputTokens'], string, string>
|
|
21
|
+
/** Curated private Zone routes. */
|
|
22
|
+
zones: JSONColumnType<db_Schema.EarnVault['zones'], string, string>
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
/** A stored curated Earn vault. */
|
|
@@ -76,6 +78,7 @@ export async function upsert(db: Db.Db, options: upsert.Options): Promise<Record
|
|
|
76
78
|
slug,
|
|
77
79
|
updatedAt: now,
|
|
78
80
|
vaultAddress: normalize(options.vaultAddress),
|
|
81
|
+
zones: JSON.stringify(normalizeZones(options.zones)),
|
|
79
82
|
})
|
|
80
83
|
.onConflict((oc) =>
|
|
81
84
|
oc.columns(['chainId', 'vaultAddress']).doUpdateSet({
|
|
@@ -85,6 +88,7 @@ export async function upsert(db: Db.Db, options: upsert.Options): Promise<Record
|
|
|
85
88
|
privateOutputTokens: JSON.stringify(options.privateOutputTokens),
|
|
86
89
|
...(options.slug !== undefined ? { slug } : {}),
|
|
87
90
|
updatedAt: now,
|
|
91
|
+
zones: JSON.stringify(normalizeZones(options.zones)),
|
|
88
92
|
}),
|
|
89
93
|
)
|
|
90
94
|
.returningAll()
|
|
@@ -109,6 +113,8 @@ export declare namespace upsert {
|
|
|
109
113
|
slug?: string | undefined
|
|
110
114
|
/** Earn vault address. */
|
|
111
115
|
vaultAddress: Address
|
|
116
|
+
/** Curated private Zone routes. */
|
|
117
|
+
zones: db_Schema.EarnVault['zones']
|
|
112
118
|
}
|
|
113
119
|
}
|
|
114
120
|
|
|
@@ -149,3 +155,7 @@ function toRecord(row: Selectable<Table>): Record {
|
|
|
149
155
|
function normalize(address: string): Address {
|
|
150
156
|
return address.toLowerCase() as Address
|
|
151
157
|
}
|
|
158
|
+
|
|
159
|
+
function normalizeZones(zones: db_Schema.EarnVault['zones']): db_Schema.EarnVault['zones'] {
|
|
160
|
+
return zones.map((zone) => ({ ...zone, earnRouter: normalize(zone.earnRouter) }))
|
|
161
|
+
}
|