@biconomy/abstractjs
Version:
SDK for Biconomy integration with support for account abstraction, smart accounts, ERC-4337.
179 lines • 7.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildSessionAction = exports.resolveSessionActions = void 0;
const viem_1 = require("viem");
const buildActionPolicy_1 = require("./buildActionPolicy.js");
const resolveSessionActions = (sessionActions) => {
return sessionActions.flat();
};
exports.resolveSessionActions = resolveSessionActions;
const resolvePoliciesOrApplyUnrestrictedPolicy = (contractAddress, policies) => {
const actionPolicies = policies && policies.length > 0
? policies.map((policy) => {
if ("policy" in policy && "initData" in policy) {
return policy;
}
if (policy.type === "spendingLimits") {
const updatedPolicy = {
...policy,
tokenLimits: policy.tokenLimits.map((tokenLimit) => ({
token: contractAddress,
limit: tokenLimit.limit
}))
};
return (0, buildActionPolicy_1.buildActionPolicy)(updatedPolicy);
}
return (0, buildActionPolicy_1.buildActionPolicy)(policy);
})
: [(0, buildActionPolicy_1.buildActionPolicy)({ type: "sudo" })];
return actionPolicies;
};
const preparePoliciesForERC20Actions = (params, recipientAddressPosition, amountPosition) => {
if (params.policies && params.policies.length > 0) {
return resolvePoliciesOrApplyUnrestrictedPolicy(params.contractAddress, params.policies);
}
let actionsPolicies = [];
const { recipientAddress, usageLimit, amountLimitPerAction, maxAmountLimit, validAfter, validUntil } = params;
const rules = [];
if (recipientAddress && (0, viem_1.isAddress)(recipientAddress)) {
rules.push({
condition: "equal",
calldataOffset: (0, buildActionPolicy_1.calldataArgument)(recipientAddressPosition),
comparisonValue: recipientAddress
});
}
if (maxAmountLimit) {
rules.push({
condition: "lessThanOrEqual",
calldataOffset: (0, buildActionPolicy_1.calldataArgument)(amountPosition),
comparisonValue: amountLimitPerAction || maxAmountLimit,
isLimited: true,
usage: { limit: maxAmountLimit, used: 0n }
});
}
else {
if (amountLimitPerAction) {
if (amountLimitPerAction) {
rules.push({
condition: "lessThanOrEqual",
calldataOffset: (0, buildActionPolicy_1.calldataArgument)(amountPosition),
comparisonValue: amountLimitPerAction
});
}
}
}
if (rules.length > 0) {
const universalPolicy = (0, buildActionPolicy_1.buildActionPolicy)({
type: "universal",
rules
});
actionsPolicies.push(universalPolicy);
}
if (usageLimit) {
actionsPolicies.push((0, buildActionPolicy_1.buildActionPolicy)({
type: "usageLimit",
limit: usageLimit
}));
}
if (validAfter || validUntil) {
const currentTime = Math.floor(Date.now() / 1000);
const oneDayInSecs = 60 * 60 * 24;
actionsPolicies.push((0, buildActionPolicy_1.buildActionPolicy)({
type: "timeframe",
validAfter: validAfter || currentTime,
validUntil: validUntil || (validAfter || currentTime) + oneDayInSecs
}));
}
if (actionsPolicies.length === 0) {
actionsPolicies = [(0, buildActionPolicy_1.buildActionPolicy)({ type: "sudo" })];
}
return actionsPolicies;
};
const buildSessionAction = (parameters) => {
const { type, data } = parameters;
switch (type) {
case "transfer": {
const functionSignature = (0, viem_1.toFunctionSelector)((0, viem_1.getAbiItem)({ abi: viem_1.erc20Abi, name: "transfer" }));
const actionPolicies = preparePoliciesForERC20Actions(data, 1, 2);
return data.chainIds.map((chainId) => {
return {
actions: [
{
actionTarget: data.contractAddress,
actionTargetSelector: functionSignature,
actionPolicies
}
],
chainId
};
});
}
case "transferFrom": {
const functionSignature = (0, viem_1.toFunctionSelector)((0, viem_1.getAbiItem)({ abi: viem_1.erc20Abi, name: "transferFrom" }));
const actionPolicies = preparePoliciesForERC20Actions(data, 2, 3);
return data.chainIds.map((chainId) => {
return {
actions: [
{
actionTarget: data.contractAddress,
actionTargetSelector: functionSignature,
actionPolicies
}
],
chainId
};
});
}
case "approve": {
const functionSignature = (0, viem_1.toFunctionSelector)((0, viem_1.getAbiItem)({ abi: viem_1.erc20Abi, name: "approve" }));
const actionPolicies = preparePoliciesForERC20Actions(data, 1, 2);
return data.chainIds.map((chainId) => {
return {
actions: [
{
actionTarget: data.contractAddress,
actionTargetSelector: functionSignature,
actionPolicies
}
],
chainId
};
});
}
case "custom": {
const actionPolicies = resolvePoliciesOrApplyUnrestrictedPolicy(data.contractAddress, data.policies);
return data.chainIds.map((chainId) => {
return {
actions: [
{
actionTarget: data.contractAddress,
actionTargetSelector: data.functionSignature,
actionPolicies
}
],
chainId
};
});
}
case "batch": {
if (data.actions.length < 2) {
throw new Error("A Batch must contain at least 2 actions");
}
if (data.actions.some(({ chainId }) => Number(chainId) !== Number(data.actions[0].chainId))) {
throw new Error("All actions must be on the same chain");
}
const batchedActions = data.actions.flatMap(({ actions }) => actions);
return [
{
actions: batchedActions,
chainId: data.actions[0].chainId
}
];
}
default: {
throw new Error(`Unknown build action type: ${type}`);
}
}
};
exports.buildSessionAction = buildSessionAction;
//# sourceMappingURL=buildSessionAction.js.map