Skip to content

Commit 6f6ae4f

Browse files
committed
Add sessions to manager
1 parent 09e3efc commit 6f6ae4f

6 files changed

Lines changed: 160 additions & 64 deletions

File tree

packages/core/src/signers/session-manager.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { State } from '..'
1313

1414
type SessionManagerConfiguration = {
1515
topology: SessionConfig.SessionsTopology
16-
provider: Provider.Provider
16+
provider?: Provider.Provider
1717
implicitSigners?: Implicit[]
1818
explicitSigners?: Explicit[]
1919
address?: Address.Address
@@ -22,7 +22,7 @@ type SessionManagerConfiguration = {
2222
export class SessionManager implements SapientSigner {
2323
private readonly _address: Address.Address
2424
private readonly _topology: SessionConfig.SessionsTopology
25-
private readonly _provider: Provider.Provider
25+
private readonly _provider: Provider.Provider | undefined
2626
private readonly _implicitSigners: Implicit[]
2727
private readonly _explicitSigners: Explicit[]
2828

@@ -159,13 +159,17 @@ export class SessionManager implements SapientSigner {
159159
throw new Error('Only calls are supported')
160160
}
161161

162+
if (!this._provider) {
163+
throw new Error('Provider not set')
164+
}
165+
162166
// Try to sign with each signer, prioritizing implicit signers
163167
const signers = [...this._implicitSigners, ...this._explicitSigners]
164168
const signatures = await Promise.all(
165169
//FIXME Run sync to support cumulative rules within a payload
166170
payload.calls.map(async (call) => {
167171
for (const signer of signers) {
168-
if (await signer.supportedCall(wallet, chainId, call, this._provider)) {
172+
if (this._provider && (await signer.supportedCall(wallet, chainId, call, this._provider))) {
169173
const signature = await signer.signCall(wallet, chainId, call, payload, this._provider)
170174
return {
171175
...signature,
@@ -202,6 +206,11 @@ export class SessionManager implements SapientSigner {
202206
// Only calls are supported
203207
return false
204208
}
209+
210+
if (!this._provider) {
211+
throw new Error('Provider not set')
212+
}
213+
205214
const encodedPayload = Payload.encodeSapient(chainId, payload)
206215
const encodedCallData = AbiFunction.encodeData(Constants.RECOVER_SAPIENT_SIGNATURE, [
207216
encodedPayload,

packages/wdk/src/sequence/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Network } from '@0xsequence/sequence-primitives'
22

33
export * from './manager'
4+
export * from './sessions'
45
export * from './signatures'
56
export * from './wallets'
67
export * from './types'

packages/wdk/src/sequence/manager.ts

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1+
import { Signers as CoreSigners, Relayer, State } from '@0xsequence/sequence-core'
2+
import { Config, Constants, Context, Extensions, Network, Payload } from '@0xsequence/sequence-primitives'
13
import { Address } from 'ox'
2-
3-
import { Extensions, Context, Config, Constants, Network, Payload } from '@0xsequence/sequence-primitives'
4-
import { Signers as CoreSigners, State, Relayer } from '@0xsequence/sequence-core'
54
import * as Db from '../dbs'
6-
import { Logger } from './logger'
5+
import * as Identity from '../identity'
76
import { Devices } from './devices'
8-
import { CompleteRedirectArgs, LoginArgs, SignupArgs, StartSignUpWithRedirectArgs, Wallets } from './wallets'
9-
import { Transactions } from './transactions'
10-
import { Signatures } from './signatures'
11-
import { Kinds, Signers } from './signers'
127
import { DevicesHandler, Handler, PasskeysHandler } from './handlers'
8+
import { AuthCodePkceHandler } from './handlers/authcode-pkce'
139
import { MnemonicHandler } from './handlers/mnemonic'
14-
import { RelayerOption, TransactionRequest, Transaction } from './types/transactionRequest'
15-
import { BaseSignatureRequest, SignatureRequest, Wallet } from './types'
1610
import { OtpHandler } from './handlers/otp'
17-
import { AuthCodePkceHandler } from './handlers/authcode-pkce'
18-
import * as Identity from '../identity'
11+
import { Logger } from './logger'
12+
import { Sessions } from './sessions'
13+
import { Signatures } from './signatures'
14+
import { Kinds, Signers } from './signers'
15+
import { Transactions } from './transactions'
16+
import { BaseSignatureRequest, SignatureRequest, Wallet } from './types'
17+
import { Transaction, TransactionRequest } from './types/transactionRequest'
18+
import { CompleteRedirectArgs, LoginArgs, SignupArgs, StartSignUpWithRedirectArgs, Wallets } from './wallets'
1919

2020
export type ManagerOptions = {
2121
verbose?: boolean
@@ -60,6 +60,13 @@ export const ManagerOptionsDefaults = {
6060
address: '0xf71eC72C8C03a0857DD7601ACeF1e42b85983e99',
6161
weight: 1n,
6262
} as Config.SignerLeaf,
63+
64+
defaultSessionTopology: {
65+
// TODO: Move this somewhere else
66+
type: 'sapient-signer',
67+
address: Constants.DefaultSessionManager,
68+
weight: 1n,
69+
} as Omit<Config.SapientSignerLeaf, 'imageHash'>,
6370
}
6471

6572
export const CreateWalletOptionsDefaults = {
@@ -89,12 +96,14 @@ export type Sequence = {
8996
readonly relayers: Relayer.Relayer[]
9097

9198
readonly defaultGuardTopology: Config.Topology
99+
readonly defaultSessionTopology: Omit<Config.SapientSignerLeaf, 'imageHash'>
92100
}
93101

94102
export type Modules = {
95103
readonly logger: Logger
96104
readonly devices: Devices
97105
readonly wallets: Wallets
106+
readonly sessions: Sessions
98107
readonly signers: Signers
99108
readonly signatures: Signatures
100109
readonly transactions: Transactions
@@ -135,6 +144,7 @@ export class Manager {
135144
relayers: ops.relayers,
136145

137146
defaultGuardTopology: ops.defaultGuardTopology,
147+
defaultSessionTopology: ops.defaultSessionTopology,
138148
},
139149

140150
databases: {
@@ -153,6 +163,7 @@ export class Manager {
153163
logger: new Logger(shared),
154164
devices: new Devices(shared),
155165
wallets: new Wallets(shared),
166+
sessions: new Sessions(shared),
156167
signers: new Signers(shared),
157168
signatures: new Signatures(shared),
158169
transactions: new Transactions(shared),
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { Wallet } from '@0xsequence/sequence-core'
2+
import { Config, Constants } from '@0xsequence/sequence-primitives'
3+
import { Address, Provider, RpcTransport } from 'ox'
4+
import { SessionController } from '../session'
5+
import { Shared } from './manager'
6+
7+
export class Sessions {
8+
constructor(private readonly shared: Shared) {}
9+
10+
async controllerForWallet(address: Address.Address, chainId?: bigint) {
11+
// Find the session configuration for the wallet
12+
const wallet = new Wallet(address, {
13+
context: this.shared.sequence.context,
14+
stateProvider: this.shared.sequence.stateProvider,
15+
guest: this.shared.sequence.guest,
16+
})
17+
const status = await wallet.getStatus()
18+
const walletConfig = status.configuration
19+
const sessionConfigLeaf = Config.findSignerLeaf(walletConfig, Constants.DefaultSessionManager)
20+
if (!sessionConfigLeaf || !Config.isSapientSignerLeaf(sessionConfigLeaf)) {
21+
throw new Error(`Session module not found for wallet ${address}`)
22+
}
23+
24+
// Get the provider if available
25+
let provider: Provider.Provider | undefined
26+
if (chainId) {
27+
const network = this.shared.sequence.networks.find((network) => network.chainId === chainId)
28+
if (network) {
29+
provider = Provider.from(RpcTransport.fromHttp(network.rpc))
30+
}
31+
}
32+
33+
// Create the controller
34+
const controller = SessionController.createFromStorage(sessionConfigLeaf.imageHash, {
35+
wallet,
36+
provider,
37+
})
38+
return controller
39+
}
40+
}

packages/wdk/src/sequence/wallets.ts

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1+
import { Wallet as CoreWallet, Envelope, Signers, State } from '@0xsequence/sequence-core'
2+
import { Config, GenericTree, Payload, SessionConfig } from '@0xsequence/sequence-primitives'
13
import { Address, Hex } from 'ox'
2-
import { Envelope, Signers, Wallet as CoreWallet, State } from '@0xsequence/sequence-core'
3-
import { Config, Payload } from '@0xsequence/sequence-primitives'
4-
import { Kinds, WitnessExtraSignerKind } from './signers'
5-
import { Shared } from './manager'
4+
import { AuthCommitment } from '../dbs/auth-commitments'
5+
import { AuthCodePkceHandler } from './handlers/authcode-pkce'
66
import { MnemonicHandler } from './handlers/mnemonic'
77
import { OtpHandler } from './handlers/otp'
8+
import { Shared } from './manager'
9+
import { Kinds, WitnessExtraSignerKind } from './signers'
810
import { Wallet } from './types'
9-
import { AuthCodePkceHandler } from './handlers/authcode-pkce'
10-
import { AuthCommitment } from '../dbs/auth-commitments'
1111

1212
export type StartSignUpWithRedirectArgs = {
1313
kind: 'google-pkce' | 'apple-pkce'
@@ -17,6 +17,7 @@ export type StartSignUpWithRedirectArgs = {
1717

1818
export type CommonSignupArgs = {
1919
noGuard?: boolean
20+
noSessionManager?: boolean
2021
onExistingWallets?: (wallets: Address.Address[]) => Promise<boolean>
2122
}
2223

@@ -350,13 +351,13 @@ export class Wallets {
350351
}
351352

352353
// Build the login tree
354+
const loginSignerAddress = await loginSigner.signer.address
353355
const loginTopology = buildCappedTree([
354356
{
355-
address: await loginSigner.signer.address,
357+
address: loginSignerAddress,
356358
imageHash: Signers.isSapientSigner(loginSigner.signer) ? await loginSigner.signer.imageHash : undefined,
357359
},
358360
])
359-
360361
const devicesTopology = buildCappedTree([{ address: device.address }])
361362
const guardTopology = args.noGuard
362363
? undefined
@@ -365,11 +366,24 @@ export class Wallets {
365366
// TODO: Add recovery module
366367
// TODO: Add smart sessions module
367368
// Placeholder
368-
const modules = {
369+
let modules: Config.Topology = {
369370
type: 'signer',
370371
address: '0x0000000000000000000000000000000000000000',
371372
weight: 0n,
372-
} as Config.SignerLeaf
373+
}
374+
if (!args.noSessionManager) {
375+
// FIXME: Calculate image hash with the identity signer
376+
const sessionManagerTopology = SessionConfig.emptySessionsTopology(loginSignerAddress)
377+
const sessionConfigTree = SessionConfig.sessionsTopologyToConfigurationTree(sessionManagerTopology)
378+
const sessionImageHash = GenericTree.hash(sessionConfigTree)
379+
modules = [
380+
{
381+
...this.shared.sequence.defaultSessionTopology,
382+
imageHash: sessionImageHash,
383+
},
384+
modules,
385+
]
386+
}
373387

374388
// Create initial configuration
375389
const initialConfiguration = toConfig(0n, loginTopology, devicesTopology, modules, guardTopology)

0 commit comments

Comments
 (0)