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 --saveImportant: 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:df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9Store 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.mp4A .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 df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9Every 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 df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9Set 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 10To verify set price:
$ afs get-price df45010fee8baf67f91f5102b9562b14d5b49c972a007cd460b1aa77fd90eaf9All transaction callbacks (
onhash,onreceipt,onconfirmation,onerror, andonmined) are optional. For more information, seeara-utilandara-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.
optsdid- TheDIDof an existingAFSowner-DIDof the owner of theAFSto be createdpassword- The password of theownerof 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 theAFSkeyringOpts- 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
didorowneris 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.
optsdid- TheDIDof theAFSto be destroyedpassword- The password of the owner of thisAFSafsPassword- The password of theAFSmnemonic- The mnemonic for thisAFSkeyringOpts- 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.
optsdid- TheDIDof theAFSto add files topassword- The password of theAFSforce- 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.
optsdid- TheDIDof theAFSwhere the files are locatedpassword- The password of theAFSpaths- 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).
optsdid-DIDof theAFSto deploypassword- Owner's password for thisAFSafsPassword- The password of theAFSestimate- Optional flag to check cost ofdeploygasPrice- Optional gas price in GWeikeyringOpts- Optional keyring optionsonhashonreceiptonconfirmationonerroronmined
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.
optsdid- TheDIDof theAFSto commitpassword- The password of the owner of thisAFSafsPassword- The password of theAFSestimate- Optional flag to check cost ofcommitestimateDid- OptionalDIDof a proxy which points to an estimate version of an AFS Standard (used for estimating cost withoutdeployfirst)price- Optional price in Ara tokens to set thisAFSgasPrice- Optional gas price in GWeikeyringOpts- Optional keyring optionswriteCallbacks- Optional callbacks for the Write transactiononhashonreceiptonconfirmationonerroronmined
priceCallbacks- Optional callbacks for the Price transactiononhashonreceiptonconfirmationonerroronmined
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.
optsdid- TheDIDof theAFSto set the price ofpassword- The password of the owner of thisAFSafsPassword- The password of theAFSprice- The price (in Ara) to purchase thisAFSestimate- Optional flag to check cost ofsetPriceestimateDid- OptionalDIDof a proxy which points to an estimate version of an AFS Standard (used for estimating cost withoutdeployfirst)gasPrice- Optional gas price in GWeikeyringOpts- Optional keyring optionsonhashonreceiptonconfirmationonerroronmined
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.
optsdid- TheDIDof theAFSto 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.
optsdid- TheDIDof theAFSto unarchivepath- Optional path to theAFSkeyringOpts- 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.
optsdid- TheDIDof theAFSto 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.
optsdid- TheDIDof theAFSto write topassword- The password of the owner of thisAFSafsPassword- The password of theAFSfilepath- 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.
optsdid- TheDIDof theAFSto write topassword- The password of the owner of thisAFSafsPassword- The password of theAFSkey- 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.
optsdid- TheDIDof theAFSto write topassword- The password of the owner of thisAFSafsPassword- The password of theAFSkeys- 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.
optsdid- TheDIDof theAFSto 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.
optsdid- TheDIDof theAFSto delete frompassword- The password of the owner of thisAFSafsPassword- The password of theAFSkey- 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.
optsdid- TheDIDof theAFSwhose metadata is to be emptiedpassword- The password of the owner of thisAFSafsPassword- The password of theAFS
const { metadata } = require('ara-filesystem')
await metadata.clear({ did, password, afsPassword })Reads all metadata from an AFS.
optsdid- TheDIDof theAFSto 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 ETHGets 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 ETHGets 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 ETHRequests 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.
optsrequesterDid-DIDof the requestercontentDid-DIDof the AFS to request ownership forpassword- password of the requesterestimate- Optional flag to check cost ofrequestgasPrice- Optional gas price in GWeikeyringOpts- Optional keyring optionsonhashonreceiptonconfirmationonerroronmined
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.
optsrequesterDid-DIDof the requestercontentDid-DIDof the AFS to revoke ownership reequest forpassword- password of the requesterestimate- Optional flag to check cost ofrevokeRequestgasPrice- Optional gas price in GWeikeyringOpts- Optional keyring optionsonhashonreceiptonconfirmationonerroronmined
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.
optscontentDid-DIDof the content to change ownership forpassword- Password of the staged ownerafsPassword- The password of theAFSnewOwnerDid-DIDof the owner to transfer ownership tomnemonic- mnemonic associated with the AFSestimate- Optional flag to check cost ofapproveTransfergasPrice- Optional gas price in GWeikeyringOpts- Optional keyring optionsonhashonreceiptonconfirmationonerroronmined
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.
optscurrentPassword- random password generated from the previous ownernewPassword- new password for this AFS identitycontentDid-DIDof 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