diff --git a/.gitignore b/.gitignore index a26dc10..2f0e690 100644 --- a/.gitignore +++ b/.gitignore @@ -1,21 +1,478 @@ -# Dependencies -/node_modules +# Created by https://www.toptal.com/developers/gitignore/api/vim,vue,node,linux,macos,dotenv,windows,intellij,visualstudiocode,docusaurus,yarn +# Edit at https://www.toptal.com/developers/gitignore?templates=vim,vue,node,linux,macos,dotenv,windows,intellij,visualstudiocode,docusaurus,yarn -# Production -/build - -# Generated files +### Docusaurus ### +# Docusaurus cache and generated files .docusaurus -.cache-loader -# Misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local +# Docusaurus Build Directory +/build/ +### Docusaurus.Node Stack ### +# Logs +logs +*.log npm-debug.log* yarn-debug.log* yarn-error.log* -.yarn/ +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp + +# Docusaurus cache and generated files + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +### dotenv ### + +### Intellij ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### Intellij Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +# https://plugins.jetbrains.com/plugin/7973-sonarlint +.idea/**/sonarlint/ + +# SonarQube Plugin +# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin +.idea/**/sonarIssues.xml + +# Markdown Navigator plugin +# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced +.idea/**/markdown-navigator.xml +.idea/**/markdown-navigator-enh.xml +.idea/**/markdown-navigator/ + +# Cache file creation bug +# See https://youtrack.jetbrains.com/issue/JBR-2257 +.idea/$CACHE_FILE$ + +# CodeStream plugin +# https://plugins.jetbrains.com/plugin/12206-codestream +.idea/codestream.xml + +# Azure Toolkit for IntelliJ plugin +# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij +.idea/**/azureSettings.xml + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### macOS Patch ### +# iCloud generated files +*.icloud + +### Node ### +# Logs + +# Diagnostic reports (https://nodejs.org/api/report.html) + +# Runtime data + +# Directory for instrumented libs generated by jscoverage/JSCover + +# Coverage directory used by tools like istanbul + +# nyc test coverage + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +# Bower dependency directory (https://bower.io/) + +# node-waf configuration + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +# Dependency directories + +# Snowpack dependency directory (https://snowpack.dev/) + +# TypeScript cache + +# Optional npm cache directory + +# Optional eslint cache + +# Optional stylelint cache + +# Microbundle cache + +# Optional REPL history + +# Output of 'npm pack' + +# Yarn Integrity file + +# dotenv environment variable files + +# parcel-bundler cache (https://parceljs.org/) + +# Next.js build output + +# Nuxt.js build / generate output + +# Gatsby files +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output + +# vuepress v2.x temp and cache directory + +# Docusaurus cache and generated files + +# Serverless directories + +# FuseBox cache + +# DynamoDB Local files + +# TernJS port file + +# Stores VSCode versions used for testing VSCode extensions + +# yarn v2 + +### Node Patch ### +# Serverless Webpack directories +.webpack/ + +# Optional stylelint cache + +# SvelteKit build / generate output +.svelte-kit + +### Vim ### +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +### Vue ### +# gitignore template for Vue.js projects +# +# Recommended template: Node.gitignore + +# TODO: where does this rule come from? +docs/_book + +# TODO: where does this rule come from? +test/ + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### yarn ### +# https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored + +.yarn/* +!.yarn/releases +!.yarn/patches +!.yarn/plugins +!.yarn/sdks +!.yarn/versions + +# if you are NOT using Zero-installs, then: +# comment the following lines +!.yarn/cache + +# and uncomment the following lines +# .pnp.* + +# End of https://www.toptal.com/developers/gitignore/api/vim,vue,node,linux,macos,dotenv,windows,intellij,visualstudiocode,docusaurus,yarn diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/canine-docs.iml b/.idea/canine-docs.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/canine-docs.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..639900d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..bd1f72a --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/docs/developers/jackaljs/intro.md b/docs/developers/jackaljs/intro.md index 1e49889..c55a18b 100644 --- a/docs/developers/jackaljs/intro.md +++ b/docs/developers/jackaljs/intro.md @@ -9,19 +9,32 @@ To get started using Jackal in the browser, you'll need a few things! ### Pre-requesites -* [Node.js](https://nodejs.org/en/download) +* [Vue.js](https://vuejs.org/guide/introduction.html) or [React](https://react.dev/learn) * [Jackal.js](https://www.npmjs.com/package/jackal.js) -* [Vite](https://vitejs.dev/) -* [Keplr](https://www.keplr.app/) +* [Vite](https://vitejs.dev) +* Chromium-family browser (Chrome, Brave, Edge, etc) +* [Keplr](https://www.keplr.app) or [Leap](https://www.leapwallet.io/cosmos) wallet extension ### Setting Up -To get started, make sure you start your project using Vite. If you have an existing React app for example, re-init the project using Vite. +To get started, make sure you [start your project using Vite](https://vitejs.dev/guide). If you have an existing React app for example, re-init the project using Vite. + +Install dependencies: +```shell +npm install jackal.js +npm install -D vite-plugin-node-stdlib-browser +``` + +Jackal.js requires Node v20+. The easiest way to manage this is with [NVM](https://github.com/nvm-sh/nvm#installing-and-updating). +```shell +nvm use 20 +``` #### Updating Vite Config ```js // In vite.config.js: +import { defineConfig } from 'vite' import nodePolyfills from 'vite-plugin-node-stdlib-browser' export default defineConfig({ @@ -33,115 +46,216 @@ export default defineConfig({ ### Connecting Your Wallet +Custom chain configurations are required for [Testnet](#testnet-configuration), and for Keplr on [Mainnet](#mainnet-configuration). The following are the correct options to use. +Jackal.js additionally supports app-level overrides to the chain default settings. This requires some redundancy, but allows for greater flexibility in projects. + +#### Wallet Selection + +Currently Jackal,js supports Keplr and Leap wallets. Only a single wallet can be used at any time, but you can switch between them as desired. + ```js -const chainConfig = { // mainnet chain config - chainId: 'jackal-1', - chainName: 'Jackal', - rpc: 'https://rpc.jackalprotocol.com', - rest: 'https://api.jackalprotocol.com', - bip44: { - coinType: 118 - }, - coinType: 118, - stakeCurrency: { +const selectedWallet = 'keplr' +// OR +const selectedWallet = 'leap' +``` + +#### Testnet Configuration + +```js +const chainConfig = { + chainId: 'lupulella-2', + chainName: 'Jackal Testnet II', + rpc: 'https://testnet-rpc.jackalprotocol.com', + rest: 'https://testnet-api.jackalprotocol.com', + bip44: { + coinType: 118 + }, + coinType: 118, + stakeCurrency: { + coinDenom: 'JKL', + coinMinimalDenom: 'ujkl', + coinDecimals: 6 + }, + bech32Config: { + bech32PrefixAccAddr: 'jkl', + bech32PrefixAccPub: 'jklpub', + bech32PrefixValAddr: 'jklvaloper', + bech32PrefixValPub: 'jklvaloperpub', + bech32PrefixConsAddr: 'jklvalcons', + bech32PrefixConsPub: 'jklvalconspub' + }, + currencies: [ + { coinDenom: 'JKL', coinMinimalDenom: 'ujkl', coinDecimals: 6 - }, - bech32Config: { - bech32PrefixAccAddr: 'jkl', - bech32PrefixAccPub: 'jklpub', - bech32PrefixValAddr: 'jklvaloper', - bech32PrefixValPub: 'jklvaloperpub', - bech32PrefixConsAddr: 'jklvalcons', - bech32PrefixConsPub: 'jklvalconspub' - }, - currencies: [ - { - coinDenom: 'JKL', - coinMinimalDenom: 'ujkl', - coinDecimals: 6 + } + ], + feeCurrencies: [ + { + coinDenom: 'JKL', + coinMinimalDenom: 'ujkl', + coinDecimals: 6, + gasPriceStep: { + low: 0.002, + average: 0.002, + high: 0.02 } - ], - feeCurrencies: [ - { - coinDenom: 'JKL', - coinMinimalDenom: 'ujkl', - coinDecimals: 6, - gasPriceStep: { - low: 0.002, - average: 0.002, - high: 0.02 - } - } - ], - features: [] + } + ], + features: [] } +``` -const walletConfig = { - selectedWallet: 'keplr', +```js +const appConfig = { + signerChain: 'lupulella-2', + enabledChains: ['lupulella-2'], + queryAddr: 'https://testnet-grpc.jackalprotocol.com', + txAddr: 'https://testnet-rpc.jackalprotocol.com' +} +``` + +#### Mainnet Configuration + +```js +const chainConfig = { + chainId: 'jackal-1', + chainName: 'Jackal Mainnet', + rpc: 'https://rpc.jackalprotocol.com', + rest: 'https://api.jackalprotocol.com', + bip44: { + coinType: 118 + }, + coinType: 118, + stakeCurrency: { + coinDenom: 'JKL', + coinMinimalDenom: 'ujkl', + coinDecimals: 6 + }, + bech32Config: { + bech32PrefixAccAddr: 'jkl', + bech32PrefixAccPub: 'jklpub', + bech32PrefixValAddr: 'jklvaloper', + bech32PrefixValPub: 'jklvaloperpub', + bech32PrefixConsAddr: 'jklvalcons', + bech32PrefixConsPub: 'jklvalconspub' + }, + currencies: [ + { + coinDenom: 'JKL', + coinMinimalDenom: 'ujkl', + coinDecimals: 6 + } + ], + feeCurrencies: [ + { + coinDenom: 'JKL', + coinMinimalDenom: 'ujkl', + coinDecimals: 6, + gasPriceStep: { + low: 0.002, + average: 0.002, + high: 0.02 + } + } + ], + features: [] +} +``` + +```js +const appConfig = { signerChain: 'jackal-1', enabledChains: ['jackal-1'], queryAddr: 'https://grpc.jackalprotocol.com', - txAddr: 'https://rpc.jackalprotocol.com', - chainConfig: chainConfig + txAddr: 'https://rpc.jackalprotocol.com' +} +``` + +#### Bringing the full config together + +```js +const finalWalletConfig = { + selectedWallet, + ...appConfig, + chainConfig } // Hooking up the wallet to your app -const wallet = await WalletHandler.trackWallet(walletConfig) +const wallet = await WalletHandler.trackWallet(finalWalletConfig) +``` +Additionally, a query-only mode for the wallet can get accessed via the following: + +```js +const wallet = await WalletHandler.trackQueryWallet('https://grpc.jackalprotocol.com') // Use the gRPC-web address of your choice ``` ### Buying Storage Space -Every account that wishes to use the Jackal Protocol to store data needs to have a paid account. This means giving the protocol $8/month/tb. We can do this with Jackal.js! +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! ```js const storage = await StorageHandler.trackStorage(wallet) -// (Wallet address, duration in hours (min 720), -// space in bytes (min 1000000000) -await storage.buyStorage(WALLET_ADDRESS, 720, 1000000000000) +// (Wallet address, duration in months (min 1), +// space in terabytes (min .001) + +// 2 TB for 1 year: +await storage.buyStorage(WALLET_ADDRESS, 12, 2) ``` -### Creating a Folder +### Creating a Root Folder ```js const fileIo = await FileIo.trackIo(wallet) -const listOfFolders = ["folder_name", ...] -// you can create as many folders as you would like this way +const listOfRootFolders = ["Home", ...] +// you can create as many root folders as you would like this way. Home is the dashboard default root directory. // The first time a user connects, they must init the system const storage = await StorageHandler.trackStorage(wallet) const msg = storage.makeStorageInitMsg() -await fileIo.generateInitialDirs(msg, listOfFolders) +await fileIo.generateInitialDirs(msg, listOfRootFolders) -// after the first time, this code can be used instead. this will only create new folders if they don't already exist -const newFolderCount = await fileIo.verifyFoldersExist(listOfFolders) +// 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) ``` +### Creating a Child Folder + +```js +const fileIo = await FileIo.trackIo(wallet) + +const parentFolderPath = PARENT_FOLDER_NAME // for example Dashboard's root folder path is s/Home +const parent = await fileIo.downloadFolder(parentFolderPath) + +const listOfChildFolders = ["Movies", "Pictures", ...] + +await fileIo.createFolders(parent, listOfChildFolders) +``` ### Uploading a File ```js const fileIo = await FileIo.trackIo(wallet) -const parentFolderPath = PARENT_FOLDER_NAME // replace this with your own path -const fileName = FILE_NAME // replace this with your own file name - -const handler = await FileUploadHandler.trackFile(FILE_OBJECT, parentFolderPath) - +const parentFolderPath = PARENT_FOLDER_NAME // for example Dashboard's root folder path is s/Home const parent = await fileIo.downloadFolder(parentFolderPath) -const uploadList = { - fileName: { - data: null, - exists: false, - handler: handler, - key: fileName, - uploadable: await handler.getForUpload() - } +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() } await fileIo.staggeredUploadFiles(uploadList, parent, {counter: 0, complete: 0}) @@ -152,17 +266,21 @@ await fileIo.staggeredUploadFiles(uploadList, parent, {counter: 0, complete: 0}) ```js const fileIo = await FileIo.trackIo(wallet) -const file = await fileIo.downloadFile( - { - rawPath: FILE_PATH - owner: OWNER_ADDRESS - isFolder: false - }, - { - track: 0 - } -) +/* optional */ +const parentFolderPath = PARENT_FOLDER_NAME // for example Dashboard's root folder path is s/Home +const parent = await fileIo.downloadFolder(parentFolderPath) +const childrenFiles = parent.getChildFiles() +const pathOfFirstChild = parent.getMyChildPath(childrenFiles[0].name) +/* end optional */ -const fileData = file.receiveBacon() +const downloadDetails = { + rawPath: FILE_PATH, // manual complete file path OR pathOfFirstChild + owner: OWNER_ADDRESS, // JKL address of file owner + isFolder: false +} + +const fileHanlder = await fileIo.downloadFile(downloadDetails, { track: 0 }) + +const file = fileHanlder.receiveBacon() // do what you want with the File object returned by receiveBacon -``` \ No newline at end of file +```