Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ jobs:
- name: Install dependencies
run: pnpm i --frozen-lockfile

- name: Build dependencies
working-directory: .
run: pnpm --filter passkeys --filter passkeys-react build

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: dist-files
path: |
packages/passkeys/dist
packages/passkeys-react/dist

- name: Run ESLint
run: pnpm lint

Expand Down Expand Up @@ -72,6 +84,12 @@ jobs:
- name: Install dependencies
run: pnpm i --frozen-lockfile

- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: dist-files
path: packages

- name: Run build
working-directory: apps/signer
run: pnpm build
2 changes: 2 additions & 0 deletions apps/signer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"lint": "eslint"
},
"dependencies": {
"passkeys": "workspace:*",
"passkeys-react": "workspace:*",
"@better-fetch/fetch": "^1.1.18",
"@jstz-dev/jstz-client": "0.1.1-alpha.5",
"@jstz-dev/jstz_sdk": "0.1.1-alpha.5",
Expand Down
13 changes: 0 additions & 13 deletions apps/signer/src/lib/passkeys/usePasskeyWallet.ts

This file was deleted.

2 changes: 1 addition & 1 deletion apps/signer/src/lib/passkeys/userStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import SuperJSON from "superjson";
import { createStore } from "zustand";
import type { PersistStorage } from "zustand/middleware";
import { devtools, persist } from "zustand/middleware";
import { RP_ID } from "./constants";
import { RP_ID } from "~/lib/constants/RP_ID";

interface User {
id: string;
Expand Down
11 changes: 8 additions & 3 deletions apps/signer/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import { PasskeyProvider } from "passkeys-react";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { RouterProvider } from "react-router";

import { WindowContextProvider } from "~/lib/Window.context.tsx";
import "./index.css";
import { RP_ID } from "./lib/constants/RP_ID";
import { userStore } from "./lib/passkeys/userStore";
import { router } from "./router";
import {WindowContextProvider} from "~/lib/Window.context.tsx";

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
createRoot(document.getElementById("app")!).render(
<StrictMode>
<WindowContextProvider>
<WindowContextProvider>
<PasskeyProvider userStore={userStore} RP_ID={RP_ID} extensionId={chrome.runtime.id}>
<RouterProvider router={router} />
</WindowContextProvider>
</PasskeyProvider>
</WindowContextProvider>
</StrictMode>,
);
10 changes: 5 additions & 5 deletions apps/signer/src/pages/home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import * as SimpleWebAuthnBrowser from "@simplewebauthn/browser";
import * as TaquitoUtils from "@taquito/utils";
import { Button, buttonVariants } from "jstz-ui/ui/button";
import { ArrowLeft, ExternalLink } from "lucide-react";
import { parseKey } from "passkeys";
import { usePasskeyWallet } from "passkeys-react";
import { Link, redirect, useLocation, useNavigate, type LoaderFunctionArgs } from "react-router";
import { AccountSelect } from "~/components/AccountSelect";
import { StorageKeys } from "~/lib/constants/storage";
import { parseKey } from "~/lib/passkeys/encode";
import { usePasskeyWallet } from "~/lib/passkeys/usePasskeyWallet";
import * as Vault from "~/lib/vault";
import { useVault, vault } from "~/lib/vaultStore";
import { loadHomeParams } from "./url-params";
Expand Down Expand Up @@ -113,7 +113,7 @@ interface RegisterPasskeyProps {
}

function RegisterPasskey({ onSuccess }: RegisterPasskeyProps) {
const wallet = usePasskeyWallet();
const { wallet } = usePasskeyWallet();

const isPopup = (() => {
const views = chrome.extension.getViews({ type: "popup" });
Expand All @@ -138,15 +138,15 @@ function RegisterPasskey({ onSuccess }: RegisterPasskeyProps) {
async function handleCreatePasskeyWallet() {
let attResp: RegistrationResponseJSON;
try {
const opts = await wallet.current.generateRegistrationOptions();
const opts = await wallet.generateRegistrationOptions();

attResp = await SimpleWebAuthnBrowser.startRegistration({ optionsJSON: opts });
} catch (err) {
console.error(err);
return;
}

const { verified, publicKey } = await wallet.current.verifyRegistration(attResp);
const { verified, publicKey } = await wallet.verifyRegistration(attResp);

if (verified) {
console.info(`Authenticator registered!`);
Expand Down
6 changes: 3 additions & 3 deletions apps/signer/src/pages/wallet/Wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "jstz-ui/ui/tooltip";
import { cn } from "jstz-ui/utils";
import { Eye, EyeOff } from "lucide-react";
import { useQueryStates } from "nuqs";
import { usePasskeyWallet } from "passkeys-react";
import { Suspense, useState } from "react";
import { redirect, useParams, type LoaderFunctionArgs } from "react-router";
import SuperJSON from "superjson";
Expand All @@ -24,7 +25,6 @@ import { useWindowContext } from "~/lib/Window.context.tsx";
import { StorageKeys, type KeyStorage } from "~/lib/constants/storage";
import { toTezString } from "~/lib/currency.utils.ts";
import { createOperation, sign } from "~/lib/jstz";
import { usePasskeyWallet } from "~/lib/passkeys/usePasskeyWallet";
import { useVault } from "~/lib/vaultStore";
import {
RequestEventTypes,
Expand Down Expand Up @@ -160,7 +160,7 @@ function OperationSigningDialog({
}: OperationSigningDialogProps) {
const { close } = useWindowContext();

const wallet = usePasskeyWallet();
const { wallet } = usePasskeyWallet();

async function handleConfirm() {
const operation = await createOperation({
Expand All @@ -182,7 +182,7 @@ function OperationSigningDialog({
signature: passKeySignature,
authenticatorData,
clientDataJSON,
} = await wallet.current.passkeySign(operation);
} = await wallet.passkeySign(operation);

signature = passKeySignature;

Expand Down
2 changes: 1 addition & 1 deletion apps/signer/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@

/* JavaScript Support */
"allowJs": true,
"checkJs": true,
"checkJs": false,
// "maxNodeModuleJsDepth": 1,

/* Emit */
Expand Down
35 changes: 35 additions & 0 deletions packages/passkeys-react/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "passkeys-react",
"version": "0.0.1",
"description": "",
"scripts": {
"build": "tsdown",
"dev": "tsdown --watch"
},
"main": "./dist/index.mjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.mts",
"files": [
"dist"
],
"keywords": [],
"author": "",
"license": "ISC",
"packageManager": "pnpm@10.12.4",
"peerDependencies": {
"react": "^19.0.0"
},
"dependencies": {
"passkeys": "workspace:*"
},
"devDependencies": {
"@types/react": "^19.2.6",
"react": "~19.2.0",
"tsdown": "^0.16.6",
"typescript": "^5.9.3"
},
"exports": {
".": "./dist/index.mjs",
"./package.json": "./package.json"
}
}
28 changes: 28 additions & 0 deletions packages/passkeys-react/src/PasskeyWalletProvider.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { PasskeyWallet } from "passkeys";
import { createContext, useContext, useMemo, useRef } from "react";

/** @import {PropsWithChildren, Context} from "react"; */
/** @import {UserStore} from "passkeys"; */

/** @type {Context<{ wallet: PasskeyWallet }>} */
const PasskeyContext = createContext(/** @type {{ wallet: PasskeyWallet }} */ ({}));

/** @param {PropsWithChildren<{ userStore: UserStore; RP_ID: string; extensionId: string }>} props */
export function PasskeyProvider({ userStore, RP_ID, extensionId, children }) {
const wallet = useRef(
new PasskeyWallet(userStore, RP_ID, [`chrome-extension://${extensionId}`], 60_000),
);

const value = useMemo(
() => ({
wallet: wallet.current,
}),
[],
);

return <PasskeyContext value={value}>{children}</PasskeyContext>;
}

export function usePasskeyWallet() {
return useContext(PasskeyContext);
}
2 changes: 2 additions & 0 deletions packages/passkeys-react/src/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/** Represents the "scope" of websites on which a credential should be usable. */
export const RP_ID = "localhost";
1 change: 1 addition & 0 deletions packages/passkeys-react/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./PasskeyWalletProvider.jsx";
117 changes: 117 additions & 0 deletions packages/passkeys-react/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
{
"$schema": "https://json.schemastore.org/tsconfig.json",
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */

/* Projects */
"incremental": true,
// "composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
// "disableSourceOfProjectReferenceRedirect": true,
// "disableSolutionSearching": true,
// "disableReferencedProjectLoad": true,

/* Language and Environment */
"target": "ES2024",
"lib": ["ES2024", "DOM", "DOM.Iterable"],
"jsx": "react-jsx",
// "experimentalDecorators": true,
// "emitDecoratorMetadata": true,
// "jsxFactory": "",
// "jsxFragmentFactory": "",
// "jsxImportSource": "",
// "reactNamespace": "",
// "noLib": true,
"useDefineForClassFields": true,
"moduleDetection": "force",

/* Modules */
"module": "ES2022",
// "rootDir": "./",
"moduleResolution": "bundler",
"baseUrl": "./",
"paths": {
"~/*": ["src/*"]
},
// "rootDirs": [],
// "typeRoots": [],
// "types": [],
// "allowUmdGlobalAccess": true,
// "moduleSuffixes": [],
"allowImportingTsExtensions": true,
// "rewriteRelativeImportExtensions": true,
// "resolvePackageJsonExports": true,
// "resolvePackageJsonImports": true,
// "customConditions": [],
// "noUncheckedSideEffectImports": true,
"resolveJsonModule": true,
// "allowArbitraryExtensions": true,
// "noResolve": true,

/* JavaScript Support */
"allowJs": true,
"checkJs": true,
// "maxNodeModuleJsDepth": 1,

/* Emit */
"declaration": true,
// "declarationMap": true,
"emitDeclarationOnly": true,
// "sourceMap": true,
// "inlineSourceMap": true,
"noEmit": false,
// "outFile": "./",
"outDir": "./dist",
// "removeComments": true,
// "importHelpers": true,
// "downlevelIteration": true,
// "sourceRoot": "",
// "mapRoot": "",
// "inlineSources": true,
// "emitBOM": true,
// "newLine": "crlf",
// "stripInternal": true,
// "noEmitHelpers": true,
// "noEmitOnError": true,
// "preserveConstEnums": true,
// "declarationDir": "./",

/* Interop Constraints */
"isolatedModules": true,
"verbatimModuleSyntax": true,
// "isolatedDeclarations": true,
// "allowSyntheticDefaultImports": true,
"esModuleInterop": true,
// "preserveSymlinks": true,
"forceConsistentCasingInFileNames": true,

/* Type Checking */
"strict": true,
// "noImplicitAny": true,
// "strictNullChecks": true,
// "strictFunctionTypes": true,
// "strictBindCallApply": true,
// "strictPropertyInitialization": true,
// "strictBuiltinIteratorReturn": true,
// "noImplicitThis": true,
// "useUnknownInCatchVariables": true,
// "alwaysStrict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
// "exactOptionalPropertyTypes": true,
// "noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
// "noImplicitOverride": true,
// "noPropertyAccessFromIndexSignature": true,
// "allowUnusedLabels": true,
// "allowUnreachableCode": true,
"noUncheckedSideEffectImports": true,

/* Completeness */
// "skipDefaultLibCheck": true,
"skipLibCheck": true
},
"include": ["src"],
"exclude": ["node_modules"]
}
12 changes: 12 additions & 0 deletions packages/passkeys-react/tsdown.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig } from "tsdown";

export default defineConfig({
entry: ["./src/index.js"],
outDir: "./dist",
dts: true,
format: "esm",
clean: true,
target: false,
platform: "node",
exports: true,
});
Loading