diff --git a/demo/constants.ts b/demo/constants.ts index 475199e..3ad61ab 100644 --- a/demo/constants.ts +++ b/demo/constants.ts @@ -40,31 +40,31 @@ export const openfortContracts: Record = { }, }, optimism: { - paymaster: "0x892c3b4C86803EbfAfBECcE9220F3F49d801Fd8A", - invoiceManager: "0xa3152B80759dfb0cB74009F4bB31b29d01e0e624", - vaultManager: "0x9E6A6E55D9DbE20DF20A90C426724442C8D95481", + paymaster: "0x7A4d8f9321fEbC571CE3233668D87aC647D446D1", + invoiceManager: "0x28FCF5Ebe34e6e1bC236Ed185E6b1f2C481b7D5E", + vaultManager: "0x5C068c5a73B9A92072738DF70Cd100763d167D03", vaults: { "0x2522F4Fc9aF2E1954a3D13f7a5B2683A00a4543A": - "0x8e2048c85Eae2a4443408C284221B33e61906463", + "0x2e13e2daD7e324904580E39F931E2821a29fee15", "0xd926e338e047aF920F59390fF98A3114CCDcab4a": - "0xB35E1f4A65341e6D916902AB0238AC17c59b7430", + "0x12EEC47E20a4d3d9A46A9aDeDA08561B423f3C69", }, }, }; export const paymasters = { base: "0x3cB057Fd3BE519cB50788b8b282732edBF533DC6", - optimism: "0x7926E12044F7f29150F5250B1A335a145298308d", + optimism: "0x7A4d8f9321fEbC571CE3233668D87aC647D446D1", }; export const vaultManagers = { base: "0xEA7aa047c78c5583a2896e18E127A5C2E59C0887", - optimism: "0x9E6A6E55D9DbE20DF20A90C426724442C8D95481", + optimism: "0x5C068c5a73B9A92072738DF70Cd100763d167D03", }; export const invoiceManagers = { base: "0xec721B31c1F003E3D45671D3e6cB83F73AA8f0D6", - optimism: "0xa3152B80759dfb0cB74009F4bB31b29d01e0e624", + optimism: "0x28FCF5Ebe34e6e1bC236Ed185E6b1f2C481b7D5E", }; export const tokenA = { @@ -84,7 +84,7 @@ export const demoNFTs = { export const vaultA = { base: "0x21c14066F5D62Cbec3c42e2c718Ce82E72fCBF87", - optimism: "0x8e2048c85Eae2a4443408C284221B33e61906463", + optimism: "0x2e13e2daD7e324904580E39F931E2821a29fee15", }; export const chainIDs = { diff --git a/demo/index.ts b/demo/index.ts index 452462b..f79dcf5 100644 --- a/demo/index.ts +++ b/demo/index.ts @@ -11,6 +11,7 @@ import { V7SimpleAccountFactoryAddress, openfortContracts, vaultA, + paymasterVerifier, } from "./constants"; import { Address, encodeAbiParameters, getAddress, Hex, parseAbi } from "viem"; import { toSimpleSmartAccount } from "./SimpleSmartAccount"; @@ -21,7 +22,7 @@ import { import util from "util"; import { invoiceManager } from "./Invoice"; -import { getBlockNumber } from "./utils"; +import { getBlockNumber, getBlockTimestamp } from "./utils"; const figlet = require("figlet"); const program = new Command(); @@ -73,8 +74,8 @@ program ) .requiredOption("-t, --token ", "token address") .requiredOption("-a, --amount ", "amount to lock") - .requiredOption("-s, --account-salt ", "account salt") - .action(async ({ token, amount, chain, accountSalt }) => { + .requiredOption("-r, --recipient ", "recipient address") + .action(async ({ token, amount, chain, recipient }) => { if (!isValidChain(chain)) { throw new Error(`Unsupported chain: ${chain}`); } @@ -85,53 +86,28 @@ program const vaultManager = openfortContracts[chain].vaultManager; const vault = openfortContracts[chain].vaults[token]; - const publicClient = publicClients[chain]; - const account = await toSimpleSmartAccount({ - client: publicClient, - owner: ownerAccount, - salt: accountSalt, - entryPoint: { - address: entryPoint07Address, - version: "0.7", - }, - }); - - const accountAddress = await account.getAddress(); - console.log(`Account Address: ${accountAddress}`); - - const bundlerClient = bundlerClients[chain]; - const unsignedUserOp = await bundlerClient.prepareUserOperation({ - account: account, - calls: [ - { - to: vaultManager, - abi: parseAbi(["function deposit(address, address, uint256, bool)"]), - functionName: "deposit", - args: [getAddress(token), getAddress(vault), amount, false], - }, - ], - }); - - const userOpHash = await getUserOperationHash({ - chainId: chainIDs[chain], - entryPointAddress: entryPoint07Address, - entryPointVersion: "0.7", - userOperation: { - ...(unsignedUserOp as any), - sender: await account.getAddress(), - }, - }); - - const signature = await ownerAccount.signMessage({ - message: { raw: userOpHash }, - }); + const walletClient = walletClients[chain]; - const hash = await bundlerClient.sendUserOperation({ - ...unsignedUserOp, - signature, - account: account, + // const approveHash = await walletClient.writeContract({ + // address: token, + // abi: parseAbi(["function approve(address, uint256)"]), + // functionName: "approve", + // args: [vaultManager, amount], + // chain: walletClient.chain, + // account: walletClient.account || null, + // }); + // console.log(`Approve transaction sent: ${approveHash}`); + const hash = await walletClient.writeContract({ + address: vaultManager, + abi: parseAbi([ + "function depositFor(address, address, address, uint256, bool)", + ]), + functionName: "depositFor", + args: [recipient, token, vault, amount, false], + chain: walletClient.chain, + account: walletClient.account || null, }); - console.log(`UserOp sent: ${hash}`); + console.log(`Transaction sent: ${hash}`); }); program @@ -276,6 +252,7 @@ program showHidden: true, depth: null, colors: true, + maxStringLength: null, }), ); }); @@ -324,7 +301,6 @@ program throw new Error(`Unsupported chain: ${chain}`); } const invoiceWithRepayTokens = await invoiceManager.readInvoice(invoiceId); - const walletClient = walletClients[chain]; // we can hard code logIndex since it is the index of the log within the tx @@ -382,4 +358,73 @@ program ); }); +program + .command("register-paymaster") + .description("register paymaster") + .addOption( + new Command() + .createOption("-c, --chain ", "choose chain") + .choices(["base", "optimism"]), + ) + .requiredOption("-s, --account-salt ", "account salt") + .action(async ({ chain, accountSalt }) => { + if (!isValidChain(chain)) { + throw new Error(`Unsupported chain: ${chain}`); + } + const publicClient = publicClients[chain]; + const bundlerClient = bundlerClients[chain]; + + const paymaster = openfortContracts[chain].paymaster; + const account = await toSimpleSmartAccount({ + owner: ownerAccount, + client: publicClient, + salt: accountSalt, + factoryAddress: V7SimpleAccountFactoryAddress, + entryPoint: { + address: entryPoint07Address, + version: "0.7", + }, + }); + const accountAddress = await account.getAddress(); + console.log(`Account Address: ${accountAddress}`); + + const unsignedUserOp = await bundlerClient.prepareUserOperation({ + account: account, + calls: [ + { + to: openfortContracts[chain].invoiceManager, + abi: parseAbi([ + "function registerPaymaster(address, address, uint256)", + ]), + functionName: "registerPaymaster", + args: [ + paymaster, + paymaster, + (await getBlockTimestamp(chain)) + 1000000n, + ], + }, + ], + }); + + const userOpHash = await getUserOperationHash({ + chainId: chainIDs[chain], + entryPointAddress: entryPoint07Address, + entryPointVersion: "0.7", + userOperation: { + ...(unsignedUserOp as any), + sender: await account.getAddress(), + }, + }); + + const signature = await ownerAccount.signMessage({ + message: { raw: userOpHash }, + }); + + const hash = await bundlerClient.sendUserOperation({ + ...unsignedUserOp, + signature, + account: account, + }); + console.log(`UserOp sent: ${hash}`); + }); program.parse(); diff --git a/demo/test/computeHash.test.ts b/demo/test/computeHash.test.ts index 6e2713a..d2e8a4e 100644 --- a/demo/test/computeHash.test.ts +++ b/demo/test/computeHash.test.ts @@ -24,7 +24,7 @@ describe("computeHash", () => { "0x3cB057Fd3BE519cB50788b8b282732edBF533DC6000000000000000000000000000f4240000000000000000000000000000186a000000136f6d400000127b494018e2048c85Eae2a4443408C284221B33e6190646300000000000000000000000000000000000000000000000000000000000001f40000000000000000000000000000000000000000000000000000000000aa37dc01fF3311cd15aB091B00421B23BcB60df02EFD8db7Fb619E988fD324734be51b0475A67b6921D0301f00000000000000000000000000000000000000000000000000000000000001f4469cfb36ee62bf829b1a21065b34fad76f69fc458ef15aef644db820e87880e91e9fc86ebe6112b1ad52f5cf050f63cabf35c42328886d54dba63d7912cbb7461b" as Hex, signature: "0x47140b77612d9ea6bb0d7175ae8c91ea693e4e231fb48ae499c45d0a9309a42735de448da6ce53a4f195607a9afb7a4a21d5ae78c20cff808702d4e892a082ee1b" as Hex, - }; + }; const chain = "base"; const validUntil = 20379348n; const validAfter = 19379348n; diff --git a/demo/viemClients.ts b/demo/viemClients.ts index 492e2ee..fc342a1 100644 --- a/demo/viemClients.ts +++ b/demo/viemClients.ts @@ -43,7 +43,9 @@ export const baseSepoliaBundlerClient = createBundlerClient({ export const optimismBundlerClient = createBundlerClient({ client: optimismPublicClient, paymaster: getPaymasterActions("optimism"), - transport: http(`http://localhost:8080/bundler/${optimismSepolia.id}`), + transport: http( + `https://api.pimlico.io/v2/optimism-sepolia/rpc?apikey=${process.env.PIMLICO_API_KEY}`, + ), }); export const walletClients: Record = {