You can restrict an Access Key so it can only interact with specific contracts and specific functions using CallScope. This prevents a compromised key from being used to call arbitrary functions on other contracts.
Scoping Logic
- Target Scoping: Defines which
address the key is allowed to call. - Selector Scoping: Within a target, you can define
SelectorRules to restrict which function selectors are allowed. - Empty Selector Rules: If
selector_rules is an empty array [], the key is allowed to call any selector on that specific target. - Explicit Selector Rules: If
selector_rules contains entries, the key can only call the listed selectors.
Recipient-Bound Token Calls
For specific token methods, you can further restrict the recipients (the first address argument in the ABI). This is useful for ensuring a key can only transfer tokens to a pre-approved list of addresses.
Supported constrained selectors:
0xa9059cbb (transfer(address,uint256))0x095ea7b3 (approve(address,uint256))0x95777d59 (transferWithMemo(address,uint256,bytes32))
// Example: Allow only 'swap' and 'exactInput' on a specific DEX
CallScope memory dexScope = CallScope({
target: DEX_ADDRESS,
selectorRules: [
SelectorRule({ selector: 0x...swap, recipients: [] }),
SelectorRule({ selector: 0x...exactInput, recipients: [] })
]
});
// Example: Allow 'transfer' ONLY to a specific receiver
CallScope memory tokenScope = CallScope({
target: TOKEN_ADDRESS,
selectorRules: [
SelectorRule({
selector: 0xa9059cbb, // transfer
recipients: [0xReceiverAddress]
})
]
});