diff --git a/apps/client-web/CHANGELOG.md b/apps/client-web/CHANGELOG.md index 449f26d..ee7f5ba 100644 --- a/apps/client-web/CHANGELOG.md +++ b/apps/client-web/CHANGELOG.md @@ -1,5 +1,15 @@ # client-web +## 0.0.8 + +### Patch Changes + +- Support for distinct verify and verifyWithProofRequest operations +- Updated dependencies + - @parcnet-js/client-rpc@0.0.6 + - @parcnet-js/podspec@0.0.5 + - @parcnet-js/client-helpers@0.0.8 + ## 0.0.7 ### Patch Changes diff --git a/apps/client-web/package.json b/apps/client-web/package.json index b1c2fe7..0554b37 100644 --- a/apps/client-web/package.json +++ b/apps/client-web/package.json @@ -1,7 +1,7 @@ { "name": "client-web", "private": true, - "version": "0.0.7", + "version": "0.0.8", "type": "module", "scripts": { "dev": "vite", diff --git a/apps/client-web/src/client/gpc.ts b/apps/client-web/src/client/gpc.ts index 3aaab9f..ca4af40 100644 --- a/apps/client-web/src/client/gpc.ts +++ b/apps/client-web/src/client/gpc.ts @@ -59,6 +59,19 @@ export class ParcnetGPCProcessor implements ParcnetGPCRPC { } public async verify( + proof: GPCProof, + boundConfig: GPCBoundConfig, + revealedClaims: GPCRevealedClaims + ): Promise { + return gpcVerify( + proof, + boundConfig, + revealedClaims, + new URL("/artifacts", window.location.origin).toString() + ); + } + + public async verifyWithProofRequest( proof: GPCProof, boundConfig: GPCBoundConfig, revealedClaims: GPCRevealedClaims, diff --git a/apps/docs/CHANGELOG.md b/apps/docs/CHANGELOG.md new file mode 100644 index 0000000..f2e6a5c --- /dev/null +++ b/apps/docs/CHANGELOG.md @@ -0,0 +1,7 @@ +# docs + +## 0.0.2 + +### Patch Changes + +- Support for distinct verify and verifyWithProofRequest operations diff --git a/apps/docs/package.json b/apps/docs/package.json index 767e1b2..cd3fd4e 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -1,7 +1,7 @@ { "name": "docs", "type": "module", - "version": "0.0.1", + "version": "0.0.2", "scripts": { "dev": "astro dev", "start": "astro dev", diff --git a/apps/docs/src/content/docs/guides/getting-started.mdx b/apps/docs/src/content/docs/guides/getting-started.mdx index 3152f45..8548e4e 100644 --- a/apps/docs/src/content/docs/guides/getting-started.mdx +++ b/apps/docs/src/content/docs/guides/getting-started.mdx @@ -24,7 +24,7 @@ To get started with the Zapp SDK, you will need to install the `@parcnet-js/app- Next, import the connector package in your application code: ```ts wrap=true title="src/main.ts" -import { connect } from "@parcnet-js/connector"; +import { connect } from "@parcnet-js/app-connector"; ``` ## Connect to Zupass diff --git a/apps/docs/src/content/docs/guides/ticket-proofs.mdx b/apps/docs/src/content/docs/guides/ticket-proofs.mdx index 3ddb12f..aafdf66 100644 --- a/apps/docs/src/content/docs/guides/ticket-proofs.mdx +++ b/apps/docs/src/content/docs/guides/ticket-proofs.mdx @@ -230,6 +230,75 @@ You can add a watermark to your proof, which allows you to uniquely identify a p If you add a watermark to your proof request, you can check the watermark when later verifying the proof. A typical workflow might involve your client application requesting a random number from your server, which stores the number. The number is passed as a watermark in the proof request, and then you can send the proof to the server for verification. The server then checks that the watermark is equal to the random number it generated. By requiring the watermark to equal some single-use secret value, you ensure that the client cannot re-use a previously-generated proof. -# Verifying a ticket proof +## Verifying a ticket proof -TODO. \ No newline at end of file +Once a proof has been made, you can verify it. + +Typically, verification is done by a different person, computer, or program than the one that produced the proof. You don't really need to verify a proof that you just created on the same computer, but if you received a proof from someone else, or if you have an application which sends proofs between, say, a client and a server then you will want to verify any proofs that you receive. + +Verification covers a few important principles: +- That, given a `revealedClaims` object which makes certain statements, a proof configuration, and a proof object, the proof object really does correspond to the configuration and revealed claims. If we didn't check this, then the `revealedClaims` might contain data for which there is no proof! +- That the configuration really is the one that you expect it to be. This is important because a proof might really match a set of claims and a configuration, but if the configuration is not the one you expect then the claims might not be valid for your use-case. + +### Proof requests + +To make this easy to get right, we have a concept of "proof requests". When you call `ticketProofRequest` as described above, you're creating a proof request object which can be used to... request a proof. However, you can also use the proof request when _verifying_ a proof, to ensure that the proof was produced in response to the correct request. + +If you're verifying the proof in the browser using the Z API, you can do so like this: + +```ts wrap=true title="src/main.ts" +import { ticketProofRequest } from "@parcnet-js/ticket-spec"; + +const request = ticketProofRequest({ + /** + * As per examples above + */ +}); + +const { proof, boundConfig, revealedClaims } = await z.gpc.prove(request); + +const isVerified = await z.gpc.verifyWithProofRequest(proof, boundConfig, revealedClaims, proofRequest); +``` + +This performs both of the checks described above. Of course, since you're using the same proof request object in both cases, you already know that the proof matches the request! + +However, you can use a similar technique when verifying the same proof in another environment, such as on a server: + +```ts wrap=true title="src/server.ts" +import { ticketProofRequest } from "@parcnet-js/ticket-spec"; +import { gpcVerify } from "@pcd/gpc"; +import isEqual from "lodash/isEqual"; + +const request = ticketProofRequest({ + /** + * This should be the same proof request that you use on the client. + * It would be a good idea to define your proof request in a shared module or + * package. + */ +}); + +// Here we assume that some kind of web framework such as Express is being used +// to receive these variables via a HTTP POST or similar. +const { proof, boundConfig, revealedClaims } = httpRequest.body; + +const { proofConfig, membershipLists, externalNullifier, watermark } = request.getProofRequest(); + +// This is necessary to satisfy the type of `GPCBoundConfig` +proofConfig.circuitIdentifier = boundConfig.circuitIdentifier; + +// These changes ensure that the revealed claims say what they are supposed to +revealedClaims.membershipLists = membershipLists; +revealedClaims.watermark = watermark; +if (revealedClaims.owner) { + revealedClaims.owner.externalNullifier = externalNullifier; +} + +const isVerified = await gpcVerify( + proof, + proofConfig as GPCBoundConfig, + revealedClaims, + pathToGPCArtifacts // This may vary depending on your installation +); +``` + +This ensures that our verified proof not only matches the claims that were sent, but that claims are those we expect them to be. \ No newline at end of file diff --git a/examples/test-app/CHANGELOG.md b/examples/test-app/CHANGELOG.md index 6189ff6..7dbe1e5 100644 --- a/examples/test-app/CHANGELOG.md +++ b/examples/test-app/CHANGELOG.md @@ -1,5 +1,15 @@ # test-app +## 1.0.10 + +### Patch Changes + +- Updated dependencies + - @parcnet-js/app-connector@0.0.9 + - @parcnet-js/ticket-spec@0.0.4 + - @parcnet-js/client-rpc@0.0.6 + - @parcnet-js/podspec@0.0.5 + ## 1.0.9 ### Patch Changes diff --git a/examples/test-app/package.json b/examples/test-app/package.json index 1c459e3..e606782 100644 --- a/examples/test-app/package.json +++ b/examples/test-app/package.json @@ -1,6 +1,6 @@ { "name": "test-app", - "version": "1.0.9", + "version": "1.0.10", "private": true, "type": "module", "scripts": { diff --git a/packages/app-connector/CHANGELOG.md b/packages/app-connector/CHANGELOG.md index 82dd623..80b380f 100644 --- a/packages/app-connector/CHANGELOG.md +++ b/packages/app-connector/CHANGELOG.md @@ -1,5 +1,14 @@ # @parcnet-js/app-connector +## 0.0.9 + +### Patch Changes + +- Support for distinct verify and verifyWithProofRequest operations +- Updated dependencies + - @parcnet-js/client-rpc@0.0.6 + - @parcnet-js/podspec@0.0.5 + ## 0.0.8 ### Patch Changes diff --git a/packages/app-connector/package.json b/packages/app-connector/package.json index 6c7a23b..268828e 100644 --- a/packages/app-connector/package.json +++ b/packages/app-connector/package.json @@ -1,6 +1,6 @@ { "name": "@parcnet-js/app-connector", - "version": "0.0.8", + "version": "0.0.9", "license": "GPL-3.0-or-later", "type": "module", "main": "dist/index.cjs", @@ -22,7 +22,7 @@ "lint": "eslint . --max-warnings 0", "build": "tsup 'src/**/*@(ts|tsx)' --format cjs,esm --clean --sourcemap", "prepublish": "tsup 'src/**/*@(ts|tsx)' --format cjs,esm --clean --sourcemap --dts", - "test": "vitest run" + "test": "vitest run --typecheck" }, "files": ["dist", "LICENSE"], "dependencies": { diff --git a/packages/app-connector/src/api_wrapper.ts b/packages/app-connector/src/api_wrapper.ts index 983a9ff..cd6d919 100644 --- a/packages/app-connector/src/api_wrapper.ts +++ b/packages/app-connector/src/api_wrapper.ts @@ -112,12 +112,25 @@ export class ParcnetGPCWrapper { } async verify( + proof: GPCProof, + config: GPCBoundConfig, + revealedClaims: GPCRevealedClaims + ): Promise { + return this.#api.gpc.verify(proof, config, revealedClaims); + } + + async verifyWithProofRequest( proof: GPCProof, config: GPCBoundConfig, revealedClaims: GPCRevealedClaims, proofRequest: p.PodspecProofRequest ): Promise { - return this.#api.gpc.verify(proof, config, revealedClaims, proofRequest); + return this.#api.gpc.verifyWithProofRequest( + proof, + config, + revealedClaims, + proofRequest + ); } } diff --git a/packages/app-connector/src/rpc_client.ts b/packages/app-connector/src/rpc_client.ts index cd6542e..84f1b5e 100644 --- a/packages/app-connector/src/rpc_client.ts +++ b/packages/app-connector/src/rpc_client.ts @@ -173,15 +173,26 @@ export class ParcnetRPCConnector implements ParcnetRPC, ParcnetEvents { ); }, verify: async ( + proof: GPCProof, + boundConfig: GPCBoundConfig, + revealedClaims: GPCRevealedClaims + ): Promise => { + return this.#typedInvoke( + "gpc.verify", + [proof, boundConfig, revealedClaims], + ParcnetRPCSchema.gpc.verify + ); + }, + verifyWithProofRequest: async ( proof: GPCProof, boundConfig: GPCBoundConfig, revealedClaims: GPCRevealedClaims, proofRequest: PodspecProofRequest ): Promise => { return this.#typedInvoke( - "gpc.verify", + "gpc.verifyWithProofRequest", [proof, boundConfig, revealedClaims, proofRequest], - ParcnetRPCSchema.gpc.verify + ParcnetRPCSchema.gpc.verifyWithProofRequest ); } }; diff --git a/packages/client-helpers/CHANGELOG.md b/packages/client-helpers/CHANGELOG.md index 3cacc7a..b818c16 100644 --- a/packages/client-helpers/CHANGELOG.md +++ b/packages/client-helpers/CHANGELOG.md @@ -1,5 +1,12 @@ # @parcnet-js/client-helpers +## 0.0.8 + +### Patch Changes + +- Updated dependencies + - @parcnet-js/client-rpc@0.0.6 + ## 0.0.7 ### Patch Changes diff --git a/packages/client-helpers/package.json b/packages/client-helpers/package.json index 35f6424..3cc651e 100644 --- a/packages/client-helpers/package.json +++ b/packages/client-helpers/package.json @@ -1,6 +1,6 @@ { "name": "@parcnet-js/client-helpers", - "version": "0.0.7", + "version": "0.0.8", "license": "GPL-3.0-or-later", "type": "module", "main": "dist/index.js", diff --git a/packages/client-rpc/CHANGELOG.md b/packages/client-rpc/CHANGELOG.md index f92eda2..afa86a3 100644 --- a/packages/client-rpc/CHANGELOG.md +++ b/packages/client-rpc/CHANGELOG.md @@ -1,5 +1,13 @@ # @parcnet-js/client-rpc +## 0.0.6 + +### Patch Changes + +- Support for distinct verify and verifyWithProofRequest operations +- Updated dependencies + - @parcnet-js/podspec@0.0.5 + ## 0.0.5 ### Patch Changes diff --git a/packages/client-rpc/package.json b/packages/client-rpc/package.json index 2ac2ec6..f98b5c5 100644 --- a/packages/client-rpc/package.json +++ b/packages/client-rpc/package.json @@ -1,7 +1,7 @@ { "name": "@parcnet-js/client-rpc", "type": "module", - "version": "0.0.5", + "version": "0.0.6", "license": "GPL-3.0-or-later", "main": "dist/index.js", "module": "dist/index.js", @@ -21,7 +21,8 @@ "scripts": { "lint": "eslint . --max-warnings 0", "build": "tsup 'src/**/*@(ts|tsx)' --format cjs,esm --clean --sourcemap", - "prepublish": "tsup 'src/**/*@(ts|tsx)' --format cjs,esm --clean --sourcemap --dts" + "prepublish": "tsup 'src/**/*@(ts|tsx)' --format cjs,esm --clean --sourcemap --dts", + "test": "vitest run --typecheck" }, "files": ["dist", "LICENSE"], "dependencies": { @@ -32,10 +33,12 @@ }, "devDependencies": { "@parcnet-js/eslint-config": "workspace:*", + "@parcnet-js/podspec": "workspace:*", "@parcnet-js/typescript-config": "workspace:*", "@types/snarkjs": "^0.7.8", "tsup": "^8.2.4", - "typescript": "^5.5" + "typescript": "^5.5", + "vitest": "^2.1.2" }, "publishConfig": { "access": "public", diff --git a/packages/client-rpc/src/rpc_interfaces.ts b/packages/client-rpc/src/rpc_interfaces.ts index b85723b..8d358fc 100644 --- a/packages/client-rpc/src/rpc_interfaces.ts +++ b/packages/client-rpc/src/rpc_interfaces.ts @@ -38,6 +38,11 @@ export interface ParcnetGPCRPC { prove: (request: PodspecProofRequest) => Promise; canProve: (request: PodspecProofRequest) => Promise; verify: ( + proof: GPCProof, + boundConfig: GPCBoundConfig, + revealedClaims: GPCRevealedClaims + ) => Promise; + verifyWithProofRequest: ( proof: GPCProof, boundConfig: GPCBoundConfig, revealedClaims: GPCRevealedClaims, diff --git a/packages/client-rpc/src/schema.ts b/packages/client-rpc/src/schema.ts index 0f7fc94..d877c72 100644 --- a/packages/client-rpc/src/schema.ts +++ b/packages/client-rpc/src/schema.ts @@ -1,134 +1,11 @@ -import type { GPCBoundConfig, GPCRevealedClaims } from "@pcd/gpc"; -import type { Groth16Proof } from "snarkjs"; import * as v from "valibot"; import type { ParcnetRPC } from "./rpc_interfaces.js"; - -const PODValueSchema = v.variant("type", [ - v.object({ - type: v.literal("string"), - value: v.string() - }), - v.object({ - type: v.literal("int"), - value: v.bigint() - }), - v.object({ - type: v.literal("cryptographic"), - value: v.bigint() - }), - v.object({ - type: v.literal("eddsa_pubkey"), - value: v.string() - }) -]); - -const PODEntriesSchema = v.record(v.string(), PODValueSchema); - -const DefinedEntrySchema = v.variant("type", [ - v.object({ - type: v.literal("string"), - isMemberOf: v.optional(v.array(PODValueSchema)), - isNotMemberOf: v.optional(v.array(PODValueSchema)), - isRevealed: v.optional(v.boolean()), - equalsEntry: v.optional(v.string()) - }), - v.object({ - type: v.literal("int"), - isMemberOf: v.optional(v.array(PODValueSchema)), - isNotMemberOf: v.optional(v.array(PODValueSchema)), - isRevealed: v.optional(v.boolean()), - equalsEntry: v.optional(v.string()), - inRange: v.optional( - v.object({ - min: v.bigint(), - max: v.bigint() - }) - ) - }), - v.object({ - type: v.literal("cryptographic"), - isMemberOf: v.optional(v.array(PODValueSchema)), - isNotMemberOf: v.optional(v.array(PODValueSchema)), - isRevealed: v.optional(v.boolean()), - equalsEntry: v.optional(v.string()) - }), - v.object({ - type: v.literal("eddsa_pubkey"), - isMemberOf: v.optional(v.array(PODValueSchema)), - isNotMemberOf: v.optional(v.array(PODValueSchema)), - isRevealed: v.optional(v.boolean()), - equalsEntry: v.optional(v.string()) - }) -]); - -const OptionalEntrySchema = v.object({ - type: v.literal("optional"), - innerType: DefinedEntrySchema -}); - -const EntrySchema = v.variant("type", [ - DefinedEntrySchema, - OptionalEntrySchema -]); - -const PODTupleSchema = v.object({ - entries: v.array(v.string()), - isMemberOf: v.optional(v.array(v.array(PODValueSchema))), - isNotMemberOf: v.optional(v.array(v.array(PODValueSchema))) -}); - -const SignerPublicKeySchema = v.object({ - isMemberOf: v.optional(v.array(v.string())), - isNotMemberOf: v.optional(v.array(v.string())) -}); - -const SignatureSchema = v.object({ - isMemberOf: v.optional(v.array(v.string())), - isNotMemberOf: v.optional(v.array(v.string())) -}); - -const PODSchemaSchema = v.object({ - entries: v.record(v.string(), EntrySchema), - tuples: v.optional(v.array(PODTupleSchema)), - signerPublicKey: v.optional(SignerPublicKeySchema), - signature: v.optional(SignatureSchema), - meta: v.optional( - v.object({ - labelEntry: v.string() - }) - ) -}); - -const ProofConfigPODSchemaSchema = v.object({ - pod: PODSchemaSchema, - revealed: v.optional(v.record(v.string(), v.optional(v.boolean()))), - owner: v.optional( - v.object({ - entry: v.string(), - protocol: v.union([v.literal("SemaphoreV3"), v.literal("SemaphoreV4")]) - }) - ) -}); - -const PodspecProofRequestSchema = v.object({ - pods: v.record(v.string(), ProofConfigPODSchemaSchema), - externalNullifier: v.optional(PODValueSchema), - watermark: v.optional(PODValueSchema) -}); - -const ProveResultSchema = v.variant("success", [ - v.object({ - success: v.literal(true), - // TODO: More specific schemas for these - proof: v.custom(() => true), - boundConfig: v.custom(() => true), - revealedClaims: v.custom(() => true) - }), - v.object({ - success: v.literal(false), - error: v.string() - }) -]); +import { + PODEntriesSchema, + PODSchemaSchema, + PodspecProofRequestSchema, + ProveResultSchema +} from "./schema_elements.js"; export type RPCFunction< I extends v.TupleSchema< @@ -173,6 +50,10 @@ export const ParcnetRPCSchema = { output: v.boolean() }, verify: { + input: v.tuple([v.any(), v.any(), v.any()]), + output: v.boolean() + }, + verifyWithProofRequest: { input: v.tuple([v.any(), v.any(), v.any(), v.any()]), output: v.boolean() } diff --git a/packages/client-rpc/src/schema_elements.ts b/packages/client-rpc/src/schema_elements.ts new file mode 100644 index 0000000..e008781 --- /dev/null +++ b/packages/client-rpc/src/schema_elements.ts @@ -0,0 +1,130 @@ +import type { GPCBoundConfig, GPCRevealedClaims } from "@pcd/gpc"; +import type { Groth16Proof } from "snarkjs"; +import * as v from "valibot"; + +export const PODValueSchema = v.variant("type", [ + v.object({ + type: v.literal("string"), + value: v.string() + }), + v.object({ + type: v.literal("int"), + value: v.bigint() + }), + v.object({ + type: v.literal("cryptographic"), + value: v.bigint() + }), + v.object({ + type: v.literal("eddsa_pubkey"), + value: v.string() + }) +]); + +export const PODEntriesSchema = v.record(v.string(), PODValueSchema); + +export const DefinedEntrySchema = v.variant("type", [ + v.object({ + type: v.literal("string"), + isMemberOf: v.optional(v.array(PODValueSchema)), + isNotMemberOf: v.optional(v.array(PODValueSchema)), + isRevealed: v.optional(v.boolean()), + equalsEntry: v.optional(v.string()) + }), + v.object({ + type: v.literal("int"), + isMemberOf: v.optional(v.array(PODValueSchema)), + isNotMemberOf: v.optional(v.array(PODValueSchema)), + isRevealed: v.optional(v.boolean()), + equalsEntry: v.optional(v.string()), + inRange: v.optional( + v.object({ + min: v.bigint(), + max: v.bigint() + }) + ) + }), + v.object({ + type: v.literal("cryptographic"), + isMemberOf: v.optional(v.array(PODValueSchema)), + isNotMemberOf: v.optional(v.array(PODValueSchema)), + isRevealed: v.optional(v.boolean()), + equalsEntry: v.optional(v.string()) + }), + v.object({ + type: v.literal("eddsa_pubkey"), + isMemberOf: v.optional(v.array(PODValueSchema)), + isNotMemberOf: v.optional(v.array(PODValueSchema)), + isRevealed: v.optional(v.boolean()), + equalsEntry: v.optional(v.string()) + }) +]); + +export const OptionalEntrySchema = v.object({ + type: v.literal("optional"), + innerType: DefinedEntrySchema +}); + +export const EntrySchema = v.variant("type", [ + DefinedEntrySchema, + OptionalEntrySchema +]); + +export const PODTupleSchema = v.object({ + entries: v.array(v.string()), + isMemberOf: v.optional(v.array(v.array(PODValueSchema))), + isNotMemberOf: v.optional(v.array(v.array(PODValueSchema))) +}); + +export const SignerPublicKeySchema = v.object({ + isMemberOf: v.optional(v.array(v.string())), + isNotMemberOf: v.optional(v.array(v.string())) +}); + +export const SignatureSchema = v.object({ + isMemberOf: v.optional(v.array(v.string())), + isNotMemberOf: v.optional(v.array(v.string())) +}); + +export const PODSchemaSchema = v.object({ + entries: v.record(v.string(), EntrySchema), + tuples: v.optional(v.array(PODTupleSchema)), + signerPublicKey: v.optional(SignerPublicKeySchema), + signature: v.optional(SignatureSchema), + meta: v.optional( + v.object({ + labelEntry: v.string() + }) + ) +}); + +export const ProofConfigPODSchemaSchema = v.object({ + pod: PODSchemaSchema, + revealed: v.optional(v.record(v.string(), v.optional(v.boolean()))), + owner: v.optional( + v.object({ + entry: v.string(), + protocol: v.union([v.literal("SemaphoreV3"), v.literal("SemaphoreV4")]) + }) + ) +}); + +export const PodspecProofRequestSchema = v.object({ + pods: v.record(v.string(), ProofConfigPODSchemaSchema), + externalNullifier: v.optional(PODValueSchema), + watermark: v.optional(PODValueSchema) +}); + +export const ProveResultSchema = v.variant("success", [ + v.object({ + success: v.literal(true), + // TODO: More specific schemas for these + proof: v.custom(() => true), + boundConfig: v.custom(() => true), + revealedClaims: v.custom(() => true) + }), + v.object({ + success: v.literal(false), + error: v.string() + }) +]); diff --git a/packages/client-rpc/test/schema.test-d.ts b/packages/client-rpc/test/schema.test-d.ts new file mode 100644 index 0000000..3dfff27 --- /dev/null +++ b/packages/client-rpc/test/schema.test-d.ts @@ -0,0 +1,25 @@ +import type { PodspecProofRequest } from "@parcnet-js/podspec"; +import type * as v from "valibot"; +import { assertType, expectTypeOf, test } from "vitest"; +import type { PodspecProofRequestSchema } from "../src/schema_elements.js"; + +type InferredPodspecProofRequest = v.InferOutput< + typeof PodspecProofRequestSchema +>; + +test("type", () => { + expectTypeOf().toMatchTypeOf(); + assertType({ + pods: { + test: { + pod: { + entries: { + name: { + type: "string" + } + } + } + } + } + }); +}); diff --git a/packages/client-rpc/tsconfig.json b/packages/client-rpc/tsconfig.json index 8bc0f87..e5cd142 100644 --- a/packages/client-rpc/tsconfig.json +++ b/packages/client-rpc/tsconfig.json @@ -4,6 +4,6 @@ "outDir": "dist", "strict": true }, - "include": ["src"], + "include": ["src", "test"], "exclude": ["node_modules", "dist"] } diff --git a/packages/podspec/CHANGELOG.md b/packages/podspec/CHANGELOG.md index 8713769..1393fdf 100644 --- a/packages/podspec/CHANGELOG.md +++ b/packages/podspec/CHANGELOG.md @@ -1,5 +1,11 @@ # @parcnet-js/podspec +## 0.0.5 + +### Patch Changes + +- Support for distinct verify and verifyWithProofRequest operations + ## 0.0.4 ### Patch Changes diff --git a/packages/podspec/package.json b/packages/podspec/package.json index ce3d35a..c5e6a8d 100644 --- a/packages/podspec/package.json +++ b/packages/podspec/package.json @@ -1,6 +1,6 @@ { "name": "@parcnet-js/podspec", - "version": "0.0.4", + "version": "0.0.5", "license": "GPL-3.0-or-later", "main": "dist/index.cjs", "module": "dist/index.js", @@ -32,7 +32,7 @@ "lint": "eslint . --max-warnings 0", "build": "tsup 'src/**/*@(ts|tsx)' --format cjs,esm --clean --sourcemap", "prepublish": "tsup 'src/**/*@(ts|tsx)' --format cjs,esm --clean --sourcemap --dts", - "test": "vitest run" + "test": "vitest run --typecheck" }, "files": ["dist", "./README.md", "./LICENSE"], "dependencies": { diff --git a/packages/podspec/test/utils.ts b/packages/podspec/test/utils.ts index 921ef79..9515db0 100644 --- a/packages/podspec/test/utils.ts +++ b/packages/podspec/test/utils.ts @@ -12,7 +12,5 @@ export function generateKeyPair(): { privateKey: string; publicKey: string } { const publicKey = encodePublicKey( derivePublicKey(decodePrivateKey(privateKey)) ); - console.log("privateKey", privateKey); - console.log("publicKey", publicKey); return { privateKey, publicKey }; } diff --git a/packages/ticket-spec/CHANGELOG.md b/packages/ticket-spec/CHANGELOG.md index 6a035c5..acae355 100644 --- a/packages/ticket-spec/CHANGELOG.md +++ b/packages/ticket-spec/CHANGELOG.md @@ -1,5 +1,14 @@ # @parcnet-js/ticket-utils +## 0.0.4 + +### Patch Changes + +- Support for distinct verify and verifyWithProofRequest operations +- Updated dependencies + - @parcnet-js/client-rpc@0.0.6 + - @parcnet-js/podspec@0.0.5 + ## 0.0.3 ### Patch Changes diff --git a/packages/ticket-spec/package.json b/packages/ticket-spec/package.json index 6e33e82..f9bf077 100644 --- a/packages/ticket-spec/package.json +++ b/packages/ticket-spec/package.json @@ -1,6 +1,6 @@ { "name": "@parcnet-js/ticket-spec", - "version": "0.0.3", + "version": "0.0.4", "license": "GPL-3.0-or-later", "type": "module", "main": "dist/index.js", @@ -22,7 +22,7 @@ "build": "tsup 'src/**/*@(ts|tsx)' --format cjs,esm --clean --sourcemap", "prepublish": "tsup 'src/**/*@(ts|tsx)' --format cjs,esm --clean --sourcemap --dts", "lint": "eslint . --max-warnings 0", - "test": "vitest run" + "test": "vitest run --typecheck" }, "files": ["dist", "LICENSE"], "dependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 827ae6a..29a49fd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -347,6 +347,9 @@ importers: typescript: specifier: ^5.5 version: 5.5.4 + vitest: + specifier: ^2.1.2 + version: 2.1.2(@types/node@22.5.5)(terser@5.34.1) packages/eslint-config: devDependencies: @@ -1873,6 +1876,9 @@ packages: '@vitest/expect@2.1.1': resolution: {integrity: sha512-YeueunS0HiHiQxk+KEOnq/QMzlUuOzbU1Go+PgAsHvvv3tUkJPm9xWt+6ITNTlzsMXUjmgm5T+U7KBPK2qQV6w==} + '@vitest/expect@2.1.2': + resolution: {integrity: sha512-FEgtlN8mIUSEAAnlvn7mP8vzaWhEaAEvhSXCqrsijM7K6QqjB11qoRZYEd4AKSCDz8p0/+yH5LzhZ47qt+EyPg==} + '@vitest/mocker@2.1.1': resolution: {integrity: sha512-LNN5VwOEdJqCmJ/2XJBywB11DLlkbY0ooDJW3uRX5cZyYCrc4PI/ePX0iQhE3BiEGiQmK4GE7Q/PqCkkaiPnrA==} peerDependencies: @@ -1885,30 +1891,54 @@ packages: vite: optional: true + '@vitest/mocker@2.1.2': + resolution: {integrity: sha512-ExElkCGMS13JAJy+812fw1aCv2QO/LBK6CyO4WOPAzLTmve50gydOlWhgdBJPx2ztbADUq3JVI0C5U+bShaeEA==} + peerDependencies: + '@vitest/spy': 2.1.2 + msw: ^2.3.5 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + '@vitest/pretty-format@2.0.5': resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==} '@vitest/pretty-format@2.1.1': resolution: {integrity: sha512-SjxPFOtuINDUW8/UkElJYQSFtnWX7tMksSGW0vfjxMneFqxVr8YJ979QpMbDW7g+BIiq88RAGDjf7en6rvLPPQ==} + '@vitest/pretty-format@2.1.2': + resolution: {integrity: sha512-FIoglbHrSUlOJPDGIrh2bjX1sNars5HbxlcsFKCtKzu4+5lpsRhOCVcuzp0fEhAGHkPZRIXVNzPcpSlkoZ3LuA==} + '@vitest/runner@2.0.5': resolution: {integrity: sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==} '@vitest/runner@2.1.1': resolution: {integrity: sha512-uTPuY6PWOYitIkLPidaY5L3t0JJITdGTSwBtwMjKzo5O6RCOEncz9PUN+0pDidX8kTHYjO0EwUIvhlGpnGpxmA==} + '@vitest/runner@2.1.2': + resolution: {integrity: sha512-UCsPtvluHO3u7jdoONGjOSil+uON5SSvU9buQh3lP7GgUXHp78guN1wRmZDX4wGK6J10f9NUtP6pO+SFquoMlw==} + '@vitest/snapshot@2.0.5': resolution: {integrity: sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==} '@vitest/snapshot@2.1.1': resolution: {integrity: sha512-BnSku1WFy7r4mm96ha2FzN99AZJgpZOWrAhtQfoxjUU5YMRpq1zmHRq7a5K9/NjqonebO7iVDla+VvZS8BOWMw==} + '@vitest/snapshot@2.1.2': + resolution: {integrity: sha512-xtAeNsZ++aRIYIUsek7VHzry/9AcxeULlegBvsdLncLmNCR6tR8SRjn8BbDP4naxtccvzTqZ+L1ltZlRCfBZFA==} + '@vitest/spy@2.0.5': resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==} '@vitest/spy@2.1.1': resolution: {integrity: sha512-ZM39BnZ9t/xZ/nF4UwRH5il0Sw93QnZXd9NAZGRpIgj0yvVwPpLd702s/Cx955rGaMlyBQkZJ2Ir7qyY48VZ+g==} + '@vitest/spy@2.1.2': + resolution: {integrity: sha512-GSUi5zoy+abNRJwmFhBDC0yRuVUn8WMlQscvnbbXdKLXX9dE59YbfwXxuJ/mth6eeqIzofU8BB5XDo/Ns/qK2A==} + '@vitest/ui@2.1.1': resolution: {integrity: sha512-IIxo2LkQDA+1TZdPLYPclzsXukBWd5dX2CKpGqH8CCt8Wh0ZuDn4+vuQ9qlppEju6/igDGzjWF/zyorfsf+nHg==} peerDependencies: @@ -1920,6 +1950,9 @@ packages: '@vitest/utils@2.1.1': resolution: {integrity: sha512-Y6Q9TsI+qJ2CC0ZKj6VBb+T8UPz593N113nnUykqwANqhgf3QkZeHFlusgKLTqrnVHbj/XDKZcDHol+dxVT+rQ==} + '@vitest/utils@2.1.2': + resolution: {integrity: sha512-zMO2KdYy6mx56btx9JvAqAZ6EyS3g49krMPPrgOp1yxGZiA93HumGk+bZ5jIZtOg5/VBYl5eBmGRQHqq4FG6uQ==} + '@volar/kit@2.4.5': resolution: {integrity: sha512-ZzyErW5UiDfiIuJ/lpqc2Kx5PHDGDZ/bPlPJYpRcxlrn8Z8aDhRlsLHkNKcNiH65TmNahk2kbLaiejiqu6BD3A==} peerDependencies: @@ -5294,6 +5327,11 @@ packages: engines: {node: ^18.0.0 || >=20.0.0} hasBin: true + vite-node@2.1.2: + resolution: {integrity: sha512-HPcGNN5g/7I2OtPjLqgOtCRu/qhVvBxTUD3qzitmL0SrG1cWFzxzhMDWussxSbrRYWqnKf8P2jiNhPMSN+ymsQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + vite-plugin-node-polyfills@0.22.0: resolution: {integrity: sha512-F+G3LjiGbG8QpbH9bZ//GSBr9i1InSTkaulfUHFa9jkLqVGORFBoqc2A/Yu5Mmh1kNAbiAeKeK+6aaQUf3x0JA==} peerDependencies: @@ -5388,6 +5426,31 @@ packages: jsdom: optional: true + vitest@2.1.2: + resolution: {integrity: sha512-veNjLizOMkRrJ6xxb+pvxN6/QAWg95mzcRjtmkepXdN87FNfxAss9RKe2far/G9cQpipfgP2taqg0KiWsquj8A==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.2 + '@vitest/ui': 2.1.2 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + vm-browserify@1.1.2: resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} @@ -7209,6 +7272,13 @@ snapshots: chai: 5.1.1 tinyrainbow: 1.2.0 + '@vitest/expect@2.1.2': + dependencies: + '@vitest/spy': 2.1.2 + '@vitest/utils': 2.1.2 + chai: 5.1.1 + tinyrainbow: 1.2.0 + '@vitest/mocker@2.1.1(@vitest/spy@2.1.1)(vite@5.4.4(@types/node@22.5.5)(terser@5.34.1))': dependencies: '@vitest/spy': 2.1.1 @@ -7217,6 +7287,14 @@ snapshots: optionalDependencies: vite: 5.4.4(@types/node@22.5.5)(terser@5.34.1) + '@vitest/mocker@2.1.2(@vitest/spy@2.1.2)(vite@5.4.4(@types/node@22.5.5)(terser@5.34.1))': + dependencies: + '@vitest/spy': 2.1.2 + estree-walker: 3.0.3 + magic-string: 0.30.11 + optionalDependencies: + vite: 5.4.4(@types/node@22.5.5)(terser@5.34.1) + '@vitest/pretty-format@2.0.5': dependencies: tinyrainbow: 1.2.0 @@ -7225,6 +7303,10 @@ snapshots: dependencies: tinyrainbow: 1.2.0 + '@vitest/pretty-format@2.1.2': + dependencies: + tinyrainbow: 1.2.0 + '@vitest/runner@2.0.5': dependencies: '@vitest/utils': 2.0.5 @@ -7235,6 +7317,11 @@ snapshots: '@vitest/utils': 2.1.1 pathe: 1.1.2 + '@vitest/runner@2.1.2': + dependencies: + '@vitest/utils': 2.1.2 + pathe: 1.1.2 + '@vitest/snapshot@2.0.5': dependencies: '@vitest/pretty-format': 2.0.5 @@ -7247,6 +7334,12 @@ snapshots: magic-string: 0.30.11 pathe: 1.1.2 + '@vitest/snapshot@2.1.2': + dependencies: + '@vitest/pretty-format': 2.1.2 + magic-string: 0.30.11 + pathe: 1.1.2 + '@vitest/spy@2.0.5': dependencies: tinyspy: 3.0.2 @@ -7255,6 +7348,10 @@ snapshots: dependencies: tinyspy: 3.0.2 + '@vitest/spy@2.1.2': + dependencies: + tinyspy: 3.0.2 + '@vitest/ui@2.1.1(vitest@2.1.1)': dependencies: '@vitest/utils': 2.1.1 @@ -7280,6 +7377,12 @@ snapshots: loupe: 3.1.1 tinyrainbow: 1.2.0 + '@vitest/utils@2.1.2': + dependencies: + '@vitest/pretty-format': 2.1.2 + loupe: 3.1.1 + tinyrainbow: 1.2.0 + '@volar/kit@2.4.5(typescript@5.6.2)': dependencies: '@volar/language-service': 2.4.5 @@ -11718,6 +11821,23 @@ snapshots: - supports-color - terser + vite-node@2.1.2(@types/node@22.5.5)(terser@5.34.1): + dependencies: + cac: 6.7.14 + debug: 4.3.7 + pathe: 1.1.2 + vite: 5.4.4(@types/node@22.5.5)(terser@5.34.1) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vite-plugin-node-polyfills@0.22.0(rollup@4.21.2)(vite@5.4.4(@types/node@20.16.3)(terser@5.34.1)): dependencies: '@rollup/plugin-inject': 5.0.5(rollup@4.21.2) @@ -11869,6 +11989,40 @@ snapshots: - supports-color - terser + vitest@2.1.2(@types/node@22.5.5)(terser@5.34.1): + dependencies: + '@vitest/expect': 2.1.2 + '@vitest/mocker': 2.1.2(@vitest/spy@2.1.2)(vite@5.4.4(@types/node@22.5.5)(terser@5.34.1)) + '@vitest/pretty-format': 2.1.2 + '@vitest/runner': 2.1.2 + '@vitest/snapshot': 2.1.2 + '@vitest/spy': 2.1.2 + '@vitest/utils': 2.1.2 + chai: 5.1.1 + debug: 4.3.7 + magic-string: 0.30.11 + pathe: 1.1.2 + std-env: 3.7.0 + tinybench: 2.9.0 + tinyexec: 0.3.0 + tinypool: 1.0.1 + tinyrainbow: 1.2.0 + vite: 5.4.4(@types/node@22.5.5)(terser@5.34.1) + vite-node: 2.1.2(@types/node@22.5.5)(terser@5.34.1) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.5.5 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vm-browserify@1.1.2: {} volar-service-css@0.0.61(@volar/language-service@2.4.5):