zklicensing 0.1.0-beta.2 → 0.1.0-beta.21
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 +417 -201
- package/build/agent.d.ts +371 -0
- package/build/agent.d.ts.map +1 -0
- package/build/agent.js +553 -0
- package/build/agent.js.map +1 -0
- package/build/agentActions.d.ts +841 -0
- package/build/agentActions.d.ts.map +1 -0
- package/build/agentActions.js +581 -0
- package/build/agentActions.js.map +1 -0
- package/build/agentRecord.d.ts +83 -0
- package/build/agentRecord.d.ts.map +1 -0
- package/build/agentRecord.js +69 -0
- package/build/agentRecord.js.map +1 -0
- package/build/agentVendor.d.ts +220 -0
- package/build/agentVendor.d.ts.map +1 -0
- package/build/agentVendor.js +306 -0
- package/build/agentVendor.js.map +1 -0
- 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 +31 -5
- package/build/archiveBootstrap.d.ts.map +1 -0
- package/build/archiveBootstrap.js +140 -47
- package/build/archiveBootstrap.js.map +1 -0
- package/build/atomicJson.d.ts +5 -0
- package/build/atomicJson.d.ts.map +1 -0
- package/build/atomicJson.js +55 -0
- package/build/atomicJson.js.map +1 -0
- package/build/bindClient.d.ts +85 -0
- package/build/bindClient.d.ts.map +1 -0
- package/build/bindClient.js +187 -0
- package/build/bindClient.js.map +1 -0
- package/build/buyClient.d.ts +27 -4
- package/build/buyClient.d.ts.map +1 -0
- package/build/buyClient.js +72 -26
- package/build/buyClient.js.map +1 -0
- package/build/chainHead.d.ts +61 -0
- package/build/chainHead.d.ts.map +1 -0
- package/build/chainHead.js +88 -0
- package/build/chainHead.js.map +1 -0
- package/build/compactMerkleMap.d.ts +72 -0
- package/build/compactMerkleMap.d.ts.map +1 -0
- package/build/compactMerkleMap.js +224 -0
- package/build/compactMerkleMap.js.map +1 -0
- package/build/contractInterface.d.ts +191 -51
- package/build/contractInterface.d.ts.map +1 -0
- package/build/contractInterface.js +234 -43
- package/build/contractInterface.js.map +1 -0
- package/build/contractTypes.d.ts +9 -0
- package/build/contractTypes.d.ts.map +1 -0
- package/build/contractTypes.js +28 -0
- package/build/contractTypes.js.map +1 -0
- package/build/countryStats.d.ts +12 -3
- package/build/countryStats.d.ts.map +1 -0
- package/build/countryStats.js +87 -23
- package/build/countryStats.js.map +1 -0
- package/build/deployClient.d.ts +138 -24
- package/build/deployClient.d.ts.map +1 -0
- package/build/deployClient.js +91 -31
- 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 +26 -6
- package/build/freezeClient.d.ts.map +1 -0
- package/build/freezeClient.js +30 -6
- package/build/freezeClient.js.map +1 -0
- package/build/generationClient.d.ts +6 -3
- package/build/generationClient.d.ts.map +1 -0
- package/build/generationClient.js +25 -38
- package/build/generationClient.js.map +1 -0
- package/build/holderSecret.d.ts +70 -0
- package/build/holderSecret.d.ts.map +1 -0
- package/build/holderSecret.js +76 -0
- package/build/holderSecret.js.map +1 -0
- package/build/index.d.ts +38 -38
- package/build/index.d.ts.map +1 -0
- package/build/index.js +97 -121
- package/build/index.js.map +1 -0
- package/build/keysClient.d.ts +142 -0
- package/build/keysClient.d.ts.map +1 -0
- package/build/keysClient.js +109 -0
- package/build/keysClient.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 +68 -5
- package/build/licenseRecord.d.ts.map +1 -0
- package/build/licenseRecord.js +26 -1
- package/build/licenseRecord.js.map +1 -0
- package/build/licenseStore.d.ts +81 -4
- package/build/licenseStore.d.ts.map +1 -0
- package/build/licenseStore.js +400 -30
- package/build/licenseStore.js.map +1 -0
- package/build/licenseTrustless.d.ts +43 -0
- package/build/licenseTrustless.d.ts.map +1 -0
- package/build/licenseTrustless.js +180 -0
- package/build/licenseTrustless.js.map +1 -0
- package/build/manifestVerify.d.ts +29 -1
- package/build/manifestVerify.d.ts.map +1 -0
- package/build/manifestVerify.js +46 -4
- package/build/manifestVerify.js.map +1 -0
- package/build/minaPriceHistory.d.ts +9 -0
- package/build/minaPriceHistory.d.ts.map +1 -0
- package/build/minaPriceHistory.js +152 -0
- package/build/minaPriceHistory.js.map +1 -0
- package/build/onChainRoot.d.ts +60 -0
- package/build/onChainRoot.d.ts.map +1 -0
- package/build/onChainRoot.js +74 -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 +153 -0
- package/build/ownershipSignature.d.ts.map +1 -0
- package/build/ownershipSignature.js +297 -0
- package/build/ownershipSignature.js.map +1 -0
- package/build/permitCheckFlow.d.ts +155 -0
- package/build/permitCheckFlow.d.ts.map +1 -0
- package/build/permitCheckFlow.js +196 -0
- package/build/permitCheckFlow.js.map +1 -0
- package/build/permitDescribe.d.ts +124 -0
- package/build/permitDescribe.d.ts.map +1 -0
- package/build/permitDescribe.js +324 -0
- package/build/permitDescribe.js.map +1 -0
- package/build/permitInterface.d.ts +85 -0
- package/build/permitInterface.d.ts.map +1 -0
- package/build/permitInterface.js +121 -0
- package/build/permitInterface.js.map +1 -0
- package/build/permitMessages.d.ts +313 -0
- package/build/permitMessages.d.ts.map +1 -0
- package/build/permitMessages.js +462 -0
- package/build/permitMessages.js.map +1 -0
- package/build/permitProof.d.ts +108 -0
- package/build/permitProof.d.ts.map +1 -0
- package/build/permitProof.js +202 -0
- package/build/permitProof.js.map +1 -0
- package/build/permitRegistryRebuild.d.ts +166 -0
- package/build/permitRegistryRebuild.d.ts.map +1 -0
- package/build/permitRegistryRebuild.js +347 -0
- package/build/permitRegistryRebuild.js.map +1 -0
- package/build/permitTree.d.ts +88 -0
- package/build/permitTree.d.ts.map +1 -0
- package/build/permitTree.js +230 -0
- package/build/permitTree.js.map +1 -0
- package/build/permitsClient.d.ts +680 -0
- package/build/permitsClient.d.ts.map +1 -0
- package/build/permitsClient.js +597 -0
- package/build/permitsClient.js.map +1 -0
- package/build/proveErrors.d.ts +50 -0
- package/build/proveErrors.d.ts.map +1 -0
- package/build/proveErrors.js +76 -0
- package/build/proveErrors.js.map +1 -0
- package/build/receipt.d.ts +95 -0
- package/build/receipt.d.ts.map +1 -0
- package/build/receipt.js +84 -0
- package/build/receipt.js.map +1 -0
- package/build/refundClient.d.ts +7 -12
- package/build/refundClient.d.ts.map +1 -0
- package/build/refundClient.js +52 -21
- package/build/refundClient.js.map +1 -0
- package/build/registryTrustVerify.d.ts +78 -0
- package/build/registryTrustVerify.d.ts.map +1 -0
- package/build/registryTrustVerify.js +129 -0
- package/build/registryTrustVerify.js.map +1 -0
- package/build/releaseClient.d.ts +26 -0
- package/build/releaseClient.d.ts.map +1 -0
- package/build/releaseClient.js +65 -0
- package/build/releaseClient.js.map +1 -0
- package/build/renewClient.d.ts +28 -2
- package/build/renewClient.d.ts.map +1 -0
- package/build/renewClient.js +31 -27
- 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/slotConstants.d.ts +15 -0
- package/build/slotConstants.d.ts.map +1 -0
- package/build/slotConstants.js +17 -0
- package/build/slotConstants.js.map +1 -0
- package/build/statsClient.d.ts +61 -7
- package/build/statsClient.d.ts.map +1 -0
- package/build/statsClient.js +44 -5
- package/build/statsClient.js.map +1 -0
- package/build/successorChain.d.ts +35 -0
- package/build/successorChain.d.ts.map +1 -0
- package/build/successorChain.js +69 -0
- package/build/successorChain.js.map +1 -0
- package/build/taxId.d.ts +44 -0
- package/build/taxId.d.ts.map +1 -0
- package/build/taxId.js +212 -0
- package/build/taxId.js.map +1 -0
- package/build/trustAnchorVerify.d.ts +49 -0
- package/build/trustAnchorVerify.d.ts.map +1 -0
- package/build/trustAnchorVerify.js +432 -0
- package/build/trustAnchorVerify.js.map +1 -0
- package/build/trustAnchorVerifyCli.d.ts +45 -0
- package/build/trustAnchorVerifyCli.d.ts.map +1 -0
- package/build/trustAnchorVerifyCli.js +235 -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 +77 -0
- package/build/unbindClient.d.ts.map +1 -0
- package/build/unbindClient.js +169 -0
- package/build/unbindClient.js.map +1 -0
- package/build/units.d.ts +28 -0
- package/build/units.d.ts.map +1 -0
- package/build/units.js +65 -0
- package/build/units.js.map +1 -0
- package/build/vatRates.d.ts +54 -0
- package/build/vatRates.d.ts.map +1 -0
- package/build/vatRates.js +82 -0
- package/build/vatRates.js.map +1 -0
- package/build/vatRatesData.d.ts +5 -0
- package/build/vatRatesData.d.ts.map +1 -0
- package/build/vatRatesData.js +42 -0
- package/build/vatRatesData.js.map +1 -0
- package/build/vendorAccountClient.d.ts +66 -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 +4 -1
- package/build/verifyCore.d.ts.map +1 -0
- package/build/verifyCore.js +21 -10
- 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 +571 -501
- package/build/verifyService.js.map +1 -0
- package/build/verifyWithAncestors.d.ts +19 -0
- package/build/verifyWithAncestors.d.ts.map +1 -0
- package/build/verifyWithAncestors.js +127 -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 +141 -16
- package/src/agent.ts +682 -0
- package/src/agentActions.ts +637 -0
- package/src/agentRecord.ts +121 -0
- package/src/agentVendor.ts +356 -0
- package/src/appsLookup.ts +48 -0
- package/src/archiveBootstrap.ts +386 -0
- package/src/atomicJson.ts +53 -0
- package/src/bindClient.ts +297 -0
- package/src/buyClient.ts +344 -0
- package/src/chainHead.ts +106 -0
- package/src/compactMerkleMap.ts +222 -0
- package/src/contractInterface.ts +465 -0
- package/src/contractTypes.ts +31 -0
- package/src/countryStats.ts +200 -0
- package/src/deployClient.ts +517 -0
- package/src/deviceIdentity.ts +249 -0
- package/src/freezeClient.ts +162 -0
- package/src/generationClient.ts +145 -0
- package/src/holderSecret.ts +91 -0
- package/src/index.ts +362 -0
- package/src/keysClient.ts +135 -0
- package/src/licenseLeaf.ts +221 -0
- package/src/licenseRecord.ts +190 -0
- package/src/licenseStore.ts +767 -0
- package/src/licenseTrustless.ts +207 -0
- package/src/manifestVerify.ts +164 -0
- package/src/minaPriceHistory.ts +166 -0
- package/src/onChainRoot.ts +90 -0
- package/src/ownershipLicenseHash.ts +31 -0
- package/src/ownershipSignature.ts +421 -0
- package/src/permitCheckFlow.ts +227 -0
- package/src/permitDescribe.ts +362 -0
- package/src/permitInterface.ts +146 -0
- package/src/permitMessages.ts +572 -0
- package/src/permitProof.ts +230 -0
- package/src/permitRegistryRebuild.ts +423 -0
- package/src/permitTree.ts +232 -0
- package/src/permitsClient.ts +746 -0
- package/src/proveErrors.ts +98 -0
- package/src/receipt.ts +156 -0
- package/src/refundClient.ts +177 -0
- package/src/registryTrustVerify.ts +192 -0
- package/src/releaseClient.ts +101 -0
- package/src/renewClient.ts +234 -0
- package/src/seatName.ts +165 -0
- package/src/slotConstants.ts +18 -0
- package/src/statsClient.ts +249 -0
- package/src/successorChain.ts +87 -0
- package/src/taxId.ts +227 -0
- package/src/trustAnchorVerify.ts +550 -0
- package/src/trustAnchorVerifyCli.ts +234 -0
- package/src/txBroadcastClient.ts +48 -0
- package/src/unbindClient.ts +233 -0
- package/src/units.ts +74 -0
- package/src/vatRates.ts +100 -0
- package/src/vatRatesData.ts +43 -0
- package/src/vendorAccountClient.ts +120 -0
- package/src/verifyCore.ts +100 -0
- package/src/verifyOffline.ts +212 -0
- package/src/verifyService.ts +982 -0
- package/src/verifyWithAncestors.ts +163 -0
- package/src/zipToState.ts +94 -0
- package/build/licenseProof.d.ts +0 -26
- package/build/licenseProof.js +0 -41
- package/build/migrateClient.d.ts +0 -43
- package/build/migrateClient.js +0 -47
- package/build/ownership.d.ts +0 -34
- package/build/ownership.js +0 -147
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permitsClient.d.ts","sourceRoot":"","sources":["../src/permitsClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,597 @@
|
|
|
1
|
+
// Copyright (c) 2025-2026 zkLicensing project developers
|
|
2
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
3
|
+
/**
|
|
4
|
+
* permitsClient.ts — `zklicensing/permits/client`
|
|
5
|
+
*
|
|
6
|
+
* Client for the keeper's /permits API: authority onboarding and registry
|
|
7
|
+
* deployment, signing requests, applications and decisions, grants,
|
|
8
|
+
* renewals, status changes, fees, key rotation, surrender and verification.
|
|
9
|
+
*
|
|
10
|
+
* Signing goes through a `PermitWallet`: in a browser, an adapter over Auro
|
|
11
|
+
* or WalletConnect; in scripts and agents, `minaSignerWallet` with a key the
|
|
12
|
+
* owner gave it. The keeper never sees a private key.
|
|
13
|
+
*
|
|
14
|
+
* `verifyPermitTrustless` checks a permit without trusting the keeper: the
|
|
15
|
+
* registry root comes straight from a Mina node and the keeper's witness
|
|
16
|
+
* must fold to it.
|
|
17
|
+
*/
|
|
18
|
+
import { Field, PublicKey, UInt64 } from 'o1js';
|
|
19
|
+
import { acceptMessage, applyMessage, authorityMoveText, networkField, permitLeafHash, surrenderMessage, toSignableFields, withdrawMessage } from './permitMessages.js';
|
|
20
|
+
import { recordToApplication, recordToLeaf, permitStatusAt } from './permitRegistryRebuild.js';
|
|
21
|
+
export class PermitsError extends Error {
|
|
22
|
+
status;
|
|
23
|
+
code;
|
|
24
|
+
retryable;
|
|
25
|
+
body;
|
|
26
|
+
constructor(message, status, code, retryable, body = null) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.status = status;
|
|
29
|
+
this.code = code;
|
|
30
|
+
this.retryable = retryable;
|
|
31
|
+
this.body = body;
|
|
32
|
+
this.name = 'PermitsError';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Canonical texts — the keeper derives the same strings.
|
|
36
|
+
/** The sign-in text: names the site and network (the keeper's challenge
|
|
37
|
+
* supplies both), so a sign-in for devnet never works on mainnet. */
|
|
38
|
+
export function sessionMessage(address, nonce, issuedAt, network, site) {
|
|
39
|
+
return ['zkLicensing session', `site: ${site}`, `network: ${network}`, `wallet: ${address}`, `nonce: ${nonce}`, `issuedAt: ${issuedAt}`].join('\n');
|
|
40
|
+
}
|
|
41
|
+
export function authorityAcceptanceMessage(f) {
|
|
42
|
+
return [
|
|
43
|
+
'zkLicensing Authority Terms acceptance',
|
|
44
|
+
`address: ${f.address}`,
|
|
45
|
+
`legalName: ${f.legalName}`,
|
|
46
|
+
`country: ${f.country}`,
|
|
47
|
+
`terms: ${f.termsVersion} ${f.termsHash}`,
|
|
48
|
+
`acceptedAt: ${f.acceptedAt}`,
|
|
49
|
+
].join('\n');
|
|
50
|
+
}
|
|
51
|
+
export function createPermitsClient(opts) {
|
|
52
|
+
const base = opts.keeperUrl.replace(/\/+$/, '');
|
|
53
|
+
const fetcher = opts.fetcher ?? fetch;
|
|
54
|
+
let session = null;
|
|
55
|
+
function wallet() {
|
|
56
|
+
if (!opts.wallet)
|
|
57
|
+
throw new PermitsError('This action needs a wallet', 0, 'INVALID_REQUEST', false);
|
|
58
|
+
return opts.wallet;
|
|
59
|
+
}
|
|
60
|
+
async function call(method, path, body, auth = false) {
|
|
61
|
+
const headers = { Accept: 'application/json' };
|
|
62
|
+
if (body !== undefined)
|
|
63
|
+
headers['Content-Type'] = 'application/json';
|
|
64
|
+
if (auth)
|
|
65
|
+
headers.Authorization = `VendorSession ${await token()}`;
|
|
66
|
+
let resp;
|
|
67
|
+
try {
|
|
68
|
+
resp = await fetcher(base + path, { method, headers, ...(body !== undefined ? { body: JSON.stringify(body) } : {}) });
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
throw new PermitsError(`Keeper unreachable: ${e?.message ?? e}`, 0, 'UPSTREAM_UNAVAILABLE', true);
|
|
72
|
+
}
|
|
73
|
+
const json = await resp.json().catch(() => null);
|
|
74
|
+
if (!resp.ok) {
|
|
75
|
+
if (resp.status === 401 && auth)
|
|
76
|
+
session = null;
|
|
77
|
+
throw new PermitsError(json?.error ?? `HTTP ${resp.status}`, resp.status, json?.code ?? (resp.status >= 500 ? 'UPSTREAM_UNAVAILABLE' : 'INVALID_REQUEST'), json?.retryable ?? resp.status >= 500, json);
|
|
78
|
+
}
|
|
79
|
+
return json;
|
|
80
|
+
}
|
|
81
|
+
/** Wallet sign-in (the keeper's existing session flow); cached until expiry. */
|
|
82
|
+
async function token() {
|
|
83
|
+
const w = wallet();
|
|
84
|
+
if (session && session.address === w.address && session.expiresAt - 60_000 > Date.now())
|
|
85
|
+
return session.token;
|
|
86
|
+
const chal = await call('POST', `/vendors/${encodeURIComponent(w.address)}/session/challenge`, { network: opts.network });
|
|
87
|
+
if (chal.network !== opts.network) {
|
|
88
|
+
throw new PermitsError(`Keeper issued a sign-in for ${chal.network}, expected ${opts.network}`, 0, 'INVALID_REQUEST', false);
|
|
89
|
+
}
|
|
90
|
+
const message = sessionMessage(w.address, chal.nonce, chal.issuedAt, chal.network, chal.site);
|
|
91
|
+
const signature = await w.signMessage(message);
|
|
92
|
+
const r = await call('POST', `/vendors/${encodeURIComponent(w.address)}/session/verify`, {
|
|
93
|
+
nonce: chal.nonce, signature, signedMessage: message, network: opts.network,
|
|
94
|
+
});
|
|
95
|
+
session = { token: r.token, expiresAt: Date.parse(r.expiresAt), address: w.address };
|
|
96
|
+
return r.token;
|
|
97
|
+
}
|
|
98
|
+
/** Describes, refuses a mismatch, and asks the confirmSignature hook. */
|
|
99
|
+
async function confirm(describe, registry) {
|
|
100
|
+
const ctx = opts.describeContext ? await opts.describeContext(registry) : {};
|
|
101
|
+
const d = describe(ctx);
|
|
102
|
+
if (!d.verified)
|
|
103
|
+
throw new PermitsError(`Refusing to sign: ${d.problem ?? 'the message could not be checked'}`, 0, 'SIGNATURE_INVALID', false, d);
|
|
104
|
+
if (opts.confirmSignature && (await opts.confirmSignature(d)) === false)
|
|
105
|
+
throw new PermitsError('Cancelled', 0, 'CANCELLED', false);
|
|
106
|
+
}
|
|
107
|
+
/** The registry's lineage from the keeper (a wrong one only fails the holder's own derivation). */
|
|
108
|
+
async function registryLineage(address) {
|
|
109
|
+
const r = await call('GET', `/permits/registries/${address}`);
|
|
110
|
+
return r.registry.lineage ?? address;
|
|
111
|
+
}
|
|
112
|
+
const client = {
|
|
113
|
+
network: opts.network,
|
|
114
|
+
signIn: token,
|
|
115
|
+
// ── reading ─────────────────────────────────────────────────────────────
|
|
116
|
+
listRegistries: () => call('GET', `/permits/registries?network=${opts.network}`),
|
|
117
|
+
getRegistry: (address) => call('GET', `/permits/registries/${address}`),
|
|
118
|
+
/** The registry's lineage (its first generation's address), which holder secrets are derived against. */
|
|
119
|
+
registryLineage: (address) => registryLineage(address),
|
|
120
|
+
/**
|
|
121
|
+
* A permit with a witness against its registry's root. Asked through an
|
|
122
|
+
* earlier generation's address, it comes from the current one
|
|
123
|
+
* (`registry`, `generation`), which starts with every permit of the one it
|
|
124
|
+
* replaced.
|
|
125
|
+
*/
|
|
126
|
+
getPermit: (registry, subject) => call('GET', `/permits/registries/${registry}/permits/${subject}`),
|
|
127
|
+
/** A registry's generations and release, and any redeploy under way (no events needed). */
|
|
128
|
+
getDeployment: (registry) => call('GET', `/permits/registries/${registry}/deployment`),
|
|
129
|
+
verifyPermit: (registry, subject, scope) => call('GET', `/permits/verify?registry=${registry}&subject=${subject}${scope !== undefined ? `&scope=${scope}` : ''}`),
|
|
130
|
+
getRequest: (id, asSelf = false) => call('GET', `/permits/requests/${id}`, undefined, asSelf),
|
|
131
|
+
// ── authority ───────────────────────────────────────────────────────────
|
|
132
|
+
/** `agentConsent`: the owner's standing consent when an AI agent's key accepts for them. */
|
|
133
|
+
async acceptAuthorityTerms(f) {
|
|
134
|
+
const w = wallet();
|
|
135
|
+
const acceptedAt = new Date().toISOString();
|
|
136
|
+
const signedMessage = authorityAcceptanceMessage({ address: w.address, legalName: f.legalName, country: f.country, termsVersion: f.termsVersion, termsHash: f.termsHash, acceptedAt });
|
|
137
|
+
const signature = await w.signMessage(signedMessage);
|
|
138
|
+
return call('POST', '/permits/authorities/accept', { ...f, address: w.address, acceptedAt, signedMessage, signature, network: opts.network });
|
|
139
|
+
},
|
|
140
|
+
/**
|
|
141
|
+
* The platform's monthly fee statement for this wallet's registries
|
|
142
|
+
* (`month` YYYY-MM): its share of each permit fee, in euros, with VAT as
|
|
143
|
+
* the authority's details require. null when nothing to show.
|
|
144
|
+
*/
|
|
145
|
+
/**
|
|
146
|
+
* What forced retirements left in escrow on this wallet's registries
|
|
147
|
+
* (Authority Terms §8.4): per registry, the applications whose fees stay
|
|
148
|
+
* there, their payers and the total.
|
|
149
|
+
*/
|
|
150
|
+
authorityStranded: () => call('GET', `/permits/authorities/${wallet().address}/stranded`, undefined, true),
|
|
151
|
+
authorityFeeStatement: (month) => call('GET', `/permits/authorities/${wallet().address}/fee-statements?network=${opts.network}&month=${encodeURIComponent(month)}`, undefined, true).then(r => r.statement),
|
|
152
|
+
/**
|
|
153
|
+
* This wallet's receipts and credit notes for a license (zklicensing/receipt),
|
|
154
|
+
* purchase first; signs in with the wallet (a receipt shows the buyer's country).
|
|
155
|
+
*/
|
|
156
|
+
getLicenseReceipts: (zkAppAddress, licenseHash) => call('GET', `/receipts?network=${opts.network}&zkAppAddress=${encodeURIComponent(zkAppAddress)}&licenseHash=${encodeURIComponent(licenseHash)}`, undefined, true).then(r => r.receipts),
|
|
157
|
+
/** This wallet's receipt or credit note for one transaction (a license or a permit fee). */
|
|
158
|
+
getReceipt: (txHash) => call('GET', `/receipts/${encodeURIComponent(txHash)}?network=${opts.network}`, undefined, true).then(r => r.receipt),
|
|
159
|
+
/**
|
|
160
|
+
* This wallet as a holder: its applications, its permits (with their
|
|
161
|
+
* effective status; a redeployed registry's earlier permits are marked
|
|
162
|
+
* frozen) and renewals offered to it that wait for acceptGrant.
|
|
163
|
+
*/
|
|
164
|
+
getHolderOverview: () => call('GET', `/permits/holders/${wallet().address}?network=${opts.network}`, undefined, true),
|
|
165
|
+
/** This wallet's authority account (404 NOT_FOUND before the terms are accepted). */
|
|
166
|
+
getAuthority: () => call('GET', `/permits/authorities/${wallet().address}`, undefined, true),
|
|
167
|
+
/** Registries this wallet is an authority of, including drafts. */
|
|
168
|
+
listMyRegistries: () => call('GET', `/permits/authorities/${wallet().address}/registries`, undefined, true),
|
|
169
|
+
listRequests: (registry, status) => call('GET', `/permits/registries/${registry}/requests${status ? `?status=${status}` : ''}`, undefined, true),
|
|
170
|
+
createRegistry: (draft) => call('POST', '/permits/registries', { ...draft, network: opts.network }, true),
|
|
171
|
+
/**
|
|
172
|
+
* Changes a registry's public details (authority). On devnet they apply
|
|
173
|
+
* at once; on a listed mainnet registry they wait for the platform's
|
|
174
|
+
* review (`staged: true`). `scopeLabels` rewords the activities, one label
|
|
175
|
+
* each in order; the activities themselves can't change.
|
|
176
|
+
*/
|
|
177
|
+
updateRegistryListing: (registry, edit) => call('PUT', `/permits/registries/${registry}/listing`, edit, true),
|
|
178
|
+
/** Stops (false) or resumes (true) taking applications (authority); everything else carries on. */
|
|
179
|
+
setApplicationsOpen: (registry, open) => call('PUT', `/permits/registries/${registry}/applications-open`, { open }, true),
|
|
180
|
+
/** Withdraws a staged edit of a registry's public details (authority). */
|
|
181
|
+
withdrawRegistryEdit: (registry) => call('DELETE', `/permits/registries/${registry}/listing/pending`, undefined, true),
|
|
182
|
+
/** A registry's figures for its authority: permits and applications by status, fees by kind and month (nanomina). */
|
|
183
|
+
getRegistryStats: (registry) => call('GET', `/permits/registries/${registry}/stats`, undefined, true),
|
|
184
|
+
/** The registry's money events (authority), oldest first: `from`/`to` as YYYY-MM-DD, `to` exclusive. Amounts in nanomina. */
|
|
185
|
+
getRegistryTransactions: (registry, period = {}) => call('GET', `/permits/registries/${registry}/transactions${period.from || period.to ? `?${new URLSearchParams(Object.entries(period).filter(([, v]) => v))}` : ''}`, undefined, true),
|
|
186
|
+
/** Signs a request with this wallet's key and adds the signature at `slot`. */
|
|
187
|
+
async signRequest(requestId, slot) {
|
|
188
|
+
const w = wallet();
|
|
189
|
+
const { request } = await client.getRequest(requestId);
|
|
190
|
+
const s = slot ?? request.keys.indexOf(w.address);
|
|
191
|
+
if (s < 0)
|
|
192
|
+
throw new PermitsError('This wallet is not in the request\'s key set', 0, 'FORBIDDEN', false);
|
|
193
|
+
const { describeRequest } = await import('./permitDescribe.js');
|
|
194
|
+
const registryCfg = request.kind === 'init' ? (await client.getRegistry(request.registry)).registry : undefined;
|
|
195
|
+
await confirm(ctx => describeRequest(request, { ...ctx, ...(registryCfg ? { registry: registryCfg } : {}) }), request.registry);
|
|
196
|
+
const signature = await w.signFields(request.message);
|
|
197
|
+
return call('POST', `/permits/requests/${requestId}/signatures`, { slot: s, signature });
|
|
198
|
+
},
|
|
199
|
+
/**
|
|
200
|
+
* Starts a redeploy to the current release: a new registry (same
|
|
201
|
+
* configuration, next generation) and two requests for the keys to sign,
|
|
202
|
+
* `retireRequest` (freezes this registry's permits on chain) and `request`
|
|
203
|
+
* (deploys the new one). Send them in that order: executeRequest(retire),
|
|
204
|
+
* then deployRegistry(request). The new registry starts with every permit
|
|
205
|
+
* of this one, as it is when it retires. With fees in escrow
|
|
206
|
+
* (ESCROW_NOT_EMPTY) only the platform can start a redeploy: the registry
|
|
207
|
+
* then drains
|
|
208
|
+
* (`draining: true`): no new filings while the open ones are decided,
|
|
209
|
+
* withdrawn or reclaimed; call again once they are, to get the requests.
|
|
210
|
+
*/
|
|
211
|
+
redeployRegistry: (registry) => call('POST', `/permits/registries/${registry}/redeploy`, {}, true),
|
|
212
|
+
/** Calls off a redeploy whose retirement hasn't been sent. */
|
|
213
|
+
cancelRedeploy: (registry) => call('POST', `/permits/registries/${registry}/redeploy/cancel`, {}, true),
|
|
214
|
+
/** Proves the deployment, signs and pays with this wallet, and reports it. */
|
|
215
|
+
async deployRegistry(requestId) {
|
|
216
|
+
const w = wallet();
|
|
217
|
+
const { transaction, registry } = await call('POST', '/permits/prove/deploy', { requestId, feePayer: w.address });
|
|
218
|
+
const txHash = await w.signAndSendTransaction(transaction);
|
|
219
|
+
await call('POST', '/permits/confirm', { registry, requestId, txHash });
|
|
220
|
+
return { registry, txHash };
|
|
221
|
+
},
|
|
222
|
+
listApplications: (registry, status) => call('GET', `/permits/registries/${registry}/applications${status ? `?status=${status}` : ''}`, undefined, true),
|
|
223
|
+
/**
|
|
224
|
+
* Approves a filed application exactly as applied for (the permit is
|
|
225
|
+
* active once the request is signed and sent): a request for the
|
|
226
|
+
* authority keys to sign, then executeRequest. An unpaid one whose
|
|
227
|
+
* payment waits for a Mina upgrade is approved before payment (no
|
|
228
|
+
* request): the keeper raises the request once its fee is in escrow,
|
|
229
|
+
* and the applicant learns of it then.
|
|
230
|
+
*/
|
|
231
|
+
approveApplication: (id) => call('POST', `/permits/applications/${id}/decision`, { decision: 'approve' }, true),
|
|
232
|
+
/**
|
|
233
|
+
* Rejects a filed application: the processing fee is kept, the rest
|
|
234
|
+
* refunded once the request is signed and sent. An unpaid one whose
|
|
235
|
+
* payment waits for a Mina upgrade is rejected before payment (no
|
|
236
|
+
* request): the keeper raises the request once its fee is in escrow,
|
|
237
|
+
* and the applicant learns of it then. `reason` stays off chain.
|
|
238
|
+
*/
|
|
239
|
+
rejectApplication: (id, reason, reasonCode) => call('POST', `/permits/applications/${id}/decision`, { decision: 'reject', reason, reasonCode }, true),
|
|
240
|
+
requestRenewal: (registry, subject, change) => call('POST', `/permits/registries/${registry}/permits/${subject}/renewal`, change, true),
|
|
241
|
+
requestStatus: (registry, subject, action, reasonCode) => call('POST', `/permits/registries/${registry}/permits/${subject}/status`, { action, reasonCode }, true),
|
|
242
|
+
/** New fees; the processing fee (MINA) and decision window (slots) stay as they are unless given. */
|
|
243
|
+
requestFees: (registry, grantFeeMina, renewalFeeMina, applications) => call('POST', `/permits/registries/${registry}/fees`, { grantFeeMina, renewalFeeMina, ...applications }, true),
|
|
244
|
+
requestRotation: (registry, keys, threshold) => call('POST', `/permits/registries/${registry}/rotation`, { keys, threshold }, true),
|
|
245
|
+
/** Proves a fully signed non-grant request, signs and pays with this wallet, and reports it. */
|
|
246
|
+
async executeRequest(requestId) {
|
|
247
|
+
const w = wallet();
|
|
248
|
+
const { request } = await client.getRequest(requestId);
|
|
249
|
+
const { transaction } = await call('POST', '/permits/prove/request', { requestId, feePayer: w.address });
|
|
250
|
+
const txHash = await w.signAndSendTransaction(transaction);
|
|
251
|
+
await call('POST', '/permits/confirm', { registry: request.registry, requestId, txHash });
|
|
252
|
+
return { txHash };
|
|
253
|
+
},
|
|
254
|
+
// ── operator ────────────────────────────────────────────────────────────
|
|
255
|
+
/**
|
|
256
|
+
* Applies for a permit and pays the fee into escrow (`pay: false` only
|
|
257
|
+
* records the application; file it later with fileApplication). What is
|
|
258
|
+
* applied for is what an approval grants: activities (`scope`), dates and
|
|
259
|
+
* conditions document. Rejection or withdrawal keeps the registry's
|
|
260
|
+
* processing fee and refunds the rest to the payer; no decision by the
|
|
261
|
+
* deadline refunds it all.
|
|
262
|
+
*
|
|
263
|
+
* A new permit's secret for anonymous proofs (zklicensing/permits/holder-secret)
|
|
264
|
+
* is derived by the holder's wallet from a counter, the first not yet
|
|
265
|
+
* used by this key in the registry; only the salt (a hash of the secret)
|
|
266
|
+
* goes to the keeper. The wallet signs once per counter tried. When
|
|
267
|
+
* another key is the holder, derive with that key's wallet
|
|
268
|
+
* (deriveHolderSecret), pass `salt` and `pay: false`, and let the holder
|
|
269
|
+
* file it. To renew or change your active permit, pass its `subject`.
|
|
270
|
+
*/
|
|
271
|
+
async apply(registry, a) {
|
|
272
|
+
const w = wallet();
|
|
273
|
+
const { pay = true, payer, ...body } = a;
|
|
274
|
+
const holderKey = body.holderKey ?? w.address;
|
|
275
|
+
const create = async (extra) => {
|
|
276
|
+
const r = await call('POST', `/permits/registries/${registry}/applications`, { ...body, holderKey, ...extra }, true);
|
|
277
|
+
if (!pay)
|
|
278
|
+
return r;
|
|
279
|
+
try {
|
|
280
|
+
return { ...r, ...(await client.fileApplication(r.application.id, payer)) };
|
|
281
|
+
}
|
|
282
|
+
catch (e) {
|
|
283
|
+
// Ahead of a Mina upgrade the application is kept and paid afterwards, on the new registry.
|
|
284
|
+
if (e instanceof PermitsError && e.code === 'PAYMENT_AFTER_UPGRADE') {
|
|
285
|
+
const b = (e.body ?? {});
|
|
286
|
+
return { ...r, paymentPaused: { reason: b.reason ?? 'upgrade', forkActivationSlot: b.forkActivationSlot ?? null } };
|
|
287
|
+
}
|
|
288
|
+
throw e;
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
if (body.salt || body.subject)
|
|
292
|
+
return create({});
|
|
293
|
+
if (holderKey !== w.address)
|
|
294
|
+
throw new PermitsError('The holder key must derive the permit secret: pass salt from deriveHolderSecret with the holder\'s wallet', 0, 'INVALID_REQUEST', false);
|
|
295
|
+
const { deriveHolderSecret, MAX_HOLDER_SECRETS } = await import('./holderSecret.js');
|
|
296
|
+
const lineage = await registryLineage(registry);
|
|
297
|
+
for (let index = 0; index < MAX_HOLDER_SECRETS; index++) {
|
|
298
|
+
const d = await deriveHolderSecret(w, { lineage, network: opts.network, index });
|
|
299
|
+
const taken = await client.getPermit(registry, d.subject).then(r => !!r.permit, e => {
|
|
300
|
+
if (e instanceof PermitsError && e.status === 404)
|
|
301
|
+
return false;
|
|
302
|
+
throw e;
|
|
303
|
+
});
|
|
304
|
+
if (taken)
|
|
305
|
+
continue; // used by an earlier permit
|
|
306
|
+
try {
|
|
307
|
+
return await create({ salt: d.salt });
|
|
308
|
+
}
|
|
309
|
+
catch (e) {
|
|
310
|
+
if (e instanceof PermitsError && e.code === 'SALT_IN_USE')
|
|
311
|
+
continue; // a pending application has it
|
|
312
|
+
throw e;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
throw new PermitsError(`This key already has ${MAX_HOLDER_SECRETS} permits or applications in this registry; use another key`, 409, 'CONFLICT', false);
|
|
316
|
+
},
|
|
317
|
+
getApplication: (id) => call('GET', `/permits/applications/${id}`, undefined, true),
|
|
318
|
+
/**
|
|
319
|
+
* The holder signs what is applied for (with the registry's current fee
|
|
320
|
+
* and processing fee) and `payer` (default: this wallet) pays the fee
|
|
321
|
+
* into escrow. Returns the deadline slot for the authority's decision.
|
|
322
|
+
*/
|
|
323
|
+
async fileApplication(id, payer) {
|
|
324
|
+
const w = wallet();
|
|
325
|
+
const { application, apply } = await client.getApplication(id);
|
|
326
|
+
if (!apply)
|
|
327
|
+
throw new PermitsError(`Application is ${application.status}`, 409, 'CONFLICT', false);
|
|
328
|
+
if (application.holderKey !== w.address)
|
|
329
|
+
throw new PermitsError('This wallet is not the applicant holder', 0, 'FORBIDDEN', false);
|
|
330
|
+
const msg = toSignableFields(applyMessage({ network: networkField(opts.network), registry: PublicKey.fromBase58(application.registry), application: recordToApplication(apply.application) }));
|
|
331
|
+
if (msg.join() !== apply.message.join())
|
|
332
|
+
throw new PermitsError('Refusing to sign: the keeper\'s message does not match the application', 0, 'SIGNATURE_INVALID', false);
|
|
333
|
+
const { describeApply } = await import('./permitDescribe.js');
|
|
334
|
+
await confirm(ctx => describeApply({ network: opts.network, registry: application.registry, application: apply.application, fields: msg }, ctx), application.registry);
|
|
335
|
+
const holderSignature = await w.signFields(msg);
|
|
336
|
+
const p = payer ?? w;
|
|
337
|
+
const proved = await call('POST', '/permits/prove/apply', { applicationId: id, feePayer: p.address, holderSignature });
|
|
338
|
+
const txHash = await p.signAndSendTransaction(proved.transaction);
|
|
339
|
+
await call('POST', '/permits/confirm', { registry: application.registry, applicationId: id, txHash });
|
|
340
|
+
return { txHash, fee: proved.fee, processingFee: proved.processingFee, deadline: proved.deadline };
|
|
341
|
+
},
|
|
342
|
+
/**
|
|
343
|
+
* Withdraws an application. Unpaid: recorded off chain. Paid (filed),
|
|
344
|
+
* before the deadline: the holder signs, the processing fee is kept and
|
|
345
|
+
* the rest goes back to the payer; this wallet pays the transaction fee.
|
|
346
|
+
*/
|
|
347
|
+
async withdrawApplication(id) {
|
|
348
|
+
const w = wallet();
|
|
349
|
+
const { application, withdrawMessage: fields } = await client.getApplication(id);
|
|
350
|
+
if (application.status !== 'filed')
|
|
351
|
+
return call('POST', `/permits/applications/${id}/withdraw`, {}, true);
|
|
352
|
+
const escrow = application.escrow;
|
|
353
|
+
const msg = toSignableFields(withdrawMessage({ network: networkField(opts.network), registry: PublicKey.fromBase58(application.registry), application: recordToApplication(escrow) }));
|
|
354
|
+
if (!fields || msg.join() !== fields.join())
|
|
355
|
+
throw new PermitsError('Refusing to sign: the keeper\'s message does not match the application', 0, 'SIGNATURE_INVALID', false);
|
|
356
|
+
const { describeWithdraw } = await import('./permitDescribe.js');
|
|
357
|
+
await confirm(ctx => describeWithdraw({ network: opts.network, registry: application.registry, application: escrow, fields: msg }, ctx), application.registry);
|
|
358
|
+
const holderSignature = await w.signFields(msg);
|
|
359
|
+
const proved = await call('POST', '/permits/prove/withdraw', { applicationId: id, feePayer: w.address, holderSignature });
|
|
360
|
+
const txHash = await w.signAndSendTransaction(proved.transaction);
|
|
361
|
+
// The keeper issues the receipt for the kept processing fee (zklicensing/receipt).
|
|
362
|
+
const confirmed = await call('POST', '/permits/confirm', { registry: application.registry, applicationId: id, txHash });
|
|
363
|
+
return { application, txHash, kept: proved.kept, refunded: proved.refunded, ...(confirmed?.receipt ? { receipt: confirmed.receipt } : {}) };
|
|
364
|
+
},
|
|
365
|
+
/** After the deadline without a decision: returns the whole fee to the payer. Any wallet can send it (it pays the transaction fee). */
|
|
366
|
+
async reclaimApplication(id, sender) {
|
|
367
|
+
const p = sender ?? wallet();
|
|
368
|
+
const { application } = await client.getApplication(id);
|
|
369
|
+
const proved = await call('POST', '/permits/prove/reclaim', { applicationId: id, feePayer: p.address });
|
|
370
|
+
const txHash = await p.signAndSendTransaction(proved.transaction);
|
|
371
|
+
await call('POST', '/permits/confirm', { registry: application.registry, txHash });
|
|
372
|
+
return { txHash, refunded: proved.refunded, payer: proved.payer };
|
|
373
|
+
},
|
|
374
|
+
/**
|
|
375
|
+
* The holder accepts a signed grant: signs the exact permit and fee,
|
|
376
|
+
* then pays with `payer` (default: this wallet). The holder's wallet can
|
|
377
|
+
* re-derive the permit's secret for anonymous proofs at any time
|
|
378
|
+
* (findHolderSecret), from the chain alone.
|
|
379
|
+
*/
|
|
380
|
+
async acceptGrant(requestId, payer) {
|
|
381
|
+
const w = wallet();
|
|
382
|
+
const { request } = await client.getRequest(requestId, true);
|
|
383
|
+
if (!request.newLeaf || request.newLeaf.holderKey !== w.address)
|
|
384
|
+
throw new PermitsError('This wallet is not the permit holder', 0, 'FORBIDDEN', false);
|
|
385
|
+
const msg = acceptMessage({ network: networkField(opts.network), registry: PublicKey.fromBase58(request.registry), newLeaf: recordToLeaf(request.newLeaf), fee: UInt64.from(request.fee) });
|
|
386
|
+
const { describeAccept } = await import('./permitDescribe.js');
|
|
387
|
+
await confirm(ctx => describeAccept({ network: opts.network, registry: request.registry, newLeaf: request.newLeaf, fee: request.fee, fields: toSignableFields(msg) }, ctx), request.registry);
|
|
388
|
+
const holderSignature = await w.signFields(toSignableFields(msg));
|
|
389
|
+
const p = payer ?? w;
|
|
390
|
+
const proved = await call('POST', '/permits/prove/request', { requestId, feePayer: p.address, holderSignature });
|
|
391
|
+
const txHash = await p.signAndSendTransaction(proved.transaction);
|
|
392
|
+
// The keeper issues the holder's receipt (zklicensing/receipt): keep it with the permit file.
|
|
393
|
+
const confirmed = await call('POST', '/permits/confirm', { registry: request.registry, requestId, txHash });
|
|
394
|
+
return { txHash, subject: request.newLeaf.subject, fee: proved.fee, toAuthority: proved.toAuthority, toPlatform: proved.toPlatform, ...(confirmed?.receipt ? { receipt: confirmed.receipt } : {}) };
|
|
395
|
+
},
|
|
396
|
+
/**
|
|
397
|
+
* A new payout address for the registry (authority): a request for the
|
|
398
|
+
* keys to sign; once sent it takes effect after 48 hours, unless
|
|
399
|
+
* cancelled (cancelRegistryPayout). The keeper applies it then.
|
|
400
|
+
*/
|
|
401
|
+
proposeRegistryPayout: (registry, payout) => call('POST', `/permits/registries/${registry}/payout`, { payout }, true),
|
|
402
|
+
/** Cancels the pending payout change: a request for the keys to sign. */
|
|
403
|
+
cancelRegistryPayout: (registry) => call('POST', `/permits/registries/${registry}/payout/cancel`, {}, true),
|
|
404
|
+
/** Applies a payout change past its delay, paid by this wallet (the keeper does it itself when it has a fee payer). */
|
|
405
|
+
async applyRegistryPayout(registry) {
|
|
406
|
+
const w = wallet();
|
|
407
|
+
const { transaction, payout } = await call('POST', '/permits/prove/payout/apply', { registry, feePayer: w.address });
|
|
408
|
+
const txHash = await w.signAndSendTransaction(transaction);
|
|
409
|
+
await call('POST', '/permits/confirm', { registry, txHash });
|
|
410
|
+
return { txHash, payout };
|
|
411
|
+
},
|
|
412
|
+
/**
|
|
413
|
+
* Signs a key rotation as one of the NEW keys (`newSlot`: its place in
|
|
414
|
+
* the new set). Every new key signs, besides the current keys' threshold.
|
|
415
|
+
*/
|
|
416
|
+
async signRotationAsNewKey(requestId, newSlot) {
|
|
417
|
+
const w = wallet();
|
|
418
|
+
const { request } = await client.getRequest(requestId);
|
|
419
|
+
if (request.kind !== 'rotate' || !request.newKeys)
|
|
420
|
+
throw new PermitsError('Not a key rotation', 0, 'INVALID_REQUEST', false);
|
|
421
|
+
const s = newSlot ?? request.newKeys.indexOf(w.address);
|
|
422
|
+
if (s < 0)
|
|
423
|
+
throw new PermitsError('This wallet is not in the new key set', 0, 'FORBIDDEN', false);
|
|
424
|
+
const { describeRequest } = await import('./permitDescribe.js');
|
|
425
|
+
await confirm(ctx => describeRequest(request, ctx), request.registry);
|
|
426
|
+
const signature = await w.signFields(request.message);
|
|
427
|
+
return call('POST', `/permits/requests/${requestId}/signatures`, { newSlot: s, signature });
|
|
428
|
+
},
|
|
429
|
+
/**
|
|
430
|
+
* Moves the holder's permit to `newWallet`'s key (both keys sign; free):
|
|
431
|
+
* the same terms under a new subject, whose secret the new wallet derives
|
|
432
|
+
* itself (its first unused counter in the registry's lineage). This
|
|
433
|
+
* wallet pays the fee unless `payer` is given.
|
|
434
|
+
*/
|
|
435
|
+
async rekeyPermit(registry, subject, newWallet, payer) {
|
|
436
|
+
const w = wallet();
|
|
437
|
+
const { permit } = await client.getPermit(registry, subject);
|
|
438
|
+
if (!permit)
|
|
439
|
+
throw new PermitsError('Permit not found', 404, 'NOT_FOUND', false);
|
|
440
|
+
if (permit.holderKey !== w.address)
|
|
441
|
+
throw new PermitsError('This wallet is not the permit holder', 0, 'FORBIDDEN', false);
|
|
442
|
+
const { deriveHolderSecret, MAX_HOLDER_SECRETS } = await import('./holderSecret.js');
|
|
443
|
+
const lineage = await registryLineage(registry);
|
|
444
|
+
let derived = null;
|
|
445
|
+
for (let index = 0; index < MAX_HOLDER_SECRETS && !derived; index++) {
|
|
446
|
+
const d = await deriveHolderSecret(newWallet, { lineage, network: opts.network, index });
|
|
447
|
+
const taken = await client.getPermit(registry, d.subject).then(r => !!r.permit).catch(() => false);
|
|
448
|
+
if (!taken)
|
|
449
|
+
derived = d;
|
|
450
|
+
}
|
|
451
|
+
if (!derived)
|
|
452
|
+
throw new PermitsError('The new wallet has no unused permit number left in this registry', 0, 'CONFLICT', false);
|
|
453
|
+
const body = { registry, subject, newHolderKey: newWallet.address, newSalt: derived.salt };
|
|
454
|
+
const m = await call('POST', '/permits/rekey/message', body);
|
|
455
|
+
if (m.newSubject !== derived.subject)
|
|
456
|
+
throw new PermitsError('The keeper names another new permit than the new wallet derived', 0, 'SIGNATURE_INVALID', false);
|
|
457
|
+
const { describeRekey } = await import('./permitDescribe.js');
|
|
458
|
+
await confirm(ctx => describeRekey({ network: opts.network, registry, leaf: permit, newSubject: m.newSubject, newHolderKey: newWallet.address, fields: m.message }, ctx), registry);
|
|
459
|
+
const holderSignature = await w.signFields(m.message);
|
|
460
|
+
const newHolderSignature = await newWallet.signFields(m.message);
|
|
461
|
+
const p = payer ?? w;
|
|
462
|
+
const { transaction } = await call('POST', '/permits/prove/rekey', { ...body, feePayer: p.address, holderSignature, newHolderSignature });
|
|
463
|
+
const txHash = await p.signAndSendTransaction(transaction);
|
|
464
|
+
await call('POST', '/permits/confirm', { registry, txHash });
|
|
465
|
+
return { txHash, subject: m.newSubject, salt: derived.salt };
|
|
466
|
+
},
|
|
467
|
+
/** Moves this wallet's authority account to `newWallet` (both sign); registry keys change by a rotation. */
|
|
468
|
+
async moveAuthorityAccount(newWallet) {
|
|
469
|
+
const w = wallet();
|
|
470
|
+
const text = authorityMoveText(w.address, newWallet.address);
|
|
471
|
+
return call('POST', '/permits/authorities/move', {
|
|
472
|
+
network: opts.network, from: w.address, to: newWallet.address,
|
|
473
|
+
oldTextSignature: await w.signMessage(text), newTextSignature: await newWallet.signMessage(text),
|
|
474
|
+
});
|
|
475
|
+
},
|
|
476
|
+
/** The holder gives up their permit. */
|
|
477
|
+
async surrender(registry, subject) {
|
|
478
|
+
const w = wallet();
|
|
479
|
+
const { permit } = await client.getPermit(registry, subject);
|
|
480
|
+
if (!permit)
|
|
481
|
+
throw new PermitsError('Permit not found', 404, 'NOT_FOUND', false);
|
|
482
|
+
const msg = surrenderMessage({ network: networkField(opts.network), registry: PublicKey.fromBase58(registry), leaf: recordToLeaf(permit) });
|
|
483
|
+
const { describeSurrender } = await import('./permitDescribe.js');
|
|
484
|
+
await confirm(ctx => describeSurrender({ network: opts.network, registry, leaf: permit, fields: toSignableFields(msg) }, ctx), registry);
|
|
485
|
+
const holderSignature = await w.signFields(toSignableFields(msg));
|
|
486
|
+
const { transaction } = await call('POST', '/permits/prove/surrender', { registry, subject, feePayer: w.address, holderSignature });
|
|
487
|
+
const txHash = await w.signAndSendTransaction(transaction);
|
|
488
|
+
await call('POST', '/permits/confirm', { registry, txHash });
|
|
489
|
+
return { txHash };
|
|
490
|
+
},
|
|
491
|
+
};
|
|
492
|
+
return client;
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* The registry's permits root and the current slot, read from a Mina node
|
|
496
|
+
* (not the keeper) — what a verifier of a holder proof should accept as
|
|
497
|
+
* `acceptedRoots` / `currentSlot` in `verifyHolderProof`.
|
|
498
|
+
*/
|
|
499
|
+
export async function readRegistryHead(args) {
|
|
500
|
+
const { readChainHead } = await import('./chainHead.js');
|
|
501
|
+
return readChainHead({ address: args.registry, network: args.network, graphqlUrl: args.graphqlUrl, fetcher: args.fetcher });
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* The current registry of `registry`'s lineage, from chain state alone: a
|
|
505
|
+
* retired registry names its successor (stored by its retirement, which its
|
|
506
|
+
* keys signed), and the successor's initialization checked the
|
|
507
|
+
* predecessor named it. Each hop also checks the successor runs a published
|
|
508
|
+
* PermitRegistry release and started from the predecessor's frozen root. A
|
|
509
|
+
* successor not deployed yet (between retirement and deployment, e.g.
|
|
510
|
+
* across a hard fork) leaves the retired registry current.
|
|
511
|
+
*/
|
|
512
|
+
export async function currentRegistryOnChain(args) {
|
|
513
|
+
const { currentOnChain, PERMIT_LINEAGE } = await import('./successorChain.js');
|
|
514
|
+
const { DEFAULT_MINA_GRAPHQL_URLS } = await import('./onChainRoot.js');
|
|
515
|
+
const { CANONICAL_PERMIT_VK_HASHES } = await import('./permitInterface.js');
|
|
516
|
+
const graphqlUrl = args.graphqlUrl ?? DEFAULT_MINA_GRAPHQL_URLS[args.network];
|
|
517
|
+
return (await currentOnChain({
|
|
518
|
+
start: args.registry, layout: PERMIT_LINEAGE, canonicalVks: Object.values(CANONICAL_PERMIT_VK_HASHES), graphqlUrl, fetcher: args.fetcher,
|
|
519
|
+
})).address;
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Verifies a permit without trusting the keeper: the root comes from
|
|
523
|
+
* `fetchRoot` (default: the registry account's appState[0] read from a
|
|
524
|
+
* Mina node), and the keeper's leaf and witness must fold to that root.
|
|
525
|
+
*/
|
|
526
|
+
export async function verifyPermitTrustless(args) {
|
|
527
|
+
const client = createPermitsClient({ keeperUrl: args.keeperUrl, network: args.network, fetcher: args.fetcher });
|
|
528
|
+
// Default: root and current slot from a Mina node in one read, so the
|
|
529
|
+
// keeper decides neither which root counts nor what time it is.
|
|
530
|
+
let chainSlot;
|
|
531
|
+
let forkSlot = 0;
|
|
532
|
+
const fetchRoot = args.fetchRoot ?? (async (registry) => {
|
|
533
|
+
const { readChainHead } = await import('./chainHead.js');
|
|
534
|
+
const { PERMIT_REGISTRY_STATE } = await import('./permitInterface.js');
|
|
535
|
+
const head = await readChainHead({ address: registry, network: args.network, graphqlUrl: args.graphqlUrl, fetcher: args.fetcher });
|
|
536
|
+
chainSlot = head.slot;
|
|
537
|
+
forkSlot = Number(head.state[PERMIT_REGISTRY_STATE.forkActivationSlot] ?? 0) || 0;
|
|
538
|
+
return head.root;
|
|
539
|
+
});
|
|
540
|
+
// A redeployed registry names its successor on chain, and only that
|
|
541
|
+
// account could start from its permits: follow the chain of successors to
|
|
542
|
+
// the current registry (with the default node reads).
|
|
543
|
+
const current = args.fetchRoot ? args.registry : await currentRegistryOnChain({ registry: args.registry, network: args.network, graphqlUrl: args.graphqlUrl, fetcher: args.fetcher });
|
|
544
|
+
const served = await client.getPermit(current, args.subject);
|
|
545
|
+
const home = served.registry ?? current;
|
|
546
|
+
const chainRoot = await fetchRoot(home);
|
|
547
|
+
const { MerkleMapWitness, Bool } = await import('o1js');
|
|
548
|
+
const toWitness = (w) => new MerkleMapWitness(w.isLefts.map(b => Bool(b)), w.siblings.map(s => Field(s)));
|
|
549
|
+
const value = served.permit ? permitLeafHash(recordToLeaf(served.permit)) : Field(0);
|
|
550
|
+
const [root, key] = toWitness(served.witness).computeRootAndKey(value);
|
|
551
|
+
// A redeployed registry starts with every permit of the one it replaced,
|
|
552
|
+
// so a permit always verifies against the current registry of its lineage.
|
|
553
|
+
const lineageOk = home === current;
|
|
554
|
+
const rootMatches = lineageOk && root.toString() === chainRoot && key.toString() === args.subject;
|
|
555
|
+
const status = rootMatches ? permitStatusAt(served.permit ?? undefined, args.slot ?? chainSlot ?? served.slot, args.gracePeriod ?? 0, forkSlot) : 'unknown';
|
|
556
|
+
const required = args.requiredScope ?? 0n;
|
|
557
|
+
const scopeOk = !!served.permit && (BigInt(served.permit.scope) & required) === required;
|
|
558
|
+
return {
|
|
559
|
+
valid: rootMatches && scopeOk && (status === 'active' || status === 'in-grace'), status, scopeOk, rootMatches,
|
|
560
|
+
permit: rootMatches ? served.permit : null, registry: home, frozen: !!served.frozen,
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* A wallet for scripts and agents, from a private key the owner handed over.
|
|
565
|
+
* `send` broadcasts the signed transaction (default: o1js on the active
|
|
566
|
+
* Mina instance). Requires the optional `mina-signer` peer dependency.
|
|
567
|
+
*/
|
|
568
|
+
export async function minaSignerWallet(privateKeyBase58, opts) {
|
|
569
|
+
const { default: Client } = await import('mina-signer');
|
|
570
|
+
const signer = new Client({ network: opts.network === 'mainnet' ? 'mainnet' : 'testnet' });
|
|
571
|
+
const address = signer.derivePublicKey(privateKeyBase58);
|
|
572
|
+
const send = opts.send ?? (async (cmd) => {
|
|
573
|
+
const { Mina } = await import('o1js');
|
|
574
|
+
const tx = Mina.Transaction.fromJSON(cmd);
|
|
575
|
+
const pending = await tx.send();
|
|
576
|
+
return pending.hash;
|
|
577
|
+
});
|
|
578
|
+
return {
|
|
579
|
+
address,
|
|
580
|
+
async signFields(fields) {
|
|
581
|
+
return signer.signFields(fields.map(BigInt), privateKeyBase58).signature;
|
|
582
|
+
},
|
|
583
|
+
async signMessage(message) {
|
|
584
|
+
return signer.signMessage(message, privateKeyBase58).signature;
|
|
585
|
+
},
|
|
586
|
+
async signAndSendTransaction(transactionJson) {
|
|
587
|
+
const zkappCommand = JSON.parse(transactionJson);
|
|
588
|
+
const body = zkappCommand.feePayer.body;
|
|
589
|
+
const signed = signer.signZkappCommand({
|
|
590
|
+
zkappCommand,
|
|
591
|
+
feePayer: { feePayer: body.publicKey, fee: body.fee, nonce: body.nonce, memo: '' },
|
|
592
|
+
}, privateKeyBase58);
|
|
593
|
+
return send(signed.data.zkappCommand);
|
|
594
|
+
},
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
//# sourceMappingURL=permitsClient.js.map
|