-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Prosopo flux package initial * add readme * drop unused env * Add getDapps command * Update readme * Make authentication generic * Command to get individual dapp details * Update README * Update Readme header * Update readme login link * Update node login instructions * Update README headers and lint * terminal wip * Successfully connecting to socket * Create function for socket URL * Use logger not console * update * remove npmignore * Add logger
- Loading branch information
Showing
25 changed files
with
966 additions
and
287 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,95 @@ | ||
# @prosopo/flux | ||
|
||
This package contains a Command Line Interface (CLI) for interacting with the Flux network. | ||
|
||
## CLI Usage | ||
|
||
### Authentication | ||
|
||
#### Authenticate with Flux Main Site only | ||
|
||
Use to generate the authentication for a Flux node for a specific app.This allows you to go straight | ||
to the [RunOnFlux Login](https://cloud.runonflux.io/login.html) and login with the login phrase and signature. | ||
|
||
```bash | ||
# authenticate with the network for a specific app | ||
npm run cli auth | ||
{ | ||
nodeAPIURL: URL { | ||
href: 'https://api.runonflux.io/', | ||
origin: 'https://api.runonflux.io', | ||
... | ||
}, | ||
nodeLoginPhrase: 'asdlkadalkdalskdasldkadlkadlkaldkasdlk', | ||
nodeSignature: 'lkjasdlajsdlkajdlkajdlaskjdlaskjdlaskjdaslkd/9I=' | ||
} | ||
|
||
``` | ||
|
||
#### Authenticate with a Node and an App | ||
|
||
Use to generate the authentication for a Flux node for a specific app. This allows you to go straight to the node for | ||
the app you are working with and login with the login phrase and signature. | ||
|
||
```bash | ||
# authenticate with the network for a specific app | ||
npm run cli auth -- --app <app_name> | ||
{ | ||
nodeAPIURL: URL { | ||
# You can now visit this (using port 16126) to login with the login phrase and signature | ||
href: 'http://x.x.x.x:16127/', | ||
origin: 'http://x.x.x.x:16127', | ||
... | ||
}, | ||
nodeLoginPhrase: 'asdlkadalkdalskdasldkadlkadlkaldkasdlk', | ||
nodeSignature: 'lkjasdlajsdlkajdlkajdlaskjdlaskjdlaskjdaslkd/9I=' | ||
} | ||
``` | ||
|
||
### Get Dapp Details | ||
|
||
#### Get Dapps | ||
|
||
Use this command to get a list of all the dapps that are running on the network. | ||
|
||
```bash | ||
# get all dapps | ||
npm run cli getDapps | ||
``` | ||
|
||
#### Get Dapp | ||
|
||
Use this command to get the IP addresses of the nodes that are running the app. | ||
|
||
```bash | ||
# get details of a specific dapp | ||
npm run cli getDapp -- --app <app_name> | ||
``` | ||
|
||
### Redeploy | ||
|
||
#### Soft redeploy | ||
|
||
Restart the app on all nodes that are running the app. | ||
|
||
```bash | ||
# redeploy the app | ||
npm run cli redeploy -- --app <app_name> | ||
... | ||
ℹ apiUrl: http://x.x.x.x:16127/id/verifylogin deploy.js 15:00:42 | ||
ℹ { status: 'success', deploy.js 15:00:42 | ||
data: { message: '<app_name> queried for global soft redeploy' } } | ||
``` | ||
#### Hard redeploy | ||
Remove the container and restart the app on all nodes that are running the app. | ||
```bash | ||
# hard redeploy the app | ||
npm run cli redeploy -- --app <app_name> --hard | ||
... | ||
ℹ apiUrl: http://x.x.x.x:16127/id/verifylogin deploy.js 15:00:42 | ||
ℹ { status: 'success', deploy.js 15:00:42 | ||
data: { message: '<app_name> queried for global hard redeploy' } } | ||
``` |
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,4 @@ | ||
NODE_ENV=development | ||
PROSOPO_LOG_LEVEL=debug | ||
PROSOPO_ZELCORE_PRIVATE_KEY= | ||
PROSOPO_ZELCORE_PUBLIC_KEY= |
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,51 @@ | ||
{ | ||
"name": "@prosopo/flux", | ||
"version": "0.2.41", | ||
"description": "Tools for managing Flux deployment", | ||
"main": "dist/index.js", | ||
"type": "module", | ||
"engines": { | ||
"node": ">=18", | ||
"npm": ">=9" | ||
}, | ||
"scripts": { | ||
"clean": "tsc --build --clean", | ||
"build": "tsc --build --verbose", | ||
"test": "NODE_OPTIONS=--max-old-space-size=4096 npx vitest run --config ./src/vite.config.ts", | ||
"cli": "node dist/index.js", | ||
"eslint": "npx eslint . --no-error-on-unmatched-pattern --ignore-path ../../.eslintignore", | ||
"eslint:fix": "npm run eslint -- --fix", | ||
"prettier": "npx prettier . --check --no-error-on-unmatched-pattern --ignore-path ../../.eslintignore", | ||
"prettier:fix": "npm run prettier -- --write", | ||
"lint": "npm run eslint && npm run prettier", | ||
"lint:fix": "npm run eslint:fix && npm run prettier:fix" | ||
}, | ||
"author": "Prosopo Limited", | ||
"license": "Apache-2.0", | ||
"dependencies": { | ||
"@noble/curves": "^1.3.0", | ||
"@polkadot/util": "12.6.1", | ||
"@polkadot/util-crypto": "12.6.1", | ||
"@prosopo/cli": "0.2.41", | ||
"@prosopo/common": "0.2.41", | ||
"@prosopo/util": "0.2.41", | ||
"consola": "^3.2.3", | ||
"dotenv": "^16.0.3", | ||
"glob": "^10.0.0", | ||
"qs": "^6.11.2", | ||
"socket.io-client": "^4.7.4", | ||
"varuint-bitcoin": "^1.1.2", | ||
"yargs": "^17.5.1", | ||
"yargs-parser": "^21.0.1" | ||
}, | ||
"overrides": { | ||
"@polkadot/keyring": "12.6.1" | ||
}, | ||
"devDependencies": { | ||
"@esm-bundle/chai": "^4.3.4-fix.0", | ||
"ts-node": "^10.9.1", | ||
"tslib": "2.6.2", | ||
"typescript": "5.1.6", | ||
"vitest": "^0.34.2" | ||
} | ||
} |
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,43 @@ | ||
import * as z from 'zod' | ||
import { ArgumentsCamelCase, Argv } from 'yargs' | ||
import { LogLevel, Logger, getLogger } from '@prosopo/common' | ||
import { getPrivateKey, getPublicKey } from './process.env.js' | ||
import { main } from '../lib/auth.js' | ||
|
||
const fluxAuthArgs = z.object({ | ||
app: z.string().optional(), | ||
ip: z.string().optional(), | ||
}) | ||
|
||
export default (cmdArgs?: { logger?: Logger }) => { | ||
const logger = cmdArgs?.logger || getLogger(LogLevel.enum.info, 'flux.cli.auth') | ||
|
||
return { | ||
command: 'auth', | ||
describe: 'Authenticate with a Flux Node', | ||
builder: (yargs: Argv) => | ||
yargs | ||
.option('app', { | ||
type: 'string' as const, | ||
demandOption: false, | ||
desc: 'Name of the app to authenticate with', | ||
} as const) | ||
.option('ip', { | ||
type: 'string' as const, | ||
demandOption: false, | ||
desc: 'IP address of Flux machine to authenticate with', | ||
} as const), | ||
handler: async (argv: ArgumentsCamelCase) => { | ||
try { | ||
const privateKey = getPrivateKey() | ||
const publicKey = getPublicKey() | ||
const parsedArgs = fluxAuthArgs.parse(argv) | ||
const result = await main(publicKey, privateKey, parsedArgs.app, parsedArgs.ip) | ||
logger.info(result) | ||
} catch (err) { | ||
logger.error(err) | ||
} | ||
}, | ||
middlewares: [], | ||
} | ||
} |
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,37 @@ | ||
import * as z from 'zod' | ||
import { ArgumentsCamelCase, Argv } from 'yargs' | ||
import { LogLevel, Logger, getLogger } from '@prosopo/common' | ||
import { getPrivateKey, getPublicKey } from './process.env.js' | ||
import { main } from '../lib/deploy.js' | ||
|
||
const fluxDeployArgs = z.object({ | ||
app: z.string(), | ||
ip: z.string().optional(), | ||
hard: z.boolean().optional(), | ||
}) | ||
|
||
export default (cmdArgs?: { logger?: Logger }) => { | ||
const logger = cmdArgs?.logger || getLogger(LogLevel.enum.info, 'flux.cli.deploy') | ||
|
||
return { | ||
command: 'deploy', | ||
describe: 'Deploy a Flux application', | ||
builder: (yargs: Argv) => | ||
yargs.option('hard', { | ||
type: 'boolean' as const, | ||
demand: false, | ||
desc: 'Whether to hard redeploy the app', | ||
} as const), | ||
handler: async (argv: ArgumentsCamelCase) => { | ||
try { | ||
const privateKey = getPrivateKey() | ||
const publicKey = getPublicKey() | ||
const parsedArgs = fluxDeployArgs.parse(argv) | ||
await main(publicKey, privateKey, parsedArgs.app, parsedArgs.ip, parsedArgs.hard) | ||
} catch (err) { | ||
logger.error(err) | ||
} | ||
}, | ||
middlewares: [], | ||
} | ||
} |
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,35 @@ | ||
import * as z from 'zod' | ||
import { ArgumentsCamelCase, Argv } from 'yargs' | ||
import { LogLevel, Logger, getLogger } from '@prosopo/common' | ||
import { getAuth, getIndividualFluxAppDetails } from '../lib/auth.js' | ||
import { getPrivateKey, getPublicKey } from './process.env.js' | ||
const fluxGetDappArgs = z.object({ | ||
app: z.string(), | ||
}) | ||
export default (cmdArgs?: { logger?: Logger }) => { | ||
const logger = cmdArgs?.logger || getLogger(LogLevel.enum.info, 'flux.cli.getDapp') | ||
|
||
return { | ||
command: 'getDapp', | ||
describe: 'Get dapp details', | ||
builder: (yargs: Argv) => | ||
yargs.option('app', { | ||
type: 'string' as const, | ||
demandOption: false, | ||
desc: 'Name of the dapp to get the details of', | ||
} as const), | ||
handler: async (argv: ArgumentsCamelCase) => { | ||
try { | ||
const privateKey = getPrivateKey() | ||
const publicKey = getPublicKey() | ||
const { signature, loginPhrase } = await getAuth(privateKey) | ||
const parsedArgs = fluxGetDappArgs.parse(argv) | ||
const dapp = await getIndividualFluxAppDetails(parsedArgs.app, publicKey, signature, loginPhrase) | ||
logger.info(JSON.stringify(dapp, null, 2)) | ||
} catch (err) { | ||
logger.error(err) | ||
} | ||
}, | ||
middlewares: [], | ||
} | ||
} |
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,23 @@ | ||
import { LogLevel, Logger, getLogger } from '@prosopo/common' | ||
import { getPrivateKey, getPublicKey } from './process.env.js' | ||
import { main } from '../lib/getDapps.js' | ||
|
||
export default (cmdArgs?: { logger?: Logger }) => { | ||
const logger = cmdArgs?.logger || getLogger(LogLevel.enum.info, 'flux.cli.getDapps') | ||
|
||
return { | ||
command: 'getDapps', | ||
describe: 'Get dapp details', | ||
handler: async () => { | ||
try { | ||
const privateKey = getPrivateKey() | ||
const publicKey = getPublicKey() | ||
const dapps = await main(publicKey, privateKey) | ||
logger.info(JSON.stringify(dapps, null, 2)) | ||
} catch (err) { | ||
logger.error(err) | ||
} | ||
}, | ||
middlewares: [], | ||
} | ||
} |
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,5 @@ | ||
export { default as commandDeploy } from './deploy.js' | ||
export { default as commandAuth } from './auth.js' | ||
export { default as commandGetDapps } from './getDapps.js' | ||
export { default as commandGetDapp } from './getDapp.js' | ||
export { default as commandTerminal } from './terminal.js' |
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,23 @@ | ||
import { ProsopoEnvError } from '@prosopo/common' | ||
import { wifToPrivateKey } from '../lib/sep256k1Sign.js' | ||
|
||
export const getPrivateKey = () => { | ||
const secret = process.env['PROSOPO_ZELCORE_PRIVATE_KEY'] | ||
if (!secret) { | ||
throw new ProsopoEnvError('DEVELOPER.MISSING_ENV_VARIABLE', { | ||
context: { missingEnvVars: ['PROSOPO_ZELCORE_PRIVATE_KEY'] }, | ||
}) | ||
} | ||
return wifToPrivateKey(secret) | ||
} | ||
|
||
export const getPublicKey = () => { | ||
const secret = process.env['PROSOPO_ZELCORE_PUBLIC_KEY'] | ||
if (!secret) { | ||
throw new ProsopoEnvError('DEVELOPER.MISSING_ENV_VARIABLE', { | ||
context: { missingEnvVars: ['PROSOPO_ZELCORE_PUBLIC_KEY'] }, | ||
}) | ||
} | ||
|
||
return secret | ||
} |
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,43 @@ | ||
import * as z from 'zod' | ||
import { ArgumentsCamelCase, Argv } from 'yargs' | ||
import { LogLevel, Logger, getLogger } from '@prosopo/common' | ||
import { getPrivateKey, getPublicKey } from './process.env.js' | ||
import { main } from '../lib/terminal.js' | ||
|
||
const fluxAuthArgs = z.object({ | ||
app: z.string(), | ||
ip: z.string().optional(), | ||
}) | ||
|
||
export default (cmdArgs?: { logger?: Logger }) => { | ||
const logger = cmdArgs?.logger || getLogger(LogLevel.enum.info, 'flux.cli.auth') | ||
|
||
return { | ||
command: 'terminal', | ||
describe: 'Start a terminal to a Flux Node', | ||
builder: (yargs: Argv) => | ||
yargs | ||
.option('app', { | ||
type: 'string' as const, | ||
demandOption: false, | ||
desc: 'Name of the app to authenticate with', | ||
} as const) | ||
.option('ip', { | ||
type: 'string' as const, | ||
demandOption: false, | ||
desc: 'IP address of Flux machine to authenticate with', | ||
} as const), | ||
handler: async (argv: ArgumentsCamelCase) => { | ||
try { | ||
const privateKey = getPrivateKey() | ||
const publicKey = getPublicKey() | ||
const parsedArgs = fluxAuthArgs.parse(argv) | ||
const result = await main(publicKey, privateKey, parsedArgs.app, parsedArgs.ip) | ||
logger.info(result) | ||
} catch (err) { | ||
logger.error(err) | ||
} | ||
}, | ||
middlewares: [], | ||
} | ||
} |
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,21 @@ | ||
import { ProsopoApiError } from '@prosopo/common' | ||
export async function streamToJson(stream: ReadableStream<Uint8Array>): Promise<Record<any, any>> { | ||
return await new Response(stream).json() | ||
} | ||
|
||
export const errorHandler = async <T>(response: Response) => { | ||
if (!response.ok) { | ||
throw new ProsopoApiError('API.BAD_REQUEST', { context: { error: `HTTP error! status: ${response.status}` } }) | ||
} | ||
if (response.body && !response.bodyUsed) { | ||
const data = await streamToJson(response.body) | ||
|
||
if (data.status === 'error') { | ||
throw new ProsopoApiError('API.BAD_REQUEST', { | ||
context: { error: `HTTP error! status: ${data.data.message} ` }, | ||
}) | ||
} | ||
return data as T | ||
} | ||
return {} as T | ||
} |
Oops, something went wrong.