diff --git a/bun.lockb b/bun.lockb index 8337e773..7e262a00 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 694a5624..2a9bc3b4 100644 --- a/package.json +++ b/package.json @@ -92,8 +92,5 @@ "simple-git-hooks": { "pre-commit": "bun run format && bun run lint:fix", "commit-msg": "npx --no -- commitlint --edit ${1}" - }, - "dependencies": { - "permissionless": "^0.1.10" } } diff --git a/src/accounts/actions/prepareUserOperationRequest.ts b/src/accounts/actions/prepareUserOperationRequest.ts index c2194e2c..506800fc 100644 --- a/src/accounts/actions/prepareUserOperationRequest.ts +++ b/src/accounts/actions/prepareUserOperationRequest.ts @@ -1,11 +1,10 @@ -import { AccountOrClientNotFoundError, parseAccount } from "permissionless" import type { Chain, Client, Transport } from "viem" import { estimateFeesPerGas } from "viem/actions" import type { Prettify } from "viem/chains" import { estimateUserOperationGas } from "../../bundler/actions/estimateUserOperationGas" import type { StateOverrides } from "../../bundler/utils/types" import { PaymasterMode } from "../../paymaster/utils/types" -import { getAction } from "../utils/helpers" +import { getAction, parseAccount } from "../utils/helpers" import type { ENTRYPOINT_ADDRESS_V06_TYPE, PrepareUserOperationRequestParameters, @@ -27,7 +26,7 @@ async function prepareUserOperationRequestForEntryPointV06< userOperation: partialUserOperation, middleware } = args - if (!account_) throw new AccountOrClientNotFoundError() + if (!account_) throw new Error("No account found") const account = parseAccount( account_ @@ -145,7 +144,7 @@ export async function prepareUserOperationRequest< stateOverrides?: StateOverrides ): Promise { const { account: account_ = client.account } = args - if (!account_) throw new AccountOrClientNotFoundError() + if (!account_) throw new Error("No account found.") return prepareUserOperationRequestForEntryPointV06( client, diff --git a/src/accounts/actions/sendTransaction.ts b/src/accounts/actions/sendTransaction.ts index 96a2d109..84c59a96 100644 --- a/src/accounts/actions/sendTransaction.ts +++ b/src/accounts/actions/sendTransaction.ts @@ -1,4 +1,3 @@ -import { AccountOrClientNotFoundError, parseAccount } from "permissionless" import { type Chain, type Client, @@ -10,7 +9,7 @@ import { import type { Prettify } from "viem/chains" import { waitForUserOperationReceipt } from "../../bundler/actions/waitForUserOperationRceipt" import type { UserOpReceipt } from "../../bundler/utils/types" -import { getAction } from "../utils/helpers" +import { getAction, parseAccount } from "../utils/helpers" import type { Middleware, SmartAccount } from "../utils/types" import { sendUserOperation } from "./sendUserOperation" @@ -88,9 +87,7 @@ export async function sendTransaction< } = args if (!account_) { - throw new AccountOrClientNotFoundError({ - docsPath: "/docs/actions/wallet/sendTransaction" - }) + throw new Error("No account found.") } const account = parseAccount(account_) as SmartAccount diff --git a/src/accounts/actions/sendTransactions.ts b/src/accounts/actions/sendTransactions.ts index f60bd06a..430ed2d0 100644 --- a/src/accounts/actions/sendTransactions.ts +++ b/src/accounts/actions/sendTransactions.ts @@ -1,4 +1,3 @@ -import { AccountOrClientNotFoundError, parseAccount } from "permissionless" import { type Address, type Chain, @@ -11,7 +10,7 @@ import { } from "viem" import type { Prettify } from "viem/chains" import { waitForUserOperationReceipt } from "../../bundler/actions/waitForUserOperationRceipt" -import { getAction } from "../utils/helpers" +import { getAction, parseAccount } from "../utils/helpers" import type { GetAccountParameter, Middleware, @@ -93,9 +92,7 @@ export async function sendTransactions< } = args if (!account_) { - throw new AccountOrClientNotFoundError({ - docsPath: "/docs/actions/wallet/sendTransaction" - }) + throw new Error("No account found.") } const account = parseAccount(account_) as SmartAccount diff --git a/src/accounts/actions/sendUserOperation.ts b/src/accounts/actions/sendUserOperation.ts index cdc42062..caef85a0 100644 --- a/src/accounts/actions/sendUserOperation.ts +++ b/src/accounts/actions/sendUserOperation.ts @@ -1,8 +1,7 @@ -import { AccountOrClientNotFoundError, parseAccount } from "permissionless" import type { Chain, Client, Hash, Transport } from "viem" import type { PartialBy, Prettify } from "viem/chains" import { sendUserOperation as sendUserOperationBundler } from "../../bundler/index" -import { getAction } from "../utils/helpers" +import { getAction, parseAccount } from "../utils/helpers" import type { GetAccountParameter, Middleware, @@ -39,7 +38,7 @@ export async function sendUserOperation< args: Prettify ): Promise { const { account: account_ = client.account } = args - if (!account_) throw new AccountOrClientNotFoundError() + if (!account_) throw new Error("No account found.") const account = parseAccount(account_) as SmartAccount diff --git a/src/accounts/actions/signMessage.ts b/src/accounts/actions/signMessage.ts index cbb3fd2e..67a1a6fb 100644 --- a/src/accounts/actions/signMessage.ts +++ b/src/accounts/actions/signMessage.ts @@ -1,4 +1,3 @@ -import { AccountOrClientNotFoundError, parseAccount } from "permissionless" import type { Chain, Client, @@ -6,6 +5,7 @@ import type { SignMessageReturnType, Transport } from "viem" +import { parseAccount } from "../utils/helpers" import type { SmartAccount } from "../utils/types" /** @@ -64,10 +64,7 @@ export async function signMessage< message }: SignMessageParameters ): Promise { - if (!account_) - throw new AccountOrClientNotFoundError({ - docsPath: "/docs/actions/wallet/signMessage" - }) + if (!account_) throw new Error("No account found.") const account = parseAccount(account_) if (account.type === "local") return account.signMessage({ message }) diff --git a/src/accounts/actions/sygnTypedData.ts b/src/accounts/actions/signTypedData.ts similarity index 96% rename from src/accounts/actions/sygnTypedData.ts rename to src/accounts/actions/signTypedData.ts index cdd118f8..fbc62616 100644 --- a/src/accounts/actions/sygnTypedData.ts +++ b/src/accounts/actions/signTypedData.ts @@ -1,4 +1,3 @@ -import { AccountOrClientNotFoundError, parseAccount } from "permissionless" import { type Chain, type Client, @@ -10,6 +9,7 @@ import { getTypesForEIP712Domain, validateTypedData } from "viem" +import { parseAccount } from "../utils/helpers" import type { SmartAccount } from "../utils/types" /** @@ -126,9 +126,7 @@ export async function signTypedData< }: SignTypedDataParameters ): Promise { if (!account_) { - throw new AccountOrClientNotFoundError({ - docsPath: "/docs/actions/wallet/signMessage" - }) + throw new Error("No account found.") } const account = parseAccount(account_) diff --git a/src/accounts/biconomyV2/signerToSmartAccount.ts b/src/accounts/biconomyV2/signerToSmartAccount.ts index cf3450f2..82962dc1 100644 --- a/src/accounts/biconomyV2/signerToSmartAccount.ts +++ b/src/accounts/biconomyV2/signerToSmartAccount.ts @@ -16,14 +16,13 @@ import { keccak256, parseAbiParameters } from "viem" -import { getChainId, signMessage, signTypedData } from "viem/actions" -import type { Prettify } from "viem/chains" - -import { isSmartAccountDeployed } from "permissionless" import { - SignTransactionNotSupportedBySmartAccount, - type SmartAccountSigner -} from "permissionless/accounts" + getBytecode, + getChainId, + signMessage, + signTypedData +} from "viem/actions" +import type { Prettify } from "viem/chains" import { type BaseValidationModule, @@ -36,7 +35,7 @@ import { toSmartAccount, validateUserOp } from "../utils/helpers.js" -import type { SmartAccount } from "../utils/types.js" +import type { SmartAccount, SmartAccountSigner } from "../utils/types.js" export type BiconomySmartAccount< transport extends Transport = Transport, @@ -131,6 +130,20 @@ const getAccountInitCode = async ({ }) } +export const isSmartAccountDeployed = async ( + client: Client, + address: Address +): Promise => { + const contractCode = await getBytecode(client, { + address: address + }) + + if ((contractCode?.length ?? 0) > 2) { + return true + } + return false +} + const getAccountAddress = async ({ factoryAddress, accountLogicAddress, @@ -227,7 +240,7 @@ export async function signerToSmartAccount< const viemSigner: LocalAccount = { ...signer, signTransaction: (_, __) => { - throw new SignTransactionNotSupportedBySmartAccount() + throw new Error("Sign transaction not supported by smart account.") } } as LocalAccount @@ -285,7 +298,7 @@ export async function signerToSmartAccount< ) }, async signTransaction(_, __) { - throw new SignTransactionNotSupportedBySmartAccount() + throw new Error("Sign transaction not supported by smart account.") }, async signTypedData< const TTypedData extends TypedData | Record, diff --git a/src/accounts/utils/helpers.ts b/src/accounts/utils/helpers.ts index 51f34a54..ba52fabf 100644 --- a/src/accounts/utils/helpers.ts +++ b/src/accounts/utils/helpers.ts @@ -1,5 +1,6 @@ import { type Abi, + type Account, type Address, type Chain, type Client, @@ -9,7 +10,9 @@ import { type Hex, type SignableMessage, type Transport, + type TypedData, type TypedDataDefinition, + type WalletClient, concat, encodeAbiParameters, keccak256, @@ -20,14 +23,14 @@ import * as chains from "viem/chains" import { toAccount } from "viem/accounts" import type { BaseValidationModule } from "../../modules/index.js" -import { isSmartAccountDeployed } from "permissionless" -import { SignTransactionNotSupportedBySmartAccount } from "permissionless/accounts" -import type { ENTRYPOINT_ADDRESS_V06_TYPE } from "permissionless/types/entrypoint.js" - +import { signTypedData } from "viem/actions" +import { isSmartAccountDeployed } from "../biconomyV2/signerToSmartAccount.js" import { ENTRYPOINT_ADDRESS_V06 } from "./constants.js" import type { + ENTRYPOINT_ADDRESS_V06_TYPE, GetUserOperationHashParams, SmartAccount, + SmartAccountSigner, UserOperationStruct } from "./types.js" @@ -162,7 +165,7 @@ export function toSmartAccount< return concat([abiEncodedMessage, MAGIC_BYTES]) }, async signTransaction(_, __) { - throw new SignTransactionNotSupportedBySmartAccount() + throw new Error("Sign transaction not supported by smart account") } }) @@ -313,3 +316,38 @@ export function getAction( } )[actionName]?.(...params) ?? action(client, ...params) } + +export function parseAccount(account: Address | Account): Account { + if (typeof account === "string") return { address: account, type: "json-rpc" } + return account +} + +export function walletClientToSmartAccountSigner< + TChain extends Chain | undefined = Chain | undefined +>( + walletClient: WalletClient +): SmartAccountSigner<"custom", Address> { + return { + address: walletClient.account.address, + type: "local", + source: "custom", + publicKey: walletClient.account.address, + signMessage: async ({ + message + }: { message: SignableMessage }): Promise => { + return walletClient.signMessage({ message }) + }, + async signTypedData< + const TTypedData extends TypedData | Record, + TPrimaryType extends keyof TTypedData | "EIP712Domain" = keyof TTypedData + >(typedData: TypedDataDefinition) { + return signTypedData( + walletClient, + { + account: walletClient.account, + ...typedData + } + ) + } + } +} diff --git a/src/client/decorators/bundler.ts b/src/client/decorators/bundler.ts index f063f220..56cbe8ba 100644 --- a/src/client/decorators/bundler.ts +++ b/src/client/decorators/bundler.ts @@ -33,26 +33,25 @@ export type BundlerActions = { * * Sends user operation to the bundler * - * - Docs: https://docs.pimlico.io/permissionless/reference/bundler-actions/sendUserOperation + * - Docs: https://docs.biconomy.io/... // TODO * * @param args {@link SendUserOperationParameters}. * @returns UserOpHash that you can use to track user operation as {@link Hash}. * * @example * import { createClient } from "viem" - * import { bundlerActions } from "permissionless" + * import { bundlerActions } from "@biconomy/sdk" // TODO * * const bundlerClient = createClient({ * chain: goerli, - * transport: http("https://api.pimlico.io/v2/goerli/rpc?apikey=YOUR_API_KEY_HERE") + * transport: http(bundlerUrl) * }).extend(bundlerActions) * * const userOpHash = await bundlerClient.sendUserOperation({ - * userOperation: signedUserOperation, - * entryPoint: entryPoint + * userOperation: signedUserOperation * }) * - * // Return '0xe9fad2cd67f9ca1d0b7a6513b2a42066784c8df938518da2b51bb8cc9a89ea34' + * Return "0x...hash" */ sendUserOperation: ( args: Prettify> @@ -61,14 +60,14 @@ export type BundlerActions = { * * Estimates preVerificationGas, verificationGasLimit and callGasLimit for user operation * - * - Docs: https://docs.pimlico.io/permissionless/reference/bundler-actions/estimateUserOperationGas + * - Docs: https://docs.biconomy.io/... // TODO * * @param args {@link EstimateUserOperationGasParameters} * @returns preVerificationGas, verificationGasLimit and callGasLimit as {@link EstimateUserOperationGasReturnType} * * @example * import { createClient } from "viem" - * import { bundlerActions } from "permissionless" + * import { bundlerActions } from "@biconomy/sdk" // TODO * * const bundlerClient = createClient({ * chain: goerli, @@ -98,13 +97,13 @@ export type BundlerActions = { * * Returns the supported entrypoints by the bundler service * - * - Docs: https://docs.pimlico.io/permissionless/reference/bundler-actions/supportedEntryPoints + * - Docs: https://docs.biconomy.io/... // TODO * * @returns Supported entryPoints * * @example * import { createClient } from "viem" - * import { bundlerActions } from "permissionless" + * import { bundlerActions } from "@biconomy/sdk" // TODO * * const bundlerClient = createClient({ * chain: goerli, @@ -120,13 +119,13 @@ export type BundlerActions = { * * Returns the supported chain id by the bundler service * - * - Docs: https://docs.pimlico.io/permissionless/reference/bundler-actions/chainId + * - Docs: https://docs.biconomy.io/... // TODO * * @returns Supported chain id * * @example * import { createClient } from "viem" - * import { bundlerActions } from "permissionless" + * import { bundlerActions } from "@biconomy/sdk" // TODO * * const bundlerClient = createClient({ * chain: goerli, @@ -141,14 +140,14 @@ export type BundlerActions = { * * Returns the user operation from userOpHash * - * - Docs: https://docs.pimlico.io/permissionless/reference/bundler-actions/getUserOperationByHash + * - Docs: https://docs.biconomy.io/... // TODO * * @param args {@link GetUserOperationByHash} UserOpHash that was returned by {@link sendUserOperation} * @returns userOperation along with entryPoint, transactionHash, blockHash, blockNumber if found or null * * @example * import { createClient } from "viem" - * import { bundlerActions } from "permissionless" + * import { bundlerActions } from "@biconomy/sdk" // TODO * * const bundlerClient = createClient({ * chain: goerli, @@ -165,14 +164,14 @@ export type BundlerActions = { * * Returns the user operation receipt from userOpHash * - * - Docs: https://docs.pimlico.io/permissionless/reference/bundler-actions/getUserOperationReceipt + * - Docs: https://docs.biconomy.io/... // TODO * * @param args {@link GetUserOperationReceiptParameters} UserOpHash that was returned by {@link sendUserOperation} * @returns user operation receipt {@link GetUserOperationReceiptReturnType} if found or null * * @example * import { createClient } from "viem" - * import { bundlerActions } from "permissionless" + * import { bundlerActions } from "@biconomy/sdk" // TODO * * const bundlerClient = createClient({ * chain: goerli, @@ -189,19 +188,20 @@ export type BundlerActions = { /** * Waits for the User Operation to be included on a [Block](https://viem.sh/docs/glossary/terms.html#block) (one confirmation), and then returns the [User Operation Receipt](https://docs.pimlico.io/permissionless/reference/bundler-actions/getUserOperationReceipt). * - * - Docs: https://docs.pimlico.io/permissionless/reference/bundler-actions/waitForUserOperationReceipt + * - Docs: https://docs.biconomy.io/... // TODO * * @param client - Bundler Client to use * @param parameters - {@link WaitForUserOperationReceiptParameters} * @returns The transaction receipt. {@link GetUserOperationReceiptReturnType} * * @example - * import { createBundlerClient, waitForUserOperationReceipt, http } from 'viem' + * import { waitForUserOperationReceipt, http } from 'viem' + * import { createBundlerClient } from "@biconomy/sdk" // TODO * import { mainnet } from 'viem/chains' * * const bundlerClient = createBundlerClient({ * chain: mainnet, - * transport: http(), + * transport: http(bundlerUrl), * }) * const userOperationReceipt = await bundlerClient.waitForUserOperationReceipt({ * hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', diff --git a/src/client/decorators/smartAccount.ts b/src/client/decorators/smartAccount.ts index a290774d..3496649e 100644 --- a/src/client/decorators/smartAccount.ts +++ b/src/client/decorators/smartAccount.ts @@ -24,7 +24,7 @@ import { sendUserOperation } from "../../accounts/actions/sendUserOperation" import { signMessage } from "../../accounts/actions/signMessage" -import { signTypedData } from "../../accounts/actions/sygnTypedData" +import { signTypedData } from "../../accounts/actions/signTypedData" import type { Middleware, SmartAccount, diff --git a/src/modules/ecdsaOwnershipValidationModule/createECDSAOwnershipModule.ts b/src/modules/ecdsaOwnershipValidationModule/createECDSAOwnershipModule.ts index be813ba8..15ca654b 100644 --- a/src/modules/ecdsaOwnershipValidationModule/createECDSAOwnershipModule.ts +++ b/src/modules/ecdsaOwnershipValidationModule/createECDSAOwnershipModule.ts @@ -3,7 +3,8 @@ import type { Prettify } from "viem/chains" import { DEFAULT_ECDSA_OWNERSHIP_MODULE, - ECDSA_OWNERSHIP_MODULE_ADDRESSES_BY_VERSION + ECDSA_OWNERSHIP_MODULE_ADDRESSES_BY_VERSION, + ENTRYPOINT_ADDRESS_V06 } from "../../accounts/utils/constants.js" import type { SmartAccountSigner } from "../../accounts/utils/types.js" import type { @@ -11,8 +12,6 @@ import type { ECDSAOwnershipValidationModuleConfig } from "../utils/types.js" -import { ENTRYPOINT_ADDRESS_V06 } from "permissionless" - /** * Creates an ECDSA Ownership Module. * @param moduleConfig - The configuration for the module. diff --git a/tests/ep6/account.test.ts b/tests/ep6/account.test.ts index 8033c8d2..72a40511 100644 --- a/tests/ep6/account.test.ts +++ b/tests/ep6/account.test.ts @@ -12,11 +12,13 @@ import { import type { Client, Hex, PublicClient } from "viem" import { privateKeyToAccount } from "viem/accounts" -import { walletClientToSmartAccountSigner } from "permissionless" import { SignTransactionNotSupportedBySmartAccount } from "permissionless/accounts" import type { UserOperationStruct } from "../../src/accounts/index.js" import { DEFAULT_ECDSA_OWNERSHIP_MODULE } from "../../src/accounts/utils/constants.js" -import { validateUserOp } from "../../src/accounts/utils/helpers.js" +import { + validateUserOp, + walletClientToSmartAccountSigner +} from "../../src/accounts/utils/helpers.js" import { createSmartAccountClient, signerToSmartAccount @@ -135,8 +137,6 @@ describe("Biconomy Smart Account V2 EP v6 tests", () => { nftAddress ) - console.warn(smartAccount.address, "Smart account address") - const txHash = await smartAccountClient.sendTransactions({ transactions: [ { diff --git a/tests/ep6/accountSignature.test.ts b/tests/ep6/accountSignature.test.ts index 0fb0f418..e15f53d3 100644 --- a/tests/ep6/accountSignature.test.ts +++ b/tests/ep6/accountSignature.test.ts @@ -2,7 +2,7 @@ import { http, createPublicClient, createWalletClient } from "viem" import { privateKeyToAccount } from "viem/accounts" import { beforeAll, describe, expect, test } from "vitest" -import { walletClientToSmartAccountSigner } from "permissionless" +import { walletClientToSmartAccountSigner } from "../../src/accounts/utils/helpers.js" import { createSmartAccountClient, signerToSmartAccount diff --git a/tests/ep6/modules/ecdsaOwnershipModule.test.ts b/tests/ep6/modules/ecdsaOwnershipModule.test.ts index 00c2bcf5..74edf8ac 100644 --- a/tests/ep6/modules/ecdsaOwnershipModule.test.ts +++ b/tests/ep6/modules/ecdsaOwnershipModule.test.ts @@ -1,6 +1,5 @@ import { beforeAll, describe, expect, test } from "vitest" -import { walletClientToSmartAccountSigner } from "permissionless" import { http, type WalletClient, @@ -10,6 +9,7 @@ import { import type { PublicClient } from "viem" import { privateKeyToAccount } from "viem/accounts" import { DEFAULT_ECDSA_OWNERSHIP_MODULE } from "../../../src/accounts/utils/constants.js" +import { walletClientToSmartAccountSigner } from "../../../src/accounts/utils/helpers.js" import { signerToSmartAccount } from "../../../src/index.js" import { getChainConfig } from "../../utils.js" diff --git a/tests/ep6/paymaster.test.ts b/tests/ep6/paymaster.test.ts index d18fa17e..a457ed74 100644 --- a/tests/ep6/paymaster.test.ts +++ b/tests/ep6/paymaster.test.ts @@ -8,10 +8,12 @@ import { } from "viem" import { describe, expect, it } from "vitest" -import { walletClientToSmartAccountSigner } from "permissionless" import { privateKeyToAccount } from "viem/accounts" import { base, baseSepolia } from "viem/chains" -import { getChain } from "../../src/accounts/utils/helpers.js" +import { + getChain, + walletClientToSmartAccountSigner +} from "../../src/accounts/utils/helpers.js" import { createBundlerClient } from "../../src/bundler/createBundlerClient.js" import { createSmartAccountClient,