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.
Files changed (105) hide show
  1. package/dist/cli/cli.d.ts +3 -0
  2. package/dist/cli/cli.d.ts.map +1 -0
  3. package/dist/cli/cli.js +59 -0
  4. package/dist/cli/cli.js.map +1 -0
  5. package/dist/cli/commands/account.d.ts +6 -0
  6. package/dist/cli/commands/account.d.ts.map +1 -0
  7. package/dist/cli/commands/account.js +23 -0
  8. package/dist/cli/commands/account.js.map +1 -0
  9. package/dist/cli/commands/inference.d.ts +15 -0
  10. package/dist/cli/commands/inference.d.ts.map +1 -0
  11. package/dist/cli/commands/inference.js +70 -0
  12. package/dist/cli/commands/inference.js.map +1 -0
  13. package/dist/cli/commands/init.d.ts +7 -0
  14. package/dist/cli/commands/init.d.ts.map +1 -0
  15. package/dist/cli/commands/init.js +60 -0
  16. package/dist/cli/commands/init.js.map +1 -0
  17. package/dist/cli/commands/storage.d.ts +19 -0
  18. package/dist/cli/commands/storage.d.ts.map +1 -0
  19. package/dist/cli/commands/storage.js +62 -0
  20. package/dist/cli/commands/storage.js.map +1 -0
  21. package/dist/cli/utils.d.ts +4 -0
  22. package/dist/cli/utils.d.ts.map +1 -0
  23. package/dist/cli/utils.js +20 -0
  24. package/dist/cli/utils.js.map +1 -0
  25. package/dist/errors.d.ts +26 -0
  26. package/dist/errors.d.ts.map +1 -0
  27. package/dist/errors.js +51 -0
  28. package/dist/errors.js.map +1 -0
  29. package/dist/index.d.ts +10 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +11 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/inference.d.ts +17 -0
  34. package/dist/inference.d.ts.map +1 -0
  35. package/dist/inference.js +179 -0
  36. package/dist/inference.js.map +1 -0
  37. package/dist/networks.d.ts +16 -0
  38. package/dist/networks.d.ts.map +1 -0
  39. package/dist/networks.js +48 -0
  40. package/dist/networks.js.map +1 -0
  41. package/dist/orbit.d.ts +27 -0
  42. package/dist/orbit.d.ts.map +1 -0
  43. package/dist/orbit.js +108 -0
  44. package/dist/orbit.js.map +1 -0
  45. package/dist/retry.d.ts +23 -0
  46. package/dist/retry.d.ts.map +1 -0
  47. package/dist/retry.js +90 -0
  48. package/dist/retry.js.map +1 -0
  49. package/dist/storage.d.ts +26 -0
  50. package/dist/storage.d.ts.map +1 -0
  51. package/dist/storage.js +121 -0
  52. package/dist/storage.js.map +1 -0
  53. package/dist/types.d.ts +81 -0
  54. package/dist/types.d.ts.map +1 -0
  55. package/dist/types.js +2 -0
  56. package/dist/types.js.map +1 -0
  57. package/examples/ai-chatbot/index.ts +74 -0
  58. package/examples/model-registry/index.ts +137 -0
  59. package/examples/quick-start/index.ts +65 -0
  60. package/package.json +42 -0
  61. package/packages/cli/package.json +30 -0
  62. package/packages/cli/src/cli.ts +69 -0
  63. package/packages/cli/src/commands/account.ts +29 -0
  64. package/packages/cli/src/commands/inference.ts +103 -0
  65. package/packages/cli/src/commands/init.ts +71 -0
  66. package/packages/cli/src/commands/storage.ts +91 -0
  67. package/packages/cli/src/utils.ts +21 -0
  68. package/packages/cli/tsconfig.json +8 -0
  69. package/packages/core/package.json +35 -0
  70. package/packages/core/src/errors.test.ts +99 -0
  71. package/packages/core/src/errors.ts +79 -0
  72. package/packages/core/src/index.ts +37 -0
  73. package/packages/core/src/inference.ts +256 -0
  74. package/packages/core/src/networks.test.ts +62 -0
  75. package/packages/core/src/networks.ts +62 -0
  76. package/packages/core/src/orbit.test.ts +153 -0
  77. package/packages/core/src/orbit.ts +159 -0
  78. package/packages/core/src/retry.test.ts +99 -0
  79. package/packages/core/src/retry.ts +99 -0
  80. package/packages/core/src/storage.test.ts +199 -0
  81. package/packages/core/src/storage.ts +158 -0
  82. package/packages/core/src/types.ts +85 -0
  83. package/packages/core/tsconfig.json +8 -0
  84. package/packages/core/vitest.config.ts +7 -0
  85. package/src/cli/cli.ts +69 -0
  86. package/src/cli/commands/account.ts +29 -0
  87. package/src/cli/commands/inference.ts +103 -0
  88. package/src/cli/commands/init.ts +71 -0
  89. package/src/cli/commands/storage.ts +91 -0
  90. package/src/cli/utils.ts +21 -0
  91. package/src/errors.test.ts +99 -0
  92. package/src/errors.ts +79 -0
  93. package/src/index.ts +37 -0
  94. package/src/inference.ts +256 -0
  95. package/src/networks.test.ts +62 -0
  96. package/src/networks.ts +62 -0
  97. package/src/orbit.test.ts +153 -0
  98. package/src/orbit.ts +159 -0
  99. package/src/retry.test.ts +99 -0
  100. package/src/retry.ts +99 -0
  101. package/src/storage.test.ts +199 -0
  102. package/src/storage.ts +158 -0
  103. package/src/types.ts +85 -0
  104. package/tsconfig.json +20 -0
  105. package/vitest.config.ts +7 -0
@@ -0,0 +1,179 @@
1
+ import { createZGComputeNetworkBroker, } from '@0glabs/0g-serving-broker';
2
+ import { InferenceError, ProviderNotFoundError, TimeoutError } from './errors.js';
3
+ import { withRetry } from './retry.js';
4
+ const DEFAULT_LEDGER_DEPOSIT = 0.1; // 0.1 OG initial deposit
5
+ const AUTO_FUND_INTERVAL = 30_000; // 30 seconds
6
+ const DEFAULT_TIMEOUT = 30_000; // 30 seconds
7
+ export class InferenceClient {
8
+ broker = null;
9
+ wallet;
10
+ network;
11
+ initialized = false;
12
+ constructor(network, wallet) {
13
+ this.network = network;
14
+ this.wallet = wallet;
15
+ }
16
+ async ensureBroker() {
17
+ if (this.broker && this.initialized)
18
+ return this.broker;
19
+ try {
20
+ // Cast wallet to avoid ESM/CJS ethers type mismatch
21
+ this.broker = await createZGComputeNetworkBroker(this.wallet, this.network.ledgerContractAddress, this.network.inferenceContractAddress, this.network.fineTuningContractAddress);
22
+ this.initialized = true;
23
+ return this.broker;
24
+ }
25
+ catch (err) {
26
+ const msg = err instanceof Error ? err.message : String(err);
27
+ throw new InferenceError(`Failed to initialize compute broker: ${msg}`, 'Check your network connection and wallet private key. The compute contracts may be temporarily unavailable.');
28
+ }
29
+ }
30
+ async listServices() {
31
+ const broker = await this.ensureBroker();
32
+ return withRetry(async () => {
33
+ try {
34
+ const services = await broker.inference.listService();
35
+ return services.map((s) => ({
36
+ provider: s.provider ?? s.address ?? '',
37
+ model: s.model ?? '',
38
+ url: s.url ?? '',
39
+ inputPrice: BigInt(s.inputPrice ?? 0),
40
+ outputPrice: BigInt(s.outputPrice ?? 0),
41
+ verifiable: Boolean(s.verifiability ?? s.verifiable),
42
+ }));
43
+ }
44
+ catch (err) {
45
+ const msg = err instanceof Error ? err.message : String(err);
46
+ throw new InferenceError(`Failed to list services: ${msg}`, 'The inference contract may be temporarily unavailable. Check your network connection.');
47
+ }
48
+ }, { maxAttempts: 3 });
49
+ }
50
+ async infer(model, options) {
51
+ const broker = await this.ensureBroker();
52
+ // Find a provider for the requested model
53
+ const providerAddress = options.provider ?? await this.findProvider(model);
54
+ const timeout = options.timeout ?? DEFAULT_TIMEOUT;
55
+ try {
56
+ // Ensure ledger exists and has funds
57
+ await this.ensureLedgerFunded(broker);
58
+ // Start auto-funding for this provider
59
+ await broker.inference.startAutoFunding(providerAddress, {
60
+ interval: AUTO_FUND_INTERVAL,
61
+ });
62
+ // Get service metadata (endpoint + model name)
63
+ const { endpoint, model: providerModel } = await broker.inference.getServiceMetadata(providerAddress);
64
+ // Build the request content for billing calculation
65
+ const content = options.messages.map((m) => m.content).join('\n');
66
+ // Get authenticated headers
67
+ const headers = await broker.inference.getRequestHeaders(providerAddress, content);
68
+ // Make the OpenAI-compatible request with timeout + retry
69
+ const data = await withRetry(() => this.fetchCompletion(endpoint, providerModel, options, headers, timeout), {
70
+ maxAttempts: 2,
71
+ baseDelay: 2000,
72
+ isRetryable: (err) => {
73
+ // Don't retry timeouts (user already waited long enough)
74
+ if (err instanceof TimeoutError)
75
+ return false;
76
+ // Retry transient provider errors
77
+ if (err instanceof InferenceError) {
78
+ const msg = err.message;
79
+ return msg.includes('502') || msg.includes('503') || msg.includes('504');
80
+ }
81
+ return false;
82
+ },
83
+ });
84
+ // Extract chatID for TEE verification
85
+ const chatID = data._chatID;
86
+ // Process response (caches fees + verifies TEE signature)
87
+ let verified = null;
88
+ try {
89
+ verified = await broker.inference.processResponse(providerAddress, chatID, data.usage ? JSON.stringify(data.usage) : undefined);
90
+ }
91
+ catch {
92
+ // Verification failure is non-fatal
93
+ verified = null;
94
+ }
95
+ // Stop auto-funding
96
+ broker.inference.stopAutoFunding(providerAddress);
97
+ return {
98
+ content: data.choices?.[0]?.message?.content ?? '',
99
+ model: data.model ?? providerModel,
100
+ usage: data.usage
101
+ ? {
102
+ promptTokens: data.usage.prompt_tokens ?? 0,
103
+ completionTokens: data.usage.completion_tokens ?? 0,
104
+ totalTokens: data.usage.total_tokens ?? 0,
105
+ }
106
+ : undefined,
107
+ verified,
108
+ };
109
+ }
110
+ catch (err) {
111
+ // Clean up auto-funding on error
112
+ broker.inference.stopAutoFunding(providerAddress);
113
+ if (err instanceof InferenceError || err instanceof TimeoutError || err instanceof ProviderNotFoundError)
114
+ throw err;
115
+ const msg = err instanceof Error ? err.message : String(err);
116
+ throw new InferenceError(`Inference failed: ${msg}`);
117
+ }
118
+ }
119
+ async fetchCompletion(endpoint, providerModel, options, headers, timeout) {
120
+ const controller = new AbortController();
121
+ const timer = setTimeout(() => controller.abort(), timeout);
122
+ let response;
123
+ try {
124
+ response = await fetch(`${endpoint}/chat/completions`, {
125
+ method: 'POST',
126
+ headers: {
127
+ 'Content-Type': 'application/json',
128
+ ...headers,
129
+ },
130
+ body: JSON.stringify({
131
+ model: providerModel,
132
+ messages: options.messages,
133
+ temperature: options.temperature,
134
+ max_tokens: options.maxTokens,
135
+ }),
136
+ signal: controller.signal,
137
+ });
138
+ }
139
+ catch (err) {
140
+ if (err instanceof Error && err.name === 'AbortError') {
141
+ throw new TimeoutError(`Inference request timed out after ${timeout / 1000}s.`);
142
+ }
143
+ throw err;
144
+ }
145
+ finally {
146
+ clearTimeout(timer);
147
+ }
148
+ if (!response.ok) {
149
+ const body = await response.text().catch(() => '');
150
+ throw new InferenceError(`Provider returned ${response.status}: ${body}`, response.status === 429
151
+ ? 'Provider is rate-limited. Wait a moment and retry, or try a different provider.'
152
+ : response.status >= 500
153
+ ? 'The provider is experiencing issues. Try a different provider with the provider option.'
154
+ : 'Check the model name and request parameters.');
155
+ }
156
+ const data = (await response.json());
157
+ const chatID = response.headers.get('ZG-Res-Key') ?? data.id ?? undefined;
158
+ return { ...data, _chatID: chatID };
159
+ }
160
+ async findProvider(model) {
161
+ const services = await this.listServices();
162
+ const match = services.find((s) => s.model.toLowerCase() === model.toLowerCase());
163
+ if (!match) {
164
+ const available = [...new Set(services.map((s) => s.model))].join(', ') || 'none';
165
+ throw new ProviderNotFoundError(`No provider found for model "${model}". Available models: ${available}`);
166
+ }
167
+ return match.provider;
168
+ }
169
+ async ensureLedgerFunded(broker) {
170
+ try {
171
+ await broker.ledger.getLedger();
172
+ }
173
+ catch {
174
+ // Ledger doesn't exist yet — create it with initial deposit
175
+ await broker.ledger.addLedger(DEFAULT_LEDGER_DEPOSIT);
176
+ }
177
+ }
178
+ }
179
+ //# sourceMappingURL=inference.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inference.js","sourceRoot":"","sources":["../src/inference.ts"],"names":[],"mappings":"AACA,OAAO,EACH,4BAA4B,GAE/B,MAAM,2BAA2B,CAAA;AAGlC,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAEtC,MAAM,sBAAsB,GAAG,GAAG,CAAA,CAAC,yBAAyB;AAC5D,MAAM,kBAAkB,GAAG,MAAM,CAAA,CAAC,aAAa;AAC/C,MAAM,eAAe,GAAG,MAAM,CAAA,CAAC,aAAa;AAa5C,MAAM,OAAO,eAAe;IAChB,MAAM,GAAkC,IAAI,CAAA;IAC5C,MAAM,CAAQ;IACd,OAAO,CAAe;IACtB,WAAW,GAAG,KAAK,CAAA;IAE3B,YAAY,OAAsB,EAAE,MAAc;QAC9C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACxB,CAAC;IAEO,KAAK,CAAC,YAAY;QACtB,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAC,MAAM,CAAA;QAEvD,IAAI,CAAC;YACD,oDAAoD;YACpD,IAAI,CAAC,MAAM,GAAG,MAAM,4BAA4B,CAC5C,IAAI,CAAC,MAAa,EAClB,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAClC,IAAI,CAAC,OAAO,CAAC,wBAAwB,EACrC,IAAI,CAAC,OAAO,CAAC,yBAAyB,CACzC,CAAA;YACD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;YACvB,OAAO,IAAI,CAAC,MAAM,CAAA;QACtB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACpB,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAC5D,MAAM,IAAI,cAAc,CACpB,wCAAwC,GAAG,EAAE,EAC7C,6GAA6G,CAChH,CAAA;QACL,CAAC;IACL,CAAC;IAED,KAAK,CAAC,YAAY;QACd,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;QACxC,OAAO,SAAS,CACZ,KAAK,IAAI,EAAE;YACP,IAAI,CAAC;gBACD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAA;gBACrD,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;oBAC7B,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,OAAO,IAAI,EAAE;oBACvC,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE;oBACpB,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE;oBAChB,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC;oBACrC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC;oBACvC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,UAAU,CAAC;iBACvD,CAAC,CAAC,CAAA;YACP,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACpB,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;gBAC5D,MAAM,IAAI,cAAc,CACpB,4BAA4B,GAAG,EAAE,EACjC,uFAAuF,CAC1F,CAAA;YACL,CAAC;QACL,CAAC,EACD,EAAE,WAAW,EAAE,CAAC,EAAE,CACrB,CAAA;IACL,CAAC;IAED,KAAK,CAAC,KAAK,CACP,KAAa,EACb,OAAqB;QAErB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;QAExC,0CAA0C;QAC1C,MAAM,eAAe,GAAG,OAAO,CAAC,QAAQ,IAAI,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;QAC1E,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,eAAe,CAAA;QAElD,IAAI,CAAC;YACD,qCAAqC;YACrC,MAAM,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAA;YAErC,uCAAuC;YACvC,MAAM,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,eAAe,EAAE;gBACrD,QAAQ,EAAE,kBAAkB;aAC/B,CAAC,CAAA;YAEF,+CAA+C;YAC/C,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE,GACpC,MAAM,MAAM,CAAC,SAAS,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAA;YAE9D,oDAAoD;YACpD,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAEjE,4BAA4B;YAC5B,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,iBAAiB,CACpD,eAAe,EACf,OAAO,CACV,CAAA;YAED,0DAA0D;YAC1D,MAAM,IAAI,GAAG,MAAM,SAAS,CACxB,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAC9E;gBACI,WAAW,EAAE,CAAC;gBACd,SAAS,EAAE,IAAI;gBACf,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE;oBACjB,yDAAyD;oBACzD,IAAI,GAAG,YAAY,YAAY;wBAAE,OAAO,KAAK,CAAA;oBAC7C,kCAAkC;oBAClC,IAAI,GAAG,YAAY,cAAc,EAAE,CAAC;wBAChC,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAA;wBACvB,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;oBAC5E,CAAC;oBACD,OAAO,KAAK,CAAA;gBAChB,CAAC;aACJ,CACJ,CAAA;YAED,sCAAsC;YACtC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAA;YAE3B,0DAA0D;YAC1D,IAAI,QAAQ,GAAmB,IAAI,CAAA;YACnC,IAAI,CAAC;gBACD,QAAQ,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,eAAe,CAC7C,eAAe,EACf,MAAM,EACN,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CACtD,CAAA;YACL,CAAC;YAAC,MAAM,CAAC;gBACL,oCAAoC;gBACpC,QAAQ,GAAG,IAAI,CAAA;YACnB,CAAC;YAED,oBAAoB;YACpB,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,eAAe,CAAC,CAAA;YAEjD,OAAO;gBACH,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE;gBAClD,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,aAAa;gBAClC,KAAK,EAAE,IAAI,CAAC,KAAK;oBACb,CAAC,CAAC;wBACI,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC;wBAC3C,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,iBAAiB,IAAI,CAAC;wBACnD,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC;qBAC5C;oBACH,CAAC,CAAC,SAAS;gBACf,QAAQ;aACX,CAAA;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,iCAAiC;YACjC,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,eAAe,CAAC,CAAA;YAEjD,IAAI,GAAG,YAAY,cAAc,IAAI,GAAG,YAAY,YAAY,IAAI,GAAG,YAAY,qBAAqB;gBAAE,MAAM,GAAG,CAAA;YACnH,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAC5D,MAAM,IAAI,cAAc,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAA;QACxD,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,eAAe,CACzB,QAAgB,EAChB,aAAqB,EACrB,OAAqB,EACrB,OAAwC,EACxC,OAAe;QAEf,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;QACxC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAA;QAE3D,IAAI,QAAkB,CAAA;QACtB,IAAI,CAAC;YACD,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,mBAAmB,EAAE;gBACnD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACL,cAAc,EAAE,kBAAkB;oBAClC,GAAG,OAAO;iBACb;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACjB,KAAK,EAAE,aAAa;oBACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,WAAW,EAAE,OAAO,CAAC,WAAW;oBAChC,UAAU,EAAE,OAAO,CAAC,SAAS;iBAChC,CAAC;gBACF,MAAM,EAAE,UAAU,CAAC,MAAM;aAC5B,CAAC,CAAA;QACN,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBACpD,MAAM,IAAI,YAAY,CAClB,qCAAqC,OAAO,GAAG,IAAI,IAAI,CAC1D,CAAA;YACL,CAAC;YACD,MAAM,GAAG,CAAA;QACb,CAAC;gBAAS,CAAC;YACP,YAAY,CAAC,KAAK,CAAC,CAAA;QACvB,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;YAClD,MAAM,IAAI,cAAc,CACpB,qBAAqB,QAAQ,CAAC,MAAM,KAAK,IAAI,EAAE,EAC/C,QAAQ,CAAC,MAAM,KAAK,GAAG;gBACnB,CAAC,CAAC,iFAAiF;gBACnF,CAAC,CAAC,QAAQ,CAAC,MAAM,IAAI,GAAG;oBACtB,CAAC,CAAC,yFAAyF;oBAC3F,CAAC,CAAC,8CAA8C,CACzD,CAAA;QACL,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA2B,CAAA;QAC9D,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,EAAE,IAAI,SAAS,CAAA;QAEzE,OAAO,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAA;IACvC,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,KAAa;QACpC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;QAC1C,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CACvB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,WAAW,EAAE,CACvD,CAAA;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,CAAA;YACjF,MAAM,IAAI,qBAAqB,CAC3B,gCAAgC,KAAK,wBAAwB,SAAS,EAAE,CAC3E,CAAA;QACL,CAAC;QACD,OAAO,KAAK,CAAC,QAAQ,CAAA;IACzB,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAC5B,MAA8B;QAE9B,IAAI,CAAC;YACD,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,CAAA;QACnC,CAAC;QAAC,MAAM,CAAC;YACL,4DAA4D;YAC5D,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAA;QACzD,CAAC;IACL,CAAC;CACJ"}
@@ -0,0 +1,16 @@
1
+ export type NetworkName = 'testnet' | 'mainnet';
2
+ export interface NetworkConfig {
3
+ name: NetworkName;
4
+ chainId: bigint;
5
+ rpcUrl: string;
6
+ /** Fallback RPC URLs, tried in order if the primary fails */
7
+ rpcUrls: string[];
8
+ indexerUrl: string;
9
+ flowContractAddress: string;
10
+ ledgerContractAddress: string;
11
+ inferenceContractAddress: string;
12
+ fineTuningContractAddress: string;
13
+ }
14
+ export declare const NETWORKS: Record<NetworkName, NetworkConfig>;
15
+ export declare function getNetwork(nameOrChainId: NetworkName | bigint): NetworkConfig;
16
+ //# sourceMappingURL=networks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"networks.d.ts","sourceRoot":"","sources":["../src/networks.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,SAAS,CAAA;AAE/C,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,WAAW,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,6DAA6D;IAC7D,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,qBAAqB,EAAE,MAAM,CAAA;IAC7B,wBAAwB,EAAE,MAAM,CAAA;IAChC,yBAAyB,EAAE,MAAM,CAAA;CACpC;AAED,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE,aAAa,CA+BvD,CAAA;AAED,wBAAgB,UAAU,CAAC,aAAa,EAAE,WAAW,GAAG,MAAM,GAAG,aAAa,CAa7E"}
@@ -0,0 +1,48 @@
1
+ export const NETWORKS = {
2
+ testnet: {
3
+ name: 'testnet',
4
+ chainId: 16602n,
5
+ rpcUrl: 'https://evmrpc-testnet.0g.ai',
6
+ rpcUrls: [
7
+ 'https://evmrpc-testnet.0g.ai',
8
+ 'https://16600-rpc.testnet.0g.ai',
9
+ 'https://og-testnet-evm-rpc.allthatnode.com',
10
+ ],
11
+ indexerUrl: 'https://indexer-storage-testnet-turbo.0g.ai',
12
+ flowContractAddress: '0xbD2C3F0E65eDF5582141C35969d66e34e4E6BF80',
13
+ ledgerContractAddress: '0xE70830508dAc0A97e6c087c75f402f9Be669E406',
14
+ inferenceContractAddress: '0xa79F4c8311FF93C06b8CfB403690cc987c93F91E',
15
+ fineTuningContractAddress: '0xC6C075D8039763C8f1EbE580be5ADdf2fd6941bA',
16
+ },
17
+ mainnet: {
18
+ name: 'mainnet',
19
+ chainId: 16661n,
20
+ rpcUrl: 'https://evmrpc.0g.ai',
21
+ rpcUrls: [
22
+ 'https://evmrpc.0g.ai',
23
+ 'https://0g-rpc-evm01.validatorvn.com',
24
+ 'https://rpc.0g.thirdweb.com',
25
+ ],
26
+ indexerUrl: 'https://indexer-storage.0g.ai',
27
+ flowContractAddress: '0x0460aA47b41a66694c0a73f667a1b795A5ED3556',
28
+ ledgerContractAddress: '0x2dE54c845Cd948B72D2e32e39586fe89607074E3',
29
+ inferenceContractAddress: '0x47340d900bdFec2BD393c626E12ea0656F938d84',
30
+ fineTuningContractAddress: '0x4e3474095518883744ddf135b7E0A23301c7F9c0',
31
+ },
32
+ };
33
+ export function getNetwork(nameOrChainId) {
34
+ if (typeof nameOrChainId === 'string') {
35
+ const config = NETWORKS[nameOrChainId];
36
+ if (!config)
37
+ throw new Error(`Unknown network: ${nameOrChainId}`);
38
+ // Return a copy so overrides don't mutate the original
39
+ return { ...config, rpcUrls: [...config.rpcUrls] };
40
+ }
41
+ for (const config of Object.values(NETWORKS)) {
42
+ if (config.chainId === nameOrChainId) {
43
+ return { ...config, rpcUrls: [...config.rpcUrls] };
44
+ }
45
+ }
46
+ throw new Error(`Unknown chain ID: ${nameOrChainId}`);
47
+ }
48
+ //# sourceMappingURL=networks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"networks.js","sourceRoot":"","sources":["../src/networks.ts"],"names":[],"mappings":"AAeA,MAAM,CAAC,MAAM,QAAQ,GAAuC;IACxD,OAAO,EAAE;QACL,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,MAAM;QACf,MAAM,EAAE,8BAA8B;QACtC,OAAO,EAAE;YACL,8BAA8B;YAC9B,iCAAiC;YACjC,4CAA4C;SAC/C;QACD,UAAU,EAAE,6CAA6C;QACzD,mBAAmB,EAAE,4CAA4C;QACjE,qBAAqB,EAAE,4CAA4C;QACnE,wBAAwB,EAAE,4CAA4C;QACtE,yBAAyB,EAAE,4CAA4C;KAC1E;IACD,OAAO,EAAE;QACL,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,MAAM;QACf,MAAM,EAAE,sBAAsB;QAC9B,OAAO,EAAE;YACL,sBAAsB;YACtB,sCAAsC;YACtC,6BAA6B;SAChC;QACD,UAAU,EAAE,+BAA+B;QAC3C,mBAAmB,EAAE,4CAA4C;QACjE,qBAAqB,EAAE,4CAA4C;QACnE,wBAAwB,EAAE,4CAA4C;QACtE,yBAAyB,EAAE,4CAA4C;KAC1E;CACJ,CAAA;AAED,MAAM,UAAU,UAAU,CAAC,aAAmC;IAC1D,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAA;QACtC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,aAAa,EAAE,CAAC,CAAA;QACjE,uDAAuD;QACvD,OAAO,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,CAAA;IACtD,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3C,IAAI,MAAM,CAAC,OAAO,KAAK,aAAa,EAAE,CAAC;YACnC,OAAO,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,CAAA;QACtD,CAAC;IACL,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,qBAAqB,aAAa,EAAE,CAAC,CAAA;AACzD,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { NetworkConfig } from './networks.js';
2
+ import { StorageClient } from './storage.js';
3
+ import { InferenceClient } from './inference.js';
4
+ import type { OrbitConfig, StoreResult, StoreOptions, RetrieveOptions, InferResult, InferOptions, ServiceInfo, AccountStatus } from './types.js';
5
+ export declare class Orbit {
6
+ readonly network: NetworkConfig;
7
+ readonly storage: StorageClient;
8
+ readonly inference: InferenceClient;
9
+ private wallet;
10
+ private provider;
11
+ private constructor();
12
+ /**
13
+ * Connect to the 0G network. This is the primary entry point.
14
+ *
15
+ * Tries the primary RPC URL first, then falls back to alternates.
16
+ * If privateKey is not provided, reads from PRIVATE_KEY env var.
17
+ */
18
+ static connect(config: OrbitConfig): Promise<Orbit>;
19
+ store(filePath: string, options?: StoreOptions): Promise<StoreResult>;
20
+ storeData(data: string | Buffer | Uint8Array, options?: StoreOptions): Promise<StoreResult>;
21
+ retrieve(rootHash: string, outputPath: string, options?: RetrieveOptions): Promise<void>;
22
+ infer(model: string, options: InferOptions): Promise<InferResult>;
23
+ listServices(): Promise<ServiceInfo[]>;
24
+ status(): Promise<AccountStatus>;
25
+ get address(): string;
26
+ }
27
+ //# sourceMappingURL=orbit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orbit.d.ts","sourceRoot":"","sources":["../src/orbit.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,aAAa,EAAE,MAAM,eAAe,CAAA;AAE/D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,KAAK,EACR,WAAW,EACX,WAAW,EACX,YAAY,EACZ,eAAe,EACf,WAAW,EACX,YAAY,EACZ,WAAW,EACX,aAAa,EAChB,MAAM,YAAY,CAAA;AAGnB,qBAAa,KAAK;IACd,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAA;IAC/B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAA;IAC/B,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAA;IACnC,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,QAAQ,CAAiB;IAEjC,OAAO;IAYP;;;;;OAKG;WACU,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC;IAuEnD,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAIrE,SAAS,CACX,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,EAClC,OAAO,CAAC,EAAE,YAAY,GACvB,OAAO,CAAC,WAAW,CAAC;IAIjB,QAAQ,CACV,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,eAAe,GAC1B,OAAO,CAAC,IAAI,CAAC;IAMV,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAIjE,YAAY,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAMtC,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC;IAWtC,IAAI,OAAO,IAAI,MAAM,CAEpB;CACJ"}
package/dist/orbit.js ADDED
@@ -0,0 +1,108 @@
1
+ import { Wallet, JsonRpcProvider } from 'ethers';
2
+ import { getNetwork } from './networks.js';
3
+ import { StorageClient } from './storage.js';
4
+ import { InferenceClient } from './inference.js';
5
+ import { ConnectionError } from './errors.js';
6
+ export class Orbit {
7
+ network;
8
+ storage;
9
+ inference;
10
+ wallet;
11
+ provider;
12
+ constructor(network, wallet, provider) {
13
+ this.network = network;
14
+ this.wallet = wallet;
15
+ this.provider = provider;
16
+ this.storage = new StorageClient(network, wallet);
17
+ this.inference = new InferenceClient(network, wallet);
18
+ }
19
+ /**
20
+ * Connect to the 0G network. This is the primary entry point.
21
+ *
22
+ * Tries the primary RPC URL first, then falls back to alternates.
23
+ * If privateKey is not provided, reads from PRIVATE_KEY env var.
24
+ */
25
+ static async connect(config) {
26
+ // Resolve private key: explicit > env var
27
+ const privateKey = config.privateKey ?? process.env.PRIVATE_KEY;
28
+ if (!privateKey) {
29
+ throw new ConnectionError('No private key provided.', 'Pass privateKey in config or set the PRIVATE_KEY environment variable. Example: PRIVATE_KEY=0x... npx tsx index.ts');
30
+ }
31
+ const networkConfig = getNetwork(config.network);
32
+ // Allow overrides
33
+ if (config.rpcUrl)
34
+ networkConfig.rpcUrl = config.rpcUrl;
35
+ if (config.indexerUrl)
36
+ networkConfig.indexerUrl = config.indexerUrl;
37
+ // Build candidate RPC URLs: explicit override first, then the fallback list
38
+ const rpcUrls = config.rpcUrl
39
+ ? [config.rpcUrl]
40
+ : networkConfig.rpcUrls;
41
+ // Try each RPC URL until one connects
42
+ let lastError = null;
43
+ for (const url of rpcUrls) {
44
+ try {
45
+ const provider = new JsonRpcProvider(url);
46
+ const wallet = new Wallet(privateKey, provider);
47
+ const chainId = (await provider.getNetwork()).chainId;
48
+ if (chainId !== networkConfig.chainId) {
49
+ throw new ConnectionError(`Chain ID mismatch: expected ${networkConfig.chainId}, got ${chainId}`, `Your RPC endpoint is on a different network. Use the correct RPC URL for ${networkConfig.name}.`);
50
+ }
51
+ // Lock in the working URL
52
+ networkConfig.rpcUrl = url;
53
+ // Check balance and warn if zero (non-blocking)
54
+ try {
55
+ const balance = await provider.getBalance(wallet.address);
56
+ if (balance === 0n) {
57
+ console.warn(`[0G Orbit] Warning: wallet ${wallet.address} has 0 OG balance on ${networkConfig.name}. ` +
58
+ `Get testnet tokens at https://faucet.0g.ai`);
59
+ }
60
+ }
61
+ catch {
62
+ // Balance check failure is non-fatal
63
+ }
64
+ return new Orbit(networkConfig, wallet, provider);
65
+ }
66
+ catch (err) {
67
+ // Chain ID mismatch is not a transient failure — don't try other URLs
68
+ if (err instanceof ConnectionError && err.message.includes('Chain ID mismatch')) {
69
+ throw err;
70
+ }
71
+ lastError = err instanceof Error ? err : new Error(String(err));
72
+ }
73
+ }
74
+ const tried = rpcUrls.join(', ');
75
+ throw new ConnectionError(`Failed to connect to any RPC endpoint. Tried: ${tried}. Last error: ${lastError?.message ?? 'unknown'}`, 'All RPC endpoints are unreachable. Check your internet connection, or provide a custom RPC URL with the rpcUrl option.');
76
+ }
77
+ // --- Storage shortcuts ---
78
+ async store(filePath, options) {
79
+ return this.storage.store(filePath, options);
80
+ }
81
+ async storeData(data, options) {
82
+ return this.storage.storeData(data, options);
83
+ }
84
+ async retrieve(rootHash, outputPath, options) {
85
+ return this.storage.retrieve(rootHash, outputPath, options);
86
+ }
87
+ // --- Inference shortcuts ---
88
+ async infer(model, options) {
89
+ return this.inference.infer(model, options);
90
+ }
91
+ async listServices() {
92
+ return this.inference.listServices();
93
+ }
94
+ // --- Account ---
95
+ async status() {
96
+ const balance = await this.provider.getBalance(this.wallet.address);
97
+ const balanceOG = Number(balance) / 1e18;
98
+ return {
99
+ balance: balanceOG.toFixed(6),
100
+ network: this.network.name,
101
+ address: this.wallet.address,
102
+ };
103
+ }
104
+ get address() {
105
+ return this.wallet.address;
106
+ }
107
+ }
108
+ //# sourceMappingURL=orbit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orbit.js","sourceRoot":"","sources":["../src/orbit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export interface RetryOptions {
2
+ /** Maximum number of attempts (default: 3) */
3
+ maxAttempts?: number;
4
+ /** Base delay between retries in ms (default: 1000). Doubles each retry. */
5
+ baseDelay?: number;
6
+ /** Maximum delay cap in ms (default: 10000) */
7
+ maxDelay?: number;
8
+ /** Predicate to decide if an error is retryable (default: transient errors only) */
9
+ isRetryable?: (err: unknown) => boolean;
10
+ /** Called before each retry with attempt number and error */
11
+ onRetry?: (attempt: number, err: unknown) => void;
12
+ }
13
+ /**
14
+ * Retry an async operation with exponential backoff.
15
+ * Only retries on transient errors (network, timeout, 5xx) by default.
16
+ */
17
+ export declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
18
+ /**
19
+ * Determines if an error is transient and worth retrying.
20
+ * Covers: network failures, timeouts, RPC errors, 5xx responses.
21
+ */
22
+ export declare function isTransientError(err: unknown): boolean;
23
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IACzB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oFAAoF;IACpF,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAA;IACvC,6DAA6D;IAC7D,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;CACpD;AASD;;;GAGG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC7B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,YAAiB,GAC3B,OAAO,CAAC,CAAC,CAAC,CA4BZ;AAMD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAiCtD"}
package/dist/retry.js ADDED
@@ -0,0 +1,90 @@
1
+ const DEFAULT_OPTIONS = {
2
+ maxAttempts: 3,
3
+ baseDelay: 1000,
4
+ maxDelay: 10_000,
5
+ isRetryable: isTransientError,
6
+ };
7
+ /**
8
+ * Retry an async operation with exponential backoff.
9
+ * Only retries on transient errors (network, timeout, 5xx) by default.
10
+ */
11
+ export async function withRetry(fn, options = {}) {
12
+ const opts = { ...DEFAULT_OPTIONS, ...options };
13
+ let lastError;
14
+ for (let attempt = 1; attempt <= opts.maxAttempts; attempt++) {
15
+ try {
16
+ return await fn();
17
+ }
18
+ catch (err) {
19
+ lastError = err;
20
+ if (attempt === opts.maxAttempts || !opts.isRetryable(err)) {
21
+ throw err;
22
+ }
23
+ if (options.onRetry) {
24
+ options.onRetry(attempt, err);
25
+ }
26
+ // Exponential backoff with jitter
27
+ const delay = Math.min(opts.baseDelay * Math.pow(2, attempt - 1) + Math.random() * 500, opts.maxDelay);
28
+ await sleep(delay);
29
+ }
30
+ }
31
+ throw lastError;
32
+ }
33
+ function sleep(ms) {
34
+ return new Promise((resolve) => setTimeout(resolve, ms));
35
+ }
36
+ /**
37
+ * Determines if an error is transient and worth retrying.
38
+ * Covers: network failures, timeouts, RPC errors, 5xx responses.
39
+ */
40
+ export function isTransientError(err) {
41
+ if (!(err instanceof Error))
42
+ return false;
43
+ const msg = err.message.toLowerCase();
44
+ // Network-level failures
45
+ if (msg.includes('econnrefused'))
46
+ return true;
47
+ if (msg.includes('econnreset'))
48
+ return true;
49
+ if (msg.includes('etimedout'))
50
+ return true;
51
+ if (msg.includes('enotfound'))
52
+ return true;
53
+ if (msg.includes('epipe'))
54
+ return true;
55
+ if (msg.includes('fetch failed'))
56
+ return true;
57
+ if (msg.includes('network error'))
58
+ return true;
59
+ // Timeout
60
+ if (msg.includes('timeout'))
61
+ return true;
62
+ if (err.name === 'AbortError')
63
+ return true;
64
+ // RPC-level transient errors
65
+ if (msg.includes('server error'))
66
+ return true;
67
+ if (msg.includes('bad gateway'))
68
+ return true;
69
+ if (msg.includes('service unavailable'))
70
+ return true;
71
+ if (msg.includes('rate limit'))
72
+ return true;
73
+ if (msg.includes('429'))
74
+ return true;
75
+ if (msg.includes('502'))
76
+ return true;
77
+ if (msg.includes('503'))
78
+ return true;
79
+ if (msg.includes('504'))
80
+ return true;
81
+ // ethers provider errors
82
+ if (msg.includes('missing response'))
83
+ return true;
84
+ if (msg.includes('connection error'))
85
+ return true;
86
+ if (msg.includes('could not detect network'))
87
+ return true;
88
+ return false;
89
+ }
90
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { Signer } from 'ethers';
2
+ import type { NetworkConfig } from './networks.js';
3
+ import type { StoreResult, StoreOptions, RetrieveOptions } from './types.js';
4
+ export declare class StorageClient {
5
+ private indexer;
6
+ private rpcUrl;
7
+ private signer;
8
+ constructor(network: NetworkConfig, signer: Signer);
9
+ /**
10
+ * Upload a file to 0G Storage by file path.
11
+ * Retries transient failures automatically. Gas escalates on each retry.
12
+ */
13
+ store(filePath: string, options?: StoreOptions): Promise<StoreResult>;
14
+ /**
15
+ * Upload raw data (string, Buffer, or Uint8Array) to 0G Storage.
16
+ * Writes to a temp file, uploads, then cleans up.
17
+ */
18
+ storeData(data: string | Buffer | Uint8Array, options?: StoreOptions): Promise<StoreResult>;
19
+ private _store;
20
+ /**
21
+ * Download a file from 0G Storage by root hash.
22
+ */
23
+ retrieve(rootHash: string, outputPath: string, options?: RetrieveOptions): Promise<void>;
24
+ private _retrieve;
25
+ }
26
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAKpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAO5E,qBAAa,aAAa;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,MAAM,CAAQ;gBAEV,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM;IAMlD;;;OAGG;IACG,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,WAAW,CAAC;IAkB/E;;;OAGG;IACG,SAAS,CACX,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,EAClC,OAAO,GAAE,YAAiB,GAC3B,OAAO,CAAC,WAAW,CAAC;YAUT,MAAM;IA4DpB;;OAEG;IACG,QAAQ,CACV,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,eAAoB,GAC9B,OAAO,CAAC,IAAI,CAAC;YAOF,SAAS;CAmB1B"}