tapimo 0.12.0 → 0.13.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.
Files changed (257) hide show
  1. package/dist/App.d.ts +5561 -5026
  2. package/dist/App.d.ts.map +1 -1
  3. package/dist/App.js +38 -3
  4. package/dist/App.js.map +1 -1
  5. package/dist/Scope.d.ts +2 -0
  6. package/dist/Scope.d.ts.map +1 -1
  7. package/dist/Scope.js +17 -0
  8. package/dist/Scope.js.map +1 -1
  9. package/dist/admin/App.d.ts +123 -74
  10. package/dist/admin/App.d.ts.map +1 -1
  11. package/dist/admin/apps/api-keys.d.ts +80 -0
  12. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  13. package/dist/admin/apps/api-keys.js +54 -0
  14. package/dist/admin/apps/api-keys.js.map +1 -1
  15. package/dist/admin/apps/earn-vaults.d.ts +15 -15
  16. package/dist/admin/apps/earn-vaults.js +1 -1
  17. package/dist/admin/apps/verified-tokens.d.ts +81 -81
  18. package/dist/admin/ui.generated.d.ts +1 -1
  19. package/dist/admin/ui.generated.d.ts.map +1 -1
  20. package/dist/admin/ui.generated.js +151 -151
  21. package/dist/admin/ui.generated.js.map +1 -1
  22. package/dist/apps/Zones.d.ts +16 -16
  23. package/dist/apps/Zones.js +4 -4
  24. package/dist/apps/data/App.js +18 -18
  25. package/dist/apps/data/App.js.map +1 -1
  26. package/dist/apps/data/ZoneSelection.d.ts +8 -8
  27. package/dist/apps/data/ZoneSelection.d.ts.map +1 -1
  28. package/dist/apps/data/ZoneSelection.js +1 -1
  29. package/dist/apps/data/ZoneSelection.js.map +1 -1
  30. package/dist/apps/data/routes/activities.d.ts +588 -584
  31. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  32. package/dist/apps/data/routes/activities.js +1561 -1239
  33. package/dist/apps/data/routes/activities.js.map +1 -1
  34. package/dist/apps/data/routes/balances.d.ts +26 -26
  35. package/dist/apps/data/routes/balances.d.ts.map +1 -1
  36. package/dist/apps/data/routes/balances.js +43 -16
  37. package/dist/apps/data/routes/balances.js.map +1 -1
  38. package/dist/apps/data/routes/blocks.d.ts +44 -44
  39. package/dist/apps/data/routes/blocks.d.ts.map +1 -1
  40. package/dist/apps/data/routes/blocks.js +21 -11
  41. package/dist/apps/data/routes/blocks.js.map +1 -1
  42. package/dist/apps/data/routes/coingecko.d.ts +3 -3
  43. package/dist/apps/data/routes/earn.d.ts +18 -18
  44. package/dist/apps/data/routes/earn.js +13 -13
  45. package/dist/apps/data/routes/exchanges.d.ts +145 -145
  46. package/dist/apps/data/routes/fee-amm.d.ts +2 -2
  47. package/dist/apps/data/routes/receipts.d.ts +155 -55
  48. package/dist/apps/data/routes/receipts.d.ts.map +1 -1
  49. package/dist/apps/data/routes/receipts.js +28 -10
  50. package/dist/apps/data/routes/receipts.js.map +1 -1
  51. package/dist/apps/data/routes/tokenlist.d.ts +13 -13
  52. package/dist/apps/data/routes/tokens.d.ts +98 -98
  53. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  54. package/dist/apps/data/routes/tokens.js +51 -20
  55. package/dist/apps/data/routes/tokens.js.map +1 -1
  56. package/dist/apps/data/routes/transactions.d.ts +7 -2
  57. package/dist/apps/data/routes/transactions.d.ts.map +1 -1
  58. package/dist/apps/data/routes/transactions.js +37 -17
  59. package/dist/apps/data/routes/transactions.js.map +1 -1
  60. package/dist/apps/data/routes/transfers.d.ts +1 -1
  61. package/dist/apps/data/routes/transfers.d.ts.map +1 -1
  62. package/dist/apps/data/routes/transfers.js +18 -12
  63. package/dist/apps/data/routes/transfers.js.map +1 -1
  64. package/dist/apps/data/routes/valuation.d.ts +1 -1
  65. package/dist/apps/data/routes/valuation.d.ts.map +1 -1
  66. package/dist/apps/data/routes/valuation.js +12 -7
  67. package/dist/apps/data/routes/valuation.js.map +1 -1
  68. package/dist/apps/data/routes/verified-tokens.d.ts +3 -3
  69. package/dist/apps/data/routes/webhooks.d.ts +11 -11
  70. package/dist/apps/data/routes/zones.d.ts +14 -14
  71. package/dist/apps/data/routes/zones.js +1 -1
  72. package/dist/apps/funding/App.d.ts +11 -0
  73. package/dist/apps/funding/App.d.ts.map +1 -1
  74. package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -1
  75. package/dist/apps/funding/routes/deposit-addresses.js +16 -11
  76. package/dist/apps/funding/routes/deposit-addresses.js.map +1 -1
  77. package/dist/apps/funding/routes/transfers.d.ts +60 -48
  78. package/dist/apps/funding/routes/transfers.d.ts.map +1 -1
  79. package/dist/apps/funding/routes/transfers.js +27 -19
  80. package/dist/apps/funding/routes/transfers.js.map +1 -1
  81. package/dist/apps/management/App.d.ts +4487 -3963
  82. package/dist/apps/management/App.d.ts.map +1 -1
  83. package/dist/apps/management/routes/api-keys.d.ts +710 -159
  84. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  85. package/dist/apps/management/routes/api-keys.js +236 -4
  86. package/dist/apps/management/routes/api-keys.js.map +1 -1
  87. package/dist/apps/management/routes/faucet.d.ts +6 -6
  88. package/dist/apps/management/routes/invite-links.d.ts +42 -42
  89. package/dist/apps/management/routes/members.d.ts +30 -30
  90. package/dist/apps/management/routes/projects.d.ts +40 -40
  91. package/dist/apps/management/routes/usage.d.ts +24 -24
  92. package/dist/apps/management/routes/verified-token-requests.d.ts +1 -1
  93. package/dist/apps/management/routes/webhooks.d.ts +55 -55
  94. package/dist/db/Db.d.ts.map +1 -1
  95. package/dist/db/Db.js +12 -1
  96. package/dist/db/Db.js.map +1 -1
  97. package/dist/db/Schema.d.ts +3 -2
  98. package/dist/db/Schema.d.ts.map +1 -1
  99. package/dist/db/Schema.js +5 -2
  100. package/dist/db/Schema.js.map +1 -1
  101. package/dist/db/tables/fundingCatalog.d.ts +4 -2
  102. package/dist/db/tables/fundingCatalog.d.ts.map +1 -1
  103. package/dist/db/tables/fundingCatalog.js +5 -1
  104. package/dist/db/tables/fundingCatalog.js.map +1 -1
  105. package/dist/handlers/internal/utils.d.ts.map +1 -1
  106. package/dist/handlers/internal/utils.js +9 -0
  107. package/dist/handlers/internal/utils.js.map +1 -1
  108. package/dist/internal/Auth.d.ts +3 -1
  109. package/dist/internal/Auth.d.ts.map +1 -1
  110. package/dist/internal/Auth.js +6 -3
  111. package/dist/internal/Auth.js.map +1 -1
  112. package/dist/internal/EarnVaults.d.ts +3 -3
  113. package/dist/internal/EarnVaults.js +3 -3
  114. package/dist/internal/Fetch.d.ts +23 -0
  115. package/dist/internal/Fetch.d.ts.map +1 -0
  116. package/dist/internal/Fetch.js +26 -0
  117. package/dist/internal/Fetch.js.map +1 -0
  118. package/dist/internal/Log.d.ts +3 -1
  119. package/dist/internal/Log.d.ts.map +1 -1
  120. package/dist/internal/Log.js +16 -3
  121. package/dist/internal/Log.js.map +1 -1
  122. package/dist/internal/OpenApi.d.ts +5 -3
  123. package/dist/internal/OpenApi.d.ts.map +1 -1
  124. package/dist/internal/OpenApi.js +13 -3
  125. package/dist/internal/OpenApi.js.map +1 -1
  126. package/dist/internal/Response.d.ts +1 -1
  127. package/dist/internal/Response.d.ts.map +1 -1
  128. package/dist/internal/Schema.d.ts +6 -3
  129. package/dist/internal/Schema.d.ts.map +1 -1
  130. package/dist/internal/Schema.js +8 -2
  131. package/dist/internal/Schema.js.map +1 -1
  132. package/dist/internal/Store.d.ts +16 -3
  133. package/dist/internal/Store.d.ts.map +1 -1
  134. package/dist/internal/Store.js +82 -16
  135. package/dist/internal/Store.js.map +1 -1
  136. package/dist/internal/Tidx.d.ts.map +1 -1
  137. package/dist/internal/Tidx.js +7 -2
  138. package/dist/internal/Tidx.js.map +1 -1
  139. package/dist/internal/Timeout.d.ts +36 -0
  140. package/dist/internal/Timeout.d.ts.map +1 -0
  141. package/dist/internal/Timeout.js +37 -0
  142. package/dist/internal/Timeout.js.map +1 -0
  143. package/dist/internal/Timing.d.ts +9 -0
  144. package/dist/internal/Timing.d.ts.map +1 -1
  145. package/dist/internal/Timing.js +7 -0
  146. package/dist/internal/Timing.js.map +1 -1
  147. package/dist/internal/WebhookDestination.d.ts.map +1 -1
  148. package/dist/internal/WebhookDestination.js +3 -0
  149. package/dist/internal/WebhookDestination.js.map +1 -1
  150. package/dist/internal/funding/Action.d.ts +9 -0
  151. package/dist/internal/funding/Action.d.ts.map +1 -1
  152. package/dist/internal/funding/Action.js +16 -8
  153. package/dist/internal/funding/Action.js.map +1 -1
  154. package/dist/internal/funding/Catalog.d.ts +9 -2
  155. package/dist/internal/funding/Catalog.d.ts.map +1 -1
  156. package/dist/internal/funding/Catalog.js +19 -8
  157. package/dist/internal/funding/Catalog.js.map +1 -1
  158. package/dist/internal/funding/Provider.d.ts +68 -13
  159. package/dist/internal/funding/Provider.d.ts.map +1 -1
  160. package/dist/internal/funding/Provider.js +29 -8
  161. package/dist/internal/funding/Provider.js.map +1 -1
  162. package/dist/internal/funding/Transfer.d.ts +13 -12
  163. package/dist/internal/funding/Transfer.d.ts.map +1 -1
  164. package/dist/internal/funding/Transfer.js +23 -21
  165. package/dist/internal/funding/Transfer.js.map +1 -1
  166. package/dist/internal/funding/providers/stargate.d.ts +28 -9
  167. package/dist/internal/funding/providers/stargate.d.ts.map +1 -1
  168. package/dist/internal/funding/providers/stargate.js +251 -117
  169. package/dist/internal/funding/providers/stargate.js.map +1 -1
  170. package/dist/internal/index.d.ts +1 -0
  171. package/dist/internal/index.d.ts.map +1 -1
  172. package/dist/internal/index.js +1 -0
  173. package/dist/internal/index.js.map +1 -1
  174. package/package.json +2 -2
  175. package/src/App.test.ts +100 -0
  176. package/src/App.ts +42 -3
  177. package/src/Client.test-d.ts +46 -0
  178. package/src/Scope.test.ts +20 -0
  179. package/src/Scope.ts +16 -0
  180. package/src/admin/apps/api-keys.test.ts +75 -0
  181. package/src/admin/apps/api-keys.ts +64 -0
  182. package/src/admin/apps/earn-vaults.test.ts +1 -1
  183. package/src/admin/apps/earn-vaults.ts +1 -1
  184. package/src/admin/ui/src/lib/api-keys.ts +19 -0
  185. package/src/admin/ui/src/routes/api-keys.tsx +89 -2
  186. package/src/admin/ui.generated.ts +189 -151
  187. package/src/apps/Zones.test.ts +4 -4
  188. package/src/apps/Zones.ts +4 -4
  189. package/src/apps/composition.test.ts +1 -1
  190. package/src/apps/data/App.test.ts +41 -0
  191. package/src/apps/data/App.ts +18 -18
  192. package/src/apps/data/ZoneSelection.test.ts +2 -2
  193. package/src/apps/data/ZoneSelection.ts +8 -8
  194. package/src/apps/data/routes/activities.test.ts +1526 -12
  195. package/src/apps/data/routes/activities.ts +1774 -1356
  196. package/src/apps/data/routes/balances.ts +133 -97
  197. package/src/apps/data/routes/blocks.test.ts +533 -0
  198. package/src/apps/data/routes/blocks.ts +35 -16
  199. package/src/apps/data/routes/earn.test.ts +4 -2
  200. package/src/apps/data/routes/earn.ts +13 -13
  201. package/src/apps/data/routes/earn.zone-access.test.ts +6 -6
  202. package/src/apps/data/routes/receipts.ts +47 -16
  203. package/src/apps/data/routes/tokens.test.ts +578 -0
  204. package/src/apps/data/routes/tokens.ts +283 -225
  205. package/src/apps/data/routes/transactions.ts +68 -29
  206. package/src/apps/data/routes/transfers.test.ts +421 -0
  207. package/src/apps/data/routes/transfers.ts +45 -27
  208. package/src/apps/data/routes/valuation.ts +94 -78
  209. package/src/apps/data/routes/zones.test.ts +2 -2
  210. package/src/apps/data/routes/zones.ts +1 -1
  211. package/src/apps/funding/routes/deposit-addresses.test.ts +25 -3
  212. package/src/apps/funding/routes/deposit-addresses.ts +17 -12
  213. package/src/apps/funding/routes/quotes.test.ts +5 -9
  214. package/src/apps/funding/routes/transfers.test.ts +395 -8
  215. package/src/apps/funding/routes/transfers.ts +76 -59
  216. package/src/apps/management/routes/api-keys.test.ts +220 -0
  217. package/src/apps/management/routes/api-keys.ts +280 -3
  218. package/src/db/Db.ts +13 -1
  219. package/src/db/Schema.ts +5 -2
  220. package/src/db/tables/earnVaults.test.ts +9 -9
  221. package/src/db/tables/fundingCatalog.test.ts +16 -2
  222. package/src/db/tables/fundingCatalog.ts +9 -3
  223. package/src/handlers/internal/utils.test.ts +53 -0
  224. package/src/handlers/internal/utils.ts +15 -0
  225. package/src/internal/Auth.ts +12 -4
  226. package/src/internal/EarnVaults.capabilities.test.ts +2 -2
  227. package/src/internal/EarnVaults.test.ts +1 -1
  228. package/src/internal/EarnVaults.ts +3 -3
  229. package/src/internal/Fetch.test.ts +46 -0
  230. package/src/internal/Fetch.ts +56 -0
  231. package/src/internal/Log.test.ts +21 -0
  232. package/src/internal/Log.ts +20 -5
  233. package/src/internal/OpenApi.ts +14 -4
  234. package/src/internal/Response.ts +1 -1
  235. package/src/internal/Schema.test.ts +2 -0
  236. package/src/internal/Schema.ts +12 -2
  237. package/src/internal/Store.test.ts +178 -0
  238. package/src/internal/Store.ts +104 -18
  239. package/src/internal/Tidx.test.ts +2 -1
  240. package/src/internal/Tidx.ts +7 -2
  241. package/src/internal/Timeout.test.ts +35 -0
  242. package/src/internal/Timeout.ts +73 -0
  243. package/src/internal/Timing.ts +16 -0
  244. package/src/internal/WebhookDestination.ts +3 -0
  245. package/src/internal/funding/Action.test.ts +41 -1
  246. package/src/internal/funding/Action.ts +69 -41
  247. package/src/internal/funding/Catalog.test.ts +34 -0
  248. package/src/internal/funding/Catalog.ts +28 -11
  249. package/src/internal/funding/Provider.test.ts +73 -0
  250. package/src/internal/funding/Provider.ts +82 -28
  251. package/src/internal/funding/Transfer.ts +133 -110
  252. package/src/internal/funding/providers/index.test.ts +4 -167
  253. package/src/internal/funding/providers/relay.test.ts +2 -2
  254. package/src/internal/funding/providers/stargate.test.ts +163 -0
  255. package/src/internal/funding/providers/stargate.ts +359 -134
  256. package/src/internal/index.test.ts +1 -0
  257. package/src/internal/index.ts +1 -0
@@ -10,6 +10,539 @@ import * as Viem from '../../../../test/Viem.js'
10
10
  import * as Blocks from './blocks.js'
11
11
  import * as Transactions from './transactions.js'
12
12
 
13
+ describe('OpenAPI', () => {
14
+ test('publishes generator-ready block, transaction, and receipt contracts', async () => {
15
+ const app = TestApp.create({ auth: false })
16
+ const spec = await (await app.request('/openapi.json')).json()
17
+ const operations = {
18
+ block: spec.paths['/v1/blocks/{block}'].get,
19
+ blocks: spec.paths['/v1/blocks'].get,
20
+ receipt: spec.paths['/v1/transactions/{transactionHash}/receipt'].get,
21
+ receipts: spec.paths['/v1/transactions/receipts'].get,
22
+ transaction: spec.paths['/v1/transactions/{transactionHash}'].get,
23
+ transactions: spec.paths['/v1/transactions'].get,
24
+ }
25
+ const summarizeError = (
26
+ response: (typeof operations)[keyof typeof operations]['responses'][number],
27
+ ) => {
28
+ const schema = response.$ref ?? response.content?.['application/json']?.schema
29
+ if (!schema || typeof schema === 'string' || !('$ref' in schema)) return schema
30
+ const name = schema.$ref.split('/').at(-1)!
31
+ return {
32
+ codes: spec.components.schemas[name].properties.error.properties.code.enum,
33
+ schema,
34
+ }
35
+ }
36
+ const summarize = (operation: (typeof operations)[keyof typeof operations]) => ({
37
+ errors: Object.fromEntries(
38
+ [400, 401, 403, 404, 429, 500, 502]
39
+ .filter((status) => operation.responses[status])
40
+ .map((status) => [status, summarizeError(operation.responses[status])]),
41
+ ),
42
+ operationId: operation.operationId,
43
+ response: operation.responses[200].content['application/json'].schema,
44
+ })
45
+
46
+ expect({
47
+ components: [
48
+ 'Block',
49
+ 'BlockList',
50
+ 'BlockMeta',
51
+ 'BlockSummary',
52
+ 'RpcBlock',
53
+ 'RpcTransaction',
54
+ 'RpcTransactionAccessListItem',
55
+ 'RpcTransactionCall',
56
+ 'RpcTransactionLog',
57
+ 'RpcTransactionReceipt',
58
+ 'RpcTransactionSignatureEnvelope',
59
+ 'Transaction',
60
+ 'TransactionCall',
61
+ 'TransactionList',
62
+ 'TransactionListMeta',
63
+ 'TransactionMeta',
64
+ 'TransactionReceipt',
65
+ 'TransactionReceiptFeeAmount',
66
+ 'TransactionReceiptList',
67
+ 'TransactionReceiptListMeta',
68
+ 'TransactionReceiptMeta',
69
+ 'TransactionType',
70
+ ].filter((name) => spec.components.schemas[name]),
71
+ descriptions: {
72
+ signature: spec.components.schemas.RpcTransactionSignatureEnvelope.description,
73
+ },
74
+ formats: {
75
+ block: spec.components.schemas.Block.properties.timestamp.format,
76
+ blockSummary: spec.components.schemas.BlockSummary.properties.timestamp.format,
77
+ receipt: spec.components.schemas.TransactionReceipt.properties.timestamp.anyOf[0].format,
78
+ transaction: spec.components.schemas.Transaction.properties.timestamp.anyOf[0].format,
79
+ validAfter: spec.components.schemas.Transaction.properties.validAfter.anyOf[0].format,
80
+ validBefore: spec.components.schemas.Transaction.properties.validBefore.anyOf[0].format,
81
+ },
82
+ hiddenCompatibilityRoute: spec.paths['/chains/{chainId}/blocks/by-timestamp'],
83
+ models: {
84
+ blockList: spec.components.schemas.BlockList.properties.data.items,
85
+ blockMeta: spec.components.schemas.Block.properties.meta,
86
+ blockRpc: spec.components.schemas.BlockMeta.properties.rpc,
87
+ receiptFeeAmount: spec.components.schemas.TransactionReceipt.properties.feeAmount,
88
+ receiptList: spec.components.schemas.TransactionReceiptList.properties.data.items,
89
+ receiptListMeta: spec.components.schemas.TransactionReceiptList.properties.meta,
90
+ receiptLogs: spec.components.schemas.TransactionReceipt.properties.logs.items,
91
+ receiptMeta: spec.components.schemas.TransactionReceipt.properties.meta,
92
+ receiptRpc: spec.components.schemas.TransactionReceiptMeta.properties.rpc,
93
+ receiptType: spec.components.schemas.TransactionReceipt.properties.type,
94
+ rpcReceiptLogs: spec.components.schemas.RpcTransactionReceipt.properties.logs.items,
95
+ rpcTransactionAccessList:
96
+ spec.components.schemas.RpcTransaction.properties.accessList.items,
97
+ rpcTransactionCalls: spec.components.schemas.RpcTransaction.properties.calls.anyOf[0].items,
98
+ rpcTransactionFeePayerSignature:
99
+ spec.components.schemas.RpcTransaction.properties.feePayerSignature.anyOf[0],
100
+ rpcTransactionSignature: spec.components.schemas.RpcTransaction.properties.signature,
101
+ transactionCalls: spec.components.schemas.Transaction.properties.calls.items,
102
+ transactionList: spec.components.schemas.TransactionList.properties.data.items,
103
+ transactionListMeta: spec.components.schemas.TransactionList.properties.meta,
104
+ transactionMeta: spec.components.schemas.Transaction.properties.meta,
105
+ transactionReceipt: spec.components.schemas.TransactionMeta.properties.receipt,
106
+ transactionRpc: spec.components.schemas.TransactionMeta.properties.rpc,
107
+ transactionType: spec.components.schemas.Transaction.properties.type,
108
+ },
109
+ operations: Object.fromEntries(
110
+ Object.entries(operations).map(([name, operation]) => [name, summarize(operation)]),
111
+ ),
112
+ }).toMatchInlineSnapshot(`
113
+ {
114
+ "components": [
115
+ "Block",
116
+ "BlockList",
117
+ "BlockMeta",
118
+ "BlockSummary",
119
+ "RpcBlock",
120
+ "RpcTransaction",
121
+ "RpcTransactionAccessListItem",
122
+ "RpcTransactionCall",
123
+ "RpcTransactionLog",
124
+ "RpcTransactionReceipt",
125
+ "RpcTransactionSignatureEnvelope",
126
+ "Transaction",
127
+ "TransactionCall",
128
+ "TransactionList",
129
+ "TransactionListMeta",
130
+ "TransactionMeta",
131
+ "TransactionReceipt",
132
+ "TransactionReceiptFeeAmount",
133
+ "TransactionReceiptList",
134
+ "TransactionReceiptListMeta",
135
+ "TransactionReceiptMeta",
136
+ "TransactionType",
137
+ ],
138
+ "descriptions": {
139
+ "signature": "A signature envelope exactly as returned by JSON-RPC.",
140
+ },
141
+ "formats": {
142
+ "block": "date-time",
143
+ "blockSummary": "date-time",
144
+ "receipt": "date-time",
145
+ "transaction": "date-time",
146
+ "validAfter": "date-time",
147
+ "validBefore": "date-time",
148
+ },
149
+ "hiddenCompatibilityRoute": undefined,
150
+ "models": {
151
+ "blockList": {
152
+ "$ref": "#/components/schemas/BlockSummary",
153
+ },
154
+ "blockMeta": {
155
+ "$ref": "#/components/schemas/BlockMeta",
156
+ },
157
+ "blockRpc": {
158
+ "$ref": "#/components/schemas/RpcBlock",
159
+ },
160
+ "receiptFeeAmount": {
161
+ "$ref": "#/components/schemas/TransactionReceiptFeeAmount",
162
+ },
163
+ "receiptList": {
164
+ "$ref": "#/components/schemas/TransactionReceipt",
165
+ },
166
+ "receiptListMeta": {
167
+ "$ref": "#/components/schemas/TransactionReceiptListMeta",
168
+ },
169
+ "receiptLogs": {
170
+ "$ref": "#/components/schemas/RpcTransactionLog",
171
+ },
172
+ "receiptMeta": {
173
+ "$ref": "#/components/schemas/TransactionReceiptMeta",
174
+ },
175
+ "receiptRpc": {
176
+ "$ref": "#/components/schemas/RpcTransactionReceipt",
177
+ },
178
+ "receiptType": {
179
+ "$ref": "#/components/schemas/TransactionType",
180
+ },
181
+ "rpcReceiptLogs": {
182
+ "$ref": "#/components/schemas/RpcTransactionLog",
183
+ },
184
+ "rpcTransactionAccessList": {
185
+ "$ref": "#/components/schemas/RpcTransactionAccessListItem",
186
+ },
187
+ "rpcTransactionCalls": {
188
+ "$ref": "#/components/schemas/RpcTransactionCall",
189
+ },
190
+ "rpcTransactionFeePayerSignature": {
191
+ "$ref": "#/components/schemas/RpcTransactionSignatureEnvelope",
192
+ },
193
+ "rpcTransactionSignature": {
194
+ "$ref": "#/components/schemas/RpcTransactionSignatureEnvelope",
195
+ },
196
+ "transactionCalls": {
197
+ "$ref": "#/components/schemas/TransactionCall",
198
+ },
199
+ "transactionList": {
200
+ "$ref": "#/components/schemas/Transaction",
201
+ },
202
+ "transactionListMeta": {
203
+ "$ref": "#/components/schemas/TransactionListMeta",
204
+ },
205
+ "transactionMeta": {
206
+ "$ref": "#/components/schemas/TransactionMeta",
207
+ },
208
+ "transactionReceipt": {
209
+ "$ref": "#/components/schemas/TransactionReceipt",
210
+ },
211
+ "transactionRpc": {
212
+ "$ref": "#/components/schemas/RpcTransaction",
213
+ },
214
+ "transactionType": {
215
+ "$ref": "#/components/schemas/TransactionType",
216
+ },
217
+ },
218
+ "operations": {
219
+ "block": {
220
+ "errors": {
221
+ "400": {
222
+ "codes": [
223
+ "api_key_malformed",
224
+ "block_invalid",
225
+ "chain_id_invalid",
226
+ "chain_id_unsupported",
227
+ "query_invalid",
228
+ ],
229
+ "schema": {
230
+ "$ref": "#/components/schemas/ApiKeyMalformedOrBlockInvalidOrChainIdInvalidOrChainIdUnsupportedOrQueryInvalidError",
231
+ },
232
+ },
233
+ "401": {
234
+ "codes": [
235
+ "api_key_invalid",
236
+ "api_key_missing",
237
+ "unauthorized",
238
+ ],
239
+ "schema": {
240
+ "$ref": "#/components/schemas/AuthenticationError",
241
+ },
242
+ },
243
+ "403": {
244
+ "codes": [
245
+ "api_key_forbidden",
246
+ "api_key_ip_forbidden",
247
+ "forbidden",
248
+ ],
249
+ "schema": {
250
+ "$ref": "#/components/schemas/ForbiddenError",
251
+ },
252
+ },
253
+ "404": {
254
+ "codes": [
255
+ "block_not_found",
256
+ ],
257
+ "schema": {
258
+ "$ref": "#/components/schemas/BlockNotFoundError",
259
+ },
260
+ },
261
+ "429": "#/components/responses/RateLimited",
262
+ "500": "#/components/responses/InternalError",
263
+ "502": {
264
+ "codes": [
265
+ "upstream_error",
266
+ ],
267
+ "schema": {
268
+ "$ref": "#/components/schemas/UpstreamError",
269
+ },
270
+ },
271
+ },
272
+ "operationId": "getBlock",
273
+ "response": {
274
+ "$ref": "#/components/schemas/Block",
275
+ },
276
+ },
277
+ "blocks": {
278
+ "errors": {
279
+ "400": {
280
+ "codes": [
281
+ "api_key_malformed",
282
+ "chain_id_invalid",
283
+ "chain_id_unsupported",
284
+ "query_invalid",
285
+ ],
286
+ "schema": {
287
+ "$ref": "#/components/schemas/ApiKeyMalformedOrChainIdInvalidOrChainIdUnsupportedOrQueryInvalidError",
288
+ },
289
+ },
290
+ "401": {
291
+ "codes": [
292
+ "api_key_invalid",
293
+ "api_key_missing",
294
+ "unauthorized",
295
+ ],
296
+ "schema": {
297
+ "$ref": "#/components/schemas/AuthenticationError",
298
+ },
299
+ },
300
+ "403": {
301
+ "codes": [
302
+ "api_key_forbidden",
303
+ "api_key_ip_forbidden",
304
+ "forbidden",
305
+ ],
306
+ "schema": {
307
+ "$ref": "#/components/schemas/ForbiddenError",
308
+ },
309
+ },
310
+ "429": "#/components/responses/RateLimited",
311
+ "500": "#/components/responses/InternalError",
312
+ "502": {
313
+ "codes": [
314
+ "upstream_error",
315
+ ],
316
+ "schema": {
317
+ "$ref": "#/components/schemas/UpstreamError",
318
+ },
319
+ },
320
+ },
321
+ "operationId": "getBlocks",
322
+ "response": {
323
+ "$ref": "#/components/schemas/BlockList",
324
+ },
325
+ },
326
+ "receipt": {
327
+ "errors": {
328
+ "400": {
329
+ "codes": [
330
+ "api_key_malformed",
331
+ "chain_id_invalid",
332
+ "chain_id_unsupported",
333
+ "query_invalid",
334
+ "transaction_invalid",
335
+ ],
336
+ "schema": {
337
+ "$ref": "#/components/schemas/ApiKeyMalformedOrChainIdInvalidOrChainIdUnsupportedOrQueryInvalidOrTransactionInvalidError",
338
+ },
339
+ },
340
+ "401": {
341
+ "codes": [
342
+ "api_key_invalid",
343
+ "api_key_missing",
344
+ "unauthorized",
345
+ ],
346
+ "schema": {
347
+ "$ref": "#/components/schemas/AuthenticationError",
348
+ },
349
+ },
350
+ "403": {
351
+ "codes": [
352
+ "api_key_forbidden",
353
+ "api_key_ip_forbidden",
354
+ "forbidden",
355
+ ],
356
+ "schema": {
357
+ "$ref": "#/components/schemas/ForbiddenError",
358
+ },
359
+ },
360
+ "404": {
361
+ "codes": [
362
+ "receipt_not_found",
363
+ ],
364
+ "schema": {
365
+ "$ref": "#/components/schemas/ReceiptNotFoundError",
366
+ },
367
+ },
368
+ "429": "#/components/responses/RateLimited",
369
+ "500": "#/components/responses/InternalError",
370
+ "502": {
371
+ "codes": [
372
+ "upstream_error",
373
+ ],
374
+ "schema": {
375
+ "$ref": "#/components/schemas/UpstreamError",
376
+ },
377
+ },
378
+ },
379
+ "operationId": "getReceipt",
380
+ "response": {
381
+ "$ref": "#/components/schemas/TransactionReceipt",
382
+ },
383
+ },
384
+ "receipts": {
385
+ "errors": {
386
+ "400": {
387
+ "codes": [
388
+ "api_key_malformed",
389
+ "chain_id_invalid",
390
+ "chain_id_unsupported",
391
+ "query_invalid",
392
+ ],
393
+ "schema": {
394
+ "$ref": "#/components/schemas/ApiKeyMalformedOrChainIdInvalidOrChainIdUnsupportedOrQueryInvalidError",
395
+ },
396
+ },
397
+ "401": {
398
+ "codes": [
399
+ "api_key_invalid",
400
+ "api_key_missing",
401
+ "unauthorized",
402
+ ],
403
+ "schema": {
404
+ "$ref": "#/components/schemas/AuthenticationError",
405
+ },
406
+ },
407
+ "403": {
408
+ "codes": [
409
+ "api_key_forbidden",
410
+ "api_key_ip_forbidden",
411
+ "forbidden",
412
+ ],
413
+ "schema": {
414
+ "$ref": "#/components/schemas/ForbiddenError",
415
+ },
416
+ },
417
+ "429": "#/components/responses/RateLimited",
418
+ "500": "#/components/responses/InternalError",
419
+ "502": {
420
+ "codes": [
421
+ "upstream_error",
422
+ ],
423
+ "schema": {
424
+ "$ref": "#/components/schemas/UpstreamError",
425
+ },
426
+ },
427
+ },
428
+ "operationId": "getReceipts",
429
+ "response": {
430
+ "$ref": "#/components/schemas/TransactionReceiptList",
431
+ },
432
+ },
433
+ "transaction": {
434
+ "errors": {
435
+ "400": {
436
+ "codes": [
437
+ "api_key_malformed",
438
+ "chain_id_invalid",
439
+ "chain_id_unsupported",
440
+ "query_invalid",
441
+ "transaction_invalid",
442
+ ],
443
+ "schema": {
444
+ "$ref": "#/components/schemas/ApiKeyMalformedOrChainIdInvalidOrChainIdUnsupportedOrQueryInvalidOrTransactionInvalidError",
445
+ },
446
+ },
447
+ "401": {
448
+ "codes": [
449
+ "api_key_invalid",
450
+ "api_key_missing",
451
+ "unauthorized",
452
+ ],
453
+ "schema": {
454
+ "$ref": "#/components/schemas/AuthenticationError",
455
+ },
456
+ },
457
+ "403": {
458
+ "codes": [
459
+ "api_key_forbidden",
460
+ "api_key_ip_forbidden",
461
+ "forbidden",
462
+ ],
463
+ "schema": {
464
+ "$ref": "#/components/schemas/ForbiddenError",
465
+ },
466
+ },
467
+ "404": {
468
+ "codes": [
469
+ "transaction_not_found",
470
+ ],
471
+ "schema": {
472
+ "$ref": "#/components/schemas/TransactionNotFoundError",
473
+ },
474
+ },
475
+ "429": "#/components/responses/RateLimited",
476
+ "500": "#/components/responses/InternalError",
477
+ "502": {
478
+ "codes": [
479
+ "upstream_error",
480
+ ],
481
+ "schema": {
482
+ "$ref": "#/components/schemas/UpstreamError",
483
+ },
484
+ },
485
+ },
486
+ "operationId": "getTransaction",
487
+ "response": {
488
+ "$ref": "#/components/schemas/Transaction",
489
+ },
490
+ },
491
+ "transactions": {
492
+ "errors": {
493
+ "400": {
494
+ "codes": [
495
+ "api_key_malformed",
496
+ "chain_id_invalid",
497
+ "chain_id_unsupported",
498
+ "query_invalid",
499
+ ],
500
+ "schema": {
501
+ "$ref": "#/components/schemas/ApiKeyMalformedOrChainIdInvalidOrChainIdUnsupportedOrQueryInvalidError",
502
+ },
503
+ },
504
+ "401": {
505
+ "codes": [
506
+ "api_key_invalid",
507
+ "api_key_missing",
508
+ "unauthorized",
509
+ ],
510
+ "schema": {
511
+ "$ref": "#/components/schemas/AuthenticationError",
512
+ },
513
+ },
514
+ "403": {
515
+ "codes": [
516
+ "api_key_forbidden",
517
+ "api_key_ip_forbidden",
518
+ "forbidden",
519
+ ],
520
+ "schema": {
521
+ "$ref": "#/components/schemas/ForbiddenError",
522
+ },
523
+ },
524
+ "429": "#/components/responses/RateLimited",
525
+ "500": "#/components/responses/InternalError",
526
+ "502": {
527
+ "codes": [
528
+ "upstream_error",
529
+ ],
530
+ "schema": {
531
+ "$ref": "#/components/schemas/UpstreamError",
532
+ },
533
+ },
534
+ },
535
+ "operationId": "getTransactions",
536
+ "response": {
537
+ "$ref": "#/components/schemas/TransactionList",
538
+ },
539
+ },
540
+ },
541
+ }
542
+ `)
543
+ })
544
+ })
545
+
13
546
  let recent: { number: bigint; hash: Hex.Hex } | undefined
14
547
  let recentNonEmpty: { number: bigint; hash: Hex.Hex } | undefined
15
548
 
@@ -115,23 +115,28 @@ export namespace schema {
115
115
  .check(z.describe('The block exactly as returned by JSON-RPC.'))
116
116
  }
117
117
 
118
+ const rpcBlock = OpenApi.component(Rpc.Block, 'RpcBlock')
119
+
118
120
  /**
119
121
  * Metadata for a block: the verbatim JSON-RPC block (always present). Held in
120
122
  * a `meta` envelope so future opt-in `include` resources (e.g. embedded
121
123
  * transactions) can layer in without breaking the response shape.
122
124
  */
123
- export const BlockMeta = Schema.describe(
124
- z.object({
125
- rpc: Rpc.Block.check(z.describe('The original JSON-RPC block payload.')),
126
- }),
127
- 'Metadata for this block: the original JSON-RPC payload plus any future `include` resources.',
125
+ export const BlockMeta = OpenApi.component(
126
+ Schema.describe(
127
+ z.object({
128
+ rpc: rpcBlock.check(z.describe('The original JSON-RPC block payload.')),
129
+ }),
130
+ 'Metadata for this block: the original JSON-RPC payload plus any future `include` resources.',
131
+ ),
132
+ 'BlockMeta',
128
133
  )
129
134
 
130
135
  /**
131
136
  * A humanized block: decimal-string amounts, ISO 8601 timestamps, and plain
132
137
  * numbers for block fields. The verbatim JSON-RPC payload is always
133
- * available under `meta.rpc`. Transactions are omitted from the response
134
- * clients fetch them via `GET /blocks/:block/transactions`.
138
+ * available under `meta.rpc`. Transactions are omitted from the response;
139
+ * clients filter `GET /v1/transactions` to this block number.
135
140
  */
136
141
  export const Block = z
137
142
  .object({
@@ -210,6 +215,8 @@ export namespace schema {
210
215
  ),
211
216
  )
212
217
 
218
+ const block = OpenApi.component(Block, 'Block')
219
+
213
220
  /**
214
221
  * A lightweight block row, returned by the `/blocks` list endpoint. Full
215
222
  * fields (parentHash, miner, gasUsed/gasLimit, …) would require one RPC
@@ -252,6 +259,8 @@ export namespace schema {
252
259
  })
253
260
  .check(z.describe('A lightweight block summary for list responses.'))
254
261
 
262
+ const blockSummary = OpenApi.component(BlockSummary, 'BlockSummary')
263
+
255
264
  /** Schemas for the getBlocks operation. */
256
265
  export namespace getBlocks {
257
266
  /** Query parameters for `GET /blocks`. */
@@ -266,12 +275,15 @@ export namespace schema {
266
275
  .check(...Schema.pageChecks(), z.describe('Query parameters for listing blocks.'))
267
276
 
268
277
  /** Page of lightweight block rows, including empty blocks. */
269
- export const Response = z
270
- .object({
271
- data: z.array(BlockSummary).check(z.describe('Blocks on this page.')),
272
- nextCursor: Schema.NextCursor,
273
- })
274
- .check(z.describe('A page of blocks ordered by block number.'))
278
+ export const Response = OpenApi.component(
279
+ z
280
+ .object({
281
+ data: z.array(blockSummary).check(z.describe('Blocks on this page.')),
282
+ nextCursor: Schema.NextCursor,
283
+ })
284
+ .check(z.describe('A page of blocks ordered by block number.')),
285
+ 'BlockList',
286
+ )
275
287
  }
276
288
 
277
289
  /** Schemas for the getBlock operation. */
@@ -311,7 +323,7 @@ export namespace schema {
311
323
  .check(z.describe('Query parameters for looking up a block.'))
312
324
 
313
325
  /** A humanized block, with the verbatim JSON-RPC payload under `meta.rpc`. */
314
- export const Response = Block
326
+ export const Response = block
315
327
  }
316
328
 
317
329
  /**
@@ -392,7 +404,10 @@ export function blocks() {
392
404
  description: 'List the ordered batches of transactions that make up Tempo.',
393
405
  operationId: 'getBlocks',
394
406
  responses: OpenApi.responses({
395
- errors: { 502: 'Could not read indexed block data from TIDX.' },
407
+ errors: {
408
+ 400: { codes: ['chain_id_invalid', 'chain_id_unsupported', 'query_invalid'] },
409
+ 502: 'Could not read indexed block data from TIDX.',
410
+ },
396
411
  success: { description: 'A page of block summaries.', schema: schema.getBlocks.Response },
397
412
  }),
398
413
  summary: 'List blocks',
@@ -440,6 +455,9 @@ export function blocks() {
440
455
  operationId: 'getBlock',
441
456
  responses: OpenApi.responses({
442
457
  errors: {
458
+ 400: {
459
+ codes: ['block_invalid', 'chain_id_invalid', 'chain_id_unsupported', 'query_invalid'],
460
+ },
443
461
  404: {
444
462
  description:
445
463
  'No block matched the selector, or no indexed block exists at or after the timestamp.',
@@ -450,7 +468,7 @@ export function blocks() {
450
468
  success: {
451
469
  description:
452
470
  'A single block with number, timestamp, gas usage, producer, and original JSON-RPC data.',
453
- schema: schema.Block,
471
+ schema: schema.getBlock.Response,
454
472
  },
455
473
  }),
456
474
  summary: 'Get a block by selector',
@@ -604,6 +622,7 @@ export function blocksByTimestampCompat() {
604
622
  operationId: 'getBlockByTimestamp',
605
623
  responses: OpenApi.responses({
606
624
  errors: {
625
+ 400: { codes: ['chain_id_invalid', 'chain_id_unsupported', 'query_invalid'] },
607
626
  404: {
608
627
  description: 'No indexed block was found within the timestamp search window.',
609
628
  codes: ['block_not_found'],
@@ -1781,6 +1781,7 @@ describe('OpenAPI', () => {
1781
1781
  const verified = operation?.parameters?.find((parameter) => parameter.name === 'verified')
1782
1782
  const errors = errorSchemas(spec, operation)
1783
1783
  const response = JSON.stringify(operation?.responses)
1784
+ const tokenReference = JSON.stringify(spec.components?.schemas?.['TokenReference'])
1784
1785
 
1785
1786
  expect(operation?.description).toContain('currently holds shares')
1786
1787
  expect(address?.schema?.examples).toStrictEqual([TestEarn.positionAddress])
@@ -1798,8 +1799,9 @@ describe('OpenAPI', () => {
1798
1799
  expect(response).toContain('"valuation"')
1799
1800
  expect(response).toContain('"vaultAddress"')
1800
1801
  expect(response).toContain('"nextCursor"')
1801
- // Token references embed the trimmed token object, not a bare address.
1802
- expect(response).toContain('"symbol"')
1802
+ expect(response).toContain('#/components/schemas/TokenReference')
1803
+ // Token references retain display metadata through the shared component.
1804
+ expect(tokenReference).toContain('"symbol"')
1803
1805
  })
1804
1806
 
1805
1807
  test('documents vault-earnings variants', async () => {