tapimo 0.10.1 → 0.11.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 +5249 -3572
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js.map +1 -1
- package/dist/Webhooks.d.ts +1 -76
- package/dist/Webhooks.d.ts.map +1 -1
- package/dist/Webhooks.js +2 -144
- package/dist/Webhooks.js.map +1 -1
- package/dist/admin/App.d.ts +74 -74
- package/dist/admin/apps/earn-vaults.d.ts +1 -1
- package/dist/admin/apps/organizations.d.ts +3 -3
- package/dist/admin/apps/verified-tokens.d.ts +74 -74
- package/dist/analytics/Analytics.d.ts.map +1 -1
- package/dist/analytics/Analytics.js +206 -0
- package/dist/analytics/Analytics.js.map +1 -1
- package/dist/analytics/tables/requestEvents.d.ts +4 -0
- package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
- package/dist/analytics/tables/requestEvents.js +2 -0
- package/dist/analytics/tables/requestEvents.js.map +1 -1
- package/dist/apps/data/App.d.ts +3618 -2954
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +7 -2
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +1 -1
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +55 -27
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/balances.d.ts +11 -11
- package/dist/apps/data/routes/balances.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.js +2 -6
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +5 -5
- package/dist/apps/data/routes/earn.d.ts +4 -4
- package/dist/apps/data/routes/earn.d.ts.map +1 -1
- package/dist/apps/data/routes/earn.js +63 -34
- package/dist/apps/data/routes/earn.js.map +1 -1
- package/dist/apps/data/routes/exchanges.d.ts +8 -4
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
- package/dist/apps/data/routes/exchanges.js +115 -77
- package/dist/apps/data/routes/exchanges.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts +26 -26
- package/dist/apps/data/routes/receipts.d.ts +240 -239
- package/dist/apps/data/routes/receipts.d.ts.map +1 -1
- package/dist/apps/data/routes/receipts.js +15 -14
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/tokenlist.d.ts +12 -12
- package/dist/apps/data/routes/tokens.d.ts +4 -4
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +4 -3
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.d.ts +282 -282
- package/dist/apps/data/routes/transfers.d.ts +13 -13
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +25 -7
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/valuation.d.ts +21 -21
- package/dist/apps/data/routes/verified-tokens.d.ts +5 -5
- package/dist/apps/data/routes/webhooks.d.ts +1519 -643
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +134 -740
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/data/routes/zones.d.ts +3 -3
- package/dist/apps/funding/App.d.ts +233 -0
- package/dist/apps/funding/App.d.ts.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.d.ts +331 -1
- package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.js +207 -11
- package/dist/apps/funding/routes/deposit-addresses.js.map +1 -1
- package/dist/apps/funding/routes/transfers.d.ts +33 -33
- package/dist/apps/management/App.d.ts +793 -16
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +50 -50
- package/dist/apps/management/routes/faucet.d.ts +2 -2
- package/dist/apps/management/routes/invite-links.d.ts +42 -42
- package/dist/apps/management/routes/members.d.ts +2 -2
- package/dist/apps/management/routes/projects.d.ts +40 -40
- package/dist/apps/management/routes/webhooks.d.ts +1031 -59
- package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/management/routes/webhooks.js +27 -4
- package/dist/apps/management/routes/webhooks.js.map +1 -1
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +53 -0
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +7 -1
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +9 -0
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/fundingDepositAddresses.d.ts +20 -0
- package/dist/db/tables/fundingDepositAddresses.d.ts.map +1 -1
- package/dist/db/tables/fundingDepositAddresses.js +17 -0
- package/dist/db/tables/fundingDepositAddresses.js.map +1 -1
- package/dist/db/tables/fundingDeposits.d.ts +41 -0
- package/dist/db/tables/fundingDeposits.d.ts.map +1 -1
- package/dist/db/tables/fundingDeposits.js +69 -0
- package/dist/db/tables/fundingDeposits.js.map +1 -1
- package/dist/db/tables/webhookQueueEvents.d.ts +3 -1
- package/dist/db/tables/webhookQueueEvents.d.ts.map +1 -1
- package/dist/db/tables/webhookQueueEvents.js +4 -0
- package/dist/db/tables/webhookQueueEvents.js.map +1 -1
- package/dist/db/tables/webhookSubscriptions.d.ts +33 -69
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
- package/dist/db/tables/webhookSubscriptions.js +63 -100
- package/dist/db/tables/webhookSubscriptions.js.map +1 -1
- package/dist/internal/Auth.d.ts +0 -26
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +0 -33
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/Credential.d.ts +27 -0
- package/dist/internal/Credential.d.ts.map +1 -0
- package/dist/internal/Credential.js +34 -0
- package/dist/internal/Credential.js.map +1 -0
- package/dist/internal/EarnRates.js +11 -7
- package/dist/internal/EarnRates.js.map +1 -1
- package/dist/internal/Log.d.ts +8 -0
- 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/MetricSink.d.ts +50 -116
- package/dist/internal/MetricSink.d.ts.map +1 -1
- package/dist/internal/MetricSink.js +60 -106
- package/dist/internal/MetricSink.js.map +1 -1
- package/dist/internal/Schema.d.ts +3 -1
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +4 -2
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/Tidx.d.ts +4 -3
- package/dist/internal/Tidx.d.ts.map +1 -1
- package/dist/internal/Tidx.js +2 -2
- package/dist/internal/Tidx.js.map +1 -1
- package/dist/internal/Viem.d.ts +4 -3
- package/dist/internal/Viem.d.ts.map +1 -1
- package/dist/internal/Viem.js +3 -2
- package/dist/internal/Viem.js.map +1 -1
- package/dist/internal/WebhookTransfer.d.ts +1 -55
- package/dist/internal/WebhookTransfer.d.ts.map +1 -1
- package/dist/internal/WebhookTransfer.js +1 -239
- package/dist/internal/WebhookTransfer.js.map +1 -1
- package/dist/internal/Webhooks.d.ts +85 -44
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +94 -73
- package/dist/internal/Webhooks.js.map +1 -1
- package/dist/internal/funding/DepositWebhook.d.ts +25 -0
- package/dist/internal/funding/DepositWebhook.d.ts.map +1 -0
- package/dist/internal/funding/DepositWebhook.js +74 -0
- package/dist/internal/funding/DepositWebhook.js.map +1 -0
- package/dist/internal/funding/Reconciliation.d.ts +6 -0
- package/dist/internal/funding/Reconciliation.d.ts.map +1 -1
- package/dist/internal/funding/Reconciliation.js +42 -10
- package/dist/internal/funding/Reconciliation.js.map +1 -1
- package/dist/internal/funding/index.d.ts +1 -0
- package/dist/internal/funding/index.d.ts.map +1 -1
- package/dist/internal/funding/index.js +1 -0
- package/dist/internal/funding/index.js.map +1 -1
- package/dist/internal/index.d.ts +1 -0
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +1 -0
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/webhookDestinations/slack.d.ts.map +1 -1
- package/dist/internal/webhookDestinations/slack.js +16 -0
- package/dist/internal/webhookDestinations/slack.js.map +1 -1
- package/package.json +1 -1
- package/src/App.test.ts +30 -0
- package/src/App.ts +3 -0
- package/src/Client.test-d.ts +55 -2
- package/src/Webhooks.ts +2 -221
- package/src/analytics/Analytics.test.ts +34 -0
- package/src/analytics/Analytics.ts +206 -0
- package/src/analytics/tables/requestEvents.ts +6 -0
- package/src/apps/composition.test.ts +1 -0
- package/src/apps/data/App.ts +10 -2
- package/src/apps/data/routes/activities.test.ts +107 -11
- package/src/apps/data/routes/activities.ts +64 -32
- package/src/apps/data/routes/balances.ts +2 -6
- package/src/apps/data/routes/earn.ts +64 -34
- package/src/apps/data/routes/exchanges.test.ts +8 -3
- package/src/apps/data/routes/exchanges.ts +134 -82
- package/src/apps/data/routes/receipts.ts +16 -14
- package/src/apps/data/routes/tokens.ts +3 -2
- package/src/apps/data/routes/transactions.bench.ts +8 -0
- package/src/apps/data/routes/transfers.ts +36 -10
- package/src/apps/data/routes/webhooks.test.ts +179 -1497
- package/src/apps/data/routes/webhooks.ts +172 -975
- package/src/apps/funding/routes/deposit-addresses.test.ts +216 -2
- package/src/apps/funding/routes/deposit-addresses.ts +254 -18
- package/src/apps/funding/routes/transfers.test.ts +17 -2
- package/src/apps/management/routes/webhooks.test.ts +79 -1
- package/src/apps/management/routes/webhooks.ts +40 -4
- package/src/db/Db.test.ts +1 -5
- package/src/db/Db.ts +59 -0
- package/src/db/Schema.ts +13 -0
- package/src/db/tables/fundingDepositAddresses.test.ts +28 -0
- package/src/db/tables/fundingDepositAddresses.ts +39 -0
- package/src/db/tables/fundingDeposits.test.ts +82 -0
- package/src/db/tables/fundingDeposits.ts +130 -0
- package/src/db/tables/organizations.test.ts +5 -2
- package/src/db/tables/webhookQueueEvents.ts +7 -1
- package/src/db/tables/webhookSubscriptions.ts +89 -138
- package/src/internal/Auth.test.ts +0 -48
- package/src/internal/Auth.ts +0 -59
- package/src/internal/Credential.test.ts +51 -0
- package/src/internal/Credential.ts +58 -0
- package/src/internal/EarnRates.ts +13 -7
- package/src/internal/Log.test.ts +3 -1
- package/src/internal/Log.ts +14 -0
- package/src/internal/MetricSink.test.ts +75 -358
- package/src/internal/MetricSink.ts +117 -246
- package/src/internal/Schema.test.ts +18 -0
- package/src/internal/Schema.ts +13 -2
- package/src/internal/Tidx.ts +5 -4
- package/src/internal/Viem.test.ts +4 -0
- package/src/internal/Viem.ts +6 -4
- package/src/internal/WebhookTransfer.ts +1 -351
- package/src/internal/Webhooks.test.ts +111 -139
- package/src/internal/Webhooks.ts +181 -105
- package/src/internal/funding/DepositWebhook.test.ts +131 -0
- package/src/internal/funding/DepositWebhook.ts +101 -0
- package/src/internal/funding/Reconciliation.test.ts +14 -0
- package/src/internal/funding/Reconciliation.ts +161 -86
- package/src/internal/funding/index.test.ts +1 -0
- package/src/internal/funding/index.ts +1 -0
- package/src/internal/index.test.ts +1 -0
- package/src/internal/index.ts +1 -0
- package/src/internal/webhookDestinations/slack.ts +15 -0
- package/src/Webhooks.bench.ts +0 -714
- package/src/Webhooks.memory.bench.ts +0 -250
- package/src/Webhooks.test.ts +0 -146
|
@@ -9,48 +9,22 @@ export type EventType = Webhooks.Envelope['type']
|
|
|
9
9
|
/** Where a delivery attempt originated. */
|
|
10
10
|
export type Trigger = 'manual_retry' | 'ping' | 'queue'
|
|
11
11
|
|
|
12
|
-
/** Bounded
|
|
13
|
-
export type
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
chainId?: number | undefined
|
|
22
|
-
/** Wall-clock duration of the tick in ms. */
|
|
23
|
-
durationMs: number
|
|
24
|
-
/** Whether the tick completed. */
|
|
25
|
-
outcome: 'error' | 'ok'
|
|
26
|
-
}
|
|
12
|
+
/** Bounded step names inside one block-fanout scan, used by `webhook:scan-step`. */
|
|
13
|
+
export type ScanStep =
|
|
14
|
+
| 'block_rpc'
|
|
15
|
+
| 'enrich'
|
|
16
|
+
| 'finalized_rpc'
|
|
17
|
+
| 'logs_rpc'
|
|
18
|
+
| 'match'
|
|
19
|
+
| 'stage'
|
|
20
|
+
| 'subscription_read'
|
|
27
21
|
|
|
28
22
|
/**
|
|
29
|
-
* A webhook metric event, recorded by the {@link webhooks} sink. The
|
|
30
|
-
*
|
|
23
|
+
* A webhook metric event, recorded by the {@link webhooks} sink. The
|
|
24
|
+
* block-fanout scan path emits head and scan measurements; the delivery path
|
|
31
25
|
* emits `webhook:delivery`.
|
|
32
26
|
*/
|
|
33
27
|
export type WebhookEvent =
|
|
34
|
-
| {
|
|
35
|
-
/** Tempo chain whose poll cycle completed. */
|
|
36
|
-
chainId: number
|
|
37
|
-
/** Whether the poll cycle completed without scan or dispatch failures. */
|
|
38
|
-
outcome: 'error' | 'ok'
|
|
39
|
-
/** Requested boundary movement since the preceding successful poll, in blocks. */
|
|
40
|
-
requestedBoundaryAdvanceBlocks?: number | undefined
|
|
41
|
-
/** Execution path that acquired this poll claim. */
|
|
42
|
-
trigger: 'alarm' | 'cron' | 'direct' | 'queue'
|
|
43
|
-
/** Identifies a transport-neutral poll-cycle measurement. */
|
|
44
|
-
type: 'webhook:poll-cycle'
|
|
45
|
-
}
|
|
46
|
-
| {
|
|
47
|
-
/** Tempo chain whose durable progress was read. */
|
|
48
|
-
chainId: number
|
|
49
|
-
/** Blocks between the desired and fully drained boundaries. */
|
|
50
|
-
lagBlocks: number
|
|
51
|
-
/** Identifies durable coordinator progress. */
|
|
52
|
-
type: 'webhook:head-progress'
|
|
53
|
-
}
|
|
54
28
|
| {
|
|
55
29
|
/** Tempo chain whose listener was checked. */
|
|
56
30
|
chainId: number
|
|
@@ -61,103 +35,53 @@ export type WebhookEvent =
|
|
|
61
35
|
}
|
|
62
36
|
| {
|
|
63
37
|
chainId: number
|
|
64
|
-
/**
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
|
|
38
|
+
/** True once finality has deferred this block at least one round. */
|
|
39
|
+
deferred: boolean
|
|
40
|
+
/** Rows matched when dispatched; zero otherwise. */
|
|
41
|
+
matches: number
|
|
42
|
+
/** Block timestamp to scan completion; absent when the block was not read. */
|
|
43
|
+
scanLagMs?: number | undefined
|
|
44
|
+
/** Block timestamp to head observation; absent without a fresh stamp. */
|
|
45
|
+
observationLagMs?: number | undefined
|
|
46
|
+
/** How the head that enqueued this block was observed. */
|
|
47
|
+
origin: string
|
|
48
|
+
/** One scanned block's outcome. */
|
|
49
|
+
outcome: 'deferred' | 'dispatched' | 'empty'
|
|
50
|
+
/** Head observation to this scan attempt starting; absent without a stamp. */
|
|
51
|
+
queueWaitMs?: number | undefined
|
|
52
|
+
/** Identifies one block-fanout scan. */
|
|
53
|
+
type: 'webhook:scan-block'
|
|
54
|
+
/** Wall-clock work inside this scan attempt. */
|
|
55
|
+
workMs: number
|
|
68
56
|
}
|
|
69
57
|
| {
|
|
70
|
-
/** Tempo chain whose recovery poke was dequeued. */
|
|
71
58
|
chainId: number
|
|
72
|
-
/**
|
|
73
|
-
dequeuedAt: number
|
|
74
|
-
/** When the recovery poke was enqueued, as epoch milliseconds. */
|
|
75
|
-
enqueuedAt: number
|
|
76
|
-
/** Recovery source carried through the Queue handoff. */
|
|
77
|
-
trigger: 'alarm' | 'queue'
|
|
78
|
-
/** Identifies recovery Queue latency, not observed head volume. */
|
|
79
|
-
type: 'webhook:head-recovery'
|
|
80
|
-
}
|
|
81
|
-
| {
|
|
82
|
-
/** Tempo chain whose poll claim was acquired. */
|
|
83
|
-
chainId: number
|
|
84
|
-
/** Delay from observing the desired boundary to acquiring the claim. */
|
|
85
|
-
delayMs?: number | undefined
|
|
86
|
-
/** Execution path that acquired the claim. */
|
|
87
|
-
trigger: 'alarm' | 'cron' | 'direct' | 'queue'
|
|
88
|
-
/** Identifies a poll beginning, before scan work runs. */
|
|
89
|
-
type: 'webhook:poll-start'
|
|
90
|
-
}
|
|
91
|
-
| {
|
|
92
|
-
/** Tempo chain whose poll failed. */
|
|
93
|
-
chainId: number
|
|
94
|
-
/** Bounded class of the thrown failure. */
|
|
95
|
-
failure: PollFailure
|
|
96
|
-
/** Operation boundary that rejected the poll. */
|
|
97
|
-
stage: 'claim' | 'continuation_enqueue' | 'finish' | 'scan'
|
|
98
|
-
/** Execution path that failed before recovery. */
|
|
99
|
-
trigger: 'alarm' | 'cron' | 'direct' | 'queue'
|
|
100
|
-
/** Identifies a transport-neutral poll failure. */
|
|
101
|
-
type: 'webhook:poll-failure'
|
|
102
|
-
}
|
|
103
|
-
| {
|
|
104
|
-
chainId: number
|
|
105
|
-
durationMs: number
|
|
106
|
-
eventType?: EventType | undefined
|
|
107
|
-
outcome: 'error' | 'ok'
|
|
108
|
-
stage: PollStage
|
|
109
|
-
type: 'webhook:poll'
|
|
110
|
-
}
|
|
111
|
-
| {
|
|
112
|
-
/** Tempo chain whose eligible subscription count was read. */
|
|
113
|
-
chainId: number
|
|
114
|
-
/** Active, unexpired subscriptions selected for the poll. */
|
|
59
|
+
/** Times this step ran across the batch, so the total can be normalized. */
|
|
115
60
|
count: number
|
|
116
|
-
/**
|
|
117
|
-
|
|
61
|
+
/** Wall-clock duration of this step summed across the batch. */
|
|
62
|
+
durationMs: number
|
|
63
|
+
/** Bounded step name. */
|
|
64
|
+
step: ScanStep
|
|
65
|
+
/** Identifies per-step scan attribution. */
|
|
66
|
+
type: 'webhook:scan-step'
|
|
118
67
|
}
|
|
119
68
|
| {
|
|
120
|
-
/** Chain scanned by this poll batch. */
|
|
121
69
|
chainId: number
|
|
122
|
-
/**
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
|
|
130
|
-
/** Matching rows retained by completed pages, present only after completion. */
|
|
131
|
-
matchedItems?: number | undefined
|
|
132
|
-
/** Largest block window requested by one subscription. */
|
|
133
|
-
maxWindowBlocks: number
|
|
134
|
-
/** Whether the checkpoint precedes allocation or follows scan completion. */
|
|
135
|
-
phase: 'complete' | 'start'
|
|
136
|
-
/** Outcome of the completed RPC-backed scan. */
|
|
137
|
-
outcome?: 'empty' | 'error' | 'missing' | 'ok' | undefined
|
|
138
|
-
/** JSON-RPC method used by this event type's scanner. */
|
|
139
|
-
rpcMethod: 'eth_getBlockByNumber' | 'eth_getLogs'
|
|
140
|
-
/** Subscriptions retained in this scan batch. */
|
|
141
|
-
subscriptionCount: number
|
|
142
|
-
/** Maximum subscriptions retained by this event-type batch. */
|
|
143
|
-
subscriptionLimit: number
|
|
144
|
-
/** Sum of subscription block windows in this scan batch. */
|
|
145
|
-
totalWindowBlocks: number
|
|
146
|
-
/** Identifies a memory-attribution scan boundary. */
|
|
147
|
-
type: 'webhook:poll-scan'
|
|
148
|
-
}
|
|
149
|
-
| {
|
|
150
|
-
cursorLagBlocks?: number | undefined
|
|
151
|
-
meta: TickMeta
|
|
152
|
-
result: Webhooks.createPoller.Result | undefined
|
|
153
|
-
type: 'webhook:tick'
|
|
70
|
+
/** Age of the oldest tracked block, absent when none are pending. */
|
|
71
|
+
oldestPendingAgeMs?: number | undefined
|
|
72
|
+
/** Tracked blocks awaiting completion reports. */
|
|
73
|
+
pendingCount: number
|
|
74
|
+
/** Identifies the coordinator's tracked-scan backlog. */
|
|
75
|
+
type: 'webhook:scan-backlog'
|
|
76
|
+
/** Blocks between the chain head and the enqueue watermark. */
|
|
77
|
+
watermarkLagBlocks?: number | undefined
|
|
154
78
|
}
|
|
155
79
|
| {
|
|
156
80
|
chainId: number
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
type: 'webhook:
|
|
81
|
+
/** Blocks between the observed head and the finalized head. */
|
|
82
|
+
lagBlocks: number
|
|
83
|
+
/** Identifies the finality gate's settling distance. */
|
|
84
|
+
type: 'webhook:scan-finality'
|
|
161
85
|
}
|
|
162
86
|
| {
|
|
163
87
|
/** Atomic ledger claim outcome. */
|
|
@@ -185,9 +109,17 @@ export type WebhookEvent =
|
|
|
185
109
|
deliveryLogMs?: number | undefined
|
|
186
110
|
envelopeToQueueMs?: number | undefined
|
|
187
111
|
endToEndMs?: number | undefined
|
|
112
|
+
/** Block timestamp to the attempt leaving; the total latency SLI. */
|
|
113
|
+
eventToAttemptMs?: number | undefined
|
|
188
114
|
eventToEnvelopeMs?: number | undefined
|
|
115
|
+
/** Head observation to the attempt leaving; the controllable SLI. */
|
|
116
|
+
observedToAttemptMs?: number | undefined
|
|
117
|
+
/** Dequeue to the attempt leaving: claim, reads, signing. */
|
|
118
|
+
preflightMs?: number | undefined
|
|
189
119
|
processingMs?: number | undefined
|
|
190
120
|
queueWaitMs?: number | undefined
|
|
121
|
+
/** Response headers to bookkeeping complete; occupancy, not latency. */
|
|
122
|
+
settleMs?: number | undefined
|
|
191
123
|
stateWriteMs?: number | undefined
|
|
192
124
|
subscriptionReadMs?: number | undefined
|
|
193
125
|
}
|
|
@@ -200,7 +132,7 @@ export type RequestSink = (entry: Log.Entry) => void
|
|
|
200
132
|
|
|
201
133
|
/** Records webhook reliability metrics. Built by {@link webhooks}. */
|
|
202
134
|
export type WebhookSink = {
|
|
203
|
-
/** Ships buffered metrics (call once per
|
|
135
|
+
/** Ships buffered metrics (call once per scan batch / delivery). */
|
|
204
136
|
flush(): void
|
|
205
137
|
/** Records one webhook event. */
|
|
206
138
|
record(event: WebhookEvent): void
|
|
@@ -275,6 +207,9 @@ export function requests(backend: Metrics): RequestSink {
|
|
|
275
207
|
backend.histogram('funding_quote_provider_duration_ms', attempt.durationMs, tags_attempt)
|
|
276
208
|
}
|
|
277
209
|
|
|
210
|
+
if (entry.fundingDepositCountFailed)
|
|
211
|
+
backend.count('funding_deposit_count_failure_count', 1, tags)
|
|
212
|
+
|
|
278
213
|
if (entry.fundingTransferCountFailed)
|
|
279
214
|
backend.count('funding_transfer_count_failure_count', 1, tags)
|
|
280
215
|
|
|
@@ -356,144 +291,61 @@ export function webhooks(backend: Metrics): WebhookSink {
|
|
|
356
291
|
},
|
|
357
292
|
record(event) {
|
|
358
293
|
switch (event.type) {
|
|
359
|
-
case 'webhook:head-recovery': {
|
|
360
|
-
const tags = { chain_id: String(event.chainId), trigger: event.trigger }
|
|
361
|
-
backend.count('webhook_head_recovery_queue_count', 1, tags)
|
|
362
|
-
backend.histogram(
|
|
363
|
-
'webhook_head_recovery_queue_wait_ms',
|
|
364
|
-
Math.max(0, event.dequeuedAt - event.enqueuedAt),
|
|
365
|
-
tags,
|
|
366
|
-
)
|
|
367
|
-
return
|
|
368
|
-
}
|
|
369
|
-
case 'webhook:head-progress':
|
|
370
|
-
backend.gauge('webhook_head_progress_lag_blocks', event.lagBlocks, {
|
|
371
|
-
chain_id: String(event.chainId),
|
|
372
|
-
})
|
|
373
|
-
return
|
|
374
294
|
case 'webhook:head-skipped':
|
|
375
295
|
backend.gauge('webhook_head_skipped_count', event.skippedHeads, {
|
|
376
296
|
chain_id: String(event.chainId),
|
|
377
297
|
})
|
|
378
298
|
return
|
|
379
|
-
case 'webhook:
|
|
380
|
-
backend.gauge('webhook_listener_head_lag_blocks', event.lagBlocks, {
|
|
381
|
-
chain_id: String(event.chainId),
|
|
382
|
-
})
|
|
383
|
-
return
|
|
384
|
-
case 'webhook:poll-failure':
|
|
385
|
-
backend.count('webhook_poll_failure_count', 1, {
|
|
386
|
-
chain_id: String(event.chainId),
|
|
387
|
-
failure: event.failure,
|
|
388
|
-
stage: event.stage,
|
|
389
|
-
trigger: event.trigger,
|
|
390
|
-
})
|
|
391
|
-
return
|
|
392
|
-
case 'webhook:poll': {
|
|
299
|
+
case 'webhook:scan-block': {
|
|
393
300
|
const tags = {
|
|
394
301
|
chain_id: String(event.chainId),
|
|
395
|
-
|
|
302
|
+
origin: event.origin,
|
|
396
303
|
outcome: event.outcome,
|
|
397
|
-
stage: event.stage,
|
|
398
|
-
}
|
|
399
|
-
backend.histogram('webhook_poller_stage_duration_ms', event.durationMs, tags)
|
|
400
|
-
return
|
|
401
|
-
}
|
|
402
|
-
case 'webhook:poll-scan': {
|
|
403
|
-
const tags = {
|
|
404
|
-
chain_id: String(event.chainId),
|
|
405
|
-
event_type: event.eventType,
|
|
406
|
-
phase: event.phase,
|
|
407
304
|
}
|
|
408
|
-
backend.count('
|
|
409
|
-
backend.
|
|
410
|
-
backend.histogram('
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
'
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
if (event.
|
|
419
|
-
backend.histogram('
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
if (event.
|
|
427
|
-
backend.
|
|
428
|
-
if (event.outcome !== undefined)
|
|
429
|
-
backend.count('webhook_poller_rpc_scan_count', 1, {
|
|
305
|
+
backend.count('webhook_scan_block_count', 1, tags)
|
|
306
|
+
if (event.matches > 0) backend.count('webhook_scan_match_count', event.matches, tags)
|
|
307
|
+
backend.histogram('webhook_scan_work_ms', event.workMs, tags)
|
|
308
|
+
// Deferred rounds are chain finality, not queue depth, so the wait
|
|
309
|
+
// carries the distinction rather than silently averaging the two.
|
|
310
|
+
if (event.queueWaitMs !== undefined)
|
|
311
|
+
backend.histogram('webhook_scan_queue_wait_ms', event.queueWaitMs, {
|
|
312
|
+
...tags,
|
|
313
|
+
deferred: String(event.deferred),
|
|
314
|
+
})
|
|
315
|
+
if (event.observationLagMs !== undefined)
|
|
316
|
+
backend.histogram('webhook_scan_observation_lag_ms', event.observationLagMs, {
|
|
317
|
+
chain_id: String(event.chainId),
|
|
318
|
+
origin: event.origin,
|
|
319
|
+
})
|
|
320
|
+
// Block timestamp to scan completion: how far behind the chain the
|
|
321
|
+
// scanner is, reported by every scanned block rather than only by
|
|
322
|
+
// blocks that produce a delivery.
|
|
323
|
+
if (event.scanLagMs !== undefined)
|
|
324
|
+
backend.histogram('webhook_scan_lag_ms', event.scanLagMs, {
|
|
430
325
|
chain_id: String(event.chainId),
|
|
431
|
-
event_type: event.eventType,
|
|
432
|
-
outcome: event.outcome,
|
|
433
|
-
rpc_method: event.rpcMethod,
|
|
434
326
|
})
|
|
435
327
|
return
|
|
436
328
|
}
|
|
437
|
-
case 'webhook:
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
chain_id: String(event.chainId),
|
|
445
|
-
outcome: event.outcome,
|
|
446
|
-
trigger: event.trigger,
|
|
447
|
-
}
|
|
448
|
-
backend.count('webhook_poll_cycle_count', 1, tags)
|
|
449
|
-
if (event.requestedBoundaryAdvanceBlocks !== undefined)
|
|
450
|
-
backend.histogram(
|
|
451
|
-
'webhook_poll_requested_boundary_advance_blocks',
|
|
452
|
-
event.requestedBoundaryAdvanceBlocks,
|
|
453
|
-
tags,
|
|
454
|
-
)
|
|
455
|
-
return
|
|
456
|
-
}
|
|
457
|
-
case 'webhook:poll-start': {
|
|
458
|
-
const tags = { chain_id: String(event.chainId), trigger: event.trigger }
|
|
459
|
-
backend.count('webhook_poll_start_count', 1, tags)
|
|
460
|
-
if (event.delayMs !== undefined)
|
|
461
|
-
backend.histogram('webhook_poll_start_delay_ms', event.delayMs, tags)
|
|
329
|
+
case 'webhook:scan-step': {
|
|
330
|
+
const tags = { chain_id: String(event.chainId), step: event.step }
|
|
331
|
+
// Batch totals, so the count is required to read a per-invocation
|
|
332
|
+
// mean: a ten-block batch otherwise reports ten times a one-block
|
|
333
|
+
// batch at identical per-call latency.
|
|
334
|
+
backend.histogram('webhook_scan_step_duration_ms', event.durationMs, tags)
|
|
335
|
+
backend.count('webhook_scan_step_count', event.count, tags)
|
|
462
336
|
return
|
|
463
337
|
}
|
|
464
|
-
case 'webhook:
|
|
465
|
-
const {
|
|
466
|
-
|
|
467
|
-
backend.
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
outcome: meta.outcome,
|
|
471
|
-
})
|
|
472
|
-
if (event.cursorLagBlocks !== undefined)
|
|
473
|
-
backend.gauge('webhook_subscription_cursor_lag_blocks', event.cursorLagBlocks, {
|
|
474
|
-
chain_id,
|
|
475
|
-
})
|
|
476
|
-
if (!result) return
|
|
477
|
-
backend.histogram('webhook_poller_subscription_count', result.subscriptions, { chain_id })
|
|
478
|
-
backend.count('webhook_poller_scanned_count', result.scanned, { chain_id })
|
|
479
|
-
backend.gauge('webhook_poller_safe_block', result.safeBlock, { chain_id })
|
|
480
|
-
backend.count('webhook_poller_dispatch_count', result.dispatched, {
|
|
481
|
-
chain_id,
|
|
482
|
-
outcome: 'dispatched',
|
|
483
|
-
})
|
|
484
|
-
backend.count('webhook_poller_dispatch_count', result.failed, {
|
|
485
|
-
chain_id,
|
|
486
|
-
outcome: 'failed',
|
|
487
|
-
})
|
|
338
|
+
case 'webhook:scan-backlog': {
|
|
339
|
+
const tags = { chain_id: String(event.chainId) }
|
|
340
|
+
backend.gauge('webhook_scan_pending_count', event.pendingCount, tags)
|
|
341
|
+
backend.gauge('webhook_scan_oldest_pending_age_ms', event.oldestPendingAgeMs ?? 0, tags)
|
|
342
|
+
if (event.watermarkLagBlocks !== undefined)
|
|
343
|
+
backend.gauge('webhook_scan_watermark_lag_blocks', event.watermarkLagBlocks, tags)
|
|
488
344
|
return
|
|
489
345
|
}
|
|
490
|
-
case 'webhook:
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
backend.count('webhook_dispatch_enqueue_count', 1, { ...tags, outcome })
|
|
494
|
-
backend.histogram('webhook_dispatch_enqueue_duration_ms', event.durationMs, {
|
|
495
|
-
...tags,
|
|
496
|
-
outcome,
|
|
346
|
+
case 'webhook:scan-finality': {
|
|
347
|
+
backend.gauge('webhook_scan_finality_lag_blocks', event.lagBlocks, {
|
|
348
|
+
chain_id: String(event.chainId),
|
|
497
349
|
})
|
|
498
350
|
return
|
|
499
351
|
}
|
|
@@ -541,6 +393,25 @@ export function webhooks(backend: Metrics): WebhookSink {
|
|
|
541
393
|
})
|
|
542
394
|
if (timings?.deliveryLogMs !== undefined)
|
|
543
395
|
backend.histogram('webhook_delivery_log_write_ms', timings.deliveryLogMs, tags)
|
|
396
|
+
if (timings?.preflightMs !== undefined)
|
|
397
|
+
backend.histogram('webhook_delivery_preflight_ms', timings.preflightMs, tags)
|
|
398
|
+
if (timings?.settleMs !== undefined)
|
|
399
|
+
backend.histogram('webhook_delivery_settle_ms', timings.settleMs, tags)
|
|
400
|
+
// The two headline latency SLIs, both ending when the attempt leaves
|
|
401
|
+
// rather than when bookkeeping finishes. Attempt-bucketed for the
|
|
402
|
+
// same reason as end-to-end: retries carry designed backoff.
|
|
403
|
+
if (timings?.eventToAttemptMs !== undefined)
|
|
404
|
+
backend.histogram('webhook_event_to_attempt_ms', timings.eventToAttemptMs, {
|
|
405
|
+
...tags,
|
|
406
|
+
attempt_bucket: attemptBucket(event.attempt),
|
|
407
|
+
outcome,
|
|
408
|
+
})
|
|
409
|
+
if (timings?.observedToAttemptMs !== undefined)
|
|
410
|
+
backend.histogram('webhook_observed_to_attempt_ms', timings.observedToAttemptMs, {
|
|
411
|
+
...tags,
|
|
412
|
+
attempt_bucket: attemptBucket(event.attempt),
|
|
413
|
+
outcome,
|
|
414
|
+
})
|
|
544
415
|
if (timings?.envelopeToQueueMs !== undefined)
|
|
545
416
|
backend.histogram(
|
|
546
417
|
'webhook_delivery_envelope_to_queue_ms',
|
|
@@ -33,6 +33,24 @@ describe('ChainIdQuery', () => {
|
|
|
33
33
|
})
|
|
34
34
|
})
|
|
35
35
|
|
|
36
|
+
describe('Limit', () => {
|
|
37
|
+
test('defaults to 10 and accepts page sizes through 50', () => {
|
|
38
|
+
expect(Schema.Limit.parse(undefined)).toMatchInlineSnapshot(`10`)
|
|
39
|
+
expect(Schema.Limit.parse('5')).toMatchInlineSnapshot(`5`)
|
|
40
|
+
expect(Schema.Limit.parse('50')).toMatchInlineSnapshot(`50`)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('caps larger page sizes at 50', () => {
|
|
44
|
+
expect(Schema.Limit.parse('51')).toMatchInlineSnapshot(`50`)
|
|
45
|
+
expect(Schema.Limit.parse('200')).toMatchInlineSnapshot(`50`)
|
|
46
|
+
expect(Schema.Limit.parse('10000')).toMatchInlineSnapshot(`50`)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('rejects page sizes below the minimum', () => {
|
|
50
|
+
expect(Schema.Limit.safeParse('4').success).toMatchInlineSnapshot(`false`)
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
|
|
36
54
|
describe('timestampBound', () => {
|
|
37
55
|
test('normalizes RFC 3339 offsets to UTC', () => {
|
|
38
56
|
const bound = Schema.timestampBound('swaps', 'from')
|
package/src/internal/Schema.ts
CHANGED
|
@@ -337,11 +337,22 @@ export const TokenAmount = describe(
|
|
|
337
337
|
*/
|
|
338
338
|
export const minLimit = 5
|
|
339
339
|
|
|
340
|
+
/** Maximum number of rows returned per page. Larger requests are clamped to this value. */
|
|
341
|
+
export const maxLimit = 50
|
|
342
|
+
|
|
340
343
|
/** Page-size query parameter shared across list endpoints. */
|
|
341
344
|
export const Limit = z
|
|
342
|
-
._default(
|
|
345
|
+
._default(
|
|
346
|
+
z.pipe(
|
|
347
|
+
z.coerce.number().check(z.int(), z.gte(minLimit)),
|
|
348
|
+
z.transform((value) => Math.min(value, maxLimit)),
|
|
349
|
+
),
|
|
350
|
+
10,
|
|
351
|
+
)
|
|
343
352
|
.check(
|
|
344
|
-
z.describe(
|
|
353
|
+
z.describe(
|
|
354
|
+
'How many items to return per page (5\u201350, default 10). Use `nextCursor` to fetch more.',
|
|
355
|
+
),
|
|
345
356
|
z.meta({ examples: [10] }),
|
|
346
357
|
)
|
|
347
358
|
|
package/src/internal/Tidx.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Tidx } from 'tidx.ts'
|
|
2
2
|
import type { Chain } from 'viem'
|
|
3
3
|
|
|
4
|
-
import * as Auth from './Auth.js'
|
|
4
|
+
import type * as Auth from './Auth.js'
|
|
5
|
+
import * as Credential from './Credential.js'
|
|
5
6
|
import * as Errors from './Errors.js'
|
|
6
7
|
import type * as Log from './Log.js'
|
|
7
8
|
import * as Viem from './Viem.js'
|
|
@@ -40,7 +41,7 @@ export function resolve(
|
|
|
40
41
|
): resolve.Resolved {
|
|
41
42
|
const config = typeof tidx === 'function' ? tidx(context) : tidx
|
|
42
43
|
return {
|
|
43
|
-
...
|
|
44
|
+
...Credential.resolveCredential({ chainId: context.chainId, value: config?.auth }),
|
|
44
45
|
...(context.zone && config?.zoneHeaders ? { zoneHeaders: config.zoneHeaders } : {}),
|
|
45
46
|
baseUrl:
|
|
46
47
|
Viem.resolveUrl(config?.baseUrl, context.chainId) ??
|
|
@@ -319,7 +320,7 @@ export declare namespace getClient {
|
|
|
319
320
|
type Tidx =
|
|
320
321
|
| {
|
|
321
322
|
/** Shared or per-chain TIDX credentials. Values containing `:` use Basic auth; others use Bearer auth. */
|
|
322
|
-
auth?:
|
|
323
|
+
auth?: Credential.ChainCredential | undefined
|
|
323
324
|
/** Resolves the TIDX base URL for a Tempo chain id, or a static base URL. */
|
|
324
325
|
baseUrl?: UrlResolver | undefined
|
|
325
326
|
/** Headers sent to Zone indexer upstreams. */
|
|
@@ -327,7 +328,7 @@ export declare namespace getClient {
|
|
|
327
328
|
}
|
|
328
329
|
| ((context: Viem.resolveRpc.Context) => {
|
|
329
330
|
/** Shared or per-chain TIDX credentials, or undefined for none. */
|
|
330
|
-
auth?:
|
|
331
|
+
auth?: Credential.ChainCredential | undefined
|
|
331
332
|
/** TIDX base URL to use; falls back to the built-in public host when omitted. */
|
|
332
333
|
baseUrl?: string | undefined
|
|
333
334
|
/** Headers sent to Zone indexer upstreams. */
|
|
@@ -220,6 +220,10 @@ describe('resolveRpc', () => {
|
|
|
220
220
|
})
|
|
221
221
|
|
|
222
222
|
describe('getClient', () => {
|
|
223
|
+
test('disables CCIP-Read', () => {
|
|
224
|
+
expect(Viem.getClient({ chainId: 4217 }).ccipRead).toBe(false)
|
|
225
|
+
})
|
|
226
|
+
|
|
223
227
|
test('disables multicall for Zones', () => {
|
|
224
228
|
const l1Client = Viem.getClient({ chainId: 4217 })
|
|
225
229
|
const zoneClient = Viem.getClient({ chainId: zone.id, zone })
|
package/src/internal/Viem.ts
CHANGED
|
@@ -6,7 +6,8 @@ import type { TempoActions } from 'viem/tempo'
|
|
|
6
6
|
import { tempoMainnet, tempoTestnet } from 'viem/tempo/chains'
|
|
7
7
|
import type * as z from 'zod/mini'
|
|
8
8
|
|
|
9
|
-
import * as Auth from './Auth.js'
|
|
9
|
+
import type * as Auth from './Auth.js'
|
|
10
|
+
import * as Credential from './Credential.js'
|
|
10
11
|
import type * as Schema from './Schema.js'
|
|
11
12
|
|
|
12
13
|
/** Known Tempo chains keyed by id, for metadata lookups. */
|
|
@@ -79,7 +80,7 @@ export function resolveRpc(
|
|
|
79
80
|
context: resolveRpc.Context,
|
|
80
81
|
): resolveRpc.Resolved {
|
|
81
82
|
const config = typeof rpc === 'function' ? rpc(context) : rpc
|
|
82
|
-
const auth =
|
|
83
|
+
const auth = Credential.resolveCredential({ chainId: context.chainId, value: config?.auth })
|
|
83
84
|
const publicZoneUrl = context.zone
|
|
84
85
|
? (resolveUrl(config?.publicZoneUrl, context.chainId) ?? context.zone.rpcUrls.default.http[0])
|
|
85
86
|
: undefined
|
|
@@ -165,6 +166,7 @@ export function getClient(options: getClient.Options): getClient.ReturnType {
|
|
|
165
166
|
// configure a deployed multicall3, can still serve the aggregated call.
|
|
166
167
|
// Zones disable multicall entirely and issue concurrent direct `eth_call`s instead.
|
|
167
168
|
batch: { multicall: zone ? false : { deployless: true } },
|
|
169
|
+
ccipRead: false,
|
|
168
170
|
chain: { ...tempoMainnet, id: chainId },
|
|
169
171
|
transport: http(rpcUrl, fetchOptions ? { fetchOptions } : {}),
|
|
170
172
|
})
|
|
@@ -250,7 +252,7 @@ export declare namespace getClient {
|
|
|
250
252
|
type Rpc =
|
|
251
253
|
| {
|
|
252
254
|
/** Shared or per-chain RPC credentials. Values containing `:` use Basic auth; others use Bearer auth. */
|
|
253
|
-
auth?:
|
|
255
|
+
auth?: Credential.ChainCredential | undefined
|
|
254
256
|
/** Resolves the public Zone RPC URL used with caller-provided authorization. */
|
|
255
257
|
publicZoneUrl?: UrlResolver | undefined
|
|
256
258
|
/** Headers sent to Zone RPC upstreams. */
|
|
@@ -260,7 +262,7 @@ export declare namespace getClient {
|
|
|
260
262
|
}
|
|
261
263
|
| ((context: resolveRpc.Context) => {
|
|
262
264
|
/** Shared or per-chain RPC credentials, or undefined for none. */
|
|
263
|
-
auth?:
|
|
265
|
+
auth?: Credential.ChainCredential | undefined
|
|
264
266
|
/** Public Zone RPC URL used with caller-provided authorization. */
|
|
265
267
|
publicZoneUrl?: string | undefined
|
|
266
268
|
/** Headers sent to Zone RPC upstreams. */
|