@biconomy/ecosystem
Version:
Testing infrastructure for abstractjs with ephemeral networks
184 lines (160 loc) • 4.71 kB
text/typescript
import {
createSmartAccountClient,
grantPermission,
ownableActions,
toNexusAccount,
toOwnableModule,
usePermission
} from "@biconomy/abstractjs-canary"
import {
getSmartSessionsValidator,
getSudoPolicy
} from "@rhinestone/module-sdk"
import { http, type LocalAccount, parseEther } from "viem"
import { privateKeyToAccount } from "viem/accounts"
import { COUNTER_ADDRESS } from "../src/addresses"
import type { Infra } from "../src/toEcosystem"
import { toClients } from "../src/utils"
export const validateModules = async (infra: Infra) => {
await validateOwnables(infra)
await validateSmartSessions(infra)
}
export const validateOwnables = async (infra: Infra) => {
const {
bundler,
network: { rpcUrl, chain, privateKey }
} = infra
const {
walletClients: [_, __, walletClientTwo]
} = await toClients({ rpcUrl, chain, privateKey })
const eoaAccount = privateKeyToAccount(privateKey)
const redeemerAccount = walletClientTwo.account as LocalAccount
const ownablesModule = toOwnableModule({
signer: eoaAccount,
threshold: 1,
owners: [redeemerAccount.address]
})
const nexusAccount = await toNexusAccount({
signer: eoaAccount,
chain,
transport: http(rpcUrl),
validators: [ownablesModule]
})
const { testClient } = await toClients({
rpcUrl,
chain,
privateKey
})
await testClient.setBalance({
address: nexusAccount.address,
value: parseEther("1")
})
const nexusClient = createSmartAccountClient({
account: nexusAccount,
transport: http(bundler.url),
mock: true
})
const ownablesClient = nexusClient.extend(ownableActions())
const { userOpHash, userOp } = await ownablesClient.prepareForMultiSign({
calls: [
{
to: COUNTER_ADDRESS,
data: "0x273ea3e3"
}
]
})
const sig = await redeemerAccount.signMessage({
message: { raw: userOpHash }
})
const multiSigHash = await ownablesClient.multiSign({
...userOp,
signatures: [sig]
})
const receipt = await nexusClient.waitForUserOperationReceipt({
hash: multiSigHash
})
if (!receipt.success) {
throw new Error("Multi sign failed")
}
console.log("ownables module check passed ✅")
}
export const validateSmartSessions = async ({
bundler,
network: { rpcUrl, chain, privateKey }
}: Infra) => {
const eoaAccount = privateKeyToAccount(privateKey)
const {
walletClients: [_, walletClientTwo],
publicClient
} = await toClients({
rpcUrl,
chain,
privateKey
})
const dappAccount = walletClientTwo.account as LocalAccount
const dappAccountAddress = dappAccount.address
const nexusAccount = await toNexusAccount({
signer: eoaAccount,
chain,
transport: http(rpcUrl)
})
const nexusClient = createSmartAccountClient({
account: nexusAccount,
transport: http(bundler.url),
mock: true
})
// Install the smart sessions module on the Nexus client's smart contract account
const hash = await nexusClient.installModule({
module: getSmartSessionsValidator({ useRegistry: false })
})
// Wait for the module installation transaction to be mined and check its success
const { success: installSuccess } =
await nexusClient.waitForUserOperationReceipt({ hash })
if (!installSuccess) {
throw new Error("Smart sessions module installation failed")
}
const sessionDetails = await grantPermission(nexusClient, {
redeemer: dappAccountAddress,
actions: [
{
actionTarget: COUNTER_ADDRESS,
actionTargetSelector: "0x273ea3e3",
actionPolicies: [getSudoPolicy()]
}
]
})
const emulatedAccount = await toNexusAccount({
accountAddress: nexusAccount.address,
signer: dappAccount,
chain,
transport: http(rpcUrl)
})
const emulatedClient = createSmartAccountClient({
account: emulatedAccount,
transport: http(bundler.url),
mock: true
})
const userOpHashOne = await usePermission(emulatedClient, {
sessionDetails,
calls: [{ to: COUNTER_ADDRESS, data: "0x273ea3e3" }],
mode: "ENABLE_AND_USE"
})
const receiptOne = await nexusClient.waitForUserOperationReceipt({
hash: userOpHashOne
})
if (!receiptOne.success) {
throw new Error("Smart sessions module validation failed")
}
const userOpHashTwo = await usePermission(emulatedClient, {
sessionDetails,
calls: [{ to: COUNTER_ADDRESS, data: "0x273ea3e3" }],
mode: "USE"
})
const receiptTwo = await nexusClient.waitForUserOperationReceipt({
hash: userOpHashTwo
})
if (!receiptTwo.success) {
throw new Error("Smart sessions module validation failed")
}
console.log("Smart sessions module check passed ✅")
}