@stasho/vf-records 0.2.0 → 0.2.2
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/README.md +8 -0
- package/dist/client-check.js +15 -2
- package/dist/legacy-message.js +4 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -9,5 +9,13 @@ what a prepared publish or transfer message should say and compares it
|
|
|
9
9
|
against what the signer actually asked for, before that signer's key ever
|
|
10
10
|
touches the message.
|
|
11
11
|
|
|
12
|
+
The format it checks is public: the Verified Frontends signing format page
|
|
13
|
+
(https://docs.stasho.xyz/reference/vf-signing-format.html) specifies the
|
|
14
|
+
request envelope, the prepare/submit endpoints, the transaction and every
|
|
15
|
+
check, for clients that do not want to run this package.
|
|
16
|
+
`examples/reference-client.ts` (in the repository) is a complete publish client that imports no
|
|
17
|
+
`@stasho/*` code; `tests/reference-client.test.ts` holds its check to the
|
|
18
|
+
same verdicts as `checkPreparedMessage`.
|
|
19
|
+
|
|
12
20
|
Zero runtime dependencies, no Node-only imports — safe to import from a
|
|
13
21
|
browser or from `@stasho/vf`.
|
package/dist/client-check.js
CHANGED
|
@@ -34,7 +34,15 @@ export function checkPreparedMessage(args) {
|
|
|
34
34
|
return refuse("instruction program is not the memo program");
|
|
35
35
|
if (ix.accounts.length !== 1 || ix.accounts[0] !== 1)
|
|
36
36
|
return refuse("your key must be the instruction's only account");
|
|
37
|
-
|
|
37
|
+
// Fatal + ignoreBOM: a leading BOM or an invalid byte is refused, never repaired
|
|
38
|
+
// into a string that compares equal while the on-chain bytes do not parse.
|
|
39
|
+
let payload;
|
|
40
|
+
try {
|
|
41
|
+
payload = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(ix.data);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return refuse("instruction data is not valid UTF-8");
|
|
45
|
+
}
|
|
38
46
|
const record = parsePayload(payload);
|
|
39
47
|
if (record === null)
|
|
40
48
|
return refuse("instruction data is not a stasho-vf record");
|
|
@@ -56,8 +64,13 @@ export function checkPreparedMessage(args) {
|
|
|
56
64
|
if (record.kind === "accept" && args.expected.kind === "accept" && record.transfer !== args.expected.transfer) {
|
|
57
65
|
return refuse(`accept names transfer ${record.transfer}, you asked for ${args.expected.transfer}`);
|
|
58
66
|
}
|
|
67
|
+
// `Date.parse` also accepts legacy formats and ignores parenthesised text, so
|
|
68
|
+
// only the exact `toISOString()` form the server emits is admitted: `t` must
|
|
69
|
+
// not carry anything but a time onto the customer's signed record.
|
|
59
70
|
const t = Date.parse(record.ts);
|
|
60
|
-
if (!Number.isFinite(t) ||
|
|
71
|
+
if (!Number.isFinite(t) || new Date(t).toISOString() !== record.ts)
|
|
72
|
+
return refuse("record timestamp is not an ISO 8601 UTC time");
|
|
73
|
+
if (Math.abs(t - args.now) > CLIENT_CHECK_SKEW_MS)
|
|
61
74
|
return refuse("record timestamp is more than 10 minutes from this clock");
|
|
62
75
|
return { ok: true, payload, record };
|
|
63
76
|
}
|
package/dist/legacy-message.js
CHANGED
|
@@ -16,6 +16,10 @@ class Reader {
|
|
|
16
16
|
let value = 0;
|
|
17
17
|
for (let shift = 0; shift <= 14; shift += 7) {
|
|
18
18
|
const b = this.u8();
|
|
19
|
+
// A trailing zero group re-encodes the same length (an "alias"), which
|
|
20
|
+
// Solana's own short_vec decoder refuses too.
|
|
21
|
+
if (b === 0 && shift > 0)
|
|
22
|
+
throw new RangeError("compact-u16 is not minimally encoded");
|
|
19
23
|
value |= (b & 0x7f) << shift;
|
|
20
24
|
if ((b & 0x80) === 0)
|
|
21
25
|
return value;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stasho/vf-records",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Stasho Verified Frontends record codec + the client-side check of a prepared publish message. Zero dependencies, browser-safe.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"build": "tsc -p tsconfig.build.json",
|
|
20
20
|
"typecheck": "tsc --noEmit",
|
|
21
21
|
"test": "vitest run",
|
|
22
|
-
"lint": "oxlint src tests",
|
|
22
|
+
"lint": "oxlint src tests examples",
|
|
23
23
|
"prepublishOnly": "npm run build"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|