Comment on page
Get User Permissions
Once the account is created you may want to ask permissions from it so you can pass permissioned transactions. Here is a guide how to to it with a simple smart contract that we will use for example.
contract BasicContract {
uint256 public value = 0;
function increment() external {
value = value + 1;
}
function add(uint amount) external {
value = value + add;
}
function mulPow(uint mul, uint pow) external {
value = value * mul ** pow;
}
}
To create a permission you will need to know what action you want to perform and in which context. Here is an example of permission for the
increment
function.import {Permission, AllowedCalldata} from '@permissivelabs/client';
const permission = new Permission({
operator: operatorAddress, // the address of the operator
to: basicContractAddress, // the address of the contract we want to interact with
selector: keccak256('increment').slice(0, 10), // the function selector we want to interact with (use interface functions with ethers, this version is for demo only)
allowed_arguments: new AllowedCalldata([]).encode(), // the allowed arguments, because the increment function asks for no arguments we set to []
expiresAtUnix: tomorrow, // the date when the permission will expire
maxUsage: 11, // the number of times your permission will be valid + 1, so in our case 10
})
A permission set is a group of permissions that can be granted to an operator by an user. Here is our example to interact with all the
BasicContract
functions.const permissionSet = new PermissionSet({
title: 'Basic contract permissions',
permissions: [
new Permission({
operator: operatorAddress,
to: basicContractAddress,
selector: keccak256('increment').slice(0, 10),
allowed_arguments: new AllowedCalldata([]).encode(),
expiresAtUnix: tomorrow,
maxUsage: 11,
dataValidation: {
validator: TOKEN_GATED_VALIDATOR,
target: AAVE_TOKEN,
data: `0x00`
}
}),
new Permission({
operator: operatorAddress,
to: basicContractAddress,
selector: keccak256('add(uint)').slice(0, 10),
allowed_arguments: new AllowedCalldata([
AllowedArgument.and([ // this means that the first argument of add must be greather than 10 and lower than 100, so in the interval ]10;100[
AllowedArgument.gt(abi.encode([10], ['uint256'])),
AllowedArgument.lt(abi.encode([100], ['uint256'])),
])
]).encode(),
expiresAtUnix: tomorrow,
maxUsage: 11,
})
new Permission({
operator: operatorAddress,
to: basicContractAddress,
selector: keccak256('mulPow(uint,uint)').slice(0, 10),
allowed_arguments: new AllowedCalldata([
AllowedArgument.and([ // this means that the first argument of mulPow must be greather than 10 and lower than 100, so in the interval ]10;100[
AllowedArgument.gt(abi.encode([10], ['uint256'])),
AllowedArgument.lt(abi.encode([100], ['uint256'])),
]),
AllowedArgument.and([ // this means that the second argument of mulPow must be either 18 or 4
AllowedArgument.eq(abi.encode([18], ['uint256'])),
AllowedArgument.eq(abi.encode([4], ['uint256'])),
])
]).encode(),
expiresAtUnix: tomorrow,
maxUsage: 11,
})
],
})
You can now upload the permission set with
permissionSet.upload()
so it will be displayed on the Permissive frontend.Once you have your permission set you can ask an account to grant them to you. You can do this easily with:
await account.setOperatorPermissions(permSet);
Note: the signer for the owner of the account must be a full signer and not a VoidSigner
This process is composed of 2 steps:
- Computing the permission set merkleRoot
- Signing the permission set with EIP-712
- Submitting the permission set
root
,maxValue
,maxFee
, andsignature
to the account contract
But now you transactions will need to process which requires gas and fee for Permissive. To do this you will have to fund the account by transfering gas tokens to it and optionally depositing gas tokens to the entrypoint so the transaction cost less gas.
import { EntryPoint__factory } from '@permissivelabs/client';
const entrypoint = EntryPoint__factory.connect(
'0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
signer
);
await entrypoint.depositTo(await account.getAddress(), {value: valueYouWantToFund})
Once the permissions are granted you can see them with
allowedPermission
.await account.allowedPermission() // returns the permission set merkle root
Last modified 5mo ago