Skip to content

Commit

Permalink
update the USE test with more utils
Browse files Browse the repository at this point in the history
  • Loading branch information
livingrockrises committed Sep 25, 2024
1 parent 27fa5e0 commit 885c5c1
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 66 deletions.
3 changes: 3 additions & 0 deletions src/sdk/modules/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { K1ValidatorModule } from "./validators/K1ValidatorModule.js"
import { OwnableValidator } from "./validators/OwnableValidator.js"
import { SmartSessionValidator } from "./validators/SmartSessionValidator.js"
import { ValidationModule } from "./validators/ValidationModule.js"

export * from "./utils/Types.js"
Expand All @@ -10,4 +11,6 @@ export * from "./interfaces/IValidationModule.js"
// export const createOwnableExecutorModule = OwnableExecutorModule.create
export const createK1ValidatorModule = K1ValidatorModule.create
export const createOwnableValidatorModule = OwnableValidator.create
// Review below should be Validator too
export const createValidationModule = ValidationModule.create
export const createSmartSessionValidatorModule = SmartSessionValidator.create
41 changes: 41 additions & 0 deletions src/sdk/modules/utils/Helper.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {
type Address,
type ByteArray,
type Chain,
type Hex,
type PrivateKeyAccount,
type PublicClient,
encodeAbiParameters,
isHex,
keccak256,
Expand All @@ -21,6 +23,9 @@ import type {
ChainInfo
// createOwnableValidatorModule
} from "../../index.js"
import { type Session } from "@rhinestone/module-sdk"
import addresses from "../../__contracts/addresses.js"
import { smartSessionAbi } from "./abi.js"

/**
* Rule
Expand Down Expand Up @@ -239,3 +244,39 @@ export const toActionConfig = (config: ActionConfig): ActionConfig => {
}
};
};

// Review
// Note: presently created local helper.
// Todo: If any changes are approved in module-sdk then start importing from there.
export const getPermissionId = async ({
client,
session,
}: {
client: PublicClient
session: Session
}) => {
// Review address population
return (await client.readContract({
address: addresses.SmartSession,
abi: smartSessionAbi,
functionName: 'getPermissionId',
args: [session],
})) as Hex
}

export const isSessionEnabled = async ({
client,
accountAddress,
permissionId,
}: {
client: PublicClient
accountAddress: Address
permissionId: Hex
}) => {
return (await client.readContract({
address: addresses.SmartSession,
abi: smartSessionAbi,
functionName: 'isSessionEnabled',
args: [permissionId, accountAddress],
})) as boolean
}
19 changes: 11 additions & 8 deletions src/sdk/modules/validators/SmartSessionValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,30 @@ import { type NexusAccount, type Signer, toSigner } from "../../account/index.js
import { BaseValidationModule } from "../base/BaseValidationModule.js"
import { type Module } from "../../clients/index.js"
import addresses from "../../__contracts/addresses.js"
import { type ActionData, encodeSmartSessionSignature, getPermissionId, type PolicyData, type Session, SmartSessionMode } from "@rhinestone/module-sdk"
import { type ActionData, encodeSmartSessionSignature, type PolicyData, type Session, SmartSessionMode } from "@rhinestone/module-sdk"
import { type ActionConfig, type CreateSessionDataParams, type CreateSessionDataResponse, type ModuleInfo, type ParamRule } from "../utils/Types.js"
import { smartSessionAbi, universalActionPolicyAbi } from "../utils/abi.js"
import { toActionConfig } from "../index.js"
import { getPermissionId, toActionConfig } from "../index.js"

const DUMMY_ECDSA_SIG = "0xe8b94748580ca0b4993c9a1b86b5be851bfc076ff5ce3a1ff65bf16392acfcb800f9b4f1aef1555c7fce5599fffb17e7c635502154a0333ba21f3ae491839af51c";
const UNIVERSAL_POLICY_ADDRESS = addresses.UniActionPolicy
const TIMEFRAME_POLICY_ADDRESS = addresses.TimeframePolicy
const SIMPLE_SESSION_VALIDATOR_ADDRESS = addresses.SimpleSessionValidator

export class SmartSessionValidator extends BaseValidationModule {
static client: PublicClient
public client: PublicClient

private constructor(
moduleConfig: Module,
signer: Signer
signer: Signer,
smartAccount: NexusAccount
) {
// if (!moduleConfig.data) {
// throw new Error("Module data is required")
// }
super(moduleConfig, signer)
const client = smartAccount.client as PublicClient;
this.client = client
this.signer = signer
// Review: could be optional override. otherwise use SMART_SESSION_ADDRESS from addresses
this.address = moduleConfig.address
Expand All @@ -50,8 +53,7 @@ export class SmartSessionValidator extends BaseValidationModule {
}): Promise<SmartSessionValidator> {
let moduleInfo: Module
// let installData: Hex
const client = smartAccount.client as PublicClient;
this.client = client
// const client = smartAccount.client as PublicClient;
moduleInfo = {
address, // @todo: change to real module address
type: "validator",
Expand All @@ -62,7 +64,7 @@ export class SmartSessionValidator extends BaseValidationModule {
const account = smartAccount.client.account
// Note: here the signer provided is existing smart account's signer.
// Review: this would be session key signer. Only applies in the case where SessionValidator supplied in SimpleValidator (ECDSA)
const instance = new SmartSessionValidator(moduleInfo, await toSigner({ signer: account! }))
const instance = new SmartSessionValidator(moduleInfo, await toSigner({ signer: account! }), smartAccount)
return instance
}

Expand Down Expand Up @@ -190,7 +192,8 @@ export class SmartSessionValidator extends BaseValidationModule {
}
};

const permissionId = await getPermissionId({ client: SmartSessionValidator.client, session: session }) as Hex;
// todo: review should allow override of constant like SMART_SESSIONS_ADDRESS
const permissionId = await getPermissionId({ client: this.client, session: session }) as Hex;
// push permissionId to the array
permissionIds.push(permissionId);

Expand Down
130 changes: 72 additions & 58 deletions src/sdk/modules/validators/smartSessionValidator.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { encodeAbiParameters, encodePacked, http, type Account, type Address, type Chain } from "viem"
import { encodeAbiParameters, encodePacked, Hex, http, PublicClient, toBytes, toHex, type Account, type Address, type Chain } from "viem"
import { TEST_CONTRACTS } from './../../../test/callDatas';
import { afterAll, beforeAll, describe, expect, test } from "vitest"
import { toNetwork } from "../../../test/testSetup"
import {
Expand All @@ -14,6 +15,7 @@ import {
type NexusClient,
createNexusClient
} from "../../clients/createNexusClient"
import { CreateSessionDataParams, createSmartSessionValidatorModule, isSessionEnabled } from "../.."

describe("modules.k1Validator.write", async () => {
let network: NetworkConfig
Expand All @@ -27,6 +29,7 @@ describe("modules.k1Validator.write", async () => {
let nexusAccountAddress: Address
let recipient: Account
let recipientAddress: Address
let permissionIdCached: Hex

beforeAll(async () => {
network = await toNetwork()
Expand Down Expand Up @@ -54,9 +57,9 @@ describe("modules.k1Validator.write", async () => {
await killNetwork([network?.rpcPort, network?.bundlerPort])
})

test.skip("should send eth", async () => {
test("should send eth", async () => {
const balanceBefore = await getBalance(testClient, recipientAddress)
const hash = await nexusClient.sendTransaction({
const hash = await nexusClient.sendUserOperation({
calls: [
{
to: recipientAddress,
Expand Down Expand Up @@ -94,66 +97,77 @@ describe("modules.k1Validator.write", async () => {
}, 60000)

test("should create Counter increment session (USE mode) on installed smart session validator", async () => {
// const isInstalledBefore = await smartAccount.isModuleInstalled({
// type: "validator",
// moduleAddress: TEST_CONTRACTS.SmartSession.address
// })
const isInstalledBefore = await nexusClient.isModuleInstalled({
module: {
type: "validator",
address: addresses.SmartSession,
}
});

// expect(isInstalledBefore).toBe(true)
expect(isInstalledBefore).toBe(true)

// const smartAccountSigner = await convertSigner(walletClient)

// const smartSessionModule = await createSmartSessionModule(
// smartAccount.publicClient,
// smartAccountSigner.signer,
// TEST_CONTRACTS.SmartSession.address
// )
const smartSessionModule = await createSmartSessionValidatorModule({
smartAccount: nexusClient.account,
address: TEST_CONTRACTS.SmartSession.address
})

// // Generate empty bytes32 hex string for dummy permisisonId
// const emptyBytes32 = "0x" + "0".repeat(64) as Hex;
// const dummySignature = smartSessionModule.getDummySignature({ permissionId: emptyBytes32 });
// // console.log("dummySignature", dummySignature)
// expect(dummySignature).toBeDefined();

// // make EOA owner of SA session key as well
// const sessionKeyEOA = account.address

// // Todo: Add a negative test case for time range policy
// const sessionRequestedInfo: CreateSessionDataParams = {
// sessionPublicKey: sessionKeyEOA,
// sessionValidatorAddress: TEST_CONTRACTS.SimpleSessionValidator.address,
// sessionKeyData: toHex(toBytes(sessionKeyEOA)),
// contractAddress: TEST_CONTRACTS.Counter.address, // counter address
// functionSelector: "0x273ea3e3" as Hex, // function selector for increment count
// validUntil: 0, // 1717001666
// validAfter: 0,
// rules: [], // no other rules and conditions applied
// valueLimit: BigInt(0)
// }

// const createSessionDataResponse = await smartSessionModule.createSessionData([sessionRequestedInfo])
// // console.log("sessionsEnableData", createSessionDataResponse.sessionsEnableData)
// expect(createSessionDataResponse.sessionsEnableData).toBeDefined()

// const permissionIds = createSessionDataResponse.permissionIds
// expect(permissionIds.length).toBe(1)
// const permissionId = permissionIds[0]
// permissionIdCached = permissionId

// const tx: Transaction = {
// to: TEST_CONTRACTS.SmartSession.address,
// data: createSessionDataResponse.sessionsEnableData
// }
// Generate empty bytes32 hex string for dummy permisisonId
const emptyBytes32 = "0x" + "0".repeat(64) as Hex;
const dummySignature = smartSessionModule.getDummySignature({ permissionId: emptyBytes32 });
// console.log("dummySignature", dummySignature)
expect(dummySignature).toBeDefined();

// make EOA owner of SA session key as well
const sessionKeyEOA = account.address

// Todo: Add a negative test case for time range policy
const sessionRequestedInfo: CreateSessionDataParams = {
sessionPublicKey: sessionKeyEOA,
sessionValidatorAddress: TEST_CONTRACTS.SimpleSessionValidator.address,
sessionKeyData: toHex(toBytes(sessionKeyEOA)),
sessionValidAfter: 0,
sessionValidUntil: 0,
actionPoliciesInfo:
[{
contractAddress: TEST_CONTRACTS.Counter.address, // counter address
functionSelector: "0x273ea3e3" as Hex, // function selector for increment count
validUntil: 0, // 1717001666
validAfter: 0,
rules: [], // no other rules and conditions applied
valueLimit: BigInt(0)
}],
}

// single session
const createSessionDataResponse = await smartSessionModule.createSessionData([sessionRequestedInfo])
// console.log("sessionsEnableData", createSessionDataResponse.sessionsEnableData)
expect(createSessionDataResponse.sessionsEnableData).toBeDefined()

const permissionIds = createSessionDataResponse.permissionIds
expect(permissionIds.length).toBe(1)
const permissionId = permissionIds[0]
permissionIdCached = permissionId

const hash = await nexusClient.sendTransaction({
calls: [
{
to: TEST_CONTRACTS.SmartSession.address,
data: createSessionDataResponse.sessionsEnableData
}
]
})

// const { wait } = await smartAccount.sendTransaction(tx)
// const { success } = await wait()
// expect(success).toBe(true)

// const isEnabled = await isSessionEnabled({
// client: smartAccount.publicClient,
// smartAccountAddress,
// permissionId
// })
// expect(isEnabled).toBe(true)
expect(hash).toBeDefined()
const { status } = await testClient.waitForTransactionReceipt({ hash })
expect(status).toBe("success")

const isEnabled = await isSessionEnabled({
client: nexusClient.account.client as PublicClient,
accountAddress: await nexusClient.account.getAddress(),
permissionId
})
expect(isEnabled).toBe(true)
}, 60000)
})
5 changes: 5 additions & 0 deletions src/test/callDatas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ export const TEST_CONTRACTS: Record<string, { chainId: number; name: string; add
name: "MockValidator",
address: "0x61Cb30337CB980383704f2Debfb8bea66d0f26b3"
},
Counter: {
chainId: 84532,
name: "Counter",
address: "0x14e4829E655F0b3a1793838dDd47273D5341d416"
},
UserOperationBuilder: {
chainId: 84532,
name: "UserOperationBuilder",
Expand Down

0 comments on commit 885c5c1

Please sign in to comment.