Skip to content

Commit 4ddf8fd

Browse files
authored
Merge pull request #742 from 0xsequence/session-refactor
Use wallets configuration for sessions management
2 parents 1d15e59 + baa1ff2 commit 4ddf8fd

File tree

7 files changed

+89
-249
lines changed

7 files changed

+89
-249
lines changed

packages/wallet/wdk/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
export * as Identity from './identity/index.js'
2-
export * as Session from './session/index.js'
32
export * as Sequence from './sequence/index.js'

packages/wallet/wdk/src/sequence/manager.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,7 @@ export class Manager {
473473
args: AuthorizeImplicitSessionArgs,
474474
): Promise<string> {
475475
return this.shared.modules.sessions.prepareAuthorizeImplicitSession(walletAddress, sessionAddress, args)
476+
// Run completeAuthorizeImplicitSession next
476477
}
477478

478479
public async completeAuthorizeImplicitSession(requestId: string): Promise<{
@@ -488,26 +489,26 @@ export class Manager {
488489
permissions: CoreSigners.Session.ExplicitParams,
489490
): Promise<string> {
490491
return this.shared.modules.sessions.addExplicitSession(walletAddress, sessionAddress, permissions)
492+
// Run completeSessionUpdate next
491493
}
492494

493495
public async removeExplicitSession(walletAddress: Address.Address, sessionAddress: Address.Address): Promise<string> {
494496
return this.shared.modules.sessions.removeExplicitSession(walletAddress, sessionAddress)
497+
// Run completeSessionUpdate next
495498
}
496499

497500
public async addBlacklistAddress(walletAddress: Address.Address, address: Address.Address): Promise<string> {
498501
return this.shared.modules.sessions.addBlacklistAddress(walletAddress, address)
502+
// Run completeSessionUpdate next
499503
}
500504

501505
public async removeBlacklistAddress(walletAddress: Address.Address, address: Address.Address): Promise<string> {
502506
return this.shared.modules.sessions.removeBlacklistAddress(walletAddress, address)
507+
// Run completeSessionUpdate next
503508
}
504509

505510
public async completeSessionUpdate(requestId: string) {
506-
const sigRequest = await this.shared.modules.signatures.get(requestId)
507-
if (sigRequest.action !== 'session-update' || !Payload.isConfigUpdate(sigRequest.envelope.payload)) {
508-
throw new Error('Invalid action')
509-
}
510-
return this.shared.modules.sessions.completeSessionUpdate(sigRequest.wallet, requestId)
511+
return this.shared.modules.sessions.completeSessionUpdate(requestId)
511512
}
512513

513514
// Recovery

packages/wallet/wdk/src/sequence/sessions.ts

Lines changed: 80 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,47 @@
1-
import { Signers as CoreSigners, Envelope, Wallet } from '@0xsequence/wallet-core'
1+
import { Signers as CoreSigners, Envelope } from '@0xsequence/wallet-core'
22
import {
33
Attestation,
4+
Config,
5+
Constants,
6+
GenericTree,
47
Payload,
5-
SessionConfig,
68
Signature as SequenceSignature,
7-
Config,
9+
SessionConfig,
810
} from '@0xsequence/wallet-primitives'
9-
import { Address, Bytes, Hex, Provider, RpcTransport } from 'ox'
10-
import { SessionController } from '../session/index.js'
11-
import { IdentityHandler, identityTypeToHex } from './handlers/identity.js'
12-
import { Shared } from './manager.js'
13-
import { AuthCodePkceHandler } from './handlers/authcode-pkce.js'
11+
import { Address, Bytes, Hex } from 'ox'
1412
import { IdentityType } from '../identity/index.js'
13+
import { AuthCodePkceHandler } from './handlers/authcode-pkce.js'
14+
import { IdentityHandler, identityTypeToHex } from './handlers/identity.js'
15+
import { ManagerOptionsDefaults, Shared } from './manager.js'
16+
import { Actions } from './types/signature-request.js'
1517

1618
export type AuthorizeImplicitSessionArgs = {
1719
target: string
1820
applicationData?: Hex.Hex
1921
}
2022

21-
export class Sessions {
22-
private readonly _sessionControllers: Map<Address.Address, SessionController> = new Map()
23+
const DefaultSessionManagerAddresses = [Constants.DefaultSessionManager]
2324

24-
constructor(private readonly shared: Shared) {}
25-
26-
getCoreWallet(walletAddress: Address.Address): Wallet {
27-
return new Wallet(walletAddress, {
28-
context: this.shared.sequence.context,
29-
guest: this.shared.sequence.guest,
30-
stateProvider: this.shared.sequence.stateProvider,
31-
})
32-
}
25+
export class Sessions {
26+
constructor(
27+
private readonly shared: Shared,
28+
private readonly sessionManagerAddresses: Address.Address[] = DefaultSessionManagerAddresses,
29+
) {}
3330

34-
async getControllerForWallet(walletAddress: Address.Address, chainId?: bigint): Promise<SessionController> {
35-
if (this._sessionControllers.has(walletAddress)) {
36-
return this._sessionControllers.get(walletAddress)!
31+
async getSessionTopology(walletAddress: Address.Address): Promise<SessionConfig.SessionsTopology> {
32+
const { modules } = await this.shared.modules.wallets.getConfigurationParts(walletAddress)
33+
const managerLeaf = modules.find((leaf) =>
34+
this.sessionManagerAddresses.some((addr) => Address.isEqual(addr, leaf.address)),
35+
)
36+
if (!managerLeaf) {
37+
throw new Error('Session manager not found')
3738
}
38-
39-
// Construct the wallet
40-
const wallet = this.getCoreWallet(walletAddress)
41-
42-
// Get the provider if available
43-
let provider: Provider.Provider | undefined
44-
if (chainId) {
45-
const network = this.shared.sequence.networks.find((network) => network.chainId === chainId)
46-
if (network) {
47-
provider = Provider.from(RpcTransport.fromHttp(network.rpc))
48-
}
39+
const imageHash = managerLeaf.imageHash
40+
const tree = await this.shared.sequence.stateProvider.getTree(imageHash)
41+
if (!tree) {
42+
throw new Error('Session topology not found')
4943
}
50-
51-
// Create the controller
52-
const controller = new SessionController({
53-
wallet,
54-
provider,
55-
stateProvider: this.shared.sequence.stateProvider,
56-
})
57-
this._sessionControllers.set(walletAddress, controller)
58-
return controller
59-
}
60-
61-
async getSessionTopology(walletAddress: Address.Address): Promise<SessionConfig.SessionsTopology> {
62-
const controller = await this.getControllerForWallet(walletAddress)
63-
return controller.getTopology()
44+
return SessionConfig.configurationTreeToSessionsTopology(tree)
6445
}
6546

6647
async prepareAuthorizeImplicitSession(
@@ -171,59 +152,89 @@ export class Sessions {
171152
permissions: CoreSigners.Session.ExplicitParams,
172153
origin?: string,
173154
): Promise<string> {
174-
const controller = await this.getControllerForWallet(walletAddress)
175-
const envelope = await controller.addExplicitSession(sessionAddress, permissions)
176-
return this.prepareSessionUpdate(envelope, origin)
155+
const topology = await this.getSessionTopology(walletAddress)
156+
const newTopology = SessionConfig.addExplicitSession(topology, {
157+
...permissions,
158+
signer: sessionAddress,
159+
})
160+
return this.prepareSessionUpdate(walletAddress, newTopology, origin)
177161
}
178162

179163
async removeExplicitSession(
180164
walletAddress: Address.Address,
181165
sessionAddress: Address.Address,
182166
origin?: string,
183167
): Promise<string> {
184-
const controller = await this.getControllerForWallet(walletAddress)
185-
const envelope = await controller.removeExplicitSession(sessionAddress)
186-
return this.prepareSessionUpdate(envelope, origin)
168+
const topology = await this.getSessionTopology(walletAddress)
169+
const newTopology = SessionConfig.removeExplicitSession(topology, sessionAddress)
170+
if (!newTopology) {
171+
throw new Error('Session not found')
172+
}
173+
return this.prepareSessionUpdate(walletAddress, newTopology, origin)
187174
}
188175

189176
async addBlacklistAddress(
190177
walletAddress: Address.Address,
191178
address: Address.Address,
192179
origin?: string,
193180
): Promise<string> {
194-
const controller = await this.getControllerForWallet(walletAddress)
195-
const envelope = await controller.addBlacklistAddress(address)
196-
return this.prepareSessionUpdate(envelope, origin)
181+
const topology = await this.getSessionTopology(walletAddress)
182+
const newTopology = SessionConfig.addToImplicitBlacklist(topology, address)
183+
return this.prepareSessionUpdate(walletAddress, newTopology, origin)
197184
}
198185

199186
async removeBlacklistAddress(
200187
walletAddress: Address.Address,
201188
address: Address.Address,
202189
origin?: string,
203190
): Promise<string> {
204-
const controller = await this.getControllerForWallet(walletAddress)
205-
const envelope = await controller.removeBlacklistAddress(address)
206-
return this.prepareSessionUpdate(envelope, origin)
191+
const topology = await this.getSessionTopology(walletAddress)
192+
const newTopology = SessionConfig.removeFromImplicitBlacklist(topology, address)
193+
return this.prepareSessionUpdate(walletAddress, newTopology, origin)
207194
}
208195

209196
private async prepareSessionUpdate(
210-
envelope: Envelope.Envelope<Payload.ConfigUpdate>,
197+
walletAddress: Address.Address,
198+
topology: SessionConfig.SessionsTopology,
211199
origin: string = 'wallet-webapp',
212200
): Promise<string> {
213-
return await this.shared.modules.signatures.request(envelope, 'session-update', {
201+
// Store the new configuration
202+
const tree = SessionConfig.sessionsTopologyToConfigurationTree(topology)
203+
await this.shared.sequence.stateProvider.saveTree(tree)
204+
const newImageHash = GenericTree.hash(tree)
205+
206+
// Find the session manager in the old configuration
207+
const { modules } = await this.shared.modules.wallets.getConfigurationParts(walletAddress)
208+
const managerLeaf = modules.find((leaf) =>
209+
this.sessionManagerAddresses.some((addr) => Address.isEqual(addr, leaf.address)),
210+
)
211+
if (!managerLeaf) {
212+
// Missing. Add it
213+
modules.push({
214+
...ManagerOptionsDefaults.defaultSessionsTopology,
215+
imageHash: newImageHash,
216+
})
217+
} else {
218+
// Update the configuration to use the new session manager image hash
219+
managerLeaf.imageHash = newImageHash
220+
}
221+
222+
return this.shared.modules.wallets.requestConfigurationUpdate(
223+
walletAddress,
224+
{
225+
modules,
226+
},
227+
Actions.SessionUpdate,
214228
origin,
215-
})
229+
)
216230
}
217231

218-
async completeSessionUpdate(walletAddress: Address.Address, requestId: string) {
219-
const controller = await this.getControllerForWallet(walletAddress)
232+
async completeSessionUpdate(requestId: string) {
220233
const sigRequest = await this.shared.modules.signatures.get(requestId)
221-
const envelope = sigRequest.envelope
222-
if (sigRequest.action !== 'session-update' || !Payload.isConfigUpdate(envelope.payload)) {
234+
if (sigRequest.action !== 'session-update' || !Payload.isConfigUpdate(sigRequest.envelope.payload)) {
223235
throw new Error('Invalid action')
224236
}
225-
console.log('Completing session update:', requestId)
226-
await controller.completeUpdateConfiguration(envelope as Envelope.Signed<Payload.ConfigUpdate>)
227-
return this.shared.modules.signatures.complete(requestId)
237+
238+
return this.shared.modules.wallets.completeConfigurationUpdate(requestId)
228239
}
229240
}

packages/wallet/wdk/src/sequence/wallets.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
import { Wallet as CoreWallet, Envelope, Signers, State } from '@0xsequence/wallet-core'
2-
import { Config, Extensions, GenericTree, Payload, SessionConfig } from '@0xsequence/wallet-primitives'
2+
import { Config, GenericTree, Payload, SessionConfig } from '@0xsequence/wallet-primitives'
33
import { Address, Hex, Provider, RpcTransport } from 'ox'
44
import { AuthCommitment } from '../dbs/auth-commitments.js'
55
import { AuthCodePkceHandler } from './handlers/authcode-pkce.js'
66
import { MnemonicHandler } from './handlers/mnemonic.js'
77
import { OtpHandler } from './handlers/otp.js'
88
import { Shared } from './manager.js'
9-
import { Wallet } from './types/wallet.js'
10-
import { Kinds, RecoverySigner, WitnessExtraSignerKind } from './types/signer.js'
11-
import { WalletSelectionUiHandler } from './types/wallet.js'
129
import { Action } from './types/index.js'
10+
import { Kinds, WitnessExtraSignerKind } from './types/signer.js'
11+
import { Wallet, WalletSelectionUiHandler } from './types/wallet.js'
1312

1413
export type StartSignUpWithRedirectArgs = {
1514
kind: 'google-pkce' | 'apple-pkce'

packages/wallet/wdk/src/session/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)