Skip to content

Commit

Permalink
feat(scan): add prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
mrcnk committed Oct 2, 2024
1 parent 0f3df90 commit 51694e2
Show file tree
Hide file tree
Showing 33 changed files with 761 additions and 218 deletions.
35 changes: 35 additions & 0 deletions .github/workflows/deploy-ghp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Deploy to GitHub Pages
on:
push:
branches: ["main"]
jobs:
build_site:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- name: Install dependencies
run: bun install
- name: build
env:
BASE_PATH: "/${{ github.event.repository.name }}"
run: |
npm bun run build
- name: Upload Artifacts
uses: actions/upload-pages-artifact@v3
with:
path: "build/"
deploy:
needs: build_site
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy
id: deployment
uses: actions/deploy-pages@v4
7 changes: 5 additions & 2 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
},
"files": {
"ignoreUnknown": false,
"ignore": []
"ignore": ["node_modules/**/*", ".svelte-kit/**/*", "build/**/*"]
},
"formatter": {
"enabled": true,
Expand All @@ -19,7 +19,10 @@
"linter": {
"enabled": true,
"rules": {
"recommended": true
"recommended": true,
"style": {
"useConst": "off"
}
}
},
"javascript": {
Expand Down
Binary file modified bun.lockb
Binary file not shown.
10 changes: 9 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,27 @@
"zustand": "^5.0.0-rc.2"
},
"dependencies": {
"@blu3r4y/lzma": "2.3.3",
"@castlenine/svelte-qrcode": "^2.2.0",
"@mina-js/accounts": "https://pkg.pr.new/palladians/mina-js/@mina-js/accounts@8107d7d",
"@noble/hashes": "^1.5.0",
"@scure/base": "^1.1.9",
"@scure/bip32": "^1.5.0",
"@scure/bip39": "^1.4.0",
"compress-json": "^3.1.0",
"html5-qrcode": "^2.3.8",
"immer": "^10.1.1",
"lucide-svelte": "^0.446.0",
"lzw-compressor": "^21.6.5",
"mina-signer": "^3.0.7",
"minizlib": "^3.0.1",
"nanoid": "^5.0.7",
"o1js": "^1.8.0",
"svelte-sonner": "^0.3.28",
"toml": "^3.0.0",
"ts-pattern": "^5.4.0"
"ts-pattern": "^5.4.0",
"zipson": "^0.2.12",
"zipurl": "^1.0.2",
"zod": "^3.23.8"
}
}
36 changes: 36 additions & 0 deletions src/lib/components/account-qr-modal.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<script lang="ts">
import { getTransportableAccount } from "$lib/transport";
import { getVault } from "$lib/vault";
import QRCode from "@castlenine/svelte-qrcode";
import { type Writable, derived } from "svelte/store";
export let accountId: Writable<string>;
const vault = getVault();
const account = derived([vault, accountId], ([$vault, $accountId]) => {
return $vault.accounts.find((account) => account.id === $accountId);
});
const transportableAccount = derived(account, ($account) => {
if (!$account) return "";
return getTransportableAccount({
address: $account.address,
signer: $account.signer,
derivationPath: $account.derivationPath,
});
});
</script>

<dialog id="qr_modal" class="modal">
{#key $accountId}
<div class="modal-box">
{#if $account}
<QRCode data={$transportableAccount} isResponsive />
{/if}
</div>
<form method="dialog" class="modal-backdrop">
<button>close</button>
</form>
{/key}
</dialog>
46 changes: 46 additions & 0 deletions src/lib/components/account-tile.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<script lang="ts">
import { goto } from "$app/navigation";
import { arrayToPath, truncateString } from "$lib/utils";
import { type Account, getVault } from "$lib/vault";
import { MoreVerticalIcon } from "lucide-svelte";
const vault = getVault();
export let account: Account;
export let exportQr: () => void;
const removeAccount = async () => {
$vault.removeAccount(account.id);
goto("/accounts");
};
</script>

<div class="card bg-neutral">
<div class="card-body flex-row">
<div class="flex flex-col flex-1">
<p>
{truncateString({
value: account.address,
endCharCount: 5,
firstCharCount: 5,
})}
</p>
<p>{arrayToPath(account.derivationPath)}</p>
<p>{account.signer}</p>
</div>
<div class="flex flex-col items-end gap-2">
<div class="dropdown dropdown-end">
<button tabindex="0" class="btn btn-square"
><MoreVerticalIcon size={16} /></button
>
<ul
tabindex="0"
class="dropdown-content menu bg-gray-800 rounded-box z-[1] w-52 p-2 shadow"
>
<li><button on:click={removeAccount}>Remove</button></li>
</ul>
</div>
<button class="btn" on:click={exportQr}>Export QR</button>
</div>
</div>
</div>
6 changes: 3 additions & 3 deletions src/lib/components/nav-item.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<script lang="ts">
export const href = "";
export const label = "";
export let href = "";
export let label = "";
</script>

<a {href} class="flex flex-col items-center justify-center gap-1">
<slot size={28} />
<span class="text-sm">{label}</span>
<span class="text-sm text-white">{label}</span>
</a>
2 changes: 1 addition & 1 deletion src/lib/components/top-bar.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
export const title = "";
export let title = "";
</script>

<header
Expand Down
43 changes: 12 additions & 31 deletions src/lib/signers/_/types.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,19 @@
export type DerivationPath = string;
export type PublicKey = string;
export type PrivateKey = string;
import type { DerivationPath, PrivateKey, PublicKey } from "$lib/types";

export type CommonSigner<T> = {
export type CommonSignArgs = {
childPrivateKey: PrivateKey;
type: number;
};

type Sign<T extends CommonSignArgs> = (args: T) => Promise<string>;

export type CommonSigner<T extends CommonSignArgs> = {
name: string;
slug: string;
getPublicKey: ({
privateKey,
}: {
privateKey: PrivateKey;
}) => Promise<PublicKey>;
deriveChildPrivateKey: ({
rootPrivateKey,
derivationPath,
}: {
getPublicKey: (args: { privateKey: PrivateKey }) => Promise<PublicKey>;
deriveChildPrivateKey: (args: {
rootPrivateKey: PrivateKey;
derivationPath: DerivationPath;
}) => Promise<string>;
signTransaction: ({
unsignedTransaction,
childPrivateKey,
options,
}: {
unsignedTransaction: T;
childPrivateKey: PrivateKey;
options?: Record<string, string>;
}) => Promise<string>;
signMessage: ({
message,
childPrivateKey,
options,
}: {
message: string;
childPrivateKey: PrivateKey;
options?: Record<string, string>;
}) => Promise<string>;
sign: Sign<T>;
};
34 changes: 19 additions & 15 deletions src/lib/signers/mina/signer.spec.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
import { expect, it } from "bun:test";
import { pathToArray } from "$lib/utils";
import { createSigner } from "./signer";

const rootPrivateKey =
"59eabf9e91adfc40f7529e619fd9a7b47d41621715c27ce699da9a3a741536f377c405e496c91361ff3d65de1bb60f52c0add214d186ea0721151bee914e55fb";
const testPrivateKey = "EKEKBJEKE4HkjsZNpdq6mAg7Ekppa84F8hzPJxKaaGGtVUcuYpt5";
"xprv9s21ZrQH143K2qibXtqGd39wAWC6cho6YL2poXyZC1ah44GGFESc2D779kstN93jzVN5Vf68usCQnHkPMcXfjNRfBp1HkDnjadcbrYwRptF";
const testPrivateKey = "EKEG5Dj44pUvRGwPZauMzYnneFWAyCn3qoJLCSwX2BnkJg4duYa4";

it("derives a child private key", async () => {
const signer = createSigner();
const childPrivateKey = await signer.deriveChildPrivateKey({
rootPrivateKey,
derivationPath: "m/44'/12586'/0'/0/0",
derivationPath: pathToArray("m/44'/12586'/0'/0/0"),
});
expect(childPrivateKey).toEqual(testPrivateKey);
});

it("signs a message", async () => {
const signer = createSigner();
const message = "Bonjour";
const signedMessage = await signer.signMessage({
message,
const signedMessage = await signer.sign({
type: 0,
payload: message,
childPrivateKey: testPrivateKey,
options: { minaNetwork: "mainnet" },
network: 0,
});
expect(signedMessage).toEqual(
"7mXLNa1vVrj9EXWhMqvE4k15XJ9ibp4DTLPYc5GvrdcwKYk2j5d83qGLy75Wp8a3NHeahos2d7oejBmrAGMuf8FKmKernmcr",
"7mX2cx8F3bFr7Tcc4N9MfxdnV91PJW3NvyUVnt5JPJ2DfhAjZXsJbgD2FCQG1HdaEKjtuirJT6NhigqQhoqrdcFbc2sKmZ6M",
);
});

Expand All @@ -36,25 +38,27 @@ it("signs a transaction", async () => {
amount: "3000000000",
fee: "100000000",
};
const signedTransaction = await signer.signTransaction({
unsignedTransaction: transaction,
const signedTransaction = await signer.sign({
type: 1,
payload: transaction,
childPrivateKey: testPrivateKey,
options: { minaNetwork: "mainnet" },
network: 0,
});
expect(signedTransaction).toEqual(
"7mXNb9QUAvMZn6aLzDYQPk75jpvhseXV1mFFLVa6P2FvdZb6JYwkDnBfn5kAB1mNQjTcUBT4b6KZ3Xg8fYUyacEJYTn4ATmB",
"7mX3cnNN6xZzRSYnmZtfpCXaiRfhmwdJALDXayM1HTvjTvnsBR4gQYNzreribztMvcBk4nu2YX2Cx2GM3hhPf3Z2g9toH8v5",
);
});

it("signs fields", async () => {
const signer = createSigner();
const fields = ["1", "2", "3"];
const signedFields = await signer.signFields({
fields,
const signedFields = await signer.sign({
type: 2,
payload: fields,
childPrivateKey: testPrivateKey,
options: { minaNetwork: "mainnet" },
network: 0,
});
expect(signedFields).toEqual(
"7mXCUvhLhFvG9ptrdfNceCrpThkCUyg1ct2z8uwY7eQbKz7UNmhv33TbuDjTznaypJtXRiMJyQWDnf27TH1FSXG7uJHTKAd9",
"7mWxizVb37wnPwUKborEy513t8GAnX1d5nmna4vgECudYA6EfHBa8xhmYqJgzDDMVFQ2THZ121xrRXK9nuq7omXNfa8WatvY",
);
});
Loading

0 comments on commit 51694e2

Please sign in to comment.