@receiz/sdk 94.0.0 → 96.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/README.md +53 -4
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +238 -0
- package/dist/index.d.ts +236 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +383 -6
- package/docs/cli-and-conformance.md +108 -0
- package/docs/copy-paste-integrations.md +205 -0
- package/docs/proof-memory-and-projections.md +42 -6
- package/fixtures/receiz-asset-manifest.example.json +6 -3
- package/fixtures/receiz-webhook-event.example.json +10 -1
- package/package.json +4 -1
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# Copy-Paste Integrations
|
|
2
|
+
|
|
3
|
+
These examples are intentionally small. They let a developer build with Receiz proof objects without inventing a parallel authority model.
|
|
4
|
+
|
|
5
|
+
The rule is the same in every example:
|
|
6
|
+
|
|
7
|
+
```txt
|
|
8
|
+
verify or validate carried proof truth -> project immediately -> admit into durable proof memory -> sync verified additions after knownHead
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The SDK is convenience, not authority. Proof objects, verified appends, ownership appends, settlement rows, and identity artifacts remain stronger truth.
|
|
12
|
+
|
|
13
|
+
## React Hook: `useReceizProofMemory`
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { useEffect, useMemo, useState } from "react";
|
|
17
|
+
import {
|
|
18
|
+
createReceizLocalStorageProofMemoryStorage,
|
|
19
|
+
createReceizProofMemory,
|
|
20
|
+
type ReceizProofMemory,
|
|
21
|
+
type ReceizSdkObservation,
|
|
22
|
+
} from "@receiz/sdk";
|
|
23
|
+
|
|
24
|
+
export function useReceizProofMemory(ownerId: string) {
|
|
25
|
+
const [memory, setMemory] = useState<ReceizProofMemory | null>(null);
|
|
26
|
+
const [observations, setObservations] = useState<ReceizSdkObservation[]>([]);
|
|
27
|
+
|
|
28
|
+
const storageKey = useMemo(() => `receiz:proof-memory:${ownerId}:v1`, [ownerId]);
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
let active = true;
|
|
32
|
+
|
|
33
|
+
void createReceizProofMemory({
|
|
34
|
+
ownerId,
|
|
35
|
+
storage: createReceizLocalStorageProofMemoryStorage(storageKey),
|
|
36
|
+
onObservation: (observation) => {
|
|
37
|
+
setObservations((current) => [...current.slice(-24), observation]);
|
|
38
|
+
},
|
|
39
|
+
}).then((opened) => {
|
|
40
|
+
if (active) setMemory(opened);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
return () => {
|
|
44
|
+
active = false;
|
|
45
|
+
};
|
|
46
|
+
}, [ownerId, storageKey]);
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
memory,
|
|
50
|
+
observations,
|
|
51
|
+
entries: memory?.entries() ?? [],
|
|
52
|
+
knownHead: memory?.knownHead(100) ?? null,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Use `entries` for immediate first paint. Use `knownHead` for append-only sync. Do not ask the server whether those entries are still true.
|
|
58
|
+
|
|
59
|
+
## Browser Proof Object Admission
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import {
|
|
63
|
+
assertReceizAssetManifest,
|
|
64
|
+
createReceizLocalStorageProofMemoryStorage,
|
|
65
|
+
createReceizProofMemory,
|
|
66
|
+
projectReceizAssetManifest,
|
|
67
|
+
} from "@receiz/sdk";
|
|
68
|
+
|
|
69
|
+
const memory = await createReceizProofMemory({
|
|
70
|
+
ownerId: "workspace-or-user-id",
|
|
71
|
+
storage: createReceizLocalStorageProofMemoryStorage("receiz:proof-memory:v1"),
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
export async function admitAssetManifest(value: unknown) {
|
|
75
|
+
const manifest = assertReceizAssetManifest(value);
|
|
76
|
+
const projection = projectReceizAssetManifest(manifest);
|
|
77
|
+
|
|
78
|
+
memory.admitAssetManifest(manifest);
|
|
79
|
+
await memory.flush();
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
projection,
|
|
83
|
+
knownHead: memory.knownHead(100),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
This is not cache. The persisted register is admitted proof memory.
|
|
89
|
+
|
|
90
|
+
## Next Route: Append Sync After Known Head
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
import { createReceizClient } from "@receiz/sdk";
|
|
94
|
+
|
|
95
|
+
export async function GET(request: Request) {
|
|
96
|
+
const url = new URL(request.url);
|
|
97
|
+
const afterKaiUpulse = url.searchParams.get("afterKaiUpulse");
|
|
98
|
+
const afterEntryId = url.searchParams.get("afterEntryId");
|
|
99
|
+
|
|
100
|
+
const receiz = createReceizClient({
|
|
101
|
+
accessToken: process.env.RECEIZ_CONNECT_ACCESS_TOKEN,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const ledger = await receiz.wallet.publicLedger({
|
|
105
|
+
limit: 100,
|
|
106
|
+
cursor: afterEntryId ?? undefined,
|
|
107
|
+
since: afterKaiUpulse ?? undefined,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
return Response.json({
|
|
111
|
+
ok: true,
|
|
112
|
+
additions: ledger.events,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Use this as transport. Do not let this route replace local proof memory. It only returns possible additions.
|
|
118
|
+
|
|
119
|
+
## Webhook Receiver
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import {
|
|
123
|
+
assertReceizWebhookEvent,
|
|
124
|
+
createReceizProofMemory,
|
|
125
|
+
createReceizLocalStorageProofMemoryStorage,
|
|
126
|
+
verifyReceizWebhookSignature,
|
|
127
|
+
} from "@receiz/sdk";
|
|
128
|
+
|
|
129
|
+
export async function receiveReceizWebhook(request: Request) {
|
|
130
|
+
const body = await request.text();
|
|
131
|
+
const signature = request.headers.get("x-receiz-signature") ?? "";
|
|
132
|
+
const timestamp = request.headers.get("x-receiz-timestamp") ?? "";
|
|
133
|
+
|
|
134
|
+
const ok = await verifyReceizWebhookSignature({
|
|
135
|
+
secret: process.env.RECEIZ_WEBHOOK_SECRET!,
|
|
136
|
+
timestamp,
|
|
137
|
+
signature,
|
|
138
|
+
body,
|
|
139
|
+
toleranceSeconds: 300,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
if (!ok) return new Response("invalid signature", { status: 401 });
|
|
143
|
+
|
|
144
|
+
const event = assertReceizWebhookEvent(JSON.parse(body));
|
|
145
|
+
const memory = await createReceizProofMemory({
|
|
146
|
+
ownerId: "webhook-worker",
|
|
147
|
+
storage: createReceizLocalStorageProofMemoryStorage("receiz:webhook-proof-memory:v1"),
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
memory.admitWebhookEvent(event);
|
|
151
|
+
await memory.flush();
|
|
152
|
+
|
|
153
|
+
return Response.json({
|
|
154
|
+
ok: true,
|
|
155
|
+
knownHead: memory.knownHead(100),
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Webhook signatures verify delivery. They do not become stronger than the proof bundle or append payload being admitted.
|
|
161
|
+
|
|
162
|
+
## Sports Card Renderer
|
|
163
|
+
|
|
164
|
+
This Sports card renderer keeps the proof object together while giving React developers a direct display component.
|
|
165
|
+
|
|
166
|
+
```tsx
|
|
167
|
+
import {
|
|
168
|
+
assertReceizSportsCardManifest,
|
|
169
|
+
projectReceizSportsCardManifest,
|
|
170
|
+
} from "@receiz/sdk";
|
|
171
|
+
|
|
172
|
+
export function SportsCardProof({ manifestJson }: { manifestJson: unknown }) {
|
|
173
|
+
const manifest = assertReceizSportsCardManifest(manifestJson);
|
|
174
|
+
const projection = projectReceizSportsCardManifest(manifest);
|
|
175
|
+
|
|
176
|
+
return (
|
|
177
|
+
<article>
|
|
178
|
+
<img src={projection.mediaUrl ?? ""} alt={projection.title} />
|
|
179
|
+
<h2>{projection.title}</h2>
|
|
180
|
+
<p>{projection.scoreLabel}</p>
|
|
181
|
+
<a href={projection.verifyUrl ?? manifest.links.proof}>Verify proof</a>
|
|
182
|
+
<dl>
|
|
183
|
+
{projection.rows.map((row) => (
|
|
184
|
+
<div key={row.label}>
|
|
185
|
+
<dt>{row.label}</dt>
|
|
186
|
+
<dd>{row.href ? <a href={row.href}>{row.value}</a> : row.value}</dd>
|
|
187
|
+
</div>
|
|
188
|
+
))}
|
|
189
|
+
</dl>
|
|
190
|
+
</article>
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Keep card identity, claim hash, ownership, value basis, append summary, and event proof summary together. They are one proof object projection.
|
|
196
|
+
|
|
197
|
+
## Local CLI Proof
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
npx @receiz/sdk conformance
|
|
201
|
+
npx @receiz/sdk inspect ./receiz-asset-manifest.json
|
|
202
|
+
npx @receiz/sdk init ./receiz-integration
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
These commands prove the SDK can admit and project carried Receiz proof truth without network or database authority.
|
|
@@ -8,6 +8,8 @@ verify proof object -> project immediately -> admit into durable proof memory ->
|
|
|
8
8
|
|
|
9
9
|
The SDK is convenience. It is not authority. The authority remains the sealed artifact, proof bundle, verified append, ownership append, and settlement ledger record.
|
|
10
10
|
|
|
11
|
+
Kai Klok is the proof object state machine. `kaiPulseEternal` is the pulse unit carried by that state machine. A complete Receiz proof object carries Kai; without its Kai coordinate it is not complete Receiz proof truth.
|
|
12
|
+
|
|
11
13
|
## Install
|
|
12
14
|
|
|
13
15
|
```bash
|
|
@@ -52,26 +54,42 @@ The projection keeps card identity, claim hash, ownership, value basis, append s
|
|
|
52
54
|
## Admit Once, Append Forever
|
|
53
55
|
|
|
54
56
|
```ts
|
|
55
|
-
import {
|
|
57
|
+
import {
|
|
58
|
+
createReceizLocalStorageProofMemoryStorage,
|
|
59
|
+
createReceizProofMemory,
|
|
60
|
+
} from "@receiz/sdk";
|
|
56
61
|
|
|
57
|
-
const memory =
|
|
62
|
+
const memory = await createReceizProofMemory({
|
|
63
|
+
ownerId: currentUserId,
|
|
64
|
+
storage: createReceizLocalStorageProofMemoryStorage(`receiz:${currentUserId}:proof-memory`),
|
|
65
|
+
});
|
|
58
66
|
|
|
59
67
|
memory.admitAssetManifest(assetManifest);
|
|
60
68
|
memory.admitSportsCardManifest(cardManifest);
|
|
61
69
|
memory.admitWebhookEvent(webhookEvent);
|
|
62
70
|
|
|
63
|
-
|
|
71
|
+
await memory.flush();
|
|
64
72
|
```
|
|
65
73
|
|
|
66
|
-
|
|
74
|
+
The storage adapter only persists already-admitted truth. It does not verify, mint, rewrite, or outrank the proof object. On next open, the same call reopens the stored register and you render it immediately:
|
|
67
75
|
|
|
68
76
|
```ts
|
|
69
|
-
const memory =
|
|
77
|
+
const memory = await createReceizProofMemory({
|
|
78
|
+
ownerId: currentUserId,
|
|
79
|
+
storage: createReceizLocalStorageProofMemoryStorage(`receiz:${currentUserId}:proof-memory`),
|
|
80
|
+
});
|
|
81
|
+
|
|
70
82
|
const knownTruth = memory.entries();
|
|
71
83
|
```
|
|
72
84
|
|
|
73
85
|
Then ask Receiz for verified additions after your known head. Do not ask whether known proof is still true.
|
|
74
86
|
|
|
87
|
+
```ts
|
|
88
|
+
const after = memory.knownHead(50);
|
|
89
|
+
|
|
90
|
+
await fetch(`/api/receiz/additions?afterKaiUpulse=${after.afterKaiUpulse ?? ""}`);
|
|
91
|
+
```
|
|
92
|
+
|
|
75
93
|
## Receiz Account Restore Boundary
|
|
76
94
|
|
|
77
95
|
Receiz Key, Identity Record, and Identity Seal restore use the same law inside Receiz itself. Current restore artifacts carry `receiz.account.state.v3`, which includes profile/account state, action ledger, calendar events, wallet settlement rows and notes, Sports vault cards, pack purchases, card appends, event proofs, entries, competitions, and tournament state.
|
|
@@ -93,6 +111,23 @@ const retained = memory.snapshot().entries[0];
|
|
|
93
111
|
|
|
94
112
|
This is intentional. Receiz proof memory is not `newest response wins`.
|
|
95
113
|
|
|
114
|
+
## Storage Adapters
|
|
115
|
+
|
|
116
|
+
Browser apps can use `createReceizLocalStorageProofMemoryStorage()`. Server-rendered or test environments can provide the same small interface:
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
import { createReceizProofMemory, type ReceizProofMemoryStorage } from "@receiz/sdk";
|
|
120
|
+
|
|
121
|
+
const storage: ReceizProofMemoryStorage = {
|
|
122
|
+
read: async () => durableStore.get("proof-memory"),
|
|
123
|
+
write: async (snapshot) => durableStore.set("proof-memory", JSON.stringify(snapshot)),
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const memory = await createReceizProofMemory({ storage });
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
For tests and demos, use `createReceizInMemoryProofMemoryStorage()`.
|
|
130
|
+
|
|
96
131
|
## Runtime Schema Exports
|
|
97
132
|
|
|
98
133
|
```ts
|
|
@@ -122,6 +157,7 @@ Use this order in every integration:
|
|
|
122
157
|
3. Project display-ready rows from the verified object.
|
|
123
158
|
4. Admit the object into proof memory.
|
|
124
159
|
5. Persist the proof memory snapshot.
|
|
125
|
-
6.
|
|
160
|
+
6. Resume from the known Kai/proof head.
|
|
161
|
+
7. Append later verified additions without rediscovering known truth.
|
|
126
162
|
|
|
127
163
|
This gives users truthful first paint and gives developers a simple integration that stays aligned with Receiz primitives.
|
|
@@ -4,15 +4,18 @@
|
|
|
4
4
|
"assetType": "proof_object",
|
|
5
5
|
"proof": {
|
|
6
6
|
"kind": "receiz.proof_bundle",
|
|
7
|
-
"payloadVersion":
|
|
7
|
+
"payloadVersion": "v2",
|
|
8
8
|
"createdAtMs": 1782400000000,
|
|
9
9
|
"ts": "2026-06-25T00:00:00.000Z",
|
|
10
10
|
"code": "EXAMPLE",
|
|
11
11
|
"slug": "developer-example",
|
|
12
12
|
"verifyPath": "/v/developer-example/EXAMPLE/123456",
|
|
13
13
|
"verifyUrl": "https://receiz.com/v/developer-example/EXAMPLE/123456",
|
|
14
|
-
"kaiPulseEternal": 123456,
|
|
15
|
-
"
|
|
14
|
+
"kaiPulseEternal": "123456",
|
|
15
|
+
"kaiKlok": "kai:123456",
|
|
16
|
+
"receizClaimId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
17
|
+
"sigilClaimSeed": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
|
18
|
+
"artifactSha256Basis": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
|
|
16
19
|
},
|
|
17
20
|
"owner": {
|
|
18
21
|
"receizSubject": "sub_example_receiz_subject",
|
|
@@ -9,9 +9,18 @@
|
|
|
9
9
|
"appendHash": "sha256:example-append",
|
|
10
10
|
"proofBundle": {
|
|
11
11
|
"kind": "receiz.proof_bundle",
|
|
12
|
+
"payloadVersion": "v2",
|
|
13
|
+
"createdAtMs": 1782400000000,
|
|
14
|
+
"ts": "2026-06-25T00:00:00.000Z",
|
|
15
|
+
"code": "EXAMPLE",
|
|
16
|
+
"slug": "developer-example",
|
|
12
17
|
"verifyPath": "/v/developer-example/EXAMPLE/123456",
|
|
13
18
|
"verifyUrl": "https://receiz.com/v/developer-example/EXAMPLE/123456",
|
|
14
|
-
"kaiPulseEternal": 123456
|
|
19
|
+
"kaiPulseEternal": "123456",
|
|
20
|
+
"kaiKlok": "kai:123456",
|
|
21
|
+
"receizClaimId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
22
|
+
"sigilClaimSeed": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
|
23
|
+
"artifactSha256Basis": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
|
|
15
24
|
}
|
|
16
25
|
}
|
|
17
26
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@receiz/sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "96.0.0",
|
|
4
4
|
"description": "TypeScript SDK for Receiz proof-native artifact, public proof, wallet, sports, and Connect integrations.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"receiz": "./dist/cli.js"
|
|
10
|
+
},
|
|
8
11
|
"exports": {
|
|
9
12
|
".": {
|
|
10
13
|
"types": "./dist/index.d.ts",
|