mirror of
https://github.com/tlsnotary/tlsn-extension.git
synced 2026-01-09 13:08:04 -05:00
Compare commits
28 Commits
iv
...
hackathon2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1dc26d9ef | ||
|
|
2587f11adc | ||
|
|
a8b9449e70 | ||
|
|
37f48c7b9e | ||
|
|
b943adeb80 | ||
|
|
a0fba10d7a | ||
|
|
0904f50c1b | ||
|
|
b1bfa543a2 | ||
|
|
87f5d7c375 | ||
|
|
b373e7384d | ||
|
|
125f35eeb4 | ||
|
|
6c18010614 | ||
|
|
e0686a50f4 | ||
|
|
6e5dee2962 | ||
|
|
89d86659b6 | ||
|
|
bc73567f48 | ||
|
|
c43e5faef2 | ||
|
|
aabb2eca65 | ||
|
|
d36a101c4e | ||
|
|
41e5222873 | ||
|
|
eaeb2cfb7c | ||
|
|
8e42ec5f50 | ||
|
|
ae846e787c | ||
|
|
f49fe3b8a2 | ||
|
|
aeeb0d2b7b | ||
|
|
e2917b7f61 | ||
|
|
473affa847 | ||
|
|
ac2bd69f25 |
247
src/components/ChatBox/index.tsx
Normal file
247
src/components/ChatBox/index.tsx
Normal file
@@ -0,0 +1,247 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import {
|
||||
Chat,
|
||||
requestProof,
|
||||
RequestProofMessage,
|
||||
sendChat,
|
||||
useChatMessages,
|
||||
useClientId,
|
||||
usePairId,
|
||||
} from '../../reducers/p2p';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import classNames from 'classnames';
|
||||
import Icon from '../Icon';
|
||||
import init, {
|
||||
Prover,
|
||||
Verifier,
|
||||
} from '../../../tlsn/tlsn/tlsn-wasm/pkg/tlsn_wasm';
|
||||
import { RENDEZVOUS_API } from '../../utils/constants';
|
||||
import PluginModal from '../PluginModal';
|
||||
import PluginDisplayBox, { PluginParams } from '../PluginDisplayBox';
|
||||
import { get, PROXY_API_LS_KEY } from '../../utils/storage';
|
||||
import { urlify } from '../../utils/misc';
|
||||
import { useRequests } from '../../reducers/requests';
|
||||
|
||||
export default function ChatBox() {
|
||||
const messages = useChatMessages();
|
||||
const dispatch = useDispatch();
|
||||
const clientId = useClientId();
|
||||
const [text, setText] = useState('');
|
||||
const pairId = usePairId();
|
||||
const [showingPluginModal, showPluginModal] = useState(false);
|
||||
const requests = useRequests();
|
||||
|
||||
const onSend = useCallback(() => {
|
||||
if (text && pairId) {
|
||||
dispatch(
|
||||
sendChat({
|
||||
text,
|
||||
from: clientId,
|
||||
to: pairId,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}, [text, pairId, clientId]);
|
||||
|
||||
const handleKeyDown = useCallback(
|
||||
(e: React.KeyboardEvent) => {
|
||||
if (e.key === 'Enter' && text && pairId) {
|
||||
onSend();
|
||||
setText('');
|
||||
}
|
||||
},
|
||||
[text],
|
||||
);
|
||||
|
||||
const onIProve = useCallback(
|
||||
async (config: {
|
||||
method: string;
|
||||
uri: string;
|
||||
headers: { [key: string]: string };
|
||||
}) => {
|
||||
await init();
|
||||
const websocketProxyUrl = await get(
|
||||
PROXY_API_LS_KEY,
|
||||
'wss://notary.pse.dev/proxy',
|
||||
);
|
||||
const hostname = urlify(config.uri)?.hostname || '';
|
||||
const prover = new Prover({
|
||||
id: 'p2p_proof',
|
||||
server_dns: hostname,
|
||||
// max_sent_data: 1024,
|
||||
// max_received_data: 1024,
|
||||
});
|
||||
await prover.setup(`${RENDEZVOUS_API}?clientId=${clientId}:proof`);
|
||||
await prover.send_request(
|
||||
`${websocketProxyUrl}?token=${hostname}`,
|
||||
config,
|
||||
);
|
||||
const redact = {
|
||||
sent: [],
|
||||
received: [],
|
||||
};
|
||||
const resp = await prover.reveal(redact);
|
||||
console.log(resp, redact);
|
||||
},
|
||||
[clientId, pairId],
|
||||
);
|
||||
|
||||
const onNotarize = useCallback(
|
||||
async (url: string) => {
|
||||
const reqs = requests.filter((req) => {
|
||||
return req?.url?.includes(url);
|
||||
});
|
||||
const req = reqs[0];
|
||||
const hostname = urlify(req.url)?.hostname || '';
|
||||
const headers: { [k: string]: string } = req.requestHeaders.reduce(
|
||||
(acc: any, h) => {
|
||||
acc[h.name] = h.value;
|
||||
return acc;
|
||||
},
|
||||
{ Host: hostname },
|
||||
);
|
||||
headers['Accept-Encoding'] = 'identity';
|
||||
headers['Connection'] = 'close';
|
||||
onIProve({
|
||||
method: req.method,
|
||||
uri: req.url,
|
||||
headers: headers,
|
||||
});
|
||||
},
|
||||
[onIProve],
|
||||
);
|
||||
|
||||
const onRequestProof = useCallback(
|
||||
async (plugin: PluginParams) => {
|
||||
await init();
|
||||
const verifier = new Verifier({
|
||||
id: 'p2p_proof',
|
||||
// max_sent_data: 1024,
|
||||
// max_received_data: 1024,
|
||||
});
|
||||
await verifier.connect(`${RENDEZVOUS_API}?clientId=${clientId}:proof`);
|
||||
dispatch(
|
||||
requestProof({
|
||||
plugin,
|
||||
from: clientId,
|
||||
to: pairId,
|
||||
}),
|
||||
);
|
||||
showPluginModal(false);
|
||||
const res = await verifier.verify();
|
||||
console.log(res);
|
||||
dispatch(
|
||||
sendChat({
|
||||
text: JSON.stringify(res),
|
||||
from: clientId,
|
||||
to: pairId,
|
||||
}),
|
||||
);
|
||||
},
|
||||
[clientId, pairId],
|
||||
);
|
||||
|
||||
const isClient = (msg: any) => {
|
||||
return msg.from === clientId;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col flex-nowrap flex-grow gap-1 p-2 flex-shrink h-0 ">
|
||||
{showingPluginModal && (
|
||||
<PluginModal
|
||||
onClose={() => showPluginModal(false)}
|
||||
onSelect={onRequestProof}
|
||||
/>
|
||||
)}
|
||||
<div className="flex flex-row gap-1 font-semibold text-xs align-center">
|
||||
<div>Client ID:</div>
|
||||
{clientId ? (
|
||||
<div className="text-green-500">{clientId}</div>
|
||||
) : (
|
||||
<Icon
|
||||
className="animate-spin text-gray-500"
|
||||
fa="fa-solid fa-spinner"
|
||||
size={1}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-row gap-1 font-semibold text-xs align-center">
|
||||
<div>Peer ID:</div>
|
||||
{pairId ? (
|
||||
<div className="text-red-500">{pairId}</div>
|
||||
) : (
|
||||
<div className="flex flex-row gap-1">
|
||||
<span className="text-slate-500">Waiting for Peer</span>
|
||||
<Icon
|
||||
className="animate-spin text-slate-500 w-fit"
|
||||
fa="fa-solid fa-spinner"
|
||||
size={1}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col flex-grow flex-shrink h-0 gap-1">
|
||||
<div className="flex flex-col border gap-1 border-slate-200 flex-grow overflow-y-auto p-2">
|
||||
{messages.map((msg: Chat | RequestProofMessage) => {
|
||||
return (
|
||||
<div
|
||||
className={classNames(`p-2 max-w-[50%] break-all`, {
|
||||
'mr-auto bg-blue-600 rounded-t-lg rounded-br-lg':
|
||||
isClient(msg),
|
||||
'ml-auto bg-slate-300 rounded-b-lg rounded-tl-lg':
|
||||
!isClient(msg),
|
||||
})}
|
||||
>
|
||||
{typeof msg.text === 'string' && (
|
||||
<div
|
||||
className={`${isClient(msg) ? 'text-white' : 'text-black'}`}
|
||||
>
|
||||
{msg.text}
|
||||
</div>
|
||||
)}
|
||||
{typeof msg.plugin !== 'undefined' && (
|
||||
<div
|
||||
className={`${isClient(msg) ? 'text-white' : 'text-black'}`}
|
||||
>
|
||||
<PluginDisplayBox
|
||||
{...msg.plugin}
|
||||
hideAction={isClient(msg)}
|
||||
onNotarize={() => onNotarize(msg.plugin.url)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="flex flex-row w-full gap-1">
|
||||
<input
|
||||
className="input border border-slate-200 focus:border-slate-400 flex-grow p-2"
|
||||
onChange={(e) => setText(e.target.value)}
|
||||
onKeyDown={handleKeyDown}
|
||||
value={text}
|
||||
autoFocus
|
||||
/>
|
||||
<button
|
||||
className={classNames('button', {
|
||||
'button--primary': !!pairId,
|
||||
})}
|
||||
// disabled={!pairId}
|
||||
onClick={() => showPluginModal(true)}
|
||||
>
|
||||
Request Proof
|
||||
</button>
|
||||
<button
|
||||
className={classNames('button', {
|
||||
'button--primary': !!text && !!pairId,
|
||||
})}
|
||||
disabled={!text || !pairId}
|
||||
onClick={onSend}
|
||||
>
|
||||
Send
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -50,7 +50,7 @@ export function ModalHeader(props: HeaderProps): ReactElement {
|
||||
<div
|
||||
className={classNames(
|
||||
'flex flex-row items-center justify-center',
|
||||
'p-2 rounded-full opacity-50',
|
||||
'rounded-full opacity-50',
|
||||
'hover:opacity-100 text-black',
|
||||
)}
|
||||
>
|
||||
|
||||
157
src/components/PluginDisplayBox/index.tsx
Normal file
157
src/components/PluginDisplayBox/index.tsx
Normal file
@@ -0,0 +1,157 @@
|
||||
import { replayRequest, urlify } from '../../utils/misc';
|
||||
import { get, NOTARY_API_LS_KEY, PROXY_API_LS_KEY } from '../../utils/storage';
|
||||
import { notarizeRequest, useRequests } from '../../reducers/requests';
|
||||
import React, { ReactElement, useCallback } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useNavigate } from 'react-router';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export type PluginParams = {
|
||||
method: string;
|
||||
url: string;
|
||||
targetUrl: string;
|
||||
type: string;
|
||||
title: string;
|
||||
description: string;
|
||||
responseSelector: string;
|
||||
valueTransform: string;
|
||||
};
|
||||
|
||||
type Props = PluginParams & {
|
||||
className?: string;
|
||||
hideAction?: boolean;
|
||||
onClick?: () => void;
|
||||
onNotarize?: () => Promise<void>;
|
||||
};
|
||||
|
||||
export default function PluginDisplayBox(props: Props): ReactElement {
|
||||
const {
|
||||
method,
|
||||
type,
|
||||
title,
|
||||
description,
|
||||
responseSelector,
|
||||
valueTransform,
|
||||
targetUrl,
|
||||
url,
|
||||
className = '',
|
||||
hideAction = false,
|
||||
onClick,
|
||||
} = props;
|
||||
|
||||
const requests = useRequests();
|
||||
const dispatch = useDispatch();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const reqs = requests.filter((req) => {
|
||||
return req?.url?.includes(url);
|
||||
});
|
||||
|
||||
const bmHost = urlify(targetUrl)?.host;
|
||||
const isReady = !!reqs.length;
|
||||
|
||||
const onNotarize = useCallback(async () => {
|
||||
if (!isReady) return;
|
||||
|
||||
const req = reqs[0];
|
||||
const res = await replayRequest(req);
|
||||
const secretHeaders = req.requestHeaders
|
||||
.map((h) => {
|
||||
return `${h.name.toLowerCase()}: ${h.value || ''}` || '';
|
||||
})
|
||||
.filter((d) => !!d);
|
||||
const selectedValue = res.match(new RegExp(responseSelector, 'g'));
|
||||
|
||||
if (selectedValue) {
|
||||
const revealed = valueTransform.replace('%s', selectedValue[0]);
|
||||
const selectionStart = res.indexOf(revealed);
|
||||
const selectionEnd = selectionStart + revealed.length - 1;
|
||||
const secretResps = [
|
||||
res.substring(0, selectionStart),
|
||||
res.substring(selectionEnd, res.length),
|
||||
].filter((d) => !!d);
|
||||
|
||||
const hostname = urlify(req.url)?.hostname;
|
||||
const notaryUrl = await get(
|
||||
NOTARY_API_LS_KEY,
|
||||
'https://notary.pse.dev/v0.1.0-alpha.5',
|
||||
);
|
||||
const websocketProxyUrl = await get(
|
||||
PROXY_API_LS_KEY,
|
||||
'wss://notary.pse.dev/proxy',
|
||||
);
|
||||
|
||||
const headers: { [k: string]: string } = req.requestHeaders.reduce(
|
||||
(acc: any, h) => {
|
||||
acc[h.name] = h.value;
|
||||
return acc;
|
||||
},
|
||||
{ Host: hostname },
|
||||
);
|
||||
|
||||
//TODO: for some reason, these needs to be override to work
|
||||
headers['Accept-Encoding'] = 'identity';
|
||||
headers['Connection'] = 'close';
|
||||
|
||||
dispatch(
|
||||
// @ts-ignore
|
||||
notarizeRequest({
|
||||
url: req.url,
|
||||
method: req.method,
|
||||
headers: headers,
|
||||
body: req.requestBody,
|
||||
maxTranscriptSize: 16384,
|
||||
notaryUrl,
|
||||
websocketProxyUrl,
|
||||
secretHeaders,
|
||||
secretResps,
|
||||
}),
|
||||
);
|
||||
|
||||
navigate(`/history`);
|
||||
}
|
||||
}, [
|
||||
isReady,
|
||||
reqs[0],
|
||||
method,
|
||||
type,
|
||||
title,
|
||||
description,
|
||||
responseSelector,
|
||||
valueTransform,
|
||||
targetUrl,
|
||||
url,
|
||||
]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames('flex flex-col flex-nowrap p-2 gap-1', className)}
|
||||
onClick={onClick}
|
||||
>
|
||||
<div className="flex flex-row items-center text-xs">
|
||||
<div className="bg-slate-200 text-slate-400 px-1 py-0.5 rounded-sm">
|
||||
{method}
|
||||
</div>
|
||||
<div className="text-slate-400 px-2 py-1 rounded-md">{type}</div>
|
||||
</div>
|
||||
<div className="font-bold">{title}</div>
|
||||
<div className="italic">{description}</div>
|
||||
{isReady && !hideAction && (
|
||||
<button
|
||||
className="button button--primary w-fit self-end mt-2"
|
||||
onClick={props.onNotarize || onNotarize}
|
||||
>
|
||||
Notarize
|
||||
</button>
|
||||
)}
|
||||
{!isReady && !hideAction && (
|
||||
<button
|
||||
className="button w-fit self-end mt-2"
|
||||
onClick={() => chrome.tabs.update({ url: targetUrl })}
|
||||
>
|
||||
{`Go to ${bmHost}`}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
5
src/components/PluginModal/index.scss
Normal file
5
src/components/PluginModal/index.scss
Normal file
@@ -0,0 +1,5 @@
|
||||
.plugin-modal {
|
||||
height: calc(100% - 2rem);
|
||||
margin: 1rem;
|
||||
width: calc(100% - 2rem) !important;
|
||||
}
|
||||
36
src/components/PluginModal/index.tsx
Normal file
36
src/components/PluginModal/index.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import React, { ReactElement, useCallback } from 'react';
|
||||
import bookmarks from '../../../utils/bookmark/bookmarks.json';
|
||||
import Modal, { ModalContent, ModalHeader } from '../Modal/Modal';
|
||||
import PluginDisplayBox, { type PluginParams } from '../PluginDisplayBox';
|
||||
import './index.scss';
|
||||
|
||||
type Props = {
|
||||
onClose: () => void;
|
||||
onSelect?: (plugin: PluginParams) => void;
|
||||
};
|
||||
|
||||
export default function PluginModal(props: Props): ReactElement {
|
||||
const onClick = useCallback(
|
||||
(plugin: PluginParams) => {
|
||||
if (props.onSelect) props.onSelect(plugin);
|
||||
},
|
||||
[props.onSelect],
|
||||
);
|
||||
|
||||
return (
|
||||
<Modal className="plugin-modal" onClose={props.onClose}>
|
||||
<ModalHeader onClose={props.onClose}>Choose a plugin</ModalHeader>
|
||||
<ModalContent>
|
||||
{bookmarks.map((bookmark, i) => (
|
||||
<PluginDisplayBox
|
||||
key={i}
|
||||
className="border-b border-slate-100 hover:bg-slate-50 cursor-pointer"
|
||||
onClick={() => onClick(bookmark)}
|
||||
{...bookmark}
|
||||
hideAction
|
||||
/>
|
||||
))}
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
@@ -18,7 +18,10 @@ import Notarize from '../../pages/Notarize';
|
||||
import ProofViewer from '../../pages/ProofViewer';
|
||||
import History from '../../pages/History';
|
||||
import ProofUploader from '../../pages/ProofUploader';
|
||||
import Connect from '../../pages/Connect';
|
||||
import browser from 'webextension-polyfill';
|
||||
import P2P from '../../pages/P2P';
|
||||
import CreateSession from '../../pages/CreateSession';
|
||||
|
||||
const Popup = () => {
|
||||
const dispatch = useDispatch();
|
||||
@@ -79,6 +82,9 @@ const Popup = () => {
|
||||
<Route path="/custom/*" element={<RequestBuilder />} />
|
||||
<Route path="/options" element={<Options />} />
|
||||
<Route path="/home" element={<Home />} />
|
||||
<Route path="/connect-session" element={<Connect />} />
|
||||
<Route path="/create-session" element={<CreateSession />} />
|
||||
<Route path="/p2p" element={<P2P />} />
|
||||
<Route path="*" element={<Navigate to="/home" />} />
|
||||
</Routes>
|
||||
</div>
|
||||
|
||||
64
src/pages/Connect/index.tsx
Normal file
64
src/pages/Connect/index.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import { sendPairRequest } from '../../reducers/p2p';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useNavigate } from 'react-router';
|
||||
import { usePairId } from '../../reducers/p2p';
|
||||
import Icon from '../../components/Icon';
|
||||
|
||||
export default function Connect() {
|
||||
const dispatch = useDispatch();
|
||||
const [peerId, setPeerId] = useState('');
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const pairId = usePairId();
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
if (pairId && loading) {
|
||||
console.log('Connected to peer', pairId);
|
||||
setLoading(false);
|
||||
navigate('/create-session');
|
||||
}
|
||||
}, [pairId]);
|
||||
|
||||
const connect = useCallback(() => {
|
||||
if (peerId) {
|
||||
console.log('Connecting to peer', peerId);
|
||||
dispatch(sendPairRequest(peerId));
|
||||
setLoading(true);
|
||||
} else {
|
||||
console.log('No peer ID provided');
|
||||
}
|
||||
}, [peerId]);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col justify-center items-center bg-slate-200 p-4 rounded border-slate-400 m-4 gap-2">
|
||||
<h1 className="text-base font-semibold">Enter peer ID to connect to</h1>
|
||||
<input
|
||||
className="input border border-slate-200 focus:border-slate-400 w-full"
|
||||
type="text"
|
||||
value={peerId}
|
||||
onChange={(e) => setPeerId(e.target.value)}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') connect();
|
||||
}}
|
||||
autoFocus
|
||||
/>
|
||||
<button
|
||||
className="button button--primary"
|
||||
disabled={!peerId || loading}
|
||||
onClick={connect}
|
||||
>
|
||||
{loading ? (
|
||||
<Icon
|
||||
className="animate-spin text-white"
|
||||
fa="fa-solid fa-spinner"
|
||||
size={1}
|
||||
/>
|
||||
) : (
|
||||
'Connect'
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
7
src/pages/CreateSession/index.tsx
Normal file
7
src/pages/CreateSession/index.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import type {} from 'redux-thunk/extend-redux';
|
||||
import React, { ReactElement, useEffect } from 'react';
|
||||
import ChatBox from '../../components/ChatBox';
|
||||
|
||||
export default function CreateSession(): ReactElement {
|
||||
return <ChatBox />;
|
||||
}
|
||||
@@ -1,29 +1,17 @@
|
||||
import React, {
|
||||
MouseEventHandler,
|
||||
ReactElement,
|
||||
ReactNode,
|
||||
useCallback,
|
||||
useState,
|
||||
} from 'react';
|
||||
import React, { MouseEventHandler, ReactElement, ReactNode } from 'react';
|
||||
import Icon from '../../components/Icon';
|
||||
import classNames from 'classnames';
|
||||
import { useNavigate } from 'react-router';
|
||||
import {
|
||||
notarizeRequest,
|
||||
useActiveTabUrl,
|
||||
useRequests,
|
||||
} from '../../reducers/requests';
|
||||
import { useActiveTabUrl, useRequests } from '../../reducers/requests';
|
||||
import { Link } from 'react-router-dom';
|
||||
import bookmarks from '../../../utils/bookmark/bookmarks.json';
|
||||
import { replayRequest, urlify } from '../../utils/misc';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { get, NOTARY_API_LS_KEY, PROXY_API_LS_KEY } from '../../utils/storage';
|
||||
import PluginDisplayBox from '../../components/PluginDisplayBox';
|
||||
|
||||
export default function Home(): ReactElement {
|
||||
const requests = useRequests();
|
||||
const url = useActiveTabUrl();
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-4 py-4 overflow-y-auto">
|
||||
@@ -32,14 +20,11 @@ export default function Home(): ReactElement {
|
||||
<span>Requests</span>
|
||||
<span>{`(${requests.length})`}</span>
|
||||
</NavButton>
|
||||
<NavButton
|
||||
fa="fa-solid fa-magnifying-glass"
|
||||
onClick={() => navigate('/custom')}
|
||||
>
|
||||
<NavButton fa="fa-solid fa-hammer" onClick={() => navigate('/custom')}>
|
||||
Custom
|
||||
</NavButton>
|
||||
<NavButton
|
||||
fa="fa-solid fa-magnifying-glass"
|
||||
fa="fa-solid fa-certificate"
|
||||
onClick={() => navigate('/verify')}
|
||||
>
|
||||
Verify
|
||||
@@ -50,6 +35,12 @@ export default function Home(): ReactElement {
|
||||
<NavButton fa="fa-solid fa-gear" onClick={() => navigate('/options')}>
|
||||
Options
|
||||
</NavButton>
|
||||
<NavButton
|
||||
fa="fa-solid fa-people-arrows"
|
||||
onClick={() => navigate('/p2p')}
|
||||
>
|
||||
P2P
|
||||
</NavButton>
|
||||
</div>
|
||||
{!bookmarks.length && (
|
||||
<div className="flex flex-col flex-nowrap">
|
||||
@@ -62,115 +53,9 @@ export default function Home(): ReactElement {
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-col px-4 gap-4">
|
||||
{bookmarks.map((bm, i) => {
|
||||
try {
|
||||
const reqs = requests.filter((req) => {
|
||||
return req?.url?.includes(bm.url);
|
||||
});
|
||||
|
||||
const bmHost = urlify(bm.targetUrl)?.host;
|
||||
const isReady = !!reqs.length;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={i}
|
||||
className="flex flex-col flex-nowrap border rounded-md p-2 gap-1 hover:bg-slate-50 cursor-pointer"
|
||||
>
|
||||
<div className="flex flex-row items-center text-xs">
|
||||
<div className="bg-slate-200 text-slate-400 px-1 py-0.5 rounded-sm">
|
||||
{bm.method}
|
||||
</div>
|
||||
<div className="text-slate-400 px-2 py-1 rounded-md">
|
||||
{bm.type}
|
||||
</div>
|
||||
</div>
|
||||
<div className="font-bold">{bm.title}</div>
|
||||
<div className="italic">{bm.description}</div>
|
||||
{isReady && (
|
||||
<button
|
||||
className="button button--primary w-fit self-end mt-2"
|
||||
onClick={async () => {
|
||||
if (!isReady) return;
|
||||
|
||||
const req = reqs[0];
|
||||
const res = await replayRequest(req);
|
||||
const secretHeaders = req.requestHeaders
|
||||
.map((h) => {
|
||||
return (
|
||||
`${h.name.toLowerCase()}: ${h.value || ''}` || ''
|
||||
);
|
||||
})
|
||||
.filter((d) => !!d);
|
||||
const selectedValue = res.match(
|
||||
new RegExp(bm.responseSelector, 'g'),
|
||||
);
|
||||
|
||||
if (selectedValue) {
|
||||
const revealed = bm.valueTransform.replace(
|
||||
'%s',
|
||||
selectedValue[0],
|
||||
);
|
||||
const selectionStart = res.indexOf(revealed);
|
||||
const selectionEnd =
|
||||
selectionStart + revealed.length - 1;
|
||||
const secretResps = [
|
||||
res.substring(0, selectionStart),
|
||||
res.substring(selectionEnd, res.length),
|
||||
].filter((d) => !!d);
|
||||
|
||||
const hostname = urlify(req.url)?.hostname;
|
||||
const notaryUrl = await get(NOTARY_API_LS_KEY);
|
||||
const websocketProxyUrl = await get(PROXY_API_LS_KEY);
|
||||
|
||||
const headers: { [k: string]: string } =
|
||||
req.requestHeaders.reduce(
|
||||
(acc: any, h) => {
|
||||
acc[h.name] = h.value;
|
||||
return acc;
|
||||
},
|
||||
{ Host: hostname },
|
||||
);
|
||||
|
||||
//TODO: for some reason, these needs to be override to work
|
||||
headers['Accept-Encoding'] = 'identity';
|
||||
headers['Connection'] = 'close';
|
||||
|
||||
dispatch(
|
||||
// @ts-ignore
|
||||
notarizeRequest({
|
||||
url: req.url,
|
||||
method: req.method,
|
||||
headers: headers,
|
||||
body: req.requestBody,
|
||||
maxTranscriptSize: 16384,
|
||||
notaryUrl,
|
||||
websocketProxyUrl,
|
||||
secretHeaders,
|
||||
secretResps,
|
||||
}),
|
||||
);
|
||||
|
||||
navigate(`/history`);
|
||||
}
|
||||
}}
|
||||
>
|
||||
Notarize
|
||||
</button>
|
||||
)}
|
||||
{!isReady && (
|
||||
<button
|
||||
className="button w-fit self-end mt-2"
|
||||
onClick={() => chrome.tabs.update({ url: bm.targetUrl })}
|
||||
>
|
||||
{`Go to ${bmHost}`}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
})}
|
||||
{bookmarks.map((bm, i) => (
|
||||
<PluginDisplayBox className="border rounded-md" key={i} {...bm} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -9,6 +9,9 @@ import {
|
||||
export default function Options(): ReactElement {
|
||||
const [notary, setNotary] = useState('https://notary.pse.dev/v0.1.0-alpha.5');
|
||||
const [proxy, setProxy] = useState('wss://notary.pse.dev/proxy');
|
||||
const [rendezvous, setRendezvous] = useState(
|
||||
'wss://notary.pse.dev/rendezvous',
|
||||
);
|
||||
const [dirty, setDirty] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -55,6 +58,19 @@ export default function Options(): ReactElement {
|
||||
value={proxy}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col flex-nowrap py-1 px-2 gap-2">
|
||||
<div className="font-semibold">Rendezvous API</div>
|
||||
<input
|
||||
type="text"
|
||||
className="input border"
|
||||
placeholder="wss://notary.pse.dev/rendezvous"
|
||||
onChange={(e) => {
|
||||
setRendezvous(e.target.value);
|
||||
setDirty(true);
|
||||
}}
|
||||
value={rendezvous}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-row flex-nowrap justify-end gap-2 p-2">
|
||||
<button
|
||||
className="button !bg-primary/[0.9] hover:bg-primary/[0.8] active:bg-primary !text-white"
|
||||
|
||||
30
src/pages/P2P/index.tsx
Normal file
30
src/pages/P2P/index.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import React, { ReactElement, useEffect } from 'react';
|
||||
import { useNavigate } from 'react-router';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { connectSession } from '../../reducers/p2p';
|
||||
|
||||
export default function P2P(): ReactElement {
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(connectSession());
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col flex-nowrap flex-grow gap-2 m-4">
|
||||
<button
|
||||
className="button button--primary mx-20 brea"
|
||||
onClick={() => navigate('/create-session')}
|
||||
>
|
||||
Create Session
|
||||
</button>
|
||||
<button
|
||||
className="button button--primary mx-20"
|
||||
onClick={() => navigate('/connect-session')}
|
||||
>
|
||||
Connect to Session
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
import { combineReducers } from 'redux';
|
||||
import requests from './requests';
|
||||
import history from './history';
|
||||
import p2p from './p2p';
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
requests,
|
||||
history,
|
||||
p2p,
|
||||
});
|
||||
|
||||
export type AppRootState = ReturnType<typeof rootReducer>;
|
||||
|
||||
316
src/reducers/p2p.tsx
Normal file
316
src/reducers/p2p.tsx
Normal file
@@ -0,0 +1,316 @@
|
||||
import { useSelector } from 'react-redux';
|
||||
import { AppRootState } from './index';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
import { safeParseJSON } from '../utils/misc';
|
||||
import { Dispatch } from 'redux';
|
||||
import { RENDEZVOUS_API } from '../utils/constants';
|
||||
import { PluginParams } from '../components/PluginDisplayBox';
|
||||
|
||||
enum ActionType {
|
||||
'/p2p/createSession' = '/p2p/createSession',
|
||||
'/p2p/setConnected' = '/p2p/setConnected',
|
||||
'/p2p/setClientId' = '/p2p/setClientId',
|
||||
'/p2p/setSocket' = '/p2p/setSocket',
|
||||
'/p2p/appendMessage' = '/p2p/appendMessage',
|
||||
'/p2p/setMessages' = '/p2p/setMessages',
|
||||
'/p2p/setPairing' = '/p2p/setPairing',
|
||||
}
|
||||
|
||||
type Action<payload> = {
|
||||
type: ActionType;
|
||||
payload?: payload;
|
||||
error?: boolean;
|
||||
meta?: any;
|
||||
};
|
||||
|
||||
type State = {
|
||||
clientId: string;
|
||||
pairing: string;
|
||||
socket: WebSocket | null;
|
||||
connected: boolean;
|
||||
messages: (Chat | RequestProofMessage)[];
|
||||
};
|
||||
|
||||
export type Chat = {
|
||||
to: string;
|
||||
from: string;
|
||||
text: string;
|
||||
id: number;
|
||||
plugin?: undefined;
|
||||
};
|
||||
|
||||
export type RequestProofMessage = {
|
||||
to: string;
|
||||
from: string;
|
||||
plugin: PluginParams;
|
||||
id: number;
|
||||
text?: undefined;
|
||||
};
|
||||
|
||||
const initialState: State = {
|
||||
clientId: '',
|
||||
pairing: '',
|
||||
socket: null,
|
||||
connected: false,
|
||||
messages: [],
|
||||
};
|
||||
|
||||
export const connectSession =
|
||||
() => async (dispatch: Dispatch, getState: () => AppRootState) => {
|
||||
const { p2p } = getState();
|
||||
|
||||
if (p2p.socket) return;
|
||||
|
||||
const socket = new WebSocket(RENDEZVOUS_API);
|
||||
|
||||
socket.onopen = () => {
|
||||
console.log('Connected to websocket');
|
||||
dispatch(setConnected(true));
|
||||
dispatch(setSocket(socket));
|
||||
};
|
||||
|
||||
socket.onmessage = async (event) => {
|
||||
const message: any = safeParseJSON(await event.data.text());
|
||||
|
||||
switch (message.method) {
|
||||
case 'client_connect': {
|
||||
const { clientId } = message.params;
|
||||
dispatch(setClientId(clientId));
|
||||
break;
|
||||
}
|
||||
case 'chat': {
|
||||
const { to, from, text, id } = message.params;
|
||||
dispatch(
|
||||
appendMessage({
|
||||
to,
|
||||
from,
|
||||
text,
|
||||
id,
|
||||
}),
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'request_proof': {
|
||||
const { to, from, plugin, id } = message.params;
|
||||
dispatch(
|
||||
appendMessage({
|
||||
to,
|
||||
from,
|
||||
plugin,
|
||||
id,
|
||||
}),
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'pair_request': {
|
||||
const { from } = message.params;
|
||||
dispatch(confirmPairRequest(from));
|
||||
break;
|
||||
}
|
||||
case 'pair_request_success': {
|
||||
const { from } = message.params;
|
||||
dispatch(setPairing(from));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
console.warn(`Unknown message type "${message.method}"`);
|
||||
break;
|
||||
}
|
||||
};
|
||||
socket.onerror = () => {
|
||||
console.error('Error connecting to websocket');
|
||||
dispatch(setConnected(false));
|
||||
};
|
||||
};
|
||||
|
||||
export const setConnected = (connected = false) => ({
|
||||
type: ActionType['/p2p/setConnected'],
|
||||
payload: connected,
|
||||
});
|
||||
|
||||
export const setClientId = (clientId: string) => ({
|
||||
type: ActionType['/p2p/setClientId'],
|
||||
payload: clientId,
|
||||
});
|
||||
|
||||
export const setSocket = (socket: WebSocket) => ({
|
||||
type: ActionType['/p2p/setSocket'],
|
||||
payload: socket,
|
||||
});
|
||||
|
||||
export const setMessages = (messages: Chat[]) => ({
|
||||
type: ActionType['/p2p/setMessages'],
|
||||
payload: messages,
|
||||
});
|
||||
|
||||
export const appendMessage = (message: Chat | RequestProofMessage) => ({
|
||||
type: ActionType['/p2p/appendMessage'],
|
||||
payload: message,
|
||||
});
|
||||
|
||||
export const setPairing = (clientId: string) => ({
|
||||
type: ActionType['/p2p/setPairing'],
|
||||
payload: clientId,
|
||||
});
|
||||
|
||||
let id = 1;
|
||||
export const sendChat =
|
||||
(message: Omit<Chat, 'id'>) =>
|
||||
async (dispatch: Dispatch, getState: () => AppRootState) => {
|
||||
const {
|
||||
p2p: { socket },
|
||||
} = getState();
|
||||
const reqId = id++;
|
||||
const params = {
|
||||
...message,
|
||||
id: reqId,
|
||||
};
|
||||
|
||||
if (socket) {
|
||||
socket.send(
|
||||
bufferify({
|
||||
method: 'chat',
|
||||
params,
|
||||
}),
|
||||
);
|
||||
dispatch(appendMessage(params));
|
||||
}
|
||||
};
|
||||
|
||||
export const requestProof =
|
||||
(message: Omit<RequestProofMessage, 'id'>) =>
|
||||
async (dispatch: Dispatch, getState: () => AppRootState) => {
|
||||
const {
|
||||
p2p: { socket },
|
||||
} = getState();
|
||||
const reqId = id++;
|
||||
const params = {
|
||||
...message,
|
||||
id: reqId,
|
||||
};
|
||||
|
||||
if (socket) {
|
||||
socket.send(
|
||||
bufferify({
|
||||
method: 'request_proof',
|
||||
params,
|
||||
}),
|
||||
);
|
||||
dispatch(appendMessage(params));
|
||||
}
|
||||
};
|
||||
|
||||
export const sendPairRequest =
|
||||
(target: string) =>
|
||||
async (dispatch: Dispatch, getState: () => AppRootState) => {
|
||||
const {
|
||||
p2p: { socket, clientId },
|
||||
} = getState();
|
||||
const reqId = id++;
|
||||
|
||||
if (socket && clientId) {
|
||||
socket.send(
|
||||
bufferify({
|
||||
method: 'pair_request',
|
||||
params: {
|
||||
from: clientId,
|
||||
to: target,
|
||||
id: reqId,
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
};
|
||||
export const confirmPairRequest =
|
||||
(target: string) => (dispatch: Dispatch, getState: () => AppRootState) => {
|
||||
const {
|
||||
p2p: { socket, clientId },
|
||||
} = getState();
|
||||
|
||||
const reqId = id++;
|
||||
|
||||
if (socket && clientId) {
|
||||
socket.send(
|
||||
bufferify({
|
||||
method: 'pair_request_success',
|
||||
params: {
|
||||
from: clientId,
|
||||
to: target,
|
||||
id: reqId,
|
||||
},
|
||||
}),
|
||||
);
|
||||
dispatch(setPairing(target));
|
||||
}
|
||||
};
|
||||
|
||||
export default function p2p(state = initialState, action: Action<any>) {
|
||||
switch (action.type) {
|
||||
case ActionType['/p2p/setConnected']:
|
||||
return {
|
||||
...state,
|
||||
connected: action.payload,
|
||||
};
|
||||
case ActionType['/p2p/setClientId']:
|
||||
return {
|
||||
...state,
|
||||
clientId: action.payload,
|
||||
};
|
||||
case ActionType['/p2p/setSocket']:
|
||||
return {
|
||||
...state,
|
||||
socket: action.payload,
|
||||
};
|
||||
case ActionType['/p2p/setMessages']:
|
||||
return {
|
||||
...state,
|
||||
messages: action.payload,
|
||||
};
|
||||
case ActionType['/p2p/setPairing']:
|
||||
return {
|
||||
...state,
|
||||
pairing: action.payload,
|
||||
};
|
||||
case ActionType['/p2p/appendMessage']:
|
||||
return {
|
||||
...state,
|
||||
messages: state.messages.concat(action.payload),
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export function useClientId() {
|
||||
return useSelector((state: AppRootState) => {
|
||||
return state.p2p.clientId;
|
||||
}, deepEqual);
|
||||
}
|
||||
|
||||
export function useSocket() {
|
||||
return useSelector((state: AppRootState) => {
|
||||
return state.p2p.socket;
|
||||
}, deepEqual);
|
||||
}
|
||||
|
||||
export function useConnected() {
|
||||
return useSelector((state: AppRootState) => {
|
||||
return state.p2p.connected;
|
||||
}, deepEqual);
|
||||
}
|
||||
|
||||
export function useChatMessages(): (Chat | RequestProofMessage)[] {
|
||||
return useSelector((state: AppRootState) => {
|
||||
return state.p2p.messages;
|
||||
}, deepEqual);
|
||||
}
|
||||
|
||||
export function usePairId(): string {
|
||||
return useSelector((state: AppRootState) => {
|
||||
return state.p2p.pairing;
|
||||
}, deepEqual);
|
||||
}
|
||||
|
||||
function bufferify(data: any): Buffer {
|
||||
return Buffer.from(JSON.stringify(data));
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
export const EXPLORER_API = 'http://localhost:3000';
|
||||
export const RENDEZVOUS_API = 'ws://localhost:3000';
|
||||
|
||||
@@ -108,3 +108,11 @@ export async function replayRequest(req: RequestLog): Promise<string> {
|
||||
return resp.blob().then((blob) => blob.text());
|
||||
}
|
||||
}
|
||||
|
||||
export function safeParseJSON(data: string) {
|
||||
try {
|
||||
return JSON.parse(data);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
1
tlsn/tlsn/tlsn-wasm/pkg/.gitignore
vendored
Normal file
1
tlsn/tlsn/tlsn-wasm/pkg/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
#*
|
||||
@@ -0,0 +1,6 @@
|
||||
onmessage = function (ev) {
|
||||
let [ia, index, value] = ev.data;
|
||||
ia = new Int32Array(ia.buffer);
|
||||
let result = Atomics.wait(ia, index, value);
|
||||
postMessage(result);
|
||||
};
|
||||
107
tlsn/tlsn/tlsn-wasm/pkg/tlsn_wasm.d.ts
vendored
Normal file
107
tlsn/tlsn/tlsn-wasm/pkg/tlsn_wasm.d.ts
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
*/
|
||||
export function setup_tracing_web(): void;
|
||||
/**
|
||||
*/
|
||||
export class Prover {
|
||||
free(): void;
|
||||
/**
|
||||
* @param {any} config
|
||||
*/
|
||||
constructor(config: any);
|
||||
/**
|
||||
* Set up the prover.
|
||||
*
|
||||
* This performs all MPC setup prior to establishing the connection to the
|
||||
* application server.
|
||||
* @param {string} verifier_url
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
setup(verifier_url: string): Promise<void>;
|
||||
/**
|
||||
* Send the HTTP request to the server.
|
||||
* @param {string} ws_proxy_url
|
||||
* @param {any} request
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
send_request(ws_proxy_url: string, request: any): Promise<any>;
|
||||
/**
|
||||
* Reveals data to the verifier, redacting the specified substrings.
|
||||
* @param {any} redact
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
reveal(redact: any): Promise<void>;
|
||||
}
|
||||
/**
|
||||
*/
|
||||
export class Verifier {
|
||||
free(): void;
|
||||
/**
|
||||
* @param {any} config
|
||||
*/
|
||||
constructor(config: any);
|
||||
/**
|
||||
* @param {string} prover_url
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
connect(prover_url: string): Promise<void>;
|
||||
/**
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
verify(): Promise<any>;
|
||||
}
|
||||
|
||||
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
||||
|
||||
export interface InitOutput {
|
||||
readonly __wbg_verifier_free: (a: number) => void;
|
||||
readonly verifier_new: (a: number, b: number) => void;
|
||||
readonly verifier_connect: (a: number, b: number, c: number) => number;
|
||||
readonly verifier_verify: (a: number) => number;
|
||||
readonly setup_tracing_web: () => void;
|
||||
readonly __wbg_prover_free: (a: number) => void;
|
||||
readonly prover_new: (a: number, b: number) => void;
|
||||
readonly prover_setup: (a: number, b: number, c: number) => number;
|
||||
readonly prover_send_request: (a: number, b: number, c: number, d: number) => number;
|
||||
readonly prover_reveal: (a: number, b: number) => number;
|
||||
readonly ring_core_0_17_8_bn_mul_mont: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
|
||||
readonly memory: WebAssembly.Memory;
|
||||
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
||||
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
||||
readonly __wbindgen_export_3: WebAssembly.Table;
|
||||
readonly wasm_bindgen__convert__closures__invoke0_mut__h866fab451526a01b: (a: number, b: number) => void;
|
||||
readonly wasm_bindgen__convert__closures__invoke1_mut__hb5831b01f9504b58: (a: number, b: number, c: number) => void;
|
||||
readonly wasm_bindgen__convert__closures__invoke1_mut__ha34040edb27f2a7b: (a: number, b: number, c: number) => void;
|
||||
readonly _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h04a8fc7e4fd75a48: (a: number, b: number, c: number) => void;
|
||||
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
|
||||
readonly __wbindgen_free: (a: number, b: number, c: number) => void;
|
||||
readonly __wbindgen_exn_store: (a: number) => void;
|
||||
readonly wasm_bindgen__convert__closures__invoke2_mut__h921fd5652408deb6: (a: number, b: number, c: number, d: number) => void;
|
||||
readonly __wbindgen_thread_destroy: (a?: number, b?: number) => void;
|
||||
readonly __wbindgen_start: () => void;
|
||||
}
|
||||
|
||||
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
||||
/**
|
||||
* Instantiates the given `module`, which can either be bytes or
|
||||
* a precompiled `WebAssembly.Module`.
|
||||
*
|
||||
* @param {SyncInitInput} module
|
||||
* @param {WebAssembly.Memory} maybe_memory
|
||||
*
|
||||
* @returns {InitOutput}
|
||||
*/
|
||||
export function initSync(module: SyncInitInput, maybe_memory?: WebAssembly.Memory): InitOutput;
|
||||
|
||||
/**
|
||||
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
||||
* for everything else, calls `WebAssembly.instantiate` directly.
|
||||
*
|
||||
* @param {InitInput | Promise<InitInput>} module_or_path
|
||||
* @param {WebAssembly.Memory} maybe_memory
|
||||
*
|
||||
* @returns {Promise<InitOutput>}
|
||||
*/
|
||||
export default function __wbg_init (module_or_path?: InitInput | Promise<InitInput>, maybe_memory?: WebAssembly.Memory): Promise<InitOutput>;
|
||||
1039
tlsn/tlsn/tlsn-wasm/pkg/tlsn_wasm.js
Normal file
1039
tlsn/tlsn/tlsn-wasm/pkg/tlsn_wasm.js
Normal file
File diff suppressed because it is too large
Load Diff
BIN
tlsn/tlsn/tlsn-wasm/pkg/tlsn_wasm_bg.wasm
Normal file
BIN
tlsn/tlsn/tlsn-wasm/pkg/tlsn_wasm_bg.wasm
Normal file
Binary file not shown.
27
tlsn/tlsn/tlsn-wasm/pkg/tlsn_wasm_bg.wasm.d.ts
vendored
Normal file
27
tlsn/tlsn/tlsn-wasm/pkg/tlsn_wasm_bg.wasm.d.ts
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export function __wbg_verifier_free(a: number): void;
|
||||
export function verifier_new(a: number, b: number): void;
|
||||
export function verifier_connect(a: number, b: number, c: number): number;
|
||||
export function verifier_verify(a: number): number;
|
||||
export function setup_tracing_web(): void;
|
||||
export function __wbg_prover_free(a: number): void;
|
||||
export function prover_new(a: number, b: number): void;
|
||||
export function prover_setup(a: number, b: number, c: number): number;
|
||||
export function prover_send_request(a: number, b: number, c: number, d: number): number;
|
||||
export function prover_reveal(a: number, b: number): number;
|
||||
export function ring_core_0_17_8_bn_mul_mont(a: number, b: number, c: number, d: number, e: number, f: number): void;
|
||||
export const memory: WebAssembly.Memory;
|
||||
export function __wbindgen_malloc(a: number, b: number): number;
|
||||
export function __wbindgen_realloc(a: number, b: number, c: number, d: number): number;
|
||||
export const __wbindgen_export_3: WebAssembly.Table;
|
||||
export function wasm_bindgen__convert__closures__invoke0_mut__h866fab451526a01b(a: number, b: number): void;
|
||||
export function wasm_bindgen__convert__closures__invoke1_mut__hb5831b01f9504b58(a: number, b: number, c: number): void;
|
||||
export function wasm_bindgen__convert__closures__invoke1_mut__ha34040edb27f2a7b(a: number, b: number, c: number): void;
|
||||
export function _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h04a8fc7e4fd75a48(a: number, b: number, c: number): void;
|
||||
export function __wbindgen_add_to_stack_pointer(a: number): number;
|
||||
export function __wbindgen_free(a: number, b: number, c: number): void;
|
||||
export function __wbindgen_exn_store(a: number): void;
|
||||
export function wasm_bindgen__convert__closures__invoke2_mut__h921fd5652408deb6(a: number, b: number, c: number, d: number): void;
|
||||
export function __wbindgen_thread_destroy(a: number, b: number): void;
|
||||
export function __wbindgen_start(): void;
|
||||
@@ -1,7 +1,7 @@
|
||||
[
|
||||
{
|
||||
"url": "https://api.twitter.com/1.1/account/settings.json",
|
||||
"targetUrl": "https://www.twitter.com",
|
||||
"url": "https://api.x.com/1.1/account/settings.json",
|
||||
"targetUrl": "https://www.x.com",
|
||||
"method": "GET",
|
||||
"type": "xmlhttprequest",
|
||||
"title": "Twitter Profile",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// tiny wrapper with default env vars
|
||||
module.exports = {
|
||||
NODE_ENV: process.env.NODE_ENV || 'development',
|
||||
PORT: process.env.PORT || 3000,
|
||||
PORT: process.env.PORT || 3001,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user