UNPKG

@abstract-foundation/agw-client

Version:
168 lines 6.05 kB
import { BaseError, concat, encodeFunctionData, fromHex, isHex, keccak256, toBytes, toHex, } from "viem"; import { parseAccount } from "viem/accounts"; import { getCode } from "viem/actions"; import { abstract, abstractTestnet, zksync, zksyncSepoliaTestnet, } from "viem/chains"; import { getAction } from "viem/utils"; import AccountFactoryAbi from "./abis/AccountFactory.js"; import { AGWRegistryAbi } from "./abis/AGWRegistryAbi.js"; import { AGW_REGISTRY_ADDRESS, SMART_ACCOUNT_FACTORY_ADDRESS, } from "./constants.js"; import { isEIP712Transaction } from "./eip712.js"; export const VALID_CHAINS = { [abstractTestnet.id]: abstractTestnet, [abstract.id]: abstract, [zksync.id]: zksync, [zksyncSepoliaTestnet.id]: zksyncSepoliaTestnet, }; export function convertBigIntToString(value) { if (typeof value === "bigint") { return value.toString(); } else if (Array.isArray(value)) { return value.map(convertBigIntToString); } else if (typeof value === "object" && value !== null) { const result = {}; for (const key in value) { result[key] = convertBigIntToString(value[key]); } return result; } return value; } export async function getSmartAccountAddressFromInitialSigner(initialSigner, publicClient) { if (initialSigner === undefined) { throw new Error("Initial signer is required to get smart account address"); } // Generate salt based off address const addressBytes = toBytes(initialSigner); const salt = keccak256(addressBytes); // Get the deployed account address const accountAddress = (await publicClient.readContract({ address: SMART_ACCOUNT_FACTORY_ADDRESS, abi: AccountFactoryAbi, functionName: "getAddressForSalt", args: [salt], })); return accountAddress; } export async function isAGWAccount(publicClient, address) { return await publicClient.readContract({ address: AGW_REGISTRY_ADDRESS, abi: AGWRegistryAbi, functionName: "isAGW", args: [address], }); } export async function isSmartAccountDeployed(client, address) { const bytecode = await getAction(client, getCode, "getCode")({ address: address, }); return bytecode !== undefined; } export function getInitializerCalldata(initialOwnerAddress, validatorAddress, initialCall) { return encodeFunctionData({ abi: [ { name: "initialize", type: "function", inputs: [ { name: "initialK1Owner", type: "address" }, { name: "initialK1Validator", type: "address" }, { name: "modules", type: "bytes[]" }, { name: "initCall", type: "tuple", components: [ { name: "target", type: "address" }, { name: "allowFailure", type: "bool" }, { name: "value", type: "uint256" }, { name: "callData", type: "bytes" }, ], }, ], outputs: [], stateMutability: "nonpayable", }, ], functionName: "initialize", args: [initialOwnerAddress, validatorAddress, [], initialCall], }); } export function transformHexValues(transaction, keys) { if (!transaction) return; for (const key of keys) { if (isHex(transaction[key])) { transaction[key] = fromHex(transaction[key], "bigint"); } } } export function isEip712TypedData(typedData) { return (typedData.message && typedData.domain?.name === "zkSync" && typedData.domain?.version === "2" && isEIP712Transaction(typedData.message)); } export function transformEip712TypedData(typedData) { if (!isEip712TypedData(typedData)) { throw new BaseError("Typed data is not an EIP712 transaction"); } if (typedData.domain?.chainId === undefined) { throw new BaseError("Chain ID is required for EIP712 transaction"); } return { chainId: Number(typedData.domain.chainId), account: parseAccount(toHex(BigInt(typedData.message.from), { size: 20, })), to: toHex(BigInt(typedData.message.to), { size: 20, }), gas: BigInt(typedData.message.gasLimit), gasPerPubdata: BigInt(typedData.message.gasPerPubdataByteLimit), maxFeePerGas: BigInt(typedData.message.maxFeePerGas), maxPriorityFeePerGas: BigInt(typedData.message.maxPriorityFeePerGas), paymaster: typedData.message.paymaster !== "0" ? toHex(BigInt(typedData.message.paymaster), { size: 20, }) : undefined, nonce: typedData.message.nonce, value: BigInt(typedData.message.value), data: typedData.message.data === "0x0" ? "0x" : typedData.message.data, factoryDeps: typedData.message.factoryDeps, paymasterInput: typedData.message.paymasterInput !== "0x" ? typedData.message.paymasterInput : undefined, }; } function encodeCall(call_) { const call = call_; const data = call.abi ? encodeFunctionData({ abi: call.abi, functionName: call.functionName, args: call.args, }) : call.data; return { data: call.dataSuffix && data ? concat([data, call.dataSuffix]) : data, to: call.to, value: call.value, }; } export function encodeCalls(calls) { return calls.map(encodeCall); } export function formatCalls(calls) { return calls.map((call_) => { const call = encodeCall(call_); return { callData: call.data ?? "0x", target: call.to, value: call.value ?? 0n, allowFailure: false, }; }); } //# sourceMappingURL=utils.js.map