Skip to content
Closed
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
5 changes: 5 additions & 0 deletions .changeset/sharp-comics-sing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"permissionless": patch
---

Dynamically loads ox, thank to @Bvvvp009
1 change: 1 addition & 0 deletions bun.lock
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@vitejs/plugin-react": "^4.2.1",
"@vitest/coverage-v8": "^2.1.5",
"@wagmi/cli": "latest",
"@wagmi/core": "2.17.1",
"async-mutex": "^0.5.0",
"buffer": "^6.0.3",
"bun-types": "^1.0.7",
Expand Down
13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
"viem": "2.28.1",
"vite": "^5.4.10",
"vitest": "^2.1.5",
"wagmi": "^2.15.1"
"wagmi": "^2.15.1",
"@wagmi/core": "2.17.1"
},
"description": "",
"keywords": [],
Expand All @@ -52,13 +53,13 @@
"build:permissionless": "bun run clean:permissionless && bun run build:permissionless:cjs && bun run build:permissionless:esm && bun run build:permissionless:types",
"build:mock-paymaster": "bun run clean:mock-paymaster && bun run build:mock-paymaster:cjs && bun run build:mock-paymaster:esm && bun run build:mock-paymaster:types",
"build:wagmi": "bun run clean:wagmi && bun run build:wagmi:esm && bun run build:wagmi:types",
"build:permissionless:cjs": "tsc --project ./tsconfig/tsconfig.permissionless.cjs.json && tsc-alias -p ./tsconfig/tsconfig.permissionless.cjs.json && printf '{\"type\":\"commonjs\"}' > ./packages/permissionless/_cjs/package.json",
"build:permissionless:esm": "tsc --project ./tsconfig/tsconfig.permissionless.esm.json && tsc-alias -p ./tsconfig/tsconfig.permissionless.esm.json && printf '{\"type\": \"module\",\"sideEffects\":false}' > ./packages/permissionless/_esm/package.json",
"build:permissionless:cjs": "tsc --project ./tsconfig/tsconfig.permissionless.cjs.json && tsc-alias -p ./tsconfig/tsconfig.permissionless.cjs.json && echo {\"type\":\"commonjs\"} > ./packages/permissionless/_cjs/package.json",
"build:permissionless:esm": "tsc --project ./tsconfig/tsconfig.permissionless.esm.json && tsc-alias -p ./tsconfig/tsconfig.permissionless.esm.json && echo {\"type\": \"module\",\"sideEffects\":false} > ./packages/permissionless/_esm/package.json",
"build:permissionless:types": "tsc --project ./tsconfig/tsconfig.permissionless.types.json && tsc-alias -p ./tsconfig/tsconfig.permissionless.types.json",
"build:wagmi:types": "tsc --project ./tsconfig/tsconfig.wagmi.types.json && tsc-alias -p ./tsconfig/tsconfig.wagmi.types.json",
"build:wagmi:esm": "tsc --project ./tsconfig/tsconfig.wagmi.esm.json && tsc-alias -p ./tsconfig/tsconfig.wagmi.esm.json && printf '{\"type\": \"module\",\"sideEffects\":false}' > ./packages/wagmi/_esm/package.json",
"build:mock-paymaster:cjs": "tsc --project ./tsconfig/tsconfig.mock-paymaster.cjs.json && tsc-alias -p ./tsconfig/tsconfig.mock-paymaster.cjs.json && printf '{\"type\":\"commonjs\"}' > ./packages/mock-paymaster/_cjs/package.json",
"build:mock-paymaster:esm": "tsc --project ./tsconfig/tsconfig.mock-paymaster.esm.json && tsc-alias -p ./tsconfig/tsconfig.mock-paymaster.esm.json && printf '{\"type\": \"module\",\"sideEffects\":false}' > ./packages/mock-paymaster/_esm/package.json",
"build:wagmi:esm": "tsc --project ./tsconfig/tsconfig.wagmi.esm.json && tsc-alias -p ./tsconfig/tsconfig.wagmi.esm.json && echo {\"type\": \"module\",\"sideEffects\":false} > ./packages/wagmi/_esm/package.json",
"build:mock-paymaster:cjs": "tsc --project ./tsconfig/tsconfig.mock-paymaster.cjs.json && tsc-alias -p ./tsconfig/tsconfig.mock-paymaster.cjs.json && echo {\"type\":\"commonjs\"} > ./packages/mock-paymaster/_cjs/package.json",
"build:mock-paymaster:esm": "tsc --project ./tsconfig/tsconfig.mock-paymaster.esm.json && tsc-alias -p ./tsconfig/tsconfig.mock-paymaster.esm.json && echo {\"type\": \"module\",\"sideEffects\":false} > ./packages/mock-paymaster/_esm/package.json",
"build:mock-paymaster:types": "tsc --project ./tsconfig/tsconfig.mock-paymaster.types.json && tsc-alias -p ./tsconfig/tsconfig.mock-paymaster.types.json",
"clean": "bun run clean:permissionless && bun run clean:wagmi && bun run clean:mock-paymaster",
"clean:permissionless": "rimraf ./packages/permissionless/_esm ./packages/permissionless/_cjs ./packages/permissionless/_types",
Expand Down
11 changes: 6 additions & 5 deletions packages/permissionless-test/mock-aa-infra/alto/instance.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { resolve } from "node:path"
import { defineInstance, toArgs } from "prool"
import { execa } from "prool/processes"
import type { Hex } from "viem"

export type AltoParameters = {
/**
Expand All @@ -18,7 +19,7 @@ export type AltoParameters = {
/**
* Address of the `BundleBulker` contract.
*/
bundleBulkerAddress?: `0x${string}` | undefined
bundleBulkerAddress?: Hex | undefined
/**
* Set if the bundler bundle user operations automatically or only when calling `debug_bundler_sendBundleNow`.
* @default "auto"
Expand Down Expand Up @@ -53,15 +54,15 @@ export type AltoParameters = {
/**
* EntryPoint contract addresses.
*/
entrypoints: readonly `0x${string}`[]
entrypoints: readonly Hex[]
/**
* Address of the EntryPoint simulations contract.
*/
entrypointSimulationContract?: `0x${string}` | undefined
entrypointSimulationContract?: Hex | undefined
/**
* Private keys of the executor accounts.
*/
executorPrivateKeys?: readonly `0x${string}`[]
executorPrivateKeys?: readonly Hex[]
/**
* Interval to refill the signer balance (seconds).
* @default 1200
Expand Down Expand Up @@ -183,7 +184,7 @@ export type AltoParameters = {
/**
* Address of the `PerOpInflator` contract.
*/
perOpInflatorAddress?: `0x${string}` | undefined
perOpInflatorAddress?: Hex | undefined
/**
* Polling interval for querying for new blocks (ms).
* @default 1000
Expand Down
18 changes: 18 additions & 0 deletions packages/permissionless/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,24 @@ bun install viem permissionless
yarn add viem permissionless
```

### Optional Dependencies

For WebAuthn functionality (passkeys), you'll also need to install the `ox` package:

```bash
npm install ox
```

```bash
bun install ox
```

```bash
yarn add ox
```

**Note**: The `ox` package is optional and only required if you plan to use WebAuthn/passkey features. The library will throw a helpful error message if you try to use WebAuthn functionality without installing `ox`.

## Quick Start

```typescript
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type Address, encodeFunctionData, zeroAddress } from "viem"
import { type Address, type Hex, encodeFunctionData, zeroAddress } from "viem"
import {
EtherspotBootstrapAbi,
EtherspotOnInstallAbi
Expand Down Expand Up @@ -29,7 +29,7 @@ const _makeBootstrapConfig = (module: string, data: string) => {
config.data = encodeFunctionData({
abi: EtherspotOnInstallAbi,
functionName: "onInstall",
args: [data as `0x${string}`]
args: [data as Hex]
})

return config
Expand All @@ -38,13 +38,13 @@ const _makeBootstrapConfig = (module: string, data: string) => {
const makeBootstrapConfig = (module: string, data: string) => {
const config: {
module: string
data: `0x${string}`
data: Hex
}[] = []

const data1 = encodeFunctionData({
abi: EtherspotOnInstallAbi,
functionName: "onInstall",
args: [data as `0x${string}`]
args: [data as Hex]
})

const newConfig = {
Expand Down
12 changes: 7 additions & 5 deletions packages/permissionless/accounts/kernel/toKernelSmartAccount.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Base64, Hex, PublicKey } from "ox"
import {
type Account,
type Address,
type Assign,
type Chain,
type Client,
type Hex,
type JsonRpcAccount,
type LocalAccount,
type OneOf,
Expand Down Expand Up @@ -38,6 +38,7 @@ import { getSenderAddress } from "../../actions/public/getSenderAddress.js"
import { encode7579Calls } from "../../utils/encode7579Calls.js"
import { encodeInstallModule } from "../../utils/encodeInstallModule.js"
import { encodeUninstallModule } from "../../utils/encodeUninstallModule.js"
import { getOxExports } from "../../utils/ox.js"
import { type EthereumProvider, toOwner } from "../../utils/toOwner.js"
import { KernelInitAbi } from "./abi/KernelAccountAbi.js"
import {
Expand Down Expand Up @@ -277,7 +278,7 @@ const getInitializationData = <entryPointVersion extends EntryPointVersion>({
entryPoint: {
version: entryPointVersion
}
validatorData: Hex.Hex
validatorData: Hex
validatorAddress: Address
}) => {
if (entryPointVersion === "0.6") {
Expand Down Expand Up @@ -320,6 +321,7 @@ const getValidatorData = async (owner: WebAuthnAccount | LocalAccount) => {
}

if (isWebAuthnAccount(owner)) {
const { PublicKey, Hex, Base64 } = await getOxExports()
const parsedPublicKey = PublicKey.fromHex(owner.publicKey)
const authenticatorIdHash = keccak256(
Hex.fromBytes(Base64.toBytes(owner.id))
Expand Down Expand Up @@ -374,13 +376,13 @@ const getAccountInitCode = async <entryPointVersion extends EntryPointVersion>({
}: {
kernelVersion: KernelVersion<entryPointVersion>
entryPointVersion: entryPointVersion
validatorData: Hex.Hex
validatorData: Hex
index: bigint
factoryAddress: Address
accountLogicAddress: Address
validatorAddress: Address
useMetaFactory: boolean
}): Promise<Hex.Hex> => {
}): Promise<Hex> => {
// Build the account initialization data
const initializationData = getInitializationData({
entryPoint: { version: entryPointVersion },
Expand Down Expand Up @@ -637,7 +639,7 @@ export async function toKernelSmartAccount<
entryPoint.version === "0.6" || _useMetaFactory === false
? factoryAddress
: metaFactoryAddress,
factoryData: await generateInitCode(_useMetaFactory)
factoryData: (await generateInitCode(_useMetaFactory)) as Hex
}
}

Expand Down
4 changes: 3 additions & 1 deletion packages/permissionless/accounts/kernel/utils/signMessage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Signature } from "ox"
import {
type Hash,
type LocalAccount,
Expand All @@ -8,6 +7,8 @@ import {
hashMessage
} from "viem"
import type { WebAuthnAccount } from "viem/account-abstraction"
import { signMessage as _signMessage } from "viem/actions"
import { getOxExports } from "../../../utils/ox.js"
import { isWebAuthnAccount } from "./isWebAuthnAccount.js"
import {
type WrapMessageHashParams,
Expand Down Expand Up @@ -52,6 +53,7 @@ export async function signMessage({
const { signature: signatureData, webauthn } = await owner.sign({
hash: messageContent as Hash
})
const { Signature } = await getOxExports()
const signature = Signature.fromHex(signatureData)

// encode signature
Expand Down
3 changes: 2 additions & 1 deletion packages/permissionless/accounts/safe/signUserOperation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Signature } from "ox"
import {
type Account,
type Address,
Expand All @@ -17,6 +16,7 @@ import {
} from "viem"
import type { UserOperation, WebAuthnAccount } from "viem/account-abstraction"
import { toOwner } from "../../utils/index.js"
import { getOxExports } from "../../utils/ox.js"
import type { EthereumProvider } from "../../utils/toOwner.js"
import {
EIP712_SAFE_OPERATION_TYPE_V06,
Expand Down Expand Up @@ -84,6 +84,7 @@ export const getWebAuthnSignature = async ({
hash
})

const { Signature } = await getOxExports()
const signature = Signature.fromHex(signatureData)

const match = webauthn.clientDataJSON.match(
Expand Down
7 changes: 4 additions & 3 deletions packages/permissionless/accounts/safe/toSafeSmartAccount.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { PublicKey } from "ox"
import {
type Account,
type Address,
Expand Down Expand Up @@ -48,6 +47,7 @@ import { getAccountNonce } from "../../actions/public/getAccountNonce.js"
import { decode7579Calls } from "../../utils/decode7579Calls.js"
import { encode7579Calls } from "../../utils/encode7579Calls.js"
import { isSmartAccountDeployed } from "../../utils/isSmartAccountDeployed.js"
import { getOxExports } from "../../utils/ox.js"
import { type EthereumProvider, toOwner } from "../../utils/toOwner.js"
import {
concatSignatures,
Expand Down Expand Up @@ -594,8 +594,8 @@ const encodeMultiSend = (
value: bigint
operation: 0 | 1
}[]
): `0x${string}` => {
const data: `0x${string}` = `0x${txs
): Hex => {
const data: Hex = `0x${txs
.map((tx) => encodeInternalTransaction(tx))
.join("")}`

Expand Down Expand Up @@ -874,6 +874,7 @@ const getInitializerCode = async ({
safeWebAuthnSharedSignerAddress &&
safeP256VerifierAddress
) {
const { PublicKey } = await getOxExports()
const parsedPublicKey = PublicKey.fromHex(webAuthnOwner.publicKey)

multiCalls.push({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type Address, type Hex, decodeFunctionData } from "viem"

export const decodeCallData = async (callData: `0x${string}`) => {
export const decodeCallData = async (callData: Hex) => {
try {
const decodedBatch = decodeFunctionData({
abi: [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type Address, type Hex, decodeFunctionData } from "viem"

export const decodeCallData = async (callData: `0x${string}`) => {
export const decodeCallData = async (callData: Hex) => {
try {
const decodedBatch = decodeFunctionData({
abi: [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Address } from "viem"
import type { Address, Hex } from "viem"
import { encodeFunctionData } from "viem"

/**
Expand All @@ -9,7 +9,7 @@ export const getFactoryData = async ({
index,
secp256k1VerificationFacetAddress
}: {
bytes: `0x${string}`
bytes: Hex
index: bigint
secp256k1VerificationFacetAddress: Address
}) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { Base64 } from "ox"
import type { WebAuthnP256 } from "ox"
import {
type Account,
type Chain,
Expand All @@ -8,8 +6,12 @@ import {
toHex
} from "viem"
import type { PasskeyServerRpcSchema } from "../../types/passkeyServer.js"
import { getOxExports } from "../../utils/ox.js"

export type StartAuthenticationReturnType = WebAuthnP256.sign.Options & {
export type StartAuthenticationReturnType = {
challenge: string
rpId: string
userVerification?: string
uuid: string
}

Expand All @@ -27,7 +29,9 @@ export const startAuthentication = async (
})

return {
challenge: toHex(Base64.toBytes(response.challenge)),
challenge: toHex(
(await getOxExports()).Base64.toBytes(response.challenge)
),
rpId: response.rpId,
userVerification: response.userVerification,
uuid: response.uuid
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Base64 } from "ox"
import type { Account, Chain, Client, Transport } from "viem"
import type { CreateWebAuthnCredentialParameters } from "viem/account-abstraction"
import type { PasskeyServerRpcSchema } from "../../types/passkeyServer.js"
import { getOxExports } from "../../utils/ox.js"

const validateAttestation = (attestation: unknown): boolean => {
return (
Expand Down Expand Up @@ -104,6 +104,7 @@ export const startRegistration = async (
throw new Error("Invalid response format from passkey server")
}

const { Base64 } = await getOxExports()
const credentialOptions: StartRegistrationReturnType = {
attestation: response.attestation,
authenticatorSelection: response.authenticatorSelection,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
import { Base64, type WebAuthnP256 } from "ox"
// import { Base64 } from "ox"
import type { Account, Chain, Client, Hex, Transport } from "viem"
import type { PasskeyServerRpcSchema } from "../../types/passkeyServer.js"
import { getOxExports } from "../../utils/ox.js"

export type VerifyAuthenticationParameters = WebAuthnP256.sign.ReturnType & {
export type VerifyAuthenticationParameters = {
raw: {
id: string
rawId: ArrayBuffer
authenticatorAttachment: string
response: {
authenticatorData?: ArrayBuffer
signature?: ArrayBuffer
userHandle?: ArrayBuffer
clientDataJSON: ArrayBuffer
}
getClientExtensionResults: () => Record<string, unknown>
type: string
}
uuid: string
}

Expand All @@ -24,6 +37,7 @@ export const verifyAuthentication = async (
args: VerifyAuthenticationParameters
): Promise<VerifyAuthenticationReturnType> => {
const { raw, uuid } = args
const { Base64 } = await getOxExports()

let responseAuthenticatorData: string

Expand Down
Loading
Loading