-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* fix incorrect function name * keep variable name consistent * security quick reference * add missing word * change image to text, remove spheron * secrets quick reference * remove reference to image * remove redundant code * fix incorrect import * fix task id * update functions to better match description of what they're doing * switch from image to text * networking quick reference * storage quick reference * configuration scaffolding * improve instructions for staking wallet * deployment quick reference * add note about hidden folder * testing quick reference * kpl token quick reference * add links to quick reference sections * clarify IPFS
- Loading branch information
1 parent
5f241fc
commit 281008e
Showing
21 changed files
with
501 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Configuration Quick Reference | ||
|
||
## Task Metadata | ||
|
||
The `task_name`, `author`, `description`, `repositoryUrl` and `imageUrl` will be displayed in the desktop node. | ||
|
||
<!-- Screenshot highlighting various areas --> | ||
|
||
## Task Details | ||
|
||
`task_executable_network`? | ||
`task_audit_program`? | ||
`round_time`, `audit_window`, `submission_window` - How do people know what to set for these? | ||
`minimum_stake_amount` - any guidelines? | ||
`total_bounty_amount`, `bounty_amount_per_round` | ||
`allowed_failed_distributions` | ||
`space` - what should this be? | ||
|
||
## Requirements Tags | ||
|
||
<!-- List of possible options? --> | ||
|
||
## Updating a Task | ||
|
||
`task_id`, `migrationDescription` | ||
|
||
<!-- what can't be updated? --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Deployment Quick Reference | ||
|
||
Before deploying your task, you can apply for our [grant program](https://www.koii.network/founders) that can help you out with initial funding. | ||
|
||
1. Make sure all dependencies are installed: | ||
|
||
```sh | ||
yarn | ||
``` | ||
|
||
2. Build the executable: | ||
|
||
```sh | ||
yarn webpack | ||
``` | ||
|
||
3. Run the create task CLI: | ||
|
||
```sh | ||
npx @_koii/create-task-cli@latest | ||
``` | ||
|
||
4. Choose "Deploy a New Task". | ||
|
||
5. At this point you will be asked how you'd like to configure your task, via the CLI or the config YML. We recommend using the YML file. | ||
|
||
6. Enter the path to your staking wallet. If you have installed the desktop node, visit `<OS-specific path>/KOII-Desktop-Node/namespace/` and you should see a file with the name `<name>stakingWallet.json`. Enter the full path to this file (`<OS-specific path>/KOII-Desktop-Node/namespace/<name>stakingWallet.json`). | ||
|
||
The OS-specific paths are as follows: | ||
|
||
**Windows**: `/Users/<username>/AppData/Roaming` | ||
|
||
**Mac**: `/Users/<username>/Library/Application Support` | ||
|
||
**Linux**: `/home/<username>/.config` | ||
|
||
7. Press 'y' to confirm you would like to deploy the task. | ||
|
||
Once your task is deployed, you will have to apply to have it [whitelisted](https://docs.koii.network/develop/write-a-koii-task/task-development-guide/task-development-flow/whitelist-task) if you would like your task to be listed in the desktop node's Add Task list. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# KPL Tokens Quick Reference | ||
|
||
## Creating KPL Tokens | ||
|
||
Visit [this site](https://dev-blue-spl-token-creator.vercel.app/) to create a KPL token. | ||
|
||
You will be asked to enter the following information: | ||
|
||
1. **Wallet.json** | ||
If you have deployed your own tasks in previous lessons, you should already know how to obtain your `wallet.json`. | ||
|
||
> [!NOTE] | ||
> | ||
> `Wallet.json` is handled through the front-end JavaScript, so rest assured, your `wallet.json` file will never be uploaded anywhere and will always remain on your local machine. | ||
> | ||
2. **PNG/ICO/JPEG** | ||
This is your icon. It is best if it is square; otherwise, it may be cropped. | ||
|
||
3. **Token Name/Token Symbol/Token Description** | ||
These are the details of your token. The symbol represents the unit, such as FIRE and KOII. | ||
|
||
> [!IMPORTANT] | ||
> | ||
> Please remember your token's Token Public Key, as it will be needed in the next step for minting. | ||
> | ||
## Minting Tokens | ||
|
||
Enter the amount of tokens you'd like to mint, your `wallet.json` file, and your Token Public Key. | ||
|
||
## Checking Token Balance | ||
|
||
You can check the token balance by choosing "Connect Finnie" to link your [Finnie Wallet](https://docs.koii.network/concepts/finnie-wallet/introduction), and then clicking "Fetch Tokens". |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# Networking Quick Reference | ||
|
||
## Configuration | ||
|
||
Koii nodes use UPnP for node-to-node communication. This is disabled by default and must be activated by the user, so fewer nodes will be available for these tasks. In order to identify users that can perform these tasks, add `REQUIRE_INTERNET` to your `requirementTags` in `config-task.yml`: | ||
|
||
```yml | ||
requirementsTags: | ||
- type: ADDON | ||
value: 'REQUIRE_INTERNET' | ||
``` | ||
## Serving Endpoints | ||
Endpoint routes can be added to index.js. Two are already defined in the task template: | ||
```js | ||
if (app) { | ||
// Write your Express Endpoints here. | ||
// Ex. app.post('/accept-cid', async (req, res) => {}) | ||
|
||
// Sample API that return your task state | ||
app.get('/taskState', async (req, res) => { | ||
const state = await namespaceWrapper.getTaskState({ | ||
is_stake_list_required: true, | ||
}); | ||
console.log('TASK STATE', state); | ||
res.status(200).json({ taskState: state }); | ||
}); | ||
|
||
// Sample API that return the value stored in NeDB | ||
app.get('/value', async (req, res) => { | ||
const value = await namespaceWrapper.storeGet('value'); | ||
console.log('value', value); | ||
res.status(200).json({ value: value }); | ||
}); | ||
} | ||
``` | ||
|
||
You can access endpoints like so when you are running `prod-debug`: `http://localhost:30017/task/<taskID>/<endpoint>` | ||
|
||
## Accessing Endpoints from Other Nodes | ||
|
||
To access other nodes' endpoints, you can access the list of IP addresses currently running the task, then choose which nodes you will access. In this example, we're selecting a single random node: | ||
|
||
```javascript | ||
async function getAddressArray() { | ||
try { | ||
// get the task state from K2 (the Koii blockchain) | ||
const taskState = await namespaceWrapper.getTaskState(); | ||
|
||
// get the list of available IP addresses from the task state | ||
// nodeList is an object with key-value pairs in the form stakingKey: ipAddress | ||
const nodeList = taskState.ip_address_list; | ||
|
||
// return just the IP addresses | ||
return Object.values(IPAddressObj); | ||
} catch (e) { | ||
console.log('ERROR GETTING TASK STATE', e); | ||
} | ||
} | ||
|
||
async function getRandomNodeEndpoint(IPAddressArray) { | ||
// choose a random index | ||
const randomIndex = Math.floor(Math.random() * IPAddressArray.length); | ||
// Return the IP address stored at the random index position | ||
return IPAddressArray[randomIndex]; | ||
} | ||
``` | ||
|
||
You can access the endpoint(s) you've chosen during the task or audit phases | ||
|
||
```javascript | ||
// Get a random node from the list | ||
const IPAddressObj = getAddressArray(); | ||
const randomNode = getRandomNodeEndpoint(IPAddressObj); | ||
|
||
// Fetch the data from the node | ||
const response = await axios.get(`${randomNode}/task/${TASK_ID}/<endpoint>`); | ||
|
||
if (response.status === 200) { | ||
const data = response.data; | ||
} else { | ||
return null; | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Secrets Quick Reference | ||
|
||
Secrets (referred to as task extensions in the desktop node) are environment variables stored by node users. These can be accessed just as you would any other environment variable, using `process.env`. During development, these should be added to your .env file. | ||
|
||
You can specify which environment variables a user must define in the `requirementsTags` section of your `config-task.yml` file, using the `TASK_VARIABLE` type. | ||
|
||
Example: | ||
|
||
```yml | ||
requirementsTags: | ||
- type: TASK_VARIABLE | ||
value: 'TWITTER_USERNAME' | ||
description: 'The username of your volunteer Twitter account.' | ||
- type: TASK_VARIABLE | ||
value: 'TWITTER_PASSWORD' | ||
description: 'The password of your volunteer Twitter account.' | ||
- type: TASK_VARIABLE | ||
value: 'TWITTER_PHONE' | ||
description: 'If verification is required, will use your phone number to login.' | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Security Quick Reference | ||
|
||
A message can be signed like so, using `namespaceWrapper.payloadSigning()`: | ||
|
||
```javascript | ||
const message = "Hello World!"; | ||
|
||
// Sign payload | ||
const signedMessage = await namespaceWrapper.payloadSigning(message); | ||
``` | ||
|
||
The `payloadSigning()` function will take care of accessing the node's private key for the signing. | ||
|
||
When you want to send this signature to another node, you'll also need to include the current node's public key. You can get this from `namespaceWrapper.getSubmitterAccount()`: | ||
|
||
```javascript | ||
// get current node's keypair | ||
const keypair = await namespaceWrapper.getSubmitterAccount(message); | ||
|
||
// get the public key from the keypair | ||
const publicKey = keypair.publicKey; | ||
``` | ||
|
||
You can then send the signed message and the public key to another node to be verified and decoded. This can be done with `namespaceWrapper.verifySignature()`: | ||
|
||
```javascript | ||
// Assuming you've already retrieved the signed message and the public key | ||
const message = namespaceWrapper.verifySignature(signedMessage, publicKey); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# Storage Quick Reference | ||
|
||
## Local Database | ||
|
||
Koii tasks use a local key-value store that can be used to pass data between functions. | ||
|
||
### Setting a value | ||
|
||
```js | ||
const value = await namespaceWrapper.storeSet('value', '<your_value>'); | ||
``` | ||
|
||
### Getting a value | ||
|
||
```js | ||
const value = await namespaceWrapper.storeGet('value'); | ||
``` | ||
|
||
## IPFS | ||
|
||
You can use IPFS in a Koii task to pass files between nodes. | ||
|
||
### Uploading a file | ||
|
||
```js | ||
const { KoiiStorageClient } = require('@_koii/storage-task-sdk'); | ||
const fs = require('fs'); | ||
|
||
async function storeFile(data, filename = 'value.json') { | ||
try { | ||
// Create a new instance of the Koii Storage Client | ||
const client = new KoiiStorageClient(); | ||
const basePath = await namespaceWrapper.getBasePath(); | ||
|
||
// Write the data to a temp file | ||
fs.writeFileSync(`${basePath}/${filename}`, JSON.stringify(data)); | ||
|
||
// Get the user staking account, to be used for signing the upload request | ||
const userStaking = await namespaceWrapper.getSubmitterAccount(); | ||
|
||
// Upload the file to IPFS and get the CID | ||
const { cid } = await client.uploadFile(`${basePath}/${filename}`, userStaking); | ||
|
||
// Delete the temp file | ||
fs.unlinkSync(`${basePath}/${filename}`); | ||
|
||
return cid; | ||
} catch (error) { | ||
console.error('Failed to upload file to IPFS:', error); | ||
fs.unlinkSync(`${basePath}/${filename}`); | ||
throw error; | ||
} | ||
} | ||
``` | ||
|
||
The CID can then be sent as part of the submission to be used by other nodes. | ||
|
||
## Retrieving a file | ||
|
||
```js | ||
const { KoiiStorageClient } = require('@_koii/storage-task-sdk'); | ||
|
||
// Create a new instance of the Koii Storage Client | ||
const client = new KoiiStorageClient(); | ||
|
||
try { | ||
// get file from IPFS | ||
const fileBlob = await client.getFile(cid, filename); | ||
if (!fileBlob) return false; | ||
|
||
// if it's a text file, you can read the contents | ||
const fileContent = await fileBlob.text(); | ||
|
||
} catch (error) { | ||
console.error('Failed to download or validate file from IPFS:', error); | ||
throw error; | ||
} | ||
``` |
Oops, something went wrong.