Skip to content

Commit

Permalink
fix: reference value
Browse files Browse the repository at this point in the history
chore: lint

ci: fix

chore: version bump

chore: version bump + biome tweak

chore: sessions roughwork

chore: lint

chore: hack fix tests

chore: remove logs

chore: continued testing

chore: remove logs

chore: lint fix
  • Loading branch information
joepegler committed May 17, 2024
1 parent c70febb commit 26e1546
Show file tree
Hide file tree
Showing 15 changed files with 236 additions and 104 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @biconomy/account

## 4.4.2

### Patch Changes

- fix referenceValue padding

## 4.4.1

### Patch Changes
Expand Down
1 change: 1 addition & 0 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"$schema": "https://biomejs.dev/schemas/1.5.3/schema.json",
"files": {
"ignore": [
"package.json",
"node_modules",
"**/node_modules",
"cache",
Expand Down
1 change: 0 additions & 1 deletion examples/CREATE_AND_USE_A_BATCH_SESSION.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ const leaves: CreateSessionParams[] = [

const { wait, session } = await createBatchSession(
smartAccount,
sessionKeyAddress,
sessionStorageClient,
leaves,
withSponsorship
Expand Down
1 change: 0 additions & 1 deletion examples/CREATE_AND_USE_A_SESSION.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ const policy: Policy[] = [
const { wait, session } = await createSession(
smartAccount,
policy,
sessionKeyAddress,
sessionStorageClient,
{
paymasterServiceData: { mode: PaymasterMode.SPONSORED },
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"sideEffects": false,
"name": "@biconomy/account",
"author": "Biconomy",
"version": "4.4.1",
"version": "4.4.2",
"description": "SDK for Biconomy integration with support for account abstraction, smart accounts, ERC-4337.",
"keywords": [
"erc-7579",
Expand Down
1 change: 1 addition & 0 deletions src/account/BiconomySmartAccountV2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,7 @@ export class BiconomySmartAccountV2 extends BaseSmartContractAccount {
_params?: SendUserOpParams
): Promise<UserOperationStruct> {
const params = { ..._params, ...(this.sessionData ? this.sessionData : {}) }

this.isActiveValidationModuleDefined()
const requiredFields: UserOperationKey[] = [
"sender",
Expand Down
3 changes: 2 additions & 1 deletion src/account/utils/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ export const ERROR_MESSAGES = {
MISSING_RPC_URL:
"rpcUrl is required for PrivateKeyAccount signer type, please provide it in the config",
INVALID_SESSION_TYPES:
"Session types and transactions must be of the same length"
"Session types and transactions must be of the same length",
SIGNER_REQUIRED: "Signer is required for creating a smart account"
}

export const NATIVE_TOKEN_ALIAS: Hex =
Expand Down
5 changes: 2 additions & 3 deletions src/modules/BatchedSessionRouterModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,6 @@ export class BatchedSessionRouterModule extends BaseValidationModule {
}

const sessionDataTupleArray: SessionDataTuple[] = []

// if needed we could do mock signature over userOpHashAndModuleAddress

// signer must be the same for all the sessions
const { signer: sessionSigner } = await convertSigner(
sessionParams[0].sessionSigner,
Expand Down Expand Up @@ -304,6 +301,8 @@ export class BatchedSessionRouterModule extends BaseValidationModule {
keccak256(leafDataHex)
)

console.log({ proof })

const sessionDataTuple: SessionDataTuple = [
BigInt(sessionSignerData.validUntil),
BigInt(sessionSignerData.validAfter),
Expand Down
3 changes: 0 additions & 3 deletions src/modules/session-storage/SessionFileStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,12 @@ export class SessionFileStorage implements ISessionStorage {
data: any,
type: "sessions" | "signers"
): Promise<void> {
console.log("")
return new Promise((resolve, reject) => {
const filePath = this.getStorageFilePath(type)
// @ts-ignore
fs.writeFile(filePath, JSON.stringify(data), "utf8", (err) => {
if (err) {
// Handle errors appropriately
console.log({ err }, JSON.stringify(data))
reject(err)
} else {
resolve()
Expand Down Expand Up @@ -90,7 +88,6 @@ export class SessionFileStorage implements ISessionStorage {
return data || { merkleRoot: "", leafNodes: [] }
} catch (error) {
// Handle errors appropriately
console.log({ error })
}
}

Expand Down
52 changes: 23 additions & 29 deletions src/modules/sessions/abi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
type ByteArray,
type Hex,
concat,
isAddress,
pad,
slice,
toFunctionSelector,
Expand All @@ -18,6 +17,7 @@ import {
type BiconomySmartAccountV2,
type BuildUserOpOptions,
ERROR_MESSAGES,
Logger,
type Transaction
} from "../../account"
import { createSessionKeyManagerModule } from "../index"
Expand All @@ -37,7 +37,7 @@ export type Session = {
/** The storage client specific to the smartAccountAddress which stores the session keys */
sessionStorageClient: ISessionStorage
/** The relevant sessionID for the chosen session */
sessionID: string
sessionIDInfo: string[]
}

export type SessionEpoch = {
Expand Down Expand Up @@ -121,7 +121,6 @@ export type SessionGrantedPayload = UserOpResponse & { session: Session }
* valueLimit: 0n
* }
* ],
* sessionKeyAddress,
* sessionStorage,
* {
* paymasterServiceData: { mode: PaymasterMode.SPONSORED },
Expand All @@ -139,19 +138,17 @@ export type SessionGrantedPayload = UserOpResponse & { session: Session }
export const createSession = async (
smartAccount: BiconomySmartAccountV2,
policy: Policy[],
sessionKeyAddress: Hex,
sessionStorageClient: ISessionStorage,
buildUseropDto?: BuildUserOpOptions
): Promise<SessionGrantedPayload> => {
const userAccountAddress = await smartAccount.getAddress()
const smartAccountAddress = await smartAccount.getAddress()
const sessionsModule = await createSessionKeyManagerModule({
smartAccountAddress: userAccountAddress,
smartAccountAddress,
sessionStorageClient
})

const { data: policyData } = await sessionsModule.createSessionData(
policy.map(createABISessionDatum)
)
const { data: policyData, sessionIDInfo } =
await sessionsModule.createSessionData(policy.map(createABISessionDatum))

const permitTx = {
to: DEFAULT_SESSION_KEY_MANAGER_MODULE,
Expand All @@ -161,33 +158,30 @@ export const createSession = async (
const txs: Transaction[] = []

const isDeployed = await smartAccount.isAccountDeployed()
if (!isDeployed) throw new Error(ERROR_MESSAGES.ACCOUNT_NOT_DEPLOYED)

const enabled = await smartAccount.isModuleEnabled(
const enableSessionTx = await smartAccount.getEnableModuleData(
DEFAULT_SESSION_KEY_MANAGER_MODULE
)

if (!enabled) {
txs.push(
await smartAccount.getEnableModuleData(DEFAULT_SESSION_KEY_MANAGER_MODULE)
if (isDeployed) {
const enabled = await smartAccount.isModuleEnabled(
DEFAULT_SESSION_KEY_MANAGER_MODULE
)
if (!enabled) {
txs.push(enableSessionTx)
}
} else {
Logger.log(ERROR_MESSAGES.ACCOUNT_NOT_DEPLOYED)
txs.push(enableSessionTx)
}

txs.push(permitTx)

const userOpResponse = await smartAccount.sendTransaction(txs, buildUseropDto)

const sessionID =
(
await sessionStorageClient.getSessionData({
sessionPublicKey: sessionKeyAddress,
sessionValidationModule: DEFAULT_ABI_SVM_MODULE
})
).sessionID ?? ""

return {
session: {
sessionStorageClient,
sessionID
sessionIDInfo
},
...userOpResponse
}
Expand Down Expand Up @@ -290,7 +284,7 @@ export function getSessionDatum(
return sessionKeyData
}

type HardcodedReference = {
export type HardcodedReference = {
raw: Hex
}
type BaseReferenceValue = string | number | bigint | boolean | ByteArray
Expand All @@ -312,11 +306,11 @@ export function parseReferenceValue(referenceValue: AnyReferenceValue): Hex {
if ((referenceValue as HardcodedReference)?.raw) {
return (referenceValue as HardcodedReference)?.raw
}
if (isAddress(referenceValue as string)) {
return pad(referenceValue as Hex, { size: 32 })
if (typeof referenceValue === "bigint") {
return pad(toHex(referenceValue), { size: 32 }) as Hex
}
return toHex(referenceValue as BaseReferenceValue)
return pad(referenceValue as Hex, { size: 32 })
} catch (e) {
return toHex(referenceValue as BaseReferenceValue)
return pad(referenceValue as Hex, { size: 32 })
}
}
83 changes: 42 additions & 41 deletions src/modules/sessions/batch.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { Chain, Hex } from "viem"
import type { Chain } from "viem"
import {
type CreateSessionDataParams,
DEFAULT_ABI_SVM_MODULE,
DEFAULT_BATCHED_SESSION_ROUTER_MODULE,
DEFAULT_SESSION_KEY_MANAGER_MODULE,
MODULE_ADDRESSES,
Expand All @@ -15,6 +14,7 @@ import {
type BiconomySmartAccountV2,
type BuildUserOpOptions,
ERROR_MESSAGES,
Logger,
type Transaction
} from "../../account"
import type { ISessionStorage } from "../interfaces/ISessionStorage"
Expand Down Expand Up @@ -97,7 +97,6 @@ export type CreateBatchSessionConfig = {
*
* const { wait, sessionID } = await createBatchSession(
* smartAccount,
* sessionKeyAddress,
* sessionStorageClient: sessionStorage,
* leaves,
* {
Expand All @@ -117,27 +116,26 @@ export type CreateBatchSessionConfig = {

export const createBatchSession = async (
smartAccount: BiconomySmartAccountV2,
sessionKeyAddress: Hex,
/** The storage client to be used for storing the session data */
sessionStorageClient: ISessionStorage,
/** An array of session configurations */
leaves: CreateSessionDataParams[],
buildUseropDto?: BuildUserOpOptions
): Promise<SessionGrantedPayload> => {
const userAccountAddress = await smartAccount.getAddress()
const smartAccountAddress = await smartAccount.getAddress()

const sessionsModule = await createSessionKeyManagerModule({
smartAccountAddress: userAccountAddress,
smartAccountAddress,
sessionStorageClient
})

// Create batched session module
const batchedSessionModule = await createBatchedSessionRouterModule({
smartAccountAddress: userAccountAddress,
smartAccountAddress,
sessionKeyManagerModule: sessionsModule
})

const { data: policyData } =
const { data: policyData, sessionIDInfo } =
await batchedSessionModule.createSessionData(leaves)

const permitTx = {
Expand All @@ -146,43 +144,40 @@ export const createBatchSession = async (
}

const isDeployed = await smartAccount.isAccountDeployed()
if (!isDeployed) throw new Error(ERROR_MESSAGES.ACCOUNT_NOT_DEPLOYED)

const txs: Transaction[] = []
const [isSessionModuleEnabled, isBatchedSessionModuleEnabled] =
await Promise.all([
smartAccount.isModuleEnabled(DEFAULT_SESSION_KEY_MANAGER_MODULE),
smartAccount.isModuleEnabled(DEFAULT_BATCHED_SESSION_ROUTER_MODULE)
])

if (!isSessionModuleEnabled) {
txs.push(
await smartAccount.getEnableModuleData(DEFAULT_SESSION_KEY_MANAGER_MODULE)
)
}
if (!isBatchedSessionModuleEnabled) {
txs.push(
await smartAccount.getEnableModuleData(
DEFAULT_BATCHED_SESSION_ROUTER_MODULE
)
)
const enableSessionKeyTx = await smartAccount.getEnableModuleData(
DEFAULT_SESSION_KEY_MANAGER_MODULE
)
const enableBatchedSessionTx = await smartAccount.getEnableModuleData(
DEFAULT_BATCHED_SESSION_ROUTER_MODULE
)
if (isDeployed) {
const [isSessionModuleEnabled, isBatchedSessionModuleEnabled] =
await Promise.all([
smartAccount.isModuleEnabled(DEFAULT_SESSION_KEY_MANAGER_MODULE),
smartAccount.isModuleEnabled(DEFAULT_BATCHED_SESSION_ROUTER_MODULE)
])

if (!isSessionModuleEnabled) {
txs.push(enableSessionKeyTx)
}
if (!isBatchedSessionModuleEnabled) {
txs.push(enableBatchedSessionTx)
}
} else {
Logger.log(ERROR_MESSAGES.ACCOUNT_NOT_DEPLOYED)
txs.push(enableSessionKeyTx, enableBatchedSessionTx)
}

txs.push(permitTx)

const userOpResponse = await smartAccount.sendTransaction(txs, buildUseropDto)

const sessionID =
(
await sessionStorageClient.getSessionData({
sessionPublicKey: sessionKeyAddress,
sessionValidationModule: DEFAULT_ABI_SVM_MODULE
})
).sessionID ?? ""

return {
session: {
sessionStorageClient,
sessionID
sessionIDInfo
},
...userOpResponse
}
Expand All @@ -208,25 +203,31 @@ export type SessionValidationType = (typeof types)[number]
export const getBatchSessionTxParams = async (
sessionValidationTypes: SessionValidationType[],
transactions: Transaction[],
{ sessionID, sessionStorageClient }: Session,
{ sessionIDInfo, sessionStorageClient }: Session,
chain: Chain
): Promise<BatchSessionParamsPayload> => {
if (sessionValidationTypes.length !== transactions.length) {
throw new Error(ERROR_MESSAGES.INVALID_SESSION_TYPES)
}

const sessionSigner = await sessionStorageClient.getSignerBySession(
{
sessionID
sessionID: sessionIDInfo[0]
},
chain
)

const batchSessionParams: SessionParams[] = sessionValidationTypes.map(
(sessionType, i): SessionParams => ({
sessionSigner,
sessionValidationModule: MODULE_ADDRESSES[sessionType],
sessionID: sessionIDInfo[i]
})
)

return {
params: {
batchSessionParams: sessionValidationTypes.map((sessionType) => ({
sessionSigner,
sessionValidationModule: MODULE_ADDRESSES[sessionType]
}))
batchSessionParams
}
}
}
Loading

0 comments on commit 26e1546

Please sign in to comment.