import { q as decodeAbiParameters } from "../../getCallError-CJA1GhgC.mjs";
import { i as createPublicClient, n as http, o as encodePacked, r as createWalletClient } from "../../_esm-BrzUp3yp.mjs";
import { R as encodeAbiParameters } from "../../chain-dTUyiOxD.mjs";
import { a as mainnet, c as base, i as optimism, l as arbitrum, n as sepolia, o as linea, r as polygon, s as baseSepolia } from "../../chains-DtOuO1lR.mjs";
import { getPolicyStore } from "./policy-store.mjs";
import { CHAIN_NAMES, DELEGATION_CONTRACTS, DELEGATION_EIP712_TYPES, DELEGATION_MANAGER_ABI, EXECUTE_MODE_DEFAULT, SUPPORTED_CHAIN_IDS, getDelegationDomain } from "./delegation-types.mjs";
import { compilePolicyToDelegation, formatCompilationSummary, setCompilationContext } from "./delegation-compiler.mjs";
import { getDelegationStore } from "./delegation-store.mjs";
//#region extensions/crypto/src/services/delegation-service.ts
/**
* Delegation Service — On-chain delegation lifecycle management.
*
* Handles creating, signing, revoking, and checking delegations via the
* MetaMask DelegationManager contract. Uses viem for all chain interaction.
*
* Delegation flow:
*   1. Policy is compiled to caveats (delegation-compiler.ts)
*   2. User signs the delegation (EIP-712 via wallet client)
*   3. Signed delegation is stored in the policy metadata
*   4. Agent can redeem the delegation to execute actions on-chain
*   5. User or agent can revoke via disableDelegation()
*
* Signing paths:
*   - Private key mode: walletClient.signTypedData() (auto-sign)
*   - WalletConnect: walletClient.signTypedData() (prompts user's wallet)
*   - Bankr: bankrSign({ signatureType: 'eth_signTypedData_v4', ... })
*/
const CHAIN_CONFIGS = {
	1: mainnet,
	8453: base,
	42161: arbitrum,
	10: optimism,
	137: polygon,
	59144: linea,
	11155111: sepolia,
	84532: baseSepolia
};
/** Default chain for delegation operations. */
const DEFAULT_CHAIN_ID = 8453;
const clientCache = /* @__PURE__ */ new Map();
function getDelegationPublicClient(chainId) {
	let client = clientCache.get(chainId);
	if (client) return client;
	const chain = CHAIN_CONFIGS[chainId];
	if (!chain) throw new Error(`No chain config for chainId ${chainId}`);
	client = createPublicClient({
		chain,
		transport: http()
	});
	clientCache.set(chainId, client);
	return client;
}
/**
* Get the wallet state from the wallet service.
* Uses dynamic import to avoid circular dependency.
*/
async function getWallet() {
	try {
		const { getWalletState, getWalletClient } = await import("./walletconnect-service.mjs");
		const state = getWalletState();
		if (!state.connected || !state.address) return {
			mode: "none",
			address: null,
			walletClient: null
		};
		let wc = null;
		try {
			wc = getWalletClient();
		} catch {}
		return {
			mode: state.mode,
			address: state.address,
			walletClient: wc
		};
	} catch {
		return {
			mode: "none",
			address: null,
			walletClient: null
		};
	}
}
/**
* Step 1: Compile a policy into a delegation and return it for user review.
* Fetches live ETH price for USD→wei conversion when possible.
* Does NOT sign or store — the user must review and approve first.
*/
async function prepareDelegation(input) {
	const chainId = input.chainId ?? DEFAULT_CHAIN_ID;
	const wallet = await getWallet();
	const zeroAddr = "0x" + "0".repeat(40);
	let delegator = input.delegator ?? zeroAddr;
	let delegate = input.delegate ?? process.env.CLAWNCHER_ADDRESS ?? zeroAddr;
	try {
		const { loadMeta } = await import("./agent-keystore.mjs");
		const meta = loadMeta();
		if (meta) {
			if (delegator === zeroAddr) delegator = meta.smartAccountAddress;
			if (delegate === zeroAddr) delegate = meta.agentAddress;
		}
	} catch {}
	if (delegator === zeroAddr && wallet.address) delegator = wallet.address;
	let ethPriceUsd = 0;
	try {
		const { getEthPrice } = await import("./price-service.mjs");
		ethPriceUsd = await getEthPrice();
	} catch {}
	if (ethPriceUsd <= 0) try {
		const data = await (await fetch("https://api.dexscreener.com/latest/dex/pairs/base/0xd0b53D9277642d899DF5C87A3966A349A798F224")).json();
		const price = parseFloat(data?.pair?.priceUsd ?? data?.pairs?.[0]?.priceUsd ?? "0");
		if (price > 0) ethPriceUsd = price;
	} catch {}
	if (ethPriceUsd > 0) setCompilationContext({ ethPriceUsd });
	else setCompilationContext({});
	const result = compilePolicyToDelegation(input.policy, delegator, delegate, chainId);
	if ("type" in result && result.type === "error") return { error: result.message };
	const compilation = result;
	return {
		compilation,
		summary: formatCompilationSummary(compilation, chainId),
		chainId
	};
}
/**
* Step 2: Sign a delegation using the connected wallet.
*
* Supports three modes:
*   - private_key: auto-sign via viem WalletClient.signTypedData()
*   - walletconnect: prompts user's external wallet for EIP-712 signature
*   - bankr: signs via Bankr Agent API (eth_signTypedData_v4)
*
* Returns the signed delegation or an error string.
*/
async function signDelegation(unsigned, chainId) {
	const wallet = await getWallet();
	try {
		const { loadAgentKey } = await import("./agent-keystore.mjs");
		const agentKey = loadAgentKey();
		if (agentKey) {
			const { privateKeyToAccount } = await import("../../accounts-CgUUF-_i.mjs");
			const { createWalletClient, http } = await import("../../_esm-BrzUp3yp.mjs").then((n) => n.t);
			const { base, baseSepolia } = await import("../../chains-DtOuO1lR.mjs").then((n) => n.t);
			const agentWallet = createWalletClient({
				account: privateKeyToAccount(agentKey),
				chain: chainId === 84532 ? baseSepolia : base,
				transport: http()
			});
			const domain = getDelegationDomain(chainId);
			const sig = await agentWallet.signTypedData({
				domain,
				types: DELEGATION_EIP712_TYPES,
				primaryType: "Delegation",
				message: {
					delegate: unsigned.delegate,
					delegator: unsigned.delegator,
					authority: unsigned.authority,
					caveats: unsigned.caveats.map((c) => ({
						enforcer: c.enforcer,
						terms: c.terms
					})),
					salt: unsigned.salt
				}
			});
			return { signed: {
				...unsigned,
				signature: sig
			} };
		}
	} catch {}
	if (wallet.mode === "none" || !wallet.address) return { error: "No wallet connected and no agent key available. Use /connect, set CLAWNCHER_PRIVATE_KEY, or run /delegator create." };
	const domain = getDelegationDomain(chainId);
	const message = {
		delegate: unsigned.delegate,
		delegator: unsigned.delegator,
		authority: unsigned.authority,
		caveats: unsigned.caveats.map((c) => ({
			enforcer: c.enforcer,
			terms: c.terms
		})),
		salt: unsigned.salt
	};
	try {
		let signature;
		if (wallet.mode === "bankr") {
			const { bankrSign } = await import("./bankr-api.mjs");
			signature = (await bankrSign({
				signatureType: "eth_signTypedData_v4",
				typedData: {
					domain,
					types: DELEGATION_EIP712_TYPES,
					primaryType: "Delegation",
					message
				},
				chainId
			})).signature;
		} else if (wallet.walletClient) signature = await wallet.walletClient.signTypedData({
			domain,
			types: DELEGATION_EIP712_TYPES,
			primaryType: "Delegation",
			message
		});
		else return { error: `Wallet mode "${wallet.mode}" connected but no wallet client available for signing.` };
		return { signed: {
			...unsigned,
			signature
		} };
	} catch (err) {
		return { error: `Signing failed: ${err instanceof Error ? err.message : String(err)}` };
	}
}
/**
* Extract the earliest expiry timestamp from TimestampEnforcer caveats.
* TimestampEnforcer terms are: (uint128 executeAfter, uint128 executeBefore).
* Returns ISO string for the earliest executeBefore, or undefined if none.
*/
function extractExpiryFromCaveats(caveats) {
	const timestampEnforcerAddr = DELEGATION_CONTRACTS.TimestampEnforcer.toLowerCase();
	let earliestExpiry;
	for (const caveat of caveats) {
		if (caveat.enforcer.toLowerCase() !== timestampEnforcerAddr) continue;
		try {
			const executeBefore = decodeAbiParameters([{
				type: "uint128",
				name: "executeAfter"
			}, {
				type: "uint128",
				name: "executeBefore"
			}], caveat.terms)[1];
			if (executeBefore > 0n) {
				if (earliestExpiry === void 0 || executeBefore < earliestExpiry) earliestExpiry = executeBefore;
			}
		} catch {}
	}
	if (earliestExpiry !== void 0) return (/* @__PURE__ */ new Date(Number(earliestExpiry) * 1e3)).toISOString();
}
/**
* Step 3: Store a signed delegation in the policy metadata and get its hash.
* Persists the full SignedDelegation struct to the delegation store (for
* later redemption and on-chain revocation) and lightweight metadata on
* the policy. Attempts to read the delegation hash from DelegationManager.
*/
async function storeDelegation(policy, userId, delegation, chainId, unmappedRules, expiresAt) {
	const policyStore = getPolicyStore();
	getDelegationStore().save(delegation, chainId, policy.id);
	let hash = "0x";
	try {
		hash = await getDelegationPublicClient(chainId).readContract({
			address: DELEGATION_CONTRACTS.DelegationManager,
			abi: DELEGATION_MANAGER_ABI,
			functionName: "getDelegationHash",
			args: [{
				delegate: delegation.delegate,
				delegator: delegation.delegator,
				authority: delegation.authority,
				caveats: delegation.caveats,
				salt: delegation.salt,
				signature: delegation.signature
			}]
		});
	} catch {}
	const info = {
		chainId,
		hash,
		delegationManager: DELEGATION_CONTRACTS.DelegationManager,
		status: "signed",
		delegate: delegation.delegate,
		delegator: delegation.delegator,
		salt: delegation.salt.toString(),
		createdAt: (/* @__PURE__ */ new Date()).toISOString(),
		expiresAt: expiresAt ?? extractExpiryFromCaveats(delegation.caveats),
		unmappedRules: unmappedRules.length > 0 ? unmappedRules : void 0
	};
	policy.delegation = info;
	policy.updatedAt = Date.now();
	policyStore.savePolicy(policy);
	return info;
}
/**
* Create a sub-delegation from a parent delegation.
*
* Sub-delegation narrows the parent's permissions by:
* 1. Setting the `authority` field to the parent delegation's hash
*    (creating a delegation chain)
* 2. Inheriting the parent's caveats (optionally filtered)
* 3. Adding additional restricting caveats (narrowing only — cannot expand)
*
* The parent agent (current delegate) signs the sub-delegation, granting
* the sub-agent a subset of its own permissions.
*
* DelegationManager verifies the full chain during redemption:
*   User → Agent (parent) → Sub-Agent (child)
*
* Important: caveats can only be made MORE restrictive in sub-delegations.
* The on-chain enforcers check both the parent and child caveats during
* redemption. Adding a wider spending limit on the child delegation is
* harmless — the parent's enforcer still caps the total.
*/
async function createSubDelegation(input) {
	const { parentDelegation, parentHash, chainId, subAgentAddress, subAgentPrivateKey, additionalCaveats, caveatFilter } = input;
	let childCaveats = [];
	if (caveatFilter && caveatFilter.length > 0) {
		const filterSet = new Set(caveatFilter.map((a) => a.toLowerCase()));
		childCaveats = parentDelegation.caveats.filter((c) => filterSet.has(c.enforcer.toLowerCase()));
	} else childCaveats = [...parentDelegation.caveats];
	if (additionalCaveats && additionalCaveats.length > 0) childCaveats.push(...additionalCaveats);
	const salt = BigInt("0x" + Array.from({ length: 32 }, () => Math.floor(Math.random() * 256).toString(16).padStart(2, "0")).join(""));
	const unsigned = {
		delegate: subAgentAddress,
		delegator: parentDelegation.delegate,
		authority: parentHash,
		caveats: childCaveats,
		salt
	};
	const domain = getDelegationDomain(chainId);
	const message = {
		delegate: unsigned.delegate,
		delegator: unsigned.delegator,
		authority: unsigned.authority,
		caveats: unsigned.caveats.map((c) => ({
			enforcer: c.enforcer,
			terms: c.terms,
			args: c.args
		})),
		salt: unsigned.salt
	};
	try {
		const agentPrivateKey = process.env.CLAWNCHER_PRIVATE_KEY;
		if (!agentPrivateKey) return { error: "CLAWNCHER_PRIVATE_KEY is required for sub-delegation signing. The agent must have its own private key." };
		const chain = CHAIN_CONFIGS[chainId];
		if (!chain) return { error: `No chain config for chainId ${chainId}` };
		const { privateKeyToAccount } = await import("../../accounts-CgUUF-_i.mjs");
		const signature = await createWalletClient({
			account: privateKeyToAccount(agentPrivateKey),
			chain,
			transport: http()
		}).signTypedData({
			domain,
			types: DELEGATION_EIP712_TYPES,
			primaryType: "Delegation",
			message
		});
		const signed = {
			...unsigned,
			signature
		};
		return {
			delegation: signed,
			chain: [parentDelegation, signed],
			authority: parentHash
		};
	} catch (err) {
		return { error: `Sub-delegation signing failed: ${err instanceof Error ? err.message : String(err)}` };
	}
}
/**
* Revoke a delegation on-chain via DelegationManager.disableDelegation().
* Requires the delegator's wallet to send the transaction.
*/
async function revokeDelegationOnChain(delegation, chainId) {
	const wallet = await getWallet();
	if (wallet.mode === "none" || !wallet.walletClient) return { error: "No wallet connected. Connect a wallet to revoke on-chain." };
	try {
		return { txHash: await wallet.walletClient.writeContract({
			address: DELEGATION_CONTRACTS.DelegationManager,
			abi: DELEGATION_MANAGER_ABI,
			functionName: "disableDelegation",
			args: [{
				delegate: delegation.delegate,
				delegator: delegation.delegator,
				authority: delegation.authority,
				caveats: delegation.caveats,
				salt: delegation.salt,
				signature: delegation.signature
			}],
			chain: CHAIN_CONFIGS[chainId]
		}) };
	} catch (err) {
		return { error: `On-chain revocation failed: ${err instanceof Error ? err.message : String(err)}` };
	}
}
/**
* Check delegation status on-chain.
* Reads the `disabledDelegations` mapping on DelegationManager.
*/
async function checkDelegationStatus(delegationHash, chainId) {
	if (!SUPPORTED_CHAIN_IDS.has(chainId)) throw new Error(`Chain ${chainId} not supported`);
	try {
		return await getDelegationPublicClient(chainId).readContract({
			address: DELEGATION_CONTRACTS.DelegationManager,
			abi: DELEGATION_MANAGER_ABI,
			functionName: "disabledDelegations",
			args: [delegationHash]
		}) ? "revoked" : "active";
	} catch {
		return "signed";
	}
}
/**
* Refresh delegation status for a policy and persist the result.
*/
async function refreshDelegationStatus(policy, userId) {
	if (!policy.delegation) return null;
	if (!policy.delegation.hash || policy.delegation.hash === "0x") return policy.delegation;
	try {
		const status = await checkDelegationStatus(policy.delegation.hash, policy.delegation.chainId);
		policy.delegation.status = status;
		policy.delegation.lastCheckedAt = (/* @__PURE__ */ new Date()).toISOString();
		getPolicyStore().savePolicy(policy);
		return policy.delegation;
	} catch {
		return policy.delegation;
	}
}
/**
* Build an EIP-7715 wallet_requestExecutionPermissions request payload.
* Can be sent to wallets that support the EIP-7715 JSON-RPC method.
*/
function buildEip7715Request(compilation, chainId) {
	const permissions = compilation.mappedRules.map(({ rule, caveats }) => {
		const base = { type: rule.type };
		if (rule.type === "spending_limit" || rule.type === "max_amount") {
			base.type = "native-token-allowance";
			base.data = { allowance: "0x" + caveats[0]?.terms.slice(2, 66) };
		} else if (rule.type === "rate_limit") {
			base.type = "call-limit";
			base.data = { count: rule.maxCalls };
		} else if (rule.type === "allowlist" && rule.field === "addresses") {
			base.type = "allowed-targets";
			base.data = { targets: rule.values };
		}
		return base;
	});
	return {
		method: "wallet_requestExecutionPermissions",
		params: [{
			chainId: `0x${chainId.toString(16)}`,
			permissions,
			expiry: Math.floor(Date.now() / 1e3) + 86400 * 30
		}]
	};
}
/**
* Revoke a delegation by policy ID. Loads the full SignedDelegation from the
* delegation store and calls disableDelegation() on-chain. Also updates the
* policy metadata and cleans up the stored struct.
*
* Returns { txHash } on success, or { error } if wallet/store/chain fails.
* Falls back to local-only revocation if the full struct isn't stored.
*/
async function revokeByPolicy(policy, userId) {
	if (!policy.delegation) return { error: "Policy has no delegation to revoke." };
	const delegationStore = getDelegationStore();
	const stored = delegationStore.load(policy.id);
	if (!stored) {
		policy.delegation.status = "revoked";
		policy.updatedAt = Date.now();
		getPolicyStore().savePolicy(policy);
		return { localOnly: true };
	}
	const result = await revokeDelegationOnChain(stored.delegation, stored.chainId);
	if ("error" in result) {
		policy.delegation.status = "revoked";
		policy.updatedAt = Date.now();
		getPolicyStore().savePolicy(policy);
		return result;
	}
	policy.delegation.status = "revoked";
	policy.delegation.lastCheckedAt = (/* @__PURE__ */ new Date()).toISOString();
	policy.updatedAt = Date.now();
	getPolicyStore().savePolicy(policy);
	delegationStore.delete(policy.id);
	return result;
}
/**
* Encode the permissionContext for redeemDelegations().
*
* The permissionContext is an ABI-encoded delegation chain. Supports both
* single-delegation (root) and multi-delegation (sub-delegation) chains.
*
* For a single root delegation:
*   abi.encode(Delegation[1])
*
* For a sub-delegation chain (User → Agent → Sub-Agent):
*   abi.encode(Delegation[2])  — ordered [parent, child]
*
* The DelegationManager walks the chain, verifying each delegation's
* authority field matches the hash of its parent.
*/
function encodePermissionContext(delegation) {
	return encodePermissionContextChain([delegation]);
}
/**
* Encode a delegation chain as permissionContext.
* Accepts an array of SignedDelegations ordered from root (parent) to leaf (child).
* Internally reverses to leaf-first order as required by the DelegationManager
* (delegations[0].delegate must equal msg.sender).
* For a single root delegation, pass a 1-element array (no reversal needed).
*/
function encodePermissionContextChain(chain) {
	return encodeAbiParameters([{
		type: "tuple[]",
		components: [
			{
				name: "delegate",
				type: "address"
			},
			{
				name: "delegator",
				type: "address"
			},
			{
				name: "authority",
				type: "bytes32"
			},
			{
				name: "caveats",
				type: "tuple[]",
				components: [
					{
						name: "enforcer",
						type: "address"
					},
					{
						name: "terms",
						type: "bytes"
					},
					{
						name: "args",
						type: "bytes"
					}
				]
			},
			{
				name: "salt",
				type: "uint256"
			},
			{
				name: "signature",
				type: "bytes"
			}
		]
	}], [(chain.length > 1 ? [...chain].reverse() : chain).map((d) => ({
		delegate: d.delegate,
		delegator: d.delegator,
		authority: d.authority,
		caveats: d.caveats.map((c) => ({
			enforcer: c.enforcer,
			terms: c.terms,
			args: c.args
		})),
		salt: d.salt,
		signature: d.signature
	}))]);
}
/**
* Encode execution calldata for a single action.
* ERC-7579 single execution: abi.encodePacked(target, value, callData).
*/
function encodeExecution(action) {
	return encodePacked([
		"address",
		"uint256",
		"bytes"
	], [
		action.target,
		action.value,
		action.callData
	]);
}
/** Known DelegationManager error signatures → human-readable messages. */
const DELEGATION_ERROR_SIGS = {
	"0x155ff427": "Signature verification failed (InvalidERC1271Signature). The delegation signature does not match the delegator account.",
	"0xded4370e": "Invalid authority chain (InvalidAuthority). Root delegations must use authority 0xfff...f.",
	"0x8baa579f": "Invalid signature (InvalidSignature). ECDSA recovery did not match the delegator.",
	"0xb5863604": "Invalid delegate (InvalidDelegate). The caller is not the authorized delegate.",
	"0xa9e649e9": "Invalid delegation struct (InvalidDelegation).",
	"0xac241e11": "Empty signature (EmptySignature). The delegation has no signature.",
	"0x0ab29062": "No delegations provided (NoDelegations)."
};
function parseDelegationError(errMsg) {
	for (const [sig, humanMsg] of Object.entries(DELEGATION_ERROR_SIGS)) if (errMsg.includes(sig)) return `Delegation simulation reverted: ${humanMsg}`;
	if (errMsg.includes("revert")) return `Delegation simulation reverted: ${errMsg.slice(0, 200)}`;
	return `Delegation simulation failed: ${errMsg.slice(0, 200)}`;
}
/**
* Redeem a delegation to execute an action on-chain.
*
* This is the core execution path: the agent calls redeemDelegations() on the
* DelegationManager, which verifies all caveats and executes the action through
* the delegator's smart account.
*
* The caller must have the delegate's wallet (agent wallet) connected, since
* the agent is the one redeeming.
*
* @param policyId - The policy whose delegation to redeem
* @param action   - The execution action (target, value, calldata)
* @returns        - Transaction hash or error
*/
async function redeemDelegation(policyId, action) {
	const stored = getDelegationStore().load(policyId);
	if (!stored) return { error: `No signed delegation found for policy "${policyId}". Create and sign a delegation first.` };
	const { delegation, chainId } = stored;
	const policyStore = getPolicyStore();
	const wallet = await getWallet();
	const userId = wallet.address?.toLowerCase() ?? "owner";
	let policies = policyStore.listPolicies(userId);
	if (policies.length === 0 && userId !== "owner") policies = policyStore.listPolicies("owner");
	const policy = policies.find((p) => p.id === policyId);
	if (policy?.delegation?.status === "revoked") return { error: "Delegation has been revoked. Cannot redeem." };
	try {
		const publicClient = getDelegationPublicClient(chainId);
		const revocationCheck = async () => {
			const delegationHash = await publicClient.readContract({
				address: DELEGATION_CONTRACTS.DelegationManager,
				abi: DELEGATION_MANAGER_ABI,
				functionName: "getDelegationHash",
				args: [delegation]
			});
			return publicClient.readContract({
				address: DELEGATION_CONTRACTS.DelegationManager,
				abi: DELEGATION_MANAGER_ABI,
				functionName: "disabledDelegations",
				args: [delegationHash]
			});
		};
		const timeout = new Promise((resolve) => setTimeout(() => resolve(false), 5e3));
		if (await Promise.race([revocationCheck(), timeout])) {
			if (policy?.delegation) policy.delegation.status = "revoked";
			return { error: "Delegation has been revoked on-chain. Cannot redeem." };
		}
	} catch {}
	if (wallet.mode === "none" || !wallet.walletClient) return { error: "No wallet connected. The agent needs a connected wallet to redeem delegations." };
	const permissionContext = encodePermissionContext(delegation);
	const executionCallData = encodeExecution(action);
	const contractCallArgs = {
		address: DELEGATION_CONTRACTS.DelegationManager,
		abi: DELEGATION_MANAGER_ABI,
		functionName: "redeemDelegations",
		args: [
			[permissionContext],
			[EXECUTE_MODE_DEFAULT],
			[executionCallData]
		],
		chain: CHAIN_CONFIGS[chainId]
	};
	try {
		const publicClient = getDelegationPublicClient(chainId);
		if (publicClient) await publicClient.simulateContract({
			...contractCallArgs,
			account: wallet.address
		});
	} catch (simErr) {
		return { error: parseDelegationError(simErr instanceof Error ? simErr.message : String(simErr)) };
	}
	try {
		return {
			txHash: await wallet.walletClient.writeContract(contractCallArgs),
			chainId
		};
	} catch (err) {
		return { error: `Redemption failed: ${err instanceof Error ? err.message : String(err)}` };
	}
}
/**
* Check if a delegation is available for redemption (stored and not revoked).
*/
function canRedeem(policyId) {
	const delegationStore = getDelegationStore();
	if (!delegationStore.has(policyId)) return {
		ready: false,
		reason: "No signed delegation stored for this policy."
	};
	if (!delegationStore.load(policyId)) return {
		ready: false,
		reason: "Delegation file corrupted or unreadable."
	};
	return { ready: true };
}
/**
* Format delegation info as a human-readable status block.
*/
function formatDelegationStatus(meta) {
	const lines = [];
	const statusLabel = {
		unsigned: "UNSIGNED (not yet signed)",
		signed: "SIGNED (ready for on-chain use)",
		active: "ACTIVE (verified on-chain)",
		revoked: "REVOKED (disabled on-chain)",
		expired: "EXPIRED"
	}[meta.status] ?? meta.status;
	lines.push(`  Delegation: [${statusLabel}]`);
	lines.push(`  Chain: ${CHAIN_NAMES[meta.chainId] ?? meta.chainId}`);
	lines.push(`  Delegate: \`${meta.delegate}\``);
	lines.push(`  Delegator: \`${meta.delegator}\``);
	if (meta.hash && meta.hash !== "0x") lines.push(`  Hash: \`${meta.hash}\``);
	if (meta.unmappedRules && meta.unmappedRules.length > 0) lines.push(`  App-layer only: ${meta.unmappedRules.join(", ")}`);
	if (meta.lastCheckedAt) lines.push(`  Last verified: ${meta.lastCheckedAt}`);
	return lines.join("\n");
}
/**
* Get all policies with delegations for a user.
*/
function getDelegatedPolicies(userId) {
	return getPolicyStore().listPolicies(userId).filter((p) => p.delegation != null);
}
/**
* Get supported chains as a formatted string.
*/
function formatSupportedChains() {
	return [...SUPPORTED_CHAIN_IDS].map((id) => `${CHAIN_NAMES[id] ?? id} (${id})`).join(", ");
}
//#endregion
export { buildEip7715Request, canRedeem, checkDelegationStatus, createSubDelegation, encodePermissionContextChain, formatDelegationStatus, formatSupportedChains, getDelegatedPolicies, prepareDelegation, redeemDelegation, refreshDelegationStatus, revokeByPolicy, revokeDelegationOnChain, signDelegation, storeDelegation };

//# sourceMappingURL=delegation-service.mjs.map