0g-orbit 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/cli.d.ts +3 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/cli/cli.js +59 -0
- package/dist/cli/cli.js.map +1 -0
- package/dist/cli/commands/account.d.ts +6 -0
- package/dist/cli/commands/account.d.ts.map +1 -0
- package/dist/cli/commands/account.js +23 -0
- package/dist/cli/commands/account.js.map +1 -0
- package/dist/cli/commands/inference.d.ts +15 -0
- package/dist/cli/commands/inference.d.ts.map +1 -0
- package/dist/cli/commands/inference.js +70 -0
- package/dist/cli/commands/inference.js.map +1 -0
- package/dist/cli/commands/init.d.ts +7 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +60 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/storage.d.ts +19 -0
- package/dist/cli/commands/storage.d.ts.map +1 -0
- package/dist/cli/commands/storage.js +62 -0
- package/dist/cli/commands/storage.js.map +1 -0
- package/dist/cli/utils.d.ts +4 -0
- package/dist/cli/utils.d.ts.map +1 -0
- package/dist/cli/utils.js +20 -0
- package/dist/cli/utils.js.map +1 -0
- package/dist/errors.d.ts +26 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +51 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/inference.d.ts +17 -0
- package/dist/inference.d.ts.map +1 -0
- package/dist/inference.js +179 -0
- package/dist/inference.js.map +1 -0
- package/dist/networks.d.ts +16 -0
- package/dist/networks.d.ts.map +1 -0
- package/dist/networks.js +48 -0
- package/dist/networks.js.map +1 -0
- package/dist/orbit.d.ts +27 -0
- package/dist/orbit.d.ts.map +1 -0
- package/dist/orbit.js +108 -0
- package/dist/orbit.js.map +1 -0
- package/dist/retry.d.ts +23 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +90 -0
- package/dist/retry.js.map +1 -0
- package/dist/storage.d.ts +26 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +121 -0
- package/dist/storage.js.map +1 -0
- package/dist/types.d.ts +81 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/examples/ai-chatbot/index.ts +74 -0
- package/examples/model-registry/index.ts +137 -0
- package/examples/quick-start/index.ts +65 -0
- package/package.json +42 -0
- package/packages/cli/package.json +30 -0
- package/packages/cli/src/cli.ts +69 -0
- package/packages/cli/src/commands/account.ts +29 -0
- package/packages/cli/src/commands/inference.ts +103 -0
- package/packages/cli/src/commands/init.ts +71 -0
- package/packages/cli/src/commands/storage.ts +91 -0
- package/packages/cli/src/utils.ts +21 -0
- package/packages/cli/tsconfig.json +8 -0
- package/packages/core/package.json +35 -0
- package/packages/core/src/errors.test.ts +99 -0
- package/packages/core/src/errors.ts +79 -0
- package/packages/core/src/index.ts +37 -0
- package/packages/core/src/inference.ts +256 -0
- package/packages/core/src/networks.test.ts +62 -0
- package/packages/core/src/networks.ts +62 -0
- package/packages/core/src/orbit.test.ts +153 -0
- package/packages/core/src/orbit.ts +159 -0
- package/packages/core/src/retry.test.ts +99 -0
- package/packages/core/src/retry.ts +99 -0
- package/packages/core/src/storage.test.ts +199 -0
- package/packages/core/src/storage.ts +158 -0
- package/packages/core/src/types.ts +85 -0
- package/packages/core/tsconfig.json +8 -0
- package/packages/core/vitest.config.ts +7 -0
- package/src/cli/cli.ts +69 -0
- package/src/cli/commands/account.ts +29 -0
- package/src/cli/commands/inference.ts +103 -0
- package/src/cli/commands/init.ts +71 -0
- package/src/cli/commands/storage.ts +91 -0
- package/src/cli/utils.ts +21 -0
- package/src/errors.test.ts +99 -0
- package/src/errors.ts +79 -0
- package/src/index.ts +37 -0
- package/src/inference.ts +256 -0
- package/src/networks.test.ts +62 -0
- package/src/networks.ts +62 -0
- package/src/orbit.test.ts +153 -0
- package/src/orbit.ts +159 -0
- package/src/retry.test.ts +99 -0
- package/src/retry.ts +99 -0
- package/src/storage.test.ts +199 -0
- package/src/storage.ts +158 -0
- package/src/types.ts +85 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +7 -0
package/dist/storage.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { Indexer, ZgFile } from '@0gfoundation/0g-ts-sdk';
|
|
2
|
+
import { writeFileSync, unlinkSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { randomBytes } from 'node:crypto';
|
|
6
|
+
import { StorageError } from './errors.js';
|
|
7
|
+
import { withRetry, isTransientError } from './retry.js';
|
|
8
|
+
const DEFAULT_REPLICAS = 1;
|
|
9
|
+
const DEFAULT_MAX_GAS_PRICE = 25_000_000_000; // 25 gwei — generous ceiling for auto-escalation
|
|
10
|
+
export class StorageClient {
|
|
11
|
+
indexer;
|
|
12
|
+
rpcUrl;
|
|
13
|
+
signer;
|
|
14
|
+
constructor(network, signer) {
|
|
15
|
+
this.indexer = new Indexer(network.indexerUrl);
|
|
16
|
+
this.rpcUrl = network.rpcUrl;
|
|
17
|
+
this.signer = signer;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Upload a file to 0G Storage by file path.
|
|
21
|
+
* Retries transient failures automatically. Gas escalates on each retry.
|
|
22
|
+
*/
|
|
23
|
+
async store(filePath, options = {}) {
|
|
24
|
+
return withRetry(() => this._store(filePath, options), {
|
|
25
|
+
maxAttempts: 3,
|
|
26
|
+
isRetryable: (err) => {
|
|
27
|
+
if (!(err instanceof StorageError))
|
|
28
|
+
return isTransientError(err);
|
|
29
|
+
const msg = err.message.toLowerCase();
|
|
30
|
+
return msg.includes('gas') ||
|
|
31
|
+
msg.includes('timeout') ||
|
|
32
|
+
msg.includes('etimedout') ||
|
|
33
|
+
msg.includes('econnrefused') ||
|
|
34
|
+
msg.includes('underpriced');
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Upload raw data (string, Buffer, or Uint8Array) to 0G Storage.
|
|
40
|
+
* Writes to a temp file, uploads, then cleans up.
|
|
41
|
+
*/
|
|
42
|
+
async storeData(data, options = {}) {
|
|
43
|
+
const tempPath = join(tmpdir(), `orbit-${randomBytes(8).toString('hex')}`);
|
|
44
|
+
try {
|
|
45
|
+
writeFileSync(tempPath, data);
|
|
46
|
+
return await this.store(tempPath, options);
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
try {
|
|
50
|
+
unlinkSync(tempPath);
|
|
51
|
+
}
|
|
52
|
+
catch { /* ignore cleanup errors */ }
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async _store(filePath, options) {
|
|
56
|
+
const file = await ZgFile.fromFilePath(filePath);
|
|
57
|
+
try {
|
|
58
|
+
const [tree, treeErr] = await file.merkleTree();
|
|
59
|
+
if (treeErr || !tree) {
|
|
60
|
+
throw new StorageError(`Failed to compute merkle tree: ${treeErr?.message ?? 'unknown error'}`, 'Ensure the file exists, is readable, and is not empty.');
|
|
61
|
+
}
|
|
62
|
+
// Always enable gas auto-escalation via the SDK's built-in retry.
|
|
63
|
+
// MaxGasPrice sets the ceiling — the SDK starts from the network estimate
|
|
64
|
+
// and bumps 10% on each retry until it hits this cap.
|
|
65
|
+
const maxGas = options.maxGasPrice
|
|
66
|
+
? Number(options.maxGasPrice)
|
|
67
|
+
: DEFAULT_MAX_GAS_PRICE;
|
|
68
|
+
// Cast signer to avoid ESM/CJS ethers type mismatch
|
|
69
|
+
const [result, uploadErr] = await this.indexer.upload(file, this.rpcUrl, this.signer, {
|
|
70
|
+
tags: options.tags ?? '0x',
|
|
71
|
+
expectedReplica: options.replicas ?? DEFAULT_REPLICAS,
|
|
72
|
+
}, { Retries: 5, Interval: 3, MaxGasPrice: maxGas });
|
|
73
|
+
if (uploadErr) {
|
|
74
|
+
const msg = uploadErr.message;
|
|
75
|
+
let suggestion = 'Check your OG balance and try again.';
|
|
76
|
+
if (msg.includes('gas') || msg.includes('underpriced')) {
|
|
77
|
+
suggestion = `Gas auto-escalation hit the ceiling (${maxGas} wei). Try a higher maxGasPrice, e.g. { maxGasPrice: ${maxGas * 2}n }`;
|
|
78
|
+
}
|
|
79
|
+
else if (msg.includes('timeout') || msg.includes('ETIMEDOUT')) {
|
|
80
|
+
suggestion = 'The RPC endpoint timed out. Try a different RPC URL with the rpcUrl option.';
|
|
81
|
+
}
|
|
82
|
+
else if (msg.includes('insufficient funds')) {
|
|
83
|
+
suggestion = 'Your wallet needs more OG for gas. Get testnet OG from: https://faucet.0g.ai';
|
|
84
|
+
}
|
|
85
|
+
throw new StorageError(`Upload failed: ${msg}`, suggestion);
|
|
86
|
+
}
|
|
87
|
+
if ('txHash' in result) {
|
|
88
|
+
return {
|
|
89
|
+
root: result.rootHash,
|
|
90
|
+
txHash: result.txHash,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
// Fragmented upload — return the first root hash as primary handle
|
|
94
|
+
return {
|
|
95
|
+
root: result.rootHashes[0],
|
|
96
|
+
txHash: result.txHashes[0],
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
await file.close();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Download a file from 0G Storage by root hash.
|
|
105
|
+
*/
|
|
106
|
+
async retrieve(rootHash, outputPath, options = {}) {
|
|
107
|
+
return withRetry(() => this._retrieve(rootHash, outputPath, options), { maxAttempts: 3 });
|
|
108
|
+
}
|
|
109
|
+
async _retrieve(rootHash, outputPath, options) {
|
|
110
|
+
const err = await this.indexer.download(rootHash, outputPath, options.proof ?? false);
|
|
111
|
+
if (err) {
|
|
112
|
+
const msg = err.message;
|
|
113
|
+
let suggestion = 'Verify the root hash is correct and the file was uploaded successfully.';
|
|
114
|
+
if (msg.includes('not found') || msg.includes('404')) {
|
|
115
|
+
suggestion = 'This root hash was not found on the network. Double-check the hash or ensure the upload completed.';
|
|
116
|
+
}
|
|
117
|
+
throw new StorageError(`Download failed: ${msg}`, suggestion);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { NetworkName } from './networks.js';
|
|
2
|
+
export interface OrbitConfig {
|
|
3
|
+
/** Private key for signing transactions. Falls back to PRIVATE_KEY env var if omitted. */
|
|
4
|
+
privateKey?: string;
|
|
5
|
+
/** Network to connect to */
|
|
6
|
+
network: NetworkName;
|
|
7
|
+
/** Custom RPC URL (overrides network default) */
|
|
8
|
+
rpcUrl?: string;
|
|
9
|
+
/** Custom indexer URL (overrides network default) */
|
|
10
|
+
indexerUrl?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface StoreResult {
|
|
13
|
+
/** Merkle root hash — use this to retrieve the file */
|
|
14
|
+
root: string;
|
|
15
|
+
/** On-chain transaction hash */
|
|
16
|
+
txHash: string;
|
|
17
|
+
}
|
|
18
|
+
export interface StoreOptions {
|
|
19
|
+
/** Custom tags for the upload (hex string) */
|
|
20
|
+
tags?: string;
|
|
21
|
+
/** Expected number of replicas */
|
|
22
|
+
replicas?: number;
|
|
23
|
+
/** Maximum gas price in wei */
|
|
24
|
+
maxGasPrice?: bigint;
|
|
25
|
+
}
|
|
26
|
+
export interface RetrieveOptions {
|
|
27
|
+
/** Whether to verify merkle proofs during download */
|
|
28
|
+
proof?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface InferResult {
|
|
31
|
+
/** The model's response text */
|
|
32
|
+
content: string;
|
|
33
|
+
/** The model used */
|
|
34
|
+
model: string;
|
|
35
|
+
/** Token usage */
|
|
36
|
+
usage?: {
|
|
37
|
+
promptTokens: number;
|
|
38
|
+
completionTokens: number;
|
|
39
|
+
totalTokens: number;
|
|
40
|
+
};
|
|
41
|
+
/** Whether the response passed TEE verification (null if not verifiable) */
|
|
42
|
+
verified: boolean | null;
|
|
43
|
+
}
|
|
44
|
+
export interface InferOptions {
|
|
45
|
+
/** Messages for chat completion */
|
|
46
|
+
messages: Array<{
|
|
47
|
+
role: 'system' | 'user' | 'assistant';
|
|
48
|
+
content: string;
|
|
49
|
+
}>;
|
|
50
|
+
/** Temperature for sampling (0-2) */
|
|
51
|
+
temperature?: number;
|
|
52
|
+
/** Maximum tokens to generate */
|
|
53
|
+
maxTokens?: number;
|
|
54
|
+
/** Specific provider address (auto-selected if omitted) */
|
|
55
|
+
provider?: string;
|
|
56
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
57
|
+
timeout?: number;
|
|
58
|
+
}
|
|
59
|
+
export interface ServiceInfo {
|
|
60
|
+
/** Provider wallet address */
|
|
61
|
+
provider: string;
|
|
62
|
+
/** Model name */
|
|
63
|
+
model: string;
|
|
64
|
+
/** Service endpoint URL */
|
|
65
|
+
url: string;
|
|
66
|
+
/** Input token price (neuron) */
|
|
67
|
+
inputPrice: bigint;
|
|
68
|
+
/** Output token price (neuron) */
|
|
69
|
+
outputPrice: bigint;
|
|
70
|
+
/** Whether TEE verification is available */
|
|
71
|
+
verifiable: boolean;
|
|
72
|
+
}
|
|
73
|
+
export interface AccountStatus {
|
|
74
|
+
/** Main ledger balance in OG */
|
|
75
|
+
balance: string;
|
|
76
|
+
/** Network name */
|
|
77
|
+
network: NetworkName;
|
|
78
|
+
/** Wallet address */
|
|
79
|
+
address: string;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEhD,MAAM,WAAW,WAAW;IACxB,0FAA0F;IAC1F,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,4BAA4B;IAC5B,OAAO,EAAE,WAAW,CAAA;IACpB,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,WAAW;IACxB,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAA;IACZ,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,YAAY;IACzB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,+BAA+B;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,eAAe;IAC5B,sDAAsD;IACtD,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IACxB,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAA;IACf,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,kBAAkB;IAClB,KAAK,CAAC,EAAE;QACJ,YAAY,EAAE,MAAM,CAAA;QACpB,gBAAgB,EAAE,MAAM,CAAA;QACxB,WAAW,EAAE,MAAM,CAAA;KACtB,CAAA;IACD,4EAA4E;IAC5E,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAA;CAC3B;AAED,MAAM,WAAW,YAAY;IACzB,mCAAmC;IACnC,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC3E,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,WAAW;IACxB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,iBAAiB;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,2BAA2B;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAA;IACnB,4CAA4C;IAC5C,UAAU,EAAE,OAAO,CAAA;CACtB;AAED,MAAM,WAAW,aAAa;IAC1B,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAA;IACf,mBAAmB;IACnB,OAAO,EAAE,WAAW,CAAA;IACpB,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAA;CAClB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 0G Orbit — AI Chatbot Example
|
|
3
|
+
*
|
|
4
|
+
* A simple interactive chatbot using 0G Compute Network.
|
|
5
|
+
* Demonstrates multi-turn conversations with TEE verification.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* PRIVATE_KEY=0x... npx tsx index.ts
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { Orbit } from '@0g-orbit/core'
|
|
12
|
+
import { createInterface } from 'node:readline'
|
|
13
|
+
|
|
14
|
+
const MODEL = 'meta-llama/Llama-3.3-70B'
|
|
15
|
+
|
|
16
|
+
async function main() {
|
|
17
|
+
const orbit = await Orbit.connect({
|
|
18
|
+
network: 'testnet',
|
|
19
|
+
privateKey: process.env.PRIVATE_KEY!,
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
const status = await orbit.status()
|
|
23
|
+
console.log(`Connected: ${status.address} (${status.balance} OG)`)
|
|
24
|
+
console.log(`Model: ${MODEL}`)
|
|
25
|
+
console.log('Type "quit" to exit.\n')
|
|
26
|
+
|
|
27
|
+
const history: Array<{ role: 'system' | 'user' | 'assistant'; content: string }> = [
|
|
28
|
+
{
|
|
29
|
+
role: 'system',
|
|
30
|
+
content: 'You are a helpful AI assistant running on 0G decentralized compute. Be concise.',
|
|
31
|
+
},
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
const rl = createInterface({
|
|
35
|
+
input: process.stdin,
|
|
36
|
+
output: process.stdout,
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const ask = (prompt: string): Promise<string> =>
|
|
40
|
+
new Promise((resolve) => rl.question(prompt, resolve))
|
|
41
|
+
|
|
42
|
+
while (true) {
|
|
43
|
+
const input = await ask('You: ')
|
|
44
|
+
if (input.toLowerCase() === 'quit') break
|
|
45
|
+
if (!input.trim()) continue
|
|
46
|
+
|
|
47
|
+
history.push({ role: 'user', content: input })
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
const result = await orbit.infer(MODEL, {
|
|
51
|
+
messages: history,
|
|
52
|
+
temperature: 0.7,
|
|
53
|
+
maxTokens: 1024,
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
history.push({ role: 'assistant', content: result.content })
|
|
57
|
+
|
|
58
|
+
console.log(`\nAssistant: ${result.content}`)
|
|
59
|
+
|
|
60
|
+
const meta: string[] = []
|
|
61
|
+
if (result.usage) meta.push(`${result.usage.totalTokens} tokens`)
|
|
62
|
+
if (result.verified === true) meta.push('TEE verified')
|
|
63
|
+
if (meta.length) console.log(` (${meta.join(' | ')})`)
|
|
64
|
+
console.log()
|
|
65
|
+
} catch (err) {
|
|
66
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}\n`)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
rl.close()
|
|
71
|
+
console.log('Goodbye!')
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
main().catch(console.error)
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 0G Orbit — Model Registry Example
|
|
3
|
+
*
|
|
4
|
+
* Store AI model weights on 0G Storage and maintain
|
|
5
|
+
* a registry of model versions with their root hashes.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* PRIVATE_KEY=0x... npx tsx index.ts
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { Orbit } from '@0g-orbit/core'
|
|
12
|
+
import { writeFileSync, readFileSync, existsSync } from 'node:fs'
|
|
13
|
+
|
|
14
|
+
const REGISTRY_FILE = './registry.json'
|
|
15
|
+
|
|
16
|
+
interface ModelEntry {
|
|
17
|
+
name: string
|
|
18
|
+
version: string
|
|
19
|
+
rootHash: string
|
|
20
|
+
txHash: string
|
|
21
|
+
uploadedAt: string
|
|
22
|
+
sizeBytes?: number
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface Registry {
|
|
26
|
+
models: ModelEntry[]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function loadRegistry(): Registry {
|
|
30
|
+
if (existsSync(REGISTRY_FILE)) {
|
|
31
|
+
return JSON.parse(readFileSync(REGISTRY_FILE, 'utf-8'))
|
|
32
|
+
}
|
|
33
|
+
return { models: [] }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function saveRegistry(registry: Registry) {
|
|
37
|
+
writeFileSync(REGISTRY_FILE, JSON.stringify(registry, null, 2) + '\n')
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function registerModel(
|
|
41
|
+
orbit: Orbit,
|
|
42
|
+
name: string,
|
|
43
|
+
version: string,
|
|
44
|
+
filePath: string
|
|
45
|
+
) {
|
|
46
|
+
console.log(`\nUploading ${name} v${version}...`)
|
|
47
|
+
const { root, txHash } = await orbit.store(filePath)
|
|
48
|
+
|
|
49
|
+
const registry = loadRegistry()
|
|
50
|
+
registry.models.push({
|
|
51
|
+
name,
|
|
52
|
+
version,
|
|
53
|
+
rootHash: root,
|
|
54
|
+
txHash,
|
|
55
|
+
uploadedAt: new Date().toISOString(),
|
|
56
|
+
})
|
|
57
|
+
saveRegistry(registry)
|
|
58
|
+
|
|
59
|
+
console.log(`Registered: ${name} v${version}`)
|
|
60
|
+
console.log(` Root: ${root}`)
|
|
61
|
+
console.log(` Tx: ${txHash}`)
|
|
62
|
+
return root
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async function downloadModel(
|
|
66
|
+
orbit: Orbit,
|
|
67
|
+
name: string,
|
|
68
|
+
version: string,
|
|
69
|
+
outputPath: string
|
|
70
|
+
) {
|
|
71
|
+
const registry = loadRegistry()
|
|
72
|
+
const entry = registry.models.find(
|
|
73
|
+
(m) => m.name === name && m.version === version
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
if (!entry) {
|
|
77
|
+
console.error(`Model ${name} v${version} not found in registry.`)
|
|
78
|
+
return
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
console.log(`\nDownloading ${name} v${version}...`)
|
|
82
|
+
await orbit.retrieve(entry.rootHash, outputPath)
|
|
83
|
+
console.log(`Downloaded to ${outputPath}`)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function listModels() {
|
|
87
|
+
const registry = loadRegistry()
|
|
88
|
+
if (registry.models.length === 0) {
|
|
89
|
+
console.log('No models registered.')
|
|
90
|
+
return
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
console.log('\nRegistered models:')
|
|
94
|
+
for (const m of registry.models) {
|
|
95
|
+
console.log(` ${m.name} v${m.version}`)
|
|
96
|
+
console.log(` root: ${m.rootHash}`)
|
|
97
|
+
console.log(` date: ${m.uploadedAt}`)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function main() {
|
|
102
|
+
const orbit = await Orbit.connect({
|
|
103
|
+
network: 'testnet',
|
|
104
|
+
privateKey: process.env.PRIVATE_KEY!,
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
const status = await orbit.status()
|
|
108
|
+
console.log(`Connected: ${status.address} (${status.balance} OG)`)
|
|
109
|
+
|
|
110
|
+
const command = process.argv[2] || 'list'
|
|
111
|
+
|
|
112
|
+
switch (command) {
|
|
113
|
+
case 'register': {
|
|
114
|
+
const [, , , name, version, filePath] = process.argv
|
|
115
|
+
if (!name || !version || !filePath) {
|
|
116
|
+
console.error('Usage: npx tsx index.ts register <name> <version> <file>')
|
|
117
|
+
process.exit(1)
|
|
118
|
+
}
|
|
119
|
+
await registerModel(orbit, name, version, filePath)
|
|
120
|
+
break
|
|
121
|
+
}
|
|
122
|
+
case 'download': {
|
|
123
|
+
const [, , , name, version, outputPath] = process.argv
|
|
124
|
+
if (!name || !version || !outputPath) {
|
|
125
|
+
console.error('Usage: npx tsx index.ts download <name> <version> <output>')
|
|
126
|
+
process.exit(1)
|
|
127
|
+
}
|
|
128
|
+
await downloadModel(orbit, name, version, outputPath)
|
|
129
|
+
break
|
|
130
|
+
}
|
|
131
|
+
case 'list':
|
|
132
|
+
default:
|
|
133
|
+
listModels()
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
main().catch(console.error)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 0G Orbit — Quick Start
|
|
3
|
+
*
|
|
4
|
+
* Demonstrates the three core operations:
|
|
5
|
+
* 1. Check account status
|
|
6
|
+
* 2. Store a file to 0G Storage
|
|
7
|
+
* 3. Run AI inference on 0G Compute
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* PRIVATE_KEY=0x... npx tsx index.ts
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { Orbit } from '@0g-orbit/core'
|
|
14
|
+
import { writeFileSync, unlinkSync } from 'node:fs'
|
|
15
|
+
|
|
16
|
+
async function main() {
|
|
17
|
+
// Connect
|
|
18
|
+
const orbit = await Orbit.connect({
|
|
19
|
+
network: 'testnet',
|
|
20
|
+
privateKey: process.env.PRIVATE_KEY!,
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
// 1. Account status
|
|
24
|
+
const status = await orbit.status()
|
|
25
|
+
console.log(`Connected: ${status.address}`)
|
|
26
|
+
console.log(`Balance: ${status.balance} OG on ${status.network}`)
|
|
27
|
+
|
|
28
|
+
// 2. Store a file
|
|
29
|
+
const testFile = '/tmp/orbit-test.txt'
|
|
30
|
+
writeFileSync(testFile, 'Hello from 0G Orbit!')
|
|
31
|
+
|
|
32
|
+
console.log('\nUploading file...')
|
|
33
|
+
const { root, txHash } = await orbit.store(testFile)
|
|
34
|
+
console.log(`Stored! Root: ${root}`)
|
|
35
|
+
console.log(`Tx: ${txHash}`)
|
|
36
|
+
|
|
37
|
+
unlinkSync(testFile)
|
|
38
|
+
|
|
39
|
+
// 3. Retrieve it back
|
|
40
|
+
const outputFile = '/tmp/orbit-test-downloaded.txt'
|
|
41
|
+
console.log('\nDownloading...')
|
|
42
|
+
await orbit.retrieve(root, outputFile)
|
|
43
|
+
console.log(`Downloaded to ${outputFile}`)
|
|
44
|
+
|
|
45
|
+
// 4. AI inference
|
|
46
|
+
console.log('\nRunning inference...')
|
|
47
|
+
const result = await orbit.infer('meta-llama/Llama-3.3-70B', {
|
|
48
|
+
messages: [
|
|
49
|
+
{ role: 'system', content: 'You are a helpful assistant.' },
|
|
50
|
+
{ role: 'user', content: 'Explain what 0G is in one sentence.' },
|
|
51
|
+
],
|
|
52
|
+
temperature: 0.7,
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
console.log(`\nResponse: ${result.content}`)
|
|
56
|
+
console.log(`Model: ${result.model}`)
|
|
57
|
+
if (result.usage) {
|
|
58
|
+
console.log(`Tokens: ${result.usage.totalTokens}`)
|
|
59
|
+
}
|
|
60
|
+
if (result.verified !== null) {
|
|
61
|
+
console.log(`Verified: ${result.verified}`)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
main().catch(console.error)
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "0g-orbit",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The developer toolkit for 0G. Store, infer, deploy — one SDK, one CLI, five minutes.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"orbit": "./dist/cli/cli.js"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"test:watch": "vitest",
|
|
21
|
+
"lint": "tsc --noEmit",
|
|
22
|
+
"clean": "rm -rf dist"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@0gfoundation/0g-ts-sdk": "^1.0.1",
|
|
26
|
+
"@0glabs/0g-serving-broker": "^0.7.4",
|
|
27
|
+
"chalk": "^5.3.0",
|
|
28
|
+
"commander": "^12.1.0",
|
|
29
|
+
"ethers": "^6.13.1",
|
|
30
|
+
"ora": "^8.0.1"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^20.12.0",
|
|
34
|
+
"typescript": "^5.4.0",
|
|
35
|
+
"vitest": "^1.6.0"
|
|
36
|
+
},
|
|
37
|
+
"keywords": ["0g", "blockchain", "ai", "storage", "inference", "sdk", "cli"],
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18.0.0"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "0g-orbit-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI for 0G Orbit — store, infer, deploy from your terminal.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"orbit": "./dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"dev": "tsc --watch",
|
|
12
|
+
"lint": "tsc --noEmit",
|
|
13
|
+
"clean": "rm -rf dist"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"0g-orbit-core": "workspace:*",
|
|
17
|
+
"commander": "^12.1.0",
|
|
18
|
+
"ora": "^8.0.1",
|
|
19
|
+
"chalk": "^5.3.0"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"typescript": "^5.4.0",
|
|
23
|
+
"@types/node": "^20.12.0"
|
|
24
|
+
},
|
|
25
|
+
"keywords": ["0g", "cli", "blockchain", "ai"],
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=18.0.0"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander'
|
|
4
|
+
import { storeCommand, storeDataCommand, retrieveCommand } from './commands/storage.js'
|
|
5
|
+
import { inferCommand, listServicesCommand } from './commands/inference.js'
|
|
6
|
+
import { statusCommand } from './commands/account.js'
|
|
7
|
+
import { initCommand } from './commands/init.js'
|
|
8
|
+
|
|
9
|
+
const program = new Command()
|
|
10
|
+
|
|
11
|
+
program
|
|
12
|
+
.name('orbit')
|
|
13
|
+
.description('The developer toolkit for 0G')
|
|
14
|
+
.version('0.1.0')
|
|
15
|
+
|
|
16
|
+
program
|
|
17
|
+
.command('init')
|
|
18
|
+
.description('Initialize a new 0G project')
|
|
19
|
+
.option('-t, --template <name>', 'template to use', 'default')
|
|
20
|
+
.option('-d, --dir <path>', 'directory to create', '.')
|
|
21
|
+
.action(initCommand)
|
|
22
|
+
|
|
23
|
+
program
|
|
24
|
+
.command('store <file>')
|
|
25
|
+
.description('Upload a file to 0G Storage')
|
|
26
|
+
.option('-n, --network <name>', 'network (testnet|mainnet)', 'testnet')
|
|
27
|
+
.option('--tags <hex>', 'custom tags (hex string)')
|
|
28
|
+
.option('--replicas <n>', 'number of replicas', '1')
|
|
29
|
+
.action(storeCommand)
|
|
30
|
+
|
|
31
|
+
program
|
|
32
|
+
.command('store-data <text>')
|
|
33
|
+
.description('Upload a text string to 0G Storage')
|
|
34
|
+
.option('-n, --network <name>', 'network (testnet|mainnet)', 'testnet')
|
|
35
|
+
.option('--tags <hex>', 'custom tags (hex string)')
|
|
36
|
+
.option('--replicas <n>', 'number of replicas', '1')
|
|
37
|
+
.action(storeDataCommand)
|
|
38
|
+
|
|
39
|
+
program
|
|
40
|
+
.command('retrieve <rootHash> <output>')
|
|
41
|
+
.description('Download a file from 0G Storage')
|
|
42
|
+
.option('-n, --network <name>', 'network (testnet|mainnet)', 'testnet')
|
|
43
|
+
.option('--proof', 'verify merkle proofs during download')
|
|
44
|
+
.action(retrieveCommand)
|
|
45
|
+
|
|
46
|
+
program
|
|
47
|
+
.command('infer <model>')
|
|
48
|
+
.description('Run AI inference on the 0G Compute Network')
|
|
49
|
+
.option('-n, --network <name>', 'network (testnet|mainnet)', 'testnet')
|
|
50
|
+
.option('-m, --message <text>', 'message to send')
|
|
51
|
+
.option('-s, --system <text>', 'system prompt')
|
|
52
|
+
.option('-t, --temperature <n>', 'sampling temperature', '0.7')
|
|
53
|
+
.option('--max-tokens <n>', 'maximum tokens to generate')
|
|
54
|
+
.option('--provider <address>', 'specific provider address')
|
|
55
|
+
.action(inferCommand)
|
|
56
|
+
|
|
57
|
+
program
|
|
58
|
+
.command('services')
|
|
59
|
+
.description('List available AI services on the network')
|
|
60
|
+
.option('-n, --network <name>', 'network (testnet|mainnet)', 'testnet')
|
|
61
|
+
.action(listServicesCommand)
|
|
62
|
+
|
|
63
|
+
program
|
|
64
|
+
.command('status')
|
|
65
|
+
.description('Show account status and balance')
|
|
66
|
+
.option('-n, --network <name>', 'network (testnet|mainnet)', 'testnet')
|
|
67
|
+
.action(statusCommand)
|
|
68
|
+
|
|
69
|
+
program.parse()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import ora from 'ora'
|
|
2
|
+
import chalk from 'chalk'
|
|
3
|
+
import { connectOrbit, formatError } from '../utils.js'
|
|
4
|
+
|
|
5
|
+
interface StatusOpts {
|
|
6
|
+
network: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export async function statusCommand(opts: StatusOpts) {
|
|
10
|
+
const spinner = ora('Checking status...').start()
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
const orbit = await connectOrbit(opts.network)
|
|
14
|
+
const status = await orbit.status()
|
|
15
|
+
|
|
16
|
+
spinner.stop()
|
|
17
|
+
|
|
18
|
+
console.log()
|
|
19
|
+
console.log(chalk.bold(' 0G Orbit'))
|
|
20
|
+
console.log(` ${chalk.dim('Network:')} ${status.network}`)
|
|
21
|
+
console.log(` ${chalk.dim('Address:')} ${status.address}`)
|
|
22
|
+
console.log(` ${chalk.dim('Balance:')} ${chalk.cyan(status.balance)} OG`)
|
|
23
|
+
console.log()
|
|
24
|
+
} catch (err) {
|
|
25
|
+
spinner.fail(chalk.red('Failed to get status'))
|
|
26
|
+
console.error(chalk.dim(` ${formatError(err)}`))
|
|
27
|
+
process.exit(1)
|
|
28
|
+
}
|
|
29
|
+
}
|