@opaquecash/psr-core 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attestation.d.ts +66 -0
- package/dist/attestation.d.ts.map +1 -0
- package/dist/attestation.js +82 -0
- package/dist/attestation.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/schema.d.ts +52 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +38 -0
- package/dist/schema.js.map +1 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +12 -2
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PSR V2 attestation codecs — chain-neutral (the attestation engine has the same encoding on
|
|
3
|
+
* Ethereum and Solana). Covers uid computation, attestation-data field encode/decode, and the
|
|
4
|
+
* `0xB2` announce-metadata marker that lets a recipient's scanner match a V2 attestation.
|
|
5
|
+
*
|
|
6
|
+
* Ported from `ethereum/frontend/src/lib/{attestationV2,psr}.ts` (UI-only zod schemas and display
|
|
7
|
+
* helpers intentionally dropped).
|
|
8
|
+
*/
|
|
9
|
+
import { type Address, type Hex } from "viem";
|
|
10
|
+
import type { FieldDef } from "./schema.js";
|
|
11
|
+
/** All-zero bytes32 (no reference uid). */
|
|
12
|
+
export declare const ZERO_BYTES32: Hex;
|
|
13
|
+
/** Minimal field descriptor accepted by the data codecs. */
|
|
14
|
+
export type AttestationField = Pick<FieldDef, "name" | "type"> | {
|
|
15
|
+
name: string;
|
|
16
|
+
type: string;
|
|
17
|
+
};
|
|
18
|
+
/** A decoded V2 attestation record (chain-neutral view). */
|
|
19
|
+
export interface AttestationV2 {
|
|
20
|
+
/** Stable id (== uid). */
|
|
21
|
+
address: string;
|
|
22
|
+
/** uid = sha256(schema_id || issuer || stealth_address_hash || block). */
|
|
23
|
+
uid: string;
|
|
24
|
+
/** schema id as 0x-hex. */
|
|
25
|
+
schemaId: string;
|
|
26
|
+
/** Issuer wallet/address. */
|
|
27
|
+
issuer: string;
|
|
28
|
+
/** Privacy-preserving stealth-address hash (bytes32 0x-hex). */
|
|
29
|
+
stealthAddressHash: string;
|
|
30
|
+
/** Encoded attestation data as 0x-hex. */
|
|
31
|
+
dataHex: string;
|
|
32
|
+
/** Block/slot when created. */
|
|
33
|
+
createdAt: number;
|
|
34
|
+
/** 0 = no expiry. */
|
|
35
|
+
expirationSlot: number;
|
|
36
|
+
/** 0 = not revoked. */
|
|
37
|
+
revocationSlot: number;
|
|
38
|
+
/** Reference uid (zeros = none). */
|
|
39
|
+
refUid: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* `uid = sha256(abi.encodePacked(schemaId, issuer, stealthAddressHash, blockNumber))`,
|
|
43
|
+
* matching the attestation engine's `computeUid` on-chain.
|
|
44
|
+
*/
|
|
45
|
+
export declare function computeUid(schemaId: Hex, issuer: Address, stealthAddressHash: Hex, blockNumber: bigint): Hex;
|
|
46
|
+
/** Encode field values: per field a 4-byte LE length prefix followed by UTF-8 bytes. */
|
|
47
|
+
export declare function encodeAttestationData(fieldValues: Record<string, string>, fieldDefs: readonly AttestationField[]): Hex;
|
|
48
|
+
/** Decode attestation data back into a field-value map. */
|
|
49
|
+
export declare function decodeAttestationData(dataHex: Hex | string, fieldDefs: readonly AttestationField[]): Record<string, string>;
|
|
50
|
+
/**
|
|
51
|
+
* Build the `announce` metadata for a V2 attestation:
|
|
52
|
+
* `viewTag(1) || 0xB2 || schemaId(32) || issuer(32) || uid(32) || nonce(32)` (130 bytes).
|
|
53
|
+
* The recipient's scanner matches it with their viewing key.
|
|
54
|
+
*/
|
|
55
|
+
export declare function encodeV2AttestationMetadata(args: {
|
|
56
|
+
viewTag: number;
|
|
57
|
+
schemaId: Hex;
|
|
58
|
+
issuer: Address;
|
|
59
|
+
uid: Hex;
|
|
60
|
+
nonce: Hex;
|
|
61
|
+
}): Hex;
|
|
62
|
+
/** A fresh 32-byte nonce as 0x-hex (uses Web Crypto, available in Node 18+ and browsers). */
|
|
63
|
+
export declare function randomNonce(): Hex;
|
|
64
|
+
/** True if a uid is all-zero (no reference). */
|
|
65
|
+
export declare function isZeroUid(uid: string): boolean;
|
|
66
|
+
//# sourceMappingURL=attestation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attestation.d.ts","sourceRoot":"","sources":["../src/attestation.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAQL,KAAK,OAAO,EACZ,KAAK,GAAG,EACT,MAAM,MAAM,CAAC;AACd,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,2CAA2C;AAC3C,eAAO,MAAM,YAAY,EAA+B,GAAG,CAAC;AAE5D,4DAA4D;AAC5D,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhG,4DAA4D;AAC5D,MAAM,WAAW,aAAa;IAC5B,0BAA0B;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,GAAG,EAAE,MAAM,CAAC;IACZ,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,uBAAuB;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,GAAG,EACb,MAAM,EAAE,OAAO,EACf,kBAAkB,EAAE,GAAG,EACvB,WAAW,EAAE,MAAM,GAClB,GAAG,CAOL;AAED,wFAAwF;AACxF,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,SAAS,EAAE,SAAS,gBAAgB,EAAE,GACrC,GAAG,CAiBL;AAED,2DAA2D;AAC3D,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,GAAG,GAAG,MAAM,EACrB,SAAS,EAAE,SAAS,gBAAgB,EAAE,GACrC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAexB;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,GAAG,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,GAAG,CAAC;IACT,KAAK,EAAE,GAAG,CAAC;CACZ,GAAG,GAAG,CASN;AAED,6FAA6F;AAC7F,wBAAgB,WAAW,IAAI,GAAG,CAIjC;AAED,gDAAgD;AAChD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE9C"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PSR V2 attestation codecs — chain-neutral (the attestation engine has the same encoding on
|
|
3
|
+
* Ethereum and Solana). Covers uid computation, attestation-data field encode/decode, and the
|
|
4
|
+
* `0xB2` announce-metadata marker that lets a recipient's scanner match a V2 attestation.
|
|
5
|
+
*
|
|
6
|
+
* Ported from `ethereum/frontend/src/lib/{attestationV2,psr}.ts` (UI-only zod schemas and display
|
|
7
|
+
* helpers intentionally dropped).
|
|
8
|
+
*/
|
|
9
|
+
import { bytesToHex, concatHex, encodePacked, hexToBytes, numberToHex, pad, sha256, } from "viem";
|
|
10
|
+
/** All-zero bytes32 (no reference uid). */
|
|
11
|
+
export const ZERO_BYTES32 = ("0x" + "00".repeat(32));
|
|
12
|
+
/**
|
|
13
|
+
* `uid = sha256(abi.encodePacked(schemaId, issuer, stealthAddressHash, blockNumber))`,
|
|
14
|
+
* matching the attestation engine's `computeUid` on-chain.
|
|
15
|
+
*/
|
|
16
|
+
export function computeUid(schemaId, issuer, stealthAddressHash, blockNumber) {
|
|
17
|
+
return sha256(encodePacked(["bytes32", "address", "bytes32", "uint256"], [schemaId, issuer, stealthAddressHash, blockNumber]));
|
|
18
|
+
}
|
|
19
|
+
/** Encode field values: per field a 4-byte LE length prefix followed by UTF-8 bytes. */
|
|
20
|
+
export function encodeAttestationData(fieldValues, fieldDefs) {
|
|
21
|
+
const enc = new TextEncoder();
|
|
22
|
+
const parts = [];
|
|
23
|
+
for (const field of fieldDefs) {
|
|
24
|
+
const encoded = enc.encode(fieldValues[field.name] ?? "");
|
|
25
|
+
const lenBuf = new Uint8Array(4);
|
|
26
|
+
new DataView(lenBuf.buffer).setUint32(0, encoded.length, true);
|
|
27
|
+
parts.push(lenBuf, encoded);
|
|
28
|
+
}
|
|
29
|
+
const total = parts.reduce((acc, p) => acc + p.length, 0);
|
|
30
|
+
const out = new Uint8Array(total);
|
|
31
|
+
let offset = 0;
|
|
32
|
+
for (const part of parts) {
|
|
33
|
+
out.set(part, offset);
|
|
34
|
+
offset += part.length;
|
|
35
|
+
}
|
|
36
|
+
return bytesToHex(out);
|
|
37
|
+
}
|
|
38
|
+
/** Decode attestation data back into a field-value map. */
|
|
39
|
+
export function decodeAttestationData(dataHex, fieldDefs) {
|
|
40
|
+
const hx = (dataHex.startsWith("0x") ? dataHex : `0x${dataHex}`);
|
|
41
|
+
const bytes = hexToBytes(hx);
|
|
42
|
+
const dec = new TextDecoder();
|
|
43
|
+
const result = {};
|
|
44
|
+
let offset = 0;
|
|
45
|
+
for (const field of fieldDefs) {
|
|
46
|
+
if (offset + 4 > bytes.length)
|
|
47
|
+
break;
|
|
48
|
+
const len = new DataView(bytes.buffer, bytes.byteOffset + offset, 4).getUint32(0, true);
|
|
49
|
+
offset += 4;
|
|
50
|
+
if (offset + len > bytes.length)
|
|
51
|
+
break;
|
|
52
|
+
result[field.name] = dec.decode(bytes.slice(offset, offset + len));
|
|
53
|
+
offset += len;
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build the `announce` metadata for a V2 attestation:
|
|
59
|
+
* `viewTag(1) || 0xB2 || schemaId(32) || issuer(32) || uid(32) || nonce(32)` (130 bytes).
|
|
60
|
+
* The recipient's scanner matches it with their viewing key.
|
|
61
|
+
*/
|
|
62
|
+
export function encodeV2AttestationMetadata(args) {
|
|
63
|
+
return concatHex([
|
|
64
|
+
numberToHex(args.viewTag & 0xff, { size: 1 }),
|
|
65
|
+
"0xb2",
|
|
66
|
+
args.schemaId,
|
|
67
|
+
pad(args.issuer, { size: 32 }),
|
|
68
|
+
args.uid,
|
|
69
|
+
args.nonce,
|
|
70
|
+
]);
|
|
71
|
+
}
|
|
72
|
+
/** A fresh 32-byte nonce as 0x-hex (uses Web Crypto, available in Node 18+ and browsers). */
|
|
73
|
+
export function randomNonce() {
|
|
74
|
+
const b = new Uint8Array(32);
|
|
75
|
+
crypto.getRandomValues(b);
|
|
76
|
+
return bytesToHex(b);
|
|
77
|
+
}
|
|
78
|
+
/** True if a uid is all-zero (no reference). */
|
|
79
|
+
export function isZeroUid(uid) {
|
|
80
|
+
return uid.replace(/^0x/, "").replace(/0/g, "") === "";
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=attestation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attestation.js","sourceRoot":"","sources":["../src/attestation.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,4 +10,6 @@ export { buildActionScope, externalNullifierFromScope } from "./scope.js";
|
|
|
10
10
|
export type { Attestation, DiscoveredTrait, MerkleRootMeta, ProofData, } from "./types.js";
|
|
11
11
|
export { PsrError, ProofError, RootExpiredError, NullifierUsedError, } from "./errors.js";
|
|
12
12
|
export { attestationsToDiscoveredTraits } from "./traits.js";
|
|
13
|
+
export { type FieldType, type FieldDef, type SchemaV2, SCHEMA_VERSION, ZERO_ADDRESS, parseFieldDefs, fieldDefsToString, computeSchemaId, packSchemaIdToField, } from "./schema.js";
|
|
14
|
+
export { type AttestationField, type AttestationV2, ZERO_BYTES32, computeUid, encodeAttestationData, decodeAttestationData, encodeV2AttestationMetadata, randomNonce, isZeroUid, } from "./attestation.js";
|
|
13
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAE1E,YAAY,EACV,WAAW,EACX,eAAe,EACf,cAAc,EACd,SAAS,GACV,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAE1E,YAAY,EACV,WAAW,EACX,eAAe,EACf,cAAc,EACd,SAAS,GACV,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAC;AAG7D,OAAO,EACL,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,cAAc,EACd,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,YAAY,EACZ,UAAU,EACV,qBAAqB,EACrB,qBAAqB,EACrB,2BAA2B,EAC3B,WAAW,EACX,SAAS,GACV,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -9,4 +9,7 @@ export { PSR_CIRCUIT_VERSION } from "./scope.js";
|
|
|
9
9
|
export { buildActionScope, externalNullifierFromScope } from "./scope.js";
|
|
10
10
|
export { PsrError, ProofError, RootExpiredError, NullifierUsedError, } from "./errors.js";
|
|
11
11
|
export { attestationsToDiscoveredTraits } from "./traits.js";
|
|
12
|
+
// PSR V2 schema + attestation codecs (chain-neutral).
|
|
13
|
+
export { SCHEMA_VERSION, ZERO_ADDRESS, parseFieldDefs, fieldDefsToString, computeSchemaId, packSchemaIdToField, } from "./schema.js";
|
|
14
|
+
export { ZERO_BYTES32, computeUid, encodeAttestationData, decodeAttestationData, encodeV2AttestationMetadata, randomNonce, isZeroUid, } from "./attestation.js";
|
|
12
15
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAS1E,OAAO,EACL,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAS1E,OAAO,EACL,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAC;AAE7D,sDAAsD;AACtD,OAAO,EAIL,cAAc,EACd,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAGL,YAAY,EACZ,UAAU,EACV,qBAAqB,EACrB,qBAAqB,EACrB,2BAA2B,EAC3B,WAAW,EACX,SAAS,GACV,MAAM,kBAAkB,CAAC"}
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PSR V2 schema codecs — chain-neutral. A schema defines an attestation class and controls who
|
|
3
|
+
* may issue it. Ported from `ethereum/frontend/src/lib/schema.ts` (zod schemas dropped).
|
|
4
|
+
*/
|
|
5
|
+
import { type Address, type Hex } from "viem";
|
|
6
|
+
export type FieldType = "bool" | "u8" | "u16" | "u32" | "u64" | "string" | "pubkey";
|
|
7
|
+
export interface FieldDef {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
type: FieldType;
|
|
11
|
+
}
|
|
12
|
+
/** A decoded V2 schema record (chain-neutral view). */
|
|
13
|
+
export interface SchemaV2 {
|
|
14
|
+
/** Stable id (== schemaId). */
|
|
15
|
+
address: string;
|
|
16
|
+
/** schemaId = sha256(authority || name || version) as 0x-hex (bytes32). */
|
|
17
|
+
schemaId: string;
|
|
18
|
+
/** Wallet that created the schema. */
|
|
19
|
+
authority: string;
|
|
20
|
+
/** Optional resolver (zero address = none). */
|
|
21
|
+
resolver: string;
|
|
22
|
+
/** Whether attestations can be revoked. */
|
|
23
|
+
revocable: boolean;
|
|
24
|
+
/** Display name. */
|
|
25
|
+
name: string;
|
|
26
|
+
/** ABI-style field definitions, e.g. "bool passed, u64 score". */
|
|
27
|
+
fieldDefinitions: string;
|
|
28
|
+
/** Schema version (always 1 currently). */
|
|
29
|
+
version: number;
|
|
30
|
+
/** Authorized delegate addresses. */
|
|
31
|
+
delegates: string[];
|
|
32
|
+
/** Block/slot when registered. */
|
|
33
|
+
createdAt: number;
|
|
34
|
+
/** 0 = no expiry. */
|
|
35
|
+
schemaExpirySlot: number;
|
|
36
|
+
/** Whether the schema has been deprecated. */
|
|
37
|
+
deprecated: boolean;
|
|
38
|
+
}
|
|
39
|
+
export declare const SCHEMA_VERSION = 1;
|
|
40
|
+
export declare const ZERO_ADDRESS: Address;
|
|
41
|
+
/** Parse a `fieldDefinitions` string ("bool passed, u64 score") into {@link FieldDef}s. */
|
|
42
|
+
export declare function parseFieldDefs(fieldDefs: string): FieldDef[];
|
|
43
|
+
/** Convert {@link FieldDef}s back to the canonical ABI string. */
|
|
44
|
+
export declare function fieldDefsToString(fields: readonly FieldDef[]): string;
|
|
45
|
+
/**
|
|
46
|
+
* `schemaId = sha256(abi.encodePacked(authority, bytes(name), version))`, byte-for-byte matching
|
|
47
|
+
* the schema registry's `computeSchemaId` on-chain.
|
|
48
|
+
*/
|
|
49
|
+
export declare function computeSchemaId(authority: Address, name: string, version?: number): Hex;
|
|
50
|
+
/** Normalize a schemaId hex to the `0x`-prefixed field input the V2 circuit expects. */
|
|
51
|
+
export declare function packSchemaIdToField(schemaId: string): string;
|
|
52
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAwB,KAAK,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAEpE,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEpF,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,uDAAuD;AACvD,MAAM,WAAW,QAAQ;IACvB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,SAAS,EAAE,OAAO,CAAC;IACnB,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,gBAAgB,EAAE,MAAM,CAAC;IACzB,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,8CAA8C;IAC9C,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,eAAO,MAAM,cAAc,IAAI,CAAC;AAChC,eAAO,MAAM,YAAY,EAAmD,OAAO,CAAC;AAEpF,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,EAAE,CAS5D;AAED,kEAAkE;AAClE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,CAKrE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,OAAO,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAuB,GAC/B,GAAG,CAEL;AAED,wFAAwF;AACxF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D"}
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PSR V2 schema codecs — chain-neutral. A schema defines an attestation class and controls who
|
|
3
|
+
* may issue it. Ported from `ethereum/frontend/src/lib/schema.ts` (zod schemas dropped).
|
|
4
|
+
*/
|
|
5
|
+
import { encodePacked, sha256 } from "viem";
|
|
6
|
+
export const SCHEMA_VERSION = 1;
|
|
7
|
+
export const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
8
|
+
/** Parse a `fieldDefinitions` string ("bool passed, u64 score") into {@link FieldDef}s. */
|
|
9
|
+
export function parseFieldDefs(fieldDefs) {
|
|
10
|
+
if (!fieldDefs.trim())
|
|
11
|
+
return [];
|
|
12
|
+
return fieldDefs.split(",").map((part, i) => {
|
|
13
|
+
const trimmed = part.trim();
|
|
14
|
+
const spaceIdx = trimmed.indexOf(" ");
|
|
15
|
+
const type = (spaceIdx === -1 ? "string" : trimmed.slice(0, spaceIdx));
|
|
16
|
+
const name = spaceIdx === -1 ? trimmed : trimmed.slice(spaceIdx + 1);
|
|
17
|
+
return { id: String(i), name: name.trim(), type: type.trim() };
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/** Convert {@link FieldDef}s back to the canonical ABI string. */
|
|
21
|
+
export function fieldDefsToString(fields) {
|
|
22
|
+
return fields
|
|
23
|
+
.filter((f) => f.name.trim())
|
|
24
|
+
.map((f) => `${f.type} ${f.name.trim()}`)
|
|
25
|
+
.join(", ");
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* `schemaId = sha256(abi.encodePacked(authority, bytes(name), version))`, byte-for-byte matching
|
|
29
|
+
* the schema registry's `computeSchemaId` on-chain.
|
|
30
|
+
*/
|
|
31
|
+
export function computeSchemaId(authority, name, version = SCHEMA_VERSION) {
|
|
32
|
+
return sha256(encodePacked(["address", "string", "uint8"], [authority, name, version]));
|
|
33
|
+
}
|
|
34
|
+
/** Normalize a schemaId hex to the `0x`-prefixed field input the V2 circuit expects. */
|
|
35
|
+
export function packSchemaIdToField(schemaId) {
|
|
36
|
+
return schemaId.startsWith("0x") ? schemaId : "0x" + schemaId;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,EAA0B,MAAM,MAAM,CAAC;AAsCpE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAChC,MAAM,CAAC,MAAM,YAAY,GAAG,4CAAuD,CAAC;AAEpF,2FAA2F;AAC3F,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,CAAC;IACjC,OAAO,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,IAAI,GAAG,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAc,CAAC;QACpF,MAAM,IAAI,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;QACrE,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAe,EAAE,CAAC;IAC9E,CAAC,CAAC,CAAC;AACL,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,iBAAiB,CAAC,MAA2B;IAC3D,OAAO,MAAM;SACV,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC5B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;SACxC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,SAAkB,EAClB,IAAY,EACZ,UAAkB,cAAc;IAEhC,OAAO,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AAC1F,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAClD,OAAO,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,QAAQ,CAAC;AAChE,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -44,6 +44,8 @@ export interface MerkleRootMeta {
|
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
46
46
|
* Groth16 proof bundle compatible with {@link submitVerifyReputation} in `@opaquecash/psr-chain`.
|
|
47
|
+
*
|
|
48
|
+
* V2 public signals: `[merkle_root, attestation_id, external_nullifier, nullifier_hash]`.
|
|
47
49
|
*/
|
|
48
50
|
export interface ProofData {
|
|
49
51
|
proof: {
|
|
@@ -52,6 +54,7 @@ export interface ProofData {
|
|
|
52
54
|
pi_c: string[];
|
|
53
55
|
};
|
|
54
56
|
publicSignals: string[];
|
|
57
|
+
/** V2 `nullifier_hash` (`publicSignals[3]` = `Poseidon(stealth_pk, external_nullifier)`). */
|
|
55
58
|
nullifier: string;
|
|
56
59
|
attestationId: number;
|
|
57
60
|
}
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEhC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,yDAAyD;IACzD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,+BAA+B;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,gDAAgD;IAChD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAC;IACtB,gCAAgC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,YAAY,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,2BAA2B;IAC3B,IAAI,EAAE,GAAG,CAAC;IACV,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEhC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,yDAAyD;IACzD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,+BAA+B;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,gDAAgD;IAChD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAC;IACtB,gCAAgC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,YAAY,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,2BAA2B;IAC3B,IAAI,EAAE,GAAG,CAAC;IACV,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;QACjB,IAAI,EAAE,MAAM,EAAE,CAAC;KAChB,CAAC;IACF,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,6FAA6F;IAC7F,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opaquecash/psr-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Programmable Stealth Reputation types, scoping, and error taxonomy",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -21,5 +21,15 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"viem": "^2.21.0"
|
|
23
23
|
},
|
|
24
|
-
"sideEffects": false
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"license": "Apache-2.0",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/opaquecash/sdk.git",
|
|
29
|
+
"directory": "packages/psr-core"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://docs.opaque.cash",
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
}
|
|
25
35
|
}
|