Skip to content

Commit

Permalink
Implementation wallet_grantPermissions based on Appkit spec (#723)
Browse files Browse the repository at this point in the history
* refactor ContextBuilderUtil

* chores: build fix

* implement userOpBuilder service as per new spec

* remove use of mockvalidator from contextBuilderUtils

* add ContractCallPermissions types

* add ERC5792 support for baseSepolia

* update WalletConnectCosigner as per new spec

* fix request/response types for UserOpBuilderService

* fix: walletClient in grantPermissions impl

* chores: remove comments

* refactor ContextBuilderUtils

* remove _middleware.ts

* handle grantPermissions error response

* change api to handle JSON rpc call for wallet_prepareCalls and wallet_sendPreparedCalls

* add passkey dummy signature support for UserOpBuilder

* chore: refactor and type fixes

* add permissions capabilities for SCA

* chores: rename and remove unused types.

* chores: refactor and deps update

* chores:fix names
  • Loading branch information
KannuSingh authored Oct 9, 2024
1 parent b6a244c commit b7c1ec6
Show file tree
Hide file tree
Showing 19 changed files with 1,130 additions and 888 deletions.
2 changes: 1 addition & 1 deletion advanced/wallets/react-wallet-v2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"@nextui-org/react": "1.0.8-beta.5",
"@polkadot/keyring": "^10.1.2",
"@polkadot/types": "^9.3.3",
"@rhinestone/module-sdk": "0.1.16",
"@rhinestone/module-sdk": "0.1.18",
"@solana/web3.js": "1.89.2",
"@taquito/signer": "^15.1.0",
"@taquito/taquito": "^15.1.0",
Expand Down
26 changes: 22 additions & 4 deletions advanced/wallets/react-wallet-v2/src/data/EIP5792Data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ export const EIP5792_METHODS = {
}

// capability names as string literals
export type CapabilityName = 'atomicBatch' | 'paymasterService' | 'sessionKey'
export type CapabilityName = 'atomicBatch' | 'paymasterService' | 'permissions'
// Capability type where each key is a capability name and value has `supported` field
export type Capabilities = {
[K in CapabilityName]?: {
supported: boolean
[key: string]: any
}
}
// GetCapabilitiesResult type using mapped types
Expand Down Expand Up @@ -65,9 +66,26 @@ export const supportedEIP5792CapabilitiesForSCA: GetCapabilitiesResult = {
paymasterService: {
supported: true
},
// sessionKey: {
// supported: true,
// },
permissions: {
supported: true,
signerTypes: ['keys'],
permissionTypes: ['contract-call'],
policyTypes: []
},
atomicBatch: {
supported: true
}
},
'0x14a34': {
paymasterService: {
supported: true
},
permissions: {
supported: true,
signerTypes: ['keys'],
permissionTypes: ['contract-call'],
policyTypes: []
},
atomicBatch: {
supported: true
}
Expand Down
134 changes: 74 additions & 60 deletions advanced/wallets/react-wallet-v2/src/data/EIP7715Data.ts
Original file line number Diff line number Diff line change
@@ -1,82 +1,96 @@
import { Address } from 'viem'

/**
* EIP7715Method
*/
export const EIP7715_METHOD = {
WALLET_GRANT_PERMISSIONS: 'wallet_grantPermissions'
}

// `data` is not necessary for this signer type as the wallet is both the signer and grantor of these permissions
export type WalletSigner = {
type: 'wallet'
data: {}
}

// A signer representing a single key.
// `id` is a did:key identifier and can therefore represent both Secp256k1 or Secp256r1 keys, among other key types.
export type KeySigner = {
type: 'key'
data: {
id: string
}
export type Signer = MultiKeySigner
export type KeyType = 'secp256k1' | 'secp256r1'
// The types of keys that are supported for the following `key` and `keys` signer types.
export enum SignerKeyType {
SECP256K1 = 0, // EOA - k1
SECP256R1 = 1 // Passkey - r1
}

// A signer representing a multisig signer.
// Each element of `ids` is a did:key identifier just like the `key` signer.
/*
* A signer representing a multisig signer.
* Each element of `publicKeys` are all explicitly the same `KeyType`, and the public keys are hex-encoded.
*/
export type MultiKeySigner = {
type: 'keys'
data: {
ids: string[]
address?: Address
keys: {
type: KeyType
publicKey: `0x${string}`
}[]
}
}

// An account that can be granted with permissions as in ERC-7710.
export type AccountSigner = {
type: 'account'
data: {
id: `0x${string}`
}
export type Policy = {
type: string
data: Record<string, unknown>
}
// Enum for parameter operators
enum ParamOperator {
EQUAL = 'EQUAL',
GREATER_THAN = 'GREATER_THAN',
LESS_THAN = 'LESS_THAN'
// Add other operators as needed
}

export enum SignerType {
EOA,
PASSKEY
// Enum for operation types
enum Operation {
Call = 'Call',
DelegateCall = 'DelegateCall'
}

export type Signer = {
type: SignerType
data: string
// Type for a single argument condition
type ArgumentCondition = {
operator: ParamOperator
value: any // You might want to be more specific based on your use case
}

export type Permission = {
type: PermissionType
policies: Policy[]
required: boolean
data: any
// Type for a single function permission
type FunctionPermission = {
functionName: string // Function name
args: ArgumentCondition[] // An array of conditions, each corresponding to an argument for the function
valueLimit: bigint // Maximum value that can be transferred for this specific function call
operation?: Operation // (optional) whether this is a call or a delegatecall. Defaults to call
}
export type Policy = {
type: PolicyType
data: any
export type ContractCallPermission = {
type: 'contract-call'
data: {
address: `0x${string}`
abi: Record<string, unknown>[]
functions: FunctionPermission[]
}
}

// Union type for all possible permissions
export type Permission = ContractCallPermission

export type WalletGrantPermissionsRequest = {
chainId: `0x${string}`
address?: `0x${string}`
expiry: number
signer: Signer
permissions: Permission[]
policies: {
type: string
data: Record<string, unknown>
}[]
}

export type WalletGrantPermissionsResponse = WalletGrantPermissionsRequest & {
context: `0x${string}`
accountMeta?: {
factory: `0x${string}`
factoryData: `0x${string}`
}
signerMeta?: {
// 7679 userOp building
userOpBuilder?: `0x${string}`
// 7710 delegation
delegationManager?: `0x${string}`
}
}
export type PermissionType =
| 'native-token-transfer'
| 'erc20-token-transfer'
| 'erc721-token-transfer'
| 'erc1155-token-transfer'
| {
custom: any
}
export type PolicyType =
| 'gas-limit'
| 'call-limit'
| 'rate-limit'
| 'spent-limit'
| 'value-limit'
| 'time-frame'
| 'uni-action'
| 'simpler-signer'
| {
custom: any
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ const {
MULTI_FACTOR_VALIDATOR_ADDRESS,
OWNABLE_VALIDATOR_ADDRESS,
WEBAUTHN_VALIDATOR_ADDRESS,
SCHEDULED_ORDERS_EXECUTER_ADDRESS,
SCHEDULED_TRANSFERS_EXECUTER_ADDRESS
SCHEDULED_ORDERS_EXECUTOR_ADDRESS,
SCHEDULED_TRANSFERS_EXECUTOR_ADDRESS
} = require('@rhinestone/module-sdk') as typeof import('@rhinestone/module-sdk')

export type ModuleView =
Expand Down Expand Up @@ -65,15 +65,15 @@ export const supportedModules: Module[] = [
name: 'Schedule Orders Executor',
type: 'executor',
url: 'schedule-orders-executor',
moduleAddress: SCHEDULED_ORDERS_EXECUTER_ADDRESS,
moduleAddress: SCHEDULED_ORDERS_EXECUTOR_ADDRESS,
description: `The Scheduled Orders module allows users to schedule swaps to be executed at a later time, with an optional recurring schedule. This module is an executor that is installed on an account and can be triggered by an automation service at the pre-specified time(s).`,
moduleData: ''
},
{
name: 'Schedule Transfers Executor',
type: 'executor',
url: '/schedule-transfers-executor',
moduleAddress: SCHEDULED_TRANSFERS_EXECUTER_ADDRESS,
moduleAddress: SCHEDULED_TRANSFERS_EXECUTOR_ADDRESS,
description: `The Scheduled Transfers module allows users to schedule token transfers to occur at a future time, with an optional recurring schedule. It is an executor that is installed on an account and can be triggered by an automation service at the pre-specified time(s).`,
moduleData: ''
}
Expand Down
Loading

0 comments on commit b7c1ec6

Please sign in to comment.