You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
With libxmtp and MLS, maybe it's time to take first principles look at how client initialization works at XMTP. Given how early we are in adoption on mobile, we should prioritize the needs of the next 100 apps over the migration path for the current handful.
Previous versions of the XMTP SDKs have been stateless. With libxmtp we now have a secure database to store state and key material. That gives us new options.
Because previous versions were stateless, most client applications look something like this simplified pseudocode at initialization:
constexistingKeys=awaitgetKeysFromMyAppDatastore(walletAddress,env);if(existingKeys){returnClient.create(null,{privateKeyOverride: existingKeys, env });}// If there are no existing keys, the app needs to do a bunch of things to get a signer. Maybe ask the user which wallet they use, possibly do a WalletConnect flow, jump to another app to finish the connection.constsigner=awaitgetSigner();// In reality, most implementations return here and will retry the entire flow once the keys are saved.// We call this getKeys in some SDKs or loadOrCreateKeys in others. They all work the same way,// which is that we prompt for 1 or 2 signatures and at the end of the process the keys are both stored// on the network and returned to the caller.constnewKeys=awaitClient.loadOrCreateKeys(signer,{ env });awaitsaveKeysToAppDatastore(newKeys);returnClient.create(null,{privateKeyOverride: newKeys, env });
There's quite a bit of room in the design space for other ideas now that we have a database to play with.
This is important, since the rules are slightly different for libxmtp. Even if a developer provides a privateKeyOverride of V2 keys, there may be a signature required the first time they initialize the SDK in an app.
One alternative model is for the SDK to tell the developer what information is needed. For example:
// This block would only be needed if the application has pre-existing keys stored in their DB that must be migrated. Brand new apps could skip this step altogether.if(Client.needsV2Keys(walletAddress,env)&&awaitgetKeysFromMyAppDatastore(walletAddress,env)){// This would only need to happen one time ever,Client.saveV2Keys(awaitgetKeysFromMyAppDatastore(walletAddress,env),env)}if(Client.needsSignature(walletAddress,env)){// This may still require a whole bunch of hoops for the user to jump throughconstsigner=awaitgetSigner()// saveSignaturesOptions would include things like the preCreateIdentityCallbackClient.saveSignatures(signer,env,saveSignaturesOptions)}returnClient.create(walletAddress,env)
There are a bunch of variations of this idea that might be more ergonomic.
The special case of server-side apps
Server-side apps that act on behalf of a user, such as Chainjet, require special consideration. Today, they typically work by running Client.getKeys(...) in a browser and then uploading those keys to a server so that the application can act on behalf of the user.
With MLS, we have an opportunity to make that more secure since those keys can be revocable. But it's either difficult or impossible for the server-side application to request signatures interactively.
Instead, a more practical model would be to have a new version of Client.getKeys(...) that creates a brand new installation locally, and exports a bundle of V2 and installation keys to the server. Once V2 is phased out completely we can drop the V2 keys from the bundle and just upload installation keys.
The server SDK would then just need a method to do a one-time import of those keys into its local database.
The text was updated successfully, but these errors were encountered:
With
libxmtp
and MLS, maybe it's time to take first principles look at how client initialization works at XMTP. Given how early we are in adoption on mobile, we should prioritize the needs of the next 100 apps over the migration path for the current handful.Previous versions of the XMTP SDKs have been stateless. With
libxmtp
we now have a secure database to store state and key material. That gives us new options.Because previous versions were stateless, most client applications look something like this simplified pseudocode at initialization:
There's quite a bit of room in the design space for other ideas now that we have a database to play with.
This is important, since the rules are slightly different for
libxmtp
. Even if a developer provides aprivateKeyOverride
of V2 keys, there may be a signature required the first time they initialize the SDK in an app.One alternative model is for the SDK to tell the developer what information is needed. For example:
There are a bunch of variations of this idea that might be more ergonomic.
The special case of server-side apps
Server-side apps that act on behalf of a user, such as Chainjet, require special consideration. Today, they typically work by running
Client.getKeys(...)
in a browser and then uploading those keys to a server so that the application can act on behalf of the user.With MLS, we have an opportunity to make that more secure since those keys can be revocable. But it's either difficult or impossible for the server-side application to request signatures interactively.
Instead, a more practical model would be to have a new version of
Client.getKeys(...)
that creates a brand new installation locally, and exports a bundle of V2 and installation keys to the server. Once V2 is phased out completely we can drop the V2 keys from the bundle and just upload installation keys.The server SDK would then just need a method to do a one-time import of those keys into its local database.
The text was updated successfully, but these errors were encountered: