@intent-engine/cli 0.1.42 → 0.1.44

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 (194) hide show
  1. package/dist/src/accounts.d.ts +4 -2
  2. package/dist/src/accounts.js +5 -4
  3. package/dist/src/accounts.js.map +1 -1
  4. package/dist/src/add-to.d.ts +2 -0
  5. package/dist/src/add-to.js +9 -3
  6. package/dist/src/add-to.js.map +1 -1
  7. package/dist/src/admin-commands.d.ts +22 -1
  8. package/dist/src/admin-commands.js +44 -12
  9. package/dist/src/admin-commands.js.map +1 -1
  10. package/dist/src/agent/actions.d.ts +1 -0
  11. package/dist/src/agent/actions.js +15 -1
  12. package/dist/src/agent/actions.js.map +1 -1
  13. package/dist/src/agent/budget.d.ts +5 -5
  14. package/dist/src/agent/budget.js +26 -6
  15. package/dist/src/agent/budget.js.map +1 -1
  16. package/dist/src/agent/claims.d.ts +2 -1
  17. package/dist/src/agent/claims.js +1 -1
  18. package/dist/src/agent/claims.js.map +1 -1
  19. package/dist/src/agent/create.d.ts +16 -7
  20. package/dist/src/agent/create.js +25 -3
  21. package/dist/src/agent/create.js.map +1 -1
  22. package/dist/src/agent/jobs.js +8 -3
  23. package/dist/src/agent/jobs.js.map +1 -1
  24. package/dist/src/agent/mandate-agent.js +3 -2
  25. package/dist/src/agent/mandate-agent.js.map +1 -1
  26. package/dist/src/agent/mandate-revoke.js +1 -1
  27. package/dist/src/agent/mandate-revoke.js.map +1 -1
  28. package/dist/src/agent/owner.js +4 -2
  29. package/dist/src/agent/owner.js.map +1 -1
  30. package/dist/src/agent/prepare.d.ts +1 -1
  31. package/dist/src/agent/prepare.js +9 -2
  32. package/dist/src/agent/prepare.js.map +1 -1
  33. package/dist/src/agent/problems.d.ts +18 -0
  34. package/dist/src/agent/problems.js +39 -15
  35. package/dist/src/agent/problems.js.map +1 -1
  36. package/dist/src/agent/profile.d.ts +1 -0
  37. package/dist/src/agent/profile.js +30 -5
  38. package/dist/src/agent/profile.js.map +1 -1
  39. package/dist/src/agent/read.js +3 -4
  40. package/dist/src/agent/read.js.map +1 -1
  41. package/dist/src/agent/reputation.js +16 -7
  42. package/dist/src/agent/reputation.js.map +1 -1
  43. package/dist/src/agent/sales.js +17 -23
  44. package/dist/src/agent/sales.js.map +1 -1
  45. package/dist/src/agent/settle.js +1 -0
  46. package/dist/src/agent/settle.js.map +1 -1
  47. package/dist/src/agent/signed-prepare.js +3 -2
  48. package/dist/src/agent/signed-prepare.js.map +1 -1
  49. package/dist/src/agent/signed-relay.d.ts +1 -1
  50. package/dist/src/agent/signed-relay.js +2 -1
  51. package/dist/src/agent/signed-relay.js.map +1 -1
  52. package/dist/src/agent/signed-submit.js +7 -5
  53. package/dist/src/agent/signed-submit.js.map +1 -1
  54. package/dist/src/agent/signed-terms.d.ts +1 -5
  55. package/dist/src/agent/spec.js +16 -4
  56. package/dist/src/agent/spec.js.map +1 -1
  57. package/dist/src/agent/wallet/account.js +2 -1
  58. package/dist/src/agent/wallet/account.js.map +1 -1
  59. package/dist/src/agent/wallet/attest.d.ts +2 -0
  60. package/dist/src/agent/wallet/attest.js +46 -24
  61. package/dist/src/agent/wallet/attest.js.map +1 -1
  62. package/dist/src/agent/wallet/committee.js +29 -17
  63. package/dist/src/agent/wallet/committee.js.map +1 -1
  64. package/dist/src/agent/wallet/delivery.d.ts +4 -1
  65. package/dist/src/agent/wallet/delivery.js +80 -23
  66. package/dist/src/agent/wallet/delivery.js.map +1 -1
  67. package/dist/src/agent/wallet/escrow.d.ts +1 -0
  68. package/dist/src/agent/wallet/escrow.js +81 -18
  69. package/dist/src/agent/wallet/escrow.js.map +1 -1
  70. package/dist/src/agent/wallet/fills.js +4 -3
  71. package/dist/src/agent/wallet/fills.js.map +1 -1
  72. package/dist/src/agent/wallet/guard.d.ts +32 -0
  73. package/dist/src/agent/wallet/guard.js +131 -9
  74. package/dist/src/agent/wallet/guard.js.map +1 -1
  75. package/dist/src/agent/wallet/history.js +2 -2
  76. package/dist/src/agent/wallet/history.js.map +1 -1
  77. package/dist/src/agent/wallet/offer.d.ts +18 -0
  78. package/dist/src/agent/wallet/offer.js +2 -1
  79. package/dist/src/agent/wallet/offer.js.map +1 -1
  80. package/dist/src/agent/wallet/openings.d.ts +37 -0
  81. package/dist/src/agent/wallet/openings.js +73 -0
  82. package/dist/src/agent/wallet/openings.js.map +1 -0
  83. package/dist/src/agent/wallet/receipt.d.ts +6 -0
  84. package/dist/src/agent/wallet/receipt.js +21 -3
  85. package/dist/src/agent/wallet/receipt.js.map +1 -1
  86. package/dist/src/agent/wallet/record.d.ts +3 -2
  87. package/dist/src/agent/wallet/record.js +16 -10
  88. package/dist/src/agent/wallet/record.js.map +1 -1
  89. package/dist/src/agent/wallet/split.d.ts +1 -0
  90. package/dist/src/agent/wallet/split.js +84 -57
  91. package/dist/src/agent/wallet/split.js.map +1 -1
  92. package/dist/src/agent/wallet/trade.js +2 -1
  93. package/dist/src/agent/wallet/trade.js.map +1 -1
  94. package/dist/src/agent/wallet/unwrap.js +2 -1
  95. package/dist/src/agent/wallet/unwrap.js.map +1 -1
  96. package/dist/src/agent/work-claims.js +3 -2
  97. package/dist/src/agent/work-claims.js.map +1 -1
  98. package/dist/src/arg-admin.d.ts +1 -1
  99. package/dist/src/arg-admin.js +4 -0
  100. package/dist/src/arg-admin.js.map +1 -1
  101. package/dist/src/arg-options.d.ts +70 -2
  102. package/dist/src/arg-options.js +36 -10
  103. package/dist/src/arg-options.js.map +1 -1
  104. package/dist/src/arg-solve.d.ts +6 -0
  105. package/dist/src/arg-solve.js +46 -1
  106. package/dist/src/arg-solve.js.map +1 -1
  107. package/dist/src/arg-usage.d.ts +2 -2
  108. package/dist/src/arg-usage.js +40 -36
  109. package/dist/src/arg-usage.js.map +1 -1
  110. package/dist/src/arg-values.d.ts +20 -1
  111. package/dist/src/arg-values.js +72 -2
  112. package/dist/src/arg-values.js.map +1 -1
  113. package/dist/src/args.d.ts +4 -1
  114. package/dist/src/args.js +39 -9
  115. package/dist/src/args.js.map +1 -1
  116. package/dist/src/claim-commands.js +24 -4
  117. package/dist/src/claim-commands.js.map +1 -1
  118. package/dist/src/clusters.d.ts +1 -0
  119. package/dist/src/clusters.js +1 -0
  120. package/dist/src/clusters.js.map +1 -1
  121. package/dist/src/command-types.d.ts +49 -1
  122. package/dist/src/commands.js +37 -8
  123. package/dist/src/commands.js.map +1 -1
  124. package/dist/src/committee-commands.d.ts +13 -2
  125. package/dist/src/committee-commands.js +58 -11
  126. package/dist/src/committee-commands.js.map +1 -1
  127. package/dist/src/crank.d.ts +3 -3
  128. package/dist/src/crank.js +11 -9
  129. package/dist/src/crank.js.map +1 -1
  130. package/dist/src/float-commands.d.ts +17 -0
  131. package/dist/src/float-commands.js +94 -0
  132. package/dist/src/float-commands.js.map +1 -0
  133. package/dist/src/flow-commands.js +2 -2
  134. package/dist/src/flow-commands.js.map +1 -1
  135. package/dist/src/flows.d.ts +2 -2
  136. package/dist/src/flows.js +8 -2
  137. package/dist/src/flows.js.map +1 -1
  138. package/dist/src/job-args.js +16 -3
  139. package/dist/src/job-args.js.map +1 -1
  140. package/dist/src/job-commands.js +39 -10
  141. package/dist/src/job-commands.js.map +1 -1
  142. package/dist/src/job-filters.d.ts +15 -3
  143. package/dist/src/job-filters.js +31 -6
  144. package/dist/src/job-filters.js.map +1 -1
  145. package/dist/src/judge-digest.d.ts +7 -0
  146. package/dist/src/judge-digest.js +27 -0
  147. package/dist/src/judge-digest.js.map +1 -0
  148. package/dist/src/judge-watch.js +16 -6
  149. package/dist/src/judge-watch.js.map +1 -1
  150. package/dist/src/judge.d.ts +18 -1
  151. package/dist/src/judge.js +87 -17
  152. package/dist/src/judge.js.map +1 -1
  153. package/dist/src/ledger-keys.d.ts +4 -1
  154. package/dist/src/ledger-keys.js +21 -5
  155. package/dist/src/ledger-keys.js.map +1 -1
  156. package/dist/src/legacy-commands.d.ts +8 -0
  157. package/dist/src/legacy-commands.js +94 -0
  158. package/dist/src/legacy-commands.js.map +1 -0
  159. package/dist/src/main.d.ts +3 -0
  160. package/dist/src/main.js +5 -0
  161. package/dist/src/main.js.map +1 -1
  162. package/dist/src/migrate-commands.d.ts +10 -0
  163. package/dist/src/migrate-commands.js +127 -0
  164. package/dist/src/migrate-commands.js.map +1 -0
  165. package/dist/src/monitor-args.d.ts +2 -0
  166. package/dist/src/monitor-args.js +9 -2
  167. package/dist/src/monitor-args.js.map +1 -1
  168. package/dist/src/monitor-fills.d.ts +2 -2
  169. package/dist/src/monitor-fills.js +9 -5
  170. package/dist/src/monitor-fills.js.map +1 -1
  171. package/dist/src/monitor-limits.d.ts +25 -0
  172. package/dist/src/monitor-limits.js +58 -0
  173. package/dist/src/monitor-limits.js.map +1 -0
  174. package/dist/src/monitor.d.ts +10 -1
  175. package/dist/src/monitor.js +81 -31
  176. package/dist/src/monitor.js.map +1 -1
  177. package/dist/src/release-simulation.d.ts +3 -2
  178. package/dist/src/release-simulation.js +1 -0
  179. package/dist/src/release-simulation.js.map +1 -1
  180. package/dist/src/sealed-commands.d.ts +6 -0
  181. package/dist/src/sealed-commands.js +19 -1
  182. package/dist/src/sealed-commands.js.map +1 -1
  183. package/dist/src/solve-commands.d.ts +3 -1
  184. package/dist/src/solve-commands.js +31 -4
  185. package/dist/src/solve-commands.js.map +1 -1
  186. package/dist/src/trust-args.d.ts +4 -2
  187. package/dist/src/trust-args.js +24 -7
  188. package/dist/src/trust-args.js.map +1 -1
  189. package/dist/src/version.d.ts +1 -1
  190. package/dist/src/version.js +1 -1
  191. package/dist/src/wallet.d.ts +8 -2
  192. package/dist/src/wallet.js +44 -7
  193. package/dist/src/wallet.js.map +1 -1
  194. package/package.json +5 -4
@@ -0,0 +1,127 @@
1
+ import { createNoopSigner, getAddressDecoder } from "@solana/kit";
2
+ import { boardTerms, buildMigrate, findConfigPda, INTENT_ENGINE_PROGRAM_ADDRESS, isConfigAccount, isCurrentAccount, migrationOf, storedVersion } from "@intent-engine/core";
3
+ import { rentExemptFor, rentSysvar } from "@intent-engine/client";
4
+ import { AUTHORITY_NEXT, previewed, unsignedFor } from "./admin-commands.js";
5
+ import { transactionSigner } from "./ledger-keys.js";
6
+ import { NOT_SENT } from "./flows.js";
7
+ export const MIGRATE_BATCH = 8;
8
+ const ADMIN_AT = 8;
9
+ export const NOTHING_TO_MIGRATE = "nothing to migrate: every engine account is current or needs close-legacy";
10
+ const adminOf = (data) => getAddressDecoder().decode(data, ADMIN_AT);
11
+ async function listed(command, transport) {
12
+ if (command.address !== null) {
13
+ const view = await transport.getAccount(command.address);
14
+ if (view === null) {
15
+ throw new Error(`${command.address} does not exist`);
16
+ }
17
+ if (view.owner !== INTENT_ENGINE_PROGRAM_ADDRESS) {
18
+ throw new Error(`${command.address} is not an engine account; migrate rewrites only accounts the engine program owns`);
19
+ }
20
+ return [{ address: command.address, data: view.data, lamports: view.lamports }];
21
+ }
22
+ if (transport.engineAccounts === undefined) {
23
+ throw new Error("this connection cannot list program accounts; migrate them one by one with --address");
24
+ }
25
+ return transport.engineAccounts();
26
+ }
27
+ function unread(entry) {
28
+ const stored = storedVersion(entry.data);
29
+ return stored === null
30
+ ? `engine account of ${entry.data.length} bytes that matches no account type; close it with intent-engine close-legacy`
31
+ : `${stored.layout.name} account in a layout no program version wrote: version ${stored.version}, ${entry.data.length} bytes; close it with intent-engine close-legacy`;
32
+ }
33
+ const countBy = (names) => Object.fromEntries([...new Set(names)].sort().map((name) => [name, names.filter((n) => n === name).length]));
34
+ const batchesOf = (items) => Array.from({ length: Math.ceil(items.length / MIGRATE_BATCH) }, (_, i) => items.slice(i * MIGRATE_BATCH, (i + 1) * MIGRATE_BATCH));
35
+ const topUpFor = (rent, entry, from, to) => {
36
+ const newMin = rentExemptFor(rent, to);
37
+ const grown = entry.lamports + newMin - rentExemptFor(rent, from);
38
+ const floor = newMin + (boardTerms(entry.data)?.held ?? 0n);
39
+ const [target = floor] = [grown, floor].sort((a, b) => Number(b - a));
40
+ return target - entry.lamports;
41
+ };
42
+ const errorText = (error) => (error instanceof Error ? error.message : String(error));
43
+ export async function migrate(command, runtime, transport) {
44
+ const payer = await transactionSigner(runtime, command.keypair);
45
+ const [config] = await findConfigPda();
46
+ const found = await listed(command, transport);
47
+ const current = found.filter((entry) => isCurrentAccount(entry.data));
48
+ const outdated = found.filter((entry) => !isCurrentAccount(entry.data));
49
+ const unmigrated = outdated.filter((entry) => migrationOf(entry.data) === null).map((entry) => ({ address: entry.address, reason: unread(entry) }));
50
+ const one = command.address === null ? null : (found[0] ?? null);
51
+ if (one !== null && current.length > 0) {
52
+ throw new Error(`${one.address} is a current ${storedVersion(one.data)?.layout.name ?? "engine"} account; there is nothing to migrate`);
53
+ }
54
+ if (one !== null && unmigrated.length > 0) {
55
+ throw new Error(`${one.address} cannot migrate: ${unread(one)}`);
56
+ }
57
+ const rent = await rentSysvar(transport);
58
+ const planned = outdated.flatMap((entry) => {
59
+ const migration = migrationOf(entry.data);
60
+ if (migration === null) {
61
+ return [];
62
+ }
63
+ const { layout, from } = migration;
64
+ const topUp = from.space < layout.space ? topUpFor(rent, entry, from.space, layout.space) : 0n;
65
+ const view = `${layout.name} account: version ${from.version}, ${from.space} bytes -> version ${layout.version}, ${layout.space} bytes`;
66
+ return [{ ...entry, name: layout.name, from: view, topUp }];
67
+ });
68
+ const configEntry = planned.find((entry) => isConfigAccount(entry.data));
69
+ const admin = configEntry === undefined ? null : adminOf(configEntry.data);
70
+ const byPayer = planned.filter((entry) => entry !== configEntry || admin === payer.address);
71
+ const proposal = admin === null || admin === payer.address
72
+ ? null
73
+ : await unsignedFor(transport, admin, [await buildMigrate({ payer: createNoopSigner(admin), account: config })]);
74
+ const instructions = await Promise.all(byPayer.map((entry) => buildMigrate({ payer, account: entry.address, ...(isConfigAccount(entry.data) ? {} : { config }) })));
75
+ const batches = batchesOf(instructions);
76
+ const topUp = byPayer.reduce((sum, entry) => sum + entry.topUp, 0n);
77
+ const configTopUp = configEntry?.topUp ?? 0n;
78
+ const adminTopUp = proposal === null ? 0n : configTopUp;
79
+ const counts = countBy(byPayer.map((entry) => entry.name));
80
+ const summary = [
81
+ one === null
82
+ ? `Migrates ${byPayer.length} outdated engine accounts in ${batches.length} transactions: ${Object.entries(counts).map(([name, n]) => `${n} ${name}`).join(", ") || "none"}`
83
+ : `Migrates ${one.address}, an outdated ${planned[0]?.from ?? "engine account"}`,
84
+ ...(topUp === 0n ? [] : [`Pays ${topUp} lamports of rent from ${payer.address} for the accounts that grow; no account loses lamports`]),
85
+ ...(one === null ? [`Skips ${current.length} accounts that are already current`] : []),
86
+ ...(unmigrated.length === 0 ? [] : [`Cannot migrate ${unmigrated.length} accounts of a layout no program version wrote; close them with intent-engine close-legacy`]),
87
+ ...(proposal === null
88
+ ? []
89
+ : [
90
+ `Only the admin ${admin} migrates the config: import config_proposal.transaction_base58 into the multisig as a proposal`,
91
+ ...(adminTopUp === 0n ? [] : [`The admin ${admin} pays ${adminTopUp} lamports of rent for the config and must hold them before the proposal executes`]),
92
+ ]),
93
+ ];
94
+ const shown = {
95
+ payer: payer.address,
96
+ migrate: counts,
97
+ current: current.length,
98
+ unmigrated,
99
+ top_up_lamports: topUp + adminTopUp,
100
+ ...(configEntry === undefined ? {} : { config: { address: configEntry.address, admin, top_up_lamports: configTopUp } }),
101
+ transactions: batches.length,
102
+ ...(proposal === null ? {} : { config_proposal: proposal }),
103
+ summary,
104
+ };
105
+ if (instructions.length === 0) {
106
+ return { ...shown, sent: false, next: proposal === null ? NOTHING_TO_MIGRATE : AUTHORITY_NEXT };
107
+ }
108
+ if (one !== null) {
109
+ return previewed(transport, instructions, payer, shown, command.yes);
110
+ }
111
+ if (!command.yes) {
112
+ return { ...shown, sent: false, next: NOT_SENT };
113
+ }
114
+ const signatures = [];
115
+ const failed = [];
116
+ for (const [at, batch] of batches.entries()) {
117
+ const accounts = byPayer.slice(at * MIGRATE_BATCH, at * MIGRATE_BATCH + batch.length).map((entry) => entry.address);
118
+ try {
119
+ signatures.push(await transport.send(batch, payer));
120
+ }
121
+ catch (error) {
122
+ failed.push({ accounts, error: errorText(error) });
123
+ }
124
+ }
125
+ return { ...shown, sent: true, signatures, failed };
126
+ }
127
+ //# sourceMappingURL=migrate-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate-commands.js","sourceRoot":"","sources":["../../src/migrate-commands.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,9 @@ export declare const MONITOR_INTERVAL = 30;
5
5
  export declare const MIN_MONITOR_INTERVAL = 5;
6
6
  export declare const MAX_MONITOR_INTERVAL = 3600;
7
7
  export declare const MAX_MONITOR_FILLS = 999;
8
+ export declare const MAX_MONITOR_SINCE = 86400;
8
9
  export declare const MONITOR_NEEDS_BASELINE = "monitor needs --expect <baseline file>; write one first with monitor --write-baseline <file> after checking the current config and program are the ones you intend";
9
10
  export declare const BASELINE_ALONE = "--write-baseline writes the current values and exits, so it takes no other monitor option but --url";
11
+ export declare const SINCE_NEEDS_ONCE = "--since sets how far back --once reads fills, so it needs --once";
10
12
  export declare const MAX_FILL_FORMAT = "--max-fill takes <mint>=<raw amount>, once per input mint";
11
13
  export declare function monitorOf(remote: Remote, values: Values): Command;
@@ -5,8 +5,10 @@ export const MONITOR_INTERVAL = 30;
5
5
  export const MIN_MONITOR_INTERVAL = 5;
6
6
  export const MAX_MONITOR_INTERVAL = 3_600;
7
7
  export const MAX_MONITOR_FILLS = 999;
8
+ export const MAX_MONITOR_SINCE = 86_400;
8
9
  export const MONITOR_NEEDS_BASELINE = "monitor needs --expect <baseline file>; write one first with monitor --write-baseline <file> after checking the current config and program are the ones you intend";
9
10
  export const BASELINE_ALONE = "--write-baseline writes the current values and exits, so it takes no other monitor option but --url";
11
+ export const SINCE_NEEDS_ONCE = "--since sets how far back --once reads fills, so it needs --once";
10
12
  export const MAX_FILL_FORMAT = "--max-fill takes <mint>=<raw amount>, once per input mint";
11
13
  function maxFills(entries, url) {
12
14
  const limits = new Map();
@@ -28,7 +30,7 @@ function maxFills(entries, url) {
28
30
  return limits;
29
31
  }
30
32
  export function monitorOf(remote, values) {
31
- const watching = [values.expect, values.interval, values["max-fill"], values["max-fills"], values.webhook, values.once];
33
+ const watching = [values.expect, values.interval, values["max-fill"], values["max-fills"], values.webhook, values.once, values.since];
32
34
  const write = values["write-baseline"];
33
35
  if (write !== undefined) {
34
36
  if (watching.some((v) => v !== undefined)) {
@@ -42,12 +44,17 @@ export function monitorOf(remote, values) {
42
44
  if (values.webhook !== undefined) {
43
45
  https(values.webhook, "webhook");
44
46
  }
47
+ if (values.since !== undefined && values.once !== true) {
48
+ throw new UsageError(SINCE_NEEDS_ONCE);
49
+ }
50
+ const interval = parseBounded(values.interval ?? String(MONITOR_INTERVAL), "interval", MAX_MONITOR_INTERVAL, MIN_MONITOR_INTERVAL);
45
51
  return {
46
52
  name: "monitor",
47
53
  ...remote,
48
54
  baseline: values.expect,
49
55
  watch: {
50
- interval: parseBounded(values.interval ?? String(MONITOR_INTERVAL), "interval", MAX_MONITOR_INTERVAL, MIN_MONITOR_INTERVAL),
56
+ interval,
57
+ since: values.since === undefined ? interval : parseBounded(values.since, "since", MAX_MONITOR_SINCE, 1),
51
58
  maxFill: maxFills(values["max-fill"] ?? [], remote.url),
52
59
  maxFills: values["max-fills"] === undefined ? null : parseBounded(values["max-fills"], "max-fills", MAX_MONITOR_FILLS),
53
60
  webhook: values.webhook ?? null,
@@ -1 +1 @@
1
- {"version":3,"file":"monitor-args.js","sourceRoot":"","sources":["../../src/monitor-args.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"monitor-args.js","sourceRoot":"","sources":["../../src/monitor-args.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,6 @@ export type SeenFill = {
8
8
  };
9
9
  export declare function fillsIn(transactions: readonly EngineTransaction[]): {
10
10
  fills: SeenFill[];
11
- created: Map<Address, Address>;
11
+ known: Map<Address, Address>;
12
12
  };
13
- export declare function inputMintsOf(transport: Transport, fills: readonly SeenFill[], created: ReadonlyMap<Address, Address>): Promise<Map<Address, Address>>;
13
+ export declare function inputMintsOf(transport: Transport, fills: readonly SeenFill[], known: ReadonlyMap<Address, Address>): Promise<Map<Address, Address>>;
@@ -2,7 +2,7 @@ import { decodeEvent, getIntentDecoder, INTENT_ENGINE_PROGRAM_ADDRESS } from "@i
2
2
  const PAID_IN_ONE_STEP = new Set(["IntentFilled", "IntentAttested", "IntentSplit"]);
3
3
  export function fillsIn(transactions) {
4
4
  const fills = [];
5
- const created = new Map();
5
+ const known = new Map();
6
6
  for (const tx of transactions) {
7
7
  if (tx.failed) {
8
8
  continue;
@@ -15,7 +15,7 @@ export function fillsIn(transactions) {
15
15
  const fields = event.fields;
16
16
  const intent = fields["intent"];
17
17
  if (event.name === "IntentCreated") {
18
- created.set(intent, fields["inputMint"]);
18
+ known.set(intent, fields["inputMint"]);
19
19
  }
20
20
  if (event.name === "FillBegun") {
21
21
  begun.set(intent, fields["amountIn"]);
@@ -27,13 +27,17 @@ export function fillsIn(transactions) {
27
27
  : undefined;
28
28
  if (amountIn !== undefined) {
29
29
  fills.push({ signature: tx.signature, slot: tx.slot, intent, amountIn: amountIn ?? 0n });
30
+ const vault = tx.tokens?.find((held) => held.owner === intent);
31
+ if (vault !== undefined && !known.has(intent)) {
32
+ known.set(intent, vault.mint);
33
+ }
30
34
  }
31
35
  }
32
36
  }
33
- return { fills, created };
37
+ return { fills, known };
34
38
  }
35
- export async function inputMintsOf(transport, fills, created) {
36
- const mints = new Map(created);
39
+ export async function inputMintsOf(transport, fills, known) {
40
+ const mints = new Map(known);
37
41
  const unknown = [...new Set(fills.map((f) => f.intent).filter((intent) => !mints.has(intent)))];
38
42
  if (unknown.length === 0) {
39
43
  return mints;
@@ -1 +1 @@
1
- {"version":3,"file":"monitor-fills.js","sourceRoot":"","sources":["../../src/monitor-fills.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"monitor-fills.js","sourceRoot":"","sources":["../../src/monitor-fills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { type Config } from "@intent-engine/core";
2
+ import type { EngineAccountFilter, Transport } from "@intent-engine/client";
3
+ export declare const CAP_LIMITS: readonly ["maxPerOrder", "windowCap", "windowSecs", "totalLimit"];
4
+ type CapLimit = (typeof CAP_LIMITS)[number];
5
+ export type CapLimits = Record<CapLimit, string | number>;
6
+ export type Floors = Record<string, string>;
7
+ export type MintCaps = Record<string, CapLimits>;
8
+ export declare const MINT_CAP_FILTER: EngineAccountFilter;
9
+ export declare const NO_FLOOR = "0";
10
+ export declare const CANNOT_LIST = "this connection cannot list program accounts, so the monitor cannot read every mint cap";
11
+ export declare function floorsOf(config: Pick<Config, "floorMints" | "floorAmounts">): Floors;
12
+ export declare function mintCapsOf(transport: Transport): Promise<MintCaps>;
13
+ export declare function isFloors(v: unknown): v is Floors;
14
+ export declare function isMintCaps(v: unknown): v is MintCaps;
15
+ export type LimitChange = {
16
+ key: string;
17
+ kind: "committee-floor" | "mint-cap-limit";
18
+ field: string;
19
+ mint: string;
20
+ expected: unknown;
21
+ observed: unknown;
22
+ };
23
+ export declare function floorChanges(baseline: Floors, now: Floors): LimitChange[];
24
+ export declare function capChanges(baseline: MintCaps, now: MintCaps, missing: string): LimitChange[];
25
+ export {};
@@ -0,0 +1,58 @@
1
+ import { committeeFloors, decodeMintCapData, getMintCapSize, isMintCapData, MINT_CAP_DISCRIMINATOR, } from "@intent-engine/core";
2
+ export const CAP_LIMITS = ["maxPerOrder", "windowCap", "windowSecs", "totalLimit"];
3
+ export const MINT_CAP_FILTER = { discriminator: MINT_CAP_DISCRIMINATOR, dataSize: getMintCapSize() };
4
+ export const NO_FLOOR = "0";
5
+ export const CANNOT_LIST = "this connection cannot list program accounts, so the monitor cannot read every mint cap";
6
+ const sortedKeys = (record) => Object.fromEntries(Object.entries(record).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)));
7
+ export function floorsOf(config) {
8
+ return sortedKeys(Object.fromEntries(committeeFloors(config).map(({ mint, floor }) => [mint, floor.toString()])));
9
+ }
10
+ export async function mintCapsOf(transport) {
11
+ if (transport.engineAccounts === undefined) {
12
+ throw new Error(CANNOT_LIST);
13
+ }
14
+ const caps = {};
15
+ for (const account of await transport.engineAccounts(MINT_CAP_FILTER)) {
16
+ if (!isMintCapData(account.data)) {
17
+ continue;
18
+ }
19
+ const cap = decodeMintCapData(account.data);
20
+ caps[cap.mint] = {
21
+ maxPerOrder: cap.maxPerOrder.toString(),
22
+ windowCap: cap.windowCap.toString(),
23
+ windowSecs: cap.windowSecs,
24
+ totalLimit: cap.totalLimit.toString(),
25
+ };
26
+ }
27
+ return sortedKeys(caps);
28
+ }
29
+ const ADDRESS = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
30
+ const RAW = /^\d+$/;
31
+ const isRecord = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
32
+ export function isFloors(v) {
33
+ return isRecord(v) && Object.entries(v).every(([mint, floor]) => ADDRESS.test(mint) && typeof floor === "string" && RAW.test(floor));
34
+ }
35
+ export function isMintCaps(v) {
36
+ return (isRecord(v) &&
37
+ Object.entries(v).every(([mint, cap]) => ADDRESS.test(mint) &&
38
+ isRecord(cap) &&
39
+ Object.keys(cap).length === CAP_LIMITS.length &&
40
+ CAP_LIMITS.every((field) => (field === "windowSecs" ? Number.isInteger(cap[field]) : typeof cap[field] === "string" && RAW.test(cap[field])))));
41
+ }
42
+ export function floorChanges(baseline, now) {
43
+ const mints = Object.keys(sortedKeys({ ...baseline, ...now }));
44
+ return mints.flatMap((mint) => {
45
+ const expected = baseline[mint] ?? NO_FLOOR;
46
+ const observed = now[mint] ?? NO_FLOOR;
47
+ return expected === observed ? [] : [{ key: `committeeFloor.${mint}`, kind: "committee-floor", field: "floor", mint, expected, observed }];
48
+ });
49
+ }
50
+ export function capChanges(baseline, now, missing) {
51
+ const mints = Object.keys(sortedKeys({ ...baseline, ...now }));
52
+ return mints.flatMap((mint) => CAP_LIMITS.flatMap((field) => {
53
+ const expected = baseline[mint]?.[field] ?? missing;
54
+ const observed = now[mint]?.[field] ?? missing;
55
+ return expected === observed ? [] : [{ key: `mintCapLimit.${mint}.${field}`, kind: "mint-cap-limit", field, mint, expected, observed }];
56
+ }));
57
+ }
58
+ //# sourceMappingURL=monitor-limits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor-limits.js","sourceRoot":"","sources":["../../src/monitor-limits.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { type Address } from "@solana/kit";
2
2
  import { type Transport } from "@intent-engine/client";
3
3
  import type { MonitorSpec } from "./command-types.js";
4
+ import { type Floors, type MintCaps } from "./monitor-limits.js";
4
5
  import type { Runtime } from "./runtime.js";
5
6
  export declare const LOADER: Address;
6
7
  export declare const PROGRAM_DATA_HEADER = 45;
@@ -13,16 +14,20 @@ type ConfigValues = Record<ConfigField, Value>;
13
14
  export type Baseline = {
14
15
  program: Address;
15
16
  config: ConfigValues;
17
+ committeeFloors: Floors;
18
+ mintCaps: MintCaps;
16
19
  upgradeAuthority: string;
17
20
  programHash: string;
18
21
  };
19
22
  export type Snapshot = {
20
23
  slot: bigint;
21
24
  config: ConfigValues | null;
25
+ committeeFloors: Floors | null;
26
+ mintCaps: MintCaps;
22
27
  upgradeAuthority: string | null;
23
28
  programHash: string | null;
24
29
  };
25
- export type AlertKind = "config" | "upgrade-authority" | "program-hash" | "fill-amount" | "fill-rate" | "rpc";
30
+ export type AlertKind = "config" | "upgrade-authority" | "program-hash" | "fill-amount" | "fill-rate" | "mint-cap" | "committee-floor" | "mint-cap-limit" | "rpc";
26
31
  export type Alert = {
27
32
  kind: AlertKind;
28
33
  field: string;
@@ -53,6 +58,10 @@ export type MonitorState = {
53
58
  seen: Set<string> | null;
54
59
  };
55
60
  export declare const freshState: () => MonitorState;
61
+ export declare function capStatus(mint: Address, cap: {
62
+ outstanding: bigint;
63
+ totalLimit: bigint;
64
+ } | null): string;
56
65
  export declare function checkOnce(transport: Transport, baseline: Baseline, spec: MonitorSpec, state: MonitorState, now: bigint, url: string): Promise<Alert[]>;
57
66
  export declare const line: (alert: Alert) => string;
58
67
  export declare function monitor(url: string, file: string, spec: MonitorSpec, runtime: Runtime, transport: Transport, io: Io): Promise<number>;
@@ -1,9 +1,10 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { getAddressDecoder } from "@solana/kit";
3
3
  import { findConfigPda, findProgramDataAddress, getConfigDecoder, getConfigDiscriminatorBytes, INTENT_ENGINE_PROGRAM_ADDRESS, } from "@intent-engine/core";
4
- import { CLOCK_SYSVAR } from "@intent-engine/client";
4
+ import { CLOCK_SYSVAR, loadMintCap } from "@intent-engine/client";
5
5
  import { UsageError } from "./arg-values.js";
6
6
  import { fillsIn, inputMintsOf } from "./monitor-fills.js";
7
+ import { capChanges, floorChanges, floorsOf, isFloors, isMintCaps, mintCapsOf } from "./monitor-limits.js";
7
8
  import { printableLines, redactUrl, render } from "./render.js";
8
9
  export const LOADER = "BPFLoaderUpgradeab1e11111111111111111111111";
9
10
  export const PROGRAM_DATA_HEADER = 45;
@@ -33,36 +34,38 @@ export const baselineExists = (file) => `${file} already exists; --write-baselin
33
34
  export const notABaseline = (file) => `--expect ${file} is not a monitor baseline; write one with monitor --write-baseline <file>`;
34
35
  export const otherProgram = (file, program) => `--expect ${file} is a baseline for program ${program}, not ${INTENT_ENGINE_PROGRAM_ADDRESS}; write a new one with monitor --write-baseline <file>`;
35
36
  const sameBytes = (a, b) => a.length === b.length && Array.from(a).every((x, i) => x === b[i]);
36
- function configValues(view) {
37
+ function decodedConfig(view) {
37
38
  const discriminator = getConfigDiscriminatorBytes();
38
39
  if (view === null || view === undefined || view.owner !== INTENT_ENGINE_PROGRAM_ADDRESS || !sameBytes(view.data.subarray(0, discriminator.length), discriminator)) {
39
40
  return null;
40
41
  }
41
42
  try {
42
- const c = getConfigDecoder().decode(view.data);
43
- return {
44
- admin: c.admin,
45
- pendingAdmin: c.pendingAdmin,
46
- guardian: c.guardian,
47
- feeRecipient: c.feeRecipient,
48
- feeBps: c.feeBps,
49
- kindFeeMask: c.kindFeeMask,
50
- kindFeeBps: [...c.kindFeeBps],
51
- partnerCutBps: c.partnerCutBps,
52
- crankBounty: c.crankBounty,
53
- createFee: c.createFee,
54
- enabledKinds: c.enabledKinds.toString(),
55
- fillDisabledKinds: c.fillDisabledKinds.toString(),
56
- paused: c.paused,
57
- capsRequired: c.capsRequired,
58
- version: c.version,
59
- domain: [...c.domain],
60
- };
43
+ return getConfigDecoder().decode(view.data);
61
44
  }
62
45
  catch {
63
46
  return null;
64
47
  }
65
48
  }
49
+ function configValues(c) {
50
+ return {
51
+ admin: c.admin,
52
+ pendingAdmin: c.pendingAdmin,
53
+ guardian: c.guardian,
54
+ feeRecipient: c.feeRecipient,
55
+ feeBps: c.feeBps,
56
+ kindFeeMask: c.kindFeeMask,
57
+ kindFeeBps: [...c.kindFeeBps],
58
+ partnerCutBps: c.partnerCutBps,
59
+ crankBounty: c.crankBounty,
60
+ createFee: c.createFee,
61
+ enabledKinds: c.enabledKinds.toString(),
62
+ fillDisabledKinds: c.fillDisabledKinds.toString(),
63
+ paused: c.paused,
64
+ capsRequired: c.capsRequired,
65
+ version: c.version,
66
+ domain: [...c.domain],
67
+ };
68
+ }
66
69
  export function executableHash(data) {
67
70
  let end = data.length;
68
71
  while (end > PROGRAM_DATA_HEADER && data[end - 1] === 0) {
@@ -92,13 +95,27 @@ export async function snapshot(transport) {
92
95
  throw new Error("the node returned no clock, so it cannot say which slot it has reached");
93
96
  }
94
97
  const slot = new DataView(clock.data.buffer, clock.data.byteOffset, clock.data.byteLength).getBigUint64(0, true);
95
- return { slot, config: configValues(config), ...programState(program, data, programData) };
98
+ const decoded = decodedConfig(config);
99
+ return {
100
+ slot,
101
+ config: decoded === null ? null : configValues(decoded),
102
+ committeeFloors: decoded === null ? null : floorsOf(decoded),
103
+ mintCaps: await mintCapsOf(transport),
104
+ ...programState(program, data, programData),
105
+ };
96
106
  }
97
107
  export function baselineOf(now) {
98
- if (now.config === null || now.upgradeAuthority === null || now.programHash === null) {
108
+ if (now.config === null || now.committeeFloors === null || now.upgradeAuthority === null || now.programHash === null) {
99
109
  throw new Error(`cannot write a baseline: the config or the upgradeable program ${INTENT_ENGINE_PROGRAM_ADDRESS} is missing on this cluster`);
100
110
  }
101
- return { program: INTENT_ENGINE_PROGRAM_ADDRESS, config: now.config, upgradeAuthority: now.upgradeAuthority, programHash: now.programHash };
111
+ return {
112
+ program: INTENT_ENGINE_PROGRAM_ADDRESS,
113
+ config: now.config,
114
+ committeeFloors: now.committeeFloors,
115
+ mintCaps: now.mintCaps,
116
+ upgradeAuthority: now.upgradeAuthority,
117
+ programHash: now.programHash,
118
+ };
102
119
  }
103
120
  const isValue = (v) => typeof v === "string" || (typeof v === "number" && Number.isInteger(v)) || (Array.isArray(v) && v.every((x) => Number.isInteger(x)));
104
121
  export function parseBaseline(text, file) {
@@ -120,7 +137,9 @@ export function parseBaseline(text, file) {
120
137
  config === null ||
121
138
  typeof config !== "object" ||
122
139
  Object.keys(config).length !== CONFIG_FIELDS.length ||
123
- !CONFIG_FIELDS.every((field) => isValue(config[field]))) {
140
+ !CONFIG_FIELDS.every((field) => isValue(config[field])) ||
141
+ !isFloors(b.committeeFloors) ||
142
+ !isMintCaps(b.mintCaps)) {
124
143
  throw new UsageError(notABaseline(file));
125
144
  }
126
145
  if (b.program !== INTENT_ENGINE_PROGRAM_ADDRESS) {
@@ -149,6 +168,26 @@ export async function readBaseline(file, runtime) {
149
168
  }
150
169
  const same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
151
170
  export const freshState = () => ({ alerted: new Map(), lastSlot: null, stalledFor: 0, failing: false, seen: null });
171
+ export function capStatus(mint, cap) {
172
+ if (cap === null) {
173
+ return `${mint} has no mint cap`;
174
+ }
175
+ const limit = cap.totalLimit === 0n ? "no total limit" : `a total limit of ${cap.totalLimit}`;
176
+ return `mint cap of ${mint}: ${cap.outstanding} raw units outstanding, ${limit}`;
177
+ }
178
+ async function capFindings(transport, spec, slot) {
179
+ const found = [];
180
+ for (const mint of spec.maxFill.keys()) {
181
+ const cap = (await loadMintCap(transport, mint))?.cap;
182
+ if (cap !== undefined && cap.totalLimit > 0n && cap.outstanding >= cap.totalLimit) {
183
+ found.push({
184
+ key: `mintCap.${mint}`,
185
+ alert: { kind: "mint-cap", field: mint, expected: `below ${cap.totalLimit}`, observed: cap.outstanding.toString(), slot: Number(slot) },
186
+ });
187
+ }
188
+ }
189
+ return found;
190
+ }
152
191
  function differences(baseline, now) {
153
192
  const slot = Number(now.slot);
154
193
  const found = [];
@@ -165,12 +204,15 @@ function differences(baseline, now) {
165
204
  compare(`config.${field}`, "config", field, baseline.config[field], now.config[field]);
166
205
  }
167
206
  }
207
+ const limits = [...(now.committeeFloors === null ? [] : floorChanges(baseline.committeeFloors, now.committeeFloors)), ...capChanges(baseline.mintCaps, now.mintCaps, MISSING)];
208
+ for (const { key, kind, field, mint, expected, observed } of limits) {
209
+ found.push({ key, alert: { kind, field, expected, observed, slot, mint } });
210
+ }
168
211
  compare("upgradeAuthority", "upgrade-authority", "upgradeAuthority", baseline.upgradeAuthority, now.upgradeAuthority ?? MISSING);
169
212
  compare("programHash", "program-hash", "programHash", baseline.programHash, now.programHash ?? MISSING);
170
213
  return found;
171
214
  }
172
- function stateAlerts(baseline, now, state) {
173
- const found = differences(baseline, now);
215
+ function stateAlerts(found, state) {
174
216
  const keys = new Set(found.map((f) => f.key));
175
217
  for (const key of [...state.alerted.keys()]) {
176
218
  if (!keys.has(key)) {
@@ -209,10 +251,10 @@ async function fillAlerts(transport, spec, state, since) {
209
251
  const seen = state.seen;
210
252
  const fresh = fetched.filter((tx) => (seen === null ? tx.blockTime !== null && tx.blockTime >= since : !seen.has(tx.signature)));
211
253
  state.seen = new Set([...(seen ?? []), ...fetched.map((tx) => tx.signature)].slice(-limit * 4));
212
- const { fills, created } = fillsIn(fresh);
254
+ const { fills, known } = fillsIn(fresh);
213
255
  const alerts = [];
214
256
  if (spec.maxFill.size > 0 && fills.length > 0) {
215
- const mints = await inputMintsOf(transport, fills, created);
257
+ const mints = await inputMintsOf(transport, fills, known);
216
258
  for (const fill of fills) {
217
259
  const mint = mints.get(fill.intent);
218
260
  const cap = mint === undefined ? undefined : spec.maxFill.get(mint);
@@ -246,9 +288,9 @@ export async function checkOnce(transport, baseline, spec, state, now, url) {
246
288
  try {
247
289
  const current = await snapshot(transport);
248
290
  alerts = [
249
- ...stateAlerts(baseline, current, state),
291
+ ...stateAlerts([...differences(baseline, current), ...(await capFindings(transport, spec, current.slot))], state),
250
292
  ...slotAlerts(current, state),
251
- ...(await fillAlerts(transport, spec, state, now - BigInt(spec.interval))),
293
+ ...(await fillAlerts(transport, spec, state, now - BigInt(spec.since))),
252
294
  ];
253
295
  }
254
296
  catch (error) {
@@ -282,6 +324,14 @@ export async function monitor(url, file, spec, runtime, transport, io) {
282
324
  const state = freshState();
283
325
  io.err(`watching program ${INTENT_ENGINE_PROGRAM_ADDRESS} on ${redactUrl(url)} every ${spec.interval}s` +
284
326
  (spec.webhook === null ? "" : `; alerts also go to ${redactUrl(spec.webhook)}`));
327
+ for (const mint of spec.maxFill.keys()) {
328
+ try {
329
+ io.err(capStatus(mint, (await loadMintCap(transport, mint))?.cap ?? null));
330
+ }
331
+ catch (error) {
332
+ io.err(`the mint cap of ${mint} cannot be read: ${scrubbed(error instanceof Error ? error.message : String(error), url)}`);
333
+ }
334
+ }
285
335
  let raised = 0;
286
336
  for (;;) {
287
337
  for (const alert of await checkOnce(transport, baseline, spec, state, runtime.now(), url)) {