From fdf008f5f9aa69137a4227e16c2b4e4ca9d8ad5b Mon Sep 17 00:00:00 2001 From: 0xExp-po Date: Fri, 13 Dec 2024 23:45:53 +0900 Subject: [PATCH 1/9] feat: display real json data from xdr --- dapp/package.json | 2 ++ .../page/proposal/ProposalDetail.tsx | 30 ++++++++++++++----- dapp/src/types/types.ts | 1 + dapp/src/utils/passToLosslessJson.ts | 12 ++++++++ dapp/src/utils/stellarXdr.ts | 24 +++++++++++++++ 5 files changed, 62 insertions(+), 7 deletions(-) create mode 100644 dapp/src/types/types.ts create mode 100644 dapp/src/utils/passToLosslessJson.ts create mode 100644 dapp/src/utils/stellarXdr.ts diff --git a/dapp/package.json b/dapp/package.json index 1a26de3..67b7a07 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -9,6 +9,7 @@ "@mdxeditor/editor": "^3.20.0", "@nanostores/react": "^0.8.2", "@stellar/stellar-sdk": "^13.0.0", + "@stellar/stellar-xdr-json": "^22.0.0-rc.1.1", "@web3-storage/w3up-client": "^16.5.2", "astro": "4.16.17", "astro-seo": "^0.8.4", @@ -16,6 +17,7 @@ "github-markdown-css": "^5.8.1", "install": "^0.13.0", "js-sha3": "^0.9.3", + "lossless-json": "^4.0.2", "markdown-to-jsx": "^7.7.1", "nanostores": "^0.11.3", "react18-json-view": "^0.2.8", diff --git a/dapp/src/components/page/proposal/ProposalDetail.tsx b/dapp/src/components/page/proposal/ProposalDetail.tsx index b2d6dfe..70ded54 100644 --- a/dapp/src/components/page/proposal/ProposalDetail.tsx +++ b/dapp/src/components/page/proposal/ProposalDetail.tsx @@ -1,19 +1,19 @@ import React from "react"; import { useState, useEffect } from "react"; +import * as StellarXdr from "utils/stellarXdr"; import Markdown from "markdown-to-jsx"; import "github-markdown-css"; import JsonView from "react18-json-view"; import "react18-json-view/src/style.css"; import { capitalizeFirstLetter, - processDecodedData, modifySlashInXdr, getProposalLinkFromIpfs, getOutcomeLinkFromIpfs, } from "utils/utils"; -import { demoOutcomeData } from "constants/demoProposalData"; import { stellarLabViewXdrLink } from "constants/serviceLinks"; import type { ProposalOutcome, ProposalViewStatus } from "types/proposal"; +import { parseToLosslessJson } from "utils/passToLosslessJson"; interface ProposalDetailProps { ipfsLink: string | null; description: string; @@ -27,6 +27,17 @@ const ProposalDetail: React.FC = ({ outcome, status, }) => { + const [isReady, setIsReady] = useState(false); + + useEffect(() => { + const init = async () => { + await StellarXdr.initialize(); + setIsReady(true); + }; + + init(); + }, []); + return (
@@ -91,6 +102,7 @@ const ProposalDetail: React.FC = ({ type={key} detail={value} proposalStatus={status} + isXdrInit={isReady} /> ))}
@@ -107,7 +119,8 @@ export const OutcomeDetail: React.FC<{ type: string; detail: { description: string; xdr: string }; proposalStatus: ProposalViewStatus | null; -}> = ({ type, detail, proposalStatus }) => { + isXdrInit: boolean; +}> = ({ type, detail, proposalStatus, isXdrInit }) => { const [content, setContent] = useState(null); const [isExpanded, setIsExpanded] = useState(false); @@ -117,10 +130,13 @@ export const OutcomeDetail: React.FC<{ const getContentFromXdr = async (_xdr: string) => { try { + if (!isXdrInit) { + return; + } + if (_xdr) { - const decoded = processDecodedData(_xdr); - console.log("decode:", decoded); - setContent(demoOutcomeData); + const decoded = StellarXdr.decode("TransactionEnvelope", _xdr); + setContent(parseToLosslessJson(decoded)); } } catch (error) { console.error("Error decoding XDR:", error); @@ -129,7 +145,7 @@ export const OutcomeDetail: React.FC<{ useEffect(() => { getContentFromXdr(detail.xdr); - }, [detail]); + }, [detail, isXdrInit]); return (
diff --git a/dapp/src/types/types.ts b/dapp/src/types/types.ts new file mode 100644 index 0000000..aeb1c09 --- /dev/null +++ b/dapp/src/types/types.ts @@ -0,0 +1 @@ +export type AnyObject = { [key: string]: any }; diff --git a/dapp/src/utils/passToLosslessJson.ts b/dapp/src/utils/passToLosslessJson.ts new file mode 100644 index 0000000..c47beec --- /dev/null +++ b/dapp/src/utils/passToLosslessJson.ts @@ -0,0 +1,12 @@ +import { parse, isNumber } from "lossless-json"; +import type { AnyObject } from "../types/types"; + +export const parseToLosslessJson = (stringObj: string) => { + return parse(stringObj, null, (value: any) => { + if (isNumber(value)) { + return BigInt(value); + } + + return value; + }) as AnyObject; +}; diff --git a/dapp/src/utils/stellarXdr.ts b/dapp/src/utils/stellarXdr.ts new file mode 100644 index 0000000..e045208 --- /dev/null +++ b/dapp/src/utils/stellarXdr.ts @@ -0,0 +1,24 @@ +import init, { + decode, + decode_stream, + encode, + guess, +} from "@stellar/stellar-xdr-json"; +import wasmUrl from "@stellar/stellar-xdr-json/stellar_xdr_json_bg.wasm?url"; + +// A wrapper for the Stellar XDR JSON +declare global { + interface Window { + __STELLAR_XDR_INIT__?: boolean; + } +} + +const initialize = async () => { + if (!window.__STELLAR_XDR_INIT__) { + await init(wasmUrl); + console.log("Stellar XDR JSON initialized"); + window.__STELLAR_XDR_INIT__ = true; + } +}; + +export { initialize, decode, decode_stream, encode, guess }; From 2d8be6c2cc9177b5b58f74fe9afbdd9b39327478 Mon Sep 17 00:00:00 2001 From: 0xExp-po Date: Sat, 14 Dec 2024 01:12:49 +0900 Subject: [PATCH 2/9] feat: create AES256 encrypt and decrypt app --- AES256-encryptor/.gitignore | 24 ++++++++ AES256-encryptor/README.md | 2 + AES256-encryptor/package.json | 40 ++++++++++++++ AES256-encryptor/public/index.html | 43 +++++++++++++++ AES256-encryptor/public/manifest.json | 25 +++++++++ AES256-encryptor/src/App.css | 0 AES256-encryptor/src/App.jsx | 75 +++++++++++++++++++++++++ AES256-encryptor/src/decryptData.js | 77 ++++++++++++++++++++++++++ AES256-encryptor/src/encryptData.js | 79 +++++++++++++++++++++++++++ AES256-encryptor/src/index.css | 8 +++ AES256-encryptor/src/index.js | 11 ++++ AES256-encryptor/src/logo.svg | 1 + 12 files changed, 385 insertions(+) create mode 100644 AES256-encryptor/.gitignore create mode 100644 AES256-encryptor/README.md create mode 100644 AES256-encryptor/package.json create mode 100644 AES256-encryptor/public/index.html create mode 100644 AES256-encryptor/public/manifest.json create mode 100644 AES256-encryptor/src/App.css create mode 100644 AES256-encryptor/src/App.jsx create mode 100644 AES256-encryptor/src/decryptData.js create mode 100644 AES256-encryptor/src/encryptData.js create mode 100644 AES256-encryptor/src/index.css create mode 100644 AES256-encryptor/src/index.js create mode 100644 AES256-encryptor/src/logo.svg diff --git a/AES256-encryptor/.gitignore b/AES256-encryptor/.gitignore new file mode 100644 index 0000000..2116652 --- /dev/null +++ b/AES256-encryptor/.gitignore @@ -0,0 +1,24 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local +package-lock.json + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/AES256-encryptor/README.md b/AES256-encryptor/README.md new file mode 100644 index 0000000..8d1efb0 --- /dev/null +++ b/AES256-encryptor/README.md @@ -0,0 +1,2 @@ +You can encryt string data to AES256 encrypted payload and decrypt it. +The displayed key is Hex data of key. diff --git a/AES256-encryptor/package.json b/AES256-encryptor/package.json new file mode 100644 index 0000000..8c8231d --- /dev/null +++ b/AES256-encryptor/package.json @@ -0,0 +1,40 @@ +{ + "name": "encrypt-proof", + "version": "0.1.0", + "private": true, + "dependencies": { + "cra-template": "1.2.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "react-scripts": "5.0.1" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject", + "formatter": "prettier --write .", + "linter": "prettier -c ." + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "devDependencies": { + "prettier": "^3.4.2" + } +} diff --git a/AES256-encryptor/public/index.html b/AES256-encryptor/public/index.html new file mode 100644 index 0000000..e65acb3 --- /dev/null +++ b/AES256-encryptor/public/index.html @@ -0,0 +1,43 @@ + + + + + + + + + + + + + React App + + + +
+ + + diff --git a/AES256-encryptor/public/manifest.json b/AES256-encryptor/public/manifest.json new file mode 100644 index 0000000..080d6c7 --- /dev/null +++ b/AES256-encryptor/public/manifest.json @@ -0,0 +1,25 @@ +{ + "short_name": "React App", + "name": "Create React App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/AES256-encryptor/src/App.css b/AES256-encryptor/src/App.css new file mode 100644 index 0000000..e69de29 diff --git a/AES256-encryptor/src/App.jsx b/AES256-encryptor/src/App.jsx new file mode 100644 index 0000000..01faab2 --- /dev/null +++ b/AES256-encryptor/src/App.jsx @@ -0,0 +1,75 @@ +import React, { useState, useEffect } from "react"; +import { generateKey, encryptData, getKeyHex } from "./encryptData.js"; +import { decryptData, getKeyFromHex } from "./decryptData.js"; + +const headerText = "storachaProof"; +const header = new TextEncoder().encode(headerText); + +const App = () => { + const [keyHex, setKeyHex] = useState(null); + const [plaintext, setPlaintext] = useState("This is secret data"); + const [encryptedPayload, setEncryptedPayload] = useState(null); + const [decryptedText, setDecryptedText] = useState(null); + + useEffect(() => { + (async () => { + const newKey = await generateKey(); + setKeyHex(await getKeyHex(newKey)); + })(); + }, []); + + const handleEncrypt = async () => { + if (keyHex) { + const data = new TextEncoder().encode(plaintext); + const key = await getKeyFromHex(keyHex); + const payload = await encryptData(key, data, header); + setEncryptedPayload(payload); + } + }; + + const handleDecrypt = async () => { + if (keyHex && encryptedPayload) { + const key = await getKeyFromHex(keyHex); + const decrypted = await decryptData(key, encryptedPayload); + setDecryptedText(new TextDecoder().decode(decrypted)); + } + }; + + return ( +
+

AES Encryption/Decryption in React

+
+ + setPlaintext(e.target.value)} + /> +
+
+ +
+ {keyHex && ( +
+

Key:

+

{keyHex}

+
+ )} + {encryptedPayload && ( +
+

Encrypted Payload:

+
{JSON.stringify(encryptedPayload, null, 2)}
+ +
+ )} + {decryptedText && ( +
+

Decrypted Text:

+

{decryptedText}

+
+ )} +
+ ); +}; + +export default App; diff --git a/AES256-encryptor/src/decryptData.js b/AES256-encryptor/src/decryptData.js new file mode 100644 index 0000000..3f3ca64 --- /dev/null +++ b/AES256-encryptor/src/decryptData.js @@ -0,0 +1,77 @@ +function base64ToArrayBuffer(base64) { + const binaryString = window.atob(base64); + const bytes = new Uint8Array(binaryString.length); + for (let i = 0; i < binaryString.length; i++) { + bytes[i] = binaryString.charCodeAt(i); + } + return bytes.buffer; +} + +function hexToArrayBuffer(hex) { + if (hex.length % 2 !== 0) { + throw new Error("Invalid hex string"); + } + const byteArray = new Uint8Array(hex.length / 2); + for (let i = 0; i < byteArray.length; i++) { + byteArray[i] = parseInt(hex.substr(i * 2, 2), 16); + } + return byteArray.buffer; +} + +/** + * Decrypts the given payload using the provided AES-GCM key. + * @param {CryptoKey} key - The AES-GCM key + * @param {Object} payload - The JSON payload with nonce, header, ciphertext, tag + * @returns {Uint8Array} plaintext + */ +export async function decryptData(key, payload) { + const nonce = new Uint8Array(base64ToArrayBuffer(payload.nonce)); + const header = new Uint8Array(base64ToArrayBuffer(payload.header)); + const ciphertext = new Uint8Array(base64ToArrayBuffer(payload.ciphertext)); + const tag = new Uint8Array(base64ToArrayBuffer(payload.tag)); + + // In AES-GCM, the tag is appended at the end of ciphertext, + // so we must recombine them before decrypting. + const encryptedCombined = new Uint8Array(ciphertext.length + tag.length); + encryptedCombined.set(ciphertext, 0); + encryptedCombined.set(tag, ciphertext.length); + + const decrypted = await window.crypto.subtle.decrypt( + { + name: "AES-GCM", + iv: nonce, + additionalData: header, + tagLength: 128, + }, + key, + encryptedCombined.buffer, + ); + + return new Uint8Array(decrypted); +} + +export async function getKeyFromHex(keyHex) { + const keyBytes = hexToArrayBuffer(keyHex); + const key = await window.crypto.subtle.importKey( + "raw", + keyBytes, + { name: "AES-GCM", length: 256 }, + true, // extractable (can be set to false in production if you don't need to export it) + ["encrypt", "decrypt"], + ); + + return key; +} + +export async function getKeyFromBase64(keyBase64) { + const keyBytes = base64ToArrayBuffer(keyBase64); + const key = await window.crypto.subtle.importKey( + "raw", + keyBytes, + { name: "AES-GCM", length: 256 }, + true, // extractable (can be set to false in production if you don't need to export it) + ["encrypt", "decrypt"], + ); + + return key; +} diff --git a/AES256-encryptor/src/encryptData.js b/AES256-encryptor/src/encryptData.js new file mode 100644 index 0000000..d3431af --- /dev/null +++ b/AES256-encryptor/src/encryptData.js @@ -0,0 +1,79 @@ +// A helper function to convert ArrayBuffers to base64 +function arrayBufferToBase64(buffer) { + let binary = ""; + const bytes = new Uint8Array(buffer); + for (let i = 0; i < bytes.byteLength; i++) { + binary += String.fromCharCode(bytes[i]); + } + return window.btoa(binary); +} + +// A helper function to convert ArrayBuffers to Hex +function arrayBufferToHex(buffer) { + const bytes = new Uint8Array(buffer); + return [...bytes].map((b) => b.toString(16).padStart(2, "0")).join(""); +} + +// Generate a new AES-GCM key (32-byte key) +export async function generateKey() { + return await window.crypto.subtle.generateKey( + { + name: "AES-GCM", + length: 256, + }, + true, + ["encrypt", "decrypt"], + ); +} + +/** + * Encrypts given data using the provided AES-GCM key. + * @param {CryptoKey} key - The AES-GCM key. + * @param {Uint8Array} data - The plaintext data to encrypt. + * @param {Uint8Array} header - Additional authenticated data. + * @returns {Object} payload containing nonce, header, ciphertext, tag + */ +export async function encryptData(key, data, header) { + // Generate a random nonce (nonce) + const nonce = window.crypto.getRandomValues(new Uint8Array(12)); + + const encrypted = await window.crypto.subtle.encrypt( + { + name: "AES-GCM", + iv: nonce, + additionalData: header, + tagLength: 128, + }, + key, + data, + ); + + // The encrypted result includes the ciphertext and tag together in AES-GCM. + // The last 16 bytes of the encrypted data are the tag. + const encryptedBytes = new Uint8Array(encrypted); + const ciphertext = encryptedBytes.slice(0, encryptedBytes.length - 16); + const tag = encryptedBytes.slice(encryptedBytes.length - 16); + + const payload = { + nonce: arrayBufferToBase64(nonce.buffer), + header: arrayBufferToBase64(header.buffer), + ciphertext: arrayBufferToBase64(ciphertext.buffer), + tag: arrayBufferToBase64(tag.buffer), + }; + + return payload; +} + +export async function getKeyHex(key) { + const rawKey = await window.crypto.subtle.exportKey("raw", key); + const keyHex = arrayBufferToHex(rawKey); + + return keyHex; +} + +export async function getKeyBase64(key) { + const rawKey = await window.crypto.subtle.exportKey("raw", key); + const keyBase64 = arrayBufferToBase64(rawKey); + + return keyBase64; +} diff --git a/AES256-encryptor/src/index.css b/AES256-encryptor/src/index.css new file mode 100644 index 0000000..ce5fda7 --- /dev/null +++ b/AES256-encryptor/src/index.css @@ -0,0 +1,8 @@ +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", + "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", + "Helvetica Neue", sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} diff --git a/AES256-encryptor/src/index.js b/AES256-encryptor/src/index.js new file mode 100644 index 0000000..df86817 --- /dev/null +++ b/AES256-encryptor/src/index.js @@ -0,0 +1,11 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import "./index.css"; +import App from "./App"; + +const root = ReactDOM.createRoot(document.getElementById("root")); +root.render( + + + , +); diff --git a/AES256-encryptor/src/logo.svg b/AES256-encryptor/src/logo.svg new file mode 100644 index 0000000..9dfc1c0 --- /dev/null +++ b/AES256-encryptor/src/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file From 2c40d1fb7b74b673ba506a449995d785c144e482 Mon Sep 17 00:00:00 2001 From: 0xExp-po Date: Sat, 14 Dec 2024 02:08:55 +0900 Subject: [PATCH 3/9] feat: use encrypted proof data --- .gitignore | 1 + dapp/src/pages/api/w3up-delegation.js | 7 +-- dapp/src/utils/decryptAES256.ts | 79 +++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 dapp/src/utils/decryptAES256.ts diff --git a/.gitignore b/.gitignore index 38e5445..fdb30b8 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,4 @@ yarn-error.log* # Storacha proof and keys .storacha +encrypted_proof.bin.test diff --git a/dapp/src/pages/api/w3up-delegation.js b/dapp/src/pages/api/w3up-delegation.js index 5c13ad5..2243b0c 100644 --- a/dapp/src/pages/api/w3up-delegation.js +++ b/dapp/src/pages/api/w3up-delegation.js @@ -13,6 +13,7 @@ import { getProjectFromName, } from "@service/ReadContractService"; import crypto from "crypto"; +import decryptProof from "../../utils/decryptAES256"; import pkg from "js-sha3"; const { keccak256 } = pkg; @@ -86,11 +87,9 @@ const getProjectMaintainers = async (projectName) => { async function generateDelegation(did) { const key = import.meta.env.STORACHA_SING_PRIVATE_KEY; - const storachaProof = import.meta.env.STORACHA_PROOF; - + let storachaProof = import.meta.env.STORACHA_PROOF; if (storachaProof.length === 64) { - // storachaProof is a AES256 key in that case - return null; + storachaProof = await decryptProof(storachaProof); } const proof = await Proof.parse(storachaProof); diff --git a/dapp/src/utils/decryptAES256.ts b/dapp/src/utils/decryptAES256.ts new file mode 100644 index 0000000..0f30d90 --- /dev/null +++ b/dapp/src/utils/decryptAES256.ts @@ -0,0 +1,79 @@ +import { promises as fs } from "fs"; + +export default async function decryptProof(keyHex: string): Promise { + const key = await getKeyFromHex(keyHex); + const fileContent = await fs.readFile("encrypted_proof.bin", "utf-8"); + const payload: { + nonce: string; + header: string; + ciphertext: string; + tag: string; + } = JSON.parse(fileContent); + + const decrypted = await decryptData(key, payload); + return new TextDecoder().decode(decrypted); +} + +async function getKeyFromHex(keyHex: string): Promise { + const keyBytes = hexToArrayBuffer(keyHex); + const key = await globalThis.crypto.subtle.importKey( + "raw", + keyBytes, + { name: "AES-GCM", length: 256 }, + true, + ["encrypt", "decrypt"], + ); + + return key; +} + +function hexToArrayBuffer(hex: string): ArrayBuffer { + if (hex.length % 2 !== 0) { + throw new Error("Invalid hex string"); + } + const byteArray = new Uint8Array(hex.length / 2); + for (let i = 0; i < byteArray.length; i++) { + byteArray[i] = parseInt(hex.substr(i * 2, 2), 16); + } + return byteArray.buffer; +} + +function atob(base64: string): string { + return Buffer.from(base64, "base64").toString("binary"); +} + +function base64ToArrayBuffer(base64: string): ArrayBuffer { + const binaryString = atob(base64); + const bytes = new Uint8Array(binaryString.length); + for (let i = 0; i < binaryString.length; i++) { + bytes[i] = binaryString.charCodeAt(i); + } + return bytes.buffer; +} + +async function decryptData( + key: CryptoKey, + payload: { nonce: string; header: string; ciphertext: string; tag: string }, +): Promise { + const nonce = new Uint8Array(base64ToArrayBuffer(payload.nonce)); + const header = new Uint8Array(base64ToArrayBuffer(payload.header)); + const ciphertext = new Uint8Array(base64ToArrayBuffer(payload.ciphertext)); + const tag = new Uint8Array(base64ToArrayBuffer(payload.tag)); + + const encryptedCombined = new Uint8Array(ciphertext.length + tag.length); + encryptedCombined.set(ciphertext, 0); + encryptedCombined.set(tag, ciphertext.length); + + const decrypted = await globalThis.crypto.subtle.decrypt( + { + name: "AES-GCM", + iv: nonce, + additionalData: header, + tagLength: 128, + }, + key, + encryptedCombined.buffer, + ); + + return new Uint8Array(decrypted); +} From 6d8a3bc91a4c7b24603370722ba7307241d12234 Mon Sep 17 00:00:00 2001 From: 0xExp-po Date: Sat, 14 Dec 2024 02:13:04 +0900 Subject: [PATCH 4/9] chore: remove demo out come data --- dapp/src/constants/demoProposalData.ts | 136 ------------------------- 1 file changed, 136 deletions(-) delete mode 100644 dapp/src/constants/demoProposalData.ts diff --git a/dapp/src/constants/demoProposalData.ts b/dapp/src/constants/demoProposalData.ts deleted file mode 100644 index 6bfff95..0000000 --- a/dapp/src/constants/demoProposalData.ts +++ /dev/null @@ -1,136 +0,0 @@ -export const demoOutcomeData: any = { - tx: { - tx: { - source_account: - "GBU764PFZXKZUORAUK3IG36Y6OXSLYM6ZERLJA2BZ2Y2GSKNKWL4KKC5", - fee: 5312486, - seq_num: 221608492723602976, - cond: { - time: { - min_time: 0, - max_time: 0, - }, - }, - memo: "none", - operations: [ - { - source_account: null, - body: { - invoke_host_function: { - host_function: { - invoke_contract: { - contract_address: - "CC5TSJ3E26YUYGYQKOBNJQLPX4XMUHUY7Q26JX53CJ2YUIZB5HVXXRV6", - function_name: "mine", - args: [ - { - bytes: - "000000ea80a23b9340abb81e22ebe2c84783896eab4ab047ebc006f9ca54fb66", - }, - { - string: "TANSU28", - }, - { - u64: 1188896, - }, - { - address: - "GBU764PFZXKZUORAUK3IG36Y6OXSLYM6ZERLJA2BZ2Y2GSKNKWL4KKC5", - }, - ], - }, - }, - auth: [ - { - credentials: "source_account", - root_invocation: { - function: { - contract_fn: { - contract_address: - "CC5TSJ3E26YUYGYQKOBNJQLPX4XMUHUY7Q26JX53CJ2YUIZB5HVXXRV6", - function_name: "mine", - args: [ - { - bytes: - "000000ea80a23b9340abb81e22ebe2c84783896eab4ab047ebc006f9ca54fb66", - }, - { - string: "TANSU28", - }, - { - u64: 1188896, - }, - { - address: - "GBU764PFZXKZUORAUK3IG36Y6OXSLYM6ZERLJA2BZ2Y2GSKNKWL4KKC5", - }, - ], - }, - }, - sub_invocations: [], - }, - }, - ], - }, - }, - }, - ], - ext: { - v1: { - ext: "v0", - resources: { - footprint: { - read_only: [ - { - contract_data: { - contract: - "CC2D4LQAWPMGD5A7XJHF5KN3A5QYJGQJS3VSFXR6TKTH6ZUR5RUFCYCW", - key: "ledger_key_contract_instance", - durability: "persistent", - }, - }, - ], - read_write: [ - { - trustline: { - account_id: - "GDNMPUEOS27LYEG4HS74RHLFWO325JMIDEAP67QOVYJBJC6XSGE4E5ST", - asset: { - credit_alphanum4: { - asset_code: "FCM", - issuer: - "GD765M4FIG4C4CGWUFDPD2QCWKISYRLBRIYMLSILCCTPY7DEGGUKPFBE", - }, - }, - }, - }, - { - contract_data: { - contract: - "CC5TSJ3E26YUYGYQKOBNJQLPX4XMUHUY7Q26JX53CJ2YUIZB5HVXXRV6", - key: { - vec: [ - { - symbol: "Block", - }, - { - u64: 4211, - }, - ], - }, - durability: "persistent", - }, - }, - ], - }, - instructions: 5000000, - read_bytes: 25000, - write_bytes: 1200, - }, - resource_fee: 5312386, - }, - }, - }, - signatures: [], - }, -}; From e58538d5de2241c11e1987acb011cb9a88dead5a Mon Sep 17 00:00:00 2001 From: 0xExp-po Date: Sat, 14 Dec 2024 02:56:42 +0900 Subject: [PATCH 5/9] chore: use real xdr in execute proposal modal --- .../components/page/proposal/ExecuteProposalModal.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dapp/src/components/page/proposal/ExecuteProposalModal.tsx b/dapp/src/components/page/proposal/ExecuteProposalModal.tsx index 8e0c78f..9264633 100644 --- a/dapp/src/components/page/proposal/ExecuteProposalModal.tsx +++ b/dapp/src/components/page/proposal/ExecuteProposalModal.tsx @@ -1,9 +1,10 @@ import React from "react"; import { useState, useEffect } from "react"; import JsonView from "react18-json-view"; -import { modifySlashInXdr, processDecodedData } from "utils/utils"; +import { modifySlashInXdr } from "utils/utils"; import { stellarLabViewXdrLink } from "constants/serviceLinks"; -import { demoOutcomeData } from "constants/demoProposalData"; +import * as StellarXdr from "utils/stellarXdr"; +import { parseToLosslessJson } from "utils/passToLosslessJson"; interface VotersModalProps { xdr: string; @@ -18,9 +19,8 @@ const VotersModal: React.FC = ({ xdr, onClose }) => { const getContentFromXdr = async (_xdr: string) => { try { if (_xdr) { - const decoded = processDecodedData(_xdr); - console.log("decode:", decoded); - setContent(demoOutcomeData); + const decoded = StellarXdr.decode("TransactionEnvelope", _xdr); + setContent(parseToLosslessJson(decoded)); } } catch (error) { console.error("Error decoding XDR:", error); From 5bf0b6d9e05fb4ba8b22fc441a6f936899cbb881 Mon Sep 17 00:00:00 2001 From: Tupui <23188539+tupui@users.noreply.github.com> Date: Fri, 13 Dec 2024 21:56:13 +0100 Subject: [PATCH 6/9] New proof --- dapp/encrypted_proof.bin | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dapp/encrypted_proof.bin b/dapp/encrypted_proof.bin index 34dec10..bb71be7 100644 --- a/dapp/encrypted_proof.bin +++ b/dapp/encrypted_proof.bin @@ -1,6 +1,6 @@ { - "nonce": "p0V6xMr0gyaDanKoJOmxEQ==", - "header": "c3RvcmFjaGFQcm9vZg==", - "ciphertext": "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", - "tag": "Hsfe5jPy5apzwm2G4PCD2g==" + "nonce": "gWp0ehc6dtNXYSCQ", + "header": "c3RvcmFjaGFQcm9vZg==", + "ciphertext": "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", + "tag": "tETKAp8LXBYe/fM8vmL5dg==" } \ No newline at end of file From 98bf52c9b6c12777802cc3a622e70c73204297da Mon Sep 17 00:00:00 2001 From: 0xExp-po Date: Sat, 14 Dec 2024 14:13:13 +0900 Subject: [PATCH 7/9] feat: create AES256-encrypt script --- tools/AES256-encrypt.js | 72 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 tools/AES256-encrypt.js diff --git a/tools/AES256-encrypt.js b/tools/AES256-encrypt.js new file mode 100644 index 0000000..af439f0 --- /dev/null +++ b/tools/AES256-encrypt.js @@ -0,0 +1,72 @@ +import { writeFileSync } from "fs"; +import { webcrypto } from "crypto"; + +const { subtle } = webcrypto; + +function arrayBufferToBase64(buffer) { + return Buffer.from(new Uint8Array(buffer)).toString("base64"); +} + +function arrayBufferToHex(buffer) { + const bytes = new Uint8Array(buffer); + return [...bytes].map((b) => b.toString(16).padStart(2, "0")).join(""); +} + +async function generateKey() { + return subtle.generateKey( + { + name: "AES-GCM", + length: 256, + }, + true, + ["encrypt", "decrypt"] + ); +} + +async function encryptData(key, data, header) { + // Generate a random nonce (12 bytes for AES-GCM) + const nonce = new Uint8Array(12); + webcrypto.getRandomValues(nonce); + + const encrypted = await subtle.encrypt( + { + name: "AES-GCM", + iv: nonce, + additionalData: header, + tagLength: 128, + }, + key, + data + ); + + const encryptedBytes = new Uint8Array(encrypted); + // Last 16 bytes are the authentication tag + const tag = encryptedBytes.slice(encryptedBytes.length - 16); + const ciphertext = encryptedBytes.slice(0, encryptedBytes.length - 16); + + return { + nonce: arrayBufferToBase64(nonce.buffer), + header: arrayBufferToBase64(header.buffer), + ciphertext: arrayBufferToBase64(ciphertext.buffer), + tag: arrayBufferToBase64(tag.buffer), + }; +} + +async function getKeyHex(key) { + const rawKey = await subtle.exportKey("raw", key); + return arrayBufferToHex(rawKey); +} + +(async () => { + const data = new TextEncoder().encode("This is some secret data..."); // This is our data to encrypt. + const header = new TextEncoder().encode("storachaProof"); + + const key = await generateKey(); + const keyHex = await getKeyHex(key); + console.log("This is our key in hex:", keyHex); + + const payload = await encryptData(key, data, header); + + writeFileSync("encrypted_proof.bin", JSON.stringify(payload, null, 4), "utf8"); + console.log("Encrypted data written to encrypted_proof.bin"); +})(); From e2d1db3f1c47e94de6b418c6c6cba778ae0f4d76 Mon Sep 17 00:00:00 2001 From: 0xExp-po Date: Sun, 15 Dec 2024 09:40:33 +0900 Subject: [PATCH 8/9] refactor: remove AES256-encryptor app --- AES256-encryptor/.gitignore | 24 -------- AES256-encryptor/README.md | 2 - AES256-encryptor/package.json | 40 -------------- AES256-encryptor/public/index.html | 43 --------------- AES256-encryptor/public/manifest.json | 25 --------- AES256-encryptor/src/App.css | 0 AES256-encryptor/src/App.jsx | 75 ------------------------- AES256-encryptor/src/decryptData.js | 77 -------------------------- AES256-encryptor/src/encryptData.js | 79 --------------------------- AES256-encryptor/src/index.css | 8 --- AES256-encryptor/src/index.js | 11 ---- AES256-encryptor/src/logo.svg | 1 - 12 files changed, 385 deletions(-) delete mode 100644 AES256-encryptor/.gitignore delete mode 100644 AES256-encryptor/README.md delete mode 100644 AES256-encryptor/package.json delete mode 100644 AES256-encryptor/public/index.html delete mode 100644 AES256-encryptor/public/manifest.json delete mode 100644 AES256-encryptor/src/App.css delete mode 100644 AES256-encryptor/src/App.jsx delete mode 100644 AES256-encryptor/src/decryptData.js delete mode 100644 AES256-encryptor/src/encryptData.js delete mode 100644 AES256-encryptor/src/index.css delete mode 100644 AES256-encryptor/src/index.js delete mode 100644 AES256-encryptor/src/logo.svg diff --git a/AES256-encryptor/.gitignore b/AES256-encryptor/.gitignore deleted file mode 100644 index 2116652..0000000 --- a/AES256-encryptor/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local -package-lock.json - -npm-debug.log* -yarn-debug.log* -yarn-error.log* diff --git a/AES256-encryptor/README.md b/AES256-encryptor/README.md deleted file mode 100644 index 8d1efb0..0000000 --- a/AES256-encryptor/README.md +++ /dev/null @@ -1,2 +0,0 @@ -You can encryt string data to AES256 encrypted payload and decrypt it. -The displayed key is Hex data of key. diff --git a/AES256-encryptor/package.json b/AES256-encryptor/package.json deleted file mode 100644 index 8c8231d..0000000 --- a/AES256-encryptor/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "encrypt-proof", - "version": "0.1.0", - "private": true, - "dependencies": { - "cra-template": "1.2.0", - "react": "^19.0.0", - "react-dom": "^19.0.0", - "react-scripts": "5.0.1" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject", - "formatter": "prettier --write .", - "linter": "prettier -c ." - }, - "eslintConfig": { - "extends": [ - "react-app", - "react-app/jest" - ] - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - }, - "devDependencies": { - "prettier": "^3.4.2" - } -} diff --git a/AES256-encryptor/public/index.html b/AES256-encryptor/public/index.html deleted file mode 100644 index e65acb3..0000000 --- a/AES256-encryptor/public/index.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - React App - - - -
- - - diff --git a/AES256-encryptor/public/manifest.json b/AES256-encryptor/public/manifest.json deleted file mode 100644 index 080d6c7..0000000 --- a/AES256-encryptor/public/manifest.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "short_name": "React App", - "name": "Create React App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/AES256-encryptor/src/App.css b/AES256-encryptor/src/App.css deleted file mode 100644 index e69de29..0000000 diff --git a/AES256-encryptor/src/App.jsx b/AES256-encryptor/src/App.jsx deleted file mode 100644 index 01faab2..0000000 --- a/AES256-encryptor/src/App.jsx +++ /dev/null @@ -1,75 +0,0 @@ -import React, { useState, useEffect } from "react"; -import { generateKey, encryptData, getKeyHex } from "./encryptData.js"; -import { decryptData, getKeyFromHex } from "./decryptData.js"; - -const headerText = "storachaProof"; -const header = new TextEncoder().encode(headerText); - -const App = () => { - const [keyHex, setKeyHex] = useState(null); - const [plaintext, setPlaintext] = useState("This is secret data"); - const [encryptedPayload, setEncryptedPayload] = useState(null); - const [decryptedText, setDecryptedText] = useState(null); - - useEffect(() => { - (async () => { - const newKey = await generateKey(); - setKeyHex(await getKeyHex(newKey)); - })(); - }, []); - - const handleEncrypt = async () => { - if (keyHex) { - const data = new TextEncoder().encode(plaintext); - const key = await getKeyFromHex(keyHex); - const payload = await encryptData(key, data, header); - setEncryptedPayload(payload); - } - }; - - const handleDecrypt = async () => { - if (keyHex && encryptedPayload) { - const key = await getKeyFromHex(keyHex); - const decrypted = await decryptData(key, encryptedPayload); - setDecryptedText(new TextDecoder().decode(decrypted)); - } - }; - - return ( -
-

AES Encryption/Decryption in React

-
- - setPlaintext(e.target.value)} - /> -
-
- -
- {keyHex && ( -
-

Key:

-

{keyHex}

-
- )} - {encryptedPayload && ( -
-

Encrypted Payload:

-
{JSON.stringify(encryptedPayload, null, 2)}
- -
- )} - {decryptedText && ( -
-

Decrypted Text:

-

{decryptedText}

-
- )} -
- ); -}; - -export default App; diff --git a/AES256-encryptor/src/decryptData.js b/AES256-encryptor/src/decryptData.js deleted file mode 100644 index 3f3ca64..0000000 --- a/AES256-encryptor/src/decryptData.js +++ /dev/null @@ -1,77 +0,0 @@ -function base64ToArrayBuffer(base64) { - const binaryString = window.atob(base64); - const bytes = new Uint8Array(binaryString.length); - for (let i = 0; i < binaryString.length; i++) { - bytes[i] = binaryString.charCodeAt(i); - } - return bytes.buffer; -} - -function hexToArrayBuffer(hex) { - if (hex.length % 2 !== 0) { - throw new Error("Invalid hex string"); - } - const byteArray = new Uint8Array(hex.length / 2); - for (let i = 0; i < byteArray.length; i++) { - byteArray[i] = parseInt(hex.substr(i * 2, 2), 16); - } - return byteArray.buffer; -} - -/** - * Decrypts the given payload using the provided AES-GCM key. - * @param {CryptoKey} key - The AES-GCM key - * @param {Object} payload - The JSON payload with nonce, header, ciphertext, tag - * @returns {Uint8Array} plaintext - */ -export async function decryptData(key, payload) { - const nonce = new Uint8Array(base64ToArrayBuffer(payload.nonce)); - const header = new Uint8Array(base64ToArrayBuffer(payload.header)); - const ciphertext = new Uint8Array(base64ToArrayBuffer(payload.ciphertext)); - const tag = new Uint8Array(base64ToArrayBuffer(payload.tag)); - - // In AES-GCM, the tag is appended at the end of ciphertext, - // so we must recombine them before decrypting. - const encryptedCombined = new Uint8Array(ciphertext.length + tag.length); - encryptedCombined.set(ciphertext, 0); - encryptedCombined.set(tag, ciphertext.length); - - const decrypted = await window.crypto.subtle.decrypt( - { - name: "AES-GCM", - iv: nonce, - additionalData: header, - tagLength: 128, - }, - key, - encryptedCombined.buffer, - ); - - return new Uint8Array(decrypted); -} - -export async function getKeyFromHex(keyHex) { - const keyBytes = hexToArrayBuffer(keyHex); - const key = await window.crypto.subtle.importKey( - "raw", - keyBytes, - { name: "AES-GCM", length: 256 }, - true, // extractable (can be set to false in production if you don't need to export it) - ["encrypt", "decrypt"], - ); - - return key; -} - -export async function getKeyFromBase64(keyBase64) { - const keyBytes = base64ToArrayBuffer(keyBase64); - const key = await window.crypto.subtle.importKey( - "raw", - keyBytes, - { name: "AES-GCM", length: 256 }, - true, // extractable (can be set to false in production if you don't need to export it) - ["encrypt", "decrypt"], - ); - - return key; -} diff --git a/AES256-encryptor/src/encryptData.js b/AES256-encryptor/src/encryptData.js deleted file mode 100644 index d3431af..0000000 --- a/AES256-encryptor/src/encryptData.js +++ /dev/null @@ -1,79 +0,0 @@ -// A helper function to convert ArrayBuffers to base64 -function arrayBufferToBase64(buffer) { - let binary = ""; - const bytes = new Uint8Array(buffer); - for (let i = 0; i < bytes.byteLength; i++) { - binary += String.fromCharCode(bytes[i]); - } - return window.btoa(binary); -} - -// A helper function to convert ArrayBuffers to Hex -function arrayBufferToHex(buffer) { - const bytes = new Uint8Array(buffer); - return [...bytes].map((b) => b.toString(16).padStart(2, "0")).join(""); -} - -// Generate a new AES-GCM key (32-byte key) -export async function generateKey() { - return await window.crypto.subtle.generateKey( - { - name: "AES-GCM", - length: 256, - }, - true, - ["encrypt", "decrypt"], - ); -} - -/** - * Encrypts given data using the provided AES-GCM key. - * @param {CryptoKey} key - The AES-GCM key. - * @param {Uint8Array} data - The plaintext data to encrypt. - * @param {Uint8Array} header - Additional authenticated data. - * @returns {Object} payload containing nonce, header, ciphertext, tag - */ -export async function encryptData(key, data, header) { - // Generate a random nonce (nonce) - const nonce = window.crypto.getRandomValues(new Uint8Array(12)); - - const encrypted = await window.crypto.subtle.encrypt( - { - name: "AES-GCM", - iv: nonce, - additionalData: header, - tagLength: 128, - }, - key, - data, - ); - - // The encrypted result includes the ciphertext and tag together in AES-GCM. - // The last 16 bytes of the encrypted data are the tag. - const encryptedBytes = new Uint8Array(encrypted); - const ciphertext = encryptedBytes.slice(0, encryptedBytes.length - 16); - const tag = encryptedBytes.slice(encryptedBytes.length - 16); - - const payload = { - nonce: arrayBufferToBase64(nonce.buffer), - header: arrayBufferToBase64(header.buffer), - ciphertext: arrayBufferToBase64(ciphertext.buffer), - tag: arrayBufferToBase64(tag.buffer), - }; - - return payload; -} - -export async function getKeyHex(key) { - const rawKey = await window.crypto.subtle.exportKey("raw", key); - const keyHex = arrayBufferToHex(rawKey); - - return keyHex; -} - -export async function getKeyBase64(key) { - const rawKey = await window.crypto.subtle.exportKey("raw", key); - const keyBase64 = arrayBufferToBase64(rawKey); - - return keyBase64; -} diff --git a/AES256-encryptor/src/index.css b/AES256-encryptor/src/index.css deleted file mode 100644 index ce5fda7..0000000 --- a/AES256-encryptor/src/index.css +++ /dev/null @@ -1,8 +0,0 @@ -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", - "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", - "Helvetica Neue", sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} diff --git a/AES256-encryptor/src/index.js b/AES256-encryptor/src/index.js deleted file mode 100644 index df86817..0000000 --- a/AES256-encryptor/src/index.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from "react"; -import ReactDOM from "react-dom/client"; -import "./index.css"; -import App from "./App"; - -const root = ReactDOM.createRoot(document.getElementById("root")); -root.render( - - - , -); diff --git a/AES256-encryptor/src/logo.svg b/AES256-encryptor/src/logo.svg deleted file mode 100644 index 9dfc1c0..0000000 --- a/AES256-encryptor/src/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From a8e5ca354d5795108b7b52943a3ce41492ea16f2 Mon Sep 17 00:00:00 2001 From: 0xExp-po Date: Sun, 15 Dec 2024 09:41:16 +0900 Subject: [PATCH 9/9] chore: remove logs --- dapp/src/components/page/governance/ProposalForm.tsx | 2 -- dapp/src/pages/api/w3up-delegation.js | 5 ----- dapp/src/utils/stellarXdr.ts | 1 - 3 files changed, 8 deletions(-) diff --git a/dapp/src/components/page/governance/ProposalForm.tsx b/dapp/src/components/page/governance/ProposalForm.tsx index b104325..2b59e47 100644 --- a/dapp/src/components/page/governance/ProposalForm.tsx +++ b/dapp/src/components/page/governance/ProposalForm.tsx @@ -203,7 +203,6 @@ const ProposalForm: React.FC = () => { cause: delegation.error, }); } - console.log("Delegation successfully extracted from server"); const space = await client.addSpace(delegation.ok); @@ -249,7 +248,6 @@ const ProposalForm: React.FC = () => { } const directoryCid = await client.uploadDirectory(files); - console.log("Proposal successfully uploaded to IPFS"); if (!directoryCid) { alert("Failed to upload proposal"); diff --git a/dapp/src/pages/api/w3up-delegation.js b/dapp/src/pages/api/w3up-delegation.js index 2243b0c..01226de 100644 --- a/dapp/src/pages/api/w3up-delegation.js +++ b/dapp/src/pages/api/w3up-delegation.js @@ -116,11 +116,6 @@ async function generateDelegation(did) { expiration, }); - console.log( - "delegation expire time:", - new Date(delegation.expiration * 1000).toUTCString(), - ); - const archive = await delegation.archive(); return archive.ok; } diff --git a/dapp/src/utils/stellarXdr.ts b/dapp/src/utils/stellarXdr.ts index e045208..1aeb858 100644 --- a/dapp/src/utils/stellarXdr.ts +++ b/dapp/src/utils/stellarXdr.ts @@ -16,7 +16,6 @@ declare global { const initialize = async () => { if (!window.__STELLAR_XDR_INIT__) { await init(wasmUrl); - console.log("Stellar XDR JSON initialized"); window.__STELLAR_XDR_INIT__ = true; } };