Untitled
unknown
plain_text
10 months ago
4.1 kB
8
Indexable
import { Address, createPublicClient, Hex, http, HttpTransport, PublicClient } from "viem"
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"
import { arbitrum, Chain } from "viem/chains"
import { createKernelAccount, CreateKernelAccountReturnType } from "../accounts/index.js"
import { KernelPluginManager, KernelValidator } from "../types/kernel.js"
import { switchChain } from "viem/actions"
export { KernelEIP1193Provider } from "./KernelEIP1193Provider.js"
const privateKey = generatePrivateKey()
const signer = privateKeyToAccount(privateKey)
// Construct a public client
const publicClient = createPublicClient({
// Use your own RPC provider (e.g. Infura/Alchemy).
transport: http(""),
chain: arbitrum,
})
// Construct a validator
const ecdsaValidator = await signerToEcdsaValidator(publicClient, {
signer,
entryPoint,
kernelVersion
})
// Construct a Kernel account
const account = await createKernelAccount(publicClient, {
plugins: {
sudo: ecdsaValidator,
},
entryPoint,
kernelVersion
})
type KernelMultichainParams<TEntryPointVersion extends EntryPointVersion> = {
chains: [Chain, ...Chain[]],
entryPoint: TEntryPointVersion,
kernelVersion: string,
clientFactory: (chain: Chain) => PublicClient<HttpTransport, Chain>,
pluginFactory: (chain: Chain) => KernelPluginManager<TEntryPointVersion>;
}
type ServerIntent = {
openInfos: {
chain: number;
amount: bigint;
address: Address;
calldata: Hex;
}[]
destination: {
chain: number;
address: Address;
calldatas: Hex[];
}
}
type MultichainKernelClient = CreateKernelAccountReturnType<> & {
currentChain: Chain;
switchChain: (chain: Chain) => Promise<void>
handleServerIntent: (intent: ServerIntent) => Promise<boolean>
}
const clientCache = new Map<number, PublicClient<HttpTransport, Chain>>()
const pluginCache = new Map<number, KernelPluginManager<string>>()
const accountCache = new Map<number, CreateKernelAccountReturnType<string>>()
export function createMultichainKernel<TEntryPointVersion extends EntryPointVersion>(
{chains, entryPoint, kernelVersion, clientFactory, pluginFactory}: KernelMultichainParams<TEntryPointVersion>
): MultichainKernelClient {
const getClient = (chain: Chain) => {
if (clientCache.get(chain.id)) {
return clientCache.get(chain.id)
}
const newClient = clientFactory(chain);
clientCache.set(chain.id, newClient)
return newClient;
}
const getPluginFactory = (chain: Chain) => {
if (pluginCache.get(chain.id)) {
return pluginCache.get(chain.id)
}
const newPlugin = pluginFactory(chain);
pluginCache.set(chain.id, newPlugin)
return newPlugin;
}
const getAccount = (chain: Chain) => {
if (accountCache.get(chain.id)) {
return accountCache.get(chain.id)
}
const client = getClient(currentchain);
const plugin = getPluginFactory(currentchain);
return createKernelAccount(client, {
plugins: plugin,
entryPoint,
kernelVersion
});
}
const handleServerIntent = async (intent: ServerIntent) => {
const waitingPromises: Promise<void>[] = [];
for (const open of intent.openInfos) {
const client = await getAccount(open.chain);
const userOpHash = await client.sendUserUserOp({
tx: {
to: open.address,
value: open.amount,
data: open.calldata,
}
})
// user op process + wait for user op
waitingPromises.push(client.waitForUserOp(userOpHash))
}
await Promise.all(waitingPromises);
}
let currentchain = chains[0];
let account = getAccount(currentchain);
return {
...acount,
currentChain: currentchain,
switchChain: (chain: Chain) => {
currentchain = chain;
account = getAccount(chain);
},
}
}
Editor is loading...
Leave a Comment