-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
1,132 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
module.exports = { | ||
extends: ["@pcd/eslint-config-custom"], | ||
root: true, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
*.js | ||
*.ts.map | ||
!.eslintrc.js | ||
dist | ||
*.tsbuildinfo |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
{ | ||
"name": "@pcd/pod-email-pcd", | ||
"private": true, | ||
"version": "0.0.0", | ||
"license": "GPL-3.0-or-later", | ||
"main": "./dist/cjs/src/index.js", | ||
"module": "./dist/esm/src/index.js", | ||
"types": "./dist/types/src/index.d.ts", | ||
"exports": { | ||
".": { | ||
"types": "./dist/types/src/index.d.ts", | ||
"import": "./dist/esm/src/index.js", | ||
"require": "./dist/cjs/src/index.js" | ||
} | ||
}, | ||
"files": [ | ||
"dist", | ||
"./README.md", | ||
"./LICENSE" | ||
], | ||
"scripts": { | ||
"lint": "eslint \"**/*.ts{,x}\"", | ||
"build": "tsc -b tsconfig.cjs.json tsconfig.esm.json", | ||
"typecheck": "yarn tsc --noEmit", | ||
"prepublishOnly": "yarn clean && yarn build", | ||
"test": "ts-mocha --type-check --config ../../../.mocharc.js --exit 'test/**/*.spec.ts'", | ||
"clean": "rm -rf dist node_modules *.tsbuildinfo" | ||
}, | ||
"dependencies": { | ||
"@pcd/pcd-types": "0.15.0", | ||
"@pcd/pod": "0.5.0" | ||
}, | ||
"devDependencies": { | ||
"@pcd/eslint-config-custom": "0.15.0", | ||
"@pcd/tsconfig": "0.15.0", | ||
"@types/chai": "^4.3.5", | ||
"@types/mocha": "^10.0.1", | ||
"@zk-kit/eddsa-poseidon": "^1.1.0", | ||
"eslint": "^8.57.0", | ||
"mocha": "^10.2.0", | ||
"ts-mocha": "^10.0.0", | ||
"typescript": "^5.3.3" | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import type { PCD, StringArgument } from "@pcd/pcd-types"; | ||
import type { | ||
PODEdDSAPublicKeyValue, | ||
PODEntries, | ||
PODStringValue | ||
} from "@pcd/pod"; | ||
|
||
export const PODEmailPCDTypeName = "pod-email-pcd"; | ||
|
||
export type PODEmailPCDArgs = { | ||
/** | ||
* The signer's EdDSA private key. This is a 32-byte value used to sign the | ||
* message. See {@link @pcd/pod!decodePrivateKey} in `@pcd/pod` if you need | ||
* to manipulate or convert this value. | ||
*/ | ||
privateKey: StringArgument; | ||
|
||
/** | ||
* The verified email address | ||
*/ | ||
emailAddress: StringArgument; | ||
|
||
/** | ||
* The signer's semaphore v4 public key | ||
* @todo link to documentation on public key format | ||
*/ | ||
semaphoreV4PublicKey: StringArgument; | ||
|
||
/** | ||
* A unique string identifying the PCD | ||
*/ | ||
id: StringArgument; | ||
}; | ||
|
||
export type PODEmailPCDRequiredEntries = { | ||
emailAddress: PODStringValue; | ||
semaphoreV4PublicKey: PODEdDSAPublicKeyValue; | ||
}; | ||
|
||
export interface PODEmailPCDClaim { | ||
podEntries: PODEntries & PODEmailPCDRequiredEntries; | ||
signerPublicKey: string; | ||
} | ||
|
||
export interface PODEmailPCDProof { | ||
signature: string; | ||
} | ||
|
||
export class PODEmailPCD implements PCD<PODEmailPCDClaim, PODEmailPCDProof> { | ||
type = PODEmailPCDTypeName; | ||
claim: PODEmailPCDClaim; | ||
proof: PODEmailPCDProof; | ||
id: string; | ||
|
||
constructor(id: string, claim: PODEmailPCDClaim, proof: PODEmailPCDProof) { | ||
this.id = id; | ||
this.claim = claim; | ||
this.proof = proof; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
import { DisplayOptions, PCDPackage, SerializedPCD } from "@pcd/pcd-types"; | ||
import { POD, PODEntries } from "@pcd/pod"; | ||
import { | ||
PODEmailPCD, | ||
PODEmailPCDArgs, | ||
PODEmailPCDClaim, | ||
PODEmailPCDProof, | ||
PODEmailPCDRequiredEntries, | ||
PODEmailPCDTypeName | ||
} from "./PODEmailPCD"; | ||
|
||
function loadPOD(pcd: PODEmailPCD): POD { | ||
return POD.load( | ||
pcd.claim.podEntries, | ||
pcd.proof.signature, | ||
pcd.claim.signerPublicKey | ||
); | ||
} | ||
|
||
export async function prove(args: PODEmailPCDArgs): Promise<PODEmailPCD> { | ||
if (!args.privateKey.value) { | ||
throw new Error("missing private key"); | ||
} | ||
|
||
if (!args.emailAddress.value) { | ||
throw new Error("missing email value"); | ||
} | ||
|
||
if (!args.semaphoreV4PublicKey.value) { | ||
throw new Error("missing semaphore v4 public key"); | ||
} | ||
|
||
const podEntries: PODEmailPCDRequiredEntries = { | ||
emailAddress: { | ||
type: "string", | ||
value: args.emailAddress.value | ||
}, | ||
semaphoreV4PublicKey: { | ||
type: "eddsa_pubkey", | ||
value: args.semaphoreV4PublicKey.value | ||
} | ||
}; | ||
|
||
const pod = POD.sign(podEntries, args.privateKey.value); | ||
|
||
const id = args.id.value ?? pod.signature; | ||
|
||
return new PODEmailPCD( | ||
id, | ||
{ | ||
podEntries, | ||
signerPublicKey: pod.signerPublicKey | ||
}, | ||
{ | ||
signature: pod.signature | ||
} | ||
); | ||
} | ||
|
||
export async function verify(pcd: PODEmailPCD): Promise<boolean> { | ||
return loadPOD(pcd).verifySignature(); | ||
} | ||
|
||
export async function serialize( | ||
pcd: PODEmailPCD | ||
): Promise<SerializedPCD<PODEmailPCD>> { | ||
return { | ||
type: PODEmailPCDTypeName, | ||
pcd: JSON.stringify({ | ||
id: pcd.id, | ||
pod: loadPOD(pcd).toJSON() | ||
}) | ||
}; | ||
} | ||
|
||
function checkPODEntries( | ||
podEntries: PODEntries | ||
): podEntries is PODEntries & PODEmailPCDRequiredEntries { | ||
if (!podEntries.emailAddress) { | ||
throw new Error("emailAddress entry is missing"); | ||
} | ||
|
||
if (!podEntries.semaphoreV4PublicKey) { | ||
throw new Error("semaphoreV4PublicKey entry is missing"); | ||
} | ||
|
||
if (typeof podEntries.emailAddress.value !== "string") { | ||
throw new Error("emailAddress entry is not a string"); | ||
} | ||
|
||
if (podEntries.semaphoreV4PublicKey.type !== "eddsa_pubkey") { | ||
throw new Error("semaphoreV4PublicKey entry is not an eddsa public key"); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
export async function deserialize(serialized: string): Promise<PODEmailPCD> { | ||
const wrapper = JSON.parse(serialized); | ||
const pod = POD.fromJSON(wrapper.pod); | ||
const podEntries = pod.content.asEntries(); | ||
|
||
if (!checkPODEntries(podEntries)) { | ||
throw new Error("invalid pod entries"); | ||
} | ||
|
||
return new PODEmailPCD( | ||
wrapper.id, | ||
{ | ||
podEntries: podEntries, | ||
signerPublicKey: pod.signerPublicKey | ||
}, | ||
{ signature: pod.signature } | ||
); | ||
} | ||
|
||
export function getDisplayOptions(pcd: PODEmailPCD): DisplayOptions { | ||
return { | ||
header: "Verified Email", | ||
displayName: pcd.claim.podEntries.emailAddress.value | ||
}; | ||
} | ||
|
||
export const PODEmailPCDPackage: PCDPackage< | ||
PODEmailPCDClaim, | ||
PODEmailPCDProof, | ||
PODEmailPCDArgs, | ||
undefined | ||
> = { | ||
name: PODEmailPCDTypeName, | ||
getDisplayOptions, | ||
prove, | ||
verify, | ||
serialize, | ||
deserialize | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export default function (): void { | ||
// Package typescript goes here | ||
} |
Oops, something went wrong.