diff --git a/demo/react-ts-webpack/src/app.tsx b/demo/react-ts-webpack/src/app.tsx index 56e53f8..1c39da3 100644 --- a/demo/react-ts-webpack/src/app.tsx +++ b/demo/react-ts-webpack/src/app.tsx @@ -9,6 +9,7 @@ import { NotaryServer, Transcript, } from 'tlsn-js'; +import { PresentationJSON } from '../../../build/types'; const { init, Prover, Presentation }: any = Comlink.wrap( new Worker(new URL('./worker.ts', import.meta.url)), @@ -23,7 +24,8 @@ function App(): ReactElement { const [initialized, setInitialized] = useState(false); const [processing, setProcessing] = useState(false); const [result, setResult] = useState(null); - const [proofHex, setProofHex] = useState(null); + const [presentationJSON, setPresentationJSON] = + useState(null); useEffect(() => { (async () => { @@ -84,19 +86,18 @@ function App(): ReactElement { const presentation = (await new Presentation({ attestationHex: notarizationOutputs.attestation, secretsHex: notarizationOutputs.secrets, + notaryUrl: notarizationOutputs.notaryUrl, + websocketProxyUrl: notarizationOutputs.websocketProxyUrl, reveal: commit, })) as TPresentation; - const presentationHex = await presentation.serialize(); - + setPresentationJSON(await presentation.json()); console.timeEnd('proof'); - setProofHex(presentationHex); - }, [setProofHex, setProcessing]); + }, [setPresentationJSON, setProcessing]); const onAltClick = useCallback(async () => { setProcessing(true); - const proof = await Prover.notarize({ - id: 'test', + const proof = await (Prover.notarize as typeof TProver.notarize)({ notaryUrl: 'http://localhost:7047', websocketProxyUrl: 'ws://localhost:55688', url: 'https://swapi.dev/api/people/1', @@ -114,17 +115,18 @@ function App(): ReactElement { }, }); - setProofHex(proof); - }, [setProofHex, setProcessing]); + setPresentationJSON(proof); + }, [setPresentationJSON, setProcessing]); useEffect(() => { (async () => { - if (proofHex) { - const proof = (await new Presentation(proofHex)) as TPresentation; + if (presentationJSON) { + const proof = (await new Presentation( + presentationJSON.data, + )) as TPresentation; const notary = NotaryServer.from(`http://localhost:7047`); - const notaryKey = await notary.publicKey(); + const notaryKey = await notary.publicKey('hex'); const verifierOutput = await proof.verify(); - console.log(verifierOutput, notaryKey); const transcript = new Transcript({ sent: verifierOutput.transcript.sent, recv: verifierOutput.transcript.recv, @@ -133,15 +135,7 @@ function App(): ReactElement { setResult({ time: verifierOutput.connection_info.time, verifyingKey: Buffer.from(vk.data).toString('hex'), - notaryKey: Buffer.from( - notaryKey - .replace('-----BEGIN PUBLIC KEY-----', '') - .replace('-----END PUBLIC KEY-----', '') - .replace(/\n/g, ''), - 'base64', - ) - .slice(23) - .toString('hex'), + notaryKey: notaryKey, serverName: verifierOutput.server_name, sent: transcript.sent(), recv: transcript.recv(), @@ -149,7 +143,7 @@ function App(): ReactElement { setProcessing(false); } })(); - }, [proofHex, setResult]); + }, [presentationJSON, setResult]); return (
@@ -171,9 +165,9 @@ function App(): ReactElement {
Proof: - {!processing && !proofHex ? ( + {!processing && !presentationJSON ? ( not started - ) : !proofHex ? ( + ) : !presentationJSON ? ( <> Proving data from swapi...
View Proof -
{JSON.stringify(proofHex, null, 2)}
+
{JSON.stringify(presentationJSON, null, 2)}
)}
Verification: - {!proofHex ? ( + {!presentationJSON ? ( not started ) : !result ? ( verifying diff --git a/package-lock.json b/package-lock.json index 04c507a..14e436b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "tlsn-js", - "version": "0.1.0-a7.rc.3", + "version": "0.1.0-a7.rc.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "tlsn-js", - "version": "0.1.0-a7.rc.3", + "version": "0.1.0-a7.rc.4", "license": "ISC", "devDependencies": { "@types/expect": "^24.3.0", @@ -35,6 +35,7 @@ "serve": "14.2.1", "serve-handler": "^6.1.5", "stream-browserify": "^3.0.0", + "tlsn-wasm": "0.1.0-alpha.7.1", "ts-loader": "^6.2.1", "ts-mocha": "^10.0.0", "ts-node": "^10.9.2", @@ -13435,6 +13436,12 @@ "node": ">=0.6.0" } }, + "node_modules/tlsn-wasm": { + "version": "0.1.0-alpha.7.1", + "resolved": "https://registry.npmjs.org/tlsn-wasm/-/tlsn-wasm-0.1.0-alpha.7.1.tgz", + "integrity": "sha512-HO0WwqjXOwj69ECI2qqSLuFD1kQJ4PYge1w0G+LxCUthBi76Pw7ZoBpPV+8s1yQR4xAkZkE7rntTFagCXPbuIg==", + "dev": true + }, "node_modules/to-buffer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", @@ -25545,6 +25552,12 @@ "process": "~0.11.0" } }, + "tlsn-wasm": { + "version": "0.1.0-alpha.7.1", + "resolved": "https://registry.npmjs.org/tlsn-wasm/-/tlsn-wasm-0.1.0-alpha.7.1.tgz", + "integrity": "sha512-HO0WwqjXOwj69ECI2qqSLuFD1kQJ4PYge1w0G+LxCUthBi76Pw7ZoBpPV+8s1yQR4xAkZkE7rntTFagCXPbuIg==", + "dev": true + }, "to-buffer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", diff --git a/package.json b/package.json index 75066cb..2e69c62 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tlsn-js", - "version": "0.1.0-a7.rc.3", + "version": "0.1.0-a7.rc.5", "description": "", "repository": "https://github.com/tlsnotary/tlsn-js", "main": "build/lib.js", @@ -55,6 +55,7 @@ "serve": "14.2.1", "serve-handler": "^6.1.5", "stream-browserify": "^3.0.0", + "tlsn-wasm": "0.1.0-alpha.7.1", "ts-loader": "^6.2.1", "ts-mocha": "^10.0.0", "ts-node": "^10.9.2", diff --git a/src/lib.ts b/src/lib.ts index c54109c..eb98dda 100644 --- a/src/lib.ts +++ b/src/lib.ts @@ -18,7 +18,7 @@ import initWasm, { build_presentation, ConnectionInfo, PartialTranscript, -} from '../wasm/pkg/tlsn_wasm'; +} from 'tlsn-wasm'; import { arrayToHex, processTranscript, @@ -26,7 +26,7 @@ import { headerToMap, hexToArray, } from './utils'; -import { ParsedTranscriptData } from './types'; +import { ParsedTranscriptData, PresentationJSON } from './types'; let LOGGING_LEVEL: LoggingLevel = 'Info'; @@ -67,6 +67,8 @@ export default async function init(config?: { export class Prover { #prover: WasmProver; #config: ProverConfig; + #verifierUrl?: string; + #websocketProxyUrl?: string; static async notarize(options: { url: string; @@ -82,7 +84,7 @@ export class Prover { maxRecvDataOnline?: number; deferDecryptionFromStart?: boolean; commit?: Commit; - }) { + }): Promise { const { url, method = 'GET', @@ -128,7 +130,14 @@ export class Prover { const presentation = build_presentation(attestation, secrets, commit); - return arrayToHex(presentation.serialize()); + return { + version: '0.1.0-alpha.7', + data: arrayToHex(presentation.serialize()), + meta: { + notaryUrl: notaryUrl, + websocketProxyUrl: websocketProxyUrl, + }, + }; } constructor(config: { @@ -153,6 +162,7 @@ export class Prover { } async setup(verifierUrl: string): Promise { + this.#verifierUrl = verifierUrl; return this.#prover.setup(verifierUrl); } @@ -213,6 +223,7 @@ export class Prover { status: number; headers: { [key: string]: string }; }> { + this.#websocketProxyUrl = wsProxyUrl; const { url, method = 'GET', headers = {}, body } = request; const headerMap = Prover.getHeaderMap(url, body, headers); @@ -238,9 +249,12 @@ export class Prover { }; } - async notarize( - commit?: Commit, - ): Promise<{ attestation: string; secrets: string }> { + async notarize(commit?: Commit): Promise<{ + attestation: string; + secrets: string; + notaryUrl?: string; + websocketProxyUrl?: string; + }> { const transcript = await this.transcript(); const output = await this.#prover.notarize( commit || { @@ -251,6 +265,8 @@ export class Prover { return { attestation: arrayToHex(output.attestation.serialize()), secrets: arrayToHex(output.secrets.serialize()), + notaryUrl: this.#verifierUrl, + websocketProxyUrl: this.#websocketProxyUrl, }; } @@ -282,12 +298,16 @@ export class Verifier { export class Presentation { #presentation: WasmPresentation; + #notaryUrl?: string; + #websocketProxyUrl?: string; constructor( params: | { attestationHex: string; secretsHex: string; + notaryUrl?: string; + websocketProxyUrl?: string; reveal?: Reveal; } | string, @@ -308,6 +328,8 @@ export class Presentation { recv: [{ start: 0, end: transcript.recv.length }], }, ); + this.#websocketProxyUrl = params.websocketProxyUrl; + this.#notaryUrl = params.notaryUrl; } } @@ -323,6 +345,17 @@ export class Presentation { return this.#presentation.verifying_key(); } + async json(): Promise { + return { + version: '0.1.0-alpha.7', + data: await this.serialize(), + meta: { + notaryUrl: this.#notaryUrl, + websocketProxyUrl: this.#websocketProxyUrl, + }, + }; + } + async verify(): Promise { const { server_name = '', @@ -398,14 +431,27 @@ export class NotaryServer { return this.#url; } - async publicKey(): Promise { + async publicKey(encoding: 'pem' | 'hex' = 'hex'): Promise { const res = await fetch(this.#url + '/info'); const { publicKey } = await res.json(); expect( typeof publicKey === 'string' && !!publicKey.length, 'invalid public key', ); - return publicKey!; + + if (encoding === 'pem') { + return publicKey!; + } + + return Buffer.from( + publicKey! + .replace('-----BEGIN PUBLIC KEY-----', '') + .replace('-----END PUBLIC KEY-----', '') + .replace(/\n/g, ''), + 'base64', + ) + .slice(23) + .toString('hex'); } async sessionUrl( diff --git a/src/types.ts b/src/types.ts index e75b2d8..65d272d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -11,3 +11,13 @@ export type ParsedTranscriptData = { json?: { [path: string]: CommitData }; lineBreaks: CommitData[]; }; + +export type PresentationJSON = { + version: '0.1.0-alpha.7'; + data: string; + meta: { + notaryUrl?: string; + websocketProxyUrl?: string; + pluginUrl?: string; + }; +}; diff --git a/wasm/pkg/package.json b/wasm/pkg/package.json index f1095b0..9f50355 100644 --- a/wasm/pkg/package.json +++ b/wasm/pkg/package.json @@ -1,11 +1,13 @@ { "name": "tlsn-wasm", "type": "module", - "version": "0.1.0-alpha.7", + "version": "0.1.0-alpha.7.1", "files": [ "tlsn_wasm_bg.wasm", + "tlsn_wasm_bg.wasm.d.ts", "tlsn_wasm.js", - "tlsn_wasm.d.ts" + "tlsn_wasm.d.ts", + "snippets/" ], "main": "tlsn_wasm.js", "types": "tlsn_wasm.d.ts",