Package Exports
- @permissivelabs/client
- @permissivelabs/client/lib/es5/index.js
- @permissivelabs/client/lib/es6/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@permissivelabs/client) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Permissive SDK
Permissive is an authorization framework built with Account Abstraction (ERC-4337). It allows services to request specific permissions from users. Once a service has been granted the required permissions, it can perform allowed actions on behalf of the user in the form of UserOperations.
Install
npm
npm install @permissivelabs/sdk ethers
pnpm
pnpm add @permissivelabs/sdk ethers
yarn
yarn add @permissivelabs/sdk ethers
Typescript support
npm install -D @types/@permissivelabs/sdk
Note
One operator can only have one permission set per account.
Get started
Create account
You must create a Permissive account directly from the UI or calling the contract with your address for both arguments:
createAccount(address owner, uint256 salt)
.
Once the account is created you can initiaite the account with:
import { Account } from '@permissivelabs/sdk';
const account = new Account({
operator, //
chainId,
owner, // EOA owner of the Account
});
Both operator and owner are ethers.Signer
you can create ethers.VoidSigner
for the address you don't have the private key / control.
Set permissions
You can set the permissions for the account with the method setOperatorPermissions
.
const permissionSet = new PermissionSet({
title,
maxFee, // in wei
maxValue, // in wei
permissions: [
new Permission({
operator,
to, // contract / account to interact with
selector, // bytes4 function selector
paymaster, // can be address(0)
expiresAtUnix, // seconds, must be 0 if expiresAtBlock is > 0
expiresAtBlock, // must be 0 if expiresAtUnix > 0
}),
],
});
const tx = await account.setOperatorPermissions(permissionSet);
Use the account
To use the account you must firstly build the transaction and initialize a bundler with the Bundler
class with a valid ERC-4337 bundler RPC url (e.g Stackup)
You can call the Account.call()
method.
import { Bundler } from '@permissivelabs/sdk';
const bundler = new Bundler(rpc_url);
const tx = await account.call(
bundler,
to, // contract / account to interact with
value, // in wei
calldata, // prefixed with selector
paymasterAndData // see https://eips.ethereum.org/EIPS/eip-4337
);
Upload permission set to Permissive
You can upload a permission set to Permissive so it is accessible to the authorization page. And can be imported by other operators (e.g https://app.permissive.dev)
permissionSet.upload();
// get the authorization page URL
permissionSet.getUrl();
Use new allowance calldata feature (not deployed yet)
The allowance calldata introduces a new standard to create conditional and permissioned calldata. In the actual state of Permissive the operator can set any values as it wants to arguments of contract functions the account interacts with. This is a problem for token allowances, capped values etc...
You can get more information about the allowance calldata here.
The calldata is a succession of allowance arguments which are condition by the following operators *, =, >, <, |
.
Where *
means any value and |
means or so any value provided in the allowance.
import { AllowedCalldata, AllowedArgument } from '@permissivelabs/sdk';
const calldata = new AllowanceCalldata([
AllowedArgument.any(),
AllowedArgument.equal(12),
AllowedArgument.lt(100),
AllowedArgument.gt(25),
AllowedArgument.canBe([
AllowedArgument.equal(address(0)),
AllowedArgument.equal(address(0x429952c8d27f515011d623dfc9038152af52c5a8)),
]),
]);
This means that the target function selector
with have the following constraints on arguments:
(*, 12, <100, >25, 0|0x429952c8d27f515011d623dfc9038152af52c5a8)
This means that the selector
function can be called by any value for the first argument, 12 for the 2nd, a number less than 100 for the 3rd etc...
Note
<
and >
operators are only for numbers (static) max uin256.