mirror of
https://github.com/logos-storage/codex-factory.git
synced 2026-01-02 13:03:07 +00:00
feat(cmds): listing availabilities
This commit is contained in:
parent
6fde43fc06
commit
35b0247a0f
444
package-lock.json
generated
444
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -15,7 +15,8 @@
|
|||||||
"dockerode": "^4",
|
"dockerode": "^4",
|
||||||
"node-fetch": "^3",
|
"node-fetch": "^3",
|
||||||
"ora": "^8",
|
"ora": "^8",
|
||||||
"semver": "^7"
|
"semver": "^7",
|
||||||
|
"tty-table": "^4.2.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/compat": "^1",
|
"@eslint/compat": "^1",
|
||||||
@ -42,7 +43,7 @@
|
|||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=20.0.0",
|
"node": ">=20.0.0",
|
||||||
"npm": ">=6.0.0",
|
"npm": ">=6.0.0",
|
||||||
"codex": "0.2.1",
|
"codex": "0.2.3",
|
||||||
"supportedCodex": ">0.2.0"
|
"supportedCodex": ">0.2.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
62
src/commands/cmd/availability/ls.ts
Normal file
62
src/commands/cmd/availability/ls.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { Flags } from '@oclif/core'
|
||||||
|
import { Header } from 'tty-table'
|
||||||
|
import Table from 'tty-table'
|
||||||
|
|
||||||
|
|
||||||
|
import { BaseCommand } from '../../../base.js'
|
||||||
|
import { ContainerType } from '../../../utils/docker.js'
|
||||||
|
import { getClientForContainer } from '../../../utils/api.js'
|
||||||
|
import { formatBytes, formatId, formatTokenAmount } from '../../../utils/format.js'
|
||||||
|
|
||||||
|
export default class LsAvailability extends BaseCommand<typeof LsAvailability> {
|
||||||
|
static override description = 'Lists all availabilities'
|
||||||
|
static override examples = [
|
||||||
|
'<%= config.bin %> <%= command.id %>',
|
||||||
|
'<%= config.bin %> <%= command.id %> -n client',
|
||||||
|
'<%= config.bin %> <%= command.id %> --node host1'
|
||||||
|
]
|
||||||
|
static override flags = {
|
||||||
|
node: Flags.string({
|
||||||
|
char: 'n',
|
||||||
|
default: ContainerType.HOST,
|
||||||
|
description: 'Node to run the command on',
|
||||||
|
options: Object.values(ContainerType).filter((value) => value !== ContainerType.BLOCKCHAIN),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
public async run (): Promise<void> {
|
||||||
|
const { flags } = await this.parse(LsAvailability)
|
||||||
|
|
||||||
|
const header: Header[] = [
|
||||||
|
{value: 'Availability ID'},
|
||||||
|
{value: 'Total Size'},
|
||||||
|
{value: 'Free Size'},
|
||||||
|
{value: 'Total Collateral'},
|
||||||
|
{value: 'Total Remaining Collateral'},
|
||||||
|
{value: 'Min Price Per Byte Per Second'},
|
||||||
|
]
|
||||||
|
|
||||||
|
const apiClient = getClientForContainer((flags.node as ContainerType))
|
||||||
|
const availabilitiesResult = await apiClient.marketplace.availabilities()
|
||||||
|
|
||||||
|
if (availabilitiesResult.error) {
|
||||||
|
throw availabilitiesResult.data
|
||||||
|
}
|
||||||
|
|
||||||
|
const rows = availabilitiesResult.data.map((availability) => {
|
||||||
|
return [
|
||||||
|
formatId(availability.id),
|
||||||
|
formatBytes(availability.totalSize),
|
||||||
|
formatBytes(availability.freeSize || 0),
|
||||||
|
formatTokenAmount(availability.totalCollateral),
|
||||||
|
formatTokenAmount(availability.totalRemainingCollateral),
|
||||||
|
formatTokenAmount(availability.minPricePerBytePerSecond),
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// eslint-disable-next-line new-cap
|
||||||
|
console.log(Table(header, rows).render())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
33
src/utils/api.ts
Normal file
33
src/utils/api.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { Codex } from '@codex-storage/sdk-js'
|
||||||
|
|
||||||
|
import { ContainerType } from './docker.js'
|
||||||
|
|
||||||
|
|
||||||
|
export function getClientForContainer (node: ContainerType): Codex {
|
||||||
|
switch (node) {
|
||||||
|
case ContainerType.CLIENT: {
|
||||||
|
return new Codex('http://localhost:8080')
|
||||||
|
}
|
||||||
|
|
||||||
|
case ContainerType.HOST: {
|
||||||
|
return new Codex('http://localhost:8081')
|
||||||
|
}
|
||||||
|
|
||||||
|
case ContainerType.HOST_2: {
|
||||||
|
return new Codex('http://localhost:8082')
|
||||||
|
}
|
||||||
|
|
||||||
|
case ContainerType.HOST_3: {
|
||||||
|
return new Codex('http://localhost:8083')
|
||||||
|
}
|
||||||
|
|
||||||
|
case ContainerType.HOST_4: {
|
||||||
|
return new Codex('http://localhost:8084')
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
throw new Error('Unsupported node type!')
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
82
src/utils/format.ts
Normal file
82
src/utils/format.ts
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
* Converts a number of bytes into a human-readable string with units.
|
||||||
|
* @param bytes - The number of bytes to convert.
|
||||||
|
* @param decimals - Number of decimal places to include (default is 2).
|
||||||
|
* @returns The formatted string in a human-readable format.
|
||||||
|
*/
|
||||||
|
export function formatBytes (bytes: number, decimals = 2): string {
|
||||||
|
if (bytes === 0) return '0 Bytes'
|
||||||
|
|
||||||
|
const k = 1024 // Bytes in a Kilobyte
|
||||||
|
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
||||||
|
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||||||
|
const formattedValue = Number.parseFloat((bytes / k**i).toFixed(decimals))
|
||||||
|
|
||||||
|
return `${formattedValue} ${sizes[i]}`
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a long hash by taking a specified number of characters
|
||||||
|
* from the start and end of the hash.
|
||||||
|
* @param hash - The long hash to format.
|
||||||
|
* @param chars - The number of characters to take from both the start and end (default: 1).
|
||||||
|
* @param separator - The string to place between the start and end characters (default: "...").
|
||||||
|
* @returns The formatted hash string.
|
||||||
|
*/
|
||||||
|
export function formatId (
|
||||||
|
hash: string,
|
||||||
|
chars = 3,
|
||||||
|
separator = '...'
|
||||||
|
): string {
|
||||||
|
if (!hash || hash.length <= chars * 2) {
|
||||||
|
return hash // Return the hash as is if it's too short to format
|
||||||
|
}
|
||||||
|
|
||||||
|
const start = hash.slice(0, chars) // Extract the starting characters
|
||||||
|
const end = hash.slice(-chars) // Extract the ending characters
|
||||||
|
|
||||||
|
return `${start}${separator}${end}`
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats token amounts by automatically determining the most appropriate unit
|
||||||
|
* (`TST`, `gTSTWei`, or `TSTWei`) for human readability, using `bigint` for precision.
|
||||||
|
* @param amount - The token amount in `wei` (as a string, number, or bigint).
|
||||||
|
* @returns The formatted token amount string.
|
||||||
|
*/
|
||||||
|
export function formatTokenAmount(amount: bigint | number | string): string {
|
||||||
|
const decimals = 10n ** 18n; // 10^18 for TST
|
||||||
|
const gWeiFactor = 10n ** 9n; // 10^9 for gTSTWei
|
||||||
|
|
||||||
|
let numericAmount: bigint;
|
||||||
|
|
||||||
|
// Convert input to bigint
|
||||||
|
if (typeof amount === "string") {
|
||||||
|
numericAmount = BigInt(amount);
|
||||||
|
} else if (typeof amount === "number") {
|
||||||
|
numericAmount = BigInt(Math.floor(amount)); // Convert to an integer first
|
||||||
|
} else {
|
||||||
|
numericAmount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the amount is greater than or equal to 1 TST (10^18 wei), format in TST
|
||||||
|
if (numericAmount >= decimals) {
|
||||||
|
const wholeUnits = (numericAmount * 100n) / decimals; // Multiply by 100 to handle decimals
|
||||||
|
return (
|
||||||
|
`${Number(wholeUnits / 100n).toLocaleString()}` +
|
||||||
|
`.${String(wholeUnits % 100n).padStart(2, "0")} TST`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the amount is greater than or equal to 1 gTSTWei (10^9 wei), format in gTSTWei
|
||||||
|
if (numericAmount >= gWeiFactor) {
|
||||||
|
const wholeUnits = (numericAmount * 100n) / gWeiFactor; // Multiply by 100 to handle decimals
|
||||||
|
return (
|
||||||
|
`${Number(wholeUnits / 100n).toLocaleString()}` +
|
||||||
|
`.${String(wholeUnits % 100n).padStart(2, "0")} gTSTWei`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, format as TSTWei (smallest unit)
|
||||||
|
return `${numericAmount.toLocaleString()} TSTWei`;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user