Contents
- Prerequisites
- Usage Flow
- Initialize Storage
- Upload File
- Download File
- Access Control
- Storage Usage Metrics
- Download File by DID
- Private NFT
- Error Handling
- Managing Network and Wallet Account Changes
Arcana Storage SDK provides data privacy and access control through blockchain transactions powered by the Arcana Network. To use the Storage SDK, you need to ensure that you have access to a Web3 wallet provider. A provider is required for signing blockchain transactions.
You can obtain a Web3 wallet provider by integrating with the Arcana Auth SDK and accessing the window.arcana.provider.
Alternatively, you can choose to use MetaMask instead of the Arcana Auth SDK or one of the supported third-party wallets. For third-party wallets, use the window.ethereum variable to access the provider.
Refer to the Arcana Storage SDK Quick Start Guide to understand how to integrate with the Storage SDK.
- Install Storage SDK
- Import
StorageProviderfrom the Storage SDK package in the dApp. Call theinitmethod ofStorageProviderand specify the Web3 walletproviderand theappAddressas input parameters. Note: Get the provider via the Auth SDK or third-party supported wallet. You can copy the App Address from the Arcana Developer Dashboard after registering your dApp - Use
StorageProviderto:uploadand push file data into the Arcana Store. Note: Save file DID that is returned after the file upload operation is successful.downloada file from the Arcana Store using DID as input.
- Use
StorageProvider.filesto:deletea file by specifying its DID.sharea file by specifying its DID and recipient's wallet address.revokeaccess to a file by specifying its DID and recipient's wallet address.changeFileOwnerof a file by specifying its DID and recipient's wallet address.getUploadLimitset by the dApp per user.getDownloadLimitset by the dApp per user.getSharedUsersto obtain a list of users with whom a file DID is shared.myFilesmethod to obtain a list of file DIDs for the files uploaded by the user (file owner).sharedFilesmethod to obtain a list of files shared with the user.
import { StorageProvider } from '@arcana/storage'; // required only once per .ts or .js file
dAppStorageProvider = await StorageProvider.init({
appAddress: ARCANA_APP_ADDRESS, // Get App Address via Dashboard after registering and configuring dApp
email: user_email_string, //optional
chainId: 100, //optional
provider: window.arcana.provider //optional
// use 'window.arcana.provider', if using the Auth SDK
// or use 'window.ethereum' if using a third-party wallet
});Note:
It suffices to invoke the init method of StorageProvider just once and use it across your dApp.
This Singleton usage is recommended as a best practice.
The Storage SDK accepts Blobs as files. The file object passed must be an instance of a Blob or a descendant (File, etc.). You cannot upload a file by providing its URL.
As of now, it supports uploading private and public files. They are identifiable by looking at the first byte of the DID. In hexadecimal format, 01 indicates it's a public file, and 02 indicates it's a private file.
await dAppStorageProvider.upload(file, {
onProgress: (bytesUploaded, bytesTotal) => {
console.log('Progress:', ((bytesUploaded / bytesTotal) * 100).toFixed(2), '%')
}
}).then((did) => console.log('File successfully uploaded. DID:', did)).catch(e => console.error(e));await dAppStorageProvider.download(
did, (bytesDownloaded, bytesTotal) => {
console.log('Progress:', ((bytesUploaded / bytesTotal) * 100).toFixed(2), '%')
}
);// did: DID of the file to be shared
// address: recipient user's address
// validity (optional): For how long will the user be able to download the file, e.g. [400] would mean 400 seconds
await dAppStorageProvider.files.share([did], [address]);// did: DID of file from which access is removed
// address: The address of the user for whom the access must be revoked
await dAppStorageProvider.files.revoke(did, address);// address: new owner's address
await dAppStorageProvider.files.changeOwner(did, address);await dAppStorageProvider.files.delete(did);//Get consumed and total storage of the current user
let [consumed, total] = await dAppStorageProvider.files.getUploadLimit();//Get consumed and the total bandwidth of the current user
let [consumed, total] = await dAppStorageProvider.files.getDownloadLimit();This method lists the files shared with the current user.
import { AccessTypeEnum } from '@arcana/storage'; // required only once per .ts or .js file
let files = await dAppStorageProvider.files.list(AccessTypeEnum.SHARED_FILES);This method lists the files uploaded by the current user.
import { AccessTypeEnum } from '@arcana/storage'; // required only once per .ts or .js file
let files = await dAppStorageProvider.files.list(AccessTypeEnum.MY_FILES);//The file DID is returned at the time of file upload and uniquely identifies the file in Arcana Store.
//Note: It is not essential to use the App Address during Storage SDK initialization if you wish to use the method `downloadDID`.
// You can provide a blockchain provider during the initialization of the Storage SDK.
// Provider can be obtained by installing and initializing the Auth SDK or a third-party provider.
// If you do not specify a provider during Storage SDK initialization, then by default,
// the Storage SDK will utilize the `window.ethereum` setting.
dAppStorageProvider = await StorageProvider.init({
appAddress: ARCANA_APP_ADDRESS, // Get App Address via Dashboard after registering and configuring dApp
email: user_email_string, //optional
chainId: 100, //optional
provider: window.arcana.provider //optional
// use 'window.arcana.provider', if using the Auth SDK
// or use 'window.ethereum' if using a third-party wallet
});
await dAppStorageProvider.downloadDID('<did of the file>');Use the following Storage SDK functionality for minting private NFTs.
Use makeMetadataURL to obtain a URL that can be used to mint a preview image of the actual private NFT. This preview image can be publicly listed in NFT marketplaces and can be transacted upon. Only the owner of the private NFT can download it from the Arcana Store and access it. Others can only view the publicly listed preview image. Arcana Network platform bridge entity tracks ownership changes corresponding to NFT transactions carried out in public marketplaces and updates the Arcana Store accordingly. For details, refer to the guide - How to create private NFT.
let metadata = await dAppStorageProvider.makeMetadataURL(
title,
description,
did, // The DID of the private NFT file hosted in the Arcana Store
file, // The 'preview image' file corresponding to the private NFT, not the actual private NFT data file
);
console.log(metadata);
// https://test-storage.arcana.network:9000/api/v1/metadata/0x129d1438ff3bf014e9b9094b3a5d410f691c208ed5305b0844307b761c0e295eOnce you have minted the NFT, to make it private and control access to it and manage ownership, you need to link it with the DID.
let chainId = 80001,tokenId = 3, nftContract = "0xE80FCAD702b72777f5036eF1a76086FD3f882E29"
await dAppStorageProvider.linkNft(did, tokenId, nftContract, chainId);During file upload operations, if there are any errors, dApp developers should address those by catching the exceptions raised by the Storage SDK:
import { StorageProvider } from '@arcana/storage'; // required only once per .ts or .js file
dAppStorageProvider = await StorageProvider.init({
appAddress: ARCANA_APP_ADDRESS, // Get appAddress via Dashboard after registering and configuring dApp
email: user_email_string, //optional
chainId: 100, //optional
provider: window.arcana.provider //optional
// use 'window.arcana.provider', if using the Auth SDK
// or use 'window.ethereum' if using a third-party wallet
});
await dAppStorageProvider.upload(
file, (bytesUploaded, bytesTotal) => {
console.log('Progress:', ((bytesUploaded / bytesTotal) * 100).toFixed(2), '%')
}
).then(
(did) => console.log('File successfully uploaded. DID:', did)
).catch(e => console.error(e));// dApp devs can modify this default function
dAppStorageProvider.onNetworkChange = (oldNetwork, newNetwork) => {
window.location.reload()
}// dApp devs can modify this default function
dAppStorageProvider.onAccountChange = (accounts) => {
window.location.reload()
}