mirror of
https://github.com/tlsnotary/tlsn-plugin-demo.git
synced 2026-01-09 21:37:55 -05:00
Merge pull request #29 from tlsnotary/1-click-changes
1 Click Plugin changes
This commit is contained in:
@@ -9,7 +9,7 @@ COPY . .
|
||||
RUN apt-get update && apt-get install -y curl && apt-get install netcat-openbsd -y
|
||||
RUN curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh -s -- -y
|
||||
RUN npm install
|
||||
RUN npm i --prefix rs/0.1.0-alpha.9/
|
||||
RUN npm i --prefix rs/0.1.0-alpha.10/
|
||||
RUN npm run build
|
||||
|
||||
EXPOSE ${PORT}
|
||||
|
||||
18
package-lock.json
generated
18
package-lock.json
generated
@@ -38,7 +38,7 @@
|
||||
"redux-thunk": "^2.4.2",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"tailwindcss": "^3.4.13",
|
||||
"tlsn-js": "^0.1.0-alpha.9"
|
||||
"tlsn-js": "^0.1.0-alpha.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
@@ -19527,22 +19527,20 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tlsn-js": {
|
||||
"version": "0.1.0-alpha.9",
|
||||
"resolved": "https://registry.npmjs.org/tlsn-js/-/tlsn-js-0.1.0-alpha.9.tgz",
|
||||
"integrity": "sha512-aEg/Pkdj0Oz9fB3xMUv67Lq69yLbuNS6IzA9j2lDwAmzOfgRBS7ZptcGuLz1hWoNvF1ma7JvdAJpHpL0ee8dkQ==",
|
||||
"license": "ISC",
|
||||
"version": "0.1.0-alpha.10.0",
|
||||
"resolved": "https://registry.npmjs.org/tlsn-js/-/tlsn-js-0.1.0-alpha.10.0.tgz",
|
||||
"integrity": "sha512-+kwcT5AISESGmSI4sZ3rZ4VqOB/ogadTBisKB8yT8j8l5RqeI3xW+gZ+gF6ZE/Y4zEtXe3d6CbZFU11lEaAo0g==",
|
||||
"dependencies": {
|
||||
"tlsn-wasm": "^0.1.0-alpha.9"
|
||||
"tlsn-wasm": "0.1.0-alpha.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16.20.2"
|
||||
}
|
||||
},
|
||||
"node_modules/tlsn-wasm": {
|
||||
"version": "0.1.0-alpha.9",
|
||||
"resolved": "https://registry.npmjs.org/tlsn-wasm/-/tlsn-wasm-0.1.0-alpha.9.tgz",
|
||||
"integrity": "sha512-/7DKVXzFdlzD9vwsROb/tvGHJ+xHlAbvaVjMGBWOrecG5KR+Dcg6QMSb4R0/2jePX6u8r6JNXbRpKgQ+yf1zaA==",
|
||||
"license": "MIT OR Apache-2.0"
|
||||
"version": "0.1.0-alpha.10",
|
||||
"resolved": "https://registry.npmjs.org/tlsn-wasm/-/tlsn-wasm-0.1.0-alpha.10.tgz",
|
||||
"integrity": "sha512-HgGLmaxyw18v34hxAOnVc9P/HuEjVuQeb/6TcskaSHGFOY2t2pjWBz93toinEAD2N1LwVQJXoECxsP5Qo81Haw=="
|
||||
},
|
||||
"node_modules/to-buffer": {
|
||||
"version": "1.1.1",
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
"redux-thunk": "^2.4.2",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"tailwindcss": "^3.4.13",
|
||||
"tlsn-js": "^0.1.0-alpha.9"
|
||||
"tlsn-js": "^0.1.0-alpha.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
@@ -108,4 +108,4 @@
|
||||
"webpack-dev-server": "^4.11.1"
|
||||
},
|
||||
"homepage": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -684,9 +684,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rangeset"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e60e90dbde8afa699f8956a7f29b6533b860963ef9c7a7e993e145ffa6f7e0c"
|
||||
checksum = "1fc7af00a06ad692080d87495a904677592c662610edb82b4fc8782f4ed2f01f"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@@ -942,8 +942,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tlsn-core"
|
||||
version = "0.1.0-alpha.9"
|
||||
source = "git+https://github.com/tlsnotary/tlsn.git?tag=v0.1.0-alpha.9#328c2af1623f742e49ab62f49dcde606f933056f"
|
||||
version = "0.1.0-alpha.10"
|
||||
source = "git+https://github.com/tlsnotary/tlsn.git?tag=v0.1.0-alpha.10#de7a47de5b4f6e4de0ec2ff3d1c42a0d2bf7a6a6"
|
||||
dependencies = [
|
||||
"bcs",
|
||||
"bimap",
|
||||
@@ -969,8 +969,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tlsn-tls-core"
|
||||
version = "0.1.0-alpha.9"
|
||||
source = "git+https://github.com/tlsnotary/tlsn.git?tag=v0.1.0-alpha.9#328c2af1623f742e49ab62f49dcde606f933056f"
|
||||
version = "0.1.0-alpha.10"
|
||||
source = "git+https://github.com/tlsnotary/tlsn.git?tag=v0.1.0-alpha.10#de7a47de5b4f6e4de0ec2ff3d1c42a0d2bf7a6a6"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"hmac",
|
||||
@@ -989,7 +989,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "tlsn-utils"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/tlsnotary/tlsn-utils?rev=6650a95#6650a956d3597d3a662fd9c15a64a1651afac399"
|
||||
source = "git+https://github.com/tlsnotary/tlsn-utils?rev=6168663#6168663495281f2c1b2c1734dc276cecc4d36ef1"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
@@ -19,4 +19,4 @@ serde = { version = "1.0.147", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
hex = "0.4"
|
||||
bincode = { version = "1.3" }
|
||||
tlsn-core = { git = "https://github.com/tlsnotary/tlsn.git", tag = "v0.1.0-alpha.9", package = "tlsn-core" }
|
||||
tlsn-core = { git = "https://github.com/tlsnotary/tlsn.git", tag = "v0.1.0-alpha.10", package = "tlsn-core" }
|
||||
BIN
rs/0.1.0-alpha.10/index.node
Executable file
BIN
rs/0.1.0-alpha.10/index.node
Executable file
Binary file not shown.
Binary file not shown.
@@ -7,7 +7,7 @@ import configureAppStore, { AppRootState } from '../web/store';
|
||||
import { Provider } from 'react-redux';
|
||||
import { Mutex } from 'async-mutex';
|
||||
//@ts-ignore
|
||||
import { verify } from '../rs/0.1.0-alpha.9/index.node';
|
||||
import { verify } from '../rs/0.1.0-alpha.10/index.node';
|
||||
import { convertNotaryWsToHttp, fetchPublicKeyFromNotary } from './util/index';
|
||||
import { assignPoapToUser } from './util/index';
|
||||
|
||||
@@ -43,7 +43,7 @@ app.get('*', (req, res) => {
|
||||
const storeConfig: AppRootState = {
|
||||
attestation: {
|
||||
raw: {
|
||||
version: '0.1.0-alpha.9',
|
||||
version: '0.1.0-alpha.10',
|
||||
data: '',
|
||||
meta: {
|
||||
notaryUrl: '',
|
||||
|
||||
@@ -12,15 +12,11 @@ import { formatDataPreview } from '../../utils/utils';
|
||||
|
||||
const steps = [
|
||||
'Connect Extension',
|
||||
'Install Plugin',
|
||||
'Run Plugin',
|
||||
'Verify Attestation',
|
||||
'🎉 Claim POAP 🎉',
|
||||
];
|
||||
|
||||
export default function Steps(): ReactElement {
|
||||
const [extensionInstalled, setExtensionInstalled] = useState(false);
|
||||
const [pluginID, setPluginID] = useState('');
|
||||
const [step, setStep] = useState<number>(0);
|
||||
const [client, setClient] = useState<any>(null);
|
||||
const [pluginData, setPluginData] = useState<PresentationJSON | null>(null);
|
||||
@@ -35,7 +31,6 @@ export default function Steps(): ReactElement {
|
||||
}
|
||||
}, [step]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const checkExtension = () => {
|
||||
//@ts-ignore
|
||||
@@ -66,7 +61,9 @@ export default function Steps(): ReactElement {
|
||||
const match = transcript.recv.match(/"screen_name":"([^"]+)"/);
|
||||
const screenName = match ? match[1] : null;
|
||||
setScreenName(screenName);
|
||||
setExploding(true);
|
||||
if (screenName) {
|
||||
setExploding(true);
|
||||
}
|
||||
}
|
||||
}, [transcript]);
|
||||
|
||||
@@ -80,57 +77,32 @@ export default function Steps(): ReactElement {
|
||||
}
|
||||
}
|
||||
|
||||
async function handleGetPlugins() {
|
||||
try {
|
||||
const plugins = await client.getPlugins('**', '**');
|
||||
const targetPlugin = plugins.find(
|
||||
(plugin: any) =>
|
||||
plugin.title === 'Twitter Profile' &&
|
||||
Array.isArray(plugin.headers) &&
|
||||
plugin.headers.includes(
|
||||
'https://api.x.com/1.1/account/settings.json',
|
||||
),
|
||||
);
|
||||
|
||||
if (targetPlugin) {
|
||||
setPluginID(targetPlugin.hash);
|
||||
setStep(2);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
async function handlePluginInstall() {
|
||||
try {
|
||||
const plugin = await client.installPlugin(
|
||||
'https://github.com/tlsnotary/tlsn-extension/raw/main/src/assets/plugins/twitter_profile.wasm',
|
||||
);
|
||||
setPluginID(plugin);
|
||||
setStep(2);
|
||||
} catch (error: any) {
|
||||
console.log(error.message);
|
||||
if (error.message === 'Plugin already exist.') {
|
||||
try {
|
||||
await handleGetPlugins();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleRunPlugin() {
|
||||
try {
|
||||
setLoading(true);
|
||||
const pluginData = await client.runPlugin(pluginID);
|
||||
setLoading(false);
|
||||
const pluginData = await client.runPlugin(
|
||||
'https://github.com/tlsnotary/tlsn-extension/raw/main/src/assets/plugins/twitter_profile.wasm'
|
||||
);
|
||||
setPluginData(pluginData);
|
||||
setStep(3);
|
||||
|
||||
const response = await fetch('/verify-attestation', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ attestation: pluginData }),
|
||||
});
|
||||
if (response.status === 200) {
|
||||
const data = await response.json();
|
||||
setTranscript(data.presentationObj);
|
||||
setStep(1); // Stay on Run Plugin step
|
||||
} else {
|
||||
console.log(await response.text());
|
||||
}
|
||||
} catch (error) {
|
||||
setLoading(false);
|
||||
console.log(error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,14 +137,7 @@ export default function Steps(): ReactElement {
|
||||
Connect
|
||||
</button>
|
||||
)}
|
||||
{step === 1 && (
|
||||
<div className="flex flex-col gap-2">
|
||||
<button onClick={handlePluginInstall} className="button">
|
||||
Install Plugin
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
{step === 2 && (
|
||||
{step === 1 && !pluginData && (
|
||||
<div className="flex flex-col items-center justify-center gap-2">
|
||||
<ul className="flex flex-col items-center justify-center gap-1">
|
||||
<li className="text-base font-light">
|
||||
@@ -187,8 +152,8 @@ export default function Steps(): ReactElement {
|
||||
notarization is finished
|
||||
</li>
|
||||
<li className="text-base font-light">
|
||||
If successful the attestation field will populate with the
|
||||
attestation from the notary
|
||||
If successful, the attestation and verified data will be
|
||||
displayed below
|
||||
</li>
|
||||
</ul>
|
||||
<Button onClick={handleRunPlugin} loading={loading}>
|
||||
@@ -196,40 +161,21 @@ export default function Steps(): ReactElement {
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{step === 3 && (
|
||||
<div>
|
||||
<ul className="flex flex-col justify-center items-center gap-1">
|
||||
<li className="text-base font-light">
|
||||
Click the "Verify" button below to verify the attestation
|
||||
</li>
|
||||
<li className="text-base font-light">
|
||||
If successful the verified data will show in the
|
||||
Presentation field and provide you with a link to claim your
|
||||
POAP
|
||||
</li>
|
||||
</ul>
|
||||
{step === 1 && pluginData && screenName && (
|
||||
<div className="flex flex-col items-center justify-center gap-2">
|
||||
<h3 className="text-lg font-semibold text-center">
|
||||
Optional: Claim Your POAP
|
||||
</h3>
|
||||
<ClaimPoap screen_name={screenName} exploding={exploding} />
|
||||
</div>
|
||||
)}
|
||||
{step === 5 && (
|
||||
<>
|
||||
<ClaimPoap
|
||||
screen_name={screenName}
|
||||
exploding={exploding}
|
||||
setStep={setStep}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{pluginData ? (
|
||||
{pluginData && (
|
||||
<DisplayPluginData
|
||||
step={step}
|
||||
pluginData={pluginData}
|
||||
transcript={transcript}
|
||||
setTranscript={setTranscript}
|
||||
setStep={setStep}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
@@ -243,38 +189,13 @@ function DisplayPluginData({
|
||||
step,
|
||||
pluginData,
|
||||
transcript,
|
||||
setTranscript,
|
||||
setStep,
|
||||
}: {
|
||||
step: number;
|
||||
pluginData: any;
|
||||
transcript: any;
|
||||
setTranscript: any;
|
||||
setStep: any;
|
||||
}): ReactElement {
|
||||
const [tab, setTab] = useState<'sent' | 'recv'>('sent');
|
||||
|
||||
async function handleVerify() {
|
||||
try {
|
||||
const response = await fetch('/verify-attestation', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ attestation: pluginData }),
|
||||
});
|
||||
if (response.status === 200) {
|
||||
const data = await response.json();
|
||||
setTranscript(data.presentationObj);
|
||||
setStep(5);
|
||||
} else {
|
||||
console.log(await response.text());
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex justify-center items-center space-x-4 mt-8">
|
||||
<div className="w-96">
|
||||
@@ -287,9 +208,6 @@ function DisplayPluginData({
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<button disabled={step !== 3} onClick={handleVerify} className="button">
|
||||
Verify
|
||||
</button>
|
||||
<div className="w-96">
|
||||
<div className="p-2 bg-gray-200 border-t rounded-t-md text-center text-lg font-semibold">
|
||||
Presentation
|
||||
@@ -327,35 +245,37 @@ function ClaimPoap({
|
||||
}: {
|
||||
screen_name: string;
|
||||
exploding: boolean;
|
||||
setStep: any;
|
||||
}): ReactElement {
|
||||
const [poapLink, setPoapLink] = useState<string>('');
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
const handleClaimPoap = async () => {
|
||||
try {
|
||||
if (!screen_name) return;
|
||||
const response = await fetch('/poap-claim', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ screenName: screen_name }),
|
||||
});
|
||||
if (response.status === 200) {
|
||||
const data = await response.json();
|
||||
setPoapLink(data.poapLink);
|
||||
} else {
|
||||
setError(await response.text());
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
const handleClaimPoap = async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
if (!screen_name) return;
|
||||
const response = await fetch('/poap-claim', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ screenName: screen_name }),
|
||||
});
|
||||
if (response.status === 200) {
|
||||
const data = await response.json();
|
||||
setPoapLink(data.poapLink);
|
||||
} else {
|
||||
const errorText = await response.text();
|
||||
setError(errorText || 'Failed to claim POAP');
|
||||
}
|
||||
};
|
||||
|
||||
handleClaimPoap();
|
||||
}, [screen_name]);
|
||||
} catch (error) {
|
||||
console.error('Error claiming POAP:', error);
|
||||
setError('Failed to connect to the server');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const mediumProps: ConfettiProps = {
|
||||
force: 0.6,
|
||||
@@ -366,13 +286,22 @@ function ClaimPoap({
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
{poapLink !== '' && (
|
||||
<a className="button" href={poapLink} target="_blank">
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
{!poapLink && !error && (
|
||||
<Button
|
||||
onClick={handleClaimPoap}
|
||||
loading={loading}
|
||||
>
|
||||
Claim POAP!
|
||||
</Button>
|
||||
)}
|
||||
{poapLink && (
|
||||
<a className="button" href={poapLink} target="_blank">
|
||||
View Your POAP!
|
||||
</a>
|
||||
)}
|
||||
{exploding && <ConfettiExplosion {...mediumProps} />}
|
||||
{error && <p className="text-red-500">Error: {error}</p>}
|
||||
{exploding && poapLink && <ConfettiExplosion {...mediumProps} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ export type State = {
|
||||
|
||||
export const initState: State = {
|
||||
raw: {
|
||||
version: '0.1.0-alpha.9',
|
||||
version: '0.1.0-alpha.10',
|
||||
data: '',
|
||||
meta: {
|
||||
notaryUrl: '',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export interface AttestedData {
|
||||
version: '0.1.0-alpha.9' | '0.1.0-alpha.8' | '0.1.0-alpha.7' | '0.1.0-alpha.5';
|
||||
version: '0.1.0-alpha.10' | '0.1.0-alpha.9' | '0.1.0-alpha.8' | '0.1.0-alpha.7' | '0.1.0-alpha.5';
|
||||
time: number;
|
||||
sent: string;
|
||||
recv: string;
|
||||
@@ -10,7 +10,7 @@ export interface AttestedData {
|
||||
}
|
||||
|
||||
export type Attestation = {
|
||||
version: '0.1.0-alpha.9' | '0.1.0-alpha.8' | '0.1.0-alpha.7';
|
||||
version: '0.1.0-alpha.10' | '0.1.0-alpha.9' | '0.1.0-alpha.8' | '0.1.0-alpha.7';
|
||||
data: string;
|
||||
meta: {
|
||||
notaryUrl: string;
|
||||
|
||||
Reference in New Issue
Block a user