is not
member of list:{" "}
@@ -294,7 +295,7 @@ export function Prove({
const prs = proofRequest(
proveOperation.proofRequest
).getProofRequest();
- const inputs = {
+ const inputs: GPCProofInputs = {
pods: proveOperation.selectedPods as Record
,
membershipLists: prs.membershipLists,
watermark: prs.watermark,
@@ -303,7 +304,6 @@ export function Prove({
externalNullifier: prs.externalNullifier
}
};
- console.log(inputs);
gpcProve(
{
...prs.proofConfig,
diff --git a/packages/app-connector/package.json b/packages/app-connector/package.json
index 88bc047..fedd8d3 100644
--- a/packages/app-connector/package.json
+++ b/packages/app-connector/package.json
@@ -38,8 +38,8 @@
"dependencies": {
"@parcnet-js/client-rpc": "workspace:*",
"@parcnet-js/podspec": "workspace:*",
- "@pcd/gpc": "^0.3.0",
- "@pcd/pod": "^0.4.0",
+ "@pcd/gpc": "^0.4.0",
+ "@pcd/pod": "^0.5.0",
"nanoevents": "^9.0.0",
"valibot": "^0.42.0"
},
diff --git a/packages/client-rpc/package.json b/packages/client-rpc/package.json
index 102daa8..4c79bb8 100644
--- a/packages/client-rpc/package.json
+++ b/packages/client-rpc/package.json
@@ -27,8 +27,8 @@
"files": ["dist", "LICENSE"],
"dependencies": {
"@parcnet-js/podspec": "workspace:*",
- "@pcd/gpc": "^0.3.0",
- "@pcd/pod": "^0.4.0",
+ "@pcd/gpc": "^0.4.0",
+ "@pcd/pod": "^0.5.0",
"valibot": "^0.42.0"
},
"devDependencies": {
diff --git a/packages/client-rpc/src/schema_elements.ts b/packages/client-rpc/src/schema_elements.ts
index e008781..a01a64d 100644
--- a/packages/client-rpc/src/schema_elements.ts
+++ b/packages/client-rpc/src/schema_elements.ts
@@ -18,6 +18,22 @@ export const PODValueSchema = v.variant("type", [
v.object({
type: v.literal("eddsa_pubkey"),
value: v.string()
+ }),
+ v.object({
+ type: v.literal("boolean"),
+ value: v.boolean()
+ }),
+ v.object({
+ type: v.literal("date"),
+ value: v.date()
+ }),
+ v.object({
+ type: v.literal("bytes"),
+ value: v.instance(Uint8Array)
+ }),
+ v.object({
+ type: v.literal("null"),
+ value: v.null()
})
]);
@@ -57,6 +73,30 @@ export const DefinedEntrySchema = v.variant("type", [
isNotMemberOf: v.optional(v.array(PODValueSchema)),
isRevealed: v.optional(v.boolean()),
equalsEntry: v.optional(v.string())
+ }),
+ v.object({
+ type: v.literal("null")
+ }),
+ v.object({
+ type: v.literal("bytes"),
+ isMemberOf: v.optional(v.array(PODValueSchema)),
+ isNotMemberOf: v.optional(v.array(PODValueSchema))
+ }),
+ v.object({
+ type: v.literal("date"),
+ isMemberOf: v.optional(v.array(PODValueSchema)),
+ isNotMemberOf: v.optional(v.array(PODValueSchema)),
+ inRange: v.optional(
+ v.object({
+ min: v.bigint(),
+ max: v.bigint()
+ })
+ )
+ }),
+ v.object({
+ type: v.literal("boolean"),
+ isMemberOf: v.optional(v.array(PODValueSchema)),
+ isNotMemberOf: v.optional(v.array(PODValueSchema))
})
]);
diff --git a/packages/podspec/package.json b/packages/podspec/package.json
index d8d159d..4ede67a 100644
--- a/packages/podspec/package.json
+++ b/packages/podspec/package.json
@@ -36,8 +36,8 @@
},
"files": ["dist", "./README.md", "./LICENSE"],
"dependencies": {
- "@pcd/gpc": "^0.3.0",
- "@pcd/pod": "^0.4.0"
+ "@pcd/gpc": "^0.4.0",
+ "@pcd/pod": "^0.5.0"
},
"devDependencies": {
"@parcnet-js/eslint-config": "workspace:*",
diff --git a/packages/podspec/src/gpc/proof_request.ts b/packages/podspec/src/gpc/proof_request.ts
index 04dcc14..646f933 100644
--- a/packages/podspec/src/gpc/proof_request.ts
+++ b/packages/podspec/src/gpc/proof_request.ts
@@ -140,8 +140,10 @@ function makeProofRequest(
schema.type === "optional" ? schema.innerType : schema;
const isRevealed = proofConfigPODSchema.revealed?.[entryName] ?? false;
- const isMemberOf = entrySchema.isMemberOf;
- const isNotMemberOf = entrySchema.isNotMemberOf;
+ const isMemberOf =
+ entrySchema.type === "null" ? undefined : entrySchema.isMemberOf;
+ const isNotMemberOf =
+ entrySchema.type === "null" ? undefined : entrySchema.isNotMemberOf;
const inRange =
(entrySchema.type === "cryptographic" || entrySchema.type === "int") &&
entrySchema.inRange;
@@ -173,11 +175,11 @@ function makeProofRequest
(
};
podConfig.entries[entryName] = entryConfig;
- if (entrySchema.isMemberOf) {
+ if (entrySchema.type !== "null" && entrySchema.isMemberOf) {
membershipLists[`allowlist_${podName}_${entryName}`] =
entrySchema.isMemberOf;
}
- if (entrySchema.isNotMemberOf) {
+ if (entrySchema.type !== "null" && entrySchema.isNotMemberOf) {
membershipLists[`blocklist_${podName}_${entryName}`] =
entrySchema.isNotMemberOf;
}
diff --git a/packages/podspec/src/parse/entries.ts b/packages/podspec/src/parse/entries.ts
index 8c5b318..cfb1f0f 100644
--- a/packages/podspec/src/parse/entries.ts
+++ b/packages/podspec/src/parse/entries.ts
@@ -8,10 +8,13 @@ import type {
PodspecUnexpectedInputEntryIssue
} from "../error.js";
import { IssueCode, PodspecError } from "../error.js";
+import { booleanCoercer, checkPODBooleanValue } from "../schemas/boolean.js";
+import { bytesCoercer, checkPODBytesValue } from "../schemas/bytes.js";
import {
checkPODCryptographicValue,
cryptographicCoercer
} from "../schemas/cryptographic.js";
+import { checkPODDateValue, dateCoercer } from "../schemas/dates.js";
import {
checkPODEdDSAPublicKeyValue,
eddsaPublicKeyCoercer
@@ -19,6 +22,7 @@ import {
import type { EntriesSchema, EntriesTupleSchema } from "../schemas/entries.js";
import type { EntrySchema } from "../schemas/entry.js";
import { checkPODIntValue, intCoercer } from "../schemas/int.js";
+import { checkPODNullValue, nullCoercer } from "../schemas/null.js";
import { checkPODStringValue, stringCoercer } from "../schemas/string.js";
import type { EntriesOutputType } from "../type_inference.js";
import { deepFreeze } from "../utils.js";
@@ -30,14 +34,22 @@ const COERCERS: Record unknown> = {
string: stringCoercer,
int: intCoercer,
eddsa_pubkey: eddsaPublicKeyCoercer,
- cryptographic: cryptographicCoercer
+ cryptographic: cryptographicCoercer,
+ boolean: booleanCoercer,
+ bytes: bytesCoercer,
+ date: dateCoercer,
+ null: nullCoercer
};
const TYPE_VALIDATORS = {
string: checkPODStringValue,
int: checkPODIntValue,
eddsa_pubkey: checkPODEdDSAPublicKeyValue,
- cryptographic: checkPODCryptographicValue
+ cryptographic: checkPODCryptographicValue,
+ boolean: checkPODBooleanValue,
+ bytes: checkPODBytesValue,
+ date: checkPODDateValue,
+ null: checkPODNullValue
};
/**
@@ -61,6 +73,10 @@ const VALID_ENTRY_SCHEMA_TYPES = [
"string",
"cryptographic",
"eddsa_pubkey",
+ "boolean",
+ "bytes",
+ "date",
+ "null",
"optional"
] as const;
@@ -118,7 +134,10 @@ export class EntriesSpec {
* @returns A ParseResult containing either a valid result or list of issues.
*/
public safeParse(
- input: Record,
+ input: Record<
+ string,
+ PODValue | string | bigint | number | boolean | Uint8Array | null | Date
+ >,
options: EntriesParseOptions = DEFAULT_ENTRIES_PARSE_OPTIONS,
path: string[] = []
): ParseResult> {
@@ -129,7 +148,10 @@ export class EntriesSpec {
* As {@link safeParse} but will throw an exception if errors are encountered.
*/
public parse(
- input: Record,
+ input: Record<
+ string,
+ PODValue | string | bigint | number | boolean | Uint8Array | null | Date
+ >,
options: EntriesParseOptions = DEFAULT_ENTRIES_PARSE_OPTIONS,
path: string[] = []
): EntriesOutputType {
@@ -191,7 +213,10 @@ export const DEFAULT_ENTRIES_PARSE_OPTIONS: EntriesParseOptions =
*/
export function safeParseEntries(
schema: E,
- input: Record,
+ input: Record<
+ string,
+ PODValue | string | bigint | number | boolean | Uint8Array | null | Date
+ >,
options: EntriesParseOptions = DEFAULT_ENTRIES_PARSE_OPTIONS,
path: string[] = []
): ParseResult> {
diff --git a/packages/podspec/src/parse/entry.ts b/packages/podspec/src/parse/entry.ts
index af8a4fe..930e3e9 100644
--- a/packages/podspec/src/parse/entry.ts
+++ b/packages/podspec/src/parse/entry.ts
@@ -1,4 +1,8 @@
-import type { PODCryptographicValue, PODIntValue } from "@pcd/pod";
+import type {
+ PODCryptographicValue,
+ PODDateValue,
+ PODIntValue
+} from "@pcd/pod";
import { checkBigintBounds } from "@pcd/pod/podChecks";
import type { PodspecBaseIssue, PodspecNotInRangeIssue } from "../error.js";
import { IssueCode } from "../error.js";
@@ -63,12 +67,19 @@ export function parseEntry(
}
}
- const checkedForMatches = safeMembershipChecks(schema, value, options, path);
- if (!checkedForMatches.isValid) {
- if (options.exitEarly) {
- return FAILURE(checkedForMatches.issues);
- } else {
- issues.push(...checkedForMatches.issues);
+ if (schema.type !== "null") {
+ const checkedForMatches = safeMembershipChecks(
+ schema,
+ value,
+ options,
+ path
+ );
+ if (!checkedForMatches.isValid) {
+ if (options.exitEarly) {
+ return FAILURE(checkedForMatches.issues);
+ } else {
+ issues.push(...checkedForMatches.issues);
+ }
}
}
@@ -95,5 +106,17 @@ export function parseEntry(
}
}
+ if (schema.type === "date") {
+ if (schema.inRange) {
+ const { min, max } = schema.inRange;
+ checkBigintBounds(
+ "",
+ BigInt((value as PODDateValue).value.getTime()),
+ min,
+ max
+ );
+ }
+ }
+
return issues.length > 0 ? FAILURE(issues) : SUCCESS(value);
}
diff --git a/packages/podspec/src/parse/parse_utils.ts b/packages/podspec/src/parse/parse_utils.ts
index 8d6b1c3..cc9edba 100644
--- a/packages/podspec/src/parse/parse_utils.ts
+++ b/packages/podspec/src/parse/parse_utils.ts
@@ -1,7 +1,11 @@
import type {
+ PODBooleanValue,
+ PODBytesValue,
PODCryptographicValue,
+ PODDateValue,
PODEdDSAPublicKeyValue,
PODIntValue,
+ PODNullValue,
PODStringValue,
PODValue
} from "@pcd/pod";
@@ -22,6 +26,7 @@ import type {
import { IssueCode } from "../error.js";
import type { EntriesSchema } from "../schemas/entries.js";
import type { DefinedEntrySchema } from "../schemas/entry.js";
+import type { NullSchema } from "../schemas/null.js";
import type { PODTupleSchema } from "../schemas/pod.js";
import type { EntriesParseOptions } from "./entries.js";
import type { EntryParseOptions } from "./entry.js";
@@ -152,7 +157,28 @@ export function safeCheckPublicKeyFormat(
* @returns True if the values are equal, false otherwise.
*/
export function isEqualPODValue(a: PODValue, b: PODValue): boolean {
- return a.type === b.type && a.value === b.value;
+ if (a.type !== b.type) {
+ return false;
+ }
+
+ switch (a.type) {
+ case "string":
+ case "int":
+ case "cryptographic":
+ case "eddsa_pubkey":
+ case "boolean":
+ case "null":
+ return a.value === b.value;
+ case "date":
+ return a.value.getTime() === (b as PODDateValue).value.getTime();
+ case "bytes":
+ return (
+ a.value.length === (b as PODBytesValue).value.length &&
+ a.value.every(
+ (byte, index) => byte === (b as PODBytesValue).value[index]
+ )
+ );
+ }
}
/**
@@ -165,7 +191,7 @@ export function isEqualPODValue(a: PODValue, b: PODValue): boolean {
* @returns A ParseResult containing either a valid result or list of issues.
*/
export function safeMembershipChecks<
- S extends DefinedEntrySchema,
+ S extends Exclude,
T extends PODValue
>(
schema: S,
@@ -303,6 +329,10 @@ export type PODValueNativeTypes = {
int: bigint;
cryptographic: bigint;
eddsa_pubkey: string;
+ boolean: boolean;
+ bytes: Uint8Array;
+ date: Date;
+ null: null;
};
export type PODValueCoerceableNativeTypes = {
@@ -310,6 +340,10 @@ export type PODValueCoerceableNativeTypes = {
int: bigint | number | boolean;
cryptographic: bigint | number | boolean;
eddsa_pubkey: string;
+ boolean: boolean;
+ bytes: Uint8Array;
+ date: Date;
+ null: null;
};
/**
@@ -320,4 +354,8 @@ export type PODValueTypeNameToPODValue = {
int: PODIntValue;
cryptographic: PODCryptographicValue;
eddsa_pubkey: PODEdDSAPublicKeyValue;
+ boolean: PODBooleanValue;
+ bytes: PODBytesValue;
+ date: PODDateValue;
+ null: PODNullValue;
};
diff --git a/packages/podspec/src/pod_value_utils.ts b/packages/podspec/src/pod_value_utils.ts
index 96d0406..9e619d1 100644
--- a/packages/podspec/src/pod_value_utils.ts
+++ b/packages/podspec/src/pod_value_utils.ts
@@ -1,7 +1,11 @@
import type {
+ PODBooleanValue,
+ PODBytesValue,
PODCryptographicValue,
+ PODDateValue,
PODEdDSAPublicKeyValue,
PODIntValue,
+ PODNullValue,
PODStringValue
} from "@pcd/pod";
@@ -56,3 +60,47 @@ export function $c(
return value.map((s) => ({ type: "cryptographic", value: BigInt(s) }));
}
}
+
+export function $b(value: boolean): PODBooleanValue;
+export function $b(value: boolean[]): PODBooleanValue[];
+export function $b(
+ value: boolean | boolean[]
+): PODBooleanValue | PODBooleanValue[] {
+ if (typeof value === "boolean") {
+ return { type: "boolean", value };
+ } else {
+ return value.map((b) => ({ type: "boolean", value: b }));
+ }
+}
+
+export function $n(value: null): PODNullValue;
+export function $n(value: null[]): PODNullValue[];
+export function $n(value: null | null[]): PODNullValue | PODNullValue[] {
+ if (value === null) {
+ return { type: "null", value: null };
+ } else {
+ return value.map(() => ({ type: "null", value: null }));
+ }
+}
+
+export function $d(value: Date): PODDateValue;
+export function $d(value: Date[]): PODDateValue[];
+export function $d(value: Date | Date[]): PODDateValue | PODDateValue[] {
+ if (value instanceof Date) {
+ return { type: "date", value };
+ } else {
+ return value.map((d) => ({ type: "date", value: d }));
+ }
+}
+
+export function $bs(value: Uint8Array): PODBytesValue;
+export function $bs(value: Uint8Array[]): PODBytesValue[];
+export function $bs(
+ value: Uint8Array | Uint8Array[]
+): PODBytesValue | PODBytesValue[] {
+ if (value instanceof Uint8Array) {
+ return { type: "bytes", value };
+ } else {
+ return value.map((b) => ({ type: "bytes", value: b }));
+ }
+}
diff --git a/packages/podspec/src/schemas/boolean.ts b/packages/podspec/src/schemas/boolean.ts
new file mode 100644
index 0000000..6b2edd7
--- /dev/null
+++ b/packages/podspec/src/schemas/boolean.ts
@@ -0,0 +1,54 @@
+import type { PODBooleanValue, PODValue } from "@pcd/pod";
+import { checkPODValue } from "@pcd/pod/podChecks";
+import type { PodspecInvalidTypeIssue } from "../error.js";
+import { IssueCode } from "../error.js";
+import type { ParseResult } from "../parse/parse_utils.js";
+import { FAILURE, SUCCESS } from "../parse/parse_utils.js";
+
+/**
+ * Schema for a PODBooleanValue.
+ */
+export interface BooleanSchema {
+ type: "boolean";
+ isMemberOf?: PODBooleanValue[];
+ isNotMemberOf?: PODBooleanValue[];
+}
+
+/**
+ * Checks if the given input is a PODBytesValue.
+ * @param data - The input to check.
+ * @returns A ParseResult wrapping the value
+ */
+export function checkPODBooleanValue(
+ data: unknown,
+ path: string[]
+): ParseResult {
+ try {
+ checkPODValue("", data as PODValue);
+ } catch {
+ const issue = {
+ code: IssueCode.invalid_type,
+ expectedType: "boolean",
+ path: path
+ } satisfies PodspecInvalidTypeIssue;
+ return FAILURE([issue]);
+ }
+
+ return SUCCESS(data as PODBooleanValue);
+}
+
+/**
+ * @param input - The input to coerce.
+ * @returns A PODBytesValue or undefined if coercion is not possible.
+ */
+export function booleanCoercer(input: unknown): PODBooleanValue | undefined {
+ let value: PODBooleanValue | undefined = undefined;
+ if (typeof input === "boolean") {
+ value = {
+ type: "boolean",
+ value: input
+ };
+ }
+
+ return value;
+}
diff --git a/packages/podspec/src/schemas/bytes.ts b/packages/podspec/src/schemas/bytes.ts
new file mode 100644
index 0000000..f85ee8a
--- /dev/null
+++ b/packages/podspec/src/schemas/bytes.ts
@@ -0,0 +1,55 @@
+import type { PODBytesValue, PODName, PODValue } from "@pcd/pod";
+import { checkPODValue } from "@pcd/pod/podChecks";
+import type { PodspecInvalidTypeIssue } from "../error.js";
+import { IssueCode } from "../error.js";
+import type { ParseResult } from "../parse/parse_utils.js";
+import { FAILURE, SUCCESS } from "../parse/parse_utils.js";
+
+/**
+ * Schema for a PODBytesValue.
+ */
+export interface BytesSchema {
+ type: "bytes";
+ isMemberOf?: PODBytesValue[];
+ isNotMemberOf?: PODBytesValue[];
+ equalsEntry?: PODName;
+}
+
+/**
+ * Checks if the given input is a PODBytesValue.
+ * @param data - The input to check.
+ * @returns A ParseResult wrapping the value
+ */
+export function checkPODBytesValue(
+ data: unknown,
+ path: string[]
+): ParseResult {
+ try {
+ checkPODValue("", data as PODValue);
+ } catch {
+ const issue = {
+ code: IssueCode.invalid_type,
+ expectedType: "bytes",
+ path: path
+ } satisfies PodspecInvalidTypeIssue;
+ return FAILURE([issue]);
+ }
+
+ return SUCCESS(data as PODBytesValue);
+}
+
+/**
+ * @param input - The input to coerce.
+ * @returns A PODBytesValue or undefined if coercion is not possible.
+ */
+export function bytesCoercer(input: unknown): PODBytesValue | undefined {
+ let value: PODBytesValue | undefined = undefined;
+ if (input instanceof Uint8Array) {
+ value = {
+ type: "bytes",
+ value: input
+ };
+ }
+
+ return value;
+}
diff --git a/packages/podspec/src/schemas/dates.ts b/packages/podspec/src/schemas/dates.ts
new file mode 100644
index 0000000..22c354f
--- /dev/null
+++ b/packages/podspec/src/schemas/dates.ts
@@ -0,0 +1,55 @@
+import type { PODDateValue, PODValue } from "@pcd/pod";
+import { checkPODValue } from "@pcd/pod/podChecks";
+import type { PodspecInvalidTypeIssue } from "../error.js";
+import { IssueCode } from "../error.js";
+import type { ParseResult } from "../parse/parse_utils.js";
+import { FAILURE, SUCCESS } from "../parse/parse_utils.js";
+
+/**
+ * Schema for a PODDateValue.
+ */
+export interface DateSchema {
+ type: "date";
+ isMemberOf?: PODDateValue[];
+ isNotMemberOf?: PODDateValue[];
+ inRange?: { min: bigint; max: bigint };
+}
+
+/**
+ * Checks if the given input is a PODBytesValue.
+ * @param data - The input to check.
+ * @returns A ParseResult wrapping the value
+ */
+export function checkPODDateValue(
+ data: unknown,
+ path: string[]
+): ParseResult {
+ try {
+ checkPODValue("", data as PODValue);
+ } catch {
+ const issue = {
+ code: IssueCode.invalid_type,
+ expectedType: "date",
+ path: path
+ } satisfies PodspecInvalidTypeIssue;
+ return FAILURE([issue]);
+ }
+
+ return SUCCESS(data as PODDateValue);
+}
+
+/**
+ * @param input - The input to coerce.
+ * @returns A PODDateValue or undefined if coercion is not possible.
+ */
+export function dateCoercer(input: unknown): PODDateValue | undefined {
+ let value: PODDateValue | undefined = undefined;
+ if (input instanceof Date) {
+ value = {
+ type: "date",
+ value: input
+ };
+ }
+
+ return value;
+}
diff --git a/packages/podspec/src/schemas/entry.ts b/packages/podspec/src/schemas/entry.ts
index 5b97c6c..a8a98d2 100644
--- a/packages/podspec/src/schemas/entry.ts
+++ b/packages/podspec/src/schemas/entry.ts
@@ -1,6 +1,10 @@
+import type { BooleanSchema } from "./boolean.js";
+import type { BytesSchema } from "./bytes.js";
import type { CryptographicSchema } from "./cryptographic.js";
+import type { DateSchema } from "./dates.js";
import type { EdDSAPublicKeySchema } from "./eddsa_pubkey.js";
import type { IntSchema } from "./int.js";
+import type { NullSchema } from "./null.js";
import type { StringSchema } from "./string.js";
/**
@@ -10,7 +14,11 @@ export type DefinedEntrySchema =
| StringSchema
| CryptographicSchema
| IntSchema
- | EdDSAPublicKeySchema;
+ | EdDSAPublicKeySchema
+ | BooleanSchema
+ | BytesSchema
+ | DateSchema
+ | NullSchema;
/**
* Schema for an optional entry.
diff --git a/packages/podspec/src/schemas/null.ts b/packages/podspec/src/schemas/null.ts
new file mode 100644
index 0000000..ba650ca
--- /dev/null
+++ b/packages/podspec/src/schemas/null.ts
@@ -0,0 +1,52 @@
+import type { PODNullValue, PODValue } from "@pcd/pod";
+import { checkPODValue } from "@pcd/pod/podChecks";
+import type { PodspecInvalidTypeIssue } from "../error.js";
+import { IssueCode } from "../error.js";
+import type { ParseResult } from "../parse/parse_utils.js";
+import { FAILURE, SUCCESS } from "../parse/parse_utils.js";
+
+/**
+ * Schema for a PODNullValue.
+ */
+export interface NullSchema {
+ type: "null";
+}
+
+/**
+ * Checks if the given input is a PODNullValue.
+ * @param data - The input to check.
+ * @returns A ParseResult wrapping the value
+ */
+export function checkPODNullValue(
+ data: unknown,
+ path: string[]
+): ParseResult {
+ try {
+ checkPODValue("", data as PODValue);
+ } catch {
+ const issue = {
+ code: IssueCode.invalid_type,
+ expectedType: "null",
+ path: path
+ } satisfies PodspecInvalidTypeIssue;
+ return FAILURE([issue]);
+ }
+
+ return SUCCESS(data as PODNullValue);
+}
+
+/**
+ * @param input - The input to coerce.
+ * @returns A PODNullValue or undefined if coercion is not possible.
+ */
+export function nullCoercer(input: unknown): PODNullValue | undefined {
+ let value: PODNullValue | undefined = undefined;
+ if (input === null) {
+ value = {
+ type: "null",
+ value: input
+ };
+ }
+
+ return value;
+}
diff --git a/packages/podspec/src/utils.ts b/packages/podspec/src/utils.ts
index 6a809e7..b28d813 100644
--- a/packages/podspec/src/utils.ts
+++ b/packages/podspec/src/utils.ts
@@ -6,6 +6,9 @@ export function deepFreeze(obj: T): T {
Object.freeze(obj);
Object.values(obj).forEach((value) => {
+ if (value instanceof Uint8Array) {
+ return;
+ }
deepFreeze(value);
});
diff --git a/packages/podspec/test/podspec.spec.ts b/packages/podspec/test/podspec.spec.ts
index 1d7a3d0..9a3f0f7 100644
--- a/packages/podspec/test/podspec.spec.ts
+++ b/packages/podspec/test/podspec.spec.ts
@@ -10,7 +10,7 @@ import type {
} from "../src/error.js";
import { IssueCode } from "../src/error.js";
import * as p from "../src/index.js";
-import { $c, $i, $s } from "../src/pod_value_utils.js";
+import { $b, $bs, $c, $i, $s } from "../src/pod_value_utils.js";
import type { EntriesTupleSchema } from "../src/schemas/entries.js";
import { GPC_NPM_ARTIFACTS_PATH } from "./constants.js";
import { generateKeyPair, generateRandomHex } from "./utils.js";
@@ -35,6 +35,24 @@ describe("podspec should work", function () {
},
publicKey: {
type: "eddsa_pubkey"
+ },
+ isActive: {
+ type: "boolean",
+ isMemberOf: [$b(true)]
+ },
+ noneExistent: {
+ type: "null"
+ },
+ byteSequence: {
+ type: "bytes",
+ isMemberOf: [$bs(new Uint8Array([1, 2, 3]))]
+ },
+ registrationDate: {
+ type: "date",
+ inRange: {
+ min: BigInt(new Date("2024-01-01").getTime()),
+ max: BigInt(new Date("2024-12-31").getTime())
+ }
}
});
@@ -58,6 +76,22 @@ describe("podspec should work", function () {
publicKey: {
type: "eddsa_pubkey",
value: publicKey
+ },
+ isActive: {
+ type: "boolean",
+ value: true
+ },
+ noneExistent: {
+ type: "null",
+ value: null
+ },
+ byteSequence: {
+ type: "bytes",
+ value: new Uint8Array([1, 2, 3])
+ },
+ registrationDate: {
+ type: "date",
+ value: new Date("2024-05-01")
}
});
@@ -73,6 +107,16 @@ describe("podspec should work", function () {
type: "eddsa_pubkey",
value: publicKey
});
+ expect(result.value.isActive).to.eql({ type: "boolean", value: true });
+ expect(result.value.noneExistent).to.eql({ type: "null", value: null });
+ expect(result.value.byteSequence).to.eql({
+ type: "bytes",
+ value: new Uint8Array([1, 2, 3])
+ });
+ expect(result.value.registrationDate).to.eql({
+ type: "date",
+ value: new Date("2024-05-01")
+ });
});
/**
@@ -98,6 +142,24 @@ describe("podspec should work", function () {
},
publicKey: {
type: "eddsa_pubkey"
+ },
+ isActive: {
+ type: "boolean",
+ isMemberOf: [$b(true)]
+ },
+ noneExistent: {
+ type: "null"
+ },
+ byteSequence: {
+ type: "bytes",
+ isMemberOf: [$bs(new Uint8Array([1, 2, 3]))]
+ },
+ registrationDate: {
+ type: "date",
+ inRange: {
+ min: BigInt(new Date("2024-01-01").getTime()),
+ max: BigInt(new Date("2024-12-31").getTime())
+ }
}
});
@@ -108,7 +170,11 @@ describe("podspec should work", function () {
firstName: "test",
age: 41, // numbers can be coerced to bigint
semaphoreId: 1000n,
- publicKey: publicKey
+ publicKey: publicKey,
+ isActive: true,
+ noneExistent: null,
+ byteSequence: new Uint8Array([1, 2, 3]),
+ registrationDate: new Date("2024-05-01")
},
{ coerce: true }
);
diff --git a/packages/ticket-spec/package.json b/packages/ticket-spec/package.json
index 2fcab84..f339be4 100644
--- a/packages/ticket-spec/package.json
+++ b/packages/ticket-spec/package.json
@@ -32,9 +32,9 @@
"devDependencies": {
"@parcnet-js/eslint-config": "workspace:*",
"@parcnet-js/typescript-config": "workspace:*",
- "@pcd/gpc": "^0.3.0",
- "@pcd/pod": "^0.4.0",
- "@pcd/proto-pod-gpc-artifacts": "^0.9.0",
+ "@pcd/gpc": "^0.4.0",
+ "@pcd/pod": "^0.5.0",
+ "@pcd/proto-pod-gpc-artifacts": "^0.13.0",
"@semaphore-protocol/core": "^4.0.3",
"@semaphore-protocol/identity": "^3.15.2",
"@types/uuid": "^9.0.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index add30a9..a081a93 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -46,20 +46,20 @@ importers:
specifier: workspace:*
version: link:../../packages/podspec
'@pcd/gpc':
- specifier: ^0.3.0
- version: 0.3.0(typescript@5.5.4)
- '@pcd/pod':
specifier: ^0.4.0
- version: 0.4.0
+ version: 0.4.0(typescript@5.5.4)
+ '@pcd/pod':
+ specifier: ^0.5.0
+ version: 0.5.0
'@pcd/proto-pod-gpc-artifacts':
- specifier: ^0.9.0
- version: 0.9.0
+ specifier: ^0.13.0
+ version: 0.13.0
'@radix-ui/react-dialog':
specifier: ^1.1.1
version: 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@semaphore-protocol/core':
- specifier: ^4.4.1
- version: 4.4.1
+ specifier: ^4.5.0
+ version: 4.5.0
'@semaphore-protocol/identity':
specifier: 3.15.2
version: 3.15.2
@@ -258,11 +258,11 @@ importers:
specifier: workspace:*
version: link:../podspec
'@pcd/gpc':
- specifier: ^0.3.0
- version: 0.3.0(typescript@5.5.4)
- '@pcd/pod':
specifier: ^0.4.0
- version: 0.4.0
+ version: 0.4.0(typescript@5.5.4)
+ '@pcd/pod':
+ specifier: ^0.5.0
+ version: 0.5.0
nanoevents:
specifier: ^9.0.0
version: 9.0.0
@@ -354,11 +354,11 @@ importers:
specifier: workspace:*
version: link:../podspec
'@pcd/gpc':
- specifier: ^0.3.0
- version: 0.3.0(typescript@5.5.4)
- '@pcd/pod':
specifier: ^0.4.0
- version: 0.4.0
+ version: 0.4.0(typescript@5.5.4)
+ '@pcd/pod':
+ specifier: ^0.5.0
+ version: 0.5.0
valibot:
specifier: ^0.42.0
version: 0.42.0(typescript@5.5.4)
@@ -424,11 +424,11 @@ importers:
packages/podspec:
dependencies:
'@pcd/gpc':
- specifier: ^0.3.0
- version: 0.3.0(typescript@5.5.4)
- '@pcd/pod':
specifier: ^0.4.0
- version: 0.4.0
+ version: 0.4.0(typescript@5.5.4)
+ '@pcd/pod':
+ specifier: ^0.5.0
+ version: 0.5.0
devDependencies:
'@parcnet-js/eslint-config':
specifier: workspace:*
@@ -477,14 +477,14 @@ importers:
specifier: workspace:*
version: link:../typescript-config
'@pcd/gpc':
- specifier: ^0.3.0
- version: 0.3.0(typescript@5.6.2)
- '@pcd/pod':
specifier: ^0.4.0
- version: 0.4.0
+ version: 0.4.0(typescript@5.6.2)
+ '@pcd/pod':
+ specifier: ^0.5.0
+ version: 0.5.0
'@pcd/proto-pod-gpc-artifacts':
- specifier: ^0.9.0
- version: 0.9.0
+ specifier: ^0.13.0
+ version: 0.13.0
'@semaphore-protocol/core':
specifier: ^4.0.3
version: 4.0.3
@@ -1460,24 +1460,33 @@ packages:
resolution: {integrity: sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==}
engines: {node: '>= 10.0.0'}
- '@pcd/gpc@0.3.0':
- resolution: {integrity: sha512-gaDwb76PYYm+qJUZu+gYWbpJKjbEAI+UPO+yaPYCURLPK+8iUMB3xIv6F3CCJNICQdpcwOVMpnWOu+5wzzwqhA==}
+ '@pcd/gpc@0.4.0':
+ resolution: {integrity: sha512-VE95hTf/Fi/j0Lz6s15cULnQAqaeHaMgRn8wR8xmxA99Bv9KEPD7KZkkrV20WtIf9/Rc+YuFIYEaBFakl4D8Ng==}
- '@pcd/gpcircuits@0.4.0':
- resolution: {integrity: sha512-rn1pkRTQit/maD80bqB2fb84yN22iTWvZWIjgOV6Y84jAZ1uyU4hfbEUJ4q6pdgb4vENiFu9g3pHGge7My9ZTQ==}
+ '@pcd/gpcircuits@0.5.0':
+ resolution: {integrity: sha512-+liYDmxPBEX8SGGPB95/oJliT3Sj+WKeXOldA+7AulqtDEuF+u266NcGOkLqOA0bRPFtzAYO2fQJTvWaK+ws+A==}
'@pcd/pod@0.4.0':
resolution: {integrity: sha512-A90GK1cv/t3pxB9YiiLIXDsJldp3YcmCJchRSbVvFfA9Q2pleumNRpFadwmweLqGf5Er9n1C7AWtiEt07K3rIw==}
+ '@pcd/pod@0.5.0':
+ resolution: {integrity: sha512-Zm8G6BXXjFtSBooYi4cHWAe44US3NjdsPtKmv1Zpcl0EejxYG0wU6GrUpnhSwJfjEpGm35Wes9BUT7wHThGnGg==}
+
'@pcd/proto-pod-gpc-artifacts@0.11.0':
resolution: {integrity: sha512-k/lASCefq1vUyqRirHUAc+yiZAMhSfTJx51qnyImXl6ArW8LtNWRyeoTql2BjY9u3BM/mWN279S5+NtghwnsDw==}
- '@pcd/proto-pod-gpc-artifacts@0.9.0':
- resolution: {integrity: sha512-DipHMqcwpwCGy0/4hpENYjhKPcxVDEM4Koe13L1QpDYlOVVlUfsV9Y5ObpjtZELH4Q8jLWEW2tnMW9vR+c388w==}
+ '@pcd/proto-pod-gpc-artifacts@0.13.0':
+ resolution: {integrity: sha512-SFKV8gmFCyZ6WIOcJPXCdx4I1gNavIw+5u7TFU8L6/DqtUPWZ1/SubyAChb7aTetfwNgJTyid/VL9fEkJYSThA==}
+
+ '@pcd/semaphore-identity-v3-wrapper@0.1.0':
+ resolution: {integrity: sha512-NlLT6Pu+ua0agmPO2bulQiF5vaNv1XbGwSyrTEH/eONq1I0LL5Yd2qdPpZbUnnCUE+Wa6yi4jUqB6i6vh8kv8g==}
'@pcd/util@0.8.0':
resolution: {integrity: sha512-KG1V8O+o8Awr9iHH9I1eVeqHGlm3F6zqzvOJzXKe/bViE8A31DuiZoeHCVPFRA5+03d+qY4tWQJKOxYGQL6Kww==}
+ '@pcd/util@0.9.0':
+ resolution: {integrity: sha512-PI9XR9DY7Okn8AJyOfFPhSihewh5VVTyFf5Hm+qaH09t0MlV8ZbMAo9hbiyB5NtHJo7fEEM5BHTRCPpMeVEJcA==}
+
'@pkgjs/parseargs@0.11.0':
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
@@ -1755,14 +1764,14 @@ packages:
'@semaphore-protocol/core@4.0.3':
resolution: {integrity: sha512-XwFSV8B8JYOS7nXDPNSQ8Uy/Yw2MPyAhcMLToAJsu6HG8rwIG5I6F6/MKgDm4IhUJnE1h22fipoteekjBMVqSg==}
- '@semaphore-protocol/core@4.4.1':
- resolution: {integrity: sha512-A0Xr4QRoTCGnE17GCUFCUvdn7hulZwNU4457iKm2157/UKcLwM9LWkl5VfY4uji0S/NH1vX6X40Xdml2Y5Nz0A==}
+ '@semaphore-protocol/core@4.5.0':
+ resolution: {integrity: sha512-DQNLJIS4YGYnkDDtywpLf1gbQLWRhNm3X3dYGxODujApaATYQaPsFo6HHgHycMRIVgxrQwiAzSCAkTR8SNNgRg==}
'@semaphore-protocol/group@4.0.3':
resolution: {integrity: sha512-ElxMN4vio301EJ6VjnfEpagG8KQn/Ck7BuBwpwHS7neDYcJkKYfRHCOd8OR/mg4dNVenflHkgIO8WTgCz+2n5A==}
- '@semaphore-protocol/group@4.4.1':
- resolution: {integrity: sha512-qrNnPi7DQfNPs1DSNFvbnarfzK9OB7mMDzalT53FNeSiY7vNEPt068n6WAEbLV0fmDe2O52Rhoprw6Aw6VhB3A==}
+ '@semaphore-protocol/group@4.5.0':
+ resolution: {integrity: sha512-8EKglTaLJ1jyKYtp9QgopyNi5BZ6bSal6qUSHXP0/LThXfbtPyiCTl0UvC9Vg0XZMeZUpu/leRgzKkOSeJ7zMg==}
'@semaphore-protocol/identity@3.15.2':
resolution: {integrity: sha512-MJ1MO5QL+oX+OFK2rHAPjQ6+kKgGxCsVJLNdn1soRawxbrxH9A6tV9AsVHV0DN4saegQ4qaOOy1XO1PAN6PiQA==}
@@ -1770,8 +1779,8 @@ packages:
'@semaphore-protocol/identity@4.0.3':
resolution: {integrity: sha512-IfGpE00gWnuM0c41g3rY1uU0he8X8JOrerqXjGzrsW0sXRe/jkxL/jln6zufVTGleN/mGdP9CkqXh7Ca7QjAiw==}
- '@semaphore-protocol/identity@4.4.1':
- resolution: {integrity: sha512-YqhvsMTJB5tN7umXWwNfkqikJlj27qrHqD4wm+6bCIV4KrJnowY5mQVsxzKNrLeAp5nzLC4QrVxGi5CODKYedA==}
+ '@semaphore-protocol/identity@4.5.0':
+ resolution: {integrity: sha512-TIKxF2Lir1LppDQDJU6Z/aJUkocHT03BLpzv5vFEdCo/IT4g/4BhbFp2UQui7HyDE+JgMfUASXfScbFfo/5ULA==}
'@semaphore-protocol/proof@4.0.3':
resolution: {integrity: sha512-egqXei3IEPNKHUxd3/9AbI/1z1nrp1DA5DtzdHI36m1RP0GOE/k4gpwaSGQQqqbUuuGYYnrZZj7bmhphfAy43A==}
@@ -1779,17 +1788,17 @@ packages:
'@semaphore-protocol/group': 4.0.3
'@semaphore-protocol/identity': 4.0.3
- '@semaphore-protocol/proof@4.4.1':
- resolution: {integrity: sha512-GD/MHSK7xSrZt76u1hTBw7ugorALjDLcJW2lfO0xe+3VQZDjqbbyA4K8A0pz6ticJuNzwyH9p/X19QUWp9Ncuw==}
+ '@semaphore-protocol/proof@4.5.0':
+ resolution: {integrity: sha512-/95XcIkud+3QOYxw7QB3wAS28EzbYyJsrqwmQgRy02Xk7b9aDvKZGXcdQ/pXMAjXc1D5mTPDOuJwnTtNtzrOcA==}
peerDependencies:
- '@semaphore-protocol/group': 4.4.1
- '@semaphore-protocol/identity': 4.4.1
+ '@semaphore-protocol/group': 4.5.0
+ '@semaphore-protocol/identity': 4.5.0
'@semaphore-protocol/utils@4.0.3':
resolution: {integrity: sha512-IMyL8C68fHbe5h1QyfZxfxDlxmB1e0TLkBKnEJHnTsNW7nKpzJNAPjcloQ/bbLwWj7SsaeOu+eMQCDPmqSzbQw==}
- '@semaphore-protocol/utils@4.4.1':
- resolution: {integrity: sha512-0ASKABpBo3lbyPM73sArkBh6uM+9SnbXA4d1Uj1LkYIdwPESaijJHMWdM+Zn0w8lKLPBTF0oW/vIcBjD5uCl8g==}
+ '@semaphore-protocol/utils@4.5.0':
+ resolution: {integrity: sha512-6dfQZJvS5JFxdcKUYQTcfptoNohylVDWf6ID+mt8T9jtwgJilDCxkCuCul21lDRxfaChTVVvCm0SYsH+wkroZw==}
'@shikijs/core@1.16.3':
resolution: {integrity: sha512-yETIvrETCeC39gSPIiSADmjri9FwKmxz0QvONMtTIUYlKZe90CJkvcjPksayC2VQOtzOJonEiULUa8v8crUQvA==}
@@ -6932,39 +6941,43 @@ snapshots:
'@parcel/watcher-win32-x64': 2.4.1
optional: true
- '@pcd/gpc@0.3.0(typescript@5.5.4)':
+ '@pcd/gpc@0.4.0(typescript@5.5.4)':
dependencies:
- '@pcd/gpcircuits': 0.4.0
- '@pcd/pod': 0.4.0
- '@pcd/util': 0.8.0
- '@semaphore-protocol/identity': 3.15.2
+ '@pcd/gpcircuits': 0.5.0
+ '@pcd/pod': 0.5.0
+ '@pcd/semaphore-identity-v3-wrapper': 0.1.0
+ '@pcd/util': 0.9.0
+ '@semaphore-protocol/core': 4.5.0
json-bigint: 1.0.0
lodash: 4.17.21
- semaphore-identity-v4: '@semaphore-protocol/identity@4.4.1'
snarkjs: 0.7.4
url-join: 4.0.1
valibot: 0.42.1(typescript@5.5.4)
transitivePeerDependencies:
+ - bufferutil
- typescript
+ - utf-8-validate
- '@pcd/gpc@0.3.0(typescript@5.6.2)':
+ '@pcd/gpc@0.4.0(typescript@5.6.2)':
dependencies:
- '@pcd/gpcircuits': 0.4.0
- '@pcd/pod': 0.4.0
- '@pcd/util': 0.8.0
- '@semaphore-protocol/identity': 3.15.2
+ '@pcd/gpcircuits': 0.5.0
+ '@pcd/pod': 0.5.0
+ '@pcd/semaphore-identity-v3-wrapper': 0.1.0
+ '@pcd/util': 0.9.0
+ '@semaphore-protocol/core': 4.5.0
json-bigint: 1.0.0
lodash: 4.17.21
- semaphore-identity-v4: '@semaphore-protocol/identity@4.4.1'
snarkjs: 0.7.4
url-join: 4.0.1
valibot: 0.42.1(typescript@5.6.2)
transitivePeerDependencies:
+ - bufferutil
- typescript
+ - utf-8-validate
- '@pcd/gpcircuits@0.4.0':
+ '@pcd/gpcircuits@0.5.0':
dependencies:
- '@pcd/pod': 0.4.0
+ '@pcd/pod': 0.5.0
fastfile: 0.0.20
snarkjs: 0.7.4
url-join: 4.0.1
@@ -6978,9 +6991,22 @@ snapshots:
js-sha256: 0.10.1
poseidon-lite: 0.3.0
+ '@pcd/pod@0.5.0':
+ dependencies:
+ '@pcd/util': 0.9.0
+ '@zk-kit/eddsa-poseidon': 1.0.4
+ '@zk-kit/lean-imt': 2.2.1
+ '@zk-kit/utils': 1.2.1
+ js-sha256: 0.10.1
+ poseidon-lite: 0.3.0
+
'@pcd/proto-pod-gpc-artifacts@0.11.0': {}
- '@pcd/proto-pod-gpc-artifacts@0.9.0': {}
+ '@pcd/proto-pod-gpc-artifacts@0.13.0': {}
+
+ '@pcd/semaphore-identity-v3-wrapper@0.1.0':
+ dependencies:
+ '@semaphore-protocol/identity': 3.15.2
'@pcd/util@0.8.0':
dependencies:
@@ -6990,6 +7016,14 @@ snapshots:
secure-random: 1.1.2
uuid: 9.0.1
+ '@pcd/util@0.9.0':
+ dependencies:
+ buffer: 6.0.3
+ email-validator: 2.0.4
+ js-sha256: 0.10.1
+ secure-random: 1.1.2
+ uuid: 9.0.1
+
'@pkgjs/parseargs@0.11.0':
optional: true
@@ -7208,11 +7242,11 @@ snapshots:
- bufferutil
- utf-8-validate
- '@semaphore-protocol/core@4.4.1':
+ '@semaphore-protocol/core@4.5.0':
dependencies:
- '@semaphore-protocol/group': 4.4.1
- '@semaphore-protocol/identity': 4.4.1
- '@semaphore-protocol/proof': 4.4.1(@semaphore-protocol/group@4.4.1)(@semaphore-protocol/identity@4.4.1)
+ '@semaphore-protocol/group': 4.5.0
+ '@semaphore-protocol/identity': 4.5.0
+ '@semaphore-protocol/proof': 4.5.0(@semaphore-protocol/group@4.5.0)(@semaphore-protocol/identity@4.5.0)
transitivePeerDependencies:
- bufferutil
- utf-8-validate
@@ -7222,7 +7256,7 @@ snapshots:
'@zk-kit/lean-imt': 2.1.0
'@zk-kit/utils': 1.0.0
- '@semaphore-protocol/group@4.4.1':
+ '@semaphore-protocol/group@4.5.0':
dependencies:
'@zk-kit/lean-imt': 2.2.1
'@zk-kit/utils': 1.2.1
@@ -7243,7 +7277,7 @@ snapshots:
'@zk-kit/utils': 1.2.0
poseidon-lite: 0.2.0
- '@semaphore-protocol/identity@4.4.1':
+ '@semaphore-protocol/identity@4.5.0':
dependencies:
'@zk-kit/baby-jubjub': 1.0.3
'@zk-kit/eddsa-poseidon': 1.0.4
@@ -7263,11 +7297,11 @@ snapshots:
- bufferutil
- utf-8-validate
- '@semaphore-protocol/proof@4.4.1(@semaphore-protocol/group@4.4.1)(@semaphore-protocol/identity@4.4.1)':
+ '@semaphore-protocol/proof@4.5.0(@semaphore-protocol/group@4.5.0)(@semaphore-protocol/identity@4.5.0)':
dependencies:
- '@semaphore-protocol/group': 4.4.1
- '@semaphore-protocol/identity': 4.4.1
- '@semaphore-protocol/utils': 4.4.1
+ '@semaphore-protocol/group': 4.5.0
+ '@semaphore-protocol/identity': 4.5.0
+ '@semaphore-protocol/utils': 4.5.0
'@zk-kit/artifacts': 1.8.0
'@zk-kit/utils': 1.2.1
ethers: 6.10.0
@@ -7283,7 +7317,7 @@ snapshots:
- bufferutil
- utf-8-validate
- '@semaphore-protocol/utils@4.4.1':
+ '@semaphore-protocol/utils@4.5.0':
dependencies:
ethers: 6.13.2
transitivePeerDependencies: