tapimo 0.0.2 → 0.2.0

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