2023-05-21 15:29:15 +00:00
|
|
|
---
|
2023-08-10 13:37:40 +00:00
|
|
|
sidebar_position: 4
|
2023-05-21 15:29:15 +00:00
|
|
|
---
|
2023-08-11 14:44:24 +00:00
|
|
|
|
2023-08-10 13:37:40 +00:00
|
|
|
# Jackal.nodejs
|
2023-05-21 15:29:15 +00:00
|
|
|
|
|
|
|
## Quickstart
|
|
|
|
|
2023-08-11 14:41:37 +00:00
|
|
|
### Demo
|
|
|
|
|
|
|
|
A working demo repo can be found [on GitHub](https://github.com/JackalLabs/pup-demo).
|
2023-05-21 15:29:15 +00:00
|
|
|
|
|
|
|
### Pre-requesites
|
|
|
|
|
2023-08-11 14:41:37 +00:00
|
|
|
* Nodejs v20+
|
|
|
|
* [Jackal.nodejs](https://www.npmjs.com/package/@jackallabs/jackal.nodejs)
|
|
|
|
* Wallet Mnemonic
|
2023-05-21 15:29:15 +00:00
|
|
|
|
|
|
|
### Setting Up
|
|
|
|
|
2023-07-07 16:14:13 +00:00
|
|
|
Install dependencies:
|
2023-08-11 14:44:24 +00:00
|
|
|
|
2023-07-07 16:14:13 +00:00
|
|
|
```shell
|
2023-08-11 14:41:37 +00:00
|
|
|
npm install @jackallabs/jackal.nodejs
|
|
|
|
npm install -D @types/node typescript tscpaths
|
2023-07-07 16:14:13 +00:00
|
|
|
```
|
|
|
|
|
2023-08-11 14:44:24 +00:00
|
|
|
Jackal.js requires Node v20+. The easiest way to manage this is
|
|
|
|
with [NVM](https://github.com/nvm-sh/nvm#installing-and-updating).
|
|
|
|
|
2023-07-07 16:14:13 +00:00
|
|
|
```shell
|
|
|
|
nvm use 20
|
|
|
|
```
|
2023-05-21 15:29:15 +00:00
|
|
|
|
2023-08-11 14:41:37 +00:00
|
|
|
#### Wallet Instantiation
|
2023-05-21 16:26:23 +00:00
|
|
|
|
2023-08-11 14:41:37 +00:00
|
|
|
Jackal.nodejs does not use a traditional wallet like Jackal.js. Instead, `MnemonicWallet.create(mnemonic)` is used for
|
|
|
|
wallet instantiation.
|
2023-07-07 16:14:13 +00:00
|
|
|
|
|
|
|
```js
|
|
|
|
const appConfig = {
|
|
|
|
signerChain: 'lupulella-2',
|
|
|
|
queryAddr: 'https://testnet-grpc.jackalprotocol.com',
|
|
|
|
txAddr: 'https://testnet-rpc.jackalprotocol.com'
|
|
|
|
}
|
|
|
|
|
2023-08-11 14:41:37 +00:00
|
|
|
const m = await MnemonicWallet.create(mnemonic)
|
2023-05-21 15:29:15 +00:00
|
|
|
|
|
|
|
// Hooking up the wallet to your app
|
2023-08-11 14:41:37 +00:00
|
|
|
const w = await WalletHandler.trackWallet(appConfig, m)
|
2023-07-07 16:14:13 +00:00
|
|
|
```
|
2023-05-21 15:29:15 +00:00
|
|
|
|
2023-07-07 16:14:13 +00:00
|
|
|
Additionally, a query-only mode for the wallet can get accessed via the following:
|
|
|
|
|
|
|
|
```js
|
2023-08-11 14:41:37 +00:00
|
|
|
const wallet = await WalletHandler.trackQueryWallet('https://testnet-grpc.jackalprotocol.com') // Use the gRPC-web address of your choice
|
2023-05-21 15:29:15 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
### Buying Storage Space
|
|
|
|
|
2023-07-07 16:14:13 +00:00
|
|
|
Every account that wishes to use the Jackal Protocol to store data needs to have a paid storage account.
|
|
|
|
This means giving the protocol $8 USD per month per tb. We can do this with Jackal.js!
|
2023-05-21 15:29:15 +00:00
|
|
|
|
|
|
|
```js
|
|
|
|
const storage = await StorageHandler.trackStorage(wallet)
|
|
|
|
|
2023-08-11 14:41:37 +00:00
|
|
|
// (Wallet address)
|
|
|
|
// duration in months (min 1)
|
2023-07-07 16:14:13 +00:00
|
|
|
// space in terabytes (min .001)
|
|
|
|
// 2 TB for 1 year:
|
|
|
|
await storage.buyStorage(WALLET_ADDRESS, 12, 2)
|
2023-05-21 15:29:15 +00:00
|
|
|
```
|
|
|
|
|
2023-07-07 16:14:13 +00:00
|
|
|
### Creating a Root Folder
|
2023-05-21 15:29:15 +00:00
|
|
|
|
|
|
|
```js
|
2023-08-11 14:41:37 +00:00
|
|
|
const minimumProviderVersion = '1.0.9'
|
|
|
|
const fileIo = await FileIo.trackIo(wallet, minimumProviderVersion)
|
2023-05-21 15:29:15 +00:00
|
|
|
|
2023-08-11 14:41:37 +00:00
|
|
|
const listOfRootFolders = ["Home", ...]
|
|
|
|
// you can create as many root folders as you would like this way. Home is the Jackal Dashboard default root directory.
|
2023-05-21 16:26:23 +00:00
|
|
|
// The first time a user connects, they must init the system
|
2023-05-21 15:56:25 +00:00
|
|
|
const storage = await StorageHandler.trackStorage(wallet)
|
|
|
|
const msg = storage.makeStorageInitMsg()
|
2023-07-07 16:14:13 +00:00
|
|
|
await fileIo.generateInitialDirs(msg, listOfRootFolders)
|
2023-05-21 15:56:25 +00:00
|
|
|
|
2023-07-07 16:14:13 +00:00
|
|
|
// after the first time, this code can be used instead. this will only create new root folders if they don't already exist
|
|
|
|
const newFolderCount = await fileIo.verifyFoldersExist(listOfRootFolders)
|
2023-05-21 15:29:15 +00:00
|
|
|
```
|
|
|
|
|
2023-07-07 16:14:13 +00:00
|
|
|
### Creating a Child Folder
|
2023-05-21 15:29:15 +00:00
|
|
|
|
|
|
|
```js
|
|
|
|
const fileIo = await FileIo.trackIo(wallet)
|
2023-08-11 14:41:37 +00:00
|
|
|
const parentFolderPath = PARENT_FOLDER_NAME_AND_PATH // for example Dashboard's root folder path is s/Home
|
2023-07-07 16:14:13 +00:00
|
|
|
const parent = await fileIo.downloadFolder(parentFolderPath)
|
|
|
|
const listOfChildFolders = ["Movies", "Pictures", ...]
|
|
|
|
await fileIo.createFolders(parent, listOfChildFolders)
|
|
|
|
```
|
2023-05-21 15:29:15 +00:00
|
|
|
|
2023-07-07 16:14:13 +00:00
|
|
|
### Uploading a File
|
|
|
|
|
|
|
|
```js
|
|
|
|
const fileIo = await FileIo.trackIo(wallet)
|
2023-05-21 15:29:15 +00:00
|
|
|
|
2023-08-11 14:41:37 +00:00
|
|
|
const parentFolderPath = PARENT_FOLDER_NAME_AND_PATH // for example Dashboard's root folder path is s/Home
|
2023-05-21 15:29:15 +00:00
|
|
|
const parent = await fileIo.downloadFolder(parentFolderPath)
|
|
|
|
|
2023-07-07 16:14:13 +00:00
|
|
|
const file = FILE_OBJECT // this MUST be an instance of File() that is in the browser memory
|
|
|
|
const fileName = file.name
|
|
|
|
const handler = await FileUploadHandler.trackFile(file, parentFolderPath)
|
|
|
|
|
|
|
|
const uploadList = {}
|
|
|
|
uploadList[fileName] = {
|
|
|
|
data: null,
|
|
|
|
exists: false,
|
|
|
|
handler: handler,
|
|
|
|
key: fileName,
|
|
|
|
uploadable: await handler.getForUpload()
|
2023-05-21 15:29:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
await fileIo.staggeredUploadFiles(uploadList, parent, {counter: 0, complete: 0})
|
|
|
|
```
|
|
|
|
|
|
|
|
### Downloading a File
|
|
|
|
|
|
|
|
```js
|
|
|
|
const fileIo = await FileIo.trackIo(wallet)
|
|
|
|
|
2023-07-07 16:14:13 +00:00
|
|
|
/* optional */
|
2023-08-11 14:41:37 +00:00
|
|
|
const parentFolderPath = PARENT_FOLDER_NAME_AND_PATH // for example Dashboard's root folder path is s/Home
|
2023-07-07 16:14:13 +00:00
|
|
|
const parent = await fileIo.downloadFolder(parentFolderPath)
|
|
|
|
const childrenFiles = parent.getChildFiles()
|
|
|
|
const pathOfFirstChild = parent.getMyChildPath(childrenFiles[0].name)
|
|
|
|
/* end optional */
|
|
|
|
|
|
|
|
const downloadDetails = {
|
|
|
|
rawPath: FILE_PATH, // manual complete file path OR pathOfFirstChild
|
|
|
|
owner: OWNER_ADDRESS, // JKL address of file owner
|
|
|
|
isFolder: false
|
|
|
|
}
|
2023-05-21 15:29:15 +00:00
|
|
|
|
2023-07-07 16:14:13 +00:00
|
|
|
const fileHanlder = await fileIo.downloadFile(downloadDetails, { track: 0 })
|
|
|
|
|
|
|
|
const file = fileHanlder.receiveBacon()
|
2023-05-21 15:29:15 +00:00
|
|
|
// do what you want with the File object returned by receiveBacon
|
2023-07-07 16:14:13 +00:00
|
|
|
```
|