1- import { Wallet } from '@0xsequence/sequence-core'
2- import { Config , Constants } from '@0xsequence/sequence-primitives'
1+ import { Signers as CoreSigners , Envelope , Wallet } from '@0xsequence/sequence-core'
2+ import { Config , Constants , Payload , SessionConfig } from '@0xsequence/sequence-primitives'
33import { Address , Provider , RpcTransport } from 'ox'
44import { SessionController } from '../session'
55import { Shared } from './manager'
66
77export class Sessions {
8+ private readonly _sessionControllers : Map < Address . Address , SessionController > = new Map ( )
9+
810 constructor ( private readonly shared : Shared ) { }
911
10- async controllerForWallet ( address : Address . Address , chainId ?: bigint ) {
12+ async getControllerForWallet ( walletAddress : Address . Address , chainId ?: bigint ) : Promise < SessionController > {
13+ if ( this . _sessionControllers . has ( walletAddress ) ) {
14+ return this . _sessionControllers . get ( walletAddress ) !
15+ }
16+
17+ //FIXME How do we check the wallet is available? Is it necessary?
1118 // Find the session configuration for the wallet
12- const wallet = new Wallet ( address , {
19+ const wallet = new Wallet ( walletAddress , {
1320 context : this . shared . sequence . context ,
1421 stateProvider : this . shared . sequence . stateProvider ,
1522 guest : this . shared . sequence . guest ,
1623 } )
17- const status = await wallet . getStatus ( )
18- const walletConfig = status . configuration
19- const sessionConfigLeaf = Config . findSignerLeaf ( walletConfig , Constants . DefaultSessionManager )
24+ const { configuration } = await wallet . getStatus ( )
25+ const sessionConfigLeaf = Config . findSignerLeaf ( configuration , Constants . DefaultSessionManager )
2026 if ( ! sessionConfigLeaf || ! Config . isSapientSignerLeaf ( sessionConfigLeaf ) ) {
21- throw new Error ( `Session module not found for wallet ${ address } ` )
27+ throw new Error ( `Session module not found for wallet ${ walletAddress } ` )
2228 }
2329
2430 // Get the provider if available
@@ -31,10 +37,80 @@ export class Sessions {
3137 }
3238
3339 // Create the controller
34- const controller = SessionController . createFromStorage ( sessionConfigLeaf . imageHash , {
40+ const controller = await SessionController . createFromStorage ( sessionConfigLeaf . imageHash , {
3541 wallet,
3642 provider,
43+ stateProvider : this . shared . sequence . stateProvider ,
3744 } )
45+ this . _sessionControllers . set ( walletAddress , controller )
3846 return controller
3947 }
48+
49+ async getSessionTopology ( walletAddress : Address . Address ) : Promise < SessionConfig . SessionsTopology > {
50+ console . log ( 'Getting session topology for:' , walletAddress )
51+ const controller = await this . getControllerForWallet ( walletAddress )
52+ console . log ( 'Session topology:' , controller . topology )
53+ return controller . topology
54+ }
55+
56+ async addImplicitSession ( walletAddress : Address . Address , sessionAddress : Address . Address ) : Promise < string > {
57+ const controller = await this . getControllerForWallet ( walletAddress )
58+ // Create attestation params
59+ //FIXME This is a login request?
60+ // const attestationParams: Attestation.Attestation = {
61+ // approvedSigner: sessionAddress,
62+ // }
63+ // const envelope = await controller.addImplicitSession(sessionAddress)
64+ // return this.shared.modules.signatures.request(envelope, 'config-update', {
65+ // origin: 'session-manager',
66+ // })
67+ throw new Error ( 'Not implemented' )
68+ }
69+
70+ async addExplicitSession (
71+ walletAddress : Address . Address ,
72+ sessionAddress : Address . Address ,
73+ permissions : CoreSigners . Session . ExplicitParams ,
74+ ) : Promise < string > {
75+ const controller = await this . getControllerForWallet ( walletAddress )
76+ const envelope = await controller . addExplicitSession ( sessionAddress , permissions )
77+ return this . prepareSessionUpdate ( envelope )
78+ }
79+
80+ async removeExplicitSession ( walletAddress : Address . Address , sessionAddress : Address . Address ) : Promise < string > {
81+ const controller = await this . getControllerForWallet ( walletAddress )
82+ const envelope = await controller . removeExplicitSession ( sessionAddress )
83+ return this . prepareSessionUpdate ( envelope )
84+ }
85+
86+ async addBlacklistAddress ( walletAddress : Address . Address , address : Address . Address ) : Promise < string > {
87+ const controller = await this . getControllerForWallet ( walletAddress )
88+ const envelope = await controller . addBlacklistAddress ( address )
89+ return this . prepareSessionUpdate ( envelope )
90+ }
91+
92+ async removeBlacklistAddress ( walletAddress : Address . Address , address : Address . Address ) : Promise < string > {
93+ const controller = await this . getControllerForWallet ( walletAddress )
94+ const envelope = await controller . removeBlacklistAddress ( address )
95+ return this . prepareSessionUpdate ( envelope )
96+ }
97+
98+ private async prepareSessionUpdate ( envelope : Envelope . Envelope < Payload . ConfigUpdate > ) : Promise < string > {
99+ const requestId = await this . shared . modules . signatures . request ( envelope , 'session-update' , {
100+ origin : 'wallet-webapp' ,
101+ } )
102+ return requestId
103+ }
104+
105+ async completeSessionUpdate ( walletAddress : Address . Address , requestId : string ) {
106+ const controller = await this . getControllerForWallet ( walletAddress )
107+ const sigRequest = await this . shared . modules . signatures . get ( requestId )
108+ const envelope = sigRequest . envelope
109+ if ( sigRequest . action !== 'session-update' || ! Payload . isConfigUpdate ( envelope . payload ) ) {
110+ throw new Error ( 'Invalid action' )
111+ }
112+ console . log ( 'Completing session update:' , requestId )
113+ await controller . completeUpdateConfiguration ( envelope as Envelope . Signed < Payload . ConfigUpdate > )
114+ return this . shared . modules . signatures . complete ( requestId )
115+ }
40116}
0 commit comments