Skip to content

Commit

Permalink
feat: bundler gas estimates
Browse files Browse the repository at this point in the history
  • Loading branch information
joepegler committed Sep 25, 2024
2 parents cbd2d6f + c22f303 commit bf8a577
Show file tree
Hide file tree
Showing 48 changed files with 1,212 additions and 430 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ jobs:
with:
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
slug: bcnmy/sdk
slug: bcnmy/sdk
2 changes: 1 addition & 1 deletion .github/workflows/playground.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ jobs:
PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
BUNDLER_URL: ${{ secrets.BUNDLER_URL }}
CHAIN_ID: 84532
CI: true
CI: true
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# @biconomy/sdk

## 0.0.0
## 0.0.0
Binary file modified bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
"commit-msg": "npx --no -- commitlint --edit ${1}"
},
"dependencies": {
"@rhinestone/module-sdk": "^0.1.17",
"merkletreejs": "^0.3.11"
}
}
2 changes: 1 addition & 1 deletion scripts/send:userOp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ if ([chain, privateKey, bundlerUrl].every(Boolean) !== true)
const account = privateKeyToAccount(`0x${privateKey}`)
const recipient = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" // vitalik.eth
const nexusClient = await createNexusClient({
holder: account,
signer: account,
chain,
transport: http(),
bundlerTransport: http(bundlerUrl),
Expand Down
2 changes: 1 addition & 1 deletion scripts/viem:bundler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ const publicClient = createPublicClient({

const main = async () => {
const nexusAccount = await toNexusAccount({
holder: account,
signer: account,
chain,
transport: http(),
k1ValidatorAddress,
Expand Down
2 changes: 1 addition & 1 deletion src/sdk/account/toNexusAccount.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ describe("nexus.account", async () => {
})

nexusClient = await createNexusClient({
holder: account,
signer: account,
chain,
transport: http(),
bundlerTransport: http(bundlerUrl)
Expand Down
73 changes: 44 additions & 29 deletions src/sdk/account/toNexusAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,28 +61,28 @@ import {
packUserOp,
typeToString
} from "./utils/Utils"
import { type UnknownHolder, toHolder } from "./utils/toHolder"
import { type UnknownSigner, toSigner } from "./utils/toSigner"

/**
* Parameters for creating a Nexus Smart Account
*/
export type ToNexusSmartAccountParameters = Prettify<
{
/** The blockchain network */
chain: Chain
/** The transport configuration */
transport: ClientConfig["transport"]
/** The holder account or address */
holder: UnknownHolder
/** Optional index for the account */
index?: bigint | undefined
/** Optional active validation module */
activeModule?: BaseValidationModule
/** Optional factory address */
factoryAddress?: Address
/** Optional K1 validator address */
k1ValidatorAddress?: Address
} & Pick<
export type ToNexusSmartAccountParameters = {
/** The blockchain network */
chain: Chain
/** The transport configuration */
transport: ClientConfig["transport"]
/** The signer account or address */
signer: UnknownSigner
/** Optional index for the account */
index?: bigint | undefined
/** Optional active validation module */
activeValidationModule?: BaseValidationModule
/** Optional factory address */
factoryAddress?: Address
/** Optional K1 validator address */
k1ValidatorAddress?: Address
} & Prettify<
Pick<
ClientConfig<Transport, Chain, Account, RpcSchema>,
| "account"
| "cacheTime"
Expand Down Expand Up @@ -114,6 +114,8 @@ export type NexusSmartAccountImplementation = SmartAccountImplementation<
encodeExecute: (call: Call) => Promise<Hex>
encodeExecuteBatch: (calls: readonly Call[]) => Promise<Hex>
getUserOpHash: (userOp: Partial<UserOperationStruct>) => Promise<Hex>
setActiveValidationModule: (validationModule: BaseValidationModule) => void
getActiveValidationModule: () => BaseValidationModule
factoryData: Hex
factoryAddress: Address
}
Expand All @@ -133,7 +135,7 @@ export type NexusSmartAccountImplementation = SmartAccountImplementation<
* const account = await toNexusAccount({
* chain: mainnet,
* transport: http(),
* holder: '0x...',
* signer: '0x...',
* })
*/
export const toNexusAccount = async (
Expand All @@ -142,19 +144,19 @@ export const toNexusAccount = async (
const {
chain,
transport,
holder: holder_,
signer: _signer,
index = 0n,
activeModule,
activeValidationModule,
factoryAddress = contracts.k1ValidatorFactory.address,
k1ValidatorAddress = contracts.k1Validator.address,
key = "nexus account",
name = "Nexus Account"
} = parameters

const holder = await toHolder({ holder: holder_ })
const signer = await toSigner({ signer: _signer })

const masterClient = createWalletClient({
account: holder,
account: signer,
chain,
transport,
key,
Expand All @@ -179,16 +181,16 @@ export const toNexusAccount = async (
args: [signerAddress, index, [], 0]
})

const defaultedActiveModule =
activeModule ??
let defaultedActiveModule =
activeValidationModule ??
new K1ValidatorModule(
{
address: k1ValidatorAddress,
type: "validator",
context: signerAddress,
data: signerAddress,
additionalContext: "0x"
},
holder
signer
)

let _accountAddress: Address
Expand All @@ -206,7 +208,7 @@ export const toNexusAccount = async (
functionName: "computeAccountAddress",
args: [signerAddress, index, [], 0]
})) as Address
} catch (e) {
} catch (e: any) {
if (e.shortMessage?.includes(ERROR_MESSAGES.MISSING_ACCOUNT_CONTRACT)) {
throw new Error(ERROR_MESSAGES.ACCOUNT_NOT_DEPLOYED)
}
Expand Down Expand Up @@ -358,6 +360,17 @@ export const toNexusAccount = async (
}
}

/**
* @description Changes the active module for the account
* @param newModule - The new module to set as active
* @returns void
*/
const setActiveValidationModule = (
validationModule: BaseValidationModule
): void => {
defaultedActiveModule = validationModule
}

/**
* @description Signs a message
* @param params - The parameters for signing
Expand All @@ -368,7 +381,7 @@ export const toNexusAccount = async (
message
}: { message: SignableMessage }): Promise<Hex> => {
const tempSignature = await defaultedActiveModule
.getHolder()
.getSigner()
.signMessage({ message })

const signature = encodePacked(
Expand Down Expand Up @@ -525,6 +538,8 @@ export const toNexusAccount = async (
encodeExecute,
encodeExecuteBatch,
getUserOpHash,
setActiveValidationModule,
getActiveValidationModule: () => defaultedActiveModule,
factoryData,
factoryAddress
}
Expand Down
7 changes: 2 additions & 5 deletions src/sdk/account/utils/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,5 @@ export const getAccountDomainStructFields = async (
keccak256(encodePacked(["uint256[]"], [extensions]))
])
}

export const isTesting =
process.env.TEST === "true"
? "pimlico_getUserOperationGasPrice"
: "biconomy_getGasFeeValues"
export const playgroundTrue = process.env.RUN_PLAYGROUND === "true"
export const shouldUsePimlico = process.env.TEST === "true" && !playgroundTrue
2 changes: 1 addition & 1 deletion src/sdk/account/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ export * from "./Utils.js"
export * from "./Constants.js"
export * from "./getChain.js"
export * from "./Logger.js"
export * from "./toHolder.js"
export * from "./toSigner.js"
86 changes: 86 additions & 0 deletions src/sdk/account/utils/toSigner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import {
type Account,
type Address,
type Chain,
type EIP1193Provider,
type EIP1193RequestFn,
type EIP1474Methods,
type LocalAccount,
type OneOf,
type Transport,
type WalletClient,
createWalletClient,
custom
} from "viem"
import { toAccount } from "viem/accounts"

import { signTypedData } from "viem/actions"
import { getAction } from "viem/utils"

export type Signer = LocalAccount
export type UnknownSigner = OneOf<
| EIP1193Provider
| WalletClient<Transport, Chain | undefined, Account>
| LocalAccount
| Account
>
export async function toSigner({
signer,
address
}: {
signer: UnknownSigner
address?: Address
}): Promise<LocalAccount> {
if ("type" in signer && signer.type === "local") {
return signer as LocalAccount
}

let walletClient:
| WalletClient<Transport, Chain | undefined, Account>
| undefined = undefined

if ("request" in signer) {
if (!address) {
try {
;[address] = await (signer.request as EIP1193RequestFn<EIP1474Methods>)(
{
method: "eth_requestAccounts"
}
)
} catch {
;[address] = await (signer.request as EIP1193RequestFn<EIP1474Methods>)(
{
method: "eth_accounts"
}
)
}
}
if (!address) throw new Error("address required")

walletClient = createWalletClient({
account: address,
transport: custom(signer as EIP1193Provider)
})
}

if (!walletClient) {
walletClient = signer as WalletClient<Transport, Chain | undefined, Account>
}

return toAccount({
address: walletClient.account.address,
async signMessage({ message }) {
return walletClient.signMessage({ message })
},
async signTypedData(typedData) {
return getAction(
walletClient,
signTypedData,
"signTypedData"
)(typedData as any)
},
async signTransaction(_) {
throw new Error("Not supported")
}
})
}
2 changes: 1 addition & 1 deletion src/sdk/clients/createBicoBundlerClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe("bico.bundler", async () => {
testClient = toTestClient(chain, getTestAccount(5))

nexusAccount = await toNexusAccount({
holder: account,
signer: account,
chain,
transport: http()
})
Expand Down
8 changes: 1 addition & 7 deletions src/sdk/clients/createBicoBundlerClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,7 @@ type BicoBundlerClientConfig = Omit<BundlerClientConfig, "transport"> &
*
* const bundlerClient = createBicoBundlerClient({ chain: mainnet });
*/
export const createBicoBundlerClient = <
transport extends Transport = Transport,
chain extends Chain | undefined = Chain | undefined,
account extends SmartAccount | undefined = SmartAccount | undefined,
client extends Client | undefined = Client | undefined,
rpcSchema extends RpcSchema | undefined = undefined
>(
export const createBicoBundlerClient = (
parameters: BicoBundlerClientConfig
): BicoBundlerClient => {
if (
Expand Down
Loading

0 comments on commit bf8a577

Please sign in to comment.