Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip - template #241

Draft
wants to merge 2 commits into
base: naynay/file-restructure
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# src/ docs

- `src/cli.ts` - the entry-point for the application. Where all CLI and TUI
(text user interface) functions are registered.
- `src/tui.ts` - the entry-point for the TUI.

## Special Folders

- `src/_template/` - a template and guide for "User Flow" folders
- `src/common/` - helper functions used accross the application
- `src/config/` - utils for entropy config
- `src/types/` - types used across the application

## "Domain" Folders

CLI functionality is grouped into "domains". Within these we pool common
resources needed for programmatic CLI and TUI usage (see `src/_template/` for
detail)

- `src/account/` - account creation, querying, manipulation etc.
- `src/balance/` - account balance querying
- `src/faucet/` - faucet functions for test-net
- `src/program/` - program deploying, querying, manipulation
- `src/sign/` - message signing
- `src/transfer/` - fund transfers

### Legacy Folders

- `src/flows` - a collection of functions leftover from an earier version

41 changes: 41 additions & 0 deletions src/_template/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Domain Template

This folder described how we structure our "Domain" folders.

```mermaid
flowchart

direction TB

entropy-base:::base

subgraph example[ ]
direction TB

types
main
command
interaction

constants:::optional
utils:::optional

main --> command & interaction
end

entropy-base --> main

classDef default fill:#B0B, stroke:none, color:#FFF;
classDef base fill:none, stroke:#000, color:#000;
classDef optional fill:#B9B, stroke:none;
classDef cluster fill:none, stroke:#B0B;
```
_Diagram showing the required + optional files, and key dependencies._


- `main.ts` - the core functions used by the flow (inherits from `EntropyBase`)
- `command.ts` - the programmatic CLI functions (depends on `main.ts`)
- `interactions.ts` - the TUI (text user interface) functions (depends on `main.ts`)
- `types.ts` - all the types/interfaces used in this flow
- `constants.ts` (optional) - constants used in this flow
- `utils.ts` (optional) - help function used in this flow
84 changes: 84 additions & 0 deletions src/_template/command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { Command } from "commander"
import { EntropyDance } from "./main"
import { loadByteCode, loadDanceConfig } from "./utils"

import { accountOption, endpointOption, loadEntropy, cliWrite } from "../common/utils-cli"

/*
This file is responsible for building up the commands related to our domain

There is a single export, which will be registered in src/cli.ts
This example has sub-commands (e.g. entropy dance learn), though not all do.

The descriptions written here will be readable when users type e.g.
- entropy --help
- entropy dance --help
- entropy dance learn --help


## References

https://www.npmjs.com/package/commander


## This example

We use the made-up domain "dance" so we will have names like
- entropyDanceCommand
- entropyDanceLearn (for command: `entropy dance learn`)

*/

export function entropyDanceCommand () {
return new Command('dance')
.description('Commands to query/ manipulate dances on the Entropy Network')
.addCommand(entropyDanceLearn())
.addCommand(entropyDanceAdd())
}


function entropyDanceLearn () {
return new Command('learn')
// description
.description('Have the Entropy network learn a new dance function.')

// arguments
.argument('<byteCodePath>', 'the path to the bytecode being learnt')

// options / flags
.addOption(accountOption())
.addOption(endpointOption())

// what is run:
.action(async (byteCodePath, opts) => {
const danceMoveByteCode = await loadByteCode(byteCodePath)
const dance = new EntropyDance(opts.account, opts.endpoint)

const pointer = await dance.learn(danceMoveByteCode)

// We write output simply so other programs can parse + consume output
cliWrite(pointer)

// NOTE: must exit the program!
process.exit(0)
})
}

function entropyDanceAdd () {
return new Command('add')
.description('Add a dance to your verifyingKey.')
.argument('<verifyingKey>', 'verifiying key to add the dance to')
.argument('<dancePointer>', 'pointer for the dance bytecode that is already learn')
.argument('[danceConfigPath]', 'path to a config file for your dance') // optional
.addOption(accountOption())
.addOption(endpointOption())
.action(async (verifyingKey, dancePionter, danceConfigPath, opts) => {
const danceConfig = await loadDanceConfig(danceConfigPath)
const dance = new EntropyDance(opts.account, opts.endpoint)

await dance.add(verifyingKey, dancePionter, danceConfig)

// NOTE: must exit the program!
process.exit(0)
})
}
12 changes: 12 additions & 0 deletions src/_template/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const PROMPT = {
amount: {
name: 'amount',
message: 'Input amount to transfer:',
default: '1',
invalidError: 'Please enter a value greater than 0',
},
recipientAddress: {
name: 'recipientAddress',
message: `Input recipient's address:`,
},
}
15 changes: 15 additions & 0 deletions src/_template/interaction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import inquirer from "inquirer"

import { EntropyDance } from "./main"
import { danceInputQuestions } from "./utils"
import { print } from "../common/utils"

export async function entropyTransfer (entropy, endpoint) {
const dance = new EntropyDance(entropy, endpoint)

await dance.transfer(recipientAddress, amount, progressTracker)

Check failure on line 10 in src/_template/interaction.ts

View workflow job for this annotation

GitHub Actions / Build, test, and lint

Property 'transfer' does not exist on type 'EntropyDance'.

Check failure on line 10 in src/_template/interaction.ts

View workflow job for this annotation

GitHub Actions / Build, test, and lint

Cannot find name 'recipientAddress'.

Check failure on line 10 in src/_template/interaction.ts

View workflow job for this annotation

GitHub Actions / Build, test, and lint

Cannot find name 'amount'.

Check failure on line 10 in src/_template/interaction.ts

View workflow job for this annotation

GitHub Actions / Build, test, and lint

Cannot find name 'progressTracker'.
print('')
print(`Transaction successful: Sent ${amount} to ${recipientAddress}`)

Check failure on line 12 in src/_template/interaction.ts

View workflow job for this annotation

GitHub Actions / Build, test, and lint

Cannot find name 'amount'.

Check failure on line 12 in src/_template/interaction.ts

View workflow job for this annotation

GitHub Actions / Build, test, and lint

Cannot find name 'recipientAddress'.
print('')
print('Press enter to return to main menu')
}
58 changes: 58 additions & 0 deletions src/_template/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import Entropy from "@entropyxyz/sdk";
import { EntropyBase } from "../common/entropy-base";

/*

This file provides core functions consumed by both ./command.ts and ./interaction.ts

## Conventions

1. unit tested
2. tight interface
- strict typing
- no this-or-that function signatures
3. minimal side-effects
- ✓ logging
- ✓ substrate queries/ mutations
- ✗ config mutation
- ✗ printing


## This example

We use the made-up domain "dance" so we will have names like
- ENTROPY_DANCE
- EntropyDance
- dance = new EntropyDance(entroyp, endpoint)
- tests: tests/dance.test.ts

*/


// this is for logging output
const FLOW_CONTEXT = 'ENTROPY_DANCE'

export class EntropyDance extends EntropyBase {
static isDanceMove (danceName: string) {
// stateless function - useful if you do not have/ need an entropy instance
// NOTE: no logging
return Boolean(danceName)
}

constructor (entropy: Entropy, endpoint: string) {
super({ entropy, endpoint, flowContext: FLOW_CONTEXT })
}

async learn (danceMoveByteCode) {
// write code requiring the use of entropy
//
// return this.entropy...
}

async add (verifyingKey, dancePointer, danceConfig) {
// ..

// logging
this.logger.debug(`add: ${dancePointer} to ${verifyingKey}`, `${FLOW_CONTEXT}::add_dance`);
}
}
6 changes: 6 additions & 0 deletions src/_template/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// @ts-ignore
/*

RECORD TYPES HERE

*/
35 changes: 35 additions & 0 deletions src/_template/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { PROMPT } from "./constants";

export async function loadByteCode (path) {
// TODO
}

export async function loadDanceConfig (path) {
// TODO
}

function validateAmount (amount: string | number) {
if (isNaN(amount as number) || parseInt(amount as string) <= 0) {
return PROMPT.amount.invalidError
}
return true
}

const amountQuestion = {
type: 'input',
name: PROMPT.amount.name,
message: PROMPT.amount.message,
default: PROMPT.amount.default,
validate: validateAmount
}

const recipientAddressQuestion = {
type: 'input',
name: PROMPT.recipientAddress.name,
message: PROMPT.recipientAddress.message,
}

export const danceInputQuestions = [
amountQuestion,
recipientAddressQuestion
]
2 changes: 1 addition & 1 deletion src/account/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const FLOW_CONTEXT = 'ENTROPY_ACCOUNT'
export const FLOW_CONTEXT = 'ENTROPY_ACCOUNTS'

export const ACCOUNTS_CONTENT = {
seed: {
Expand Down
11 changes: 8 additions & 3 deletions src/account/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@ export class EntropyAccount extends EntropyBase {

await wasmGlobalsReady()
const keyring = new Keyring({ seed, path, debug: true })
const fullAccount = keyring.getAccount()
const data = keyring.getAccount()
// TODO: sdk should create account on constructor
const { admin } = keyring.getAccount()
const { admin } = data

const data = fullAccount
delete admin.pair
// const encryptedData = password ? passwordFlow.encrypt(data, password) : data

Expand Down Expand Up @@ -99,6 +98,12 @@ export class EntropyAccount extends EntropyBase {

/* PRIVATE */

/*

WARNIG: this function needs to be removed in next core release [0.3.0]!

*/

private async pruneRegistration () {
return new Promise((resolve, reject) => {
this.entropy.substrate.tx.registry.pruneRegistration()
Expand Down
2 changes: 1 addition & 1 deletion src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export function getSync (configPath = CONFIG_PATH) {

export async function set (config: EntropyConfig, configPath = CONFIG_PATH) {
assertConfigPath(configPath)

console.log('config spy: ', config)
await mkdirp(dirname(configPath))
await writeFile(configPath, serialize(config))
}
Expand Down
Loading