sememe 0.0.0-stage → 0.4.21
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/LICENSE +21 -0
- package/README.md +2667 -2
- package/bin/sememe.mjs +556 -0
- package/index.mjs +48 -0
- package/interface/ata-ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL.json +62 -0
- package/interface/native-11111111111111111111111111111111.json +226 -0
- package/interface/native-ComputeBudget111111111111111111111111111111.json +72 -0
- package/interface/raydium-675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8.json +352 -0
- package/interface/token-TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA.json +334 -0
- package/interface/token-TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb.json +535 -0
- package/interface/token-metadata.json +132 -0
- package/package.json +71 -4
- package/src/account-list.mjs +308 -0
- package/src/account-union.mjs +523 -0
- package/src/account.mjs +199 -0
- package/src/acquire.mjs +145 -0
- package/src/adopt.mjs +205 -0
- package/src/ata-interface.mjs +276 -0
- package/src/ata.mjs +223 -0
- package/src/base58.mjs +96 -0
- package/src/canonical.mjs +24 -0
- package/src/cli-surface.mjs +300 -0
- package/src/codec.mjs +1069 -0
- package/src/conformance.mjs +431 -0
- package/src/corpus/harvest-compute-budget-2026-10-31.json +19122 -0
- package/src/corpus/harvest-system-2026-10-31.json +26090 -0
- package/src/decode.mjs +286 -0
- package/src/dialect.mjs +145 -0
- package/src/discriminators.mjs +177 -0
- package/src/drift.mjs +172 -0
- package/src/gap.mjs +205 -0
- package/src/lighthouse.mjs +168 -0
- package/src/lock.mjs +440 -0
- package/src/native-audit.mjs +56 -0
- package/src/native-corpus.mjs +57 -0
- package/src/native-interface.mjs +252 -0
- package/src/native.mjs +324 -0
- package/src/peer.mjs +95 -0
- package/src/program-id.mjs +74 -0
- package/src/pull.mjs +117 -0
- package/src/rawle.mjs +450 -0
- package/src/raydium-interface.mjs +747 -0
- package/src/raydium.mjs +391 -0
- package/src/receipt-digest.mjs +84 -0
- package/src/receipt-name.mjs +128 -0
- package/src/receipt-order.mjs +56 -0
- package/src/shank.mjs +73 -0
- package/src/short-forms.mjs +209 -0
- package/src/store-read.mjs +250 -0
- package/src/store-write.mjs +46 -0
- package/src/token-interface.mjs +394 -0
- package/src/token-metadata-interface.mjs +371 -0
- package/src/token-metadata.mjs +317 -0
- package/src/token.mjs +443 -0
- package/src/union.mjs +428 -0
- package/vendor/anza-solana-sdk/8db406e2edfafa25939ec782b77b5b6f30de164d/LICENSE.txt +201 -0
- package/vendor/anza-solana-sdk/8db406e2edfafa25939ec782b77b5b6f30de164d/compute-budget-interface/src/lib.rs +93 -0
- package/vendor/anza-solana-sdk/8db406e2edfafa25939ec782b77b5b6f30de164d/system-interface/src/instruction.rs +1899 -0
- package/vendor/lighthouse/4c579479c98635e419b1b167f08be02a71604a71/LICENSE +21 -0
- package/vendor/lighthouse/4c579479c98635e419b1b167f08be02a71604a71/lighthouse.json +2769 -0
- package/vendor/raydium-amm/91739d8d9f5cf347e0ce14ebe4d2bb7069fb31b6/LICENSE +201 -0
- package/vendor/raydium-amm/91739d8d9f5cf347e0ce14ebe4d2bb7069fb31b6/program/src/instruction.rs +1189 -0
- package/vendor/raydium-amm/91739d8d9f5cf347e0ce14ebe4d2bb7069fb31b6/program/src/state.rs +1348 -0
- package/vendor/spl-associated-token-account/fbf5379e7398ac8b231c73ee8a9ff677b43dd0ec/LICENSE +201 -0
- package/vendor/spl-associated-token-account/fbf5379e7398ac8b231c73ee8a9ff677b43dd0ec/interface/src/instruction.rs +169 -0
- package/vendor/spl-associated-token-account/fbf5379e7398ac8b231c73ee8a9ff677b43dd0ec/interface/src/lib.rs +12 -0
- package/vendor/spl-associated-token-account/fbf5379e7398ac8b231c73ee8a9ff677b43dd0ec/program/src/processor.rs +308 -0
- package/vendor/spl-token/737788ff5bcc3f1f44cfb222f25483187650be76/LICENSE.txt +176 -0
- package/vendor/spl-token/737788ff5bcc3f1f44cfb222f25483187650be76/interface/src/instruction.rs +1963 -0
- package/vendor/spl-token-2022/5251dcc07ecbcb721d6c4f0231090defadf00311/LICENSE.txt +176 -0
- package/vendor/spl-token-2022/5251dcc07ecbcb721d6c4f0231090defadf00311/interface/src/instruction.rs +2868 -0
- package/vendor/spl-token-metadata-interface/7038969ec74a89f1afdb9bc97c112d4d26fead9a/LICENSE +201 -0
- package/vendor/spl-token-metadata-interface/7038969ec74a89f1afdb9bc97c112d4d26fead9a/interface/src/error.rs +58 -0
- package/vendor/spl-token-metadata-interface/7038969ec74a89f1afdb9bc97c112d4d26fead9a/interface/src/instruction.rs +596 -0
- package/vendor/spl-token-metadata-interface/7038969ec74a89f1afdb9bc97c112d4d26fead9a/interface/src/lib.rs +21 -0
- package/vendor/spl-token-metadata-interface/7038969ec74a89f1afdb9bc97c112d4d26fead9a/interface/src/state.rs +229 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
// The CLI's DECLARED surface: which flags each command accepts and how many
|
|
2
|
+
// positional arguments it consumes.
|
|
3
|
+
//
|
|
4
|
+
// Why this file exists (measured 2026-11-06, on the working tree at 641b895):
|
|
5
|
+
//
|
|
6
|
+
// The CLI parsed flags by SEARCHING the argument list for a name and taking
|
|
7
|
+
// whatever came next. A flag the command does not know was therefore not an
|
|
8
|
+
// error — it was silently discarded, and so was every extra positional
|
|
9
|
+
// argument. The consequences were measured on the real CLI:
|
|
10
|
+
//
|
|
11
|
+
// sememe lock --store <valid> --o out.lock
|
|
12
|
+
// -> exit 0, a lock written to ./sememe.lock, NOT to out.lock.
|
|
13
|
+
// The caller asked for a file at one path and got a file at another,
|
|
14
|
+
// with a success exit code.
|
|
15
|
+
// sememe decode <prog> <payload> --stro ./store
|
|
16
|
+
// -> exit 1, "no sememe store at /home/<user>/.sememe": the typo'd
|
|
17
|
+
// --store was dropped and the DEFAULT store was used instead.
|
|
18
|
+
// sememe verify --store <valid> --lock <valid> --mod warn
|
|
19
|
+
// -> --mod dropped; verify ran in its default error mode.
|
|
20
|
+
// sememe native-provenance --store <dir>
|
|
21
|
+
// -> "--store is not a native program sememe pins": the flag's VALUE was
|
|
22
|
+
// read as the program id.
|
|
23
|
+
// sememe decode --store <valid> <prog> <payload>
|
|
24
|
+
// -> "no sememe store at /home/<user>/.sememe": with a flag in the
|
|
25
|
+
// program slot, the STORE PATH was read as the payload and the
|
|
26
|
+
// program id as the store.
|
|
27
|
+
// sememe pull <prog> --stor <dir>
|
|
28
|
+
// -> the typo was dropped and the pull RAN against the default store:
|
|
29
|
+
// a write the caller never asked for.
|
|
30
|
+
// sememe decode <prog> <payload> --store A --store B
|
|
31
|
+
// -> A was used, B was silently ignored.
|
|
32
|
+
//
|
|
33
|
+
// A parser error here is a silent change of WHAT gets read, signed, pinned or
|
|
34
|
+
// written. The rule this file implements is the one the repository already
|
|
35
|
+
// applies to stores, receipts and locks: an unrecognized input is REFUSED BY
|
|
36
|
+
// NAME, never tolerated.
|
|
37
|
+
//
|
|
38
|
+
// Two deliberate properties:
|
|
39
|
+
//
|
|
40
|
+
// - The check runs BEFORE any command does work. No store is read, no file
|
|
41
|
+
// is written, no RPC is contacted, no key is touched. A refusal must not
|
|
42
|
+
// have a side effect.
|
|
43
|
+
// - The refusal NAMES THE REPAIR: the offending flag, the closest supported
|
|
44
|
+
// flag (measured by edit distance), and the full supported list. "unknown
|
|
45
|
+
// flag" alone is a verdict, not a repair.
|
|
46
|
+
//
|
|
47
|
+
// The table is DATA, not code paths, so it can be read and pinned. The CLI
|
|
48
|
+
// dispatch reads it; nothing else may add a flag to a command without adding
|
|
49
|
+
// it here, which is exactly the drift this file exists to make visible.
|
|
50
|
+
|
|
51
|
+
/** A refusal about the SHAPE of the invocation, not about what it produced. */
|
|
52
|
+
export class UsageError extends Error {
|
|
53
|
+
constructor(message) {
|
|
54
|
+
super(message);
|
|
55
|
+
this.name = 'UsageError';
|
|
56
|
+
this.code = 'usage';
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The per-command surface.
|
|
62
|
+
*
|
|
63
|
+
* flags the flags the command accepts; 'value' takes the next token,
|
|
64
|
+
* 'boolean' stands alone
|
|
65
|
+
* positionals how many positional arguments the command consumes, either a
|
|
66
|
+
* fixed count or [min, max] for an optional one
|
|
67
|
+
* positionalNames the names used in the refusal message
|
|
68
|
+
* extraMessage a command-specific refusal for a surplus positional argument
|
|
69
|
+
* (lock/verify have their own wording, and it has been the
|
|
70
|
+
* product's wording since the lock shipped)
|
|
71
|
+
*/
|
|
72
|
+
export const COMMAND_SPECS = {
|
|
73
|
+
'absent-help': { flags: {}, positionals: 0 },
|
|
74
|
+
pull: {
|
|
75
|
+
flags: { '--store': 'value', '--rpc': 'value' },
|
|
76
|
+
positionals: 1,
|
|
77
|
+
positionalNames: ['program id'],
|
|
78
|
+
},
|
|
79
|
+
gap: {
|
|
80
|
+
flags: { '--rpc': 'value' },
|
|
81
|
+
positionals: 1,
|
|
82
|
+
positionalNames: ['program id'],
|
|
83
|
+
},
|
|
84
|
+
lock: {
|
|
85
|
+
flags: { '--store': 'value', '--out': 'value' },
|
|
86
|
+
positionals: 0,
|
|
87
|
+
extraMessage: (extras) => `lock takes no program id — it snapshots the whole store; got "${extras[0]}"`,
|
|
88
|
+
},
|
|
89
|
+
verify: {
|
|
90
|
+
flags: { '--store': 'value', '--lock': 'value', '--mode': 'value' },
|
|
91
|
+
positionals: 0,
|
|
92
|
+
extraMessage: (extras) => `verify takes no program id — it checks the whole lock; got "${extras[0]}"`,
|
|
93
|
+
},
|
|
94
|
+
adopt: {
|
|
95
|
+
flags: { '--store': 'value', '--source': 'value', '--origin': 'value' },
|
|
96
|
+
positionals: 2,
|
|
97
|
+
positionalNames: ['program id', 'interface file'],
|
|
98
|
+
},
|
|
99
|
+
'adopt-lighthouse': {
|
|
100
|
+
flags: { '--store': 'value' },
|
|
101
|
+
positionals: 0,
|
|
102
|
+
},
|
|
103
|
+
decode: {
|
|
104
|
+
flags: { '--store': 'value', '--trailing': 'value', '--absent': 'value', '--union': 'boolean' },
|
|
105
|
+
positionals: 2,
|
|
106
|
+
positionalNames: ['program id', 'payload'],
|
|
107
|
+
},
|
|
108
|
+
conform: {
|
|
109
|
+
flags: { '--store': 'value', '--only': 'value' },
|
|
110
|
+
positionals: 1,
|
|
111
|
+
positionalNames: ['transaction file'],
|
|
112
|
+
},
|
|
113
|
+
'decode-native': {
|
|
114
|
+
flags: { '--trailing': 'value' },
|
|
115
|
+
positionals: 2,
|
|
116
|
+
positionalNames: ['program id', 'payload'],
|
|
117
|
+
},
|
|
118
|
+
'native-provenance': {
|
|
119
|
+
flags: {},
|
|
120
|
+
positionals: [0, 1],
|
|
121
|
+
positionalNames: ['program id'],
|
|
122
|
+
},
|
|
123
|
+
'decode-token': {
|
|
124
|
+
flags: { '--trailing': 'value' },
|
|
125
|
+
positionals: 2,
|
|
126
|
+
positionalNames: ['program id', 'payload'],
|
|
127
|
+
},
|
|
128
|
+
'token-provenance': {
|
|
129
|
+
flags: {},
|
|
130
|
+
positionals: [0, 1],
|
|
131
|
+
positionalNames: ['program id'],
|
|
132
|
+
},
|
|
133
|
+
'raydium-provenance': {
|
|
134
|
+
flags: {},
|
|
135
|
+
positionals: [0, 1],
|
|
136
|
+
positionalNames: ['program id'],
|
|
137
|
+
},
|
|
138
|
+
'decode-raydium': {
|
|
139
|
+
flags: { '--trailing': 'value' },
|
|
140
|
+
positionals: 2,
|
|
141
|
+
positionalNames: ['program id', 'payload'],
|
|
142
|
+
},
|
|
143
|
+
'decode-ata': {
|
|
144
|
+
flags: { '--trailing': 'value', '--empty': 'boolean' },
|
|
145
|
+
positionals: [1, 2],
|
|
146
|
+
positionalNames: ['program id', 'payload'],
|
|
147
|
+
},
|
|
148
|
+
'ata-provenance': {
|
|
149
|
+
flags: {},
|
|
150
|
+
positionals: [0, 1],
|
|
151
|
+
positionalNames: ['program id'],
|
|
152
|
+
},
|
|
153
|
+
account: {
|
|
154
|
+
flags: { '--store': 'value', '--name': 'value', '--trailing': 'value', '--union': 'boolean' },
|
|
155
|
+
positionals: 2,
|
|
156
|
+
positionalNames: ['program id', 'account data'],
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
/** The command names this CLI knows, in the order the usage text lists them. */
|
|
161
|
+
export const COMMAND_NAMES = Object.keys(COMMAND_SPECS);
|
|
162
|
+
|
|
163
|
+
/** Levenshtein distance — enough to suggest a flag, not a spellchecker. */
|
|
164
|
+
export function editDistance(a, b) {
|
|
165
|
+
const s = String(a);
|
|
166
|
+
const t = String(b);
|
|
167
|
+
if (s === t) return 0;
|
|
168
|
+
if (!s.length) return t.length;
|
|
169
|
+
if (!t.length) return s.length;
|
|
170
|
+
let prev = Array.from({ length: t.length + 1 }, (_, i) => i);
|
|
171
|
+
for (let i = 1; i <= s.length; i++) {
|
|
172
|
+
const cur = [i];
|
|
173
|
+
for (let j = 1; j <= t.length; j++) {
|
|
174
|
+
const cost = s[i - 1] === t[j - 1] ? 0 : 1;
|
|
175
|
+
cur[j] = Math.min(prev[j] + 1, cur[j - 1] + 1, prev[j - 1] + cost);
|
|
176
|
+
}
|
|
177
|
+
prev = cur;
|
|
178
|
+
}
|
|
179
|
+
return prev[t.length];
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* The closest supported flag, when one is close enough to be a plausible
|
|
184
|
+
* typo. "Close enough" is measured, not guessed: within two edits, or within
|
|
185
|
+
* a quarter of the flag's own length.
|
|
186
|
+
*
|
|
187
|
+
* The quarter rule matters: the flag `--absent-help` is three edits away from
|
|
188
|
+
* the flag `--absent`, but it is not a typo of it — it is a COMMAND name with a
|
|
189
|
+
* prefix — so a distance of three must NOT produce a suggestion. Two edits is
|
|
190
|
+
* the line.
|
|
191
|
+
*/
|
|
192
|
+
export function closestFlag(flag, supported) {
|
|
193
|
+
const target = String(flag);
|
|
194
|
+
let best = null;
|
|
195
|
+
let bestDistance = Infinity;
|
|
196
|
+
for (const candidate of supported) {
|
|
197
|
+
const distance = editDistance(target, candidate);
|
|
198
|
+
if (distance < bestDistance) {
|
|
199
|
+
bestDistance = distance;
|
|
200
|
+
best = candidate;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (best === null) return null;
|
|
204
|
+
const limit = Math.max(2, Math.floor(target.length / 4));
|
|
205
|
+
return bestDistance <= limit ? best : null;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* The refusal for a flag the command does not accept.
|
|
210
|
+
*
|
|
211
|
+
* The supported list appears exactly ONCE. Measured on the published
|
|
212
|
+
* v0.4.7 install 2026-11-07 (a defect found by running the README examples
|
|
213
|
+
* verbatim against the packed tarball, not by a unit test): the first
|
|
214
|
+
* version printed the list in the no-suggestion clause AND again at the end,
|
|
215
|
+
* so `decode … --rpc` printed the same four flags twice in one line.
|
|
216
|
+
*/
|
|
217
|
+
export function unknownFlagMessage(command, flag, supported) {
|
|
218
|
+
const suggestion = closestFlag(flag, supported);
|
|
219
|
+
if (suggestion) {
|
|
220
|
+
return `sememe ${command}: unknown flag "${flag}" — did you mean "${suggestion}"? supported flags: ${supported.join(', ')}`;
|
|
221
|
+
}
|
|
222
|
+
if (!supported.length) {
|
|
223
|
+
return `sememe ${command}: unknown flag "${flag}" — this command accepts no flags`;
|
|
224
|
+
}
|
|
225
|
+
return `sememe ${command}: unknown flag "${flag}" — supported flags: ${supported.join(', ')}`;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/** The refusal for a surplus positional argument. */
|
|
229
|
+
export function extraPositionalMessage(command, extras, spec) {
|
|
230
|
+
if (typeof spec?.extraMessage === 'function') return spec.extraMessage(extras);
|
|
231
|
+
const expected = Array.isArray(spec?.positionals) ? spec.positionals[1] : spec?.positionals;
|
|
232
|
+
const names = (spec?.positionalNames ?? []).join(', ');
|
|
233
|
+
return `sememe ${command} takes ${expected} positional argument${expected === 1 ? '' : 's'}`
|
|
234
|
+
+ `${names ? ` (${names})` : ''}; got ${expected + extras.length} — extra: ${extras.map((e) => JSON.stringify(e)).join(', ')}`;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Parse one command's arguments against its spec.
|
|
239
|
+
*
|
|
240
|
+
* Returns { flags, positionals }. Throws UsageError for anything the command
|
|
241
|
+
* does not declare. The order of the checks is the point:
|
|
242
|
+
*
|
|
243
|
+
* 1. every flag is checked FIRST, before any value is consumed — so a
|
|
244
|
+
* typo'd flag is refused as a typo, not silently reinterpreted as
|
|
245
|
+
* something else;
|
|
246
|
+
* 2. a flag that needs a value but has none is refused naming the flag;
|
|
247
|
+
* 3. a flag given twice is refused: the second value would otherwise be
|
|
248
|
+
* silently dropped, and the caller would believe the LAST one won
|
|
249
|
+
* (it does not — the FIRST one wins, which is the worse surprise);
|
|
250
|
+
* 4. only then is the positional count checked.
|
|
251
|
+
*
|
|
252
|
+
* A command this CLI does not know is NOT an error here: the caller prints
|
|
253
|
+
* the usage text for it, which is the product's existing behaviour.
|
|
254
|
+
*/
|
|
255
|
+
export function parseCommandArgs(command, tokens) {
|
|
256
|
+
const spec = COMMAND_SPECS[command];
|
|
257
|
+
if (!spec) return { flags: {}, positionals: [] };
|
|
258
|
+
const supported = Object.keys(spec.flags);
|
|
259
|
+
const flags = {};
|
|
260
|
+
const positionals = [];
|
|
261
|
+
const list = Array.isArray(tokens) ? tokens : [];
|
|
262
|
+
|
|
263
|
+
for (let i = 0; i < list.length; i++) {
|
|
264
|
+
const token = list[i];
|
|
265
|
+
if (typeof token !== 'string' || !token.startsWith('--')) {
|
|
266
|
+
positionals.push(token);
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
const kind = spec.flags[token];
|
|
270
|
+
if (!kind) throw new UsageError(unknownFlagMessage(command, token, supported));
|
|
271
|
+
if (Object.prototype.hasOwnProperty.call(flags, token)) {
|
|
272
|
+
throw new UsageError(`sememe ${command}: flag "${token}" given more than once — pass it once`);
|
|
273
|
+
}
|
|
274
|
+
if (kind === 'boolean') {
|
|
275
|
+
flags[token] = true;
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
const value = list[i + 1];
|
|
279
|
+
if (value === undefined || (typeof value === 'string' && value.startsWith('--'))) {
|
|
280
|
+
throw new UsageError(`sememe ${command}: missing value for ${token}`);
|
|
281
|
+
}
|
|
282
|
+
flags[token] = value;
|
|
283
|
+
i++;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const [min, max] = Array.isArray(spec.positionals)
|
|
287
|
+
? spec.positionals
|
|
288
|
+
: [spec.positionals, spec.positionals];
|
|
289
|
+
if (positionals.length > max) {
|
|
290
|
+
throw new UsageError(extraPositionalMessage(command, positionals.slice(max), spec));
|
|
291
|
+
}
|
|
292
|
+
if (positionals.length < min) {
|
|
293
|
+
// Too FEW positionals is the command's own business: every command
|
|
294
|
+
// already refuses with its own wording ("decode needs a program id"),
|
|
295
|
+
// and that wording is pinned by other tests. Only the surplus case is
|
|
296
|
+
// decided here.
|
|
297
|
+
return { flags, positionals };
|
|
298
|
+
}
|
|
299
|
+
return { flags, positionals };
|
|
300
|
+
}
|