UNPKG

@abstract-foundation/agw-client

Version:
68 lines 3.77 kB
import { BaseError, fromRlp, hashTypedData, } from "viem"; import { EOA_VALIDATOR_ADDRESS, SESSION_KEY_VALIDATOR_ADDRESS, } from "../constants.js"; import { getAgwTypedSignature } from "../getAgwTypedSignature.js"; import { encodeSessionWithPeriodIds, getPeriodIdsForTransaction, } from "../sessions.js"; import { isEip712TypedData, transformEip712TypedData } from "../utils.js"; import { sendPrivySignTypedData } from "./sendPrivyTransaction.js"; import { signEip712TransactionInternal, signTransaction, } from "./signTransaction.js"; export async function signTypedData(client, signerClient, publicClient, parameters, isPrivyCrossApp = false) { // if the typed data is already a zkSync EIP712 transaction, don't try to transform it // to an AGW typed signature, just pass it through to the signer. if (isEip712TypedData(parameters)) { const transformedTypedData = transformEip712TypedData(parameters); if (transformedTypedData.chainId !== client.chain.id) { throw new BaseError("Chain ID mismatch in AGW typed signature"); } const signedTransaction = await signTransaction(client, signerClient, publicClient, { ...transformedTypedData, chain: client.chain, }, EOA_VALIDATOR_ADDRESS, {}, undefined, isPrivyCrossApp); if (!signedTransaction.startsWith("0x71")) { throw new BaseError("Expected RLP encoded EIP-712 transaction as signature"); } const rlpSignature = `0x${signedTransaction.slice(4)}`; const signatureParts = fromRlp(rlpSignature, "hex"); if (signatureParts.length < 15) { throw new BaseError("Expected RLP encoded EIP-712 transaction with at least 15 fields"); } // This is somewhat not type safe as it assumes that the signature from signTransaction is an // RLP encoded 712 transaction and that the customSignature field is the 15th field in the transaction. // That being said, it's a safe assumption for the current use case. return signatureParts[14]; } else if (isPrivyCrossApp) { return await sendPrivySignTypedData(client, parameters); } return await getAgwTypedSignature({ client, signer: signerClient, messageHash: hashTypedData(parameters), }); } export async function signTypedDataForSession(client, signerClient, publicClient, parameters, session, paymasterHandler) { // if the typed data is already a zkSync EIP712 transaction, don't try to transform it // to an AGW typed signature, just pass it through to the signer. if (!isEip712TypedData(parameters)) { throw new BaseError("Session client can only sign EIP712 transactions as typed data"); } const transactionRequest = transformEip712TypedData(parameters); if (!transactionRequest.to) { throw new BaseError("Transaction must have a to address"); } // Match the expect signature format of the AGW smart account so the result can be // directly used in eth_sendRawTransaction as the customSignature field const validationHookData = { [SESSION_KEY_VALIDATOR_ADDRESS]: encodeSessionWithPeriodIds(session, getPeriodIdsForTransaction({ sessionConfig: session, target: transactionRequest.to, selector: (transactionRequest.data?.slice(0, 10) ?? "0x"), timestamp: BigInt(Math.floor(Date.now() / 1000)), })), }; const { customSignature } = await signEip712TransactionInternal(client, signerClient, publicClient, { chain: client.chain, ...transactionRequest, }, SESSION_KEY_VALIDATOR_ADDRESS, validationHookData, paymasterHandler); return customSignature; } //# sourceMappingURL=signTypedData.js.map