Skip to content

Commit

Permalink
chore(demos): add demos/taco-nft-demo
Browse files Browse the repository at this point in the history
  • Loading branch information
piotr-roslaniec committed Oct 5, 2023
1 parent 54bf317 commit 620b755
Show file tree
Hide file tree
Showing 19 changed files with 3,554 additions and 2,863 deletions.
1 change: 1 addition & 0 deletions demos/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# `@nucypher/*` Demos

- [`taco-demo`](./taco-demo) - A demo of the `@nucypher/taco` library.
- [`taco-nft-demo`](./taco-nft-demo) - A demo an NFT-based condition using the `@nucypher/taco` library.
- [`nucypher-ts-demo`](https://github.com/nucypher/nucypher-ts-demo) - A demo of PRE in the `nucypher-ts` library.
- [`tdec-sandbox`](https://github.com/nucypher/tdec-sandbox) - A demo of tDec in the `nucypher-ts` library.
- [`tdec-nft-example`](https://github.com/nucypher/tdec-nft-example) - A demo of tDec in the `nucypher-ts` library.
9 changes: 5 additions & 4 deletions demos/taco-demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ pnpm start

## Usage

In order to run this demo will need a MetaMask with an account funded with some $MATIC.
In order to run this demo will need a MetaMask with an account funded with some
$MATIC.

In order to connect with the network, the demo uses a public instances of
[Porter](https://docs.nucypher.com/en/latest/application_development/web_development.html#running-porter).
Expand All @@ -19,10 +20,10 @@ In order to connect with the network, the demo uses a public instances of
`@nucypher/taco` is in an early release. We recommend **not** using it in
production _just yet_.

### Oryx/Tapir - Mumbai Testnet
### Tapir - Mumbai Testnet

The current release of `@nucypher/taco` supports Ursulas working on Oryx/Tapir
networks and contracts deployed on Mumbai testnet.
The current release of `@nucypher/taco` supports Ursulas working on Tapir
network and contracts deployed on Mumbai testnet.

## References

Expand Down
6 changes: 4 additions & 2 deletions demos/taco-demo/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { Encrypt } from './Encrypt';
import { Spinner } from './Spinner';

export default function App() {
const { activateBrowserWallet, deactivate, account, switchNetwork } =
const { activateBrowserWallet, deactivate, account, switchNetwork, chainId } =
useEthers();

const [loading, setLoading] = useState(false);
Expand All @@ -37,14 +37,16 @@ export default function App() {
}
setLoading(true);

await switchNetwork(Mumbai.chainId);

const provider = new ethers.providers.Web3Provider(window.ethereum);
const ritualId = 2; // Replace with your own ritual ID
const encryptedMessage = await encrypt(
provider,
message,
condition,
ritualId,
provider.getSigner()
provider.getSigner(),
);

setEncryptedMessage(encryptedMessage);
Expand Down
21 changes: 11 additions & 10 deletions demos/taco-demo/src/ConditionBuilder.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { conditions } from '@nucypher/taco';
import { Mumbai, useEthers } from '@usedapp/core';
import React, { useState } from 'react';
import {conditions} from '@nucypher/taco';
import {Mumbai, useEthers} from '@usedapp/core';
import React, {useState} from 'react';

interface Props {
condition?: conditions.Condition | undefined;
Expand All @@ -20,11 +20,11 @@ const rpcCondition = new conditions.RpcCondition({
});

export const ConditionBuilder = ({
condition,
setConditions,
enabled,
}: Props) => {
const { library } = useEthers();
condition,
setConditions,
enabled,
}: Props) => {
const {library} = useEthers();

const demoCondition = JSON.stringify((condition ?? rpcCondition).toObj());
const [conditionString, setConditionString] = useState(demoCondition);
Expand Down Expand Up @@ -53,7 +53,7 @@ export const ConditionBuilder = ({
</textarea>
);

const ConditionJSONInput = makeInput(
const conditionJSONInput = makeInput(
setConditionString,
JSON.stringify(rpcCondition.toObj()),
);
Expand All @@ -70,7 +70,8 @@ export const ConditionBuilder = ({
<div>
<h3>Customize your Conditions</h3>
<div>
<p>Condition JSON {ConditionJSONInput}</p>
<h3>Condition JSON</h3>
{conditionJSONInput}
</div>
</div>
<button onClick={onCreateCondition}>Create Conditions</button>
Expand Down
31 changes: 31 additions & 0 deletions demos/taco-nft-demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# taco-nft-example

## Installation

```bash
pnpm install
pnpm start
```

## Usage

In order to run this demo will need a MetaMask with an account funded with some
$MATIC.

In order to connect with the network, the demo uses a public instances of
[Porter](https://docs.nucypher.com/en/latest/application_development/web_development.html#running-porter).

### Polygon

`@nucypher/taco` is in an early release. We recommend **not** using it in
production _just yet_.

### Tapir - Mumbai Testnet

The current release of `@nucypher/taco` supports Ursulas working on Tapir
network and contracts deployed on Mumbai testnet.

## References

This dApp is based on
[`useDapp` example](https://github.com/EthWorks/useDapp/tree/master/packages/example).
38 changes: 38 additions & 0 deletions demos/taco-nft-demo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "taco-nft-demo",
"version": "0.1.0",
"description": "A usage example for @nucypher/taco",
"private": true,
"author": "Piotr Rosłaniec <p.roslaniec@gmail.com>",
"scripts": {
"start": "webpack serve --mode development",
"build": "tsc --noEmit && rimraf build && webpack --mode production --progress"
},
"dependencies": {
"@nucypher/taco": "workspace:*",
"@usedapp/core": "^1.2.13",
"buffer": "^6.0.3",
"ethers": "^5.7.1",
"file-loader": "^6.2.0",
"react": "^18.2.0",
"react-copy-to-clipboard": "^5.1.0",
"react-dom": "^18.2.0",
"react-spinners": "^0.13.6"
},
"devDependencies": {
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
"@types/react": "^18.0.20",
"@types/react-copy-to-clipboard": "^5.0.4",
"@types/react-dom": "^18.0.6",
"copy-webpack-plugin": "^11.0.0",
"esbuild-loader": "^2.20.0",
"html-webpack-plugin": "^5.5.0",
"react-refresh": "^0.14.0",
"rimraf": "^3.0.2",
"stream-browserify": "^3.0.0",
"typescript": "^4.8.3",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1"
}
}
117 changes: 117 additions & 0 deletions demos/taco-nft-demo/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import {
conditions,
decrypt,
encrypt,
getPorterUri,
initialize,
ThresholdMessageKit,
} from '@nucypher/taco';
import {Mumbai, useEthers} from '@usedapp/core';
import {ethers} from 'ethers';
import React, {useEffect, useState} from 'react';

import {Decrypt} from './Decrypt';
import {Encrypt} from './Encrypt';
import {NFTConditionBuilder} from './NFTConditionBuilder';
import {Spinner} from './Spinner';

export default function App() {
const {activateBrowserWallet, deactivate, account, switchNetwork } =
useEthers();

const [loading, setLoading] = useState(false);
const [condition, setCondition] = useState<conditions.Condition>();
const [encryptedMessage, setEncryptedMessage] =
useState<ThresholdMessageKit>();
const [decryptedMessage, setDecryptedMessage] = useState<string>();
const [decryptionErrors, setDecryptionErrors] = useState<string[]>([]);

useEffect(() => {
initialize();
}, []);

const encryptMessage = async (message: string) => {
if (!condition) {
return;
}
setLoading(true);

await switchNetwork(Mumbai.chainId);

const provider = new ethers.providers.Web3Provider(window.ethereum);
const ritualId = 2; // Replace with your own ritual ID
const encryptedMessage = await encrypt(
provider,
message,
condition,
ritualId,
provider.getSigner(),
);

setEncryptedMessage(encryptedMessage);
setLoading(false);
};

const decryptMessage = async (encryptedMessage: ThresholdMessageKit) => {
if (!condition) {
return;
}
setLoading(true);
setDecryptedMessage('');
setDecryptionErrors([]);

const provider = new ethers.providers.Web3Provider(window.ethereum);
const porterUri = getPorterUri('lynx');
const decryptedMessage = await decrypt(
provider,
encryptedMessage,
provider.getSigner(),
porterUri,
);

setDecryptedMessage(new TextDecoder().decode(decryptedMessage));
setLoading(false);
};

if (!account) {
return (
<div>
<h2>Web3 Provider</h2>
<button onClick={() => activateBrowserWallet()}>Connect Wallet</button>
</div>
);
}

if (loading) {
return <Spinner loading={loading}/>;
}

return (
<div>
<div>
<h2>Web3 Provider</h2>
<button onClick={deactivate}> Disconnect Wallet</button>
{account && <p>Account: {account}</p>}
</div>

<NFTConditionBuilder
enabled={true}
condition={condition}
setConditions={setCondition}
/>

<Encrypt
enabled={!!condition}
encrypt={encryptMessage}
encryptedMessage={encryptedMessage!}
/>

<Decrypt
enabled={!!encryptedMessage}
decrypt={decryptMessage}
decryptedMessage={decryptedMessage}
decryptionErrors={decryptionErrors}
/>
</div>
);
}
76 changes: 76 additions & 0 deletions demos/taco-nft-demo/src/Decrypt.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { ThresholdMessageKit } from '@nucypher/taco';
import React, { useState } from 'react';

interface Props {
enabled: boolean;
decrypt: (encryptedMessage: ThresholdMessageKit) => void;
decryptedMessage?: string | undefined;
decryptionErrors: string[];
}

export const Decrypt = ({
decrypt,
decryptedMessage,
decryptionErrors,
enabled,
}: Props) => {
const [encryptedMessage, setEncryptedMessage] = useState('');

if (!enabled) {
return <></>;
}

const onDecrypt = () => {
if (!encryptedMessage) {
return;
}
const mkBytes = Buffer.from(encryptedMessage, 'base64');
const mk = ThresholdMessageKit.fromBytes(mkBytes);
decrypt(mk);
};

const DecryptedMessage = () => {
if (!decryptedMessage) {
return <></>;
}
return (
<>
<h3>Decrypted Message:</h3>
<p>{decryptedMessage}</p>
</>
);
};

const DecryptionErrors = () => {
if (decryptionErrors.length === 0) {
return null;
}

return (
<div>
<h2>Decryption Errors</h2>
<p>Not enough decryption shares to decrypt the message.</p>
<p>Some Ursulas have failed with errors:</p>
<ul>
{decryptionErrors.map((error, index) => (
<li key={index}>{error}</li>
))}
</ul>
</div>
);
};

return (
<div>
<h2>Step 3 - Decrypt Encrypted Message</h2>
<input
value={encryptedMessage}
placeholder="Enter encrypted message"
onChange={(e) => setEncryptedMessage(e.currentTarget.value)}
/>
<button onClick={onDecrypt}>Decrypt</button>
{DecryptedMessage()}
{DecryptionErrors()}
</div>
);
};
Loading

0 comments on commit 620b755

Please sign in to comment.