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,303 @@
1
+ import { xdr, Address, StrKey, scValToNative } from "@stellar/stellar-sdk";
2
+ import { getContract } from "../db/repositories.js";
3
+ import { StellarRpcClient } from "../rpc/client.js";
4
+ import { classifyTTL, formatTimeToCloseLedger, formatContractID } from "../utils/formatting.js";
5
+ import { getLogger } from "../logging/index.js";
6
+ const logger = getLogger().child({ component: "InspectCore" });
7
+ /**
8
+ * Format token balance in stroops/raw units to string representation with decimals.
9
+ */
10
+ export function formatTokenBalance(amount, decimals) {
11
+ const bigAmount = BigInt(amount);
12
+ const isNegative = bigAmount < 0n;
13
+ const absAmount = isNegative ? -bigAmount : bigAmount;
14
+ const divisor = 10n ** BigInt(decimals);
15
+ const integerPart = absAmount / divisor;
16
+ const remainder = absAmount % divisor;
17
+ let result = integerPart.toString();
18
+ if (decimals > 0) {
19
+ const remainderStr = remainder.toString().padStart(decimals, "0");
20
+ const trimmedRemainder = remainderStr.replace(/0+$/, "");
21
+ if (trimmedRemainder.length > 0) {
22
+ result += "." + trimmedRemainder;
23
+ }
24
+ }
25
+ return isNegative ? "-" + result : result;
26
+ }
27
+ /**
28
+ * Custom parser for SAC balance map layout.
29
+ */
30
+ export function parseSacBalance(scVal) {
31
+ let valObj;
32
+ if (typeof scVal === "string") {
33
+ try {
34
+ valObj = xdr.ScVal.fromXDR(scVal, "base64");
35
+ }
36
+ catch {
37
+ throw new Error("Invalid SAC balance map layout");
38
+ }
39
+ }
40
+ else {
41
+ valObj = scVal;
42
+ }
43
+ if (!valObj || typeof valObj.switch !== "function" || valObj.switch().name !== "scvMap") {
44
+ throw new Error("Invalid SAC balance map layout");
45
+ }
46
+ let native;
47
+ try {
48
+ native = scValToNative(valObj);
49
+ }
50
+ catch {
51
+ throw new Error("Invalid SAC balance map layout");
52
+ }
53
+ if (!native || typeof native !== "object" || native.amount === undefined) {
54
+ throw new Error("Invalid SAC balance map layout");
55
+ }
56
+ return {
57
+ amount: BigInt(native.amount),
58
+ authorized: Boolean(native.authorized ?? true),
59
+ clawback: Boolean(native.clawback ?? false),
60
+ };
61
+ }
62
+ /**
63
+ * Build storage key XDR for a SAC address balance entry.
64
+ */
65
+ export function buildSacBalanceKeyXdr(contractId, address) {
66
+ const addr = Address.fromString(address);
67
+ const keyVal = xdr.ScVal.scvVec([
68
+ xdr.ScVal.scvSymbol("Balance"),
69
+ addr.toScVal(),
70
+ ]);
71
+ const raw = Buffer.from(contractId, "hex").length === 32
72
+ ? Buffer.from(contractId, "hex")
73
+ : Buffer.from(StrKey.decodeContract(contractId));
74
+ const contractAddress = xdr.ScAddress.scAddressTypeContract(raw);
75
+ const ledgerKey = xdr.LedgerKey.contractData(new xdr.LedgerKeyContractData({
76
+ contract: contractAddress,
77
+ key: keyVal,
78
+ durability: xdr.ContractDataDurability.persistent(),
79
+ }));
80
+ return ledgerKey.toXDR("base64");
81
+ }
82
+ /**
83
+ * Inspect contract storage and token balances on SAC contracts.
84
+ */
85
+ export async function inspectContract(db, contractId, options = {}) {
86
+ let contract = null;
87
+ try {
88
+ contract = getContract(db, contractId);
89
+ }
90
+ catch {
91
+ // DB not initialized or not found
92
+ }
93
+ const network = contract?.network ?? options.network ?? "testnet";
94
+ const rpcUrl = contract?.rpc_url ?? options.rpcUrl;
95
+ const contractName = contract?.name ?? null;
96
+ const client = new StellarRpcClient(network, rpcUrl ?? undefined);
97
+ // 1. Check if SAC contract
98
+ const instance = await client.getContractInstanceEntry(contractId);
99
+ if (!instance) {
100
+ return {
101
+ success: false,
102
+ contractId,
103
+ error: `Contract instance not found on-chain for ${formatContractID(contractId)}.`,
104
+ };
105
+ }
106
+ const isSac = instance.executableType === "contractExecutableStellarAsset";
107
+ // 2. Fetch SAC decimals (only if SAC)
108
+ const decimals = isSac ? await client.getSacDecimals(contractId) : 0;
109
+ // 3. Process entries
110
+ const inputEntries = options.entries ?? [];
111
+ if (inputEntries.length === 0) {
112
+ return {
113
+ success: true,
114
+ contractId,
115
+ contractName,
116
+ network,
117
+ isSac,
118
+ decimals,
119
+ results: [],
120
+ };
121
+ }
122
+ const mapped = [];
123
+ for (const inputEntry of inputEntries) {
124
+ if (inputEntry.startsWith("balance:")) {
125
+ if (!isSac) {
126
+ return {
127
+ success: false,
128
+ contractId,
129
+ error: `Contract ${formatContractID(contractId)} is not a standard Stellar Asset Contract (SAC). Cannot inspect balance slots.`,
130
+ };
131
+ }
132
+ const address = inputEntry.slice("balance:".length).trim();
133
+ try {
134
+ const keyXdr = buildSacBalanceKeyXdr(contractId, address);
135
+ mapped.push({ inputEntry, entryKeyXdr: keyXdr, type: "balance" });
136
+ }
137
+ catch (err) {
138
+ return {
139
+ success: false,
140
+ contractId,
141
+ error: `Failed to locate balance slot for address "${address}": ${err.message ?? String(err)}`,
142
+ };
143
+ }
144
+ }
145
+ else {
146
+ mapped.push({ inputEntry, entryKeyXdr: inputEntry, type: "raw" });
147
+ }
148
+ }
149
+ const keyXdrs = mapped.map(m => m.entryKeyXdr);
150
+ const storageEntries = await client.getContractStorageEntries(keyXdrs);
151
+ const entryMap = new Map(storageEntries.map(e => [e.entryKeyXdr, e]));
152
+ const results = mapped.map(item => {
153
+ const foundEntry = entryMap.get(item.entryKeyXdr);
154
+ if (!foundEntry || !foundEntry.valXdr) {
155
+ if (item.type === "balance") {
156
+ return {
157
+ inputEntry: item.inputEntry,
158
+ entryKeyXdr: item.entryKeyXdr,
159
+ type: "balance",
160
+ found: false,
161
+ remainingTTL: null,
162
+ approximateTimeRemaining: null,
163
+ status: "unknown",
164
+ balance: { amount: 0n, authorized: true, clawback: false },
165
+ formattedBalance: formatTokenBalance(0n, decimals),
166
+ };
167
+ }
168
+ else {
169
+ return {
170
+ inputEntry: item.inputEntry,
171
+ entryKeyXdr: item.entryKeyXdr,
172
+ type: "raw",
173
+ found: false,
174
+ remainingTTL: null,
175
+ approximateTimeRemaining: null,
176
+ status: "unknown",
177
+ };
178
+ }
179
+ }
180
+ const remTTL = foundEntry.remainingTTL;
181
+ const ttlStatus = classifyTTL(remTTL);
182
+ const approxTime = formatTimeToCloseLedger(remTTL);
183
+ if (item.type === "balance") {
184
+ let bal = { amount: 0n, authorized: true, clawback: false };
185
+ try {
186
+ bal = parseSacBalance(foundEntry.valXdr);
187
+ }
188
+ catch {
189
+ logger.debug("Failed to decode balance valXdr", { valXdr: foundEntry.valXdr });
190
+ }
191
+ return {
192
+ inputEntry: item.inputEntry,
193
+ entryKeyXdr: item.entryKeyXdr,
194
+ type: "balance",
195
+ found: true,
196
+ remainingTTL: remTTL,
197
+ approximateTimeRemaining: approxTime,
198
+ status: ttlStatus,
199
+ balance: bal,
200
+ formattedBalance: formatTokenBalance(bal.amount, decimals),
201
+ };
202
+ }
203
+ else {
204
+ let decodedValue;
205
+ if (foundEntry.valXdr) {
206
+ decodedValue = decodeScVal(foundEntry.valXdr);
207
+ }
208
+ return {
209
+ inputEntry: item.inputEntry,
210
+ entryKeyXdr: item.entryKeyXdr,
211
+ type: "raw",
212
+ found: true,
213
+ remainingTTL: remTTL,
214
+ approximateTimeRemaining: approxTime,
215
+ status: ttlStatus,
216
+ decodedValue,
217
+ };
218
+ }
219
+ });
220
+ return {
221
+ success: true,
222
+ contractId,
223
+ contractName,
224
+ network,
225
+ isSac,
226
+ decimals,
227
+ results,
228
+ };
229
+ }
230
+ /**
231
+ * Decode a base64 XDR ScVal string into a JSON-friendly structure.
232
+ */
233
+ export function decodeScVal(scValBase64) {
234
+ try {
235
+ const scVal = xdr.ScVal.fromXDR(scValBase64, "base64");
236
+ return decodeScValRecursive(scVal);
237
+ }
238
+ catch (e) {
239
+ return { type: "error", value: `Failed to decode ScVal: ${e.message}` };
240
+ }
241
+ }
242
+ function decodeScValRecursive(scVal) {
243
+ const type = scVal.switch().name;
244
+ let value;
245
+ switch (type) {
246
+ case "scvU32":
247
+ case "scvI32":
248
+ value = scVal.value();
249
+ break;
250
+ case "scvBool":
251
+ value = scVal.b();
252
+ break;
253
+ case "scvString":
254
+ case "scvSymbol":
255
+ value = scVal.value()?.toString() ?? null;
256
+ break;
257
+ case "scvU64":
258
+ case "scvI64":
259
+ case "scvU128":
260
+ case "scvI128":
261
+ case "scvU256":
262
+ case "scvI256":
263
+ try {
264
+ value = scValToNative(scVal).toString();
265
+ }
266
+ catch {
267
+ value = "<unsupported bigint>";
268
+ }
269
+ break;
270
+ case "scvMap":
271
+ value = (scVal.map() ?? []).map((entry) => ({
272
+ key: decodeScValRecursive(entry.key()),
273
+ value: decodeScValRecursive(entry.val()),
274
+ }));
275
+ break;
276
+ case "scvVec":
277
+ value = (scVal.vec() ?? []).map((val) => decodeScValRecursive(val));
278
+ break;
279
+ case "scvBytes":
280
+ value = scVal.bytes().toString("hex");
281
+ break;
282
+ case "scvAddress":
283
+ try {
284
+ value = scValToNative(scVal);
285
+ }
286
+ catch {
287
+ value = "<address>";
288
+ }
289
+ break;
290
+ case "scvVoid":
291
+ value = null;
292
+ break;
293
+ default:
294
+ try {
295
+ value = scValToNative(scVal);
296
+ }
297
+ catch {
298
+ value = `<native conversion failed for ${type}>`;
299
+ }
300
+ }
301
+ return { type, value };
302
+ }
303
+ //# sourceMappingURL=inspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.js","sourceRoot":"","sources":["../../src/core/inspect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type Database from "better-sqlite3";
2
+ export interface IntrospectionResult {
3
+ contractsChecked: number;
4
+ newEntriesFound: number;
5
+ errors: string[];
6
+ }
7
+ export declare function runIntrospectionRescan(_db: Database.Database, _network: string, _rpcUrl: string | undefined): Promise<IntrospectionResult>;
8
+ //# sourceMappingURL=introspection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introspection.d.ts","sourceRoot":"","sources":["../../src/core/introspection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,MAAM,WAAW,mBAAmB;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAsB,sBAAsB,CACxC,GAAG,EAAE,QAAQ,CAAC,QAAQ,EACtB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GAAG,SAAS,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAM9B"}
@@ -0,0 +1,8 @@
1
+ export async function runIntrospectionRescan(_db, _network, _rpcUrl) {
2
+ return {
3
+ contractsChecked: 0,
4
+ newEntriesFound: 0,
5
+ errors: [],
6
+ };
7
+ }
8
+ //# sourceMappingURL=introspection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introspection.js","sourceRoot":"","sources":["../../src/core/introspection.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,KAAK,UAAU,sBAAsB,CACxC,GAAsB,EACtB,QAAgB,EAChB,OAA2B;IAE3B,OAAO;QACH,gBAAgB,EAAE,CAAC;QACnB,eAAe,EAAE,CAAC;QAClB,MAAM,EAAE,EAAE;KACb,CAAC;AACN,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type Database from "better-sqlite3";
2
+ export interface MonitorCycleResult {
3
+ /** Number of contracts belonging to the target network that were processed. */
4
+ contractsChecked: number;
5
+ /** Number of individual ledger entries whose TTL was refreshed in the DB. */
6
+ entriesUpdated: number;
7
+ /** Number of alert threshold crossings detected (new, not previously fired). */
8
+ thresholdsCrossed: number;
9
+ /** Number of previously-open alerts that were resolved because TTL recovered. */
10
+ alertsResolved: number;
11
+ /** Total ledger entries extended by the auto-extension phase this cycle. */
12
+ extensionsTriggered: number;
13
+ /** Non-fatal errors from the auto-extension phase. */
14
+ extensionErrors: string[];
15
+ /** Per-contract error messages for any contract that failed during the cycle. */
16
+ errors: string[];
17
+ /** Timestamp when this cycle started. */
18
+ cycleStartedAt: Date;
19
+ /** Timestamp when this cycle completed. */
20
+ cycleFinishedAt: Date;
21
+ }
22
+ /**
23
+ * One complete monitoring polling cycle.
24
+ *
25
+ * Responsibilities:
26
+ * 1. Load all contracts for the given network from the DB.
27
+ * 2. For each contract, fetch fresh TTLs from the RPC in a single batched call.
28
+ * 3. Persist updated TTL values back to the DB.
29
+ * 4. Detect alert threshold crossings and record them (deduplication aware).
30
+ * 5. Auto-resolve open alerts whose TTL has recovered above the threshold.
31
+ *
32
+ * Contract: pure logic — no timers, no CLI concerns, no side-effects beyond the
33
+ * provided `db` handle. Errors from individual contracts are collected and
34
+ * returned rather than propagated so that one bad contract cannot abort the
35
+ * entire cycle.
36
+ *
37
+ * @param db - An open better-sqlite3 Database handle.
38
+ * @param network - The Stellar network to monitor ("testnet" | "mainnet" | …).
39
+ * @param rpcUrl - Optional override for the RPC endpoint URL.
40
+ */
41
+ export declare function runMonitorCycle(db: Database.Database, network: string, rpcUrl?: string, feeSponsorSecret?: string): Promise<MonitorCycleResult>;
42
+ //# sourceMappingURL=monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor.d.ts","sourceRoot":"","sources":["../../src/core/monitor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAsB3C,MAAM,WAAW,kBAAkB;IAC/B,+EAA+E;IAC/E,gBAAgB,EAAE,MAAM,CAAC;IACzB,6EAA6E;IAC7E,cAAc,EAAE,MAAM,CAAC;IACvB,gFAAgF;IAChF,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iFAAiF;IACjF,cAAc,EAAE,MAAM,CAAC;IACvB,4EAA4E;IAC5E,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sDAAsD;IACtD,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,iFAAiF;IACjF,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,yCAAyC;IACzC,cAAc,EAAE,IAAI,CAAC;IACrB,2CAA2C;IAC3C,eAAe,EAAE,IAAI,CAAC;CACzB;AAID;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,eAAe,CACjC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,EACf,gBAAgB,CAAC,EAAE,MAAM,GAC1B,OAAO,CAAC,kBAAkB,CAAC,CAwE7B"}
@@ -0,0 +1,188 @@
1
+ import { getAllContracts, getEntriesForContract, upsertEntry, updateLastCheckedLedger, getAlertConfigsForContract, getAlertConfigById, hasUnresolvedAlert, recordAlertFired, resolveAlerts, } from "../db/repositories.js";
2
+ import { StellarRpcClient } from "../rpc/client.js";
3
+ import { deliverSingleAlert } from "../alerts/dispatcher.js";
4
+ import { buildAlertEvent } from "../alerts/types.js";
5
+ import { runAutoExtensions } from "./extension.js";
6
+ import { getLogger } from "../logging/index.js";
7
+ const logger = getLogger().child({ component: "MonitorCycle" });
8
+ // ─── Core implementation ──────────────────────────────────────────────────────
9
+ /**
10
+ * One complete monitoring polling cycle.
11
+ *
12
+ * Responsibilities:
13
+ * 1. Load all contracts for the given network from the DB.
14
+ * 2. For each contract, fetch fresh TTLs from the RPC in a single batched call.
15
+ * 3. Persist updated TTL values back to the DB.
16
+ * 4. Detect alert threshold crossings and record them (deduplication aware).
17
+ * 5. Auto-resolve open alerts whose TTL has recovered above the threshold.
18
+ *
19
+ * Contract: pure logic — no timers, no CLI concerns, no side-effects beyond the
20
+ * provided `db` handle. Errors from individual contracts are collected and
21
+ * returned rather than propagated so that one bad contract cannot abort the
22
+ * entire cycle.
23
+ *
24
+ * @param db - An open better-sqlite3 Database handle.
25
+ * @param network - The Stellar network to monitor ("testnet" | "mainnet" | …).
26
+ * @param rpcUrl - Optional override for the RPC endpoint URL.
27
+ */
28
+ export async function runMonitorCycle(db, network, rpcUrl, feeSponsorSecret) {
29
+ const cycleStartedAt = new Date();
30
+ const result = {
31
+ contractsChecked: 0,
32
+ entriesUpdated: 0,
33
+ thresholdsCrossed: 0,
34
+ alertsResolved: 0,
35
+ extensionsTriggered: 0,
36
+ extensionErrors: [],
37
+ errors: [],
38
+ cycleStartedAt,
39
+ cycleFinishedAt: cycleStartedAt, // will be overwritten at the end
40
+ };
41
+ // One RPC client shared across the cycle for the target network.
42
+ const client = new StellarRpcClient(network, rpcUrl);
43
+ // 1. Load all contracts and filter to the target network and active status.
44
+ const contracts = getAllContracts(db).filter(c => c.network === network && c.active === 1);
45
+ logger.debug(`Monitor cycle started — ${contracts.length} contract(s) on ${network}`);
46
+ for (const contract of contracts) {
47
+ result.contractsChecked++;
48
+ try {
49
+ await processContract(db, client, contract.id, network, result);
50
+ }
51
+ catch (error) {
52
+ // Fault isolation: record the failure, move to next contract.
53
+ const message = error instanceof Error ? error.message : String(error);
54
+ const errorEntry = `Error processing contract ${contract.id}: ${message}`;
55
+ result.errors.push(errorEntry);
56
+ logger.error(errorEntry, error);
57
+ }
58
+ }
59
+ // Auto-extension phase: check extension_policies and submit transactions for
60
+ // entries whose TTL fell below the configured threshold.
61
+ try {
62
+ const ext = await runAutoExtensions(db, network, rpcUrl, feeSponsorSecret);
63
+ result.extensionsTriggered = ext.entriesExtended;
64
+ result.extensionErrors = ext.errors;
65
+ if (ext.entriesExtended > 0) {
66
+ logger.info(`Auto-extensions — contracts: ${ext.contractsExtended}, ` +
67
+ `entries: ${ext.entriesExtended}`);
68
+ }
69
+ for (const e of ext.extensions) {
70
+ if (e.isAnomaly) {
71
+ logger.warn(`Cost anomaly — contract: ${e.contractId}: ${e.anomalyDetails}`);
72
+ }
73
+ }
74
+ }
75
+ catch (err) {
76
+ const msg = err instanceof Error ? err.message : String(err);
77
+ result.extensionErrors = [msg];
78
+ logger.error("runAutoExtensions threw unexpectedly", err);
79
+ }
80
+ result.cycleFinishedAt = new Date();
81
+ logger.debug(`Monitor cycle finished — checked: ${result.contractsChecked}, ` +
82
+ `updated: ${result.entriesUpdated}, ` +
83
+ `crossed: ${result.thresholdsCrossed}, ` +
84
+ `resolved: ${result.alertsResolved}, ` +
85
+ `extended: ${result.extensionsTriggered}, ` +
86
+ `errors: ${result.errors.length}`);
87
+ return result;
88
+ }
89
+ // ─── Private helpers ──────────────────────────────────────────────────────────
90
+ /**
91
+ * Process a single contract within a cycle.
92
+ * Throws on RPC failure — caller handles fault isolation.
93
+ */
94
+ async function processContract(db, client, contractId, network, result) {
95
+ const entries = getEntriesForContract(db, contractId);
96
+ // If this contract has no tracked entries there is nothing to do.
97
+ // We skip the RPC call entirely to avoid unnecessary network traffic.
98
+ if (entries.length === 0) {
99
+ logger.debug(`Contract ${contractId} has no tracked entries — skipping RPC call`);
100
+ return;
101
+ }
102
+ // 2. One batched RPC call for all entry keys of this contract.
103
+ const entryKeyXdrs = entries.map(e => e.entry_key_xdr);
104
+ const rpcResult = await client.getEntryTTLs(entryKeyXdrs);
105
+ // 3. Update last_checked_ledger with the ledger that backed this RPC response.
106
+ updateLastCheckedLedger(db, contractId, rpcResult.latestLedger);
107
+ // Build a lookup map: entryKeyXdr → RPC data.
108
+ const rpcMap = new Map(rpcResult.entries.map(e => [e.entryKeyXdr, e]));
109
+ // Load alert configurations once per contract.
110
+ const alertConfigs = getAlertConfigsForContract(db, contractId);
111
+ for (const entry of entries) {
112
+ const rpcEntry = rpcMap.get(entry.entry_key_xdr);
113
+ if (!rpcEntry) {
114
+ // Entry not returned by the RPC — possibly archived.
115
+ // Do NOT zero out the DB value; leave it stale rather than destructive.
116
+ logger.debug(`Contract ${contractId}: entry ${entry.entry_key_xdr} not returned by RPC (possibly archived)`);
117
+ continue;
118
+ }
119
+ // 3a. Persist fresh TTL data.
120
+ upsertEntry(db, {
121
+ contract_id: contractId,
122
+ entry_key_xdr: entry.entry_key_xdr,
123
+ entry_type: entry.entry_type,
124
+ label: entry.label ?? undefined,
125
+ live_until_ledger: rpcEntry.liveUntilLedgerSeq,
126
+ last_modified_ledger: rpcEntry.lastModifiedLedgerSeq,
127
+ discovery_source: entry.discovery_source,
128
+ });
129
+ result.entriesUpdated++;
130
+ // 4 & 5. Threshold detection and resolution.
131
+ if (alertConfigs.length === 0)
132
+ continue;
133
+ const remainingTTL = rpcEntry.remainingTTL;
134
+ for (const alertConfig of alertConfigs) {
135
+ const isBelowThreshold = remainingTTL < alertConfig.threshold_ledgers;
136
+ if (isBelowThreshold) {
137
+ // 4. TTL is below threshold — fire if not already unresolved.
138
+ if (!hasUnresolvedAlert(db, alertConfig.id, entry.id)) {
139
+ recordAlertFired(db, {
140
+ alert_config_id: alertConfig.id,
141
+ contract_entry_id: entry.id,
142
+ fired_at_ledger: rpcResult.latestLedger,
143
+ ttl_at_fire: remainingTTL,
144
+ });
145
+ result.thresholdsCrossed++;
146
+ logger.warn(`Threshold crossed — contract: ${contractId}, ` +
147
+ `entry: ${entry.entry_key_xdr}, ` +
148
+ `remainingTTL: ${remainingTTL}, ` +
149
+ `threshold: ${alertConfig.threshold_ledgers}`);
150
+ }
151
+ }
152
+ else {
153
+ // 5. TTL is at or above threshold — resolve any open alert.
154
+ if (hasUnresolvedAlert(db, alertConfig.id, entry.id)) {
155
+ const resolvedConfigIds = resolveAlerts(db, entry.id, alertConfig.id);
156
+ result.alertsResolved++;
157
+ logger.info(`Alert resolved — contract: ${contractId}, ` +
158
+ `entry: ${entry.entry_key_xdr}, ` +
159
+ `remainingTTL: ${remainingTTL}, ` +
160
+ `threshold: ${alertConfig.threshold_ledgers}`);
161
+ // Send resolution notifications (best-effort, errors don't block).
162
+ for (const configId of resolvedConfigIds) {
163
+ const config = getAlertConfigById(db, configId);
164
+ if (!config)
165
+ continue;
166
+ const event = buildAlertEvent({
167
+ type: "alert_resolved",
168
+ contractId,
169
+ contractName: null,
170
+ network,
171
+ entryKeyXdr: entry.entry_key_xdr,
172
+ entryType: entry.entry_type,
173
+ entryLabel: entry.label,
174
+ configuredLedgers: config.threshold_ledgers,
175
+ remainingTTL,
176
+ firedAtLedger: rpcResult.latestLedger,
177
+ });
178
+ // Best-effort — log failures so they're visible, but don't block.
179
+ deliverSingleAlert(config.channel_type, config.channel_target, event, config.webhook_secret).catch((err) => {
180
+ logger.warn(`Resolution notification failed for config ${configId}: ${err instanceof Error ? err.message : String(err)}`);
181
+ });
182
+ }
183
+ }
184
+ }
185
+ }
186
+ }
187
+ }
188
+ //# sourceMappingURL=monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor.js","sourceRoot":"","sources":["../../src/core/monitor.ts"],"names":[],"mappings":"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"}