Skip to content

Commit

Permalink
chore: introduce deferred terminology
Browse files Browse the repository at this point in the history
  • Loading branch information
joepegler committed Jan 2, 2025
1 parent 9c0759d commit 6d5a087
Show file tree
Hide file tree
Showing 16 changed files with 182 additions and 186 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @biconomy/sdk

## 0.0.22

### Patch Changes

- Smart sessions enable mode

## 0.0.21

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@biconomy/sdk",
"version": "0.0.21",
"version": "0.0.22",
"author": "Biconomy",
"repository": "github:bcnmy/sdk",
"main": "./dist/_cjs/index.js",
Expand Down
7 changes: 3 additions & 4 deletions src/sdk/clients/createNexusSessionClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,9 @@ describe("nexus.session.client", async () => {

nexusClient.account.getCounterFactualAddress()

const createSessionsResponse =
await nexusSessionClient.grantPermissionInAdvance({
sessionRequestedInfo
})
const createSessionsResponse = await nexusSessionClient.grantPermission({
sessionRequestedInfo
})

expect(createSessionsResponse.userOpHash).toBeDefined()
expect(createSessionsResponse.permissionIds).toBeDefined()
Expand Down
2 changes: 1 addition & 1 deletion src/sdk/modules/smartSessionsValidator/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export type PreparePermissionResponse = {
/**
* Represents the response for creating sessions.
*/
export type GrantPermissionInAdvanceResponse = {
export type GrantPermissionResponse = {
/** The hash of the user operation. */
userOpHash: Hex
} & PreparePermissionResponse
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,33 @@
import type { Chain, Client, Hex, PublicClient, Transport } from "viem"
import { sendUserOperation } from "viem/account-abstraction"
import type { Chain, Client, PublicClient, Transport } from "viem"
import { getAction, parseAccount } from "viem/utils"
import { AccountNotFoundError } from "../../../account/utils/AccountNotFound"
import type { Call } from "../../../account/utils/Types"
import {
MAINNET_ADDRESS_K1_VALIDATOR_ADDRESS,
SmartSessionMode,
getAccount,
getEnableSessionDetails
} from "../../../constants"
import type { ModularSmartAccount } from "../../utils/Types"
import type {
CreateSessionDataParams,
GrantPermissionInAdvanceResponse
} from "../Types"
import type { CreateSessionDataParams, SessionData } from "../Types"
import { preparePermission } from "./preparePermission"

/**
* Parameters for creating sessions in a modular smart account.
*
* @template TModularSmartAccount - Type of the modular smart account, extending ModularSmartAccount or undefined.
*/
export type GrantPermissionInAdvanceParameters<
export type GrantDeferredPermissionParameters<
TModularSmartAccount extends ModularSmartAccount | undefined
> = {
/** Array of session data parameters for creating multiple sessions. */
sessionRequestedInfo: CreateSessionDataParams[]
/** The maximum fee per gas unit the transaction is willing to pay. */
maxFeePerGas?: bigint
/** The maximum priority fee per gas unit the transaction is willing to pay. */
maxPriorityFeePerGas?: bigint
/** The nonce of the transaction. If not provided, it will be determined automatically. */
nonce?: bigint
/** Optional public client for blockchain interactions. */
publicClient?: PublicClient
/** The modular smart account to create sessions for. If not provided, the client's account will be used. */
account?: TModularSmartAccount
/** Optional attesters to trust. */
attesters?: Hex[]
/** Additional calls to be included in the user operation. */
calls?: Call[]
}

export type GrantDeferredPermissionResponse = SessionData["moduleData"]
/**
* Adds multiple sessions to the SmartSessionValidator module of a given smart account.
*
Expand All @@ -53,9 +45,9 @@ export type GrantPermissionInAdvanceParameters<
*
* @example
* ```typescript
* import { grantPermissionInAdvance } from '@biconomy/sdk'
* import { grantDeferredPermission } from '@biconomy/sdk'
*
* const result = await grantPermissionInAdvance(nexusClient, {
* const result = await grantDeferredPermission(nexusClient, {
* sessionRequestedInfo: [
* {
* sessionKeyData: '0x...',
Expand All @@ -80,19 +72,13 @@ export type GrantPermissionInAdvanceParameters<
* - The number of sessions created is determined by the length of the `sessionRequestedInfo` array.
* - Each session's policies and permissions are determined by the `actionPoliciesInfo` provided.
*/
export async function grantPermissionInAdvance<
export async function grantDeferredPermission<
TModularSmartAccount extends ModularSmartAccount | undefined
>(
client: Client<Transport, Chain | undefined, TModularSmartAccount>,
parameters: GrantPermissionInAdvanceParameters<TModularSmartAccount>
): Promise<GrantPermissionInAdvanceResponse> {
const {
account: account_ = client.account,
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
calls: calls_
} = parameters
parameters: GrantDeferredPermissionParameters<TModularSmartAccount>
): Promise<GrantDeferredPermissionResponse> {
const { account: account_ = client.account } = parameters

if (!account_) {
throw new AccountNotFoundError({
Expand All @@ -101,6 +87,8 @@ export async function grantPermissionInAdvance<
}

const account = parseAccount(account_) as ModularSmartAccount
const publicClient = account?.client as PublicClient

if (!account || !account.address) {
throw new Error("Account not found")
}
Expand All @@ -111,26 +99,30 @@ export async function grantPermissionInAdvance<
"preparePermission"
)(parameters)

const userOpHash = await getAction(
client,
sendUserOperation,
"sendUserOperation"
)({
calls: [
{
to: preparedPermission.action.target,
data: preparedPermission.action.callData
},
...(calls_ || [])
],
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
account
const nexusAccount = getAccount({
address: account.address,
type: "nexus"
})

const sessionDetailsWithPermissionEnableHash = await getEnableSessionDetails({
enableMode: SmartSessionMode.UNSAFE_ENABLE,
sessions: preparedPermission.sessions,
account: nexusAccount,
clients: [publicClient],
enableValidatorAddress: MAINNET_ADDRESS_K1_VALIDATOR_ADDRESS
})

const { permissionEnableHash, ...sessionDetails } =
sessionDetailsWithPermissionEnableHash

sessionDetails.enableSessionData.enableSession.permissionEnableSig =
await account.signer.signMessage({ message: { raw: permissionEnableHash } })

return {
userOpHash,
...preparedPermission
permissionIds: preparedPermission.permissionIds,
action: preparedPermission.action,
mode: SmartSessionMode.UNSAFE_ENABLE,
sessions: preparedPermission.sessions,
enableSessionData: sessionDetails.enableSessionData
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import type { Chain, Client, PublicClient, Transport } from "viem"
import type { Chain, Client, Hex, PublicClient, Transport } from "viem"
import { sendUserOperation } from "viem/account-abstraction"
import { getAction, parseAccount } from "viem/utils"
import { AccountNotFoundError } from "../../../account/utils/AccountNotFound"
import {
MAINNET_ADDRESS_K1_VALIDATOR_ADDRESS,
SmartSessionMode,
getAccount,
getEnableSessionDetails
} from "../../../constants"
import type { Call } from "../../../account/utils/Types"
import type { ModularSmartAccount } from "../../utils/Types"
import type { CreateSessionDataParams, SessionData } from "../Types"
import type { CreateSessionDataParams, GrantPermissionResponse } from "../Types"
import { preparePermission } from "./preparePermission"

/**
Expand All @@ -21,13 +17,22 @@ export type GrantPermissionParameters<
> = {
/** Array of session data parameters for creating multiple sessions. */
sessionRequestedInfo: CreateSessionDataParams[]
/** The maximum fee per gas unit the transaction is willing to pay. */
maxFeePerGas?: bigint
/** The maximum priority fee per gas unit the transaction is willing to pay. */
maxPriorityFeePerGas?: bigint
/** The nonce of the transaction. If not provided, it will be determined automatically. */
nonce?: bigint
/** Optional public client for blockchain interactions. */
publicClient?: PublicClient
/** The modular smart account to create sessions for. If not provided, the client's account will be used. */
account?: TModularSmartAccount
/** Optional attesters to trust. */
attesters?: Hex[]
/** Additional calls to be included in the user operation. */
calls?: Call[]
}

export type GrantPermissionResponse = SessionData["moduleData"]
/**
* Adds multiple sessions to the SmartSessionValidator module of a given smart account.
*
Expand Down Expand Up @@ -78,7 +83,13 @@ export async function grantPermission<
client: Client<Transport, Chain | undefined, TModularSmartAccount>,
parameters: GrantPermissionParameters<TModularSmartAccount>
): Promise<GrantPermissionResponse> {
const { account: account_ = client.account } = parameters
const {
account: account_ = client.account,
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
calls: calls_
} = parameters

if (!account_) {
throw new AccountNotFoundError({
Expand All @@ -87,8 +98,6 @@ export async function grantPermission<
}

const account = parseAccount(account_) as ModularSmartAccount
const publicClient = account?.client as PublicClient

if (!account || !account.address) {
throw new Error("Account not found")
}
Expand All @@ -99,30 +108,26 @@ export async function grantPermission<
"preparePermission"
)(parameters)

const nexusAccount = getAccount({
address: account.address,
type: "nexus"
})

const sessionDetailsWithPermissionEnableHash = await getEnableSessionDetails({
enableMode: SmartSessionMode.UNSAFE_ENABLE,
sessions: preparedPermission.sessions,
account: nexusAccount,
clients: [publicClient],
enableValidatorAddress: MAINNET_ADDRESS_K1_VALIDATOR_ADDRESS
const userOpHash = await getAction(
client,
sendUserOperation,
"sendUserOperation"
)({
calls: [
{
to: preparedPermission.action.target,
data: preparedPermission.action.callData
},
...(calls_ || [])
],
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
account
})

const { permissionEnableHash, ...sessionDetails } =
sessionDetailsWithPermissionEnableHash

sessionDetails.enableSessionData.enableSession.permissionEnableSig =
await account.signer.signMessage({ message: { raw: permissionEnableHash } })

return {
permissionIds: preparedPermission.permissionIds,
action: preparedPermission.action,
mode: SmartSessionMode.UNSAFE_ENABLE,
sessions: preparedPermission.sessions,
enableSessionData: sessionDetails.enableSessionData
userOpHash,
...preparedPermission
}
}
37 changes: 18 additions & 19 deletions src/sdk/modules/smartSessionsValidator/decorators/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import type { Chain, Client, Hash, Transport } from "viem"
import type { ModularSmartAccount, Module } from "../../utils/Types"
import type {
GrantPermissionInAdvanceResponse,
GrantPermissionResponse,
PreparePermissionResponse
} from "../Types"
import type { SmartSessionModule } from "../toSmartSessionsValidator"
import {
type GrantDeferredPermissionParameters,
grantDeferredPermission
} from "./grantDeferredPermission.ts"

Check failure on line 11 in src/sdk/modules/smartSessionsValidator/decorators/index.ts

View workflow job for this annotation

GitHub Actions / size report

An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled.
import {
type GrantPermissionParameters,
grantPermission
} from "./grantPermission.js"
import {
type GrantPermissionInAdvanceParameters,
grantPermissionInAdvance
} from "./grantPermissionInAdvance.js"
} from "./grantPermission.ts"

Check failure on line 15 in src/sdk/modules/smartSessionsValidator/decorators/index.ts

View workflow job for this annotation

GitHub Actions / size report

An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled.
import {
type PreparePermissionParameters,
preparePermission
} from "./preparePermission.js"
} from "./preparePermission"
import { type TrustAttestersParameters, trustAttesters } from "./trustAttesters"
import { type UsePermissionParameters, usePermission } from "./usePermission"
/**
Expand All @@ -29,27 +29,27 @@ export type SmartSessionCreateActions<
> = {
/**
* Creates multiple sessions for a modular smart account.
* This differs from grantPermissionInAdvance in that it defers the moment that the permission is granted
* This differs from grantPermission in that it defers the moment that the permission is granted
* on chain to the moment that the redemption user operation is sent/redeemed. It is also known as "ENABLE_MODE".
* It is the default mode for the grantPermission function.
* It is the default mode for the grantDeferredPermission function.
*
* @param args - Parameters for creating sessions.
* @returns A promise that resolves to the creation response.
*/
grantPermission: (
args: GrantPermissionParameters<TModularSmartAccount>
grantDeferredPermission: (
args: GrantDeferredPermissionParameters<TModularSmartAccount>
) => Promise<PreparePermissionResponse>
/**
* Creates multiple sessions for a modular smart account. This differs from grantPermission in that it
* Creates multiple sessions for a modular smart account. This differs from grantDeferredPermission in that it
* grants the permission on chain immediately. It is also known as "USE_MODE", and it means that the permission
* is granted on chain immediately, and the permission is later redeemed when the user operation is sent.
*
* @param args - Parameters for creating sessions.
* @returns A promise that resolves to the creation response.
*/
grantPermissionInAdvance: (
args: GrantPermissionInAdvanceParameters<TModularSmartAccount>
) => Promise<GrantPermissionInAdvanceResponse>
grantPermission: (
args: GrantPermissionParameters<TModularSmartAccount>
) => Promise<GrantPermissionResponse>

/**
* Trusts attesters for a modular smart account.
Expand Down Expand Up @@ -101,9 +101,8 @@ export function smartSessionCreateActions(_: Module) {
client: Client<Transport, Chain | undefined, TModularSmartAccount>
): SmartSessionCreateActions<TModularSmartAccount> => {
return {
grantDeferredPermission: (args) => grantDeferredPermission(client, args),
grantPermission: (args) => grantPermission(client, args),
grantPermissionInAdvance: (args) =>
grantPermissionInAdvance(client, args),
trustAttesters: (args) => trustAttesters(client, args),
preparePermission: (args) => preparePermission(client, args)
}
Expand All @@ -129,7 +128,7 @@ export function smartSessionUseActions(
}
}

export * from "./grantPermission"
export * from "./trustAttesters"
export * from "./usePermission"
export * from "./grantPermissionInAdvance.js"
export * from "./grantDeferredPermission"
export * from "./grantPermission"
Loading

0 comments on commit 6d5a087

Please sign in to comment.