UNPKG

@abstract-foundation/agw-client

Version:
69 lines 3.8 kB
import { BaseError, fromRlp, hashTypedData, } from 'viem'; import {} from 'viem/accounts'; 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