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.
- package/CONTRIBUTING.md +296 -0
- package/LICENSE +21 -0
- package/README.md +677 -0
- package/dist/alerts/alerts.d.ts +21 -0
- package/dist/alerts/alerts.d.ts.map +1 -0
- package/dist/alerts/alerts.js +18 -0
- package/dist/alerts/alerts.js.map +1 -0
- package/dist/alerts/discord.d.ts +3 -0
- package/dist/alerts/discord.d.ts.map +1 -0
- package/dist/alerts/discord.js +199 -0
- package/dist/alerts/discord.js.map +1 -0
- package/dist/alerts/dispatcher.d.ts +13 -0
- package/dist/alerts/dispatcher.d.ts.map +1 -0
- package/dist/alerts/dispatcher.js +91 -0
- package/dist/alerts/dispatcher.js.map +1 -0
- package/dist/alerts/keys.d.ts +24 -0
- package/dist/alerts/keys.d.ts.map +1 -0
- package/dist/alerts/keys.js +44 -0
- package/dist/alerts/keys.js.map +1 -0
- package/dist/alerts/pagerduty.d.ts +8 -0
- package/dist/alerts/pagerduty.d.ts.map +1 -0
- package/dist/alerts/pagerduty.js +164 -0
- package/dist/alerts/pagerduty.js.map +1 -0
- package/dist/alerts/resource.d.ts +23 -0
- package/dist/alerts/resource.d.ts.map +1 -0
- package/dist/alerts/resource.js +167 -0
- package/dist/alerts/resource.js.map +1 -0
- package/dist/alerts/slack.d.ts +7 -0
- package/dist/alerts/slack.d.ts.map +1 -0
- package/dist/alerts/slack.js +184 -0
- package/dist/alerts/slack.js.map +1 -0
- package/dist/alerts/telegram.d.ts +9 -0
- package/dist/alerts/telegram.d.ts.map +1 -0
- package/dist/alerts/telegram.js +133 -0
- package/dist/alerts/telegram.js.map +1 -0
- package/dist/alerts/templates.d.ts +109 -0
- package/dist/alerts/templates.d.ts.map +1 -0
- package/dist/alerts/templates.js +139 -0
- package/dist/alerts/templates.js.map +1 -0
- package/dist/alerts/types.d.ts +113 -0
- package/dist/alerts/types.d.ts.map +1 -0
- package/dist/alerts/types.js +87 -0
- package/dist/alerts/types.js.map +1 -0
- package/dist/alerts/webhook.d.ts +13 -0
- package/dist/alerts/webhook.d.ts.map +1 -0
- package/dist/alerts/webhook.js +56 -0
- package/dist/alerts/webhook.js.map +1 -0
- package/dist/cli/schemaFormatter.d.ts +11 -0
- package/dist/cli/schemaFormatter.d.ts.map +1 -0
- package/dist/cli/schemaFormatter.js +74 -0
- package/dist/cli/schemaFormatter.js.map +1 -0
- package/dist/commands/alerts.d.ts +3 -0
- package/dist/commands/alerts.d.ts.map +1 -0
- package/dist/commands/alerts.js +256 -0
- package/dist/commands/alerts.js.map +1 -0
- package/dist/commands/budget.d.ts +3 -0
- package/dist/commands/budget.d.ts.map +1 -0
- package/dist/commands/budget.js +47 -0
- package/dist/commands/budget.js.map +1 -0
- package/dist/commands/channels.d.ts +3 -0
- package/dist/commands/channels.d.ts.map +1 -0
- package/dist/commands/channels.js +84 -0
- package/dist/commands/channels.js.map +1 -0
- package/dist/commands/check.d.ts +3 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +58 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/completion.d.ts +3 -0
- package/dist/commands/completion.d.ts.map +1 -0
- package/dist/commands/completion.js +36 -0
- package/dist/commands/completion.js.map +1 -0
- package/dist/commands/costs.d.ts +15 -0
- package/dist/commands/costs.d.ts.map +1 -0
- package/dist/commands/costs.js +280 -0
- package/dist/commands/costs.js.map +1 -0
- package/dist/commands/daemon.d.ts +3 -0
- package/dist/commands/daemon.d.ts.map +1 -0
- package/dist/commands/daemon.js +93 -0
- package/dist/commands/daemon.js.map +1 -0
- package/dist/commands/db.d.ts +3 -0
- package/dist/commands/db.d.ts.map +1 -0
- package/dist/commands/db.js +140 -0
- package/dist/commands/db.js.map +1 -0
- package/dist/commands/guard.d.ts +3 -0
- package/dist/commands/guard.d.ts.map +1 -0
- package/dist/commands/guard.js +181 -0
- package/dist/commands/guard.js.map +1 -0
- package/dist/commands/history.d.ts +3 -0
- package/dist/commands/history.d.ts.map +1 -0
- package/dist/commands/history.js +57 -0
- package/dist/commands/history.js.map +1 -0
- package/dist/commands/inspect.d.ts +3 -0
- package/dist/commands/inspect.d.ts.map +1 -0
- package/dist/commands/inspect.js +82 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/mcp.d.ts +3 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +20 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/pause.d.ts +3 -0
- package/dist/commands/pause.d.ts.map +1 -0
- package/dist/commands/pause.js +32 -0
- package/dist/commands/pause.js.map +1 -0
- package/dist/commands/resources.d.ts +3 -0
- package/dist/commands/resources.d.ts.map +1 -0
- package/dist/commands/resources.js +95 -0
- package/dist/commands/resources.js.map +1 -0
- package/dist/commands/restore.d.ts +3 -0
- package/dist/commands/restore.d.ts.map +1 -0
- package/dist/commands/restore.js +92 -0
- package/dist/commands/restore.js.map +1 -0
- package/dist/commands/resume.d.ts +3 -0
- package/dist/commands/resume.d.ts.map +1 -0
- package/dist/commands/resume.js +31 -0
- package/dist/commands/resume.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +63 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/watch.d.ts +3 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +163 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/core/aws_secrets.d.ts +13 -0
- package/dist/core/aws_secrets.d.ts.map +1 -0
- package/dist/core/aws_secrets.js +34 -0
- package/dist/core/aws_secrets.js.map +1 -0
- package/dist/core/budget.d.ts +10 -0
- package/dist/core/budget.d.ts.map +1 -0
- package/dist/core/budget.js +31 -0
- package/dist/core/budget.js.map +1 -0
- package/dist/core/channels.d.ts +67 -0
- package/dist/core/channels.d.ts.map +1 -0
- package/dist/core/channels.js +136 -0
- package/dist/core/channels.js.map +1 -0
- package/dist/core/check.d.ts +25 -0
- package/dist/core/check.d.ts.map +1 -0
- package/dist/core/check.js +85 -0
- package/dist/core/check.js.map +1 -0
- package/dist/core/completion.d.ts +9 -0
- package/dist/core/completion.d.ts.map +1 -0
- package/dist/core/completion.js +68 -0
- package/dist/core/completion.js.map +1 -0
- package/dist/core/costs.d.ts +90 -0
- package/dist/core/costs.d.ts.map +1 -0
- package/dist/core/costs.js +147 -0
- package/dist/core/costs.js.map +1 -0
- package/dist/core/decoder.d.ts +7 -0
- package/dist/core/decoder.d.ts.map +1 -0
- package/dist/core/decoder.js +38 -0
- package/dist/core/decoder.js.map +1 -0
- package/dist/core/discovery.d.ts +38 -0
- package/dist/core/discovery.d.ts.map +1 -0
- package/dist/core/discovery.js +208 -0
- package/dist/core/discovery.js.map +1 -0
- package/dist/core/extension.d.ts +83 -0
- package/dist/core/extension.d.ts.map +1 -0
- package/dist/core/extension.js +429 -0
- package/dist/core/extension.js.map +1 -0
- package/dist/core/inspect.d.ts +62 -0
- package/dist/core/inspect.d.ts.map +1 -0
- package/dist/core/inspect.js +303 -0
- package/dist/core/inspect.js.map +1 -0
- package/dist/core/introspection.d.ts +8 -0
- package/dist/core/introspection.d.ts.map +1 -0
- package/dist/core/introspection.js +8 -0
- package/dist/core/introspection.js.map +1 -0
- package/dist/core/monitor.d.ts +42 -0
- package/dist/core/monitor.d.ts.map +1 -0
- package/dist/core/monitor.js +188 -0
- package/dist/core/monitor.js.map +1 -0
- package/dist/core/rent_projection.d.ts +153 -0
- package/dist/core/rent_projection.d.ts.map +1 -0
- package/dist/core/rent_projection.js +146 -0
- package/dist/core/rent_projection.js.map +1 -0
- package/dist/core/scvalTranslator.d.ts +11 -0
- package/dist/core/scvalTranslator.d.ts.map +1 -0
- package/dist/core/scvalTranslator.js +36 -0
- package/dist/core/scvalTranslator.js.map +1 -0
- package/dist/core/state_diff.d.ts +45 -0
- package/dist/core/state_diff.d.ts.map +1 -0
- package/dist/core/state_diff.js +112 -0
- package/dist/core/state_diff.js.map +1 -0
- package/dist/core/status.d.ts +24 -0
- package/dist/core/status.d.ts.map +1 -0
- package/dist/core/status.js +57 -0
- package/dist/core/status.js.map +1 -0
- package/dist/core/vault.d.ts +37 -0
- package/dist/core/vault.d.ts.map +1 -0
- package/dist/core/vault.js +179 -0
- package/dist/core/vault.js.map +1 -0
- package/dist/core/watch.d.ts +36 -0
- package/dist/core/watch.d.ts.map +1 -0
- package/dist/core/watch.js +176 -0
- package/dist/core/watch.js.map +1 -0
- package/dist/daemon/loop.d.ts +38 -0
- package/dist/daemon/loop.d.ts.map +1 -0
- package/dist/daemon/loop.js +169 -0
- package/dist/daemon/loop.js.map +1 -0
- package/dist/db/backup.d.ts +12 -0
- package/dist/db/backup.d.ts.map +1 -0
- package/dist/db/backup.js +132 -0
- package/dist/db/backup.js.map +1 -0
- package/dist/db/budget.d.ts +17 -0
- package/dist/db/budget.d.ts.map +1 -0
- package/dist/db/budget.js +31 -0
- package/dist/db/budget.js.map +1 -0
- package/dist/db/database.d.ts +6 -0
- package/dist/db/database.d.ts.map +1 -0
- package/dist/db/database.js +134 -0
- package/dist/db/database.js.map +1 -0
- package/dist/db/migrations/.gitkeep +1 -0
- package/dist/db/migrations/001_resource_usage_logs.sql +28 -0
- package/dist/db/migrator.d.ts +28 -0
- package/dist/db/migrator.d.ts.map +1 -0
- package/dist/db/migrator.js +75 -0
- package/dist/db/migrator.js.map +1 -0
- package/dist/db/repositories.d.ts +474 -0
- package/dist/db/repositories.d.ts.map +1 -0
- package/dist/db/repositories.js +809 -0
- package/dist/db/repositories.js.map +1 -0
- package/dist/db/schema.sql +207 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/lib.d.ts +20 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +16 -0
- package/dist/lib.js.map +1 -0
- package/dist/logging/index.d.ts +22 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +34 -0
- package/dist/logging/index.js.map +1 -0
- package/dist/logging/logger.d.ts +14 -0
- package/dist/logging/logger.d.ts.map +1 -0
- package/dist/logging/logger.js +135 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/logging/types.d.ts +10 -0
- package/dist/logging/types.d.ts.map +1 -0
- package/dist/logging/types.js +2 -0
- package/dist/logging/types.js.map +1 -0
- package/dist/mcp/index.d.ts +3 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +14 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +10 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +51 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/get-extension-costs.d.ts +4 -0
- package/dist/mcp/tools/get-extension-costs.d.ts.map +1 -0
- package/dist/mcp/tools/get-extension-costs.js +33 -0
- package/dist/mcp/tools/get-extension-costs.js.map +1 -0
- package/dist/mcp/tools/get_contract_status.d.ts +8 -0
- package/dist/mcp/tools/get_contract_status.d.ts.map +1 -0
- package/dist/mcp/tools/get_contract_status.js +33 -0
- package/dist/mcp/tools/get_contract_status.js.map +1 -0
- package/dist/rpc/client.d.ts +154 -0
- package/dist/rpc/client.d.ts.map +1 -0
- package/dist/rpc/client.js +766 -0
- package/dist/rpc/client.js.map +1 -0
- package/dist/utils/config.d.ts +51 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +86 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/formatting.d.ts +10 -0
- package/dist/utils/formatting.d.ts.map +1 -0
- package/dist/utils/formatting.js +66 -0
- package/dist/utils/formatting.js.map +1 -0
- package/dist/utils/watch-config.d.ts +13 -0
- package/dist/utils/watch-config.d.ts.map +1 -0
- package/dist/utils/watch-config.js +32 -0
- package/dist/utils/watch-config.js.map +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { StellarRpcClient } from "../rpc/client.js";
|
|
2
|
+
import { getChannelAccounts, updateChannelBalance, insertChannelAccount, markChannelFunded, } from "../db/repositories.js";
|
|
3
|
+
import { getLogger } from "../logging/index.js";
|
|
4
|
+
const logger = getLogger().child({ component: "ChannelAccountPool" });
|
|
5
|
+
/**
|
|
6
|
+
* Pool of channel accounts for concurrent TTL extensions.
|
|
7
|
+
*
|
|
8
|
+
* Each account tracks its own sequence number on Stellar, so concurrent
|
|
9
|
+
* transactions submitted through different accounts avoid sequence conflicts.
|
|
10
|
+
* acquire() hands out a slot in round-robin order, blocking callers until
|
|
11
|
+
* a slot is free. release() returns the slot and unblocks the next waiter.
|
|
12
|
+
*/
|
|
13
|
+
export class ChannelAccountPool {
|
|
14
|
+
db;
|
|
15
|
+
network;
|
|
16
|
+
accounts;
|
|
17
|
+
/** Tracks which publicKeys are currently in use. */
|
|
18
|
+
inUse = new Set();
|
|
19
|
+
/** Queue of resolve callbacks waiting for the next free slot. */
|
|
20
|
+
waiters = [];
|
|
21
|
+
/** Round-robin cursor. */
|
|
22
|
+
cursor = 0;
|
|
23
|
+
constructor(db, network) {
|
|
24
|
+
this.db = db;
|
|
25
|
+
this.network = network;
|
|
26
|
+
this.accounts = getChannelAccounts(db, network);
|
|
27
|
+
}
|
|
28
|
+
/** Number of registered channel accounts. */
|
|
29
|
+
size() {
|
|
30
|
+
return this.accounts.length;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Acquire an available channel account slot.
|
|
34
|
+
* If all slots are in use, waits until one is released.
|
|
35
|
+
*/
|
|
36
|
+
acquire() {
|
|
37
|
+
const slot = this.nextFreeSlot();
|
|
38
|
+
if (slot) {
|
|
39
|
+
this.inUse.add(slot.publicKey);
|
|
40
|
+
return Promise.resolve(slot);
|
|
41
|
+
}
|
|
42
|
+
// All slots busy — queue the caller
|
|
43
|
+
return new Promise(resolve => {
|
|
44
|
+
this.waiters.push(resolve);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Release a slot back to the pool.
|
|
49
|
+
* Unblocks the oldest waiting acquire() call if any.
|
|
50
|
+
*/
|
|
51
|
+
release(publicKey) {
|
|
52
|
+
this.inUse.delete(publicKey);
|
|
53
|
+
if (this.waiters.length > 0) {
|
|
54
|
+
const slot = this.nextFreeSlot();
|
|
55
|
+
if (slot) {
|
|
56
|
+
this.inUse.add(slot.publicKey);
|
|
57
|
+
this.waiters.shift()(slot);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Returns current balance information for all accounts in the pool.
|
|
63
|
+
* Reads from the DB — does not call the RPC.
|
|
64
|
+
*/
|
|
65
|
+
getBalances() {
|
|
66
|
+
return getChannelAccounts(this.db, this.network).map(a => ({
|
|
67
|
+
publicKey: a.public_key,
|
|
68
|
+
balanceXlm: a.balance_xlm,
|
|
69
|
+
balanceCheckedAt: a.balance_checked_at,
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Fetch native XLM balances for all accounts from the RPC and persist them.
|
|
74
|
+
* Errors per-account are logged and swallowed — does not throw.
|
|
75
|
+
*/
|
|
76
|
+
async refreshBalances(rpcUrl) {
|
|
77
|
+
if (this.accounts.length === 0)
|
|
78
|
+
return;
|
|
79
|
+
const client = new StellarRpcClient(this.network, rpcUrl);
|
|
80
|
+
await Promise.all(this.accounts.map(async (account) => {
|
|
81
|
+
try {
|
|
82
|
+
const response = await client.getAccount(account.public_key);
|
|
83
|
+
const nativeBalance = response.balances?.find((b) => b.asset_type === "native");
|
|
84
|
+
const xlm = nativeBalance ? parseFloat(nativeBalance.balance) : 0;
|
|
85
|
+
updateChannelBalance(this.db, account.public_key, xlm);
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
89
|
+
logger.warn(`Failed to refresh balance for ${account.public_key}: ${msg}`);
|
|
90
|
+
}
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
// ─── Private ─────────────────────────────────────────────────────────────
|
|
94
|
+
/**
|
|
95
|
+
* Find the next free account in round-robin order.
|
|
96
|
+
* Returns undefined if all accounts are in use.
|
|
97
|
+
*/
|
|
98
|
+
nextFreeSlot() {
|
|
99
|
+
const n = this.accounts.length;
|
|
100
|
+
for (let i = 0; i < n; i++) {
|
|
101
|
+
const idx = (this.cursor + i) % n;
|
|
102
|
+
const account = this.accounts[idx];
|
|
103
|
+
if (!this.inUse.has(account.public_key)) {
|
|
104
|
+
this.cursor = (idx + 1) % n;
|
|
105
|
+
return { publicKey: account.public_key, keypairSource: account.keypair_source };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
export function addChannel(db, publicKey, network, label) {
|
|
112
|
+
insertChannelAccount(db, { public_key: publicKey, network, label });
|
|
113
|
+
}
|
|
114
|
+
export function listChannels(db, network) {
|
|
115
|
+
return getChannelAccounts(db, network);
|
|
116
|
+
}
|
|
117
|
+
export async function fundChannels(db, masterSecretKey, amountXlm, network, rpcUrl) {
|
|
118
|
+
const accounts = getChannelAccounts(db, network);
|
|
119
|
+
if (accounts.length === 0) {
|
|
120
|
+
return { funded: 0, txHash: "", errors: [] };
|
|
121
|
+
}
|
|
122
|
+
const client = new StellarRpcClient(network, rpcUrl);
|
|
123
|
+
const destinations = accounts.map((a) => ({
|
|
124
|
+
publicKey: a.public_key,
|
|
125
|
+
amountXlm,
|
|
126
|
+
}));
|
|
127
|
+
const result = await client.sendPayments(destinations, masterSecretKey);
|
|
128
|
+
if (!result.success) {
|
|
129
|
+
return { funded: 0, txHash: result.txHash, errors: [result.error ?? "Transaction failed"] };
|
|
130
|
+
}
|
|
131
|
+
for (const account of accounts) {
|
|
132
|
+
markChannelFunded(db, account.public_key);
|
|
133
|
+
}
|
|
134
|
+
return { funded: accounts.length, txHash: result.txHash, errors: [] };
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=channels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels.js","sourceRoot":"","sources":["../../src/core/channels.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface CheckEntry {
|
|
2
|
+
entryKeyXdr: string;
|
|
3
|
+
entryType: "instance" | "wasm";
|
|
4
|
+
liveUntilLedger: number;
|
|
5
|
+
remainingTTL: number;
|
|
6
|
+
}
|
|
7
|
+
export interface CheckResult {
|
|
8
|
+
contractId: string;
|
|
9
|
+
network: string;
|
|
10
|
+
threshold: number;
|
|
11
|
+
latestLedger: number;
|
|
12
|
+
minimumTTL: number;
|
|
13
|
+
passed: boolean;
|
|
14
|
+
entries: CheckEntry[];
|
|
15
|
+
error?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* One-shot, stateless TTL check for a Soroban contract.
|
|
19
|
+
*
|
|
20
|
+
* Queries the Stellar RPC directly — no local DB required.
|
|
21
|
+
* Checks both the contract instance and its WASM code entry (when present).
|
|
22
|
+
* Returns `passed: true` when minimumTTL >= threshold.
|
|
23
|
+
*/
|
|
24
|
+
export declare function checkContractTTL(contractId: string, network: string, threshold: number, rpcUrl?: string): Promise<CheckResult>;
|
|
25
|
+
//# sourceMappingURL=check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/core/check.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,UAAU,GAAG,MAAM,CAAC;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAClC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,WAAW,CAAC,CAgFtB"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { StellarRpcClient } from "../rpc/client.js";
|
|
2
|
+
import { getLogger } from "../logging/index.js";
|
|
3
|
+
const logger = getLogger().child({ component: "CheckCommand" });
|
|
4
|
+
/**
|
|
5
|
+
* One-shot, stateless TTL check for a Soroban contract.
|
|
6
|
+
*
|
|
7
|
+
* Queries the Stellar RPC directly — no local DB required.
|
|
8
|
+
* Checks both the contract instance and its WASM code entry (when present).
|
|
9
|
+
* Returns `passed: true` when minimumTTL >= threshold.
|
|
10
|
+
*/
|
|
11
|
+
export async function checkContractTTL(contractId, network, threshold, rpcUrl) {
|
|
12
|
+
const client = new StellarRpcClient(network, rpcUrl);
|
|
13
|
+
const entries = [];
|
|
14
|
+
try {
|
|
15
|
+
const instanceEntry = await client.getContractInstanceEntry(contractId);
|
|
16
|
+
if (!instanceEntry) {
|
|
17
|
+
return {
|
|
18
|
+
contractId,
|
|
19
|
+
network,
|
|
20
|
+
threshold,
|
|
21
|
+
latestLedger: 0,
|
|
22
|
+
minimumTTL: 0,
|
|
23
|
+
passed: false,
|
|
24
|
+
entries: [],
|
|
25
|
+
error: `Contract ${contractId} not found on ${network}`,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
entries.push({
|
|
29
|
+
entryKeyXdr: instanceEntry.entryKeyXdr,
|
|
30
|
+
entryType: "instance",
|
|
31
|
+
liveUntilLedger: instanceEntry.liveUntilLedgerSeq,
|
|
32
|
+
remainingTTL: instanceEntry.remainingTTL,
|
|
33
|
+
});
|
|
34
|
+
if (instanceEntry.wasmHash) {
|
|
35
|
+
const wasmEntry = await client.getWasmCodeEntry(instanceEntry.wasmHash);
|
|
36
|
+
if (wasmEntry) {
|
|
37
|
+
entries.push({
|
|
38
|
+
entryKeyXdr: wasmEntry.entryKeyXdr,
|
|
39
|
+
entryType: "wasm",
|
|
40
|
+
liveUntilLedger: wasmEntry.liveUntilLedgerSeq,
|
|
41
|
+
remainingTTL: wasmEntry.remainingTTL,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
return {
|
|
46
|
+
contractId,
|
|
47
|
+
network,
|
|
48
|
+
threshold,
|
|
49
|
+
latestLedger: instanceEntry.latestLedger,
|
|
50
|
+
minimumTTL: 0,
|
|
51
|
+
passed: false,
|
|
52
|
+
entries,
|
|
53
|
+
error: `WASM code entry (hash: ${instanceEntry.wasmHash.substring(0, 10)}...) not found`,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const minimumTTL = Math.min(...entries.map(e => e.remainingTTL));
|
|
58
|
+
const passed = minimumTTL >= threshold;
|
|
59
|
+
logger.debug(`TTL check — contract: ${contractId}, minimumTTL: ${minimumTTL}, threshold: ${threshold}, passed: ${passed}`);
|
|
60
|
+
return {
|
|
61
|
+
contractId,
|
|
62
|
+
network,
|
|
63
|
+
threshold,
|
|
64
|
+
latestLedger: instanceEntry.latestLedger,
|
|
65
|
+
minimumTTL,
|
|
66
|
+
passed,
|
|
67
|
+
entries,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
72
|
+
logger.error(`TTL check failed for ${contractId}: ${message}`);
|
|
73
|
+
return {
|
|
74
|
+
contractId,
|
|
75
|
+
network,
|
|
76
|
+
threshold,
|
|
77
|
+
latestLedger: 0,
|
|
78
|
+
minimumTTL: 0,
|
|
79
|
+
passed: false,
|
|
80
|
+
entries: [],
|
|
81
|
+
error: message,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/core/check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type Database from "better-sqlite3";
|
|
2
|
+
export declare const TOP_LEVEL_COMMANDS: string[];
|
|
3
|
+
export declare const ALERTS_SUBCOMMANDS: string[];
|
|
4
|
+
export declare const CHANNELS_SUBCOMMANDS: string[];
|
|
5
|
+
export declare const STATUS_CONTRACT_COMMANDS: string[];
|
|
6
|
+
export declare function getCompletionSuggestions(db: Database.Database, words: string[], cursorIndex: number): string[];
|
|
7
|
+
export declare function renderBashCompletionScript(): string;
|
|
8
|
+
export declare function renderZshCompletionScript(): string;
|
|
9
|
+
//# sourceMappingURL=completion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../src/core/completion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAG3C,eAAO,MAAM,kBAAkB,UAY9B,CAAC;AAEF,eAAO,MAAM,kBAAkB,UAA+C,CAAC;AAC/E,eAAO,MAAM,oBAAoB,UAA0B,CAAC;AAC5D,eAAO,MAAM,wBAAwB,UAAgE,CAAC;AAEtG,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,KAAK,EAAE,MAAM,EAAE,EACf,WAAW,EAAE,MAAM,GAClB,MAAM,EAAE,CAsBV;AAED,wBAAgB,0BAA0B,IAAI,MAAM,CAYnD;AAED,wBAAgB,yBAAyB,IAAI,MAAM,CAgBlD"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { getAllContracts } from "../db/repositories.js";
|
|
2
|
+
export const TOP_LEVEL_COMMANDS = [
|
|
3
|
+
"watch",
|
|
4
|
+
"status",
|
|
5
|
+
"check",
|
|
6
|
+
"daemon",
|
|
7
|
+
"alerts",
|
|
8
|
+
"guard",
|
|
9
|
+
"costs",
|
|
10
|
+
"resources",
|
|
11
|
+
"restore",
|
|
12
|
+
"channels",
|
|
13
|
+
"completion",
|
|
14
|
+
];
|
|
15
|
+
export const ALERTS_SUBCOMMANDS = ["add", "list", "remove", "test", "history"];
|
|
16
|
+
export const CHANNELS_SUBCOMMANDS = ["add", "list", "fund"];
|
|
17
|
+
export const STATUS_CONTRACT_COMMANDS = ["status", "check", "resources", "costs", "guard", "restore"];
|
|
18
|
+
export function getCompletionSuggestions(db, words, cursorIndex) {
|
|
19
|
+
if (words.length <= 1 || cursorIndex <= 1) {
|
|
20
|
+
return TOP_LEVEL_COMMANDS;
|
|
21
|
+
}
|
|
22
|
+
const normalizedWords = words.slice(1, cursorIndex + 1);
|
|
23
|
+
const firstCommand = normalizedWords[0];
|
|
24
|
+
if (firstCommand === "alerts") {
|
|
25
|
+
if (cursorIndex === 2) {
|
|
26
|
+
return ALERTS_SUBCOMMANDS;
|
|
27
|
+
}
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
if (firstCommand && STATUS_CONTRACT_COMMANDS.includes(firstCommand) && cursorIndex === 2) {
|
|
31
|
+
const contracts = getAllContracts(db)
|
|
32
|
+
.map((contract) => contract.id)
|
|
33
|
+
.filter((id) => typeof id === "string");
|
|
34
|
+
return contracts;
|
|
35
|
+
}
|
|
36
|
+
return TOP_LEVEL_COMMANDS.filter((cmd) => cmd.startsWith(normalizedWords[0] ?? ""));
|
|
37
|
+
}
|
|
38
|
+
export function renderBashCompletionScript() {
|
|
39
|
+
return `#!/usr/bin/env bash
|
|
40
|
+
_sorokeep_complete() {
|
|
41
|
+
local cur prev words cword
|
|
42
|
+
_init_completion -n : || return
|
|
43
|
+
|
|
44
|
+
local suggestions
|
|
45
|
+
suggestions=$(sorokeep completion --query --cursor "$cword" "\${words[@]}" 2>/dev/null)
|
|
46
|
+
COMPREPLY=( $(compgen -W "$suggestions" -- "$cur") )
|
|
47
|
+
}
|
|
48
|
+
complete -F _sorokeep_complete sorokeep
|
|
49
|
+
`;
|
|
50
|
+
}
|
|
51
|
+
export function renderZshCompletionScript() {
|
|
52
|
+
return [
|
|
53
|
+
"#compdef sorokeep",
|
|
54
|
+
"",
|
|
55
|
+
"_sorokeep() {",
|
|
56
|
+
" local -a suggestions",
|
|
57
|
+
" local -a words",
|
|
58
|
+
"",
|
|
59
|
+
' local current_word=${words[CURRENT]}',
|
|
60
|
+
' suggestions=( ${(f)"$(sorokeep completion --query --cursor "$CURRENT" "${words[@]}")"} )',
|
|
61
|
+
" _describe 'values' suggestions",
|
|
62
|
+
"}",
|
|
63
|
+
"",
|
|
64
|
+
"compdef _sorokeep sorokeep",
|
|
65
|
+
"",
|
|
66
|
+
].join("\n");
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=completion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../../src/core/completion.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,OAAO;IACP,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,OAAO;IACP,WAAW;IACX,SAAS;IACT,UAAU;IACV,YAAY;CACb,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;AAC/E,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAC5D,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;AAEtG,MAAM,UAAU,wBAAwB,CACtC,EAAqB,EACrB,KAAe,EACf,WAAmB;IAEnB,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;QAC1C,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IACH,MAAM,eAAe,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC;IACtD,MAAM,YAAY,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;IAExC,IAAI,YAAY,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,kBAAkB,CAAC;QAC5B,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAEF,IAAI,YAAY,IAAI,wBAAwB,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;QACxF,MAAM,SAAS,GAAG,eAAe,CAAC,EAAE,CAAC;aAClC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;aAC9B,MAAM,CAAC,CAAC,EAAE,EAAgB,EAAE,CAAC,OAAO,EAAE,KAAK,QAAQ,CAAC,CAAC;QACxD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,0BAA0B;IACxC,OAAO;;;;;;;;;;CAUR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,yBAAyB;IACvC,OAAO;QACL,mBAAmB;QACnB,EAAE;QACF,eAAe;QACf,wBAAwB;QACxB,kBAAkB;QAClB,EAAE;QACF,wCAAwC;QACxC,4FAA4F;QAC5F,kCAAkC;QAClC,GAAG;QACH,EAAE;QACF,4BAA4B;QAC5B,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type Database from "better-sqlite3";
|
|
2
|
+
import type { FeeStatsResult } from "../rpc/client.js";
|
|
3
|
+
export interface EntryTypeCostBreakdown {
|
|
4
|
+
count: number;
|
|
5
|
+
costXlm: number;
|
|
6
|
+
}
|
|
7
|
+
export interface ExtensionCostDetail {
|
|
8
|
+
executedAt: string;
|
|
9
|
+
entryLabel: string;
|
|
10
|
+
entryType: string;
|
|
11
|
+
oldTtlLedgers: number;
|
|
12
|
+
newTtlLedgers: number;
|
|
13
|
+
oldTtlFormatted: string;
|
|
14
|
+
newTtlFormatted: string;
|
|
15
|
+
costXlm: number | null;
|
|
16
|
+
txHash: string;
|
|
17
|
+
executedAtLedger: number;
|
|
18
|
+
}
|
|
19
|
+
export interface CostProjection {
|
|
20
|
+
estimated30DayCostXlm: number;
|
|
21
|
+
basisDays: number;
|
|
22
|
+
formula: string;
|
|
23
|
+
}
|
|
24
|
+
export interface ExtensionCostsResult {
|
|
25
|
+
contract: {
|
|
26
|
+
id: string;
|
|
27
|
+
name: string | null;
|
|
28
|
+
network: string;
|
|
29
|
+
};
|
|
30
|
+
period: {
|
|
31
|
+
days: number | null;
|
|
32
|
+
label: string;
|
|
33
|
+
};
|
|
34
|
+
summary: {
|
|
35
|
+
totalExtensions: number;
|
|
36
|
+
totalCostXlm: number;
|
|
37
|
+
};
|
|
38
|
+
byEntryType: Record<string, EntryTypeCostBreakdown>;
|
|
39
|
+
recentExtensions: ExtensionCostDetail[];
|
|
40
|
+
projection?: CostProjection;
|
|
41
|
+
message?: string;
|
|
42
|
+
}
|
|
43
|
+
export type GetExtensionCostsError = {
|
|
44
|
+
success: false;
|
|
45
|
+
error: "contract_not_found";
|
|
46
|
+
contractId: string;
|
|
47
|
+
} | {
|
|
48
|
+
success: false;
|
|
49
|
+
error: "invalid_period";
|
|
50
|
+
period: number;
|
|
51
|
+
};
|
|
52
|
+
export type GetExtensionCostsResponse = {
|
|
53
|
+
success: true;
|
|
54
|
+
data: ExtensionCostsResult;
|
|
55
|
+
} | GetExtensionCostsError;
|
|
56
|
+
export declare function getExtensionCosts(db: Database.Database, contractId: string, options?: {
|
|
57
|
+
period?: number;
|
|
58
|
+
all?: boolean;
|
|
59
|
+
}): GetExtensionCostsResponse;
|
|
60
|
+
export interface PeriodCostSummary {
|
|
61
|
+
days: number;
|
|
62
|
+
totalExtensions: number;
|
|
63
|
+
totalCostXlm: number;
|
|
64
|
+
}
|
|
65
|
+
export interface MultiPeriodCostsData {
|
|
66
|
+
contract: {
|
|
67
|
+
id: string;
|
|
68
|
+
name: string | null;
|
|
69
|
+
network: string;
|
|
70
|
+
};
|
|
71
|
+
periods: PeriodCostSummary[];
|
|
72
|
+
projection: FeeAdjustedProjection;
|
|
73
|
+
}
|
|
74
|
+
export type GetMultiPeriodCostsResponse = {
|
|
75
|
+
success: true;
|
|
76
|
+
data: MultiPeriodCostsData;
|
|
77
|
+
} | {
|
|
78
|
+
success: false;
|
|
79
|
+
error: "contract_not_found";
|
|
80
|
+
contractId: string;
|
|
81
|
+
};
|
|
82
|
+
export declare function getMultiPeriodCosts(db: Database.Database, contractId: string, feeStats?: Pick<FeeStatsResult, "baseFeeStroops" | "surgePricingMultiplier">): GetMultiPeriodCostsResponse;
|
|
83
|
+
export interface FeeAdjustedProjection {
|
|
84
|
+
baseProjectedCostXlm: number;
|
|
85
|
+
adjustedProjectedCostXlm: number;
|
|
86
|
+
baseFeeMultiplier: number;
|
|
87
|
+
surgePricingMultiplier: number;
|
|
88
|
+
}
|
|
89
|
+
export declare function calculateFeeAdjustedProjection(totalCostXlm: number, periodDays: number, feeStats?: Pick<FeeStatsResult, "baseFeeStroops" | "surgePricingMultiplier">): FeeAdjustedProjection;
|
|
90
|
+
//# sourceMappingURL=costs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"costs.d.ts","sourceRoot":"","sources":["../../src/core/costs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { getContract, getEntriesForContract, getExtensionHistory, } from "../db/repositories.js";
|
|
2
|
+
import { formatTimeToCloseLedger } from "../utils/formatting.js";
|
|
3
|
+
const DEFAULT_PERIOD_DAYS = 30;
|
|
4
|
+
export function getExtensionCosts(db, contractId, options) {
|
|
5
|
+
const contract = getContract(db, contractId);
|
|
6
|
+
if (!contract) {
|
|
7
|
+
return {
|
|
8
|
+
success: false,
|
|
9
|
+
error: "contract_not_found",
|
|
10
|
+
contractId,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
const allTime = options?.all === true;
|
|
14
|
+
const period = allTime ? undefined : (options?.period ?? DEFAULT_PERIOD_DAYS);
|
|
15
|
+
if (period !== undefined && (!Number.isInteger(period) || period <= 0)) {
|
|
16
|
+
return {
|
|
17
|
+
success: false,
|
|
18
|
+
error: "invalid_period",
|
|
19
|
+
period,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const history = getExtensionHistory(db, contractId, period);
|
|
23
|
+
const periodLabel = allTime ? "all time" : `last ${period} days`;
|
|
24
|
+
if (history.length === 0) {
|
|
25
|
+
return {
|
|
26
|
+
success: true,
|
|
27
|
+
data: {
|
|
28
|
+
contract: {
|
|
29
|
+
id: contract.id,
|
|
30
|
+
name: contract.name,
|
|
31
|
+
network: contract.network,
|
|
32
|
+
},
|
|
33
|
+
period: {
|
|
34
|
+
days: period ?? null,
|
|
35
|
+
label: periodLabel,
|
|
36
|
+
},
|
|
37
|
+
summary: {
|
|
38
|
+
totalExtensions: 0,
|
|
39
|
+
totalCostXlm: 0,
|
|
40
|
+
},
|
|
41
|
+
byEntryType: {},
|
|
42
|
+
recentExtensions: [],
|
|
43
|
+
message: "No extensions recorded for this period.",
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const entries = getEntriesForContract(db, contractId);
|
|
48
|
+
const entryMap = new Map(entries.map((entry) => [entry.id, entry]));
|
|
49
|
+
let totalCostXlm = 0;
|
|
50
|
+
const byEntryType = {};
|
|
51
|
+
for (const record of history) {
|
|
52
|
+
const cost = record.cost_xlm ?? 0;
|
|
53
|
+
totalCostXlm += cost;
|
|
54
|
+
const entry = entryMap.get(record.contract_entry_id);
|
|
55
|
+
const entryType = entry?.entry_type ?? "unknown";
|
|
56
|
+
if (!byEntryType[entryType]) {
|
|
57
|
+
byEntryType[entryType] = { count: 0, costXlm: 0 };
|
|
58
|
+
}
|
|
59
|
+
byEntryType[entryType].count++;
|
|
60
|
+
byEntryType[entryType].costXlm += cost;
|
|
61
|
+
}
|
|
62
|
+
const recentExtensions = history.map((record) => {
|
|
63
|
+
const entry = entryMap.get(record.contract_entry_id);
|
|
64
|
+
const entryLabel = entry?.label ?? entry?.entry_type ?? "unknown";
|
|
65
|
+
const entryType = entry?.entry_type ?? "unknown";
|
|
66
|
+
return {
|
|
67
|
+
executedAt: record.executed_at,
|
|
68
|
+
entryLabel,
|
|
69
|
+
entryType,
|
|
70
|
+
oldTtlLedgers: record.old_ttl_ledgers,
|
|
71
|
+
newTtlLedgers: record.new_ttl_ledgers,
|
|
72
|
+
oldTtlFormatted: formatTimeToCloseLedger(record.old_ttl_ledgers),
|
|
73
|
+
newTtlFormatted: formatTimeToCloseLedger(record.new_ttl_ledgers),
|
|
74
|
+
costXlm: record.cost_xlm,
|
|
75
|
+
txHash: record.tx_hash,
|
|
76
|
+
executedAtLedger: record.executed_at_ledger,
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
return {
|
|
80
|
+
success: true,
|
|
81
|
+
data: {
|
|
82
|
+
contract: {
|
|
83
|
+
id: contract.id,
|
|
84
|
+
name: contract.name,
|
|
85
|
+
network: contract.network,
|
|
86
|
+
},
|
|
87
|
+
period: {
|
|
88
|
+
days: period ?? null,
|
|
89
|
+
label: periodLabel,
|
|
90
|
+
},
|
|
91
|
+
summary: {
|
|
92
|
+
totalExtensions: history.length,
|
|
93
|
+
totalCostXlm,
|
|
94
|
+
},
|
|
95
|
+
byEntryType,
|
|
96
|
+
recentExtensions,
|
|
97
|
+
...(period !== undefined
|
|
98
|
+
? {
|
|
99
|
+
projection: {
|
|
100
|
+
estimated30DayCostXlm: (totalCostXlm / period) * 30,
|
|
101
|
+
basisDays: period,
|
|
102
|
+
formula: "linear extrapolation from period average",
|
|
103
|
+
},
|
|
104
|
+
}
|
|
105
|
+
: {}),
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
const MULTI_PERIOD_WINDOWS = [7, 30, 90];
|
|
110
|
+
export function getMultiPeriodCosts(db, contractId, feeStats) {
|
|
111
|
+
const contract = getContract(db, contractId);
|
|
112
|
+
if (!contract) {
|
|
113
|
+
return { success: false, error: "contract_not_found", contractId };
|
|
114
|
+
}
|
|
115
|
+
const periods = MULTI_PERIOD_WINDOWS.map((days) => {
|
|
116
|
+
const history = getExtensionHistory(db, contractId, days);
|
|
117
|
+
let totalCostXlm = 0;
|
|
118
|
+
for (const record of history) {
|
|
119
|
+
totalCostXlm += record.cost_xlm ?? 0;
|
|
120
|
+
}
|
|
121
|
+
return { days, totalExtensions: history.length, totalCostXlm };
|
|
122
|
+
});
|
|
123
|
+
const thirtyDay = periods.find((p) => p.days === 30);
|
|
124
|
+
const projection = calculateFeeAdjustedProjection(thirtyDay.totalCostXlm, 30, feeStats);
|
|
125
|
+
return {
|
|
126
|
+
success: true,
|
|
127
|
+
data: {
|
|
128
|
+
contract: { id: contract.id, name: contract.name, network: contract.network },
|
|
129
|
+
periods,
|
|
130
|
+
projection,
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const DEFAULT_BASE_FEE_STROOPS = 100;
|
|
135
|
+
export function calculateFeeAdjustedProjection(totalCostXlm, periodDays, feeStats) {
|
|
136
|
+
const baseProjectedCostXlm = (totalCostXlm / periodDays) * 30;
|
|
137
|
+
const liveBaseFee = feeStats?.baseFeeStroops ?? DEFAULT_BASE_FEE_STROOPS;
|
|
138
|
+
const baseFeeMultiplier = Math.max(liveBaseFee / DEFAULT_BASE_FEE_STROOPS, 0);
|
|
139
|
+
const surgePricingMultiplier = Math.max(feeStats?.surgePricingMultiplier ?? 1, 1);
|
|
140
|
+
return {
|
|
141
|
+
baseProjectedCostXlm,
|
|
142
|
+
adjustedProjectedCostXlm: baseProjectedCostXlm * baseFeeMultiplier * surgePricingMultiplier,
|
|
143
|
+
baseFeeMultiplier,
|
|
144
|
+
surgePricingMultiplier,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=costs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"costs.js","sourceRoot":"","sources":["../../src/core/costs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decoder.d.ts","sourceRoot":"","sources":["../../src/core/decoder.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,GAAG,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAqCnE"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { xdr, Address, scValToNative } from '@stellar/stellar-sdk';
|
|
2
|
+
export function decodeLedgerKey(base64Key) {
|
|
3
|
+
const buf = Buffer.from(base64Key, 'base64');
|
|
4
|
+
const key = xdr.LedgerKey.fromXDR(buf);
|
|
5
|
+
if (key.switch() !== xdr.LedgerEntryType.contractData()) {
|
|
6
|
+
throw new Error('Unsupported ledger entry type');
|
|
7
|
+
}
|
|
8
|
+
const contractData = key.contractData();
|
|
9
|
+
const contractAddress = Address.fromScAddress(contractData.contract());
|
|
10
|
+
const contractId = contractAddress.toString();
|
|
11
|
+
const scValKey = contractData.key();
|
|
12
|
+
let symbol;
|
|
13
|
+
if (scValKey.switch() === xdr.ScValType.scvLedgerKeyContractInstance()) {
|
|
14
|
+
symbol = 'ContractInstance';
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
try {
|
|
18
|
+
symbol = scValToNative(scValKey);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
symbol = 'Unknown';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const durabilityType = contractData.durability();
|
|
25
|
+
let durability = 'Unknown';
|
|
26
|
+
if (durabilityType.value === xdr.ContractDataDurability.persistent().value) {
|
|
27
|
+
durability = 'Persistent';
|
|
28
|
+
}
|
|
29
|
+
else if (durabilityType.value === xdr.ContractDataDurability.temporary().value) {
|
|
30
|
+
durability = 'Temporary';
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
contractId,
|
|
34
|
+
symbol,
|
|
35
|
+
durability
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=decoder.js.map
|