zklicensing 0.1.0-beta.2 → 0.1.0-beta.4
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 +335 -97
- package/build/appsLookup.d.ts +14 -0
- package/build/appsLookup.d.ts.map +1 -0
- package/build/appsLookup.js +12 -0
- package/build/appsLookup.js.map +1 -0
- package/build/archiveBootstrap.d.ts +15 -1
- package/build/archiveBootstrap.d.ts.map +1 -0
- package/build/archiveBootstrap.js +62 -9
- package/build/archiveBootstrap.js.map +1 -0
- package/build/bindClient.d.ts +51 -0
- package/build/bindClient.d.ts.map +1 -0
- package/build/bindClient.js +115 -0
- package/build/bindClient.js.map +1 -0
- package/build/buyClient.d.ts +10 -3
- package/build/buyClient.d.ts.map +1 -0
- package/build/buyClient.js +33 -15
- package/build/buyClient.js.map +1 -0
- package/build/contractInterface.d.ts +11 -5
- package/build/contractInterface.d.ts.map +1 -0
- package/build/contractInterface.js +82 -17
- package/build/contractInterface.js.map +1 -0
- package/build/countryStats.d.ts +6 -1
- package/build/countryStats.d.ts.map +1 -0
- package/build/countryStats.js +33 -9
- package/build/countryStats.js.map +1 -0
- package/build/deployClient.d.ts.map +1 -0
- package/build/deployClient.js +1 -1
- package/build/deployClient.js.map +1 -0
- package/build/deviceIdentity.d.ts +68 -0
- package/build/deviceIdentity.d.ts.map +1 -0
- package/build/deviceIdentity.js +209 -0
- package/build/deviceIdentity.js.map +1 -0
- package/build/freezeClient.d.ts.map +1 -0
- package/build/freezeClient.js +1 -1
- package/build/freezeClient.js.map +1 -0
- package/build/generationClient.d.ts +1 -0
- package/build/generationClient.d.ts.map +1 -0
- package/build/generationClient.js +2 -2
- package/build/generationClient.js.map +1 -0
- package/build/index.d.ts +27 -37
- package/build/index.d.ts.map +1 -0
- package/build/index.js +85 -116
- package/build/index.js.map +1 -0
- package/build/licenseLeaf.d.ts +76 -0
- package/build/licenseLeaf.d.ts.map +1 -0
- package/build/licenseLeaf.js +189 -0
- package/build/licenseLeaf.js.map +1 -0
- package/build/licenseRecord.d.ts +20 -1
- package/build/licenseRecord.d.ts.map +1 -0
- package/build/licenseRecord.js +1 -1
- package/build/licenseRecord.js.map +1 -0
- package/build/licenseStore.d.ts +17 -2
- package/build/licenseStore.d.ts.map +1 -0
- package/build/licenseStore.js +167 -7
- package/build/licenseStore.js.map +1 -0
- package/build/manifestVerify.d.ts.map +1 -0
- package/build/manifestVerify.js +8 -3
- package/build/manifestVerify.js.map +1 -0
- package/build/migrateClient.d.ts +6 -21
- package/build/migrateClient.d.ts.map +1 -0
- package/build/migrateClient.js +30 -17
- package/build/migrateClient.js.map +1 -0
- package/build/onChainRoot.d.ts +67 -0
- package/build/onChainRoot.d.ts.map +1 -0
- package/build/onChainRoot.js +87 -0
- package/build/onChainRoot.js.map +1 -0
- package/build/ownershipLicenseHash.d.ts +25 -0
- package/build/ownershipLicenseHash.d.ts.map +1 -0
- package/build/ownershipLicenseHash.js +29 -0
- package/build/ownershipLicenseHash.js.map +1 -0
- package/build/ownershipSignature.d.ts +122 -0
- package/build/ownershipSignature.d.ts.map +1 -0
- package/build/ownershipSignature.js +244 -0
- package/build/ownershipSignature.js.map +1 -0
- package/build/proveErrors.d.ts +35 -0
- package/build/proveErrors.d.ts.map +1 -0
- package/build/proveErrors.js +49 -0
- package/build/proveErrors.js.map +1 -0
- package/build/refundClient.d.ts +2 -11
- package/build/refundClient.d.ts.map +1 -0
- package/build/refundClient.js +35 -17
- package/build/refundClient.js.map +1 -0
- package/build/renewClient.d.ts +4 -1
- package/build/renewClient.d.ts.map +1 -0
- package/build/renewClient.js +11 -4
- package/build/renewClient.js.map +1 -0
- package/build/seatName.d.ts +8 -0
- package/build/seatName.d.ts.map +1 -0
- package/build/seatName.js +136 -0
- package/build/seatName.js.map +1 -0
- package/build/statsClient.d.ts +47 -4
- package/build/statsClient.d.ts.map +1 -0
- package/build/statsClient.js +44 -5
- package/build/statsClient.js.map +1 -0
- package/build/trustAnchorVerify.d.ts +48 -0
- package/build/trustAnchorVerify.d.ts.map +1 -0
- package/build/trustAnchorVerify.js +431 -0
- package/build/trustAnchorVerify.js.map +1 -0
- package/build/trustAnchorVerifyCli.d.ts +35 -0
- package/build/trustAnchorVerifyCli.d.ts.map +1 -0
- package/build/trustAnchorVerifyCli.js +177 -0
- package/build/trustAnchorVerifyCli.js.map +1 -0
- package/build/txBroadcastClient.d.ts +26 -0
- package/build/txBroadcastClient.d.ts.map +1 -0
- package/build/txBroadcastClient.js +20 -0
- package/build/txBroadcastClient.js.map +1 -0
- package/build/unbindClient.d.ts +56 -0
- package/build/unbindClient.d.ts.map +1 -0
- package/build/unbindClient.js +113 -0
- package/build/unbindClient.js.map +1 -0
- package/build/vendorAccountClient.d.ts +56 -0
- package/build/vendorAccountClient.d.ts.map +1 -0
- package/build/vendorAccountClient.js +47 -0
- package/build/vendorAccountClient.js.map +1 -0
- package/build/verifyCore.d.ts +1 -1
- package/build/verifyCore.d.ts.map +1 -0
- package/build/verifyCore.js +11 -4
- package/build/verifyCore.js.map +1 -0
- package/build/verifyOffline.d.ts +85 -0
- package/build/verifyOffline.d.ts.map +1 -0
- package/build/verifyOffline.js +139 -0
- package/build/verifyOffline.js.map +1 -0
- package/build/verifyService.d.ts.map +1 -0
- package/build/verifyService.js +582 -455
- package/build/verifyService.js.map +1 -0
- package/build/verifyWithAncestors.d.ts +18 -0
- package/build/verifyWithAncestors.d.ts.map +1 -0
- package/build/verifyWithAncestors.js +119 -0
- package/build/verifyWithAncestors.js.map +1 -0
- package/build/zipToState.d.ts +2 -0
- package/build/zipToState.d.ts.map +1 -0
- package/build/zipToState.js +94 -0
- package/build/zipToState.js.map +1 -0
- package/package.json +57 -13
- package/src/appsLookup.ts +48 -0
- package/src/archiveBootstrap.ts +342 -0
- package/src/bindClient.ts +175 -0
- package/src/buyClient.ts +304 -0
- package/src/contractInterface.d.ts +61 -0
- package/src/contractInterface.ts +313 -0
- package/src/countryStats.ts +171 -0
- package/src/deployClient.ts +388 -0
- package/src/deviceIdentity.ts +249 -0
- package/src/freezeClient.ts +117 -0
- package/src/generationClient.ts +165 -0
- package/src/index.ts +329 -0
- package/src/licenseLeaf.ts +221 -0
- package/src/licenseRecord.ts +108 -0
- package/src/licenseStore.ts +538 -0
- package/src/manifestVerify.ts +111 -0
- package/src/migrateClient.ts +84 -0
- package/src/onChainRoot.ts +107 -0
- package/src/ownershipLicenseHash.ts +31 -0
- package/src/ownershipSignature.ts +354 -0
- package/src/proveErrors.ts +70 -0
- package/src/refundClient.ts +158 -0
- package/src/renewClient.ts +214 -0
- package/src/seatName.ts +165 -0
- package/src/statsClient.ts +235 -0
- package/src/trustAnchorVerify.ts +548 -0
- package/src/trustAnchorVerifyCli.ts +179 -0
- package/src/txBroadcastClient.ts +48 -0
- package/src/unbindClient.ts +149 -0
- package/src/vendorAccountClient.ts +110 -0
- package/src/verifyCore.ts +92 -0
- package/src/verifyOffline.ts +212 -0
- package/src/verifyService.ts +969 -0
- package/src/verifyWithAncestors.ts +153 -0
- package/src/zipToState.ts +94 -0
- package/build/licenseProof.d.ts +0 -26
- package/build/licenseProof.js +0 -41
- package/build/ownership.d.ts +0 -34
- package/build/ownership.js +0 -147
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"licenseRecord.d.ts","sourceRoot":"","sources":["../src/licenseRecord.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AAQH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAI,MAAM,CAAC;IACtB,WAAW,EAAI,MAAM,CAAC;IACtB,WAAW,EAAI,MAAM,CAAC;IACtB,UAAU,EAAK,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,YAAY,EAAI,MAAM,CAAC;IACvB,WAAW,EAAK,MAAM,CAAC;IACvB,UAAU,EAAM,MAAM,CAAC;IACvB,YAAY,EAAI,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAU,MAAM,CAAC;IACvB,SAAS,EAAO,MAAM,CAAC;IAMvB,SAAS,CAAC,EAAQ,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAI3B,OAAO,CAAC,EAAE,KAAK,CAAC;QACd,SAAS,EAAS,MAAM,CAAC;QACzB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAO,MAAM,CAAC;QACzB,WAAW,EAAO,MAAM,CAAC;KAC1B,CAAC,CAAC;IACH,YAAY,CAAC,EAAG,MAAM,CAAC;IACvB,YAAY,CAAC,EAAG,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAO,MAAM,CAAC;IACvB,OAAO,CAAC,EAAQ,OAAO,CAAC;IACxB,YAAY,CAAC,EAAG,MAAM,CAAC;IAGvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAG3B,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAC;IAGvD,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAG7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IAGnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IAKrB,aAAa,CAAC,EAAE,MAAM,CAAC;IAOvB,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,gBAAgB,CAAA;KAAE,CAAC,CAAC;IAKxH,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAMhC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAMhC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAIF,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC"}
|
package/build/licenseRecord.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Copyright (c) 2025-2026 zkLicensing project developers
|
|
2
|
-
//
|
|
2
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
3
3
|
// Reap pending records this many slots after prove time if no event ever lands.
|
|
4
4
|
// 60 slots ≈ 90 minutes — a generous window for tx inclusion under devnet conditions.
|
|
5
5
|
export const PENDING_REAP_SLOTS = 60;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"licenseRecord.js","sourceRoot":"","sources":["../src/licenseRecord.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,oCAAoC;AAsGpC,gFAAgF;AAChF,sFAAsF;AACtF,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC"}
|
package/build/licenseStore.d.ts
CHANGED
|
@@ -34,15 +34,30 @@ export declare function updateExpiry(zkAppAddress: string, licenseHash: string,
|
|
|
34
34
|
};
|
|
35
35
|
}): Promise<boolean>;
|
|
36
36
|
export declare function recordRefund(zkAppAddress: string, licenseHash: string): Promise<boolean>;
|
|
37
|
-
export declare function recordRelease(zkAppAddress: string, licenseHash: string, releaseSlot?: number): Promise<boolean>;
|
|
37
|
+
export declare function recordRelease(zkAppAddress: string, licenseHash: string, releaseSlot?: number, txHash?: string): Promise<boolean>;
|
|
38
38
|
export declare function confirmRecord(zkAppAddress: string, licenseHash: string): Promise<boolean>;
|
|
39
39
|
export declare function applyLicenseIssued(zkAppAddress: string, licenseHash: string, fields: {
|
|
40
40
|
expirySlot: number;
|
|
41
41
|
purchaseSlot: number;
|
|
42
42
|
purchaseAmount: string;
|
|
43
|
-
tier?: 'monthly' | 'yearly' | 'fiveYear';
|
|
43
|
+
tier?: 'monthly' | 'yearly' | 'fiveYear' | 'perpetual';
|
|
44
44
|
escrowless?: boolean;
|
|
45
|
+
deviceCap?: number;
|
|
46
|
+
deviceSlotsRoot?: string;
|
|
47
|
+
deviceSlotsFilled?: number;
|
|
45
48
|
}): Promise<void>;
|
|
49
|
+
export declare function applyLicenseRenewed(zkAppAddress: string, licenseHash: string, fields: {
|
|
50
|
+
newExpiry: number;
|
|
51
|
+
}): Promise<boolean>;
|
|
52
|
+
export declare function applyDeviceBound(zkAppAddress: string, licenseHash: string, fields: {
|
|
53
|
+
slotIndex: number;
|
|
54
|
+
deviceCommitment: string;
|
|
55
|
+
boundAtSlot: number;
|
|
56
|
+
}): Promise<boolean>;
|
|
57
|
+
export declare function applyDeviceUnbound(zkAppAddress: string, licenseHash: string, fields: {
|
|
58
|
+
slotIndex: number;
|
|
59
|
+
freedAtSlot: number;
|
|
60
|
+
}): Promise<boolean>;
|
|
46
61
|
export declare function deleteRecord(zkAppAddress: string, licenseHash: string): Promise<boolean>;
|
|
47
62
|
export declare function getStalePendingRecords(currentSlot: number, maxAgeSlots?: number): Promise<LicenseRecord[]>;
|
|
48
63
|
export declare function getReleasableRecords(currentSlot: number): Promise<LicenseRecord[]>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"licenseStore.d.ts","sourceRoot":"","sources":["../src/licenseStore.ts"],"names":[],"mappings":"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"}
|
package/build/licenseStore.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Copyright (c) 2025-2026 zkLicensing project developers
|
|
2
|
-
//
|
|
2
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
3
3
|
/**
|
|
4
4
|
* licenseStore.ts
|
|
5
5
|
*
|
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
* Used by:
|
|
14
14
|
* - interact.ts / buyLicense.ts (CLI) — reads/writes directly
|
|
15
15
|
* - keeperService.ts — exposes the same logic over HTTP
|
|
16
|
-
* - proofServer.ts — reads expirySlot for a given licenseHash
|
|
17
16
|
*/
|
|
18
17
|
import fs from 'fs/promises';
|
|
19
18
|
import { Bool, Field, MerkleMap, MerkleMapWitness, Poseidon, PublicKey, UInt32, UInt64 } from 'o1js';
|
|
20
19
|
import { GRACE_PERIOD_N, REFUND_WINDOW_N } from './contractInterface.js';
|
|
20
|
+
import { computeDeviceSlotsRoot, DEVICE_SLOT_CAP_N, leafFromRecord, leafHash } from './licenseLeaf.js';
|
|
21
21
|
import { PENDING_REAP_SLOTS as _PENDING_REAP_SLOTS } from './licenseRecord.js';
|
|
22
22
|
export const PENDING_REAP_SLOTS = _PENDING_REAP_SLOTS;
|
|
23
23
|
export function licenseStorePath() {
|
|
@@ -64,12 +64,19 @@ function recordsForApp(records, zkAppAddress) {
|
|
|
64
64
|
return records.filter(r => r.zkAppAddress === zkAppAddress);
|
|
65
65
|
}
|
|
66
66
|
// Rebuild the license MerkleMap for a single zkApp. Only inserts entries
|
|
67
|
-
// with expirySlot > 0.
|
|
67
|
+
// with expirySlot > 0. The value stored at each key is `leaf.hash()` — the
|
|
68
|
+
// Poseidon commitment over (licenseHash, expirySlot, cap, deviceSlotsRoot,
|
|
69
|
+
// deviceSlotsFilled) — matching what LicensingApp writes. Records that
|
|
70
|
+
// predate device binding rebuild to a leaf with empty slots (see
|
|
71
|
+
// leafFromRecord for the exact defaults); on those records the rebuilt
|
|
72
|
+
// root matches what the old contract wrote, but any mutation call will
|
|
73
|
+
// fail the in-circuit hash check until the missing fields are backfilled
|
|
74
|
+
// from chain events.
|
|
68
75
|
export function buildMap(records, zkAppAddress) {
|
|
69
76
|
const map = new MerkleMap();
|
|
70
77
|
for (const r of recordsForApp(records, zkAppAddress)) {
|
|
71
78
|
if (r.expirySlot !== 0) {
|
|
72
|
-
map.set(Field(r.licenseHash),
|
|
79
|
+
map.set(Field(r.licenseHash), leafHash(leafFromRecord(r)));
|
|
73
80
|
}
|
|
74
81
|
}
|
|
75
82
|
return map;
|
|
@@ -138,6 +145,15 @@ export async function upsertLicense(record) {
|
|
|
138
145
|
if (!record.zkAppAddress) {
|
|
139
146
|
throw new Error('upsertLicense: record.zkAppAddress is required');
|
|
140
147
|
}
|
|
148
|
+
// Populate the empty-slot mirror at insert time when the license is capped.
|
|
149
|
+
// Without this, /confirm/buy writes deviceCap:N but leaves deviceSlotsRoot
|
|
150
|
+
// and deviceSlotsFilled undefined until the first bind — leafFromRecord's
|
|
151
|
+
// fallbacks paper over it for hash reconstruction, but every consumer that
|
|
152
|
+
// reads the mirror directly (preflight logs, /license responses, offline
|
|
153
|
+
// verify) would see undefined and either misreport or need its own fallback.
|
|
154
|
+
if ((record.deviceCap ?? 0) > 0 && (record.deviceSlotsRoot === undefined || record.deviceSlotsFilled === undefined)) {
|
|
155
|
+
refreshSlotMirror(record);
|
|
156
|
+
}
|
|
141
157
|
return withWriteLock(async () => {
|
|
142
158
|
const records = await readRecords();
|
|
143
159
|
const idx = records.findIndex(r => r.zkAppAddress === record.zkAppAddress && r.licenseHash === record.licenseHash);
|
|
@@ -187,6 +203,12 @@ export async function recordRefund(zkAppAddress, licenseHash) {
|
|
|
187
203
|
record.purchaseSlot = 0;
|
|
188
204
|
record.purchaseAmount = '0';
|
|
189
205
|
record.refunded = true;
|
|
206
|
+
// Same pending-clear the buy/renew apply* siblings do — /confirm/refund
|
|
207
|
+
// wrote pending:true optimistically; the on-chain event landing is what
|
|
208
|
+
// authorizes clearing it. Without this the SDK poller (which requires
|
|
209
|
+
// pending===false && status==='refunded') hangs forever.
|
|
210
|
+
delete record.pending;
|
|
211
|
+
delete record.provedAtSlot;
|
|
190
212
|
await writeRecords(records);
|
|
191
213
|
return true;
|
|
192
214
|
});
|
|
@@ -194,7 +216,7 @@ export async function recordRefund(zkAppAddress, licenseHash) {
|
|
|
194
216
|
// Mark escrow as released. Preserves purchaseAmount/purchaseSlot so stats can
|
|
195
217
|
// compute released revenue. The `released` flag is the truth signal —
|
|
196
218
|
// buildEscrowMap and getReleasableRecords filter on it directly.
|
|
197
|
-
export async function recordRelease(zkAppAddress, licenseHash, releaseSlot) {
|
|
219
|
+
export async function recordRelease(zkAppAddress, licenseHash, releaseSlot, txHash) {
|
|
198
220
|
return withWriteLock(async () => {
|
|
199
221
|
const records = await readRecords();
|
|
200
222
|
const record = records.find(r => r.zkAppAddress === zkAppAddress && r.licenseHash === licenseHash);
|
|
@@ -203,6 +225,8 @@ export async function recordRelease(zkAppAddress, licenseHash, releaseSlot) {
|
|
|
203
225
|
record.released = true;
|
|
204
226
|
if (releaseSlot !== undefined)
|
|
205
227
|
record.releaseSlot = releaseSlot;
|
|
228
|
+
if (txHash !== undefined)
|
|
229
|
+
record.releaseTxHash = txHash;
|
|
206
230
|
await writeRecords(records);
|
|
207
231
|
return true;
|
|
208
232
|
});
|
|
@@ -252,9 +276,23 @@ export async function applyLicenseIssued(zkAppAddress, licenseHash, fields) {
|
|
|
252
276
|
record.escrowless = true;
|
|
253
277
|
dirty = true;
|
|
254
278
|
}
|
|
279
|
+
// Backfill leaf fields if the record was created before the event
|
|
280
|
+
// carried them, or if a prior partial rehydrate is still missing them.
|
|
281
|
+
if (fields.deviceCap !== undefined && record.deviceCap === undefined) {
|
|
282
|
+
record.deviceCap = fields.deviceCap;
|
|
283
|
+
dirty = true;
|
|
284
|
+
}
|
|
285
|
+
if (fields.deviceSlotsRoot !== undefined && record.deviceSlotsRoot === undefined) {
|
|
286
|
+
record.deviceSlotsRoot = fields.deviceSlotsRoot;
|
|
287
|
+
dirty = true;
|
|
288
|
+
}
|
|
289
|
+
if (fields.deviceSlotsFilled !== undefined && record.deviceSlotsFilled === undefined) {
|
|
290
|
+
record.deviceSlotsFilled = fields.deviceSlotsFilled;
|
|
291
|
+
dirty = true;
|
|
292
|
+
}
|
|
255
293
|
}
|
|
256
294
|
else {
|
|
257
|
-
|
|
295
|
+
const inserted = {
|
|
258
296
|
zkAppAddress,
|
|
259
297
|
licenseHash,
|
|
260
298
|
expirySlot: fields.expirySlot,
|
|
@@ -265,13 +303,135 @@ export async function applyLicenseIssued(zkAppAddress, licenseHash, fields) {
|
|
|
265
303
|
initialExpirySlot: fields.expirySlot,
|
|
266
304
|
...(fields.tier ? { tier: fields.tier } : {}),
|
|
267
305
|
...(fields.escrowless === true ? { escrowless: true } : {}),
|
|
268
|
-
|
|
306
|
+
...(fields.deviceCap !== undefined ? { deviceCap: fields.deviceCap } : {}),
|
|
307
|
+
...(fields.deviceSlotsRoot !== undefined ? { deviceSlotsRoot: fields.deviceSlotsRoot } : {}),
|
|
308
|
+
...(fields.deviceSlotsFilled !== undefined ? { deviceSlotsFilled: fields.deviceSlotsFilled } : {}),
|
|
309
|
+
};
|
|
310
|
+
// Same rationale as upsertLicense: populate the empty-slot mirror on
|
|
311
|
+
// first insert so the record is immediately queryable without relying
|
|
312
|
+
// on leafFromRecord's undefined fallbacks.
|
|
313
|
+
if ((inserted.deviceCap ?? 0) > 0 && (inserted.deviceSlotsRoot === undefined || inserted.deviceSlotsFilled === undefined)) {
|
|
314
|
+
refreshSlotMirror(inserted);
|
|
315
|
+
}
|
|
316
|
+
records.push(inserted);
|
|
269
317
|
dirty = true;
|
|
270
318
|
}
|
|
271
319
|
if (dirty)
|
|
272
320
|
await writeRecords(records);
|
|
273
321
|
});
|
|
274
322
|
}
|
|
323
|
+
// Apply a licenseRenewed event atomically: clear any pending /confirm/renew
|
|
324
|
+
// write, align expirySlot with the event, and flip renewedAtLeastOnce.
|
|
325
|
+
// Symmetric to applyLicenseIssued — the archive-events path is what closes
|
|
326
|
+
// out a renew that the bestChain sweep missed (tx landed after the sweep's
|
|
327
|
+
// BESTCHAIN_DEPTH window rolled past), and without a pending-clear step here
|
|
328
|
+
// the flag on a landed record could be stuck forever.
|
|
329
|
+
//
|
|
330
|
+
// Does NOT append to renewals[] — that log is populated at /confirm/renew
|
|
331
|
+
// time from the intent (which carries amount + txHash); the archive event
|
|
332
|
+
// carries only newExpiry, so replaying it must not overwrite the richer
|
|
333
|
+
// confirm-time entry.
|
|
334
|
+
export async function applyLicenseRenewed(zkAppAddress, licenseHash, fields) {
|
|
335
|
+
return withWriteLock(async () => {
|
|
336
|
+
const records = await readRecords();
|
|
337
|
+
const record = records.find(r => r.zkAppAddress === zkAppAddress && r.licenseHash === licenseHash);
|
|
338
|
+
if (!record)
|
|
339
|
+
return false;
|
|
340
|
+
let dirty = false;
|
|
341
|
+
if (record.pending) {
|
|
342
|
+
delete record.pending;
|
|
343
|
+
delete record.provedAtSlot;
|
|
344
|
+
dirty = true;
|
|
345
|
+
}
|
|
346
|
+
if (record.expirySlot !== fields.newExpiry) {
|
|
347
|
+
record.expirySlot = fields.newExpiry;
|
|
348
|
+
dirty = true;
|
|
349
|
+
}
|
|
350
|
+
if (!record.renewedAtLeastOnce) {
|
|
351
|
+
record.renewedAtLeastOnce = true;
|
|
352
|
+
dirty = true;
|
|
353
|
+
}
|
|
354
|
+
if (dirty)
|
|
355
|
+
await writeRecords(records);
|
|
356
|
+
return true;
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
// Recompute deviceSlotsRoot + deviceSlotsFilled from the record's mirror after
|
|
360
|
+
// a bind/unbind mutation. `leafFromRecord` uses those two persisted fields when
|
|
361
|
+
// building the on-chain leaf hash; if they drift from the on-chain state the
|
|
362
|
+
// next mutation call fails the in-circuit leaf-hash assert. Mirror the exact
|
|
363
|
+
// packing the circuit uses (packSlotTimes: freedAt in low 32 bits, boundAt in
|
|
364
|
+
// high 32) so the fold matches the on-chain deviceSlotsRoot bit-for-bit.
|
|
365
|
+
function refreshSlotMirror(record) {
|
|
366
|
+
const devices = record.devices ?? [];
|
|
367
|
+
const occupied = [];
|
|
368
|
+
const freedAt = [];
|
|
369
|
+
for (let i = 0; i < DEVICE_SLOT_CAP_N; i++) {
|
|
370
|
+
const entry = devices.find(d => d.slotIndex === i);
|
|
371
|
+
const occ = entry?.deviceCommitment ?? '0';
|
|
372
|
+
occupied.push(Field(occ));
|
|
373
|
+
const boundAt = BigInt(entry?.boundAtSlot ?? 0);
|
|
374
|
+
const freed = BigInt(entry?.freedAtSlot ?? 0);
|
|
375
|
+
// packSlotTimes(boundAt, freedAt) in licenseLeaf.ts: freedAt low 32, boundAt high 32.
|
|
376
|
+
const packed = freed + (boundAt << 32n);
|
|
377
|
+
freedAt.push(Field(packed));
|
|
378
|
+
}
|
|
379
|
+
record.deviceSlotsRoot = computeDeviceSlotsRoot(occupied, freedAt).toString();
|
|
380
|
+
record.deviceSlotsFilled = devices.filter(d => d.deviceCommitment !== '0').length;
|
|
381
|
+
}
|
|
382
|
+
// Apply a deviceBound event atomically: mirrors the on-chain slot mutation
|
|
383
|
+
// into the record.devices[] array and recomputes deviceSlotsRoot / filled so
|
|
384
|
+
// leafFromRecord reconstructs the exact leaf hash the chain committed.
|
|
385
|
+
//
|
|
386
|
+
// `boundAtSlot` MUST be the circuit's proof-time `globalSlotSinceGenesis` (the
|
|
387
|
+
// value emitted in `DeviceBoundEvent.boundAtSlot`). The block slot when the tx
|
|
388
|
+
// landed is NOT interchangeable: TOLERANCE_WINDOW allows them to differ, and
|
|
389
|
+
// any drift flips the packed `freedAt` field → wrong leaf → root divergence.
|
|
390
|
+
export async function applyDeviceBound(zkAppAddress, licenseHash, fields) {
|
|
391
|
+
return withWriteLock(async () => {
|
|
392
|
+
const records = await readRecords();
|
|
393
|
+
const record = records.find(r => r.zkAppAddress === zkAppAddress && r.licenseHash === licenseHash);
|
|
394
|
+
if (!record)
|
|
395
|
+
return false;
|
|
396
|
+
const devices = (record.devices ??= []);
|
|
397
|
+
// Ensure the array is long enough — pad with empty slots.
|
|
398
|
+
while (devices.length <= fields.slotIndex) {
|
|
399
|
+
devices.push({ slotIndex: devices.length, deviceCommitment: '0', boundAtSlot: 0, freedAtSlot: 0 });
|
|
400
|
+
}
|
|
401
|
+
devices[fields.slotIndex] = {
|
|
402
|
+
slotIndex: fields.slotIndex,
|
|
403
|
+
deviceCommitment: fields.deviceCommitment,
|
|
404
|
+
boundAtSlot: fields.boundAtSlot,
|
|
405
|
+
freedAtSlot: 0, // pristine → fresh bind resets freedAt
|
|
406
|
+
};
|
|
407
|
+
refreshSlotMirror(record);
|
|
408
|
+
await writeRecords(records);
|
|
409
|
+
return true;
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
// Apply a deviceUnbound event atomically. Preserves boundAtSlot for audit,
|
|
413
|
+
// stamps freedAtSlot for the cooldown timer the circuit's next bind enforces.
|
|
414
|
+
//
|
|
415
|
+
// `freedAtSlot` MUST be the circuit's proof-time `globalSlotSinceGenesis` (the
|
|
416
|
+
// value emitted in `DeviceUnboundEvent.freedAtSlot`). Same reason as
|
|
417
|
+
// `applyDeviceBound.boundAtSlot`.
|
|
418
|
+
export async function applyDeviceUnbound(zkAppAddress, licenseHash, fields) {
|
|
419
|
+
return withWriteLock(async () => {
|
|
420
|
+
const records = await readRecords();
|
|
421
|
+
const record = records.find(r => r.zkAppAddress === zkAppAddress && r.licenseHash === licenseHash);
|
|
422
|
+
if (!record || !record.devices)
|
|
423
|
+
return false;
|
|
424
|
+
const slot = record.devices.find(d => d.slotIndex === fields.slotIndex);
|
|
425
|
+
if (!slot)
|
|
426
|
+
return false;
|
|
427
|
+
slot.deviceCommitment = '0';
|
|
428
|
+
slot.freedAtSlot = fields.freedAtSlot;
|
|
429
|
+
// boundAtSlot stays as the last bind time — historical / audit.
|
|
430
|
+
refreshSlotMirror(record);
|
|
431
|
+
await writeRecords(records);
|
|
432
|
+
return true;
|
|
433
|
+
});
|
|
434
|
+
}
|
|
275
435
|
// Delete a record entirely (used to reap stale pending entries the buyer never submitted).
|
|
276
436
|
export async function deleteRecord(zkAppAddress, licenseHash) {
|
|
277
437
|
return withWriteLock(async () => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"licenseStore.js","sourceRoot":"","sources":["../src/licenseStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifestVerify.d.ts","sourceRoot":"","sources":["../src/manifestVerify.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;GAmBG;AASH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQnD;AA6BD;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,OAAO,EAChB,eAAe,EAAE,MAAM,EACvB,sBAAsB,EAAE,SAAS,MAAM,EAAE,GACxC,OAAO,CAAC,OAAO,CAAC,CA+BlB"}
|
package/build/manifestVerify.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Copyright (c) 2025-2026 zkLicensing project developers
|
|
2
|
-
//
|
|
2
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
3
3
|
/**
|
|
4
4
|
* manifestVerify.ts
|
|
5
5
|
*
|
|
@@ -21,6 +21,10 @@
|
|
|
21
21
|
* simple and mirrored.
|
|
22
22
|
*/
|
|
23
23
|
// Canonical JSON: sorted keys, no whitespace, arrays preserved in order.
|
|
24
|
+
// Undefined values are skipped, mirroring JSON.stringify — otherwise the
|
|
25
|
+
// signed bytes would contain `"key":undefined` for optional fields left
|
|
26
|
+
// unset, while `res.json()` on the wire would strip them, and the signature
|
|
27
|
+
// would never verify.
|
|
24
28
|
// Mirror of src/manifestSign.ts:canonicalize. Divergence here silently
|
|
25
29
|
// breaks verification.
|
|
26
30
|
export function canonicalize(value) {
|
|
@@ -28,8 +32,9 @@ export function canonicalize(value) {
|
|
|
28
32
|
return JSON.stringify(value);
|
|
29
33
|
if (Array.isArray(value))
|
|
30
34
|
return '[' + value.map(canonicalize).join(',') + ']';
|
|
31
|
-
const
|
|
32
|
-
|
|
35
|
+
const obj = value;
|
|
36
|
+
const keys = Object.keys(obj).filter(k => obj[k] !== undefined).sort();
|
|
37
|
+
return '{' + keys.map(k => JSON.stringify(k) + ':' + canonicalize(obj[k])).join(',') + '}';
|
|
33
38
|
}
|
|
34
39
|
function base64ToBytes(b64) {
|
|
35
40
|
// atob is present in every modern JS runtime we target (browser + Node ≥ 16).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifestVerify.js","sourceRoot":"","sources":["../src/manifestVerify.ts"],"names":[],"mappings":"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"}
|
package/build/migrateClient.d.ts
CHANGED
|
@@ -1,22 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* migrateClient.ts
|
|
3
|
-
*
|
|
4
|
-
* Browser-safe client for /prove/migrate. Assembles a single-hop cross-
|
|
5
|
-
* generation proof against the current live map — the keeper walks the
|
|
6
|
-
* deploymentHistory once, gathers all three witnesses (ancestor / pred /
|
|
7
|
-
* live-empty), and returns a signable tx.
|
|
8
|
-
*
|
|
9
|
-
* Failure surfaces:
|
|
10
|
-
* - 404 "license refunded or unknown": no leaf anywhere in history for
|
|
11
|
-
* this licenseHash. Caller should not retry — it's terminal.
|
|
12
|
-
* - 409 "already migrated": leaf is present in the live map. Caller
|
|
13
|
-
* should refresh their license record and stop.
|
|
14
|
-
* - 409 "migration in flight": another caller is proving right now.
|
|
15
|
-
* `retryAfterMs` on the error tells the caller how long to wait
|
|
16
|
-
* before trying again. See `ProveMigrateError.retryAfterMs`.
|
|
17
|
-
*/
|
|
18
1
|
export interface ProveMigrateRequest {
|
|
19
2
|
keeperUrl: string;
|
|
3
|
+
network: 'devnet' | 'mainnet';
|
|
20
4
|
licenseHash: string;
|
|
21
5
|
appId: string;
|
|
22
6
|
buyerAddress: string;
|
|
@@ -29,15 +13,16 @@ export interface ProveMigrateResponse {
|
|
|
29
13
|
expirySlot: number;
|
|
30
14
|
licenseHash: string;
|
|
31
15
|
zkAppAddress: string;
|
|
16
|
+
appKey: string;
|
|
32
17
|
}
|
|
33
18
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
19
|
+
* Terminal migrate failures (404 refunded/unknown, 409 already migrated).
|
|
20
|
+
* The queue-busy 409 is surfaced separately as ProveQueueBusyError so
|
|
21
|
+
* callers can share one retry helper across buy/renew/migrate.
|
|
36
22
|
*/
|
|
37
23
|
export declare class ProveMigrateError extends Error {
|
|
38
24
|
readonly status: number;
|
|
39
|
-
|
|
40
|
-
constructor(message: string, status: number, retryAfterMs?: number);
|
|
25
|
+
constructor(message: string, status: number);
|
|
41
26
|
}
|
|
42
27
|
export declare function proveMigrate(req: ProveMigrateRequest): Promise<ProveMigrateResponse>;
|
|
43
28
|
//# sourceMappingURL=migrateClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrateClient.d.ts","sourceRoot":"","sources":["../src/migrateClient.ts"],"names":[],"mappings":"AAwBA,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAK,MAAM,CAAC;IACrB,OAAO,EAAO,QAAQ,GAAG,SAAS,CAAC;IACnC,WAAW,EAAG,MAAM,CAAC;IACrB,KAAK,EAAS,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAM,OAAO,KAAK,CAAC;IAC3B,MAAM,CAAC,EAAO,WAAW,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAG,MAAM,CAAC;IACrB,UAAU,EAAI,MAAM,CAAC;IACrB,WAAW,EAAG,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IAGrB,MAAM,EAAQ,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBACZ,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAK5C;AAMD,wBAAsB,YAAY,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAoB1F"}
|
package/build/migrateClient.js
CHANGED
|
@@ -1,17 +1,35 @@
|
|
|
1
1
|
// Copyright (c) 2025-2026 zkLicensing project developers
|
|
2
|
-
//
|
|
2
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* migrateClient.ts
|
|
5
|
+
*
|
|
6
|
+
* Browser-safe client for /prove/migrate. Assembles a single-hop cross-
|
|
7
|
+
* generation proof against the current live map — the keeper walks the
|
|
8
|
+
* deploymentHistory once, gathers all three witnesses (ancestor / pred /
|
|
9
|
+
* live-empty), and returns a signable tx.
|
|
10
|
+
*
|
|
11
|
+
* Failure surfaces:
|
|
12
|
+
* - 404 "license refunded or unknown": no leaf anywhere in history for
|
|
13
|
+
* this licenseHash. Caller should not retry — it's terminal.
|
|
14
|
+
* - 409 "already migrated": leaf is present in the live map. Caller
|
|
15
|
+
* should refresh their license record and stop.
|
|
16
|
+
* - 409 "proving queue busy": another root-mutating request (buy, renew,
|
|
17
|
+
* migrate) is holding this app's in-flight slot. Thrown as the shared
|
|
18
|
+
* ProveQueueBusyError so callers can wait+retry uniformly across the
|
|
19
|
+
* three endpoints.
|
|
20
|
+
*/
|
|
21
|
+
import { readErrorBody, tryQueueBusyFromBody } from './proveErrors.js';
|
|
22
|
+
/**
|
|
23
|
+
* Terminal migrate failures (404 refunded/unknown, 409 already migrated).
|
|
24
|
+
* The queue-busy 409 is surfaced separately as ProveQueueBusyError so
|
|
25
|
+
* callers can share one retry helper across buy/renew/migrate.
|
|
6
26
|
*/
|
|
7
27
|
export class ProveMigrateError extends Error {
|
|
8
28
|
status;
|
|
9
|
-
|
|
10
|
-
constructor(message, status, retryAfterMs) {
|
|
29
|
+
constructor(message, status) {
|
|
11
30
|
super(message);
|
|
12
31
|
this.name = 'ProveMigrateError';
|
|
13
32
|
this.status = status;
|
|
14
|
-
this.retryAfterMs = retryAfterMs;
|
|
15
33
|
}
|
|
16
34
|
}
|
|
17
35
|
function baseUrl(url) {
|
|
@@ -24,23 +42,18 @@ export async function proveMigrate(req) {
|
|
|
24
42
|
headers: { 'Content-Type': 'application/json' },
|
|
25
43
|
signal: req.signal,
|
|
26
44
|
body: JSON.stringify({
|
|
45
|
+
network: req.network,
|
|
27
46
|
licenseHash: req.licenseHash,
|
|
28
47
|
appId: req.appId,
|
|
29
48
|
buyerAddress: req.buyerAddress,
|
|
30
49
|
}),
|
|
31
50
|
});
|
|
32
51
|
if (!resp.ok) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
msg = body.error;
|
|
39
|
-
if (typeof body.retryAfterMs === 'number')
|
|
40
|
-
retryAfterMs = body.retryAfterMs;
|
|
41
|
-
}
|
|
42
|
-
catch { /* body wasn't JSON */ }
|
|
43
|
-
throw new ProveMigrateError(msg, resp.status, retryAfterMs);
|
|
52
|
+
const parsed = await readErrorBody(resp);
|
|
53
|
+
const queueBusy = tryQueueBusyFromBody(parsed);
|
|
54
|
+
if (queueBusy)
|
|
55
|
+
throw queueBusy;
|
|
56
|
+
throw new ProveMigrateError(parsed.message, resp.status);
|
|
44
57
|
}
|
|
45
58
|
return await resp.json();
|
|
46
59
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrateClient.js","sourceRoot":"","sources":["../src/migrateClient.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,oCAAoC;AAEpC;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAuBvE;;;;GAIG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IACjC,MAAM,CAAS;IACxB,YAAY,OAAe,EAAE,MAAc;QACzC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAwB;IACzD,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,KAAK,CAAC;IACrC,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,gBAAgB,EAAE;QACpE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,OAAO,EAAO,GAAG,CAAC,OAAO;YACzB,WAAW,EAAG,GAAG,CAAC,WAAW;YAC7B,KAAK,EAAS,GAAG,CAAC,KAAK;YACvB,YAAY,EAAE,GAAG,CAAC,YAAY;SAC/B,CAAC;KACH,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,SAAS,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,SAAS;YAAE,MAAM,SAAS,CAAC;QAC/B,MAAM,IAAI,iBAAiB,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,MAAM,IAAI,CAAC,IAAI,EAA0B,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* onChainRoot.ts
|
|
3
|
+
*
|
|
4
|
+
* Non-custodial trust anchor for `verifyOffline`. Reads the live
|
|
5
|
+
* `licensesRoot` (`zkapp.appState[0]`) directly from Mina — no
|
|
6
|
+
* licensing-service round-trip, no trust assumption about whoever
|
|
7
|
+
* served the witness / license record.
|
|
8
|
+
*
|
|
9
|
+
* Pair it with `verifyOffline` to close the trust loop:
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { fetchOnChainLicensesRoot } from 'zklicensing/on-chain-root';
|
|
13
|
+
* import { verifyOffline } from 'zklicensing/verify-offline';
|
|
14
|
+
*
|
|
15
|
+
* // 1. Ask the licensing service for a witness + slot snapshot.
|
|
16
|
+
* const snap = await fetch(`${service}/witness?licenseHash=${h}&zkAppAddress=${a}`).then(r => r.json());
|
|
17
|
+
*
|
|
18
|
+
* // 2. Fetch the on-chain root INDEPENDENTLY, from Mina.
|
|
19
|
+
* const onChainRoot = await fetchOnChainLicensesRoot({ zkAppAddress: a, network: 'devnet' });
|
|
20
|
+
*
|
|
21
|
+
* // 3. Cross-check — if they disagree, the service is stale/wrong; bail.
|
|
22
|
+
* if (snap.root !== onChainRoot) throw new Error('service root disagrees with chain');
|
|
23
|
+
*
|
|
24
|
+
* // 4. Fold-verify the snapshot against the on-chain root.
|
|
25
|
+
* const res = verifyOffline({ licensesRoot: onChainRoot, ...snap });
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* o1js is a peer dep — this file imports it dynamically so callers
|
|
29
|
+
* that only want `verifyOffline` (pure fold, no chain read) don't
|
|
30
|
+
* have to install o1js.
|
|
31
|
+
*
|
|
32
|
+
* Global-state caveat: o1js `Mina.setActiveInstance` mutates a module-
|
|
33
|
+
* scoped singleton. Long-lived hosts that talk to multiple Mina
|
|
34
|
+
* networks in the same process should treat this helper as a
|
|
35
|
+
* one-shot and re-set their own preferred network after use, or wrap
|
|
36
|
+
* it in a mutex.
|
|
37
|
+
*/
|
|
38
|
+
export declare const DEFAULT_MINA_GRAPHQL_URLS: {
|
|
39
|
+
readonly mainnet: "https://api.minascan.io/node/mainnet/v1/graphql";
|
|
40
|
+
readonly devnet: "https://api.minascan.io/node/devnet/v1/graphql";
|
|
41
|
+
};
|
|
42
|
+
export type NetworkName = 'mainnet' | 'devnet';
|
|
43
|
+
export type FetchOnChainLicensesRootInput = {
|
|
44
|
+
/** B62q… address of the deployed LicensingApp for this app. */
|
|
45
|
+
zkAppAddress: string;
|
|
46
|
+
} & ({
|
|
47
|
+
network: NetworkName;
|
|
48
|
+
graphqlUrl?: string;
|
|
49
|
+
} | {
|
|
50
|
+
graphqlUrl: string;
|
|
51
|
+
network?: NetworkName;
|
|
52
|
+
});
|
|
53
|
+
/**
|
|
54
|
+
* Read the live `licensesRoot` from the deployed LicensingApp's
|
|
55
|
+
* on-chain state. Returns the field value as a decimal string,
|
|
56
|
+
* matching the shape `verifyOffline` and the licensing service both
|
|
57
|
+
* consume.
|
|
58
|
+
*
|
|
59
|
+
* Throws on any of:
|
|
60
|
+
* - `o1js` not installed (peer dep missing);
|
|
61
|
+
* - `fetchAccount` returned an error (network down, wrong endpoint,
|
|
62
|
+
* account doesn't exist on this chain);
|
|
63
|
+
* - account exists but has no zkApp state (not a zkApp address, or
|
|
64
|
+
* contract deployed but `initialize()` never ran).
|
|
65
|
+
*/
|
|
66
|
+
export declare function fetchOnChainLicensesRoot(input: FetchOnChainLicensesRootInput): Promise<string>;
|
|
67
|
+
//# sourceMappingURL=onChainRoot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onChainRoot.d.ts","sourceRoot":"","sources":["../src/onChainRoot.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAKH,eAAO,MAAM,yBAAyB;;;CAG5B,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE/C,MAAM,MAAM,6BAA6B,GAAG;IAC1C,+DAA+D;IAC/D,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,CACA;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,WAAW,CAAA;CAAE,CAChD,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,6BAA6B,GACnC,OAAO,CAAC,MAAM,CAAC,CAgCjB"}
|