feat: alpha.9 (#44)

This commit is contained in:
tsukino
2025-04-01 04:35:53 -04:00
committed by GitHub
parent 1ae41917de
commit 95e4e63cf3
9 changed files with 54 additions and 42 deletions

31
package-lock.json generated
View File

@@ -40,7 +40,7 @@
"redux-thunk": "^2.4.2", "redux-thunk": "^2.4.2",
"stream": "^0.0.2", "stream": "^0.0.2",
"tailwindcss": "^3.3.3", "tailwindcss": "^3.3.3",
"tlsn-js": "0.1.0-alpha.7.1", "tlsn-js": "0.1.0-alpha.9",
"tlsn-js-v5": "npm:tlsn-js@0.1.0-alpha.5.4", "tlsn-js-v5": "npm:tlsn-js@0.1.0-alpha.5.4",
"ws": "^8.16.0" "ws": "^8.16.0"
}, },
@@ -22462,12 +22462,12 @@
} }
}, },
"node_modules/tlsn-js": { "node_modules/tlsn-js": {
"version": "0.1.0-alpha.7.1", "version": "0.1.0-alpha.9",
"resolved": "https://registry.npmjs.org/tlsn-js/-/tlsn-js-0.1.0-alpha.7.1.tgz", "resolved": "https://registry.npmjs.org/tlsn-js/-/tlsn-js-0.1.0-alpha.9.tgz",
"integrity": "sha512-EWdRp1VQBfdre8jehJgmDjtDvt01ZL1JWbcscctnFTLIIwMYS7IBxU07UYG0NMZFXeTE8PlrUDEVwEl1+vla+g==", "integrity": "sha512-aEg/Pkdj0Oz9fB3xMUv67Lq69yLbuNS6IzA9j2lDwAmzOfgRBS7ZptcGuLz1hWoNvF1ma7JvdAJpHpL0ee8dkQ==",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"tlsn-wasm": "^0.1.0-alpha.7.2" "tlsn-wasm": "^0.1.0-alpha.9"
}, },
"engines": { "engines": {
"node": ">= 16.20.2" "node": ">= 16.20.2"
@@ -22486,9 +22486,10 @@
} }
}, },
"node_modules/tlsn-wasm": { "node_modules/tlsn-wasm": {
"version": "0.1.0-alpha.7.2", "version": "0.1.0-alpha.9",
"resolved": "https://registry.npmjs.org/tlsn-wasm/-/tlsn-wasm-0.1.0-alpha.7.2.tgz", "resolved": "https://registry.npmjs.org/tlsn-wasm/-/tlsn-wasm-0.1.0-alpha.9.tgz",
"integrity": "sha512-NzrDfOxmFtMHDb4lmMsx6RaS6F+IVXEHxK0zow8jpnx+NryuJ+qnp4380Lq0uj61w/Yuq+yzOhzFe6Bpeo59dA==" "integrity": "sha512-/7DKVXzFdlzD9vwsROb/tvGHJ+xHlAbvaVjMGBWOrecG5KR+Dcg6QMSb4R0/2jePX6u8r6JNXbRpKgQ+yf1zaA==",
"license": "MIT OR Apache-2.0"
}, },
"node_modules/tmpl": { "node_modules/tmpl": {
"version": "1.0.5", "version": "1.0.5",
@@ -40320,11 +40321,11 @@
"optional": true "optional": true
}, },
"tlsn-js": { "tlsn-js": {
"version": "0.1.0-alpha.7.1", "version": "0.1.0-alpha.9",
"resolved": "https://registry.npmjs.org/tlsn-js/-/tlsn-js-0.1.0-alpha.7.1.tgz", "resolved": "https://registry.npmjs.org/tlsn-js/-/tlsn-js-0.1.0-alpha.9.tgz",
"integrity": "sha512-EWdRp1VQBfdre8jehJgmDjtDvt01ZL1JWbcscctnFTLIIwMYS7IBxU07UYG0NMZFXeTE8PlrUDEVwEl1+vla+g==", "integrity": "sha512-aEg/Pkdj0Oz9fB3xMUv67Lq69yLbuNS6IzA9j2lDwAmzOfgRBS7ZptcGuLz1hWoNvF1ma7JvdAJpHpL0ee8dkQ==",
"requires": { "requires": {
"tlsn-wasm": "^0.1.0-alpha.7.2" "tlsn-wasm": "^0.1.0-alpha.9"
} }
}, },
"tlsn-js-v5": { "tlsn-js-v5": {
@@ -40336,9 +40337,9 @@
} }
}, },
"tlsn-wasm": { "tlsn-wasm": {
"version": "0.1.0-alpha.7.2", "version": "0.1.0-alpha.9",
"resolved": "https://registry.npmjs.org/tlsn-wasm/-/tlsn-wasm-0.1.0-alpha.7.2.tgz", "resolved": "https://registry.npmjs.org/tlsn-wasm/-/tlsn-wasm-0.1.0-alpha.9.tgz",
"integrity": "sha512-NzrDfOxmFtMHDb4lmMsx6RaS6F+IVXEHxK0zow8jpnx+NryuJ+qnp4380Lq0uj61w/Yuq+yzOhzFe6Bpeo59dA==" "integrity": "sha512-/7DKVXzFdlzD9vwsROb/tvGHJ+xHlAbvaVjMGBWOrecG5KR+Dcg6QMSb4R0/2jePX6u8r6JNXbRpKgQ+yf1zaA=="
}, },
"tmpl": { "tmpl": {
"version": "1.0.5", "version": "1.0.5",

View File

@@ -58,7 +58,7 @@
"redux-thunk": "^2.4.2", "redux-thunk": "^2.4.2",
"stream": "^0.0.2", "stream": "^0.0.2",
"tailwindcss": "^3.3.3", "tailwindcss": "^3.3.3",
"tlsn-js": "0.1.0-alpha.7.1", "tlsn-js": "0.1.0-alpha.9",
"tlsn-js-v5": "npm:tlsn-js@0.1.0-alpha.5.4", "tlsn-js-v5": "npm:tlsn-js@0.1.0-alpha.5.4",
"ws": "^8.16.0" "ws": "^8.16.0"
}, },

View File

@@ -14,12 +14,12 @@ import { verify } from '../rs/verifier/index.node';
// @ts-ignore // @ts-ignore
import { verify as verifyV7 } from '../rs/0.1.0-alpha.7/index.node'; import { verify as verifyV7 } from '../rs/0.1.0-alpha.7/index.node';
import { Attestation } from '../web/utils/types/types'; import { Attestation } from '../web/utils/types/types';
import { convertNotaryWsToHttp } from '../web/utils';
import { IncomingMessage } from 'node:http'; import { IncomingMessage } from 'node:http';
import { createServer } from 'http'; import { createServer } from 'http';
import { WebSocketServer, type RawData, type WebSocket } from 'ws'; import { WebSocketServer, type RawData, type WebSocket } from 'ws';
import crypto from 'crypto'; import crypto from 'crypto';
import qs from 'qs'; import qs from 'qs';
import { convertNotaryWsToHttp } from '../utils/url';
const app = express(); const app = express();
const port = process.env.PORT || 3000; const port = process.env.PORT || 3000;
@@ -114,7 +114,7 @@ app.get('/ipfs/:cid', async (req, res) => {
notaryUrl: jsonProof.notaryUrl, notaryUrl: jsonProof.notaryUrl,
notaryKey: notaryPem, notaryKey: notaryPem,
}; };
} else if (jsonProof.version === '0.1.0-alpha.7') { } else if (jsonProof.version) {
const notaryUrl = convertNotaryWsToHttp(jsonProof.meta.notaryUrl); const notaryUrl = convertNotaryWsToHttp(jsonProof.meta.notaryUrl);
const notaryPem = await fetchPublicKeyFromNotary(notaryUrl).catch( const notaryPem = await fetchPublicKeyFromNotary(notaryUrl).catch(
() => '', () => '',
@@ -122,7 +122,7 @@ app.get('/ipfs/:cid', async (req, res) => {
const proof = await verifyV7(jsonProof.data, notaryPem); const proof = await verifyV7(jsonProof.data, notaryPem);
proof.notaryUrl = jsonProof.meta.notaryUrl; proof.notaryUrl = jsonProof.meta.notaryUrl;
storeConfig.proofs.ipfs[req.params.cid].proof = { storeConfig.proofs.ipfs[req.params.cid].proof = {
version: '0.1.0-alpha.7', version: jsonProof.version,
time: proof.time, time: proof.time,
sent: proof.sent, sent: proof.sent,
recv: proof.recv, recv: proof.recv,

8
utils/url.ts Normal file
View File

@@ -0,0 +1,8 @@
export function convertNotaryWsToHttp(notaryWs: string) {
const { protocol, pathname, hostname, port } = new URL(notaryWs);
const p = protocol === 'wss:' ? 'https:' : 'http:';
const pt = port ? `:${port}` : '';
const path = pathname === '/' ? '' : pathname.replace('/notarize', '');
const h = hostname === 'localhost' ? '127.0.0.1' : hostname;
return p + '//' + h + pt + path;
}

View File

@@ -7,7 +7,6 @@ import { FileDropdown } from '../FileDropdown';
import { PubkeyInput } from '../../pages/PubkeyInput'; import { PubkeyInput } from '../../pages/PubkeyInput';
import { AttestedData } from '../../utils/types/types'; import { AttestedData } from '../../utils/types/types';
import { File } from '@web-std/file'; import { File } from '@web-std/file';
import { verify } from '../../utils';
export default function SharedProof(): ReactElement { export default function SharedProof(): ReactElement {
const { cid } = useParams(); const { cid } = useParams();
@@ -33,6 +32,8 @@ export default function SharedProof(): ReactElement {
const onVerify = useCallback( const onVerify = useCallback(
async (key = '') => { async (key = '') => {
if (!proofData?.raw) return; if (!proofData?.raw) return;
const { verify } = await import('../../utils');
const resp = await verify(proofData?.raw, key); const resp = await verify(proofData?.raw, key);
setVerifiedProof(resp); setVerifiedProof(resp);
}, },

View File

@@ -1,6 +1,5 @@
import React, { ReactElement, useCallback, useState } from 'react'; import React, { ReactElement, useCallback, useState } from 'react';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { readFileAsync, safeParseJSON, verify } from '../../utils';
import FileUploadInput from '../../components/FileUploadInput'; import FileUploadInput from '../../components/FileUploadInput';
import ProofViewer from '../../components/ProofViewer'; import ProofViewer from '../../components/ProofViewer';
import { import {
@@ -24,6 +23,7 @@ export default function FileDrop(): ReactElement {
const onVerify = useCallback(async (json: Attestation, key = '') => { const onVerify = useCallback(async (json: Attestation, key = '') => {
try { try {
const { verify } = await import('../../utils');
const resp = await verify(json, key); const resp = await verify(json, key);
setVerifiedProof(resp); setVerifiedProof(resp);
setStep('result'); setStep('result');
@@ -54,6 +54,7 @@ export default function FileDrop(): ReactElement {
setError(''); setError('');
const { readFileAsync, safeParseJSON } = await import('../../utils');
const proofContent = await readFileAsync(file); const proofContent = await readFileAsync(file);
const json: Attestation = safeParseJSON(proofContent); const json: Attestation = safeParseJSON(proofContent);

View File

@@ -4,7 +4,6 @@ import { useSelector } from 'react-redux';
import deepEqual from 'fast-deep-equal'; import deepEqual from 'fast-deep-equal';
import { EXPLORER_URL } from '../utils/constants'; import { EXPLORER_URL } from '../utils/constants';
import { Attestation, AttestedData } from '../utils/types/types'; import { Attestation, AttestedData } from '../utils/types/types';
import { verify } from '../utils';
enum ActionType { enum ActionType {
SetIPFSProof = 'proofs/setIPFSProof', SetIPFSProof = 'proofs/setIPFSProof',
@@ -54,9 +53,12 @@ export const fetchProofFromIPFS =
data = old.raw; data = old.raw;
} }
const proof = await verify(data, notaryKey); if (typeof window !== 'undefined') {
const { verify } = await import('../utils');
const proof = await verify(data, notaryKey);
dispatch(setIPFSProof({ cid, proof, raw: data })); dispatch(setIPFSProof({ cid, proof, raw: data }));
}
}; };
export const setIPFSProof = ( export const setIPFSProof = (

View File

@@ -1,5 +1,10 @@
import React, { ReactElement, useRef } from 'react'; import React, { ReactElement, useRef } from 'react';
import { Attestation, AttestedData } from './types/types'; import { Attestation, AttestedData } from './types/types';
import * as Comlink from 'comlink';
import { convertNotaryWsToHttp } from '../../utils/url';
const { init, Presentation }: any = Comlink.wrap(
new Worker(new URL('./worker.ts', import.meta.url)),
);
export const readFileAsync = (file: File): Promise<string> => { export const readFileAsync = (file: File): Promise<string> => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@@ -89,8 +94,6 @@ async function initTlsnJs() {
if (tlsnInitPromise) return tlsnInitPromise; if (tlsnInitPromise) return tlsnInitPromise;
const { promise, resolve } = defer(); const { promise, resolve } = defer();
tlsnInitPromise = promise; tlsnInitPromise = promise;
const { default: init } = await import('tlsn-js');
await init(); await init();
resolve(); resolve();
} }
@@ -117,9 +120,11 @@ export async function verify(
notaryKey: key, notaryKey: key,
}; };
} }
case '0.1.0-alpha.7': { case '0.1.0-alpha.7':
const { Presentation, Transcript } = await import('tlsn-js'); case '0.1.0-alpha.8':
const tlsProof = new Presentation(attestation.data); case '0.1.0-alpha.9':
const { Transcript } = await import('tlsn-js');
const tlsProof = await new Presentation(attestation.data);
const data = await tlsProof.verify(); const data = await tlsProof.verify();
const transcript = new Transcript({ const transcript = new Transcript({
sent: data.transcript.sent, sent: data.transcript.sent,
@@ -133,7 +138,7 @@ export async function verify(
.catch(() => ''); .catch(() => '');
return { return {
version: '0.1.0-alpha.7', version: attestation.version,
sent: transcript.sent(), sent: transcript.sent(),
recv: transcript.recv(), recv: transcript.recv(),
time: data.connection_info.time, time: data.connection_info.time,
@@ -142,21 +147,11 @@ export async function verify(
websocketProxyUrl: attestation.meta.websocketProxyUrl, websocketProxyUrl: attestation.meta.websocketProxyUrl,
verifierKey: verifyingKey, verifierKey: verifyingKey,
}; };
}
} }
throw new Error('Invalid Proof'); throw new Error('Invalid Proof');
} }
export function convertNotaryWsToHttp(notaryWs: string) {
const { protocol, pathname, hostname, port } = new URL(notaryWs);
const p = protocol === 'wss:' ? 'https:' : 'http:';
const pt = port ? `:${port}` : '';
const path = pathname === '/' ? '' : pathname.replace('/notarize', '');
const h = hostname === 'localhost' ? '127.0.0.1' : hostname;
return p + '//' + h + pt + path;
}
function defer(): { function defer(): {
promise: Promise<any>; promise: Promise<any>;
resolve: (args?: any) => any; resolve: (args?: any) => any;

View File

@@ -1,5 +1,9 @@
export interface AttestedData { export interface AttestedData {
version: '0.1.0-alpha.7' | '0.1.0-alpha.5'; version:
| '0.1.0-alpha.7'
| '0.1.0-alpha.8'
| '0.1.0-alpha.9'
| '0.1.0-alpha.5';
time: number; time: number;
sent: string; sent: string;
recv: string; recv: string;
@@ -17,7 +21,7 @@ export type AttestationV0 = {
}; };
export type AttestationV1 = { export type AttestationV1 = {
version: '0.1.0-alpha.7'; version: '0.1.0-alpha.7' | '0.1.0-alpha.8' | '0.1.0-alpha.9';
data: string; data: string;
meta: { meta: {
notaryUrl: string; notaryUrl: string;