sorokeep 1.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 (275) hide show
  1. package/CONTRIBUTING.md +296 -0
  2. package/LICENSE +21 -0
  3. package/README.md +677 -0
  4. package/dist/alerts/alerts.d.ts +21 -0
  5. package/dist/alerts/alerts.d.ts.map +1 -0
  6. package/dist/alerts/alerts.js +18 -0
  7. package/dist/alerts/alerts.js.map +1 -0
  8. package/dist/alerts/discord.d.ts +3 -0
  9. package/dist/alerts/discord.d.ts.map +1 -0
  10. package/dist/alerts/discord.js +199 -0
  11. package/dist/alerts/discord.js.map +1 -0
  12. package/dist/alerts/dispatcher.d.ts +13 -0
  13. package/dist/alerts/dispatcher.d.ts.map +1 -0
  14. package/dist/alerts/dispatcher.js +91 -0
  15. package/dist/alerts/dispatcher.js.map +1 -0
  16. package/dist/alerts/keys.d.ts +24 -0
  17. package/dist/alerts/keys.d.ts.map +1 -0
  18. package/dist/alerts/keys.js +44 -0
  19. package/dist/alerts/keys.js.map +1 -0
  20. package/dist/alerts/pagerduty.d.ts +8 -0
  21. package/dist/alerts/pagerduty.d.ts.map +1 -0
  22. package/dist/alerts/pagerduty.js +164 -0
  23. package/dist/alerts/pagerduty.js.map +1 -0
  24. package/dist/alerts/resource.d.ts +23 -0
  25. package/dist/alerts/resource.d.ts.map +1 -0
  26. package/dist/alerts/resource.js +167 -0
  27. package/dist/alerts/resource.js.map +1 -0
  28. package/dist/alerts/slack.d.ts +7 -0
  29. package/dist/alerts/slack.d.ts.map +1 -0
  30. package/dist/alerts/slack.js +184 -0
  31. package/dist/alerts/slack.js.map +1 -0
  32. package/dist/alerts/telegram.d.ts +9 -0
  33. package/dist/alerts/telegram.d.ts.map +1 -0
  34. package/dist/alerts/telegram.js +133 -0
  35. package/dist/alerts/telegram.js.map +1 -0
  36. package/dist/alerts/templates.d.ts +109 -0
  37. package/dist/alerts/templates.d.ts.map +1 -0
  38. package/dist/alerts/templates.js +139 -0
  39. package/dist/alerts/templates.js.map +1 -0
  40. package/dist/alerts/types.d.ts +113 -0
  41. package/dist/alerts/types.d.ts.map +1 -0
  42. package/dist/alerts/types.js +87 -0
  43. package/dist/alerts/types.js.map +1 -0
  44. package/dist/alerts/webhook.d.ts +13 -0
  45. package/dist/alerts/webhook.d.ts.map +1 -0
  46. package/dist/alerts/webhook.js +56 -0
  47. package/dist/alerts/webhook.js.map +1 -0
  48. package/dist/cli/schemaFormatter.d.ts +11 -0
  49. package/dist/cli/schemaFormatter.d.ts.map +1 -0
  50. package/dist/cli/schemaFormatter.js +74 -0
  51. package/dist/cli/schemaFormatter.js.map +1 -0
  52. package/dist/commands/alerts.d.ts +3 -0
  53. package/dist/commands/alerts.d.ts.map +1 -0
  54. package/dist/commands/alerts.js +256 -0
  55. package/dist/commands/alerts.js.map +1 -0
  56. package/dist/commands/budget.d.ts +3 -0
  57. package/dist/commands/budget.d.ts.map +1 -0
  58. package/dist/commands/budget.js +47 -0
  59. package/dist/commands/budget.js.map +1 -0
  60. package/dist/commands/channels.d.ts +3 -0
  61. package/dist/commands/channels.d.ts.map +1 -0
  62. package/dist/commands/channels.js +84 -0
  63. package/dist/commands/channels.js.map +1 -0
  64. package/dist/commands/check.d.ts +3 -0
  65. package/dist/commands/check.d.ts.map +1 -0
  66. package/dist/commands/check.js +58 -0
  67. package/dist/commands/check.js.map +1 -0
  68. package/dist/commands/completion.d.ts +3 -0
  69. package/dist/commands/completion.d.ts.map +1 -0
  70. package/dist/commands/completion.js +36 -0
  71. package/dist/commands/completion.js.map +1 -0
  72. package/dist/commands/costs.d.ts +15 -0
  73. package/dist/commands/costs.d.ts.map +1 -0
  74. package/dist/commands/costs.js +280 -0
  75. package/dist/commands/costs.js.map +1 -0
  76. package/dist/commands/daemon.d.ts +3 -0
  77. package/dist/commands/daemon.d.ts.map +1 -0
  78. package/dist/commands/daemon.js +93 -0
  79. package/dist/commands/daemon.js.map +1 -0
  80. package/dist/commands/db.d.ts +3 -0
  81. package/dist/commands/db.d.ts.map +1 -0
  82. package/dist/commands/db.js +140 -0
  83. package/dist/commands/db.js.map +1 -0
  84. package/dist/commands/guard.d.ts +3 -0
  85. package/dist/commands/guard.d.ts.map +1 -0
  86. package/dist/commands/guard.js +181 -0
  87. package/dist/commands/guard.js.map +1 -0
  88. package/dist/commands/history.d.ts +3 -0
  89. package/dist/commands/history.d.ts.map +1 -0
  90. package/dist/commands/history.js +57 -0
  91. package/dist/commands/history.js.map +1 -0
  92. package/dist/commands/inspect.d.ts +3 -0
  93. package/dist/commands/inspect.d.ts.map +1 -0
  94. package/dist/commands/inspect.js +82 -0
  95. package/dist/commands/inspect.js.map +1 -0
  96. package/dist/commands/mcp.d.ts +3 -0
  97. package/dist/commands/mcp.d.ts.map +1 -0
  98. package/dist/commands/mcp.js +20 -0
  99. package/dist/commands/mcp.js.map +1 -0
  100. package/dist/commands/pause.d.ts +3 -0
  101. package/dist/commands/pause.d.ts.map +1 -0
  102. package/dist/commands/pause.js +32 -0
  103. package/dist/commands/pause.js.map +1 -0
  104. package/dist/commands/resources.d.ts +3 -0
  105. package/dist/commands/resources.d.ts.map +1 -0
  106. package/dist/commands/resources.js +95 -0
  107. package/dist/commands/resources.js.map +1 -0
  108. package/dist/commands/restore.d.ts +3 -0
  109. package/dist/commands/restore.d.ts.map +1 -0
  110. package/dist/commands/restore.js +92 -0
  111. package/dist/commands/restore.js.map +1 -0
  112. package/dist/commands/resume.d.ts +3 -0
  113. package/dist/commands/resume.d.ts.map +1 -0
  114. package/dist/commands/resume.js +31 -0
  115. package/dist/commands/resume.js.map +1 -0
  116. package/dist/commands/status.d.ts +3 -0
  117. package/dist/commands/status.d.ts.map +1 -0
  118. package/dist/commands/status.js +63 -0
  119. package/dist/commands/status.js.map +1 -0
  120. package/dist/commands/watch.d.ts +3 -0
  121. package/dist/commands/watch.d.ts.map +1 -0
  122. package/dist/commands/watch.js +163 -0
  123. package/dist/commands/watch.js.map +1 -0
  124. package/dist/core/aws_secrets.d.ts +13 -0
  125. package/dist/core/aws_secrets.d.ts.map +1 -0
  126. package/dist/core/aws_secrets.js +34 -0
  127. package/dist/core/aws_secrets.js.map +1 -0
  128. package/dist/core/budget.d.ts +10 -0
  129. package/dist/core/budget.d.ts.map +1 -0
  130. package/dist/core/budget.js +31 -0
  131. package/dist/core/budget.js.map +1 -0
  132. package/dist/core/channels.d.ts +67 -0
  133. package/dist/core/channels.d.ts.map +1 -0
  134. package/dist/core/channels.js +136 -0
  135. package/dist/core/channels.js.map +1 -0
  136. package/dist/core/check.d.ts +25 -0
  137. package/dist/core/check.d.ts.map +1 -0
  138. package/dist/core/check.js +85 -0
  139. package/dist/core/check.js.map +1 -0
  140. package/dist/core/completion.d.ts +9 -0
  141. package/dist/core/completion.d.ts.map +1 -0
  142. package/dist/core/completion.js +68 -0
  143. package/dist/core/completion.js.map +1 -0
  144. package/dist/core/costs.d.ts +90 -0
  145. package/dist/core/costs.d.ts.map +1 -0
  146. package/dist/core/costs.js +147 -0
  147. package/dist/core/costs.js.map +1 -0
  148. package/dist/core/decoder.d.ts +7 -0
  149. package/dist/core/decoder.d.ts.map +1 -0
  150. package/dist/core/decoder.js +38 -0
  151. package/dist/core/decoder.js.map +1 -0
  152. package/dist/core/discovery.d.ts +38 -0
  153. package/dist/core/discovery.d.ts.map +1 -0
  154. package/dist/core/discovery.js +208 -0
  155. package/dist/core/discovery.js.map +1 -0
  156. package/dist/core/extension.d.ts +83 -0
  157. package/dist/core/extension.d.ts.map +1 -0
  158. package/dist/core/extension.js +429 -0
  159. package/dist/core/extension.js.map +1 -0
  160. package/dist/core/inspect.d.ts +62 -0
  161. package/dist/core/inspect.d.ts.map +1 -0
  162. package/dist/core/inspect.js +303 -0
  163. package/dist/core/inspect.js.map +1 -0
  164. package/dist/core/introspection.d.ts +8 -0
  165. package/dist/core/introspection.d.ts.map +1 -0
  166. package/dist/core/introspection.js +8 -0
  167. package/dist/core/introspection.js.map +1 -0
  168. package/dist/core/monitor.d.ts +42 -0
  169. package/dist/core/monitor.d.ts.map +1 -0
  170. package/dist/core/monitor.js +188 -0
  171. package/dist/core/monitor.js.map +1 -0
  172. package/dist/core/rent_projection.d.ts +153 -0
  173. package/dist/core/rent_projection.d.ts.map +1 -0
  174. package/dist/core/rent_projection.js +146 -0
  175. package/dist/core/rent_projection.js.map +1 -0
  176. package/dist/core/scvalTranslator.d.ts +11 -0
  177. package/dist/core/scvalTranslator.d.ts.map +1 -0
  178. package/dist/core/scvalTranslator.js +36 -0
  179. package/dist/core/scvalTranslator.js.map +1 -0
  180. package/dist/core/state_diff.d.ts +45 -0
  181. package/dist/core/state_diff.d.ts.map +1 -0
  182. package/dist/core/state_diff.js +112 -0
  183. package/dist/core/state_diff.js.map +1 -0
  184. package/dist/core/status.d.ts +24 -0
  185. package/dist/core/status.d.ts.map +1 -0
  186. package/dist/core/status.js +57 -0
  187. package/dist/core/status.js.map +1 -0
  188. package/dist/core/vault.d.ts +37 -0
  189. package/dist/core/vault.d.ts.map +1 -0
  190. package/dist/core/vault.js +179 -0
  191. package/dist/core/vault.js.map +1 -0
  192. package/dist/core/watch.d.ts +36 -0
  193. package/dist/core/watch.d.ts.map +1 -0
  194. package/dist/core/watch.js +176 -0
  195. package/dist/core/watch.js.map +1 -0
  196. package/dist/daemon/loop.d.ts +38 -0
  197. package/dist/daemon/loop.d.ts.map +1 -0
  198. package/dist/daemon/loop.js +169 -0
  199. package/dist/daemon/loop.js.map +1 -0
  200. package/dist/db/backup.d.ts +12 -0
  201. package/dist/db/backup.d.ts.map +1 -0
  202. package/dist/db/backup.js +132 -0
  203. package/dist/db/backup.js.map +1 -0
  204. package/dist/db/budget.d.ts +17 -0
  205. package/dist/db/budget.d.ts.map +1 -0
  206. package/dist/db/budget.js +31 -0
  207. package/dist/db/budget.js.map +1 -0
  208. package/dist/db/database.d.ts +6 -0
  209. package/dist/db/database.d.ts.map +1 -0
  210. package/dist/db/database.js +134 -0
  211. package/dist/db/database.js.map +1 -0
  212. package/dist/db/migrations/.gitkeep +1 -0
  213. package/dist/db/migrations/001_resource_usage_logs.sql +28 -0
  214. package/dist/db/migrator.d.ts +28 -0
  215. package/dist/db/migrator.d.ts.map +1 -0
  216. package/dist/db/migrator.js +75 -0
  217. package/dist/db/migrator.js.map +1 -0
  218. package/dist/db/repositories.d.ts +474 -0
  219. package/dist/db/repositories.d.ts.map +1 -0
  220. package/dist/db/repositories.js +809 -0
  221. package/dist/db/repositories.js.map +1 -0
  222. package/dist/db/schema.sql +207 -0
  223. package/dist/index.d.ts +3 -0
  224. package/dist/index.d.ts.map +1 -0
  225. package/dist/index.js +47 -0
  226. package/dist/index.js.map +1 -0
  227. package/dist/lib.d.ts +20 -0
  228. package/dist/lib.d.ts.map +1 -0
  229. package/dist/lib.js +16 -0
  230. package/dist/lib.js.map +1 -0
  231. package/dist/logging/index.d.ts +22 -0
  232. package/dist/logging/index.d.ts.map +1 -0
  233. package/dist/logging/index.js +34 -0
  234. package/dist/logging/index.js.map +1 -0
  235. package/dist/logging/logger.d.ts +14 -0
  236. package/dist/logging/logger.d.ts.map +1 -0
  237. package/dist/logging/logger.js +135 -0
  238. package/dist/logging/logger.js.map +1 -0
  239. package/dist/logging/types.d.ts +10 -0
  240. package/dist/logging/types.d.ts.map +1 -0
  241. package/dist/logging/types.js +2 -0
  242. package/dist/logging/types.js.map +1 -0
  243. package/dist/mcp/index.d.ts +3 -0
  244. package/dist/mcp/index.d.ts.map +1 -0
  245. package/dist/mcp/index.js +14 -0
  246. package/dist/mcp/index.js.map +1 -0
  247. package/dist/mcp/server.d.ts +10 -0
  248. package/dist/mcp/server.d.ts.map +1 -0
  249. package/dist/mcp/server.js +51 -0
  250. package/dist/mcp/server.js.map +1 -0
  251. package/dist/mcp/tools/get-extension-costs.d.ts +4 -0
  252. package/dist/mcp/tools/get-extension-costs.d.ts.map +1 -0
  253. package/dist/mcp/tools/get-extension-costs.js +33 -0
  254. package/dist/mcp/tools/get-extension-costs.js.map +1 -0
  255. package/dist/mcp/tools/get_contract_status.d.ts +8 -0
  256. package/dist/mcp/tools/get_contract_status.d.ts.map +1 -0
  257. package/dist/mcp/tools/get_contract_status.js +33 -0
  258. package/dist/mcp/tools/get_contract_status.js.map +1 -0
  259. package/dist/rpc/client.d.ts +154 -0
  260. package/dist/rpc/client.d.ts.map +1 -0
  261. package/dist/rpc/client.js +766 -0
  262. package/dist/rpc/client.js.map +1 -0
  263. package/dist/utils/config.d.ts +51 -0
  264. package/dist/utils/config.d.ts.map +1 -0
  265. package/dist/utils/config.js +86 -0
  266. package/dist/utils/config.js.map +1 -0
  267. package/dist/utils/formatting.d.ts +10 -0
  268. package/dist/utils/formatting.d.ts.map +1 -0
  269. package/dist/utils/formatting.js +66 -0
  270. package/dist/utils/formatting.js.map +1 -0
  271. package/dist/utils/watch-config.d.ts +13 -0
  272. package/dist/utils/watch-config.d.ts.map +1 -0
  273. package/dist/utils/watch-config.js +32 -0
  274. package/dist/utils/watch-config.js.map +1 -0
  275. package/package.json +73 -0
@@ -0,0 +1,296 @@
1
+ # Contributing to Sorokeep
2
+
3
+ Sorokeep is an open-source project and contributions are welcome. This document explains how the project works, how to set up your environment, and what we expect from contributions.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Before You Start](#before-you-start)
8
+ - [Quick Start](#quick-start)
9
+ - [Project Structure](#project-structure)
10
+ - [Development Workflow](#development-workflow)
11
+ - [Test-Driven Development](#test-driven-development)
12
+ - [Running Tests](#running-tests)
13
+ - [Running the CLI During Development](#running-the-cli-during-development)
14
+ - [Database](#database)
15
+ - [Linting and Type Checking](#linting-and-type-checking)
16
+ - [Code Conventions](#code-conventions)
17
+ - [TypeScript](#typescript)
18
+ - [Naming](#naming)
19
+ - [Imports](#imports)
20
+ - [Error Handling](#error-handling)
21
+ - [Commits](#commits)
22
+ - [Branches](#branches)
23
+ - [Architecture Decision Records](#architecture-decision-records)
24
+ - [E2E Sandbox Testing](#e2e-sandbox-testing)
25
+ - [What Makes a Good Contribution](#what-makes-a-good-contribution)
26
+ - [Good First Issues](#good-first-issues)
27
+ - [Larger Contributions](#larger-contributions)
28
+ - [PR Checklist](#pr-checklist)
29
+ - [Getting Help](#getting-help)
30
+
31
+ ## Before You Start
32
+
33
+ Read the [README](README.md) to understand what Sorokeep does and how it's structured. The short version: Sorokeep monitors Soroban smart contract TTLs and alerts developers before their contract state expires. It's a TypeScript CLI that reads from the Stellar RPC and stores data in local SQLite.
34
+
35
+ If you want to work on something, check the [open issues](https://github.com/AbdulmalikAlayande/sorokeep/issues) first. If there's no issue for what you want to do, open one and describe the change before writing code. This prevents wasted effort on changes that don't fit the project direction.
36
+
37
+ ## Quick Start
38
+
39
+ You need:
40
+
41
+ - Node.js 22 or later
42
+ - npm
43
+ - Git
44
+
45
+ Clone and install:
46
+
47
+ ```bash
48
+ git clone https://github.com/AbdulmalikAlayande/sorokeep.git
49
+ cd sorokeep
50
+ npm install
51
+ ```
52
+
53
+ Verify everything works:
54
+
55
+ ```bash
56
+ # Run all tests
57
+ npm test
58
+
59
+ # Run the CLI
60
+ npx tsx src/index.ts --help
61
+
62
+ # Watch a real contract on testnet (optional, requires internet)
63
+ npx tsx src/index.ts watch CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC --network testnet --name "XLM Test"
64
+ ```
65
+
66
+ If all tests pass and the CLI prints its help screen, you're ready.
67
+
68
+ ## Project Structure
69
+
70
+ ```
71
+ sorokeep/
72
+ ├── src/
73
+ │ ├── index.ts # CLI entry point (Commander.js)
74
+ │ ├── commands/ # CLI command handlers (parse args, call core, format output)
75
+ │ ├── core/ # Business logic (no CLI dependencies, no side effects)
76
+ │ ├── rpc/ # Stellar RPC client wrapper
77
+ │ ├── db/ # SQLite schema, connection, and data access functions
78
+ │ ├── alerts/ # Alert dispatcher (webhook, Slack)
79
+ │ ├── daemon/ # Monitoring loop and lifecycle
80
+ │ ├── logging/ # Structured logging with pino
81
+ │ └── utils/ # Formatting helpers, config loading
82
+ ├── tests/ # Mirrors src/ — same folder names, .test.ts suffix
83
+ │ ├── commands/
84
+ │ ├── core/
85
+ │ ├── alerts/
86
+ │ ├── daemon/
87
+ │ ├── rpc/
88
+ │ ├── db/
89
+ │ └── utils/
90
+ ├── docs/ # Documentation
91
+ │ ├── adr/ # Architecture Decision Records
92
+ │ └── e2e-sandbox.md # E2E sandbox setup guide
93
+ ├── .github/workflows/ # CI (test + type-check) and publish
94
+ ├── package.json
95
+ ├── tsconfig.json
96
+ ├── vitest.config.ts
97
+ └── CONTRIBUTING.md
98
+ ```
99
+
100
+ **Key architectural rule:** core logic never depends on CLI or presentation code. The `commands/` layer is a thin wrapper that calls functions from `core/`, which do all the real work. This means the daemon can reuse the same core functions without importing CLI code.
101
+
102
+ If you're adding a new feature, the logic goes in `core/`, the CLI wiring goes in `commands/`, and tests go in `tests/core/`.
103
+
104
+ ## Development Workflow
105
+
106
+ ### Test-Driven Development
107
+
108
+ We enforce strict test-driven development. Your PR will not be accepted without comprehensive tests.
109
+
110
+ The process is:
111
+
112
+ 1. **Write the test first.** Define what the function should do, what inputs it takes, and what outputs it returns. Run the test — it should fail (red).
113
+ 2. **Write the minimum implementation** to make the test pass (green).
114
+ 3. **Refactor if needed**, then run all tests to make sure nothing broke.
115
+
116
+ ### Running Tests
117
+
118
+ ```bash
119
+ # All tests
120
+ npm test
121
+
122
+ # Specific file
123
+ npx vitest run tests/core/monitor.test.ts
124
+
125
+ # Watch mode (re-runs on file changes)
126
+ npx vitest
127
+
128
+ # With coverage
129
+ npx vitest run --coverage
130
+ ```
131
+
132
+ All tests use in-memory SQLite databases and mocked RPC responses — no network calls, no filesystem side effects.
133
+
134
+ ### Running the CLI During Development
135
+
136
+ Use `tsx` to run TypeScript directly without compiling:
137
+
138
+ ```bash
139
+ npx tsx src/index.ts watch <contractId> --network testnet
140
+ npx tsx src/index.ts --help
141
+ ```
142
+
143
+ ### Database
144
+
145
+ Sorokeep uses SQLite stored at `~/.sorokeep/sorokeep.db`. The schema is in `src/db/schema.sql`.
146
+
147
+ Tests use an in-memory SQLite database (`getDatabaseForTesting()`) so they're fast and don't touch your local state.
148
+
149
+ If you need to reset your local database during development:
150
+
151
+ ```bash
152
+ # Linux/macOS
153
+ rm ~/.sorokeep/sorokeep.db
154
+
155
+ # Windows PowerShell
156
+ Remove-Item "$HOME\.sorokeep\sorokeep.db"
157
+ ```
158
+
159
+ ### Linting and Type Checking
160
+
161
+ ```bash
162
+ # Lint
163
+ npm run lint
164
+
165
+ # Type check (without emitting files)
166
+ npx tsc --noEmit
167
+ ```
168
+
169
+ Run both before pushing to ensure CI passes.
170
+
171
+ ## Code Conventions
172
+
173
+ ### TypeScript
174
+
175
+ - Strict mode is on (`strict: true` in tsconfig)
176
+ - `noUncheckedIndexedAccess` is enabled — array access returns `T | undefined`
177
+ - ESM modules (`"type": "module"` in package.json). See [ADR-002](docs/adr/ADR-002-use-esm-modules.md).
178
+ - Use `import type` for type-only imports
179
+ - No `console.log` in core logic — use the pino logger for operational logging, and return data for the CLI layer to print
180
+
181
+ ### Naming
182
+
183
+ - Files: `kebab-case.ts`
184
+ - Functions: `camelCase`
185
+ - Interfaces/Types: `PascalCase`
186
+ - Database columns: `snake_case`
187
+ - Constants: `UPPER_SNAKE_CASE` for true constants, `camelCase` for configuration
188
+
189
+ ### Imports
190
+
191
+ Order imports by:
192
+ 1. Node.js built-ins (`node:fs`, `node:path`)
193
+ 2. Third-party packages (`vitest`, `better-sqlite3`, `commander`)
194
+ 3. Internal modules (`../../src/core/monitor.js`)
195
+
196
+ Use explicit `.js` extensions for internal imports (ESM requirement). Type-only imports use `import type`.
197
+
198
+ ### Error Handling
199
+
200
+ Catch errors and return structured results (like `WatchResult`) instead of throwing from core functions. Let the CLI layer decide how to present errors.
201
+
202
+ ```typescript
203
+ // Core function returns a result type, doesn't throw
204
+ function doSomething(input: string): { ok: true; value: number } | { ok: false; error: string }
205
+ ```
206
+
207
+ ### Commits
208
+
209
+ Follow conventional commit format:
210
+
211
+ ```
212
+ feat: add slack alert integration
213
+ fix: handle archived WASM entries in monitor cycle
214
+ test: add boundary tests for TTL threshold detection
215
+ docs: update README with daemon usage
216
+ refactor: extract RPC response mapping into helper
217
+ ```
218
+
219
+ Types: `feat`, `fix`, `test`, `docs`, `refactor`, `chore`
220
+
221
+ ### Branches
222
+
223
+ ```
224
+ feature/short-description
225
+ fix/short-description
226
+ docs/short-description
227
+ ```
228
+
229
+ Branch from `main`, PR back to `main`.
230
+
231
+ ## Architecture Decision Records
232
+
233
+ Significant design decisions are documented as Architecture Decision Records (ADRs) in [docs/adr/](docs/adr/). Each ADR explains the context, options considered, and rationale for the chosen approach.
234
+
235
+ | ADR | Title | Description |
236
+ |-----|-------|-------------|
237
+ | [ADR-001](docs/adr/ADR-001-use-sqlite-for-local-storage.md) | Use SQLite for Local Storage | Why SQLite over PostgreSQL or JSON files |
238
+ | [ADR-002](docs/adr/ADR-002-use-esm-modules.md) | Use ESM (ECMAScript Modules) | Why ESM over CommonJS |
239
+ | [ADR-003](docs/adr/ADR-003-use-commander-js-for-cli.md) | Use Commander.js for CLI Framework | Why Commander over oclif or yargs |
240
+ | [ADR-004](docs/adr/ADR-004-polling-daemon-architecture.md) | Polling Daemon Architecture | Why polling over event-driven |
241
+ | [ADR-005](docs/adr/ADR-005-use-typescript-over-rust.md) | Use TypeScript (Not Rust) | Why TypeScript over Rust for this tool |
242
+ | [ADR-006](docs/adr/ADR-006-in-memory-sqlite-for-testing.md) | In-Memory SQLite for Testing | Why tests use in-memory databases |
243
+
244
+ Before making a significant new design decision, write an ADR. This helps future contributors understand why things are the way they are.
245
+
246
+ ## E2E Sandbox Testing
247
+
248
+ We provide a complete guide for setting up an end-to-end sandbox environment with a local Stellar network using Docker. See [docs/e2e-sandbox.md](docs/e2e-sandbox.md) for:
249
+
250
+ - Running a local Soroban-enabled Stellar network
251
+ - Creating and funding test accounts
252
+ - Deploying test contracts
253
+ - Configuring Sorokeep to monitor local contracts
254
+ - An automated E2E test script for CI usage
255
+ - Troubleshooting common issues
256
+
257
+ The sandbox lets you test Sorokeep against a real Stellar RPC without touching public testnet or mainnet.
258
+
259
+ ## What Makes a Good Contribution
260
+
261
+ ### Good First Issues
262
+
263
+ If you're new to the project, look for issues tagged `good first issue`. These are typically:
264
+
265
+ - Adding a new alert channel (email, Discord, Telegram)
266
+ - CLI UX improvements (better error messages, colored output)
267
+ - Documentation improvements
268
+ - Adding test coverage for edge cases
269
+
270
+ ### Larger Contributions
271
+
272
+ For anything beyond small fixes, open an issue first to discuss the approach. This is especially important for:
273
+
274
+ - New CLI commands
275
+ - Database schema changes
276
+ - Changes to the monitor cycle logic
277
+ - New RPC client methods
278
+
279
+ ### PR Checklist
280
+
281
+ Before submitting a PR, verify:
282
+
283
+ - [ ] Tests pass (`npm test`)
284
+ - [ ] Type check passes (`npx tsc --noEmit`)
285
+ - [ ] Lint passes (`npm run lint`)
286
+ - [ ] Tests cover the new functionality (TDD preferred)
287
+ - [ ] No unnecessary dependencies added
288
+ - [ ] Commit messages follow conventional format
289
+ - [ ] Code matches the project's style and conventions
290
+ - [ ] No `console.log` in core logic
291
+ - [ ] ADR created if making a significant design decision
292
+ - [ ] E2E sandbox tested (for changes affecting RPC or daemon interactions)
293
+
294
+ ## Getting Help
295
+
296
+ If you're stuck or have questions about the codebase, open an issue or reach out on X ([@The_good_man02](https://twitter.com/The_good_man02)). We'd rather answer questions early than review a PR that went in the wrong direction.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AbdulmalikAlayande
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.