Skip to content

Commit

Permalink
added smart-session support on base-sepolia
Browse files Browse the repository at this point in the history
  • Loading branch information
KannuSingh committed Sep 13, 2024
1 parent d90370a commit 45d4694
Show file tree
Hide file tree
Showing 14 changed files with 583 additions and 834 deletions.
3 changes: 1 addition & 2 deletions advanced/wallets/react-wallet-v2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"prettier:write": "prettier --write '**/*.{js,ts,jsx,tsx}'"
},
"dependencies": {
"@biconomy/permission-context-builder": "^1.1.2",
"@cosmjs/amino": "0.32.3",
"@cosmjs/encoding": "0.32.3",
"@cosmjs/proto-signing": "0.32.3",
Expand All @@ -29,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.13",
"@rhinestone/module-sdk": "0.1.15",
"@solana/web3.js": "1.89.2",
"@taquito/signer": "^15.1.0",
"@taquito/taquito": "^15.1.0",
Expand Down
76 changes: 76 additions & 0 deletions advanced/wallets/react-wallet-v2/src/data/EIP7715Data.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,82 @@
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
}
}

// A signer representing a multisig signer.
// Each element of `ids` is a did:key identifier just like the `key` signer.
export type MultiKeySigner = {
type: 'keys'
data: {
ids: string[]
address?: Address
}
}

// An account that can be granted with permissions as in ERC-7710.
export type AccountSigner = {
type: 'account'
data: {
id: `0x${string}`
}
}

export enum SignerType {
EOA,
PASSKEY
}

export type Signer = {
type: SignerType
data: string
}

export type Permission = {
type: PermissionType
policies: Policy[]
required: boolean
data: any
}
export type Policy = {
type: PolicyType
data: any
}
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 @@ -11,18 +11,16 @@ import {
Hex,
WalletGrantPermissionsParameters,
createWalletClient,
encodeFunctionData,
http,
type WalletGrantPermissionsReturnType
} from 'viem'
import { MultiKeySigner } from 'viem/_types/experimental/erc7715/types/signer'
import {
mockValidator,
Permission,
userOperationBuilderAddress
} from '@biconomy/permission-context-builder'
import { ModuleType } from 'permissionless/actions/erc7579'
import { getContext } from './builders/ContextBuilderUtil'
const { SMART_SESSIONS_ADDRESS } =
import { MOCK_VALIDATOR_ADDRESSES } from './builders/SmartSessionUtil'
import { Permission } from '@/data/EIP7715Data'
import { getSmartSessionContext } from './builders/ContextBuilderUtil'
const { SMART_SESSIONS_ADDRESS, getAccount } =
require('@rhinestone/module-sdk') as typeof import('@rhinestone/module-sdk')
export class SafeSmartAccountLib extends SmartAccountLib {
protected ERC_7579_LAUNCHPAD_ADDRESS: Address = '0xEBe001b3D534B9B6E2500FB78E67a1A137f561CE'
Expand Down Expand Up @@ -75,11 +73,15 @@ export class SafeSmartAccountLib extends SmartAccountLib {
console.log('walletClient chainId:', walletClient.chain.id)
let permissionContext = '0x'
try {
permissionContext = await getContext(walletClient, {
permissionContext = await getSmartSessionContext({
walletClient,
account: getAccount({
address: this.client.account.address,
type: 'safe'
}),
permissions: [...grantPermissionsRequestParameters.permissions] as unknown as Permission[],
expiry: grantPermissionsRequestParameters.expiry,
signer: grantPermissionsRequestParameters.signer as MultiKeySigner,
smartAccountAddress: this.client.account.address
signer: grantPermissionsRequestParameters.signer as MultiKeySigner
})
} catch (error) {
console.error(`Error getting permission context: ${error}`)
Expand All @@ -92,7 +94,6 @@ export class SafeSmartAccountLib extends SmartAccountLib {
grantedPermissions: grantPermissionsRequestParameters.permissions,
expiry: grantPermissionsRequestParameters.expiry,
signerData: {
userOpBuilder: userOperationBuilderAddress[this.chain.id] as Address,
submitToAddress: this.client.account.address
}
} as WalletGrantPermissionsReturnType
Expand All @@ -114,15 +115,17 @@ export class SafeSmartAccountLib extends SmartAccountLib {
this.publicClient,
this.client.account.address
)
// TODO: check if account trust the attesters of the module
await this.trustAttesters()

let smartSessionValidatorInstalled = false
let mockValidatorInstalled = false
console.log(`SmartSession Address: ${SMART_SESSIONS_ADDRESS}`)
console.log(`mockValidator Address: ${mockValidator[this.chain.id]}`)
console.log(`mockValidator Address: ${MOCK_VALIDATOR_ADDRESSES[this.chain.id]}`)
if (isAccountDeployed) {
;[smartSessionValidatorInstalled, mockValidatorInstalled] = await Promise.all([
this.isValidatorModuleInstalled(SMART_SESSIONS_ADDRESS as Address),
this.isValidatorModuleInstalled(mockValidator[this.chain.id] as Address)
this.isValidatorModuleInstalled(MOCK_VALIDATOR_ADDRESSES[this.chain.id] as Address)
])
}
console.log({ smartSessionValidatorInstalled, mockValidatorInstalled })
Expand Down Expand Up @@ -150,7 +153,7 @@ export class SafeSmartAccountLib extends SmartAccountLib {

if (!isAccountDeployed || !mockValidatorInstalled) {
installModules.push({
address: mockValidator[this.chain.id],
address: MOCK_VALIDATOR_ADDRESSES[this.chain.id],
type: 'validator',
context: '0x'
})
Expand Down Expand Up @@ -193,4 +196,35 @@ export class SafeSmartAccountLib extends SmartAccountLib {
const receipt = await this.bundlerClient.waitForUserOperationReceipt({ hash: userOpHash })
console.log(`Module installation receipt:`, receipt)
}

private async trustAttesters(): Promise<void> {
if (!this.client?.account) {
throw new Error('Client not initialized')
}
const trustAttestersAction = {
to: '0x000000000069E2a187AEFFb852bF3cCdC95151B2' as Address, // mock-registry
value: BigInt(0),
data: encodeFunctionData({
abi: [
{
inputs: [
{ type: 'uint8', name: 'threshold' },
{ type: 'address[]', name: 'attesters' }
],
name: 'trustAttesters',
type: 'function',
stateMutability: 'nonpayable',
outputs: []
}
],
functionName: 'trustAttesters',
args: [1, ['0xA4C777199658a41688E9488c4EcbD7a2925Cc23A']]
})
}

const userOpHash = await this.sendTransaction(trustAttestersAction)
console.log(`Trust Attesters userOpHash:`, userOpHash)
// const receipt = await this.bundlerClient.waitForUserOperationReceipt({ hash: userOpHash })
// console.log(`Trust Attesters receipt:`, receipt)
}
}
Loading

0 comments on commit 45d4694

Please sign in to comment.