Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Become a webnative jedi 🧘
Check the webnative version.
Add the following to your code to enable webnative debug logging.
When webnative makes a change to the user's filesystem, it logs:
Next, webnative links the change to make it available across the web.
When linking completes, the change is published and available to other browsers.
While you are testing an app, you may want to force a logout to check the NotAuthorised
authentication state. The wn.leave()
method will log out and completely remove a user from your app. The user will still be authenticated with Fission, and they can sign back into your app to re-authorize.
WNFS comes with three separate top-level file systems "roots": public, pretty, and private.
Not encrypted. Full metadata support. Starts with /public
.
Not encrypted. No metadata. Represented simply as /p
to be nice and short when creating public URLs like /p/path/to/file.img
. It does not support versioning, use the Public or Private trees for that.
Encrypted. Structured so that file metadata as well as contents are obscured. Starts with /private
.
We initialize WNFS with a set of default private folders, which should be familiar to people from working with desktop operating systems.
TODO: We'll be documenting and versioning these default folders in the webnative Github repo.
Additionally, in apps like Drive or in file pickers, the user sees a top level Public folder, which maps to the Public system root
More about roots. Learn more about roots in the Fission whitepaper.
Can I use my file system in a web worker? Yes, this only requires a slightly different setup.
Since the file system may evolve over time, a "version" is associated with each node in the file system (tracked with semver).
Currently two versions exist:
1.0.0
: file tree with metadata. Nodes in the file tree are structured as 2 layers where one layer contains "header" information (metadata, cache, etc), and the second layer contains data or links. This is the default version, use this unless you have a good reason not to.
0.0.0
: legacy bare file tree of an early version.
Customization can be done using the setup
module. Run these before anything else you do with the SDK.
Warning: Here be 🐉! Only use lower level utilities if you know what you're doing.
This library is built on top of js-ipfs and keystore-idb. If you have already integrated an ipfs daemon or keystore-idb into your web application, you probably don't want to have two instances floating around.
You can use one instance for your whole application by doing the following:
Authentication and Authorization with the Webnative SDK
Users authenticate once per browser in the . If the user is new to Fission, they are prompted to sign up. They may also link an existing account from another browser.
Apps redirect users to the Auth Lobby to sign up and request authorization to use resources. Sign-up only happens once, and each subsequent visit from any app is for authorization only.
Auth in webnative looks similar to an OAuth authentication flow but with an important difference. Webnative stores user credentials in the browser, and authentication through a third-party is not necessary. Private credentials are stored as CryptoKey
s to keep them secure. See the of the Fission Whitepaper for more details.
The Auth Lobby grants apps authorization to access WNFS. Apps request permission to use app-specific storage and additional public and private directories. The Auth Lobby creates a User Controlled Authorization Networks (UCAN) token that reflects the requested permissions.
Webnative checks the UCAN at initialization and returns an auth scenario.
AuthSucceded. The user has just returned from the Auth Lobby, and they granted the requested permissions.
Continuation. The user has already granted permission, and the UCAN has not expired.
AuthCancelled. The user denied the requested permissions.
NotAuthorised. The user has not granted permission yet or the UCAN has expired.
UCANs expire and users must periodically re-authorize apps through the Auth Lobby. All user data is preserved in WNFS across authorizations, including the data stored in App Storage.
More on UCANs. Read more about UCANs in our blog post and in the .
One case where logging out is desirable is on a shared device. Logging out on a shared device can be accomplished in two steps:
Remove the UCAN token from apps that were granted permissions with the webnativewn.leave
function
Working with the Webnative File System (WNFS)
The Web Native File System (WNFS) is a file system built on top of the InterPlanetary File System (IPFS). Each Fission user has their own WNFS, and apps store user files and data in it when granted permission.
Each file system has a public tree and a private tree, much like your macOS, Windows, or Linux desktop file system. The public tree is "live" and publicly accessible on the Internet. The private tree is encrypted so that only the owner can see the contents.
All information (links, data, metadata, etc.) in the private tree is encrypted. Decryption keys are stored so that access to a given directory grants access to all of its subdirectories.
WNFS is structured and functions similarly to a Unix-style file system, with one notable exception: it's a Directed Acyclic Graph (DAG), meaning that a given child can have more than one parent (think symlinks but without the "sym").
Every file system action checks if an app has received sufficient permissions from the user. Apps request permissions
when they initialize webnative. The .
Apps request permission for app storage, additional private and public directories, and user apps published with the Platform APIs. For example, a notes app might request these permissions.
The app would have access to its dedicated app storage and public and private Notes directories.
Apps request permissions.app
to store user data in a default app storage directory and other public and private directories. Webnative creates these directories for your app if they do not already exist.
The initialize function will return a NotAuthorised
scenario if one of the UCAN will expire in one day to minimize the likelihood of receiving an expired permissions error. But to be safe, apps should also account for this error.
WNFS exposes a POSIX-style interface:
add
: add a file
cat
: retrieve a file
exists
: check if a file or directory exists
ls
: list a directory
mkdir
: create a directory
mv
: move a file or directory
read
: alias for cat
rm
: remove a file or directory
write
: alias for add
The publish
function synchronizes your file system with the Fission API and IPFS. WNFS does not publish changes automatically because it is more practical to batch changes in some cases. For example, a large data set is better published once than over multiple calls to publish
.
Returns: CID
the updated root CID for the file system.
Remember to publish! If you do not call publish
after making changes, user data will not be persisted to WNFS.
Methods for interacting with the filesystem all use absolute paths.
The FileContent
that WNFS can store includes FileContentRaw
, Blob
, string
, number
, and boolean
. FileContentRaw
is Uint8Array
. In addition, the private file system can store Object
s.
add
Adds file content at a given path.
Params:
path: FilePath
required
content: FileContent
required
Returns: CID
the updated root CID for the file system
Example:
cat
Retrieves some file content at a given path.
Params:
path: FilePath
required
Returns: FileContent
Example:
exists
Checks if there is anything located at a given path.
Params:
path: DistinctivePath
required
Returns: boolean
Example:
get
Retrieves the node at the given path, either a File
or Tree
object
Params:
path: DistinctivePath
required
Returns: Tree | File | null
Example:
ls
Returns a list of links at a given directory path
Params:
path: DirectoryPath
required
Returns: { [name: string]: Link }
Object with the file name as the key and its Link
as the value.
Example:
mkdir
Creates a directory at the given path
Params:
path: DirectoryPath
required
Returns: CID
the updated root CID for the file system
Example:
mv
Move a directory or file from one path to another.
Params:
from: DistinctivePath
required
to: DistinctivePath
required
Returns: CID
the updated root CID for the file system
Example:
rm
Removes a file or directory at a given path.
Params:
path: DistinctivePath
required
Returns: CID
the updated root CID for the file system
Example:
write
Alias for add
.
Params:
path: FilePath
required
content: FileContent
required
Returns: CID
the updated root CID for the file system
Example:
Each file and directory has a history
property, which you can use to get an earlier version of that item. We use the delta
variable as the order index, primarily because the timestamps can be slightly out of sequence due to device inconsistencies.
Requesting many versions with file.history.list
can be slow. The acceptable delay will depend on your application.
The webnative software development kit offers tools for:
Auth. Users make an account and link their account across devices in the .
Storage. The webnative file system (WNFS) stores user data for apps.
UCAN and DID tools for working with UCANs and distributed identities
Platform APIs for interacting with user apps
Versions. This guide is versioned for each version of the CLI/Webnative SDK. See the top left above Overview in the sidebar to select the version of CLI or SDK you are working with. Latest represents all versions newer that last numbered version. We will always add a numbered version when a breaking change occurs.
API documentation and code. Read more in the (or an ) and in the .
Have questions? Come join the or post your question to the . We are here to help!
Migration guides for new versions of the webnative SDK
The way paths are used throughout the webnative and filesystem APIs has changed.
In earlier versions of webnative, API calls expected UNIX style paths.
In webnative 0.24, paths are created by for files and directories.
The docs for the remain available for reference.
The URL for loading webnative from UNPKG has changed. In previous versions, webnative was available as index.umd.js
.
In webnative 0.26, webnative is available as index.min.js
.
The URL for loading webnative from UNPKG has changed. In webnative 0.26.0, webnative was available as index.min.js
.
We found that some projects needed the UMD build and brought it back in webnative 0.26.1. We have replaced index.min.js
with index.umd.min.js
.
The type of App
returned app.index
has changed. Previously, the return type was
In webnative 0.27.0, the the return type is
The domain for the app is now in the domains
array.
The publicReadKey
function in keystore-idb
was renamed topublicExchangeKey
.
Most users will not need to change anything for webnative 0.28.0, unless they are interacting directly with keystore-idb.
No migrations are needed for this version of webnative.
Paths in the Webnative SDK
Webnative uses directory and file paths built from path segments by path functions.
All webnative SDK methods expect paths created by path functions. See the for more path utility functions.
Path Objects. The path functions create objects like { directory: ["public", "some", "directory"] }
or { file: ["public", "some", "file"] }
. We recommend you use path functions because they validate paths to make sure they are well-formed.
Fission Platform APIs
The webnative platform API provides methods to work with the apps associated with users.
The platform API makes it possible to manage user apps and, combined with the webnative filesystem methods, create and manage apps entirely from the browser.
Yes, you can build an app, that creates apps on behalf of the user! This is a way for developers to make use of the Fission Platform to build their own MicroSaaS business, including custom domains and other features for their users.
The API methods are prefixed with apps
.
apps.index
: A list of all of your apps and their associated domain names
apps.create
: Creates a new app, assigns an initial subdomain, and sets an asset placeholder
apps.publish
: Publish a new app version
apps.deleteByDomain
: Destroy an app identified by domain
Apps that use the platform API must request permission to work with a user's apps. Permissions are requested when a user signs in through the Fission Auth Lobby. See the for more on the webnative authentication flow.
Platform API permissions are requested at permissions.platform.apps
in the initialization object.
The value at permissions.platform.apps
can be
"*"
: Grant complete app management access for all of the user's apps
An array of domain names, e.g. [ "an-app.fission.app", "another-app.fission.app" ]
: Grant permission to manage specific apps. Those apps can be published or deleted.
apps.index
Lists all user apps and their associated domain names.
Required permissions: { platform: { apps: "*" } }
full app management permissions
Params: No parameters
Returns: App[]
with the domain names, creation and modification times for each app
Example:
apps.create
Creates a new app, assigns an initial subdomain, and publishes a placeholder site.
Required permissions: { platform: { apps: "*" } }
full app management permissions
Params:
subdomain: string
optional
Returns: { domain: string }
the subdomain of the newly created app
Example:
apps.publish
Publishes a new app version by IPFS CID. If the app does not exist yet, create the app first with apps.create
.
Params:
domain: string
required
cid: string
required
Returns: Nothing returned
Example:
Retrieving the CID depends on where you have staged the app code. One convenient way to do this is to publish the app's HTML, CSS, JavaScript, and assets to a public directory in WNFS and retrieve the CID of that directory.
apps.deleteByDomain
Delete an app by domain.
Params:
url: string
required
Returns: Nothing returned
Example:
Installing the Webnative SDK
You can add the webnative SDK to a project by loading it from a CDN or installing it with a package manager.
For prototyping or experimentation, you can use the latest version of the SDK.
We recommend linking to a specific version in production to avoid unexpected changes.
We recommend installing with a package manager for larger projects that use build tools or bundlers.
Install the SDK with npm
or your preferred package manager.
Import the SDK in your application.
Apps intialize webnative with and permissions. The redirectToLobby
method redirects users to the Auth Lobby, where users grant or deny permission to use their resources. redirectToLobby
takes an optional parameter, a URL that the lobby should redirect back to (the default is location.href
).
In most cases, users will not need to log out of an app or a device. Read more about this part of our vision for Fission-enabled apps in the forum post.
Log out from the Auth Lobby on the reset page ()
Platform permissions. The platform permissions could be left out of this example because this app will not need them. See the for more information on working with user apps.
Paths created by have a FilePath
or DirectoryPath
type. Methods with a DistinctivePath
param accept either a FilePath
or a DirectoryPath
.
Required permissions: Needs either permission for the app domain or full app management permissions. See .
Required permissions: Needs either permission for the app domain or full app management permissions. See .
How to share private data with the Webnative SDK
You can share a private file or directory with another Fission user:
Here you see a photo being shared from Fission Drive and being accepted by another user in the auth lobby.
Private shared data uses public keys, which we call exchange keys, that live in a user's public filesystem under .well-known/exchange/
. Exchange keys are unique per domain because webnative generates a key-pair per domain, so we need to add an exchange key to each domain that will accept shares. We can add an exchange key to a filesystem using:
The auth lobby automatically does this when we create our account, link a device, or authorise an application.
When the receiver of the share has their exchange key(s) set up, we're ready to create a share:
That will do an fs.publish()
and consequently a data root update, so you'll want to wait until those are complete before accepting a share.
The shareDetails
contain a shareId
used to accept or load a share.
By accepting a share, you create a symbolic link (aka. soft link) to the shared data in the /private/Shared with me/SENDER_USERNAME/
directory. In other words, accepting a share is fs.loadShare()
plus copying the soft link from the share:
If you'd like to use the auth lobby to accept, for ease of use like Fission Drive does, then you can create a share link with the share details we got earlier:
When sharing a file or directory with someone, they will receive the updates to those items due to how soft links work. Most filesystem methods work out of the box with soft links, such as get
and cat
. But sometimes, you need to resolve them manually, which you can do with fs.resolveSymlink()
. If you want to create a soft link manually, you can do that with:
⚠️ For now soft links are read-only.