Most important functions live on the root.
Low-level functions are available through “sub modules”.
// Important
sdk.initialise()
sdk.redirectToLobby()
// Low Level
sdk.did.local()
sdk.ucan.build()
sdk.fs /* FileSystem class */
sdk.lobby /* Lobby functions such as `createAccount` */
I included an overview of all the functions and modules at the end.
Auth
There’s 3 basic scenarios regarding auth:
- Not authenticated, at some time we redirect to the auth lobby using
sdk.redirectToLobby()
- We got redirected back from the lobby, we have some url params:
a. User authorised the app
b. User did not authorise the app (cancelled) - User authenticated before (auth ucan was stored in cache, which we’ll use now)
// We'll cover the `initialise` arguments later
sdk.initialise( ... ).then((scenario, state) => {
if (scenario.notAuthenticated) {
// state.authenticated = false
} else if (scenario.authSucceeded) {
// state.authenticated = true
// state.throughLobby = true
// state.newUser = true | false
// state.username = ...
// state.fs : FileSystemInstance
// state.app : ScopedFileSystemInstance
} else if (scenario.authCancelled) {
// state.authenticated = false
// state.throughLobby = true
// state.newUser = true | false
// state.cancellationReason = "DENIED"
} else if (scenario.continuum) {
// state.authenticated = true
// state.throughLobby = false
// state.username = ...
// state.fs : FileSystemInstance
// state.app : ScopedFileSystemInstance
}
})
Additional notes:
- We store the UCAN from the authorisation in indexed-db, along with the username. Which is how we detect the
continuum
scenario. - These stored values can be removed via
sdk.deauthenticate()
- Username can be requested separately via
sdk.authenticatedUsername()
Interacting with the file system
Two basic scenarios:
- Use the
app
scoped file system.
Requires app uuid. - Use the unscoped, default, file system instance.
Requires access to specific paths.
(do we create a scoped file-system instance for each granted path? )
// Scenario (1)
const { app } = await sdk.initialise({ app: "my-app-uuid" })
app.private.write("config.json", "{}")
app.private.read("config.json")
app.private.rm()
// Scenario (2)
const { fs } = await sdk.initialise({ paths: [ "private/Music" ] })
const musicList = await fs.ls()
// Failure scenario (invalid combination of arguments)
sdk.initialise().catch( ... )
Important note:
When redirecting to the auth lobby, the sdk will tell the auth lobby to ask for permission to the application-data directories and/or the given paths
.
Additional notes:
- There is private and public application data (hence
app.private
andapp.public
) -
initialise
can fail if not given the proper arguments (or combination of arguments), then you’ll need.catch
ortry {} catch ()
- The user’s data root is updated automatically when a file system change occurs. Don’t know yet how that’s exactly going to work with scoped file system instances, but I don’t imagine that being too difficult.
The file system interaction could most likely be done better, since I don’t know what the hard/soft links interface is going to look like, and how we’re dealing exactly with shared data, etc.
Future
Things to consider in the future:
- Multiple apps
- …
Overview & Types
Functions & Modules
sdk.initialise()
sdk.authenticatedUsername()
sdk.deauthenticate()
sdk.redirectToLobby()
sdk.loadFileSystem() /* Web worker users */
// Config
// • Host your own Fission API and auth lobby
// • Custom IPFS settings
sdk.config.endpoints({ api, lobby, user })
sdk.config.ipfs(jsIpfsSettings)
// Low Level Modules
sdk.did
sdk.fs
sdk.lobby
sdk.ucan
Scenarios
Result from sdk.initialise()
type Scenario = {
notAuthenticated?: true,
authSucceeded?: true,
authCancelled?: true,
continuum?: true,
}
type InitialisationState = NotAuthenticated | AuthSucceeded | AuthCancelled | Continuum
Where Continuum
the interface has the type (AuthSucceeded
is very similar):
type Continuum = {
authenticated: true
throughLobby: false
username: string
fs: FileSystem
app: ScopedAppFileSystem
}
And lastly ScopedAppFileSystem
.
type ScopedAppFileSystem = {
private: ScopedFileSystem,
public: ScopedFileSystem
}
Besides that, ScopedFileSystem
is pretty much the same as a normal file system. Except that for certain methods you can omit the param to target the scope itself. For example, if the scope is private/Apps/Example
, you could do scopedFs.ls()
to list everything in that Example
path.