UNPKG

@abstract-foundation/agw-client

Version:
151 lines 6.79 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SessionKeyPolicyStatus = void 0; exports.assertSessionKeyPolicies = assertSessionKeyPolicies; const viem_1 = require("viem"); const chains_1 = require("viem/chains"); const utils_1 = require("viem/utils"); const SessionKeyPolicyRegistry_js_1 = require("./abis/SessionKeyPolicyRegistry.js"); const SessionKeyValidator_js_1 = require("./abis/SessionKeyValidator.js"); const constants_js_1 = require("./constants.js"); const constants_js_2 = require("./exports/constants.js"); const sessions_js_1 = require("./sessions.js"); const restrictedSelectors = new Set([ (0, viem_1.toFunctionSelector)('function setApprovalForAll(address, bool)'), (0, viem_1.toFunctionSelector)('function approve(address, uint256)'), (0, viem_1.toFunctionSelector)('function transfer(address, uint256)'), ]); var SessionKeyPolicyStatus; (function (SessionKeyPolicyStatus) { SessionKeyPolicyStatus[SessionKeyPolicyStatus["Unset"] = 0] = "Unset"; SessionKeyPolicyStatus[SessionKeyPolicyStatus["Allowed"] = 1] = "Allowed"; SessionKeyPolicyStatus[SessionKeyPolicyStatus["Denied"] = 2] = "Denied"; })(SessionKeyPolicyStatus || (exports.SessionKeyPolicyStatus = SessionKeyPolicyStatus = {})); async function assertSessionKeyPolicies(client, chainId, account, transaction) { if (chainId !== chains_1.abstract.id) { return; } const sessions = []; if (transaction.to === account.address && transaction.data?.substring(0, 10) === constants_js_1.BATCH_CALL_SELECTOR) { const batchCall = (0, utils_1.decodeFunctionData)({ abi: constants_js_2.AGWAccountAbi, data: transaction.data, }); if (batchCall.functionName === 'batchCall') { for (const call of batchCall.args[0]) { const subTransaction = { ...transaction, to: call.target, data: call.callData, }; const session = getSessionFromTransaction(account, subTransaction); if (session) { sessions.push(session); } } } } else { const session = getSessionFromTransaction(account, transaction); if (session) { sessions.push(session); } } if (sessions.length === 0) { return; } for (const session of sessions) { const callPolicies = session.callPolicies; const transferPolicies = session.transferPolicies; const checks = []; for (const callPolicy of callPolicies) { if (restrictedSelectors.has(callPolicy.selector)) { const destinationConstraints = callPolicy.constraints.filter((c) => c.index === 0n && c.condition === sessions_js_1.ConstraintCondition.Equal); if (destinationConstraints.length === 0) { throw new viem_1.BaseError(`Unconstrained token approval/transfer destination in call policy. Selector: ${callPolicy.selector}; Target: ${callPolicy.target}`); } for (const constraint of destinationConstraints) { const [target] = (0, utils_1.decodeAbiParameters)([ { type: 'address', }, ], constraint.refValue); checks.push({ target, check: { address: constants_js_1.SESSION_KEY_POLICY_REGISTRY_ADDRESS, abi: SessionKeyPolicyRegistry_js_1.SessionKeyPolicyRegistryAbi, functionName: 'getApprovalTargetStatus', args: [ callPolicy.target, target, ], }, }); } } else { checks.push({ target: callPolicy.target, check: { address: constants_js_1.SESSION_KEY_POLICY_REGISTRY_ADDRESS, abi: SessionKeyPolicyRegistry_js_1.SessionKeyPolicyRegistryAbi, functionName: 'getCallPolicyStatus', args: [callPolicy.target, callPolicy.selector], }, }); } } for (const transferPolicy of transferPolicies) { checks.push({ target: transferPolicy.target, check: { address: constants_js_1.SESSION_KEY_POLICY_REGISTRY_ADDRESS, abi: SessionKeyPolicyRegistry_js_1.SessionKeyPolicyRegistryAbi, functionName: 'getTransferPolicyStatus', args: [transferPolicy.target], }, }); } const results = await client.multicall({ contracts: checks.map((c) => c.check), allowFailure: false, }); for (let i = 0; i < checks.length; i++) { const result = results[i]; const check = checks[i]; if (Number(result) !== SessionKeyPolicyStatus.Allowed) { throw new viem_1.BaseError(`Session key policy violation. Target: ${check?.target}; Status: ${SessionKeyPolicyStatus[Number(result)]}`); } } } } function getSessionFromTransaction(account, transaction) { if (transaction.to === constants_js_1.SESSION_KEY_VALIDATOR_ADDRESS && transaction.data?.substring(0, 10) === constants_js_1.CREATE_SESSION_SELECTOR) { const sessionSpec = (0, utils_1.decodeFunctionData)({ abi: SessionKeyValidator_js_1.SessionKeyValidatorAbi, data: transaction.data, }); if (sessionSpec.functionName === 'createSession') { return sessionSpec.args[0]; } } if (transaction.to === account?.address && transaction.data?.substring(0, 10) === constants_js_1.ADD_MODULE_SELECTOR) { const moduleAndData = (0, utils_1.decodeFunctionData)({ abi: constants_js_2.AGWAccountAbi, data: transaction.data, }); if (moduleAndData.functionName === 'addModule' && moduleAndData.args[0] .toLowerCase() .startsWith(constants_js_1.SESSION_KEY_VALIDATOR_ADDRESS.toLowerCase())) { const sessionData = moduleAndData.args[0].substring(42); return (0, utils_1.decodeAbiParameters)([(0, sessions_js_1.getSessionSpec)()], `0x${sessionData}`)[0]; } } return undefined; } //# sourceMappingURL=sessionValidator.js.map