The Ara Filesystem, standalone and secure filesystems backed by Ara identities.
[Stability][stability-index]: 2 - Stable. Stable. Compatibility with the npm ecosystem is a high priority.
Although the API is stable, this project is still in alpha development and is not yet ready to be used in a production environment.
$ npm install ara-filesystem --save
Important: Each CLI command that makes changes to the AFS requires the password of the owner identity (the one created with
aid create
). Do not forget this password, as it's the only way to update the AFS.
Run the create command with a valid owner identity.
$ afs create did:ara:df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9
Store the mnemonic phrase in a safe place as it is the only recovery mechanism for your AFS.
Note: The
did:ara:
prefix is optional for all commands.
Adding files and/or directories can be done with the add
command.
$ afs add <did> <pathspec...>
Example:
$ afs add df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9 my_video.mp4
$ afs remove <did> <pathspec...>
Example:
$ afs remove df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9 my_video.mp4
A .afsignore
file can be used to specify any files or directories to ignore when adding to an AFS. Only a .afsignore
file located at the directory where the afs
command is run will be honored.
Each line in afsignore
specifies a pattern, similar to .npmignore
and .gitignore
files:
- Blank lines or lines starting with # are ignored.
- Standard glob patterns work.
- You can end patterns with a forward slash / to specify a directory.
- You can negate a pattern by starting it with an exclamation point !.
By default, .afs/
and .afsignore
are ignored.
An example .afsignore
file (taken from the .gitignore
link above):
# ignore all .a files
*.a
# but do track lib.a, even though you're ignoring .a files above
!lib.a
# only ignore the TODO file in the current directory, not subdir/TODO
/TODO
# ignore all files in any directory named build
build/
# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt
# ignore all .pdf files in the doc/ directory and any of its subdirectories
doc/**/*.pdf
Before you can commit to an AFS, a proxy contract representing that AFS must be deployed to the network.
$ afs deploy df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9
Every change in the AFS saved to a local file on disc, much like staged commits. Changes must be commited before they are discoverable and published to the Ara network.
$ afs commit df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9
Set the price of an AFS by passing in an AFS identity and price in ara tokens. For example, this sets the price of the AFS to 10 ara tokens:
$ afs set-price df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9 10
To verify set price:
$ afs get-price df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9
All transaction callbacks (
onhash
,onreceipt
,onconfirmation
,onerror
, andonmined
) are optional. For more information, seeara-util
andara-contracts
.
- async create(opts)
- async destroy(opts)
- async add(opts)
- async remove(opts)
- async deploy(opts)
- async commit(opts)
- async setPrice(opts)
- async getPrice(opts)
- async unarchive(opts)
- async isUpdateAvailable(opts)
- async metadata.writeFile(opts)
- async metadata.writeKey(opts)
- async metadata.writeKeys(opts)
- async metadata.readKey(opts)
- async metadata.delKey(opts)
- async metadata.clear(opts)
- async metadata.readFile(opts)
- async ownership.estimateRequestGasCost(opts)
- async ownership.estimateRevokeGasCost(opts)
- async ownership.estimateApproveGasCost(ops)
- async ownership.request(opts)
- async ownership.revokeRequest(opts)
- async ownership.approveTransfer(opts)
- async ownership.claim(opts)
If owner
is given, this function will create a new AFS with the owning identity owner
. If did
is given, it attempts to get a reference to a previously created AFS.
opts
did
- TheDID
of an existingAFS
owner
-DID
of the owner of theAFS
to be createdpassword
- The password of theowner
of thisAFS
; this is only required for writing to theAFS
.afsPassword
- The password of theAFS
; this is only required for writing to theAFS
.storage
- Optional storage function to use for theAFS
keyringOpts
- Optional keyring options
Returns the AFS
object
.
To create a new AFS
:
const aid = require('ara-identity')
const { create } = require('ara-filesystem')
const identity = await aid.create({ context, password })
await writeIdentity(identity)
const { publicKey: owner } = identity
const { afs } = await create({ owner, password, afsPassword })
To obtain a reference to an existing AFS
:
const did = did:ara:df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9
const { afs } = await create({ did })
Note: Either
did
orowner
is required, but not both.
Destroys the local copy of an AFS
and unlists it from the blockchain (if owner), effectively removing it from the Ara network.
opts
did
- TheDID
of theAFS
to be destroyedpassword
- The password of the owner of thisAFS
afsPassword
- The password of theAFS
mnemonic
- The mnemonic for thisAFS
keyringOpts
- Optional keyring options
If an estimate, returns the cost
(in ETH), otherwise returns the transaction receipt.
const { create, destroy } = require('ara-filesystem')
const { afs, mnemonic } = await create({ owner, password, afsPassword })
const { did } = afs
await destroy({
did,
mnemonic,
password,
afsPassword
})
Adds one or more files to an existing AFS
.
opts
did
- TheDID
of theAFS
to add files topassword
- The password of theAFS
force
- Force add the path(s)paths
- The path(s) of the files to addkeyringOpts
- Optional keyring options
Returns the AFS
object
.
const { create, add } = require('ara-filesystem')
let { afs } = await create({ owner, password })
const { did } = afs
const paths = ['./index.js', './add.js', './picture.png']
afs = await add({
did,
paths,
password
})
Removes one or more files from an AFS
.
opts
did
- TheDID
of theAFS
where the files are locatedpassword
- The password of theAFS
paths
- The path(s) of the files to removekeyringOpts
- Optional keyring options
Returns the AFS
object
.
const { remove } = require('ara-filesystem')
const afs = await remove({
did,
paths,
password
})
Deploys an AFS proxy to the network. Returns the Ethereum address of the deploy contract (if not an estimation).
opts
did
-DID
of theAFS
to deploypassword
- Owner's password for thisAFS
afsPassword
- The password of theAFS
estimate
- Optional flag to check cost ofdeploy
gasPrice
- Optional gas price in GWeikeyringOpts
- Optional keyring optionsonhash
onreceipt
onconfirmation
onerror
onmined
If an estimate, returns the cost
(in ETH), otherwise returns the Ethereum address where the contract was deployed.
const { deploy } = require('ara-filesystem')
const address = await deploy({
afsPassword,
password,
did
})
// estimate deploy
const cost = await deploy({
estimate: true,
afsPassword,
password,
did
})
Commits any changes to an AFS
to the blockchain. Calling deploy
is required before any commits can occur.
opts
did
- TheDID
of theAFS
to commitpassword
- The password of the owner of thisAFS
afsPassword
- The password of theAFS
estimate
- Optional flag to check cost ofcommit
estimateDid
- OptionalDID
of a proxy which points to an estimate version of an AFS Standard (used for estimating cost withoutdeploy
first)price
- Optional price in Ara tokens to set thisAFS
gasPrice
- Optional gas price in GWeikeyringOpts
- Optional keyring optionswriteCallbacks
- Optional callbacks for the Write transactiononhash
onreceipt
onconfirmation
onerror
onmined
priceCallbacks
- Optional callbacks for the Price transactiononhash
onreceipt
onconfirmation
onerror
onmined
If an estimate, returns the cost
(in ETH), otherwise returns the transaction receipt.
const { commit } = require('ara-filesystem')
const result = await commit({
afsPassword,
password,
price,
did
})
// estimate commit cost
const cost = await commit({
estimate: true,
afsPassword,
password,
price,
did
})
Sets the price in Ara tokens of an AFS
.
opts
did
- TheDID
of theAFS
to set the price ofpassword
- The password of the owner of thisAFS
afsPassword
- The password of theAFS
price
- The price (in Ara) to purchase thisAFS
estimate
- Optional flag to check cost ofsetPrice
estimateDid
- OptionalDID
of a proxy which points to an estimate version of an AFS Standard (used for estimating cost withoutdeploy
first)gasPrice
- Optional gas price in GWeikeyringOpts
- Optional keyring optionsonhash
onreceipt
onconfirmation
onerror
onmined
If an estimate, returns the cost
(in ETH), otherwise returns the transaction receipt.
const { setPrice } = require('ara-filesystem')
const price = 10
await setPrice({
afsPassword,
password,
price,
did
})
// estimate set price cost
const cost = await setPrice({
estimate: true,
afsPassword
password,
price,
did
})
Gets the price in Ara tokens of an AFS
.
opts
did
- TheDID
of theAFS
to get the price of
If an estimate, returns the cost
(in ETH) as a string
.
const { getPrice } = require('ara-filesystem')
const price = await getPrice({ did })
Stability: 2 Stable
Unarchives (unzips) an AFS
to a specified location.
opts
did
- TheDID
of theAFS
to unarchivepath
- Optional path to theAFS
keyringOpts
- Optional keyring options
const { unarchive } = require('ara-filesystem')
await unarchive({
did,
path
})
Compares local AFS
version to what has been published. Returns true
if the published AFS
version is greater than the local, otherwise false
.
opts
did
- TheDID
of theAFS
to checkkeyringOpts
- Optional keyring options
Returns a boolean
.
const { isUpdateAvailable } = require('ara-filesystem')
const available = await isUpdateAvailable({ did: 'df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9' })
Writes a metadata JSON file to the metadata partition of an AFS
.
opts
did
- TheDID
of theAFS
to write topassword
- The password of the owner of thisAFS
afsPassword
- The password of theAFS
filepath
- The path of the metadata JSON file to copykeyringOpts
- Optional keyring options
Returns the updated metadata object
.
const { metadata } = require('ara-filesystem')
const result = await metadata.writeFile({
did,
password,
filepath,
afsPassword
})
Writes a metadata key/value pair to the metadata partition of an AFS
.
opts
did
- TheDID
of theAFS
to write topassword
- The password of the owner of thisAFS
afsPassword
- The password of theAFS
key
- The key to writevalue
- The value to writekeyringOpts
- Optional keyring options
Returns the updated metadata object
.
const { metadata } = require('ara-filesystem')
const key = 'foo'
const value = 'bar'
const result = await metadata.writeKey({
did,
key,
value,
password,
afsPassword
})
Writes multiple key/value pairs to the metadata parition of an AFS
.
opts
did
- TheDID
of theAFS
to write topassword
- The password of the owner of thisAFS
afsPassword
- The password of theAFS
keys
- Object containing the key/value pairs to writekeyringOpts
- Optional keyring options
Returns the updated metadata object
.
const { metadata } = require('ara-filesystem')
const keys = { foo: 'bar', hello: 'world' }
await metadata.writeKeys({
did,
keys,
password,
afsPassword
})
Reads a metadata key from the metadata partition of an AFS
.
opts
did
- TheDID
of theAFS
to read fromkey
- The key to write
Returns the value
of the metadata key
.
const { metadata } = require('ara-filesystem')
const result = await metadata.readKey({
did,
key
})
Deletes a metadata key/value pair from the metadata partition of an AFS
.
opts
did
- TheDID
of theAFS
to delete frompassword
- The password of the owner of thisAFS
afsPassword
- The password of theAFS
key
- The key to writekeyringOpts
- Optional keyring options
Returns the updated metadata object
.
const { metadata } = require('ara-filesystem')
await metadata.delKey({
did,
key,
password,
afsPassword
})
Empties all metadata contents of an AFS
.
opts
did
- TheDID
of theAFS
whose metadata is to be emptiedpassword
- The password of the owner of thisAFS
afsPassword
- The password of theAFS
const { metadata } = require('ara-filesystem')
await metadata.clear({ did, password, afsPassword })
Reads all metadata from an AFS
.
opts
did
- TheDID
of theAFS
to read from
Returns the updated metadata object
.
const { metadata } = require('ara-filesystem')
const contents = await metadata.readFile({ did })
Gets the estimated gas cost of requesting ownership of an AFS.
Note: This function takes the same arguments as
ownership.request(opts)
Returns the cost
(in ETH) as a string
.
const { ownership } = require('ara-filesystem')
const cost = await ownership.estimateRequestGasCost(opts) // 0.015 ETH
Gets the estimated gas cost of revoking a previous ownership request.
Note: This function takes the same arguments as
ownership.revokeRequest(opts)
Returns the cost
(in ETH) as a string
.
const { ownership } = require('ara-filesystem')
const cost = await ownership.estimateRevokeGasCost(opts) // 0.015 ETH
Gets the estimated gas cost of approving an ownership request.
Note: This function takes the same arguments as
ownership.approveTransfer(opts)
Returns the cost
(in ETH) as a string
.
const { ownership } = require('ara-filesystem')
const cost = await ownership.estimateApproveGasCost(opts) // 0.015 ETH
Requests the transfer of ownership of an AFS to requesterDid
. Must be approved by the current owner. This transaction will revert if a request is already active.
opts
requesterDid
-DID
of the requestercontentDid
-DID
of the AFS to request ownership forpassword
- password of the requesterestimate
- Optional flag to check cost ofrequest
gasPrice
- Optional gas price in GWeikeyringOpts
- Optional keyring optionsonhash
onreceipt
onconfirmation
onerror
onmined
Returns the transaction receipt as an object
.
const { ownership } = require('ara-filesystem')
const requesterDid = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const password = 'pass'
const contentDid = 'did:ara:114045f3883a21735188bb02de024a4e1451cb96c5dcc80bdfa1b801ecf81b85'
const receipt = await ownership.request({ requesterDid, password, contentDid })
Revokes a previous request for AFS ownership transfer. This transaction will revert if there isn't an active request.
opts
requesterDid
-DID
of the requestercontentDid
-DID
of the AFS to revoke ownership reequest forpassword
- password of the requesterestimate
- Optional flag to check cost ofrevokeRequest
gasPrice
- Optional gas price in GWeikeyringOpts
- Optional keyring optionsonhash
onreceipt
onconfirmation
onerror
onmined
Returns the transaction receipt as an object
.
const { ownership } = require('ara-filesystem')
const requesterDid = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const password = 'pass'
const contentDid = 'did:ara:114045f3883a21735188bb02de024a4e1451cb96c5dcc80bdfa1b801ecf81b85'
const receipt = await ownership.revokeRequest({ requesterDid, password, contentDid })
Approves a pending transfer request, this officially transfers ownership for the given AFS. If not an estimate, this function will return an object containing a random password to be delivered to the identity claiming ownership, along with the transaction receipt.
opts
contentDid
-DID
of the content to change ownership forpassword
- Password of the staged ownerafsPassword
- The password of theAFS
newOwnerDid
-DID
of the owner to transfer ownership tomnemonic
- mnemonic associated with the AFSestimate
- Optional flag to check cost ofapproveTransfer
gasPrice
- Optional gas price in GWeikeyringOpts
- Optional keyring optionsonhash
onreceipt
onconfirmation
onerror
onmined
Returns object
:
receipt
- transaction receiptpassword
- randomly generated password
const { ownership } = require('ara-filesystem')
const contentDid = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const password = 'pass'
const afsPassword = 'password'
const newOwnerDid = 'did:ara:7dc039cfb220029c371d0f4aabf4a956ed0062d66c447df7b4595d7e11187271'
const mnemonic = 'cargo diary bracket crumble stable chief grief grab frost seven wet repeat'
const result = await ownership.approveTransfer({ contentDid, password, afsPassword, newOwnerDid, mnemonic })
Fully claims ownership of an AFS after it has been transferred by the previous owner.
opts
currentPassword
- random password generated from the previous ownernewPassword
- new password for this AFS identitycontentDid
-DID
of the content to claim ownership formnemonic
- mnemonic associated with the AFS to claimkeyringOpts
- Optional keyring options
const { ownership } = require('ara-filesystem')
const contentDid = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const currentPassword = 'generatedPassword'
const newPassword = 'secureNewPassword'
const mnemonic = 'cargo diary bracket crumble stable chief grief grab frost seven wet repeat'
await ownership.claim({
currentPassword,
newPassword,
contentDid,
mnemonic
})
Releases follow Semantic Versioning
LGPL-3.0