@biconomy/permission-context-builder
Version:
ERC-7715 Permission Context Builder utility package.
108 lines • 6.04 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getDigest = exports._prepareMockEnableData = exports.encodeEnableSessions = exports.getContext = void 0;
const general_1 = require("./types/general.js");
const viem_1 = require("viem");
const ethers_1 = require("ethers");
const methods_1 = require("./utils/methods.js");
const signers_1 = require("./types/signers.js");
const accounts_1 = require("viem/accounts");
const webauthn_p256_1 = require("webauthn-p256");
const constants_1 = require("./utils/constants.js");
const getContext = async (walletClient, { smartAccountAddress, permissions, expiry, signer }) => {
if (walletClient.chain === undefined) {
throw new Error("Chain is undefined");
}
const chainId = walletClient.chain?.id;
const uint160Address = BigInt(constants_1.smartSessionAddress[chainId]);
const nonceKey = uint160Address << BigInt(32);
let signers = [];
if (signer.type === "keys") {
const publicKeys = signer.data.ids.map((id) => (0, methods_1.decodeDIDToPublicKey)(id));
publicKeys.forEach(key => {
if (key.keyType === methods_1.KEY_TYPES.secp256k1) {
const eoaAddress = (0, accounts_1.publicKeyToAddress)(key.key);
const signer = { type: signers_1.SignerType.EOA, data: eoaAddress };
signers.push(signer);
}
if (key.keyType === methods_1.KEY_TYPES.secp256r1) {
const passkeyPublicKey = (0, webauthn_p256_1.parsePublicKey)(key.key);
const signer = { type: signers_1.SignerType.PASSKEY, data: (0, viem_1.encodeAbiParameters)((0, viem_1.parseAbiParameters)('uint256, uint256'), [passkeyPublicKey.x, passkeyPublicKey.y]) };
signers.push(signer);
}
});
}
const signerId = (0, viem_1.keccak256)((0, viem_1.encodeAbiParameters)((0, viem_1.parseAbiParameters)("address, bytes"), [constants_1.multiKeySignerAddress[chainId], (0, methods_1.encodeSigners)(signers)]));
const actions = permissions.map(permission => ({
actionId: (0, viem_1.keccak256)((0, viem_1.encodePacked)(["address", "bytes4"], [permission.data.target, (0, viem_1.toFunctionSelector)(permission.data.functionName)])),
actionPolicies: [{ policy: constants_1.timeFramePolicyAddress[chainId], initData: (0, viem_1.encodePacked)(["uint128", "uint128"], [BigInt(expiry), BigInt(0)]) }]
}));
const enableData = await (0, exports._prepareMockEnableData)({
smartAccountAddress,
signers,
walletClient,
userOpPolicies: [],
actions,
erc1271Policies: [],
});
const context = (0, viem_1.encodePacked)(['uint192', 'bytes', 'bytes32', 'bytes'], [
nonceKey,
general_1.EXECUTE_SINGLE,
signerId,
(0, exports.encodeEnableSessions)(enableData)
]);
return context;
};
exports.getContext = getContext;
const encodeEnableSessions = (enableData) => {
return ethers_1.ethers.utils.defaultAbiCoder.encode([
'tuple(address isigner, bytes isignerInitData, tuple(address policy, bytes initData)[] userOpPolicies, tuple(address policy, bytes initData)[] erc1271Policies, tuple(bytes32 actionId, tuple(address policy, bytes initData)[] actionPolicies)[] actions, bytes permissionEnableSig)'
], [{
isigner: enableData.isigner,
isignerInitData: enableData.isignerInitData,
userOpPolicies: enableData.userOpPolicies,
erc1271Policies: enableData.erc1271Policies,
actions: enableData.actions.map(action => ({
actionId: action.actionId,
actionPolicies: action.actionPolicies
})),
permissionEnableSig: enableData.permissionEnableSig
}]);
};
exports.encodeEnableSessions = encodeEnableSessions;
const _prepareMockEnableData = async ({ smartAccountAddress, signers, walletClient, userOpPolicies, actions, erc1271Policies, }) => {
if (walletClient.account === undefined) {
throw new Error("Account is undefined");
}
if (walletClient.chain === undefined) {
throw new Error("Chain is undefined");
}
const chainId = walletClient.chain?.id;
let enableData = {
isigner: constants_1.multiKeySignerAddress[chainId],
isignerInitData: (0, viem_1.toBytes)((0, methods_1.encodeSigners)(signers)),
userOpPolicies,
erc1271Policies,
actions,
permissionEnableSig: (0, viem_1.toBytes)("")
};
const digest = await (0, exports.getDigest)(walletClient, smartAccountAddress, enableData, general_1.SmartSessionMode.UNSAFE_ENABLE);
enableData.permissionEnableSig = (0, viem_1.toBytes)((0, viem_1.encodePacked)(['address', 'bytes'], [constants_1.mockValidator[chainId], await walletClient.signMessage({ account: walletClient.account, message: digest })]));
return enableData;
};
exports._prepareMockEnableData = _prepareMockEnableData;
const getDigest = async (walletClient, smartAccountAddress, enableData, mode) => {
if (walletClient.chain === undefined) {
throw new Error("Chain is undefined");
}
const chainId = walletClient.chain?.id;
const abi = [
"function getDigest(address isigner, address account, tuple(address isigner, bytes isignerInitData, tuple(address policy, bytes initData)[] userOpPolicies, tuple(address policy, bytes initData)[] erc1271Policies, tuple(bytes32 actionId, tuple(address policy, bytes initData)[] actionPolicies)[] actions, bytes permissionEnableSig) data, uint8 mode) view returns (bytes32)"
];
const provider = new ethers_1.ethers.providers.JsonRpcProvider(walletClient.chain.rpcUrls.default.http[0]);
const contract = new ethers_1.ethers.Contract(constants_1.smartSessionAddress[chainId], abi, provider);
const digest = await contract.getDigest(constants_1.multiKeySignerAddress[chainId], smartAccountAddress, enableData, mode);
return digest;
};
exports.getDigest = getDigest;
//# sourceMappingURL=contextBuilder.js.map