@substrat-run/contract-tests 0.162.0 → 0.163.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.
@@ -0,0 +1,13 @@
1
+ import { type ScopeId, type TenantId } from '@substrat-run/contracts';
2
+ import type { ScopeHostFixture } from './scope-host-suite.js';
3
+ /**
4
+ * The wire-signing nonce store (RFC wire-signing §4), through each host's `claimWireNonceLocal`:
5
+ * the claim the platform's entry makes in the scope a verified envelope names, after every other
6
+ * check passed. Held alike on both adapters: a nonce is spent once per scope, and the store is the
7
+ * scope's own and no dump's, so a copy carries none and a restore empties it. The claim's own rules
8
+ * (the window, the purge, the cap) are the kernel's, tested there.
9
+ */
10
+ export declare function wireNonceContractSuite(adapterName: string, makeFixture: () => Promise<ScopeHostFixture & {
11
+ claimWireNonceLocal(tenantId: TenantId, scopeId: ScopeId, nonce: string, until: number): Promise<boolean>;
12
+ }>): void;
13
+ //# sourceMappingURL=wire-nonce-suite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire-nonce-suite.d.ts","sourceRoot":"","sources":["../src/wire-nonce-suite.ts"],"names":[],"mappings":"AACA,OAAO,EAAuD,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAE3H,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,OAAO,CACxB,gBAAgB,GAAG;IACjB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3G,CACF,GACA,IAAI,CAsEN"}
@@ -0,0 +1,73 @@
1
+ import { afterAll, beforeAll, describe, expect, it } from 'vitest';
2
+ import { platformActorId, scopeId as scopeIdSchema, tenantId } from '@substrat-run/contracts';
3
+ import { WIRE_NONCE_CAP, ulid } from '@substrat-run/kernel';
4
+ /**
5
+ * The wire-signing nonce store (RFC wire-signing §4), through each host's `claimWireNonceLocal`:
6
+ * the claim the platform's entry makes in the scope a verified envelope names, after every other
7
+ * check passed. Held alike on both adapters: a nonce is spent once per scope, and the store is the
8
+ * scope's own and no dump's, so a copy carries none and a restore empties it. The claim's own rules
9
+ * (the window, the purge, the cap) are the kernel's, tested there.
10
+ */
11
+ export function wireNonceContractSuite(adapterName, makeFixture) {
12
+ describe(`the wire nonce store (RFC wire-signing §4): ${adapterName}`, () => {
13
+ let fixture;
14
+ const staff = platformActorId.parse(ulid());
15
+ const t = tenantId.parse(ulid());
16
+ /** Far enough ahead that no run of this suite reaches it. */
17
+ const until = Math.floor(Date.now() / 1000) + 3600;
18
+ let n = 0;
19
+ /** A fresh canonical nonce: 21 base64url characters and a last one with its trailing bits zero. */
20
+ const nonce = () => `${(n++).toString(36).padStart(10, '0')}${ulid().slice(-11).toLowerCase()}A`;
21
+ /** One provisioned scope the suite shares: each test spends nonces of its own. */
22
+ const s = scopeIdSchema.parse(ulid());
23
+ beforeAll(async () => {
24
+ fixture = await makeFixture();
25
+ await fixture.host.admin.createTenant(staff, { id: t, slug: `wire-nonce-${t.slice(-8).toLowerCase()}`, name: 'Wire nonces' });
26
+ await fixture.host.provisionScope(staff, { tenantId: t, scopeId: s, vertical: 'wire-nonce' });
27
+ await fixture.host.admin.activateScope(staff, t, s);
28
+ });
29
+ afterAll(async () => fixture?.cleanup());
30
+ const claim = (s, value) => fixture.claimWireNonceLocal(t, s, value, until);
31
+ it('spends a nonce once per scope, a scope nothing has provisioned yet included', async () => {
32
+ // The call that provisions a scope spends its nonce there too, so no provisioned check.
33
+ const unprovisioned = scopeIdSchema.parse(ulid());
34
+ const a = nonce();
35
+ expect(await claim(s, a)).toBe(true);
36
+ expect(await claim(unprovisioned, a)).toBe(true);
37
+ expect(await claim(s, a)).toBe(false);
38
+ expect(await claim(unprovisioned, a)).toBe(false);
39
+ });
40
+ // That the dump leaves the tables out is the shared host suite's export check.
41
+ it('a copy and a restore start with no nonce spent', async () => {
42
+ const a = nonce();
43
+ expect(await claim(s, a)).toBe(true);
44
+ const dump = await fixture.host.admin.exportScope(staff, t, s);
45
+ // A copy of the scope starts with none spent…
46
+ const fork = scopeIdSchema.parse(ulid());
47
+ await fixture.host.importScope(staff, { tenantId: t, scopeId: fork, vertical: 'wire-nonce' }, dump);
48
+ expect(await claim(fork, a)).toBe(true);
49
+ // …and so does the scope itself once a restore has replaced its store (RFC §4: why the window is short).
50
+ expect(await claim(s, a)).toBe(false);
51
+ await fixture.host.restoreScope(staff, t, s, dump);
52
+ expect(await claim(s, a)).toBe(true);
53
+ });
54
+ it('a dump that does carry the nonce tables (a full count, spent nonces) loads without them', async () => {
55
+ const spent = nonce();
56
+ const dump = await fixture.host.admin.exportScope(staff, t, s);
57
+ dump.tables.push({
58
+ name: '_substrat_wire_nonce_count',
59
+ ddl: 'CREATE TABLE _substrat_wire_nonce_count (slot TEXT PRIMARY KEY, live INTEGER NOT NULL) WITHOUT ROWID',
60
+ columns: ['slot', 'live'],
61
+ rows: [['live', WIRE_NONCE_CAP]],
62
+ }, {
63
+ name: '_substrat_wire_nonces',
64
+ ddl: 'CREATE TABLE _substrat_wire_nonces (nonce TEXT PRIMARY KEY, until_s INTEGER NOT NULL) WITHOUT ROWID',
65
+ columns: ['nonce', 'until_s'],
66
+ rows: [[spent, until]],
67
+ });
68
+ await fixture.host.restoreScope(staff, t, s, dump);
69
+ expect(await claim(s, spent)).toBe(true);
70
+ });
71
+ });
72
+ }
73
+ //# sourceMappingURL=wire-nonce-suite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire-nonce-suite.js","sourceRoot":"","sources":["../src/wire-nonce-suite.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@substrat-run/contract-tests",
3
- "version": "0.162.0",
3
+ "version": "0.163.0",
4
4
  "description": "The suite every scope-host adapter must pass, forever (D-14)",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {
@@ -30,8 +30,8 @@
30
30
  "dist"
31
31
  ],
32
32
  "dependencies": {
33
- "@substrat-run/contracts": "^0.162.0",
34
- "@substrat-run/kernel": "^0.162.0"
33
+ "@substrat-run/contracts": "^0.163.0",
34
+ "@substrat-run/kernel": "^0.163.0"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/node": "^22.20.5",