thevoidforge 21.0.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 (328) hide show
  1. package/dist/scripts/vault-read.d.ts +11 -0
  2. package/dist/scripts/vault-read.js +89 -0
  3. package/dist/scripts/voidforge.d.ts +20 -0
  4. package/dist/scripts/voidforge.js +404 -0
  5. package/dist/tsconfig.tsbuildinfo +1 -0
  6. package/dist/wizard/api/auth.d.ts +5 -0
  7. package/dist/wizard/api/auth.js +133 -0
  8. package/dist/wizard/api/blueprint.d.ts +45 -0
  9. package/dist/wizard/api/blueprint.js +184 -0
  10. package/dist/wizard/api/cloud-providers.d.ts +16 -0
  11. package/dist/wizard/api/cloud-providers.js +363 -0
  12. package/dist/wizard/api/credentials.d.ts +1 -0
  13. package/dist/wizard/api/credentials.js +258 -0
  14. package/dist/wizard/api/danger-room.d.ts +18 -0
  15. package/dist/wizard/api/danger-room.js +401 -0
  16. package/dist/wizard/api/deploy.d.ts +4 -0
  17. package/dist/wizard/api/deploy.js +164 -0
  18. package/dist/wizard/api/prd.d.ts +1 -0
  19. package/dist/wizard/api/prd.js +363 -0
  20. package/dist/wizard/api/project.d.ts +1 -0
  21. package/dist/wizard/api/project.js +239 -0
  22. package/dist/wizard/api/projects.d.ts +6 -0
  23. package/dist/wizard/api/projects.js +648 -0
  24. package/dist/wizard/api/provision.d.ts +4 -0
  25. package/dist/wizard/api/provision.js +535 -0
  26. package/dist/wizard/api/terminal.d.ts +25 -0
  27. package/dist/wizard/api/terminal.js +241 -0
  28. package/dist/wizard/api/users.d.ts +6 -0
  29. package/dist/wizard/api/users.js +244 -0
  30. package/dist/wizard/api/war-room.d.ts +14 -0
  31. package/dist/wizard/api/war-room.js +45 -0
  32. package/dist/wizard/lib/ad-platform-core.d.ts +6 -0
  33. package/dist/wizard/lib/ad-platform-core.js +1 -0
  34. package/dist/wizard/lib/adapters/index.d.ts +52 -0
  35. package/dist/wizard/lib/adapters/index.js +38 -0
  36. package/dist/wizard/lib/adapters/sandbox-bank.d.ts +17 -0
  37. package/dist/wizard/lib/adapters/sandbox-bank.js +77 -0
  38. package/dist/wizard/lib/adapters/sandbox.d.ts +39 -0
  39. package/dist/wizard/lib/adapters/sandbox.js +174 -0
  40. package/dist/wizard/lib/adapters/stripe.d.ts +19 -0
  41. package/dist/wizard/lib/adapters/stripe.js +143 -0
  42. package/dist/wizard/lib/adapters/types.d.ts +9 -0
  43. package/dist/wizard/lib/adapters/types.js +10 -0
  44. package/dist/wizard/lib/agent-memory.d.ts +36 -0
  45. package/dist/wizard/lib/agent-memory.js +114 -0
  46. package/dist/wizard/lib/anomaly-detection.d.ts +59 -0
  47. package/dist/wizard/lib/anomaly-detection.js +122 -0
  48. package/dist/wizard/lib/anthropic.d.ts +21 -0
  49. package/dist/wizard/lib/anthropic.js +105 -0
  50. package/dist/wizard/lib/asset-scanner.d.ts +23 -0
  51. package/dist/wizard/lib/asset-scanner.js +107 -0
  52. package/dist/wizard/lib/audit-log.d.ts +23 -0
  53. package/dist/wizard/lib/audit-log.js +70 -0
  54. package/dist/wizard/lib/autonomy-controller.d.ts +76 -0
  55. package/dist/wizard/lib/autonomy-controller.js +183 -0
  56. package/dist/wizard/lib/body-parser.d.ts +2 -0
  57. package/dist/wizard/lib/body-parser.js +36 -0
  58. package/dist/wizard/lib/build-analytics.d.ts +39 -0
  59. package/dist/wizard/lib/build-analytics.js +91 -0
  60. package/dist/wizard/lib/build-step.d.ts +21 -0
  61. package/dist/wizard/lib/build-step.js +104 -0
  62. package/dist/wizard/lib/campaign-proposer.d.ts +39 -0
  63. package/dist/wizard/lib/campaign-proposer.js +180 -0
  64. package/dist/wizard/lib/campaign-state-machine.d.ts +63 -0
  65. package/dist/wizard/lib/campaign-state-machine.js +114 -0
  66. package/dist/wizard/lib/ci-generator.d.ts +14 -0
  67. package/dist/wizard/lib/ci-generator.js +187 -0
  68. package/dist/wizard/lib/claude-merge.d.ts +38 -0
  69. package/dist/wizard/lib/claude-merge.js +115 -0
  70. package/dist/wizard/lib/codegen/erd-gen.d.ts +16 -0
  71. package/dist/wizard/lib/codegen/erd-gen.js +98 -0
  72. package/dist/wizard/lib/codegen/integrations.d.ts +18 -0
  73. package/dist/wizard/lib/codegen/integrations.js +189 -0
  74. package/dist/wizard/lib/codegen/openapi-gen.d.ts +15 -0
  75. package/dist/wizard/lib/codegen/openapi-gen.js +79 -0
  76. package/dist/wizard/lib/codegen/prisma-types.d.ts +15 -0
  77. package/dist/wizard/lib/codegen/prisma-types.js +44 -0
  78. package/dist/wizard/lib/codegen/seed-gen.d.ts +16 -0
  79. package/dist/wizard/lib/codegen/seed-gen.js +128 -0
  80. package/dist/wizard/lib/compliance.d.ts +51 -0
  81. package/dist/wizard/lib/compliance.js +112 -0
  82. package/dist/wizard/lib/correlation-engine.d.ts +59 -0
  83. package/dist/wizard/lib/correlation-engine.js +151 -0
  84. package/dist/wizard/lib/cost-estimator.d.ts +22 -0
  85. package/dist/wizard/lib/cost-estimator.js +72 -0
  86. package/dist/wizard/lib/cost-tracker.d.ts +27 -0
  87. package/dist/wizard/lib/cost-tracker.js +37 -0
  88. package/dist/wizard/lib/daemon-aggregator.d.ts +71 -0
  89. package/dist/wizard/lib/daemon-aggregator.js +204 -0
  90. package/dist/wizard/lib/daemon-core.d.ts +6 -0
  91. package/dist/wizard/lib/daemon-core.js +5 -0
  92. package/dist/wizard/lib/dashboard-data.d.ts +132 -0
  93. package/dist/wizard/lib/dashboard-data.js +336 -0
  94. package/dist/wizard/lib/dashboard-ws.d.ts +25 -0
  95. package/dist/wizard/lib/dashboard-ws.js +91 -0
  96. package/dist/wizard/lib/deep-current.d.ts +77 -0
  97. package/dist/wizard/lib/deep-current.js +234 -0
  98. package/dist/wizard/lib/deploy-coordinator.d.ts +40 -0
  99. package/dist/wizard/lib/deploy-coordinator.js +86 -0
  100. package/dist/wizard/lib/deploy-log.d.ts +28 -0
  101. package/dist/wizard/lib/deploy-log.js +52 -0
  102. package/dist/wizard/lib/desktop-notify.d.ts +27 -0
  103. package/dist/wizard/lib/desktop-notify.js +98 -0
  104. package/dist/wizard/lib/dns/cloudflare-dns.d.ts +35 -0
  105. package/dist/wizard/lib/dns/cloudflare-dns.js +216 -0
  106. package/dist/wizard/lib/dns/cloudflare-registrar.d.ts +31 -0
  107. package/dist/wizard/lib/dns/cloudflare-registrar.js +148 -0
  108. package/dist/wizard/lib/dns/types.d.ts +22 -0
  109. package/dist/wizard/lib/dns/types.js +4 -0
  110. package/dist/wizard/lib/document-discovery.d.ts +33 -0
  111. package/dist/wizard/lib/document-discovery.js +145 -0
  112. package/dist/wizard/lib/env-validator.d.ts +14 -0
  113. package/dist/wizard/lib/env-validator.js +205 -0
  114. package/dist/wizard/lib/env-writer.d.ts +13 -0
  115. package/dist/wizard/lib/env-writer.js +26 -0
  116. package/dist/wizard/lib/exec.d.ts +30 -0
  117. package/dist/wizard/lib/exec.js +52 -0
  118. package/dist/wizard/lib/experiment.d.ts +70 -0
  119. package/dist/wizard/lib/experiment.js +169 -0
  120. package/dist/wizard/lib/extensions.d.ts +20 -0
  121. package/dist/wizard/lib/extensions.js +183 -0
  122. package/dist/wizard/lib/financial/adapter-factory.d.ts +47 -0
  123. package/dist/wizard/lib/financial/adapter-factory.js +225 -0
  124. package/dist/wizard/lib/financial/billing/base.d.ts +6 -0
  125. package/dist/wizard/lib/financial/billing/base.js +1 -0
  126. package/dist/wizard/lib/financial/billing/google-billing.d.ts +56 -0
  127. package/dist/wizard/lib/financial/billing/google-billing.js +298 -0
  128. package/dist/wizard/lib/financial/billing/meta-billing.d.ts +54 -0
  129. package/dist/wizard/lib/financial/billing/meta-billing.js +243 -0
  130. package/dist/wizard/lib/financial/billing/tiktok-billing.d.ts +54 -0
  131. package/dist/wizard/lib/financial/billing/tiktok-billing.js +260 -0
  132. package/dist/wizard/lib/financial/campaign/base.d.ts +13 -0
  133. package/dist/wizard/lib/financial/campaign/base.js +1 -0
  134. package/dist/wizard/lib/financial/campaign/google-campaign.d.ts +42 -0
  135. package/dist/wizard/lib/financial/campaign/google-campaign.js +388 -0
  136. package/dist/wizard/lib/financial/campaign/meta-campaign.d.ts +41 -0
  137. package/dist/wizard/lib/financial/campaign/meta-campaign.js +311 -0
  138. package/dist/wizard/lib/financial/campaign/sandbox-campaign.d.ts +45 -0
  139. package/dist/wizard/lib/financial/campaign/sandbox-campaign.js +261 -0
  140. package/dist/wizard/lib/financial/campaign/tiktok-campaign.d.ts +40 -0
  141. package/dist/wizard/lib/financial/campaign/tiktok-campaign.js +350 -0
  142. package/dist/wizard/lib/financial/funding-auto.d.ts +44 -0
  143. package/dist/wizard/lib/financial/funding-auto.js +52 -0
  144. package/dist/wizard/lib/financial/funding-policy.d.ts +60 -0
  145. package/dist/wizard/lib/financial/funding-policy.js +179 -0
  146. package/dist/wizard/lib/financial/platform-planner.d.ts +47 -0
  147. package/dist/wizard/lib/financial/platform-planner.js +134 -0
  148. package/dist/wizard/lib/financial/reconciliation-engine.d.ts +78 -0
  149. package/dist/wizard/lib/financial/reconciliation-engine.js +193 -0
  150. package/dist/wizard/lib/financial/registry.d.ts +22 -0
  151. package/dist/wizard/lib/financial/registry.js +26 -0
  152. package/dist/wizard/lib/financial/reporting.d.ts +96 -0
  153. package/dist/wizard/lib/financial/reporting.js +198 -0
  154. package/dist/wizard/lib/financial/stablecoin/base.d.ts +6 -0
  155. package/dist/wizard/lib/financial/stablecoin/base.js +1 -0
  156. package/dist/wizard/lib/financial/stablecoin/circle.d.ts +54 -0
  157. package/dist/wizard/lib/financial/stablecoin/circle.js +367 -0
  158. package/dist/wizard/lib/financial/stablecoin/mercury.d.ts +24 -0
  159. package/dist/wizard/lib/financial/stablecoin/mercury.js +171 -0
  160. package/dist/wizard/lib/financial/stablecoin/sandbox-stablecoin.d.ts +47 -0
  161. package/dist/wizard/lib/financial/stablecoin/sandbox-stablecoin.js +202 -0
  162. package/dist/wizard/lib/financial/treasury-planner.d.ts +52 -0
  163. package/dist/wizard/lib/financial/treasury-planner.js +128 -0
  164. package/dist/wizard/lib/financial-core.d.ts +6 -0
  165. package/dist/wizard/lib/financial-core.js +5 -0
  166. package/dist/wizard/lib/financial-vault.d.ts +34 -0
  167. package/dist/wizard/lib/financial-vault.js +199 -0
  168. package/dist/wizard/lib/frontmatter.d.ts +30 -0
  169. package/dist/wizard/lib/frontmatter.js +96 -0
  170. package/dist/wizard/lib/gap-analysis.d.ts +37 -0
  171. package/dist/wizard/lib/gap-analysis.js +218 -0
  172. package/dist/wizard/lib/github.d.ts +22 -0
  173. package/dist/wizard/lib/github.js +261 -0
  174. package/dist/wizard/lib/headless-deploy.d.ts +14 -0
  175. package/dist/wizard/lib/headless-deploy.js +452 -0
  176. package/dist/wizard/lib/health-monitor.d.ts +15 -0
  177. package/dist/wizard/lib/health-monitor.js +91 -0
  178. package/dist/wizard/lib/health-poller.d.ts +9 -0
  179. package/dist/wizard/lib/health-poller.js +123 -0
  180. package/dist/wizard/lib/heartbeat.d.ts +15 -0
  181. package/dist/wizard/lib/heartbeat.js +827 -0
  182. package/dist/wizard/lib/http-helpers.d.ts +9 -0
  183. package/dist/wizard/lib/http-helpers.js +24 -0
  184. package/dist/wizard/lib/image-gen.d.ts +56 -0
  185. package/dist/wizard/lib/image-gen.js +159 -0
  186. package/dist/wizard/lib/instance-sizing.d.ts +26 -0
  187. package/dist/wizard/lib/instance-sizing.js +51 -0
  188. package/dist/wizard/lib/kongo/analytics.d.ts +29 -0
  189. package/dist/wizard/lib/kongo/analytics.js +179 -0
  190. package/dist/wizard/lib/kongo/campaigns.d.ts +52 -0
  191. package/dist/wizard/lib/kongo/campaigns.js +91 -0
  192. package/dist/wizard/lib/kongo/client.d.ts +58 -0
  193. package/dist/wizard/lib/kongo/client.js +221 -0
  194. package/dist/wizard/lib/kongo/jobs.d.ts +57 -0
  195. package/dist/wizard/lib/kongo/jobs.js +122 -0
  196. package/dist/wizard/lib/kongo/pages.d.ts +60 -0
  197. package/dist/wizard/lib/kongo/pages.js +150 -0
  198. package/dist/wizard/lib/kongo/provisioner.d.ts +64 -0
  199. package/dist/wizard/lib/kongo/provisioner.js +116 -0
  200. package/dist/wizard/lib/kongo/seed.d.ts +49 -0
  201. package/dist/wizard/lib/kongo/seed.js +237 -0
  202. package/dist/wizard/lib/kongo/types.d.ts +323 -0
  203. package/dist/wizard/lib/kongo/types.js +11 -0
  204. package/dist/wizard/lib/kongo/variants.d.ts +57 -0
  205. package/dist/wizard/lib/kongo/variants.js +88 -0
  206. package/dist/wizard/lib/kongo/webhooks.d.ts +41 -0
  207. package/dist/wizard/lib/kongo/webhooks.js +112 -0
  208. package/dist/wizard/lib/marker.d.ts +28 -0
  209. package/dist/wizard/lib/marker.js +79 -0
  210. package/dist/wizard/lib/migrator.d.ts +35 -0
  211. package/dist/wizard/lib/migrator.js +190 -0
  212. package/dist/wizard/lib/natural-language-deploy.d.ts +30 -0
  213. package/dist/wizard/lib/natural-language-deploy.js +186 -0
  214. package/dist/wizard/lib/network.d.ts +22 -0
  215. package/dist/wizard/lib/network.js +72 -0
  216. package/dist/wizard/lib/oauth-core.d.ts +6 -0
  217. package/dist/wizard/lib/oauth-core.js +5 -0
  218. package/dist/wizard/lib/open-browser.d.ts +1 -0
  219. package/dist/wizard/lib/open-browser.js +26 -0
  220. package/dist/wizard/lib/patterns/ad-billing-adapter.d.ts +209 -0
  221. package/dist/wizard/lib/patterns/ad-billing-adapter.js +269 -0
  222. package/dist/wizard/lib/patterns/ad-platform-adapter.d.ts +200 -0
  223. package/dist/wizard/lib/patterns/ad-platform-adapter.js +212 -0
  224. package/dist/wizard/lib/patterns/daemon-process.d.ts +88 -0
  225. package/dist/wizard/lib/patterns/daemon-process.js +271 -0
  226. package/dist/wizard/lib/patterns/financial-transaction.d.ts +161 -0
  227. package/dist/wizard/lib/patterns/financial-transaction.js +132 -0
  228. package/dist/wizard/lib/patterns/funding-plan.d.ts +136 -0
  229. package/dist/wizard/lib/patterns/funding-plan.js +200 -0
  230. package/dist/wizard/lib/patterns/oauth-token-lifecycle.d.ts +94 -0
  231. package/dist/wizard/lib/patterns/oauth-token-lifecycle.js +139 -0
  232. package/dist/wizard/lib/patterns/outbound-rate-limiter.d.ts +67 -0
  233. package/dist/wizard/lib/patterns/outbound-rate-limiter.js +216 -0
  234. package/dist/wizard/lib/patterns/revenue-source-adapter.d.ts +96 -0
  235. package/dist/wizard/lib/patterns/revenue-source-adapter.js +182 -0
  236. package/dist/wizard/lib/patterns/stablecoin-adapter.d.ts +218 -0
  237. package/dist/wizard/lib/patterns/stablecoin-adapter.js +264 -0
  238. package/dist/wizard/lib/prd-validator.d.ts +39 -0
  239. package/dist/wizard/lib/prd-validator.js +137 -0
  240. package/dist/wizard/lib/project-init.d.ts +24 -0
  241. package/dist/wizard/lib/project-init.js +193 -0
  242. package/dist/wizard/lib/project-registry.d.ts +86 -0
  243. package/dist/wizard/lib/project-registry.js +359 -0
  244. package/dist/wizard/lib/provision-manifest.d.ts +44 -0
  245. package/dist/wizard/lib/provision-manifest.js +164 -0
  246. package/dist/wizard/lib/provisioner-registry.d.ts +15 -0
  247. package/dist/wizard/lib/provisioner-registry.js +34 -0
  248. package/dist/wizard/lib/provisioners/aws-vps.d.ts +6 -0
  249. package/dist/wizard/lib/provisioners/aws-vps.js +643 -0
  250. package/dist/wizard/lib/provisioners/cloudflare.d.ts +6 -0
  251. package/dist/wizard/lib/provisioners/cloudflare.js +300 -0
  252. package/dist/wizard/lib/provisioners/docker.d.ts +6 -0
  253. package/dist/wizard/lib/provisioners/docker.js +75 -0
  254. package/dist/wizard/lib/provisioners/http-client.d.ts +20 -0
  255. package/dist/wizard/lib/provisioners/http-client.js +79 -0
  256. package/dist/wizard/lib/provisioners/railway.d.ts +6 -0
  257. package/dist/wizard/lib/provisioners/railway.js +413 -0
  258. package/dist/wizard/lib/provisioners/scripts/caddyfile.d.ts +10 -0
  259. package/dist/wizard/lib/provisioners/scripts/caddyfile.js +54 -0
  260. package/dist/wizard/lib/provisioners/scripts/deploy-vps.d.ts +10 -0
  261. package/dist/wizard/lib/provisioners/scripts/deploy-vps.js +112 -0
  262. package/dist/wizard/lib/provisioners/scripts/docker-compose.d.ts +11 -0
  263. package/dist/wizard/lib/provisioners/scripts/docker-compose.js +91 -0
  264. package/dist/wizard/lib/provisioners/scripts/dockerfile.d.ts +5 -0
  265. package/dist/wizard/lib/provisioners/scripts/dockerfile.js +185 -0
  266. package/dist/wizard/lib/provisioners/scripts/ecosystem-config.d.ts +10 -0
  267. package/dist/wizard/lib/provisioners/scripts/ecosystem-config.js +36 -0
  268. package/dist/wizard/lib/provisioners/scripts/provision-vps.d.ts +14 -0
  269. package/dist/wizard/lib/provisioners/scripts/provision-vps.js +202 -0
  270. package/dist/wizard/lib/provisioners/scripts/rollback-vps.d.ts +10 -0
  271. package/dist/wizard/lib/provisioners/scripts/rollback-vps.js +67 -0
  272. package/dist/wizard/lib/provisioners/self-deploy.d.ts +41 -0
  273. package/dist/wizard/lib/provisioners/self-deploy.js +185 -0
  274. package/dist/wizard/lib/provisioners/static-s3.d.ts +6 -0
  275. package/dist/wizard/lib/provisioners/static-s3.js +235 -0
  276. package/dist/wizard/lib/provisioners/types.d.ts +40 -0
  277. package/dist/wizard/lib/provisioners/types.js +4 -0
  278. package/dist/wizard/lib/provisioners/vercel.d.ts +6 -0
  279. package/dist/wizard/lib/provisioners/vercel.js +287 -0
  280. package/dist/wizard/lib/pty-manager.d.ts +42 -0
  281. package/dist/wizard/lib/pty-manager.js +231 -0
  282. package/dist/wizard/lib/rate-limiter-core.d.ts +5 -0
  283. package/dist/wizard/lib/rate-limiter-core.js +5 -0
  284. package/dist/wizard/lib/reconciliation.d.ts +43 -0
  285. package/dist/wizard/lib/reconciliation.js +173 -0
  286. package/dist/wizard/lib/revenue-types.d.ts +5 -0
  287. package/dist/wizard/lib/revenue-types.js +1 -0
  288. package/dist/wizard/lib/route-optimizer.d.ts +28 -0
  289. package/dist/wizard/lib/route-optimizer.js +93 -0
  290. package/dist/wizard/lib/s3-deploy.d.ts +19 -0
  291. package/dist/wizard/lib/s3-deploy.js +156 -0
  292. package/dist/wizard/lib/safety-tiers.d.ts +76 -0
  293. package/dist/wizard/lib/safety-tiers.js +134 -0
  294. package/dist/wizard/lib/sentry-generator.d.ts +15 -0
  295. package/dist/wizard/lib/sentry-generator.js +116 -0
  296. package/dist/wizard/lib/server-config.d.ts +13 -0
  297. package/dist/wizard/lib/server-config.js +23 -0
  298. package/dist/wizard/lib/service-install.d.ts +18 -0
  299. package/dist/wizard/lib/service-install.js +182 -0
  300. package/dist/wizard/lib/site-scanner.d.ts +80 -0
  301. package/dist/wizard/lib/site-scanner.js +262 -0
  302. package/dist/wizard/lib/ssh-deploy.d.ts +25 -0
  303. package/dist/wizard/lib/ssh-deploy.js +225 -0
  304. package/dist/wizard/lib/templates.d.ts +24 -0
  305. package/dist/wizard/lib/templates.js +219 -0
  306. package/dist/wizard/lib/totp.d.ts +35 -0
  307. package/dist/wizard/lib/totp.js +276 -0
  308. package/dist/wizard/lib/tower-auth.d.ts +43 -0
  309. package/dist/wizard/lib/tower-auth.js +352 -0
  310. package/dist/wizard/lib/tower-rate-limit.d.ts +14 -0
  311. package/dist/wizard/lib/tower-rate-limit.js +61 -0
  312. package/dist/wizard/lib/tower-session.d.ts +28 -0
  313. package/dist/wizard/lib/tower-session.js +119 -0
  314. package/dist/wizard/lib/treasury-backup.d.ts +23 -0
  315. package/dist/wizard/lib/treasury-backup.js +126 -0
  316. package/dist/wizard/lib/treasury-heartbeat.d.ts +82 -0
  317. package/dist/wizard/lib/treasury-heartbeat.js +1104 -0
  318. package/dist/wizard/lib/updater.d.ts +29 -0
  319. package/dist/wizard/lib/updater.js +190 -0
  320. package/dist/wizard/lib/user-manager.d.ts +39 -0
  321. package/dist/wizard/lib/user-manager.js +182 -0
  322. package/dist/wizard/lib/vault.d.ts +26 -0
  323. package/dist/wizard/lib/vault.js +161 -0
  324. package/dist/wizard/router.d.ts +5 -0
  325. package/dist/wizard/router.js +15 -0
  326. package/dist/wizard/server.d.ts +18 -0
  327. package/dist/wizard/server.js +436 -0
  328. package/package.json +59 -0
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Financial Reporting + Export — daily reports, monthly ledgers, and funding simulation.
3
+ *
4
+ * Pure logic — no API calls, no file I/O, fully testable.
5
+ * All monetary values use branded integer cents (Cents type).
6
+ * Output formats: markdown (daily), JSON (monthly), simulation object.
7
+ *
8
+ * PRD Reference: §16 (Reporting and Reconciliation)
9
+ * Agents: Dockson (treasury), Heartbeat daemon
10
+ */
11
+ import { forecastSpend } from './treasury-planner.js';
12
+ import { evaluatePolicy, aggregateDecisions } from './funding-policy.js';
13
+ // ── Shared Helpers ───────────────────────────────────
14
+ function centsToUsd(cents) {
15
+ return `$${(cents / 100).toFixed(2)}`;
16
+ }
17
+ // ── Daily Report Generator ───────────────────────────
18
+ export function generateDailyReport(input) {
19
+ const netCents = input.revenueCents - input.spendCents;
20
+ const netSign = netCents >= 0 ? '+' : '';
21
+ const lines = [
22
+ `# Treasury Daily Report — ${input.date}`,
23
+ '',
24
+ '## Revenue & Spend',
25
+ `| Metric | Amount |`,
26
+ `|--------|--------|`,
27
+ `| Revenue | ${centsToUsd(input.revenueCents)} |`,
28
+ `| Spend | ${centsToUsd(input.spendCents)} |`,
29
+ `| **Net** | **${netSign}${centsToUsd(netCents)}** |`,
30
+ '',
31
+ '## Stablecoin Position',
32
+ `| Metric | Amount |`,
33
+ `|--------|--------|`,
34
+ `| Stablecoin Balance | ${centsToUsd(input.stablecoinBalanceCents)} |`,
35
+ `| Pending Transfers | ${centsToUsd(input.pendingTransfersCents)} |`,
36
+ '',
37
+ '## Bank Position',
38
+ `| Metric | Amount |`,
39
+ `|--------|--------|`,
40
+ `| Bank Balance | ${centsToUsd(input.bankBalanceCents)} |`,
41
+ `| Settled Today | ${centsToUsd(input.settledTodayCents)} |`,
42
+ `| Runway | ${input.runwayDays === Infinity ? 'Unlimited' : `${input.runwayDays} days`} |`,
43
+ '',
44
+ ];
45
+ // Reconciliation section
46
+ if (input.reconciliation) {
47
+ const r = input.reconciliation;
48
+ lines.push('## Reconciliation', `| Metric | Value |`, `|--------|-------|`, `| Transfers Matched | ${r.transferMatches.length} |`, `| Spend Matched | ${r.spendMatches.length} |`, `| Unmatched Transfers | ${r.unmatchedTransfers.length} |`, `| Unmatched Bank Txns | ${r.unmatchedBankTransactions.length} |`, `| Overall Variance | ${centsToUsd(r.overallVarianceCents)} |`, `| Mismatches | ${r.mismatchCount} |`, '');
49
+ }
50
+ else {
51
+ lines.push('## Reconciliation', '', 'No reconciliation data for this date.', '');
52
+ }
53
+ // Circuit breakers
54
+ if (input.activeCircuitBreakers.length > 0 || input.fundingFrozen) {
55
+ lines.push('## Circuit Breakers', '');
56
+ if (input.fundingFrozen) {
57
+ lines.push(`**FUNDING FROZEN:** ${input.freezeReason ?? 'Unknown reason'}`, '');
58
+ }
59
+ for (const cb of input.activeCircuitBreakers) {
60
+ lines.push(`- ${cb}`);
61
+ }
62
+ lines.push('');
63
+ }
64
+ return lines.join('\n');
65
+ }
66
+ // ── Monthly Ledger Generator ─────────────────────────
67
+ export function generateMonthlyLedger(month, transfers, reconciliations) {
68
+ const totalTransfersCents = transfers.reduce((sum, t) => sum + t.amountCents, 0);
69
+ const totalFeesCents = transfers.reduce((sum, t) => sum + t.feesCents, 0);
70
+ const totalNetTransferredCents = transfers.reduce((sum, t) => sum + t.netAmountCents, 0);
71
+ const totalSpendCents = reconciliations.reduce((sum, r) => sum + r.spendCents, 0);
72
+ const totalBankSettledCents = reconciliations.reduce((sum, r) => sum + r.bankSettledCents, 0);
73
+ const totalVarianceCents = reconciliations.reduce((sum, r) => sum + r.varianceCents, 0);
74
+ const mismatchCount = reconciliations.filter(r => r.result === 'MISMATCH').length;
75
+ return {
76
+ month,
77
+ generatedAt: new Date().toISOString(),
78
+ transfers,
79
+ reconciliations,
80
+ summary: {
81
+ totalTransfersCents,
82
+ totalFeesCents,
83
+ totalNetTransferredCents,
84
+ totalSpendCents,
85
+ totalBankSettledCents,
86
+ totalVarianceCents,
87
+ transferCount: transfers.length,
88
+ reconciliationCount: reconciliations.length,
89
+ mismatchCount,
90
+ },
91
+ };
92
+ }
93
+ // ── Funding Simulation ───────────────────────────────
94
+ // Projects forward N days showing when off-ramp triggers,
95
+ // expected bank balance trajectory, and freeze risk dates.
96
+ export function simulateFunding(startDate, startingBankBalanceCents, config, campaigns, days, stablecoinAvailableCents, minimumBufferCents) {
97
+ const dailySpendCents = forecastSpend(campaigns, 1);
98
+ const simDays = [];
99
+ let bankBalance = startingBankBalanceCents;
100
+ let stablecoinRemaining = stablecoinAvailableCents;
101
+ let firstOfframpDay = null;
102
+ let totalOfframpsCents = 0;
103
+ let offrampCount = 0;
104
+ let minimumBalance = bankBalance;
105
+ let minimumBalanceDay = 0;
106
+ const freezeRiskDays = [];
107
+ const startMs = new Date(startDate).getTime();
108
+ const oneDayMs = 24 * 60 * 60 * 1000;
109
+ for (let d = 0; d < days; d++) {
110
+ const dayDate = new Date(startMs + d * oneDayMs).toISOString().slice(0, 10);
111
+ const spend = dailySpendCents;
112
+ // Deduct daily spend
113
+ bankBalance -= spend;
114
+ // Check if off-ramp should trigger
115
+ let offrampTriggered = false;
116
+ let offrampAmount = 0;
117
+ let policyBlocked = false;
118
+ let freezeRisk = false;
119
+ if (bankBalance < config.bufferTargetCents) {
120
+ // Need an off-ramp
121
+ const deficit = config.bufferTargetCents - bankBalance;
122
+ const clampedAmount = Math.min(deficit, config.maxDailyOfframpCents, stablecoinRemaining);
123
+ if (clampedAmount >= config.minimumOfframpCents && stablecoinRemaining > 0) {
124
+ // Simulate policy evaluation
125
+ const policyState = {
126
+ bankBalanceCents: bankBalance,
127
+ minimumBufferCents,
128
+ reservedCents: 0,
129
+ proposedOfframpCents: clampedAmount,
130
+ maxDailyMovementCents: config.maxDailyOfframpCents,
131
+ googleInvoiceDueSoon: false,
132
+ googleInvoiceCents: 0,
133
+ metaUsesDirectDebit: false,
134
+ metaForecast7DayCents: 0,
135
+ debitProtectionBufferCents: 0,
136
+ discrepancyExists: false,
137
+ proposingBudgetRaise: false,
138
+ platformCapability: 'FULLY_FUNDABLE',
139
+ claimingAutonomousFunding: true,
140
+ };
141
+ const decisions = evaluatePolicy(policyState);
142
+ const aggregate = aggregateDecisions(decisions);
143
+ if (aggregate.action === 'allow') {
144
+ offrampTriggered = true;
145
+ offrampAmount = clampedAmount;
146
+ bankBalance += clampedAmount;
147
+ stablecoinRemaining -= clampedAmount;
148
+ totalOfframpsCents += clampedAmount;
149
+ offrampCount++;
150
+ if (firstOfframpDay === null)
151
+ firstOfframpDay = d + 1;
152
+ }
153
+ else {
154
+ policyBlocked = true;
155
+ }
156
+ }
157
+ }
158
+ // Freeze risk: balance below minimum buffer
159
+ if (bankBalance < minimumBufferCents) {
160
+ freezeRisk = true;
161
+ freezeRiskDays.push(d + 1);
162
+ }
163
+ // Track minimum balance
164
+ if (bankBalance < minimumBalance) {
165
+ minimumBalance = bankBalance;
166
+ minimumBalanceDay = d + 1;
167
+ }
168
+ simDays.push({
169
+ day: d + 1,
170
+ date: dayDate,
171
+ bankBalanceCents: Math.round(bankBalance),
172
+ spendCents: spend,
173
+ offrampTriggered,
174
+ offrampAmountCents: Math.round(offrampAmount),
175
+ policyBlocked,
176
+ freezeRisk,
177
+ });
178
+ }
179
+ return {
180
+ config: {
181
+ startDate,
182
+ days,
183
+ startingBankBalanceCents,
184
+ bufferTargetCents: config.bufferTargetCents,
185
+ maxDailyOfframpCents: config.maxDailyOfframpCents,
186
+ },
187
+ days: simDays,
188
+ summary: {
189
+ firstOfframpDay,
190
+ totalOfframpsCents: Math.round(totalOfframpsCents),
191
+ offrampCount,
192
+ minimumBalanceCents: Math.round(minimumBalance),
193
+ minimumBalanceDay,
194
+ freezeRiskDays,
195
+ finalBalanceCents: Math.round(bankBalance),
196
+ },
197
+ };
198
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Stablecoin adapter types — re-exports from the pattern file.
3
+ * ARCH-R2-012: Production code should not import from docs/patterns/ directly.
4
+ */
5
+ export type { StablecoinSetup, StablecoinAdapter, StablecoinProvider, SupportedAsset, ProviderCredentials, StablecoinBalance, FiatBalance, CombinedBalances, OfframpQuote, TransferStatus, TransferRecord, TransferStatusDetail, FundingPlanRef, DateRange, } from '../../patterns/stablecoin-adapter.js';
6
+ export { toCents, toDollars, computeTransferHash } from '../../patterns/stablecoin-adapter.js';
@@ -0,0 +1 @@
1
+ export { toCents, toDollars, computeTransferHash } from '../../patterns/stablecoin-adapter.js';
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Circle Stablecoin Adapter — real implementation via node:https (zero new dependencies).
3
+ *
4
+ * Implements StablecoinSetup (interactive CLI) + StablecoinAdapter (daemon runtime)
5
+ * for Circle's Business Account API v1.
6
+ *
7
+ * Circle API v1:
8
+ * Base URL: https://api.circle.com/v1
9
+ * Auth: Authorization: Bearer {apiKey}
10
+ *
11
+ * PRD Reference: §11.1A, §12.1, §12.4, §12.5
12
+ * No Stubs Doctrine: every method makes a real API call (except quoteRedemption — local computation).
13
+ */
14
+ import type { StablecoinSetup, StablecoinAdapter, ProviderCredentials, SupportedAsset, StablecoinBalance, CombinedBalances, OfframpQuote, TransferRecord, TransferStatusDetail, FundingPlanRef, DateRange } from './base.js';
15
+ type Cents = number & {
16
+ readonly __brand: 'Cents';
17
+ };
18
+ export declare class CircleSetup implements StablecoinSetup {
19
+ private apiKey;
20
+ constructor(apiKey: string);
21
+ authenticate(_credentials: ProviderCredentials): Promise<{
22
+ valid: boolean;
23
+ accountId?: string;
24
+ permissions?: string[];
25
+ error?: string;
26
+ }>;
27
+ verifySupportedAssets(_credentials: ProviderCredentials): Promise<SupportedAsset[]>;
28
+ verifyLinkedBank(_credentials: ProviderCredentials): Promise<{
29
+ linked: boolean;
30
+ bankId?: string;
31
+ bankName?: string;
32
+ accountLast4?: string;
33
+ error?: string;
34
+ }>;
35
+ getInitialBalances(_credentials: ProviderCredentials): Promise<StablecoinBalance[]>;
36
+ }
37
+ export declare class CircleAdapter implements StablecoinAdapter {
38
+ private apiKey;
39
+ private bankId;
40
+ constructor(config: {
41
+ apiKey: string;
42
+ bankId: string;
43
+ });
44
+ getBalances(): Promise<CombinedBalances>;
45
+ quoteRedemption(amountCents: Cents): Promise<OfframpQuote>;
46
+ initiateOfframp(plan: FundingPlanRef, previousHash: string): Promise<TransferRecord>;
47
+ getTransferStatus(transferId: string): Promise<TransferStatusDetail>;
48
+ cancelTransfer(_transferId: string): Promise<{
49
+ cancelled: boolean;
50
+ reason?: string;
51
+ }>;
52
+ listCompletedTransfers(dateRange: DateRange): Promise<TransferRecord[]>;
53
+ }
54
+ export {};
@@ -0,0 +1,367 @@
1
+ /**
2
+ * Circle Stablecoin Adapter — real implementation via node:https (zero new dependencies).
3
+ *
4
+ * Implements StablecoinSetup (interactive CLI) + StablecoinAdapter (daemon runtime)
5
+ * for Circle's Business Account API v1.
6
+ *
7
+ * Circle API v1:
8
+ * Base URL: https://api.circle.com/v1
9
+ * Auth: Authorization: Bearer {apiKey}
10
+ *
11
+ * PRD Reference: §11.1A, §12.1, §12.4, §12.5
12
+ * No Stubs Doctrine: every method makes a real API call (except quoteRedemption — local computation).
13
+ */
14
+ import { randomUUID } from 'node:crypto';
15
+ import { request as httpsRequest } from 'node:https';
16
+ import { toCents, toDollars, computeTransferHash } from './base.js';
17
+ const CIRCLE_HOST = 'api.circle.com';
18
+ // ── HTTP helpers ─────────────────────────────────────
19
+ async function circleGet(path, apiKey, params) {
20
+ const query = params ? '?' + new URLSearchParams(params).toString() : '';
21
+ return new Promise((resolve, reject) => {
22
+ const req = httpsRequest({
23
+ hostname: CIRCLE_HOST,
24
+ path: `/v1${path}${query}`,
25
+ method: 'GET',
26
+ headers: {
27
+ 'Authorization': `Bearer ${apiKey}`,
28
+ 'Accept': 'application/json',
29
+ },
30
+ timeout: 15000,
31
+ }, (res) => {
32
+ let data = '';
33
+ res.on('data', (chunk) => { data += chunk.toString(); });
34
+ res.on('end', () => resolve({ status: res.statusCode ?? 500, body: data }));
35
+ });
36
+ req.on('error', reject);
37
+ req.on('timeout', () => { req.destroy(); reject(new Error('Circle API timeout')); });
38
+ req.end();
39
+ });
40
+ }
41
+ async function circlePost(path, apiKey, body) {
42
+ const payload = JSON.stringify(body);
43
+ return new Promise((resolve, reject) => {
44
+ const req = httpsRequest({
45
+ hostname: CIRCLE_HOST,
46
+ path: `/v1${path}`,
47
+ method: 'POST',
48
+ headers: {
49
+ 'Authorization': `Bearer ${apiKey}`,
50
+ 'Content-Type': 'application/json',
51
+ 'Accept': 'application/json',
52
+ },
53
+ timeout: 15000,
54
+ }, (res) => {
55
+ let data = '';
56
+ res.on('data', (chunk) => { data += chunk.toString(); });
57
+ res.on('end', () => resolve({ status: res.statusCode ?? 500, body: data }));
58
+ });
59
+ req.on('error', reject);
60
+ req.on('timeout', () => { req.destroy(); reject(new Error('Circle API timeout')); });
61
+ req.write(payload);
62
+ req.end();
63
+ });
64
+ }
65
+ /** Parse JSON response body; on failure return a descriptive error object. */
66
+ function safeParseJson(body) {
67
+ // VG-R1-005: Wrap error-path JSON.parse in try/catch
68
+ try {
69
+ return JSON.parse(body);
70
+ }
71
+ catch {
72
+ return { error: { message: 'Non-JSON response from Circle API' } };
73
+ }
74
+ }
75
+ /** Map Circle payout status strings to our TransferStatus union. */
76
+ function mapCircleStatus(circleStatus) {
77
+ switch (circleStatus) {
78
+ case 'pending': return 'pending';
79
+ case 'processing': return 'processing';
80
+ case 'complete': return 'completed';
81
+ case 'failed': return 'failed';
82
+ default: return 'pending';
83
+ }
84
+ }
85
+ // ── Setup Implementation ─────────────────────────────
86
+ export class CircleSetup {
87
+ apiKey;
88
+ constructor(apiKey) {
89
+ this.apiKey = apiKey;
90
+ }
91
+ async authenticate(_credentials) {
92
+ try {
93
+ const { status, body } = await circleGet('/configuration', this.apiKey);
94
+ if (status === 200) {
95
+ const data = safeParseJson(body);
96
+ const payments = data.data?.payments;
97
+ return {
98
+ valid: true,
99
+ accountId: payments?.masterWalletId,
100
+ permissions: ['read_balances', 'initiate_payouts', 'read_payouts'],
101
+ };
102
+ }
103
+ const parsed = safeParseJson(body);
104
+ const err = parsed.error;
105
+ return { valid: false, error: err?.message ?? `HTTP ${status}` };
106
+ }
107
+ catch (err) {
108
+ return { valid: false, error: err instanceof Error ? err.message : 'Connection failed' };
109
+ }
110
+ }
111
+ async verifySupportedAssets(_credentials) {
112
+ // Circle supports USDC on multiple networks. The /configuration endpoint
113
+ // confirms available chains but does not list contract addresses per-chain.
114
+ // We return the known production USDC contract addresses for supported networks.
115
+ return [
116
+ { asset: 'USDC', network: 'ETH', contractAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', minRedemption: toCents(100) },
117
+ { asset: 'USDC', network: 'SOL', contractAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', minRedemption: toCents(100) },
118
+ { asset: 'USDC', network: 'MATIC', contractAddress: '0x3c499c542cef5e3811e1192ce70d8cc03d5c3359', minRedemption: toCents(100) },
119
+ { asset: 'USDC', network: 'AVAX', contractAddress: '0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e', minRedemption: toCents(100) },
120
+ ];
121
+ }
122
+ async verifyLinkedBank(_credentials) {
123
+ try {
124
+ const { status, body } = await circleGet('/businessAccount/banks/wires', this.apiKey);
125
+ if (status !== 200) {
126
+ const parsed = safeParseJson(body);
127
+ const err = parsed.error;
128
+ return { linked: false, error: err?.message ?? `HTTP ${status}` };
129
+ }
130
+ const parsed = safeParseJson(body);
131
+ const banks = parsed.data;
132
+ if (!banks || banks.length === 0) {
133
+ return { linked: false, error: 'No linked wire bank accounts found in Circle' };
134
+ }
135
+ const primary = banks[0];
136
+ const billingDetails = primary.billingDetails;
137
+ return {
138
+ linked: true,
139
+ bankId: primary.id,
140
+ bankName: billingDetails?.name,
141
+ accountLast4: primary.trackingRef
142
+ ? primary.trackingRef.slice(-4)
143
+ : undefined,
144
+ };
145
+ }
146
+ catch (err) {
147
+ return { linked: false, error: err instanceof Error ? err.message : 'Connection failed' };
148
+ }
149
+ }
150
+ async getInitialBalances(_credentials) {
151
+ try {
152
+ const { status, body } = await circleGet('/businessAccount/balances', this.apiKey);
153
+ if (status !== 200)
154
+ return [];
155
+ const parsed = safeParseJson(body);
156
+ const data = parsed.data;
157
+ const available = data?.available;
158
+ if (!available)
159
+ return [];
160
+ const now = new Date().toISOString();
161
+ return available
162
+ .filter(b => b.currency === 'USD')
163
+ .map(b => ({
164
+ provider: 'circle',
165
+ asset: 'USDC',
166
+ network: 'ETH',
167
+ balanceCents: toCents(parseFloat(b.amount)),
168
+ lastUpdated: now,
169
+ }));
170
+ }
171
+ catch {
172
+ return [];
173
+ }
174
+ }
175
+ }
176
+ // ── Runtime Adapter Implementation ───────────────────
177
+ export class CircleAdapter {
178
+ apiKey;
179
+ bankId;
180
+ constructor(config) {
181
+ this.apiKey = config.apiKey;
182
+ this.bankId = config.bankId;
183
+ }
184
+ async getBalances() {
185
+ const { status, body } = await circleGet('/businessAccount/balances', this.apiKey);
186
+ if (status !== 200) {
187
+ // VG-R1-005: safe parse
188
+ let errorMsg = `HTTP ${status}`;
189
+ try {
190
+ const e = JSON.parse(body);
191
+ errorMsg = e.error?.message ?? errorMsg;
192
+ }
193
+ catch { /* non-JSON */ }
194
+ throw new Error(`Circle getBalances failed: ${errorMsg}`);
195
+ }
196
+ const parsed = safeParseJson(body);
197
+ const data = parsed.data;
198
+ const available = data?.available ?? [];
199
+ const now = new Date().toISOString();
200
+ const stablecoin = available
201
+ .filter(b => b.currency === 'USD')
202
+ .map(b => ({
203
+ provider: 'circle',
204
+ asset: 'USDC',
205
+ network: 'ETH',
206
+ balanceCents: toCents(parseFloat(b.amount)),
207
+ lastUpdated: now,
208
+ }));
209
+ const totalStablecoinCents = stablecoin.reduce((sum, b) => (sum + b.balanceCents), 0);
210
+ return {
211
+ stablecoin,
212
+ fiat: [],
213
+ totalStablecoinCents,
214
+ totalFiatAvailableCents: 0,
215
+ };
216
+ }
217
+ async quoteRedemption(amountCents) {
218
+ // Circle wire payout fee: typically $25 flat for domestic wire.
219
+ // No API endpoint for quotes — computed locally based on known fee structure.
220
+ const feeCents = toCents(25);
221
+ return {
222
+ provider: 'circle',
223
+ sourceAsset: 'USDC',
224
+ sourceNetwork: 'ETH',
225
+ requestedCents: amountCents,
226
+ estimatedFeeCents: feeCents,
227
+ estimatedNetCents: (amountCents - feeCents),
228
+ estimatedSettlementMinutes: 24 * 60, // 1 business day
229
+ expiresAt: new Date(Date.now() + 5 * 60 * 1000).toISOString(),
230
+ };
231
+ }
232
+ async initiateOfframp(plan, previousHash) {
233
+ const { status, body } = await circlePost('/businessAccount/payouts', this.apiKey, {
234
+ idempotencyKey: plan.idempotencyKey,
235
+ source: { type: 'wallet', id: 'master' },
236
+ destination: { type: 'wire', id: this.bankId },
237
+ amount: { amount: toDollars(plan.requiredCents).toFixed(2), currency: 'USD' },
238
+ });
239
+ if (status !== 200 && status !== 201) {
240
+ // VG-R1-005: safe parse
241
+ let errorMsg = `HTTP ${status}`;
242
+ try {
243
+ const e = JSON.parse(body);
244
+ errorMsg = e.error?.message ?? errorMsg;
245
+ }
246
+ catch { /* non-JSON */ }
247
+ throw new Error(`Circle initiateOfframp failed: ${errorMsg}`);
248
+ }
249
+ const parsed = safeParseJson(body);
250
+ const payout = parsed.data;
251
+ const now = new Date().toISOString();
252
+ const id = randomUUID();
253
+ const feeCents = toCents(25);
254
+ const record = {
255
+ id,
256
+ fundingPlanId: plan.id,
257
+ providerTransferId: payout.id,
258
+ provider: 'circle',
259
+ direction: 'crypto_to_fiat',
260
+ sourceAsset: 'USDC',
261
+ sourceNetwork: 'ETH',
262
+ amountCents: plan.requiredCents,
263
+ feesCents: feeCents,
264
+ netAmountCents: (plan.requiredCents - feeCents),
265
+ destinationBankId: plan.destinationBankId,
266
+ status: 'pending',
267
+ initiatedAt: now,
268
+ idempotencyKey: plan.idempotencyKey,
269
+ previousHash,
270
+ };
271
+ const hash = computeTransferHash(record, previousHash);
272
+ return { ...record, hash };
273
+ }
274
+ async getTransferStatus(transferId) {
275
+ const { status, body } = await circleGet(`/businessAccount/payouts/${transferId}`, this.apiKey);
276
+ if (status !== 200) {
277
+ let errorMsg = `HTTP ${status}`;
278
+ try {
279
+ const e = JSON.parse(body);
280
+ errorMsg = e.error?.message ?? errorMsg;
281
+ }
282
+ catch { /* non-JSON */ }
283
+ throw new Error(`Circle getTransferStatus failed: ${errorMsg}`);
284
+ }
285
+ const parsed = safeParseJson(body);
286
+ const payout = parsed.data;
287
+ const amount = payout.amount;
288
+ const fees = payout.fees;
289
+ const mappedStatus = mapCircleStatus(payout.status);
290
+ return {
291
+ transferId,
292
+ providerTransferId: payout.id,
293
+ status: mappedStatus,
294
+ amountCents: toCents(parseFloat(amount.amount)),
295
+ feesCents: fees ? toCents(parseFloat(fees.amount)) : 0,
296
+ initiatedAt: payout.createDate,
297
+ completedAt: mappedStatus === 'completed' ? payout.updateDate : undefined,
298
+ estimatedCompletionAt: mappedStatus !== 'completed'
299
+ ? new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString()
300
+ : undefined,
301
+ providerRawStatus: payout.status,
302
+ };
303
+ }
304
+ async cancelTransfer(_transferId) {
305
+ // Circle does not support programmatic payout cancellation via API.
306
+ // Wire payouts cannot be cancelled once submitted.
307
+ return {
308
+ cancelled: false,
309
+ reason: 'Circle does not support programmatic payout cancellation. Contact support for pending payouts.',
310
+ };
311
+ }
312
+ async listCompletedTransfers(dateRange) {
313
+ const params = {
314
+ destination: this.bankId,
315
+ status: 'complete',
316
+ };
317
+ const { status, body } = await circleGet('/businessAccount/payouts', this.apiKey, params);
318
+ if (status !== 200) {
319
+ let errorMsg = `HTTP ${status}`;
320
+ try {
321
+ const e = JSON.parse(body);
322
+ errorMsg = e.error?.message ?? errorMsg;
323
+ }
324
+ catch { /* non-JSON */ }
325
+ throw new Error(`Circle listCompletedTransfers failed: ${errorMsg}`);
326
+ }
327
+ const parsed = safeParseJson(body);
328
+ const payouts = parsed.data ?? [];
329
+ const rangeStart = new Date(dateRange.start).getTime();
330
+ const rangeEnd = new Date(dateRange.end).getTime();
331
+ // Filter by date range client-side (Circle API pagination doesn't support date filters directly)
332
+ return payouts
333
+ .filter(p => {
334
+ const created = new Date(p.createDate).getTime();
335
+ return created >= rangeStart && created <= rangeEnd;
336
+ })
337
+ .map(p => {
338
+ const amount = p.amount;
339
+ const fees = p.fees;
340
+ const amountCents = toCents(parseFloat(amount.amount));
341
+ const feesCents = fees ? toCents(parseFloat(fees.amount)) : toCents(0);
342
+ // Use Circle payout ID as stable identifier instead of randomUUID()
343
+ // to ensure idempotent reads return consistent IDs for the same payout.
344
+ const id = p.id;
345
+ const record = {
346
+ id,
347
+ fundingPlanId: '',
348
+ providerTransferId: p.id,
349
+ provider: 'circle',
350
+ direction: 'crypto_to_fiat',
351
+ sourceAsset: 'USDC',
352
+ sourceNetwork: 'ETH',
353
+ amountCents,
354
+ feesCents,
355
+ netAmountCents: (amountCents - feesCents),
356
+ destinationBankId: this.bankId,
357
+ status: 'completed',
358
+ initiatedAt: p.createDate,
359
+ completedAt: p.updateDate,
360
+ idempotencyKey: '',
361
+ previousHash: '',
362
+ };
363
+ const hash = computeTransferHash(record, '');
364
+ return { ...record, hash };
365
+ });
366
+ }
367
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Mercury Bank Adapter — real implementation via node:https (zero new dependencies).
3
+ *
4
+ * Implements RevenueSourceAdapter for Mercury's REST API.
5
+ * Mercury is a bank, not a stablecoin provider — this reads bank balances
6
+ * and transactions for treasury visibility (same pattern as Stripe adapter).
7
+ *
8
+ * Mercury API v1:
9
+ * Base URL: https://api.mercury.com/api/v1
10
+ * Auth: Authorization: Bearer {apiKey}
11
+ *
12
+ * PRD Reference: §12.2 (Operating Bank Account)
13
+ * No Stubs Doctrine: every method makes a real API call.
14
+ */
15
+ import type { RevenueSourceAdapter, RevenueCredentials, ConnectionResult, TransactionPage, BalanceResult, DateRange } from '../../revenue-types.js';
16
+ export declare class MercuryBankAdapter implements RevenueSourceAdapter {
17
+ private apiKey;
18
+ private accountId;
19
+ constructor(apiKey: string, accountId?: string);
20
+ connect(_credentials?: RevenueCredentials): Promise<ConnectionResult>;
21
+ detectCurrency(_credentials?: RevenueCredentials): Promise<string>;
22
+ getTransactions(range: DateRange, cursor?: string): Promise<TransactionPage>;
23
+ getBalance(): Promise<BalanceResult>;
24
+ }