diff --git a/.gitignore b/.gitignore index 6db6ff8..28ca62e 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,6 @@ node_modules # cli dist + +# env +.env diff --git a/packages/nextjs/app/page.tsx b/packages/nextjs/app/page.tsx index 6a213ba..46bd109 100644 --- a/packages/nextjs/app/page.tsx +++ b/packages/nextjs/app/page.tsx @@ -1,4 +1,3 @@ -// app/page.tsx "use client"; import Link from "next/link"; @@ -7,6 +6,8 @@ import { useAccount } from "wagmi"; import { BugAntIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline"; import { Address } from "~~/components/scaffold-eth"; +// app/page.tsx + const Home: NextPage = () => { const { address: connectedAddress } = useAccount(); diff --git a/packages/nextjs/app/safe/page.tsx b/packages/nextjs/app/safe/page.tsx index 705577b..8b99b6e 100644 --- a/packages/nextjs/app/safe/page.tsx +++ b/packages/nextjs/app/safe/page.tsx @@ -7,7 +7,7 @@ import { formatUnits } from "viem"; import { baseSepolia } from "viem/chains"; import { useAccount, useBalance, useReadContract } from "wagmi"; import { CheckCircleIcon } from "@heroicons/react/20/solid"; -import { CheckBadgeIcon, ClipboardIcon } from "@heroicons/react/24/outline"; +import { ClipboardIcon } from "@heroicons/react/24/outline"; import { ERC20_ABI } from "~~/lib/ABI"; import { TransactionDetails, getTransactionOnBaseSepoliaByHash } from "~~/lib/blockscout"; import { diff --git a/packages/nextjs/components/Header.tsx b/packages/nextjs/components/Header.tsx index 840386c..d63c1c6 100644 --- a/packages/nextjs/components/Header.tsx +++ b/packages/nextjs/components/Header.tsx @@ -5,7 +5,7 @@ import Image from "next/image"; import Link from "next/link"; import { usePathname } from "next/navigation"; import { DynamicWidget } from "@dynamic-labs/sdk-react-core"; -import { Bars3Icon, BugAntIcon, WalletIcon } from "@heroicons/react/24/outline"; +import { Bars3Icon, BugAntIcon, WalletIcon } from "@heroicons/react/24/outline"; import { FaucetButton } from "~~/components/scaffold-eth"; import { useOutsideClick } from "~~/hooks/scaffold-eth"; diff --git a/packages/nextjs/components/ScaffoldEthAppWithProviders.tsx b/packages/nextjs/components/ScaffoldEthAppWithProviders.tsx index c0b7821..c950e5d 100644 --- a/packages/nextjs/components/ScaffoldEthAppWithProviders.tsx +++ b/packages/nextjs/components/ScaffoldEthAppWithProviders.tsx @@ -59,19 +59,6 @@ export const ScaffoldEthAppWithProviders = ({ children }: { children: React.Reac }, networkId: 2810, }, - { - blockExplorerUrls: ["https://sepolia.basescan.org/"], - chainId: 84532, - name: "Base Sepolia", - rpcUrls: ["https://base-sepolia-rpc.publicnode.com"], - iconUrls: ["https://avatars.githubusercontent.com/u/108554348?v=4"], - nativeCurrency: { - name: "Ethereum", - symbol: "ETH", - decimals: 18, - }, - networkId: 84532, - }, { blockExplorerUrls: ["https://explorer.zircuit.com"], chainId: 48899, diff --git a/packages/nextjs/lib/ABI.ts b/packages/nextjs/lib/ABI.ts index 4f4ed5f..edb8484 100644 --- a/packages/nextjs/lib/ABI.ts +++ b/packages/nextjs/lib/ABI.ts @@ -1,559 +1,559 @@ export const ERC20_ABI = [ - { - constant: true, - inputs: [], - name: "name", - outputs: [ - { - name: "", - type: "string", - }, - ], - payable: false, - stateMutability: "view", - type: "function", - }, - { - constant: false, - inputs: [ - { - name: "_spender", - type: "address", - }, - { - name: "_value", - type: "uint256", - }, - ], - name: "approve", - outputs: [ - { - name: "", - type: "bool", - }, - ], - payable: false, - stateMutability: "nonpayable", - type: "function", - }, - { - constant: true, - inputs: [], - name: "totalSupply", - outputs: [ - { - name: "", - type: "uint256", - }, - ], - payable: false, - stateMutability: "view", - type: "function", - }, - { - constant: false, - inputs: [ - { - name: "_from", - type: "address", - }, - { - name: "_to", - type: "address", - }, - { - name: "_value", - type: "uint256", - }, - ], - name: "transferFrom", - outputs: [ - { - name: "", - type: "bool", - }, - ], - payable: false, - stateMutability: "nonpayable", - type: "function", - }, - { - constant: true, - inputs: [], - name: "decimals", - outputs: [ - { - name: "", - type: "uint8", - }, - ], - payable: false, - stateMutability: "view", - type: "function", - }, - { - constant: true, - inputs: [ - { - name: "_owner", - type: "address", - }, - ], - name: "balanceOf", - outputs: [ - { - name: "balance", - type: "uint256", - }, - ], - payable: false, - stateMutability: "view", - type: "function", - }, - { - constant: true, - inputs: [], - name: "symbol", - outputs: [ - { - name: "", - type: "string", - }, - ], - payable: false, - stateMutability: "view", - type: "function", - }, - { - constant: false, - inputs: [ - { - name: "_to", - type: "address", - }, - { - name: "_value", - type: "uint256", - }, - ], - name: "transfer", - outputs: [ - { - name: "", - type: "bool", - }, - ], - payable: false, - stateMutability: "nonpayable", - type: "function", - }, - { - constant: true, - inputs: [ - { - name: "_owner", - type: "address", - }, - { - name: "_spender", - type: "address", - }, - ], - name: "allowance", - outputs: [ - { - name: "", - type: "uint256", - }, - ], - payable: false, - stateMutability: "view", - type: "function", - }, - { - payable: true, - stateMutability: "payable", - type: "fallback", - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - name: "owner", - type: "address", - }, - { - indexed: true, - name: "spender", - type: "address", - }, - { - indexed: false, - name: "value", - type: "uint256", - }, - ], - name: "Approval", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - name: "from", - type: "address", - }, - { - indexed: true, - name: "to", - type: "address", - }, - { - indexed: false, - name: "value", - type: "uint256", - }, - ], - name: "Transfer", - type: "event", - }, - ]; + { + constant: true, + inputs: [], + name: "name", + outputs: [ + { + name: "", + type: "string", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, + { + constant: false, + inputs: [ + { + name: "_spender", + type: "address", + }, + { + name: "_value", + type: "uint256", + }, + ], + name: "approve", + outputs: [ + { + name: "", + type: "bool", + }, + ], + payable: false, + stateMutability: "nonpayable", + type: "function", + }, + { + constant: true, + inputs: [], + name: "totalSupply", + outputs: [ + { + name: "", + type: "uint256", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, + { + constant: false, + inputs: [ + { + name: "_from", + type: "address", + }, + { + name: "_to", + type: "address", + }, + { + name: "_value", + type: "uint256", + }, + ], + name: "transferFrom", + outputs: [ + { + name: "", + type: "bool", + }, + ], + payable: false, + stateMutability: "nonpayable", + type: "function", + }, + { + constant: true, + inputs: [], + name: "decimals", + outputs: [ + { + name: "", + type: "uint8", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, + { + constant: true, + inputs: [ + { + name: "_owner", + type: "address", + }, + ], + name: "balanceOf", + outputs: [ + { + name: "balance", + type: "uint256", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, + { + constant: true, + inputs: [], + name: "symbol", + outputs: [ + { + name: "", + type: "string", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, + { + constant: false, + inputs: [ + { + name: "_to", + type: "address", + }, + { + name: "_value", + type: "uint256", + }, + ], + name: "transfer", + outputs: [ + { + name: "", + type: "bool", + }, + ], + payable: false, + stateMutability: "nonpayable", + type: "function", + }, + { + constant: true, + inputs: [ + { + name: "_owner", + type: "address", + }, + { + name: "_spender", + type: "address", + }, + ], + name: "allowance", + outputs: [ + { + name: "", + type: "uint256", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, + { + payable: true, + stateMutability: "payable", + type: "fallback", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: "owner", + type: "address", + }, + { + indexed: true, + name: "spender", + type: "address", + }, + { + indexed: false, + name: "value", + type: "uint256", + }, + ], + name: "Approval", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: "from", + type: "address", + }, + { + indexed: true, + name: "to", + type: "address", + }, + { + indexed: false, + name: "value", + type: "uint256", + }, + ], + name: "Transfer", + type: "event", + }, +]; export const ERC20_CROSSCHAIN_TRANSFER_ABI = [ - { - "inputs": [ - { - "internalType": "uint64", - "name": "destinationChainSelector", - "type": "uint64" - } - ], - "name": "DestinationChainNotAllowlisted", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "FailedToWithdrawEth", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidReceiverAddress", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "currentBalance", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "calculatedFees", - "type": "uint256" - } - ], - "name": "NotEnoughBalance", - "type": "error" - }, - { - "inputs": [], - "name": "NothingToWithdraw", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "OwnershipTransferRequested", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "messageId", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint64", - "name": "destinationChainSelector", - "type": "uint64" - }, - { - "indexed": false, - "internalType": "address", - "name": "receiver", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "feeToken", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "fees", - "type": "uint256" - } - ], - "name": "TokensTransferred", - "type": "event" - }, - { - "inputs": [], - "name": "acceptOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "_destinationChainSelector", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "allowed", - "type": "bool" - } - ], - "name": "allowlistDestinationChain", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "_destinationChainSelector", - "type": "uint64" - }, - { - "internalType": "address", - "name": "_receiver", - "type": "address" - }, - { - "internalType": "address", - "name": "_token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "transferTokensPayLINK", - "outputs": [ - { - "internalType": "bytes32", - "name": "messageId", - "type": "bytes32" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "_destinationChainSelector", - "type": "uint64" - }, - { - "internalType": "address", - "name": "_receiver", - "type": "address" - }, - { - "internalType": "address", - "name": "_token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "transferTokensPayNative", - "outputs": [ - { - "internalType": "bytes32", - "name": "messageId", - "type": "bytes32" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_beneficiary", - "type": "address" - } - ], - "name": "withdraw", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_beneficiary", - "type": "address" - }, - { - "internalType": "address", - "name": "_token", - "type": "address" - } - ], - "name": "withdrawToken", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_router", - "type": "address" - }, - { - "internalType": "address", - "name": "_link", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "name": "allowlistedChains", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } -]; \ No newline at end of file + { + inputs: [ + { + internalType: "uint64", + name: "destinationChainSelector", + type: "uint64", + }, + ], + name: "DestinationChainNotAllowlisted", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "owner", + type: "address", + }, + { + internalType: "address", + name: "target", + type: "address", + }, + { + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "FailedToWithdrawEth", + type: "error", + }, + { + inputs: [], + name: "InvalidReceiverAddress", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "currentBalance", + type: "uint256", + }, + { + internalType: "uint256", + name: "calculatedFees", + type: "uint256", + }, + ], + name: "NotEnoughBalance", + type: "error", + }, + { + inputs: [], + name: "NothingToWithdraw", + type: "error", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "to", + type: "address", + }, + ], + name: "OwnershipTransferRequested", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "to", + type: "address", + }, + ], + name: "OwnershipTransferred", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "messageId", + type: "bytes32", + }, + { + indexed: true, + internalType: "uint64", + name: "destinationChainSelector", + type: "uint64", + }, + { + indexed: false, + internalType: "address", + name: "receiver", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "tokenAmount", + type: "uint256", + }, + { + indexed: false, + internalType: "address", + name: "feeToken", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "fees", + type: "uint256", + }, + ], + name: "TokensTransferred", + type: "event", + }, + { + inputs: [], + name: "acceptOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint64", + name: "_destinationChainSelector", + type: "uint64", + }, + { + internalType: "bool", + name: "allowed", + type: "bool", + }, + ], + name: "allowlistDestinationChain", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "to", + type: "address", + }, + ], + name: "transferOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint64", + name: "_destinationChainSelector", + type: "uint64", + }, + { + internalType: "address", + name: "_receiver", + type: "address", + }, + { + internalType: "address", + name: "_token", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + ], + name: "transferTokensPayLINK", + outputs: [ + { + internalType: "bytes32", + name: "messageId", + type: "bytes32", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint64", + name: "_destinationChainSelector", + type: "uint64", + }, + { + internalType: "address", + name: "_receiver", + type: "address", + }, + { + internalType: "address", + name: "_token", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + ], + name: "transferTokensPayNative", + outputs: [ + { + internalType: "bytes32", + name: "messageId", + type: "bytes32", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + stateMutability: "payable", + type: "receive", + }, + { + inputs: [ + { + internalType: "address", + name: "_beneficiary", + type: "address", + }, + ], + name: "withdraw", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_beneficiary", + type: "address", + }, + { + internalType: "address", + name: "_token", + type: "address", + }, + ], + name: "withdrawToken", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_router", + type: "address", + }, + { + internalType: "address", + name: "_link", + type: "address", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [ + { + internalType: "uint64", + name: "", + type: "uint64", + }, + ], + name: "allowlistedChains", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "owner", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, +]; diff --git a/packages/nextjs/lib/permissionless.ts b/packages/nextjs/lib/permissionless.ts index 0e616d2..070304e 100644 --- a/packages/nextjs/lib/permissionless.ts +++ b/packages/nextjs/lib/permissionless.ts @@ -1,101 +1,87 @@ /* eslint-disable prettier/prettier */ -/* eslint-disable @typescript-eslint/no-unused-vars */ -import { Chain, WalletClient, createPublicClient, encodeFunctionData, http } from "viem" -import { - ENTRYPOINT_ADDRESS_V07, - createSmartAccountClient, - walletClientToSmartAccountSigner -} from "permissionless" -import { - signerToSafeSmartAccount -} from "permissionless/accounts" -import { createPimlicoBundlerClient, createPimlicoPaymasterClient } from "permissionless/clients/pimlico" -import { ERC20_ABI, ERC20_CROSSCHAIN_TRANSFER_ABI } from "./ABI" -import { CROSSCHAIN_TRANSFER_CONTRACT_BASE_SEPOLIA } from "./constants" +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { ERC20_ABI, ERC20_CROSSCHAIN_TRANSFER_ABI } from "./ABI"; +import { CROSSCHAIN_TRANSFER_CONTRACT_BASE_SEPOLIA } from "./constants"; +import { ENTRYPOINT_ADDRESS_V07, createSmartAccountClient, walletClientToSmartAccountSigner } from "permissionless"; +import { signerToSafeSmartAccount } from "permissionless/accounts"; +import { createPimlicoBundlerClient, createPimlicoPaymasterClient } from "permissionless/clients/pimlico"; +import { Chain, WalletClient, createPublicClient, encodeFunctionData, http } from "viem"; const transportUrl = (chain: Chain) => - `https://api.pimlico.io/v2/${chain.id}/rpc?apikey=${process.env.NEXT_PUBLIC_PIMLICO_API_KEY}`; + `https://api.pimlico.io/v2/${chain.id}/rpc?apikey=${process.env.NEXT_PUBLIC_PIMLICO_API_KEY}`; - export const publicClient = (chain: Chain) => createPublicClient({ +export const publicClient = (chain: Chain) => + createPublicClient({ transport: http(chain?.rpcUrls.default.http[0].toString()), }); - - export const paymasterClient = (chain: Chain) => - createPimlicoPaymasterClient({ - transport: http(transportUrl(chain)), - entryPoint: ENTRYPOINT_ADDRESS_V07, - }); - - export const pimlicoBundlerClient = (chain: Chain) => - createPimlicoBundlerClient({ - transport: http(transportUrl(chain)), - entryPoint: ENTRYPOINT_ADDRESS_V07, - }); - export const getPimlicoSmartAccountClient = async ( - address: `0x${string}`, - chain: Chain, - walletClient: WalletClient //-> wallet: EmbeddedWalletState - ) => { - const signer = walletClientToSmartAccountSigner(walletClient as any); - - const safeSmartAccountClient = await signerToSafeSmartAccount( - publicClient(chain), - { - entryPoint: ENTRYPOINT_ADDRESS_V07, - signer: signer, - safeVersion: "1.4.1" - } - ); - - return createSmartAccountClient({ - account: safeSmartAccountClient, - entryPoint: ENTRYPOINT_ADDRESS_V07, - chain, - bundlerTransport: http(transportUrl(chain)), - middleware: { - gasPrice: async () => - (await pimlicoBundlerClient(chain).getUserOperationGasPrice()).fast, // use pimlico bundler to get gas prices - sponsorUserOperation: paymasterClient(chain).sponsorUserOperation, // optional - }, - }); - }; - export const approveERC20 = async ( - smartAccountClient: any, - tokenAddress: string, - amount: bigint, - spender: string - ) => { - return await smartAccountClient.writeContract({ - address: tokenAddress, - abi: ERC20_ABI, - functionName: "approve", - args: [spender, amount.toString()], - }); - }; +export const paymasterClient = (chain: Chain) => + createPimlicoPaymasterClient({ + transport: http(transportUrl(chain)), + entryPoint: ENTRYPOINT_ADDRESS_V07, + }); + +export const pimlicoBundlerClient = (chain: Chain) => + createPimlicoBundlerClient({ + transport: http(transportUrl(chain)), + entryPoint: ENTRYPOINT_ADDRESS_V07, + }); + +export const getPimlicoSmartAccountClient = async ( + address: `0x${string}`, + chain: Chain, + walletClient: WalletClient, //-> wallet: EmbeddedWalletState +) => { + const signer = walletClientToSmartAccountSigner(walletClient as any); - export const transferERC20 = async ( - smartAccountClient: any, - tokenAddress: string, - amount: bigint, - toAddress: string - ) => { - return await smartAccountClient.writeContract({ - address: tokenAddress, - abi: ERC20_ABI, - functionName: "transfer", - args: [toAddress, amount.toString()], - }); - }; + const safeSmartAccountClient = await signerToSafeSmartAccount(publicClient(chain), { + entryPoint: ENTRYPOINT_ADDRESS_V07, + signer: signer, + safeVersion: "1.4.1", + }); + + return createSmartAccountClient({ + account: safeSmartAccountClient, + entryPoint: ENTRYPOINT_ADDRESS_V07, + chain, + bundlerTransport: http(transportUrl(chain)), + middleware: { + gasPrice: async () => (await pimlicoBundlerClient(chain).getUserOperationGasPrice()).fast, // use pimlico bundler to get gas prices + sponsorUserOperation: paymasterClient(chain).sponsorUserOperation, // optional + }, + }); +}; +export const approveERC20 = async (smartAccountClient: any, tokenAddress: string, amount: bigint, spender: string) => { + return await smartAccountClient.writeContract({ + address: tokenAddress, + abi: ERC20_ABI, + functionName: "approve", + args: [spender, amount.toString()], + }); +}; + +export const transferERC20 = async ( + smartAccountClient: any, + tokenAddress: string, + amount: bigint, + toAddress: string, +) => { + return await smartAccountClient.writeContract({ + address: tokenAddress, + abi: ERC20_ABI, + functionName: "transfer", + args: [toAddress, amount.toString()], + }); +}; - export const crossChainTransferERC20 = async ( +export const crossChainTransferERC20 = async ( smartAccountClient: any, tokenAddress: string, amount: bigint, - receiver: string + receiver: string, ) => { - const destChainSelector = "3478487238524512106" //https://docs.chain.link/ccip/supported-networks/v1_2_0/testnet#base-sepolia-arbitrum-sepolia + const destChainSelector = "3478487238524512106"; //https://docs.chain.link/ccip/supported-networks/v1_2_0/testnet#base-sepolia-arbitrum-sepolia return await smartAccountClient.writeContract({ address: CROSSCHAIN_TRANSFER_CONTRACT_BASE_SEPOLIA, @@ -103,4 +89,4 @@ const transportUrl = (chain: Chain) => functionName: "transferTokensPayNative", args: [destChainSelector, receiver, tokenAddress, amount.toString()], }); -}; \ No newline at end of file +};