@layr-labs/ecloud-sdk 0.1.2 → 0.2.0-dev.1

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/index.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  requirePrivateKey,
14
14
  storePrivateKey,
15
15
  validatePrivateKey
16
- } from "./chunk-4RG5IMZ7.js";
16
+ } from "./chunk-GB4GM4C2.js";
17
17
  import {
18
18
  PRIMARY_LANGUAGES,
19
19
  assertValidFilePath,
@@ -40,7 +40,9 @@ import {
40
40
  getTemplate,
41
41
  logs,
42
42
  prepareDeploy,
43
+ prepareDeployFromVerifiableBuild,
43
44
  prepareUpgrade,
45
+ prepareUpgradeFromVerifiableBuild,
44
46
  sanitizeString,
45
47
  sanitizeURL,
46
48
  sanitizeXURL,
@@ -62,7 +64,7 @@ import {
62
64
  validateXURL,
63
65
  watchDeployment,
64
66
  watchUpgrade
65
- } from "./chunk-MQ2NGP4C.js";
67
+ } from "./chunk-O7EU5JL7.js";
66
68
  import {
67
69
  NoopClient,
68
70
  PostHogClient,
@@ -70,6 +72,7 @@ import {
70
72
  addHexPrefix,
71
73
  addMetric,
72
74
  addMetricWithDimensions,
75
+ calculateBillingAuthSignature,
73
76
  createAppEnvironment,
74
77
  createMetricsContext,
75
78
  createTelemetryClient,
@@ -77,14 +80,370 @@ import {
77
80
  getAvailableEnvironments,
78
81
  getBuildType,
79
82
  getEnvironmentConfig,
83
+ getLogger,
80
84
  getPostHogAPIKey,
81
85
  getPostHogEndpoint,
82
86
  isEnvironmentAvailable,
83
87
  isMainnet,
84
88
  isNoopClient,
85
89
  isSubscriptionActive,
90
+ stripHexPrefix,
86
91
  withSDKTelemetry
87
- } from "./chunk-AOZRDBLK.js";
92
+ } from "./chunk-FY7UU55U.js";
93
+
94
+ // src/client/common/utils/buildapi.ts
95
+ import axios from "axios";
96
+ import { privateKeyToAccount } from "viem/accounts";
97
+ var BuildApiClient = class {
98
+ constructor(options) {
99
+ this.baseUrl = options.baseUrl.replace(/\/+$/, "");
100
+ this.clientId = options.clientId;
101
+ if (options.privateKey) {
102
+ this.account = privateKeyToAccount(options.privateKey);
103
+ }
104
+ }
105
+ async submitBuild(payload) {
106
+ return this.authenticatedJsonRequest("/builds", "POST", payload);
107
+ }
108
+ async getBuild(buildId) {
109
+ return this.publicJsonRequest(`/builds/${encodeURIComponent(buildId)}`);
110
+ }
111
+ async getBuildByDigest(digest) {
112
+ return this.publicJsonRequest(`/builds/image/${encodeURIComponent(digest)}`);
113
+ }
114
+ async verify(identifier) {
115
+ return this.publicJsonRequest(`/builds/verify/${encodeURIComponent(identifier)}`);
116
+ }
117
+ async getLogs(buildId) {
118
+ return this.authenticatedTextRequest(`/builds/${encodeURIComponent(buildId)}/logs`);
119
+ }
120
+ async listBuilds(params) {
121
+ const res = await axios({
122
+ url: `${this.baseUrl}/builds`,
123
+ method: "GET",
124
+ params,
125
+ headers: this.clientId ? { "x-client-id": this.clientId } : void 0,
126
+ timeout: 6e4,
127
+ validateStatus: () => true
128
+ });
129
+ if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
130
+ return res.data;
131
+ }
132
+ async publicJsonRequest(path) {
133
+ const res = await axios({
134
+ url: `${this.baseUrl}${path}`,
135
+ method: "GET",
136
+ headers: this.clientId ? { "x-client-id": this.clientId } : void 0,
137
+ timeout: 6e4,
138
+ validateStatus: () => true
139
+ });
140
+ if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
141
+ return res.data;
142
+ }
143
+ async authenticatedJsonRequest(path, method, body) {
144
+ if (!this.account) throw new Error("Private key required for authenticated requests");
145
+ const headers = {
146
+ "Content-Type": "application/json"
147
+ };
148
+ if (this.clientId) headers["x-client-id"] = this.clientId;
149
+ const expiry = BigInt(Math.floor(Date.now() / 1e3) + 60);
150
+ const { signature } = await calculateBillingAuthSignature({
151
+ account: this.account,
152
+ product: "compute",
153
+ expiry
154
+ });
155
+ headers.Authorization = `Bearer ${signature}`;
156
+ headers["X-eigenx-expiry"] = expiry.toString();
157
+ headers["X-Account"] = this.account.address;
158
+ const res = await axios({
159
+ url: `${this.baseUrl}${path}`,
160
+ method,
161
+ headers,
162
+ data: body,
163
+ timeout: 6e4,
164
+ validateStatus: () => true
165
+ });
166
+ if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
167
+ return res.data;
168
+ }
169
+ async authenticatedTextRequest(path) {
170
+ if (!this.account) throw new Error("Private key required for authenticated requests");
171
+ const headers = {};
172
+ if (this.clientId) headers["x-client-id"] = this.clientId;
173
+ const expiry = BigInt(Math.floor(Date.now() / 1e3) + 60);
174
+ const { signature } = await calculateBillingAuthSignature({
175
+ account: this.account,
176
+ product: "compute",
177
+ expiry
178
+ });
179
+ headers.Authorization = `Bearer ${signature}`;
180
+ headers["X-eigenx-expiry"] = expiry.toString();
181
+ headers["X-Account"] = this.account.address;
182
+ const res = await axios({
183
+ url: `${this.baseUrl}${path}`,
184
+ method: "GET",
185
+ headers,
186
+ timeout: 6e4,
187
+ responseType: "text",
188
+ validateStatus: () => true
189
+ });
190
+ if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
191
+ return typeof res.data === "string" ? res.data : JSON.stringify(res.data);
192
+ }
193
+ };
194
+ function buildApiHttpError(res) {
195
+ const status = res.status;
196
+ const body = typeof res.data === "string" ? res.data : res.data ? JSON.stringify(res.data) : "";
197
+ const url = res.config?.url ? ` ${res.config.url}` : "";
198
+ return new Error(`BuildAPI request failed: ${status}${url} - ${body || "Unknown error"}`);
199
+ }
200
+
201
+ // src/client/modules/build/types.ts
202
+ var BUILD_STATUS = {
203
+ BUILDING: "building",
204
+ SUCCESS: "success",
205
+ FAILED: "failed"
206
+ };
207
+
208
+ // src/client/modules/build/errors.ts
209
+ var BuildError = class extends Error {
210
+ constructor(message) {
211
+ super(message);
212
+ this.name = "BuildError";
213
+ }
214
+ };
215
+ var AuthRequiredError = class extends BuildError {
216
+ constructor(message = "Authentication required") {
217
+ super(message);
218
+ this.name = "AuthRequiredError";
219
+ }
220
+ };
221
+ var BuildFailedError = class extends BuildError {
222
+ constructor(message, buildId) {
223
+ super(message);
224
+ this.buildId = buildId;
225
+ this.name = "BuildFailedError";
226
+ }
227
+ };
228
+ var ConflictError = class extends BuildError {
229
+ constructor(message = "Build already in progress") {
230
+ super(message);
231
+ this.name = "ConflictError";
232
+ }
233
+ };
234
+ var NotFoundError = class extends BuildError {
235
+ constructor(message = "Build not found") {
236
+ super(message);
237
+ this.name = "NotFoundError";
238
+ }
239
+ };
240
+ var ForbiddenError = class extends BuildError {
241
+ constructor(message = "Permission denied") {
242
+ super(message);
243
+ this.name = "ForbiddenError";
244
+ }
245
+ };
246
+ var TimeoutError = class extends BuildError {
247
+ constructor(message = "Operation timed out") {
248
+ super(message);
249
+ this.name = "TimeoutError";
250
+ }
251
+ };
252
+ var BadRequestError = class extends BuildError {
253
+ constructor(message = "Bad request") {
254
+ super(message);
255
+ this.name = "BadRequestError";
256
+ }
257
+ };
258
+
259
+ // src/client/modules/build/index.ts
260
+ var DEFAULT_POLL_INTERVAL = 2e3;
261
+ var DEFAULT_TIMEOUT = 30 * 60 * 1e3;
262
+ function createBuildModule(config) {
263
+ const { verbose = false, skipTelemetry = false } = config;
264
+ const logger = getLogger(verbose);
265
+ const environment = config.environment || "sepolia";
266
+ const environmentConfig = getEnvironmentConfig(environment);
267
+ const api = new BuildApiClient({
268
+ baseUrl: environmentConfig.userApiServerURL,
269
+ privateKey: config.privateKey ? addHexPrefix(config.privateKey) : void 0,
270
+ clientId: config.clientId
271
+ });
272
+ return {
273
+ async submit(request) {
274
+ return withSDKTelemetry(
275
+ {
276
+ functionName: "build.submit",
277
+ skipTelemetry,
278
+ properties: { environment, repoUrl: request.repoUrl }
279
+ },
280
+ async () => {
281
+ if (!config.privateKey) throw new AuthRequiredError("Private key required for submit()");
282
+ const data = await api.submitBuild({
283
+ repo_url: request.repoUrl,
284
+ git_ref: request.gitRef,
285
+ dockerfile_path: request.dockerfilePath ?? "Dockerfile",
286
+ caddyfile_path: request.caddyfilePath,
287
+ build_context_path: request.buildContextPath ?? ".",
288
+ dependencies: request.dependencies ?? []
289
+ });
290
+ logger.debug(`Submitted build: ${data.build_id}`);
291
+ return { buildId: data.build_id };
292
+ }
293
+ );
294
+ },
295
+ async list(options) {
296
+ const { billingAddress, limit, offset } = options;
297
+ return withSDKTelemetry(
298
+ {
299
+ functionName: "build.list",
300
+ skipTelemetry,
301
+ properties: {
302
+ environment,
303
+ billingAddress,
304
+ ...limit !== void 0 ? { limit: String(limit) } : {},
305
+ ...offset !== void 0 ? { offset: String(offset) } : {}
306
+ }
307
+ },
308
+ async () => {
309
+ const data = await api.listBuilds({
310
+ billing_address: billingAddress,
311
+ limit,
312
+ offset
313
+ });
314
+ return Array.isArray(data) ? data.map(transformBuild) : [];
315
+ }
316
+ );
317
+ },
318
+ async get(buildId) {
319
+ return withSDKTelemetry(
320
+ { functionName: "build.get", skipTelemetry, properties: { environment, buildId } },
321
+ async () => transformBuild(await api.getBuild(buildId))
322
+ );
323
+ },
324
+ async getByDigest(digest) {
325
+ return withSDKTelemetry(
326
+ { functionName: "build.getByDigest", skipTelemetry, properties: { environment, digest } },
327
+ async () => transformBuild(await api.getBuildByDigest(digest))
328
+ );
329
+ },
330
+ async verify(identifier) {
331
+ return withSDKTelemetry(
332
+ { functionName: "build.verify", skipTelemetry, properties: { environment, identifier } },
333
+ async () => transformVerifyResult(await api.verify(identifier))
334
+ );
335
+ },
336
+ async getLogs(buildId) {
337
+ return withSDKTelemetry(
338
+ { functionName: "build.getLogs", skipTelemetry, properties: { environment, buildId } },
339
+ async () => {
340
+ if (!config.privateKey) throw new AuthRequiredError("Private key required for getLogs()");
341
+ return api.getLogs(buildId);
342
+ }
343
+ );
344
+ },
345
+ async submitAndWait(request, options = {}) {
346
+ const { buildId } = await this.submit(request);
347
+ return this.waitForBuild(buildId, options);
348
+ },
349
+ async waitForBuild(buildId, options = {}) {
350
+ const {
351
+ onLog,
352
+ onProgress,
353
+ pollIntervalMs = DEFAULT_POLL_INTERVAL,
354
+ timeoutMs = DEFAULT_TIMEOUT
355
+ } = options;
356
+ const startTime = Date.now();
357
+ let lastLogLength = 0;
358
+ while (true) {
359
+ if (Date.now() - startTime > timeoutMs) {
360
+ throw new TimeoutError(`Build timed out after ${timeoutMs}ms`);
361
+ }
362
+ const build = await this.get(buildId);
363
+ let logs2 = "";
364
+ try {
365
+ logs2 = await this.getLogs(buildId);
366
+ if (onLog && logs2.length > lastLogLength) {
367
+ onLog(logs2.slice(lastLogLength));
368
+ lastLogLength = logs2.length;
369
+ }
370
+ } catch {
371
+ }
372
+ onProgress?.({ build, logs: logs2 });
373
+ if (build.status === BUILD_STATUS.SUCCESS) return build;
374
+ if (build.status === BUILD_STATUS.FAILED) {
375
+ throw new BuildFailedError(build.errorMessage ?? "Build failed", buildId);
376
+ }
377
+ await sleep(pollIntervalMs);
378
+ }
379
+ },
380
+ async *streamLogs(buildId, pollIntervalMs = DEFAULT_POLL_INTERVAL) {
381
+ let lastLength = 0;
382
+ while (true) {
383
+ const build = await this.get(buildId);
384
+ let logs2 = "";
385
+ try {
386
+ logs2 = await this.getLogs(buildId);
387
+ } catch {
388
+ }
389
+ if (logs2.length > lastLength) {
390
+ yield {
391
+ content: logs2.slice(lastLength),
392
+ totalLength: logs2.length,
393
+ isComplete: build.status !== BUILD_STATUS.BUILDING,
394
+ finalStatus: build.status !== BUILD_STATUS.BUILDING ? build.status : void 0
395
+ };
396
+ lastLength = logs2.length;
397
+ }
398
+ if (build.status !== BUILD_STATUS.BUILDING) break;
399
+ await sleep(pollIntervalMs);
400
+ }
401
+ }
402
+ };
403
+ }
404
+ function sleep(ms) {
405
+ return new Promise((resolve) => setTimeout(resolve, ms));
406
+ }
407
+ function transformBuild(raw) {
408
+ return {
409
+ buildId: raw.build_id,
410
+ billingAddress: raw.billing_address,
411
+ repoUrl: raw.repo_url,
412
+ gitRef: raw.git_ref,
413
+ status: raw.status,
414
+ buildType: raw.build_type,
415
+ imageName: raw.image_name,
416
+ imageUrl: raw.image_url,
417
+ imageDigest: raw.image_digest,
418
+ provenanceJson: raw.provenance_json ?? void 0,
419
+ provenanceSignature: raw.provenance_signature ?? void 0,
420
+ errorMessage: raw.error_message ?? void 0,
421
+ createdAt: raw.created_at,
422
+ updatedAt: raw.updated_at,
423
+ dependencies: raw.dependencies ? Object.fromEntries(Object.entries(raw.dependencies).map(([k, v]) => [k, transformBuild(v)])) : void 0
424
+ };
425
+ }
426
+ function transformVerifyResult(raw) {
427
+ if (raw.status === "verified") {
428
+ return {
429
+ status: "verified",
430
+ buildId: raw.build_id,
431
+ imageUrl: raw.image_url,
432
+ imageDigest: raw.image_digest,
433
+ repoUrl: raw.repo_url,
434
+ gitRef: raw.git_ref,
435
+ provenanceJson: raw.provenance_json,
436
+ provenanceSignature: raw.provenance_signature,
437
+ payloadType: raw.payload_type,
438
+ payload: raw.payload
439
+ };
440
+ }
441
+ return {
442
+ status: "failed",
443
+ error: raw.error,
444
+ buildId: raw.build_id
445
+ };
446
+ }
88
447
 
89
448
  // src/client/common/utils/instance.ts
90
449
  async function getCurrentInstanceType(preflightCtx, appID, logger, clientId) {
@@ -139,10 +498,20 @@ function createECloudClient(cfg) {
139
498
  };
140
499
  }
141
500
  export {
501
+ AuthRequiredError,
502
+ BUILD_STATUS,
503
+ BadRequestError,
504
+ BuildError,
505
+ BuildFailedError,
506
+ ConflictError,
507
+ ForbiddenError,
142
508
  NoopClient,
509
+ NotFoundError,
143
510
  PRIMARY_LANGUAGES,
144
511
  PostHogClient,
512
+ TimeoutError,
145
513
  UserApiClient,
514
+ addHexPrefix,
146
515
  addMetric,
147
516
  addMetricWithDimensions,
148
517
  assertValidFilePath,
@@ -152,6 +521,7 @@ export {
152
521
  createApp,
153
522
  createAppEnvironment,
154
523
  createBillingModule,
524
+ createBuildModule,
155
525
  createComputeModule,
156
526
  createECloudClient,
157
527
  createMetricsContext,
@@ -195,12 +565,15 @@ export {
195
565
  listStoredKeys,
196
566
  logs,
197
567
  prepareDeploy,
568
+ prepareDeployFromVerifiableBuild,
198
569
  prepareUpgrade,
570
+ prepareUpgradeFromVerifiableBuild,
199
571
  requirePrivateKey,
200
572
  sanitizeString,
201
573
  sanitizeURL,
202
574
  sanitizeXURL,
203
575
  storePrivateKey,
576
+ stripHexPrefix,
204
577
  validateAppID,
205
578
  validateAppName,
206
579
  validateCreateAppParams,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client/common/utils/instance.ts","../src/client/index.ts"],"sourcesContent":["/**\n * Instance type utilities\n */\n\nimport { Address } from \"viem\";\nimport { PreflightContext } from \"./preflight\";\nimport { Logger } from \"../types\";\nimport { UserApiClient } from \"./userapi\";\n\n/**\n * Get current instance type for an app (best-effort)\n * Returns empty string if unable to fetch (API unavailable, app info not ready, etc.).\n * This is used as a convenience default for the upgrade flow.\n */\nexport async function getCurrentInstanceType(\n preflightCtx: PreflightContext,\n appID: Address,\n logger: Logger,\n clientId?: string,\n): Promise<string> {\n try {\n const userApiClient = new UserApiClient(\n preflightCtx.environmentConfig,\n preflightCtx.privateKey,\n preflightCtx.rpcUrl,\n clientId,\n );\n\n const infos = await userApiClient.getInfos([appID], 1);\n if (infos.length === 0) {\n return \"\"; // No app info available yet\n }\n\n return infos[0].machineType || \"\";\n } catch (err: any) {\n logger.debug(`Failed to get current instance type: ${err.message}`);\n return \"\"; // API call failed, skip default\n }\n}\n","/**\n * Main SDK Client entry point\n */\n\nimport { createComputeModule, type ComputeModule } from \"./modules/compute\";\nimport {\n getEnvironmentConfig,\n isEnvironmentAvailable,\n getAvailableEnvironments,\n} from \"./common/config/environment\";\nimport { createBillingModule, type BillingModule } from \"./modules/billing\";\nimport { addHexPrefix } from \"./common/utils\";\nimport { Hex } from \"viem\";\n\n// Export all types\nexport * from \"./common/types\";\n\n// Export validation utilities (non-interactive)\nexport * from \"./common/utils/validation\";\n\n// Special case on createApp - we don't need the client to run it\nexport {\n createApp,\n CreateAppOpts,\n SDKCreateAppOpts,\n PRIMARY_LANGUAGES,\n getAvailableTemplates,\n} from \"./modules/compute/app/create\";\nexport { logs, LogsOptions, SDKLogsOptions } from \"./modules/compute/app/logs\";\nexport {\n SDKDeployOptions,\n prepareDeploy,\n executeDeploy,\n watchDeployment,\n type PrepareDeployResult,\n} from \"./modules/compute/app/deploy\";\nexport {\n SDKUpgradeOptions,\n prepareUpgrade,\n executeUpgrade,\n watchUpgrade,\n type PrepareUpgradeResult,\n} from \"./modules/compute/app/upgrade\";\n\n// Export compute module for standalone use\nexport {\n createComputeModule,\n type ComputeModule,\n type ComputeModuleConfig,\n encodeStartAppData,\n encodeStopAppData,\n encodeTerminateAppData,\n} from \"./modules/compute\";\nexport {\n createBillingModule,\n type BillingModule,\n type BillingModuleConfig,\n} from \"./modules/billing\";\n\n// Export environment config utilities\nexport {\n getEnvironmentConfig,\n getAvailableEnvironments,\n isEnvironmentAvailable,\n getBuildType,\n isMainnet,\n} from \"./common/config/environment\";\nexport { isSubscriptionActive } from \"./common/utils/billing\";\n\n// Export auth utilities\nexport * from \"./common/auth\";\n\n// Export telemetry\nexport * from \"./common/telemetry\";\n\n// Export template catalog utilities for CLI\nexport {\n fetchTemplateCatalog,\n getTemplate,\n getCategoryDescriptions,\n} from \"./common/templates/catalog\";\n\n// Export contract utilities\nexport {\n getAllAppsByDeveloper,\n getAppLatestReleaseBlockNumbers,\n getBlockTimestamps,\n estimateTransactionGas,\n formatETH,\n type GasEstimate,\n type EstimateGasOptions,\n} from \"./common/contract/caller\";\n\n// Export batch gas estimation and delegation check\nexport {\n estimateBatchGas,\n checkERC7702Delegation,\n type EstimateBatchGasOptions,\n} from \"./common/contract/eip7702\";\n\n// Export instance type utilities\nexport { getCurrentInstanceType } from \"./common/utils/instance\";\n\n// Export user API client\nexport {\n UserApiClient,\n type AppInfo,\n type AppProfileInfo,\n type AppMetrics,\n} from \"./common/utils/userapi\";\n\nexport type Environment = \"sepolia\" | \"sepolia-dev\" | \"mainnet-alpha\";\n\nexport interface ClientConfig {\n verbose: boolean;\n privateKey: Hex;\n environment: Environment | string;\n rpcUrl?: string;\n}\n\nexport interface ECloudClient {\n compute: ComputeModule;\n billing: BillingModule;\n}\n\nexport function createECloudClient(cfg: ClientConfig): ECloudClient {\n cfg.privateKey = addHexPrefix(cfg.privateKey);\n\n // Validate environment is available in current build\n const environment = cfg.environment || \"sepolia\";\n if (!isEnvironmentAvailable(environment)) {\n throw new Error(\n `Environment \"${environment}\" is not available in this build type. ` +\n `Available environments: ${getAvailableEnvironments().join(\", \")}`,\n );\n }\n\n // Get environment config\n const environmentConfig = getEnvironmentConfig(environment);\n\n // Get rpc url from environment config or use provided rpc url\n let rpcUrl = cfg.rpcUrl;\n if (!rpcUrl) {\n rpcUrl = process.env.RPC_URL ?? environmentConfig.defaultRPCURL;\n }\n if (!rpcUrl) {\n throw new Error(\n `RPC URL is required. Provide via options.rpcUrl, RPC_URL env var, or ensure environment has default RPC URL`,\n );\n }\n\n return {\n compute: createComputeModule({\n rpcUrl,\n verbose: cfg.verbose,\n privateKey: cfg.privateKey,\n environment: cfg.environment,\n }),\n billing: createBillingModule({\n verbose: cfg.verbose,\n privateKey: cfg.privateKey,\n }),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,eAAsB,uBACpB,cACA,OACA,QACA,UACiB;AACjB,MAAI;AACF,UAAM,gBAAgB,IAAI;AAAA,MACxB,aAAa;AAAA,MACb,aAAa;AAAA,MACb,aAAa;AAAA,MACb;AAAA,IACF;AAEA,UAAM,QAAQ,MAAM,cAAc,SAAS,CAAC,KAAK,GAAG,CAAC;AACrD,QAAI,MAAM,WAAW,GAAG;AACtB,aAAO;AAAA,IACT;AAEA,WAAO,MAAM,CAAC,EAAE,eAAe;AAAA,EACjC,SAAS,KAAU;AACjB,WAAO,MAAM,wCAAwC,IAAI,OAAO,EAAE;AAClE,WAAO;AAAA,EACT;AACF;;;ACuFO,SAAS,mBAAmB,KAAiC;AAClE,MAAI,aAAa,aAAa,IAAI,UAAU;AAG5C,QAAM,cAAc,IAAI,eAAe;AACvC,MAAI,CAAC,uBAAuB,WAAW,GAAG;AACxC,UAAM,IAAI;AAAA,MACR,gBAAgB,WAAW,kEACE,yBAAyB,EAAE,KAAK,IAAI,CAAC;AAAA,IACpE;AAAA,EACF;AAGA,QAAM,oBAAoB,qBAAqB,WAAW;AAG1D,MAAI,SAAS,IAAI;AACjB,MAAI,CAAC,QAAQ;AACX,aAAS,QAAQ,IAAI,WAAW,kBAAkB;AAAA,EACpD;AACA,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS,oBAAoB;AAAA,MAC3B;AAAA,MACA,SAAS,IAAI;AAAA,MACb,YAAY,IAAI;AAAA,MAChB,aAAa,IAAI;AAAA,IACnB,CAAC;AAAA,IACD,SAAS,oBAAoB;AAAA,MAC3B,SAAS,IAAI;AAAA,MACb,YAAY,IAAI;AAAA,IAClB,CAAC;AAAA,EACH;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/client/common/utils/buildapi.ts","../src/client/modules/build/types.ts","../src/client/modules/build/errors.ts","../src/client/modules/build/index.ts","../src/client/common/utils/instance.ts","../src/client/index.ts"],"sourcesContent":["/**\n * Build API Client to manage verifiable builds and provenance\n *\n * This is a standalone HTTP client that talks to the (compute) UserAPI host.\n */\n\nimport axios, { AxiosResponse } from \"axios\";\nimport { privateKeyToAccount } from \"viem/accounts\";\n\nimport type { Hex } from \"viem\";\nimport { calculateBillingAuthSignature } from \"./auth\";\n\nexport class BuildApiClient {\n private readonly baseUrl: string;\n private readonly account?: ReturnType<typeof privateKeyToAccount>;\n private readonly clientId?: string;\n\n constructor(options: { baseUrl: string; privateKey?: Hex | string; clientId?: string }) {\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.clientId = options.clientId;\n\n if (options.privateKey) {\n this.account = privateKeyToAccount(options.privateKey as Hex);\n }\n }\n\n async submitBuild(payload: {\n repo_url: string;\n git_ref: string;\n dockerfile_path: string;\n caddyfile_path?: string;\n build_context_path: string;\n dependencies: string[];\n }): Promise<{ build_id: string }> {\n return this.authenticatedJsonRequest<{ build_id: string }>(\"/builds\", \"POST\", payload);\n }\n\n async getBuild(buildId: string): Promise<any> {\n return this.publicJsonRequest(`/builds/${encodeURIComponent(buildId)}`);\n }\n\n async getBuildByDigest(digest: string): Promise<any> {\n return this.publicJsonRequest(`/builds/image/${encodeURIComponent(digest)}`);\n }\n\n async verify(identifier: string): Promise<any> {\n return this.publicJsonRequest(`/builds/verify/${encodeURIComponent(identifier)}`);\n }\n\n async getLogs(buildId: string): Promise<string> {\n return this.authenticatedTextRequest(`/builds/${encodeURIComponent(buildId)}/logs`);\n }\n\n async listBuilds(params: {\n billing_address: string;\n limit?: number;\n offset?: number;\n }): Promise<any[]> {\n const res: AxiosResponse = await axios({\n url: `${this.baseUrl}/builds`,\n method: \"GET\",\n params,\n headers: this.clientId ? { \"x-client-id\": this.clientId } : undefined,\n timeout: 60_000,\n validateStatus: () => true,\n });\n if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);\n return res.data as any[];\n }\n\n private async publicJsonRequest(path: string): Promise<any> {\n const res: AxiosResponse = await axios({\n url: `${this.baseUrl}${path}`,\n method: \"GET\",\n headers: this.clientId ? { \"x-client-id\": this.clientId } : undefined,\n timeout: 60_000,\n validateStatus: () => true,\n });\n if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);\n return res.data;\n }\n\n private async authenticatedJsonRequest<T>(\n path: string,\n method: \"POST\" | \"GET\",\n body?: unknown,\n ): Promise<T> {\n if (!this.account) throw new Error(\"Private key required for authenticated requests\");\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (this.clientId) headers[\"x-client-id\"] = this.clientId;\n\n // Builds API uses BillingAuth signature format (same as Billing API).\n // Keep expiry short to reduce replay window.\n const expiry = BigInt(Math.floor(Date.now() / 1000) + 60);\n const { signature } = await calculateBillingAuthSignature({\n account: this.account,\n product: \"compute\",\n expiry,\n });\n headers.Authorization = `Bearer ${signature}`;\n headers[\"X-eigenx-expiry\"] = expiry.toString();\n headers[\"X-Account\"] = this.account.address;\n\n const res: AxiosResponse = await axios({\n url: `${this.baseUrl}${path}`,\n method,\n headers,\n data: body,\n timeout: 60_000,\n validateStatus: () => true,\n });\n if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);\n return res.data as T;\n }\n\n private async authenticatedTextRequest(path: string): Promise<string> {\n if (!this.account) throw new Error(\"Private key required for authenticated requests\");\n\n const headers: Record<string, string> = {};\n if (this.clientId) headers[\"x-client-id\"] = this.clientId;\n\n const expiry = BigInt(Math.floor(Date.now() / 1000) + 60);\n const { signature } = await calculateBillingAuthSignature({\n account: this.account,\n product: \"compute\",\n expiry,\n });\n headers.Authorization = `Bearer ${signature}`;\n headers[\"X-eigenx-expiry\"] = expiry.toString();\n headers[\"X-Account\"] = this.account.address;\n\n const res: AxiosResponse = await axios({\n url: `${this.baseUrl}${path}`,\n method: \"GET\",\n headers,\n timeout: 60_000,\n responseType: \"text\",\n validateStatus: () => true,\n });\n if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);\n return typeof res.data === \"string\" ? res.data : JSON.stringify(res.data);\n }\n}\n\nfunction buildApiHttpError(res: AxiosResponse): Error {\n const status = res.status;\n const body = typeof res.data === \"string\" ? res.data : res.data ? JSON.stringify(res.data) : \"\";\n const url = res.config?.url ? ` ${res.config.url}` : \"\";\n return new Error(`BuildAPI request failed: ${status}${url} - ${body || \"Unknown error\"}`);\n}\n","// ============ Request/Response Types ============\n\nexport interface SubmitBuildRequest {\n repoUrl: string;\n gitRef: string;\n dockerfilePath?: string;\n /**\n * Path to a Caddyfile within the repository (relative to buildContextPath).\n * If omitted, the build service will not copy a Caddyfile into the image.\n */\n caddyfilePath?: string;\n buildContextPath?: string;\n dependencies?: string[];\n}\n\nexport interface SubmitBuildResponse {\n buildId: string;\n}\n\nexport const BUILD_STATUS = {\n BUILDING: \"building\",\n SUCCESS: \"success\",\n FAILED: \"failed\",\n} as const;\n\nexport type BuildStatus = (typeof BUILD_STATUS)[keyof typeof BUILD_STATUS];\n\nexport interface Build {\n buildId: string;\n billingAddress: string;\n repoUrl: string;\n gitRef: string;\n status: BuildStatus;\n /** 'application' | 'dependency' (as returned by the API) */\n buildType: string;\n imageName: string;\n imageUrl?: string;\n imageDigest?: string;\n provenanceJson?: Record<string, unknown>;\n provenanceSignature?: string;\n errorMessage?: string;\n createdAt: string;\n updatedAt: string;\n dependencies?: Record<string, Build>;\n}\n\n// ============ Verification Types ============\n\nexport type VerifyProvenanceResult = VerifyProvenanceSuccess | VerifyProvenanceFailure;\n\nexport interface VerifyProvenanceSuccess {\n status: \"verified\";\n buildId: string;\n imageUrl: string;\n imageDigest: string;\n repoUrl: string;\n gitRef: string;\n provenanceJson: Record<string, unknown>;\n provenanceSignature: string;\n payloadType: string;\n payload: string;\n}\n\nexport interface VerifyProvenanceFailure {\n status: \"failed\";\n error: string;\n buildId?: string;\n}\n\n// ============ Log Streaming ============\n\nexport interface LogChunk {\n content: string;\n totalLength: number;\n isComplete: boolean;\n finalStatus?: BuildStatus;\n}\n\nexport interface BuildProgress {\n build: Build;\n logs: string;\n}\n","export class BuildError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"BuildError\";\n }\n}\n\nexport class AuthRequiredError extends BuildError {\n constructor(message = \"Authentication required\") {\n super(message);\n this.name = \"AuthRequiredError\";\n }\n}\n\nexport class BuildFailedError extends BuildError {\n constructor(\n message: string,\n public readonly buildId: string,\n ) {\n super(message);\n this.name = \"BuildFailedError\";\n }\n}\n\nexport class ConflictError extends BuildError {\n constructor(message = \"Build already in progress\") {\n super(message);\n this.name = \"ConflictError\";\n }\n}\n\nexport class NotFoundError extends BuildError {\n constructor(message = \"Build not found\") {\n super(message);\n this.name = \"NotFoundError\";\n }\n}\n\nexport class ForbiddenError extends BuildError {\n constructor(message = \"Permission denied\") {\n super(message);\n this.name = \"ForbiddenError\";\n }\n}\n\nexport class TimeoutError extends BuildError {\n constructor(message = \"Operation timed out\") {\n super(message);\n this.name = \"TimeoutError\";\n }\n}\n\nexport class BadRequestError extends BuildError {\n constructor(message = \"Bad request\") {\n super(message);\n this.name = \"BadRequestError\";\n }\n}\n","/**\n * Build module entry point (verifiable builds + provenance)\n */\n\nimport { getEnvironmentConfig } from \"../../common/config/environment\";\nimport { withSDKTelemetry } from \"../../common/telemetry/wrapper\";\nimport { getLogger, addHexPrefix } from \"../../common/utils\";\nimport { BuildApiClient } from \"../../common/utils/buildapi\";\n\nimport { BUILD_STATUS } from \"./types\";\nimport type {\n Build,\n BuildProgress,\n BuildStatus,\n LogChunk,\n SubmitBuildRequest,\n SubmitBuildResponse,\n VerifyProvenanceResult,\n} from \"./types\";\nimport { AuthRequiredError, BuildFailedError, TimeoutError } from \"./errors\";\n\nexport interface BuildModuleConfig {\n privateKey?: string;\n environment?: string;\n verbose?: boolean;\n clientId?: string;\n skipTelemetry?: boolean;\n}\n\nexport interface BuildModule {\n submit(request: SubmitBuildRequest): Promise<SubmitBuildResponse>;\n getLogs(buildId: string): Promise<string>;\n\n list(options: { billingAddress: string; limit?: number; offset?: number }): Promise<Build[]>;\n get(buildId: string): Promise<Build>;\n getByDigest(digest: string): Promise<Build>;\n verify(identifier: string): Promise<VerifyProvenanceResult>;\n\n submitAndWait(\n request: SubmitBuildRequest,\n options?: {\n onLog?: (chunk: string) => void;\n onProgress?: (progress: BuildProgress) => void;\n pollIntervalMs?: number;\n timeoutMs?: number;\n },\n ): Promise<Build>;\n\n waitForBuild(\n buildId: string,\n options?: {\n onLog?: (chunk: string) => void;\n onProgress?: (progress: BuildProgress) => void;\n pollIntervalMs?: number;\n timeoutMs?: number;\n },\n ): Promise<Build>;\n\n streamLogs(buildId: string, pollIntervalMs?: number): AsyncGenerator<LogChunk, void, unknown>;\n}\n\nconst DEFAULT_POLL_INTERVAL = 2000;\nconst DEFAULT_TIMEOUT = 30 * 60 * 1000;\n\nexport function createBuildModule(config: BuildModuleConfig): BuildModule {\n const { verbose = false, skipTelemetry = false } = config;\n const logger = getLogger(verbose);\n\n const environment = config.environment || \"sepolia\";\n const environmentConfig = getEnvironmentConfig(environment);\n\n // NOTE: build endpoints are served from the compute UserAPI host\n const api = new BuildApiClient({\n baseUrl: environmentConfig.userApiServerURL,\n privateKey: config.privateKey ? addHexPrefix(config.privateKey) : undefined,\n clientId: config.clientId,\n });\n\n return {\n async submit(request: SubmitBuildRequest): Promise<SubmitBuildResponse> {\n return withSDKTelemetry(\n {\n functionName: \"build.submit\",\n skipTelemetry,\n properties: { environment, repoUrl: request.repoUrl },\n },\n async () => {\n if (!config.privateKey) throw new AuthRequiredError(\"Private key required for submit()\");\n\n const data = await api.submitBuild({\n repo_url: request.repoUrl,\n git_ref: request.gitRef,\n dockerfile_path: request.dockerfilePath ?? \"Dockerfile\",\n caddyfile_path: request.caddyfilePath,\n build_context_path: request.buildContextPath ?? \".\",\n dependencies: request.dependencies ?? [],\n });\n\n logger.debug(`Submitted build: ${data.build_id}`);\n return { buildId: data.build_id };\n },\n );\n },\n\n async list(options): Promise<Build[]> {\n const { billingAddress, limit, offset } = options;\n return withSDKTelemetry(\n {\n functionName: \"build.list\",\n skipTelemetry,\n properties: {\n environment,\n billingAddress,\n ...(limit !== undefined ? { limit: String(limit) } : {}),\n ...(offset !== undefined ? { offset: String(offset) } : {}),\n },\n },\n async () => {\n const data = await api.listBuilds({\n billing_address: billingAddress,\n limit,\n offset,\n });\n return Array.isArray(data) ? data.map(transformBuild) : [];\n },\n );\n },\n\n async get(buildId: string): Promise<Build> {\n return withSDKTelemetry(\n { functionName: \"build.get\", skipTelemetry, properties: { environment, buildId } },\n async () => transformBuild(await api.getBuild(buildId)),\n );\n },\n\n async getByDigest(digest: string): Promise<Build> {\n return withSDKTelemetry(\n { functionName: \"build.getByDigest\", skipTelemetry, properties: { environment, digest } },\n async () => transformBuild(await api.getBuildByDigest(digest)),\n );\n },\n\n async verify(identifier: string): Promise<VerifyProvenanceResult> {\n return withSDKTelemetry(\n { functionName: \"build.verify\", skipTelemetry, properties: { environment, identifier } },\n async () => transformVerifyResult(await api.verify(identifier)),\n );\n },\n\n async getLogs(buildId: string): Promise<string> {\n return withSDKTelemetry(\n { functionName: \"build.getLogs\", skipTelemetry, properties: { environment, buildId } },\n async () => {\n if (!config.privateKey) throw new AuthRequiredError(\"Private key required for getLogs()\");\n return api.getLogs(buildId);\n },\n );\n },\n\n async submitAndWait(request, options = {}) {\n const { buildId } = await this.submit(request);\n return this.waitForBuild(buildId, options);\n },\n\n async waitForBuild(buildId, options = {}) {\n const {\n onLog,\n onProgress,\n pollIntervalMs = DEFAULT_POLL_INTERVAL,\n timeoutMs = DEFAULT_TIMEOUT,\n } = options;\n\n const startTime = Date.now();\n let lastLogLength = 0;\n\n while (true) {\n if (Date.now() - startTime > timeoutMs) {\n throw new TimeoutError(`Build timed out after ${timeoutMs}ms`);\n }\n\n const build = await this.get(buildId);\n let logs = \"\";\n\n try {\n logs = await this.getLogs(buildId);\n if (onLog && logs.length > lastLogLength) {\n onLog(logs.slice(lastLogLength));\n lastLogLength = logs.length;\n }\n } catch {\n // ignore\n }\n\n onProgress?.({ build, logs });\n\n if (build.status === BUILD_STATUS.SUCCESS) return build;\n if (build.status === BUILD_STATUS.FAILED) {\n throw new BuildFailedError(build.errorMessage ?? \"Build failed\", buildId);\n }\n\n await sleep(pollIntervalMs);\n }\n },\n\n async *streamLogs(buildId, pollIntervalMs = DEFAULT_POLL_INTERVAL) {\n let lastLength = 0;\n while (true) {\n const build = await this.get(buildId);\n let logs = \"\";\n\n try {\n logs = await this.getLogs(buildId);\n } catch {\n // ignore\n }\n\n if (logs.length > lastLength) {\n yield {\n content: logs.slice(lastLength),\n totalLength: logs.length,\n isComplete: build.status !== BUILD_STATUS.BUILDING,\n finalStatus: build.status !== BUILD_STATUS.BUILDING ? build.status : undefined,\n };\n lastLength = logs.length;\n }\n\n if (build.status !== BUILD_STATUS.BUILDING) break;\n await sleep(pollIntervalMs);\n }\n },\n };\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction transformBuild(raw: any): Build {\n return {\n buildId: raw.build_id,\n billingAddress: raw.billing_address,\n repoUrl: raw.repo_url,\n gitRef: raw.git_ref,\n status: raw.status as BuildStatus,\n buildType: raw.build_type,\n imageName: raw.image_name,\n imageUrl: raw.image_url,\n imageDigest: raw.image_digest,\n provenanceJson: raw.provenance_json ?? undefined,\n provenanceSignature: raw.provenance_signature ?? undefined,\n errorMessage: raw.error_message ?? undefined,\n createdAt: raw.created_at,\n updatedAt: raw.updated_at,\n dependencies: raw.dependencies\n ? Object.fromEntries(Object.entries(raw.dependencies).map(([k, v]) => [k, transformBuild(v)]))\n : undefined,\n };\n}\n\nfunction transformVerifyResult(raw: any): VerifyProvenanceResult {\n if (raw.status === \"verified\") {\n return {\n status: \"verified\",\n buildId: raw.build_id,\n imageUrl: raw.image_url,\n imageDigest: raw.image_digest,\n repoUrl: raw.repo_url,\n gitRef: raw.git_ref,\n provenanceJson: raw.provenance_json,\n provenanceSignature: raw.provenance_signature,\n payloadType: raw.payload_type,\n payload: raw.payload,\n };\n }\n\n return {\n status: \"failed\",\n error: raw.error,\n buildId: raw.build_id,\n };\n}\n\n// Re-export errors/types for convenience\nexport * from \"./types\";\nexport * from \"./errors\";\n","/**\n * Instance type utilities\n */\n\nimport { Address } from \"viem\";\nimport { PreflightContext } from \"./preflight\";\nimport { Logger } from \"../types\";\nimport { UserApiClient } from \"./userapi\";\n\n/**\n * Get current instance type for an app (best-effort)\n * Returns empty string if unable to fetch (API unavailable, app info not ready, etc.).\n * This is used as a convenience default for the upgrade flow.\n */\nexport async function getCurrentInstanceType(\n preflightCtx: PreflightContext,\n appID: Address,\n logger: Logger,\n clientId?: string,\n): Promise<string> {\n try {\n const userApiClient = new UserApiClient(\n preflightCtx.environmentConfig,\n preflightCtx.privateKey,\n preflightCtx.rpcUrl,\n clientId,\n );\n\n const infos = await userApiClient.getInfos([appID], 1);\n if (infos.length === 0) {\n return \"\"; // No app info available yet\n }\n\n return infos[0].machineType || \"\";\n } catch (err: any) {\n logger.debug(`Failed to get current instance type: ${err.message}`);\n return \"\"; // API call failed, skip default\n }\n}\n","/**\n * Main SDK Client entry point\n */\n\nimport { createComputeModule, type ComputeModule } from \"./modules/compute\";\nimport {\n getEnvironmentConfig,\n isEnvironmentAvailable,\n getAvailableEnvironments,\n} from \"./common/config/environment\";\nimport { createBillingModule, type BillingModule } from \"./modules/billing\";\nimport { createBuildModule, type BuildModule, type BuildModuleConfig } from \"./modules/build\";\nimport { addHexPrefix } from \"./common/utils\";\nimport { Hex } from \"viem\";\n\n// Export all types\nexport * from \"./common/types\";\n\n// Export validation utilities (non-interactive)\nexport * from \"./common/utils/validation\";\n\n// Export common hex helpers (used by CLI as well)\nexport { addHexPrefix, stripHexPrefix } from \"./common/utils\";\n\n// Special case on createApp - we don't need the client to run it\nexport {\n createApp,\n CreateAppOpts,\n SDKCreateAppOpts,\n PRIMARY_LANGUAGES,\n getAvailableTemplates,\n} from \"./modules/compute/app/create\";\nexport { logs, LogsOptions, SDKLogsOptions } from \"./modules/compute/app/logs\";\nexport {\n SDKDeployOptions,\n prepareDeploy,\n prepareDeployFromVerifiableBuild,\n executeDeploy,\n watchDeployment,\n type PrepareDeployResult,\n} from \"./modules/compute/app/deploy\";\nexport {\n SDKUpgradeOptions,\n prepareUpgrade,\n prepareUpgradeFromVerifiableBuild,\n executeUpgrade,\n watchUpgrade,\n type PrepareUpgradeResult,\n} from \"./modules/compute/app/upgrade\";\n\n// Export compute module for standalone use\nexport {\n createComputeModule,\n type ComputeModule,\n type ComputeModuleConfig,\n encodeStartAppData,\n encodeStopAppData,\n encodeTerminateAppData,\n} from \"./modules/compute\";\nexport {\n createBillingModule,\n type BillingModule,\n type BillingModuleConfig,\n} from \"./modules/billing\";\n\n// Export environment config utilities\nexport {\n getEnvironmentConfig,\n getAvailableEnvironments,\n isEnvironmentAvailable,\n getBuildType,\n isMainnet,\n} from \"./common/config/environment\";\nexport { isSubscriptionActive } from \"./common/utils/billing\";\n\n// Export auth utilities\nexport * from \"./common/auth\";\n\n// Export telemetry\nexport * from \"./common/telemetry\";\n\n// Export template catalog utilities for CLI\nexport {\n fetchTemplateCatalog,\n getTemplate,\n getCategoryDescriptions,\n} from \"./common/templates/catalog\";\n\n// Export contract utilities\nexport {\n getAllAppsByDeveloper,\n getAppLatestReleaseBlockNumbers,\n getBlockTimestamps,\n estimateTransactionGas,\n formatETH,\n type GasEstimate,\n type EstimateGasOptions,\n} from \"./common/contract/caller\";\n\n// Export batch gas estimation and delegation check\nexport {\n estimateBatchGas,\n checkERC7702Delegation,\n type EstimateBatchGasOptions,\n} from \"./common/contract/eip7702\";\n\n// Export instance type utilities\nexport { getCurrentInstanceType } from \"./common/utils/instance\";\n\n// Export user API client\nexport {\n UserApiClient,\n type AppInfo,\n type AppProfileInfo,\n type AppMetrics,\n type AppRelease,\n type AppReleaseBuild,\n type AppResponse,\n} from \"./common/utils/userapi\";\n\nexport type Environment = \"sepolia\" | \"sepolia-dev\" | \"mainnet-alpha\";\n\nexport interface ClientConfig {\n verbose: boolean;\n privateKey: Hex;\n environment: Environment | string;\n rpcUrl?: string;\n}\n\nexport interface ECloudClient {\n compute: ComputeModule;\n billing: BillingModule;\n}\n\nexport function createECloudClient(cfg: ClientConfig): ECloudClient {\n cfg.privateKey = addHexPrefix(cfg.privateKey);\n\n // Validate environment is available in current build\n const environment = cfg.environment || \"sepolia\";\n if (!isEnvironmentAvailable(environment)) {\n throw new Error(\n `Environment \"${environment}\" is not available in this build type. ` +\n `Available environments: ${getAvailableEnvironments().join(\", \")}`,\n );\n }\n\n // Get environment config\n const environmentConfig = getEnvironmentConfig(environment);\n\n // Get rpc url from environment config or use provided rpc url\n let rpcUrl = cfg.rpcUrl;\n if (!rpcUrl) {\n rpcUrl = process.env.RPC_URL ?? environmentConfig.defaultRPCURL;\n }\n if (!rpcUrl) {\n throw new Error(\n `RPC URL is required. Provide via options.rpcUrl, RPC_URL env var, or ensure environment has default RPC URL`,\n );\n }\n\n return {\n compute: createComputeModule({\n rpcUrl,\n verbose: cfg.verbose,\n privateKey: cfg.privateKey,\n environment: cfg.environment,\n }),\n billing: createBillingModule({\n verbose: cfg.verbose,\n privateKey: cfg.privateKey,\n }),\n };\n}\n\n// ============ Build module exports ============\nexport { createBuildModule };\nexport type { BuildModule, BuildModuleConfig };\nexport * from \"./modules/build/types\";\nexport * from \"./modules/build/errors\";\n"],"mappings":"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","names":["logs"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@layr-labs/ecloud-sdk",
3
- "version": "0.1.2",
3
+ "version": "0.2.0-dev.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",