Skip to content

Commit f712143

Browse files
authored
create & restore wallet ✨
0 parents  commit f712143

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+2290
-0
lines changed

bun.lockb

150 KB
Binary file not shown.

lint-staged.config.cjs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* https://github.com/vercel/next.js/blob/canary/lint-staged.config.js
3+
*/
4+
5+
const { quote } = require("shell-quote");
6+
7+
const isWin = process.platform === "win32";
8+
9+
module.exports = {
10+
"**/*.{js,jsx,cjs,mjs,ts,tsx,mts,cts,md,json}": (filenames) => {
11+
const escapedFileNames = filenames
12+
.map((filename) => `"${isWin ? filename : escape([filename])}"`)
13+
.join(" ");
14+
return [
15+
`prettier --write ${escapedFileNames}`,
16+
`git add ${escapedFileNames}`,
17+
];
18+
},
19+
};
20+
21+
function escape(str) {
22+
const escaped = quote(str);
23+
return escaped.replace(/\\@/g, "@");
24+
}

options.html

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Options</title>
5+
</head>
6+
7+
<body>
8+
<div id="root"></div>
9+
<script type="module" src="./src/options.tsx"></script>
10+
</body>
11+
</html>

package.json

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"name": "cesium",
3+
"private": true,
4+
"type": "module",
5+
"scripts": {
6+
"prepare": "husky install",
7+
"dev": "vite build --watch",
8+
"build": "vite build",
9+
"ui": "bunx --bun vite dev",
10+
"export": "vite build && zip -r dist.zip dist",
11+
"style": "prettier --check \"src/**/*.{ts,tsx}\"",
12+
"style:fix": "prettier --write \"src/**/*.{ts,tsx}\""
13+
},
14+
"author": "Nano Gift Developers",
15+
"license": "MIT",
16+
"dependencies": {
17+
"@emotion/react": "^11.11.4",
18+
"multi-nano-web": "^1.5.1",
19+
"react": "^18.2.0",
20+
"react-confetti-boom": "^1.0.0",
21+
"react-dom": "^18.2.0",
22+
"react-icons": "^5.0.1",
23+
"react-spinners": "^0.13.8",
24+
"react-toastify": "^10.0.5",
25+
"vite-plugin-node-polyfills": "^0.21.0"
26+
},
27+
"prettier": {
28+
"tabWidth": 2
29+
},
30+
"devDependencies": {
31+
"@tailwindcss/forms": "^0.5.7",
32+
"@types/chrome": "0.0.158",
33+
"@types/node": "^20.10.4",
34+
"@types/react": "^18.0.29",
35+
"@types/react-dom": "^18.0.11",
36+
"@vitejs/plugin-react-swc": "^3.5.0",
37+
"autoprefixer": "^10.4.16",
38+
"husky": "^8.0.3",
39+
"lint-staged": "^15.2.0",
40+
"postcss": "^8.4.32",
41+
"prettier": "^2.2.1",
42+
"shell-quote": "^1.8.1",
43+
"tailwindcss": "^3.3.6",
44+
"typescript": "^5.0.4",
45+
"vite": "^5.0.7"
46+
}
47+
}

popup.html

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>Cesium Wallet</title>
6+
</head>
7+
<body>
8+
<div id="root"></div>
9+
<script type="module" src="./src/popup.tsx"></script>
10+
</body>
11+
</html>

postcss.config.cjs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
plugins: {
3+
tailwindcss: {},
4+
autoprefixer: {},
5+
},
6+
};

public/fonts/tauri.ttf

32.5 KB
Binary file not shown.

public/icon.png

1.73 KB
Loading

public/img/logo.svg

+3
Loading

public/manifest.json

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"manifest_version": 3,
3+
"name": "Cesium Wallet",
4+
"description": "Secure, private and minimalist wallet extension for the Nano (XNO) - brought to you by Nano Gift",
5+
"version": "1.0",
6+
"options_ui": {
7+
"page": "options.html",
8+
"open_in_tab": true
9+
},
10+
"action": {
11+
"default_icon": "icon.png",
12+
"default_popup": "popup.html"
13+
},
14+
"icons": {
15+
"16": "icon.png",
16+
"32": "icon.png",
17+
"48": "icon.png",
18+
"128": "icon.png"
19+
},
20+
"content_scripts": [
21+
{
22+
"matches": ["<all_urls>"],
23+
"js": ["content_script.js"]
24+
}
25+
],
26+
"background": {
27+
"type": "module",
28+
"service_worker": "service_worker.js"
29+
},
30+
"permissions": ["storage", "tabs"],
31+
"host_permissions": ["<all_urls>"]
32+
}

src/background.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const sessionPrefix = "session_";
2+
3+
function clearSessionData() {
4+
chrome.storage.local.get(null, function (items) {
5+
for (var key in items) {
6+
if (key.startsWith(sessionPrefix)) {
7+
chrome.storage.local.remove(key);
8+
}
9+
}
10+
});
11+
}
12+
13+
chrome.runtime.onStartup.addListener(function () {
14+
return clearSessionData();
15+
});

src/components/Popup/Forgot.tsx

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import React from "react";
2+
3+
import "../../styles/forgot.css";
4+
import { BiLockAlt } from "react-icons/bi";
5+
import { BiX } from "react-icons/bi";
6+
7+
import { resetWallet } from "../../utils/storage";
8+
9+
export default function Forgot({
10+
goBack,
11+
}: {
12+
goBack: React.Dispatch<React.SetStateAction<boolean>>;
13+
}) {
14+
return (
15+
<>
16+
<section className="forgot-nav select-none">
17+
<div
18+
className="forgot-close-btn !text-red-500 !ml-3 hover:!bg-black !rounded-full"
19+
onClick={() => goBack(false)}
20+
>
21+
<BiX size={24} />
22+
</div>
23+
<div className="forgot-w">
24+
<p>Forgot Password</p>
25+
</div>
26+
<div />
27+
</section>
28+
29+
<div className="forgot-c-w !p-3">
30+
<div />
31+
<section className="forgot-c-s">
32+
<BiLockAlt size={128} className="!mb-3 p-6 bg-black/50 rounded-full" />
33+
<p className="forgot-p-c-s-p !mb-2">Forgot Password</p>
34+
<p className="f-p-c">
35+
You can reset your password by entering your wallet's 24 word
36+
recovery phrase. Cesium cannot recover your password for you.
37+
</p>
38+
</section>
39+
40+
<div className="w-full">
41+
<button className="f-p-c-b hover:!bg-red-400" onClick={() => {
42+
resetWallet();
43+
return window.location.reload();
44+
}}>Reset Secret Phrase</button>
45+
</div>
46+
</div>
47+
</>
48+
);
49+
}
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import Navbar from "../Lock/Navbar";
2+
import { Dispatch } from "react";
3+
4+
export default function Start({ setW }: { setW: Dispatch<React.SetStateAction<number>> }) {
5+
return (
6+
<div className="min-h-[554px]">
7+
<Navbar />
8+
<div className="flex flex-col justify-between align-center p-[20px] h-full">
9+
<div className="init-wrapper">
10+
<div className="start-content">
11+
<div className="select-none items-center flex flex-col justify-center align-center w-full">
12+
<div className="flex flex-col space-y-3 items-center justify-center w-full">
13+
<img
14+
src="img/logo.svg"
15+
className="w-auto h-32 mr-2"
16+
alt="Cesium Wallet Logo"
17+
draggable={false}
18+
/>
19+
<div className="flex flex-col">
20+
<span className="text-sm text-gray-600">
21+
Created with ❤️ by{" "}
22+
<a
23+
href="https://nano.gift/"
24+
onClick={(e) => {
25+
e.preventDefault();
26+
return chrome.tabs.create({ url: 'https://nano.gift/?referrer=caesium'});
27+
}}
28+
className="text-blue-500 hover:underline"
29+
target="_blank"
30+
rel="noopener noreferrer"
31+
>
32+
Nano Gift
33+
</a>
34+
</span>
35+
</div>
36+
</div>
37+
<p className="start-content-text">
38+
To get started, create a new wallet or import one from a seed
39+
phrase.
40+
</p>
41+
</div>
42+
</div>
43+
44+
<div className="buttons-wrapper">
45+
<div className="button-create" role="button" onClick={() => setW(1)}>
46+
Create a new wallet
47+
</div>
48+
49+
<div className="button-restore" role="button" onClick={() => setW(4)}>
50+
I already have a wallet
51+
</div>
52+
</div>
53+
</div>
54+
</div>
55+
</div>
56+
);
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import React, { Dispatch, useEffect, useState } from "react";
2+
import { IoArrowBack } from "react-icons/io5";
3+
import Confetti from "react-confetti-boom";
4+
import { HashLoader as RingLoader } from "react-spinners";
5+
import { getSessionValue, setLocalStorage } from "../../../../utils/storage";
6+
7+
// @ts-expect-error no check
8+
import cryptoWorker from "../../../../worker/crypto?worker&url";
9+
10+
export default function Created({
11+
setW,
12+
prevStep,
13+
}: {
14+
setW: Dispatch<React.SetStateAction<number>>;
15+
prevStep?: number;
16+
}) {
17+
const [loading, setLoading] = useState<boolean>(true);
18+
const [password, setPassword] = useState<string>("");
19+
const [mnemonic, setMnemonic] = useState<string>("");
20+
21+
useEffect(() => {
22+
async function fetchData() {
23+
const fetchedPassword = await getSessionValue("password");
24+
const fetchedMnemonic = await getSessionValue("mnemonic");
25+
setPassword(fetchedPassword || "");
26+
setMnemonic(fetchedMnemonic || "");
27+
setLoading(false);
28+
}
29+
30+
fetchData();
31+
}, []);
32+
33+
useEffect(() => {
34+
async function encryptData() {
35+
if (password && mnemonic) {
36+
try {
37+
setLoading(true);
38+
const worker = new Worker(cryptoWorker, { type: "module" });
39+
40+
worker.onmessage = (event) => {
41+
const { result, error } = event.data;
42+
if (result) {
43+
setLocalStorage("encryptedMasterKey", result);
44+
} else if (error) {
45+
console.error("Encryption failed:", error);
46+
}
47+
setLoading(false);
48+
};
49+
50+
worker.postMessage({
51+
action: "encrypt",
52+
payload: { seed: mnemonic, password },
53+
});
54+
} catch (error) {
55+
console.error("Error occurred:", error);
56+
setLoading(false);
57+
}
58+
}
59+
}
60+
61+
encryptData();
62+
}, [password, mnemonic]);
63+
64+
return (
65+
<>
66+
<div className="step-p-nav">
67+
<div
68+
className="cursor-pointer text-slate-400 hover:text-slate-200"
69+
role="button"
70+
onClick={() => setW(prevStep || 2)}
71+
>
72+
<IoArrowBack size={20} />
73+
</div>
74+
<div className="step-p-steps select-none">
75+
<div className="step-dot mr-[10px]" />
76+
<div className="step-dot mr-[10px]" />
77+
<div className="step-dot" />
78+
</div>
79+
</div>
80+
{loading ? (
81+
<div className="flex justify-center items-center h-full">
82+
<RingLoader color={"#FFFFFF"} loading={loading} size={150} />
83+
</div>
84+
) : (
85+
<>
86+
<div className="relative flex items-center align-center justify-center !min-h-[554px] h-full w-full">
87+
<div className="flex flex-col p-2 items-center align-center justify-center select-none">
88+
<img
89+
src="img/logo.svg"
90+
className="h-32 w-auto"
91+
draggable={false}
92+
/>
93+
<p className="mt-4 text-2xl">You're all done!</p>
94+
<p className="mt-2 text-md text-slate-300">
95+
You can now fully enjoy your wallet.
96+
</p>
97+
98+
<div className="ml-2 mr-2 flex justify-center">
99+
<button className="absolute bottom-0 mb-4 w-11/12 rounded-md hover:bg-blue-400 !text-black p-3 bg-blue-500" onClick={() => window.location.reload()}>
100+
Get Started
101+
</button>
102+
</div>
103+
</div>
104+
</div>
105+
106+
<Confetti
107+
particleCount={50}
108+
shapeSize={8}
109+
mode="fall"
110+
colors={["#0096FF", "#0047AB", "#FFFF8F", "#301934", "#FFE5B4"]}
111+
/>
112+
</>
113+
)}
114+
</>
115+
);
116+
}

0 commit comments

Comments
 (0)