@receiz/sdk 95.0.0 → 96.1.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,229 @@
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
+ ## Receiz World Storefront Twin
198
+
199
+ Use the public World profile for first paint. Use delegated Twin methods only after the user authorizes your app through Connect.
200
+
201
+ ```ts
202
+ import { createReceizClient } from "@receiz/sdk";
203
+
204
+ export async function loadPublicStorefront(username: string) {
205
+ const receiz = createReceizClient();
206
+ const world = await receiz.world.profile(username);
207
+ if (!world.ok) throw new Error(world.error ?? "world_profile_failed");
208
+ return world.world;
209
+ }
210
+
211
+ export async function runDelegatedTwin(accessToken: string) {
212
+ const receiz = createReceizClient({ accessToken });
213
+ const mandate = await receiz.twin.marketMandate();
214
+ const intents = await receiz.twin.marketIntents();
215
+ return { mandate: mandate.mandate, intents: intents.intents ?? [] };
216
+ }
217
+ ```
218
+
219
+ The public surface is public proof projection. The delegated surface is scoped action permission. Do not use a Connect token as the identity proof root.
220
+
221
+ ## Local CLI Proof
222
+
223
+ ```bash
224
+ npx @receiz/sdk conformance
225
+ npx @receiz/sdk inspect ./receiz-asset-manifest.json
226
+ npx @receiz/sdk init ./receiz-integration
227
+ ```
228
+
229
+ These commands prove the SDK can admit and project carried Receiz proof truth without network or database authority.
@@ -54,26 +54,42 @@ The projection keeps card identity, claim hash, ownership, value basis, append s
54
54
  ## Admit Once, Append Forever
55
55
 
56
56
  ```ts
57
- import { createReceizProofRegister } from "@receiz/sdk";
57
+ import {
58
+ createReceizLocalStorageProofMemoryStorage,
59
+ createReceizProofMemory,
60
+ } from "@receiz/sdk";
58
61
 
59
- const memory = createReceizProofRegister({ ownerId: currentUserId });
62
+ const memory = await createReceizProofMemory({
63
+ ownerId: currentUserId,
64
+ storage: createReceizLocalStorageProofMemoryStorage(`receiz:${currentUserId}:proof-memory`),
65
+ });
60
66
 
61
67
  memory.admitAssetManifest(assetManifest);
62
68
  memory.admitSportsCardManifest(cardManifest);
63
69
  memory.admitWebhookEvent(webhookEvent);
64
70
 
65
- const snapshot = memory.snapshot();
71
+ await memory.flush();
66
72
  ```
67
73
 
68
- Persist `snapshot` in your app storage. On next open, reconstruct memory from `snapshot.entries` and render it immediately:
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:
69
75
 
70
76
  ```ts
71
- const memory = createReceizProofRegister(savedSnapshot);
77
+ const memory = await createReceizProofMemory({
78
+ ownerId: currentUserId,
79
+ storage: createReceizLocalStorageProofMemoryStorage(`receiz:${currentUserId}:proof-memory`),
80
+ });
81
+
72
82
  const knownTruth = memory.entries();
73
83
  ```
74
84
 
75
85
  Then ask Receiz for verified additions after your known head. Do not ask whether known proof is still true.
76
86
 
87
+ ```ts
88
+ const after = memory.knownHead(50);
89
+
90
+ await fetch(`/api/receiz/additions?afterKaiUpulse=${after.afterKaiUpulse ?? ""}`);
91
+ ```
92
+
77
93
  ## Receiz Account Restore Boundary
78
94
 
79
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.
@@ -95,6 +111,23 @@ const retained = memory.snapshot().entries[0];
95
111
 
96
112
  This is intentional. Receiz proof memory is not `newest response wins`.
97
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
+
98
131
  ## Runtime Schema Exports
99
132
 
100
133
  ```ts
@@ -0,0 +1,163 @@
1
+ # Twin And World
2
+
3
+ The SDK exposes Receiz World and Live Twin without changing the authority model.
4
+
5
+ Public World reads and public twin conversations are public surfaces. Owner Twin controls are delegated Connect actions and require a registered OIDC client plus the user-granted scopes your app needs.
6
+
7
+ ```txt
8
+ Receiz ID / proof objects / Twin mind artifact -> projection now
9
+ Connect token -> delegated API permission
10
+ server routes -> sync, append, import, export, execute inside mandate
11
+ ```
12
+
13
+ The SDK is convenience, not authority. A Connect token authorizes access after identity proof. It does not replace Receiz ID, the Twin mind artifact, market mandates, proof memory, or settlement primitives.
14
+
15
+ ## Public World Profile
16
+
17
+ ```ts
18
+ import { createReceizClient } from "@receiz/sdk";
19
+
20
+ const receiz = createReceizClient();
21
+
22
+ const profile = await receiz.world.profile("bjklock", {
23
+ visitorKey: "visitor-local-id",
24
+ threadKey: "thread-local-id",
25
+ });
26
+
27
+ if (!profile.ok) throw new Error(profile.error);
28
+
29
+ renderWorld(profile.world);
30
+ ```
31
+
32
+ ## Public Twin Conversation
33
+
34
+ ```ts
35
+ const reply = await receiz.world.message("bjklock", {
36
+ visitorKey: "visitor-local-id",
37
+ threadKey: "thread-local-id",
38
+ message: "Can you show me the current offer?",
39
+ });
40
+
41
+ renderReply(reply.reply);
42
+ renderWorld(reply.world);
43
+ ```
44
+
45
+ Streaming uses the same public route and returns parsed server-sent events:
46
+
47
+ ```ts
48
+ for await (const event of receiz.world.streamProfile("bjklock", {
49
+ visitorKey: "visitor-local-id",
50
+ threadKey: "thread-local-id",
51
+ message: "Walk me through this site.",
52
+ })) {
53
+ if (event.type === "reply_delta") appendText(event.delta ?? "");
54
+ if (event.type === "reply_done") renderWorld(event.world);
55
+ }
56
+ ```
57
+
58
+ ## OIDC Scopes
59
+
60
+ For owner actions, register an app and request only the scopes your app needs:
61
+
62
+ ```ts
63
+ const authorizeUrl = receiz.identity.authorizeUrl({
64
+ clientId: process.env.RECEIZ_CLIENT_ID!,
65
+ redirectUri: "https://app.example.com/auth/receiz/callback",
66
+ codeChallenge,
67
+ scope: [
68
+ "openid",
69
+ "profile",
70
+ "offline_access",
71
+ "receiz:twin.read",
72
+ "receiz:twin.write",
73
+ ],
74
+ state,
75
+ });
76
+ ```
77
+
78
+ `receiz:twin.read` allows delegated reads such as market mandate, intent list, Twin approval state, and Twin mind export.
79
+
80
+ `receiz:twin.write` allows delegated mutations such as saving a market mandate, creating or approving market intents, importing Twin mind artifacts, and approving public Twin promotion when the owner has the required automation entitlement.
81
+
82
+ ## Market Twin Mandate
83
+
84
+ ```ts
85
+ const receiz = createReceizClient({
86
+ accessToken: process.env.RECEIZ_ACCESS_TOKEN!,
87
+ });
88
+
89
+ const current = await receiz.twin.marketMandate();
90
+
91
+ await receiz.twin.saveMarketMandate({
92
+ status: "active",
93
+ executionMode: "approve",
94
+ allowedMarketTypes: ["asset"],
95
+ allowedSides: ["buy", "sell"],
96
+ maxOrderUsd: "25.00",
97
+ maxDailyGrossUsd: "100.00",
98
+ maxDailyLossUsd: "0.00",
99
+ });
100
+ ```
101
+
102
+ This does not bypass the Market Twin mandate. It edits the mandate through the same server primitive Receiz uses.
103
+
104
+ ## Market Twin Intents
105
+
106
+ ```ts
107
+ const created = await receiz.twin.createMarketIntent({
108
+ marketItemId: "asset_123",
109
+ marketType: "asset",
110
+ side: "buy",
111
+ amountUsd: "10.00",
112
+ reason: "Owner-approved storefront inventory test.",
113
+ });
114
+
115
+ if (created.intent?.status === "pending") {
116
+ const approved = await receiz.twin.approveMarketIntent(created.intent.id);
117
+ renderTrade(approved.trade);
118
+ }
119
+ ```
120
+
121
+ Intent execution remains inside the mandate, risk checks, wallet settlement, and market execution primitives. The SDK does not create a second execution engine.
122
+
123
+ ## Twin Mind Export And Import
124
+
125
+ ```ts
126
+ const mindImage = await receiz.twin.exportMind();
127
+ await saveFile("receiz-twin-mind.png", mindImage);
128
+ ```
129
+
130
+ Import verifies the Twin mind artifact before restore:
131
+
132
+ ```ts
133
+ const summary = await receiz.twin.importMind(file);
134
+ renderImportSummary(summary.summary);
135
+ ```
136
+
137
+ This is file-carried Twin memory. Treat the exported image as a proof object transport. Do not flatten it into generic profile metadata.
138
+
139
+ ## Public Twin Promotion
140
+
141
+ ```ts
142
+ const approval = await receiz.twin.approval();
143
+
144
+ await receiz.twin.approvePromotion({
145
+ performance: {
146
+ style: "photoreal",
147
+ score: 98,
148
+ reason: "Owner-approved public Twin promotion.",
149
+ },
150
+ approvalReference: "external-app-review-001",
151
+ evidenceAssets: [{ kind: "image", url: "https://app.example.com/evidence.png" }],
152
+ });
153
+ ```
154
+
155
+ Promotion approval still requires the owner account to have the required automation entitlement. A token with `receiz:twin.write` authorizes the app to ask; it does not remove account-level law.
156
+
157
+ ## Business / Developer Account Boundary
158
+
159
+ Public World reads do not require a business/developer account.
160
+
161
+ Delegated owner actions require an app registration so Receiz can issue OIDC tokens for that app. In practice, a business/developer account is the correct account type for creating and managing OIDC clients, redirect URIs, scopes, token lifecycle, and production app access.
162
+
163
+ The user still proves identity through Receiz. The app receives delegated access only after the user authorizes it.
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "@receiz/sdk",
3
- "version": "95.0.0",
4
- "description": "TypeScript SDK for Receiz proof-native artifact, public proof, wallet, sports, and Connect integrations.",
3
+ "version": "96.1.0",
4
+ "description": "TypeScript SDK for Receiz proof-native artifact, public proof, wallet, sports, Twin, World, 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",