@elsoul/erpc-sdk 0.1.0 → 0.2.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/README.md +28 -0
- package/dist/index.cjs +394 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +137 -1
- package/dist/index.d.ts +137 -1
- package/dist/index.js +389 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,6 +48,7 @@ network request.
|
|
|
48
48
|
| `erpc.ethereum.subscriptions` | Ethereum WebSocket subscriptions |
|
|
49
49
|
| `erpc.price` | Price metadata, updates, and streams |
|
|
50
50
|
| `erpc.account` | ERPC token balance |
|
|
51
|
+
| `erpc.usage` | Masked monthly API-key usage |
|
|
51
52
|
|
|
52
53
|
## Examples
|
|
53
54
|
|
|
@@ -72,6 +73,33 @@ await heads.unsubscribe()
|
|
|
72
73
|
erpc.close()
|
|
73
74
|
```
|
|
74
75
|
|
|
76
|
+
Monthly API-key usage is available from the same client:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
const usage = await erpc.usage.getMonthlyApiKeyUsage({
|
|
80
|
+
yearMonth: '2026-08',
|
|
81
|
+
})
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
For scoped ERPC Cloud OAuth access tokens, create a client that cannot receive
|
|
85
|
+
or retain refresh credentials:
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { createErpcCloudClient } from '@elsoul/erpc-sdk'
|
|
89
|
+
|
|
90
|
+
const cloud = createErpcCloudClient({ accessToken })
|
|
91
|
+
const catalog = await cloud.catalog.list()
|
|
92
|
+
const credit = await cloud.credit.get()
|
|
93
|
+
const resources = await cloud.resources.list()
|
|
94
|
+
const first = resources[0]
|
|
95
|
+
const status = first ? await cloud.resources.getStatus(first.id) : undefined
|
|
96
|
+
const monthlyUsage = await cloud.usage.getMonthlyApiKeyUsage()
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Catalog, credit, and resource results are projected onto documented public
|
|
100
|
+
fields. Interactive login and operating-system keychain storage belong to
|
|
101
|
+
`@elsoul/erpc-cli`.
|
|
102
|
+
|
|
75
103
|
## Raw methods
|
|
76
104
|
|
|
77
105
|
The typed catalogs track methods available from ERPC. The raw API provides
|
package/dist/index.cjs
CHANGED
|
@@ -242,9 +242,82 @@ var AccountClient = class {
|
|
|
242
242
|
}
|
|
243
243
|
};
|
|
244
244
|
|
|
245
|
+
// src/catalog.ts
|
|
246
|
+
var resourceKinds = [
|
|
247
|
+
"bare-metal",
|
|
248
|
+
"solana-grpc",
|
|
249
|
+
"solana-shredstream",
|
|
250
|
+
"vps"
|
|
251
|
+
];
|
|
252
|
+
var resourceModes = [
|
|
253
|
+
"dedicated",
|
|
254
|
+
"direct",
|
|
255
|
+
"shared"
|
|
256
|
+
];
|
|
257
|
+
var objectValue = (value) => typeof value === "object" && value !== null ? value : null;
|
|
258
|
+
var stringArray = (value) => Array.isArray(value) && value.every((item) => typeof item === "string") ? value : null;
|
|
259
|
+
var parseOffering = (value) => {
|
|
260
|
+
const offering = objectValue(value);
|
|
261
|
+
if (offering === null || typeof offering.id !== "string" || typeof offering.kind !== "string" || !resourceKinds.includes(offering.kind) || typeof offering.name !== "string" || typeof offering.description !== "string" || offering.mode !== void 0 && (typeof offering.mode !== "string" || !resourceModes.includes(offering.mode))) return null;
|
|
262
|
+
const regions = stringArray(offering.regions);
|
|
263
|
+
const capabilities = stringArray(offering.capabilities);
|
|
264
|
+
if (regions === null || capabilities === null) return null;
|
|
265
|
+
const compute = offering.compute === void 0 ? void 0 : objectValue(offering.compute);
|
|
266
|
+
if (compute !== void 0 && (compute === null || compute.tenancy !== "virtual-machine" && compute.tenancy !== "bare-metal")) return null;
|
|
267
|
+
const solana = offering.solana === void 0 ? void 0 : objectValue(offering.solana);
|
|
268
|
+
if (solana !== void 0 && (solana === null || solana.transport !== "grpc" && solana.transport !== "shredstream")) return null;
|
|
269
|
+
const billing = offering.billing === void 0 ? void 0 : objectValue(offering.billing);
|
|
270
|
+
if (billing !== void 0 && (billing === null || billing.unit !== "cents-per-hour" || typeof billing.amountCents !== "number" || !Number.isInteger(billing.amountCents) || billing.amountCents < 0)) return null;
|
|
271
|
+
return {
|
|
272
|
+
id: offering.id,
|
|
273
|
+
kind: offering.kind,
|
|
274
|
+
name: offering.name,
|
|
275
|
+
description: offering.description,
|
|
276
|
+
regions,
|
|
277
|
+
capabilities,
|
|
278
|
+
...typeof offering.mode === "string" ? { mode: offering.mode } : {},
|
|
279
|
+
...compute && (compute.tenancy === "virtual-machine" || compute.tenancy === "bare-metal") ? { compute: { tenancy: compute.tenancy } } : {},
|
|
280
|
+
...solana && (solana.transport === "grpc" || solana.transport === "shredstream") ? { solana: { transport: solana.transport } } : {},
|
|
281
|
+
...billing && billing.unit === "cents-per-hour" && typeof billing.amountCents === "number" ? {
|
|
282
|
+
billing: {
|
|
283
|
+
amountCents: billing.amountCents,
|
|
284
|
+
unit: billing.unit
|
|
285
|
+
}
|
|
286
|
+
} : {}
|
|
287
|
+
};
|
|
288
|
+
};
|
|
289
|
+
var CloudCatalogClient = class {
|
|
290
|
+
#transport;
|
|
291
|
+
constructor(transport) {
|
|
292
|
+
this.#transport = transport;
|
|
293
|
+
}
|
|
294
|
+
async list(options) {
|
|
295
|
+
const response = await this.#transport.get(
|
|
296
|
+
"/v4/cloud/catalog",
|
|
297
|
+
void 0,
|
|
298
|
+
options
|
|
299
|
+
);
|
|
300
|
+
const envelope = objectValue(response);
|
|
301
|
+
const message = objectValue(envelope?.message);
|
|
302
|
+
if (envelope?.success !== true || !Array.isArray(message?.offerings)) {
|
|
303
|
+
throw new ErpcInvalidResponseError(
|
|
304
|
+
"ERPC returned an invalid Cloud catalog"
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
const offerings = message.offerings.map(parseOffering);
|
|
308
|
+
if (offerings.some((offering) => offering === null)) {
|
|
309
|
+
throw new ErpcInvalidResponseError(
|
|
310
|
+
"ERPC returned an invalid Cloud catalog"
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
return offerings;
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
|
|
245
317
|
// src/config.ts
|
|
246
318
|
var DEFAULT_ENDPOINT = "https://edge.erpc.global";
|
|
247
319
|
var DEFAULT_ACCOUNT_ENDPOINT = "https://solana-rpc.erpc.global";
|
|
320
|
+
var DEFAULT_USER_ENDPOINT = "https://user-api.erpc.global";
|
|
248
321
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
249
322
|
var requireFetch = (provided) => {
|
|
250
323
|
const implementation = provided ?? globalThis.fetch;
|
|
@@ -260,11 +333,13 @@ var resolveConfig = (config) => {
|
|
|
260
333
|
if (!apiKey) throw new ErpcConfigError("apiKey must not be empty");
|
|
261
334
|
let endpoint;
|
|
262
335
|
let accountEndpoint;
|
|
336
|
+
let userEndpoint;
|
|
263
337
|
try {
|
|
264
338
|
endpoint = new URL(config.endpoint ?? DEFAULT_ENDPOINT);
|
|
265
339
|
accountEndpoint = new URL(
|
|
266
340
|
config.accountEndpoint ?? DEFAULT_ACCOUNT_ENDPOINT
|
|
267
341
|
);
|
|
342
|
+
userEndpoint = new URL(config.userEndpoint ?? DEFAULT_USER_ENDPOINT);
|
|
268
343
|
} catch {
|
|
269
344
|
throw new ErpcConfigError("endpoint must be an absolute HTTP(S) URL");
|
|
270
345
|
}
|
|
@@ -274,12 +349,18 @@ var resolveConfig = (config) => {
|
|
|
274
349
|
if (accountEndpoint.protocol !== "https:" && accountEndpoint.protocol !== "http:") {
|
|
275
350
|
throw new ErpcConfigError("accountEndpoint must use HTTP or HTTPS");
|
|
276
351
|
}
|
|
352
|
+
if (userEndpoint.protocol !== "https:" && userEndpoint.protocol !== "http:") {
|
|
353
|
+
throw new ErpcConfigError("userEndpoint must use HTTP or HTTPS");
|
|
354
|
+
}
|
|
277
355
|
endpoint.search = "";
|
|
278
356
|
endpoint.hash = "";
|
|
279
357
|
endpoint.pathname = endpoint.pathname.replace(/\/+$/, "") || "/";
|
|
280
358
|
accountEndpoint.search = "";
|
|
281
359
|
accountEndpoint.hash = "";
|
|
282
360
|
accountEndpoint.pathname = accountEndpoint.pathname.replace(/\/+$/, "") || "/";
|
|
361
|
+
userEndpoint.search = "";
|
|
362
|
+
userEndpoint.hash = "";
|
|
363
|
+
userEndpoint.pathname = userEndpoint.pathname.replace(/\/+$/, "") || "/";
|
|
283
364
|
const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
284
365
|
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
285
366
|
throw new ErpcConfigError("timeoutMs must be a positive finite number");
|
|
@@ -291,6 +372,7 @@ var resolveConfig = (config) => {
|
|
|
291
372
|
fetch: requireFetch(config.fetch),
|
|
292
373
|
headers: config.headers ?? {},
|
|
293
374
|
timeoutMs,
|
|
375
|
+
userEndpoint,
|
|
294
376
|
...config.webSocket === void 0 ? {} : { webSocket: config.webSocket }
|
|
295
377
|
};
|
|
296
378
|
};
|
|
@@ -1198,6 +1280,91 @@ var HttpJsonRpcTransport = class {
|
|
|
1198
1280
|
}
|
|
1199
1281
|
};
|
|
1200
1282
|
|
|
1283
|
+
// src/usage.ts
|
|
1284
|
+
var YEAR_MONTH = /^\d{4}-(0[1-9]|1[0-2])$/;
|
|
1285
|
+
var objectValue2 = (value) => typeof value === "object" && value !== null ? value : null;
|
|
1286
|
+
var isTimestamp = (value) => value === null || typeof value === "string";
|
|
1287
|
+
var parseMethod = (value) => {
|
|
1288
|
+
const method = objectValue2(value);
|
|
1289
|
+
if (method === null || typeof method.count !== "number" || typeof method.creditCost !== "number" || typeof method.credits !== "number" || typeof method.method !== "string" || !isTimestamp(method.updatedAt)) return null;
|
|
1290
|
+
return {
|
|
1291
|
+
count: method.count,
|
|
1292
|
+
creditCost: method.creditCost,
|
|
1293
|
+
credits: method.credits,
|
|
1294
|
+
method: method.method,
|
|
1295
|
+
updatedAt: method.updatedAt
|
|
1296
|
+
};
|
|
1297
|
+
};
|
|
1298
|
+
var parseChain = (value) => {
|
|
1299
|
+
const chain = objectValue2(value);
|
|
1300
|
+
if (chain === null || typeof chain.chain !== "string" || typeof chain.count !== "number" || typeof chain.credits !== "number" || !Array.isArray(chain.methods) || !isTimestamp(chain.updatedAt)) return null;
|
|
1301
|
+
const methods = chain.methods.map(parseMethod);
|
|
1302
|
+
if (methods.some((method) => method === null)) return null;
|
|
1303
|
+
return {
|
|
1304
|
+
chain: chain.chain,
|
|
1305
|
+
count: chain.count,
|
|
1306
|
+
credits: chain.credits,
|
|
1307
|
+
methods,
|
|
1308
|
+
updatedAt: chain.updatedAt
|
|
1309
|
+
};
|
|
1310
|
+
};
|
|
1311
|
+
var parseApiKey = (value) => {
|
|
1312
|
+
const apiKey = objectValue2(value);
|
|
1313
|
+
if (apiKey === null || typeof apiKey.apiKeyLast4 !== "string" || typeof apiKey.apiKeyLength !== "number" || !Array.isArray(apiKey.chains) || typeof apiKey.count !== "number" || typeof apiKey.credits !== "number" || apiKey.keyId !== null && typeof apiKey.keyId !== "number" || !isTimestamp(apiKey.updatedAt)) return null;
|
|
1314
|
+
const chains = apiKey.chains.map(parseChain);
|
|
1315
|
+
if (chains.some((chain) => chain === null)) return null;
|
|
1316
|
+
return {
|
|
1317
|
+
apiKeyLast4: apiKey.apiKeyLast4,
|
|
1318
|
+
apiKeyLength: apiKey.apiKeyLength,
|
|
1319
|
+
chains,
|
|
1320
|
+
count: apiKey.count,
|
|
1321
|
+
credits: apiKey.credits,
|
|
1322
|
+
keyId: apiKey.keyId,
|
|
1323
|
+
updatedAt: apiKey.updatedAt
|
|
1324
|
+
};
|
|
1325
|
+
};
|
|
1326
|
+
var parseMonthlyUsage = (value) => {
|
|
1327
|
+
const usage = objectValue2(value);
|
|
1328
|
+
if (usage === null || !Array.isArray(usage.apiKeys) || !Array.isArray(usage.chains) || typeof usage.hasStrandedUsage !== "boolean" || typeof usage.keyCount !== "number" || typeof usage.totalCount !== "number" || typeof usage.totalCredits !== "number" || !isTimestamp(usage.updatedAt) || typeof usage.yearMonth !== "string" || !YEAR_MONTH.test(usage.yearMonth)) return null;
|
|
1329
|
+
const apiKeys = usage.apiKeys.map(parseApiKey);
|
|
1330
|
+
const chains = usage.chains.map(parseChain);
|
|
1331
|
+
if (apiKeys.some((apiKey) => apiKey === null) || chains.some((chain) => chain === null)) return null;
|
|
1332
|
+
return {
|
|
1333
|
+
apiKeys,
|
|
1334
|
+
chains,
|
|
1335
|
+
hasStrandedUsage: usage.hasStrandedUsage,
|
|
1336
|
+
keyCount: usage.keyCount,
|
|
1337
|
+
totalCount: usage.totalCount,
|
|
1338
|
+
totalCredits: usage.totalCredits,
|
|
1339
|
+
updatedAt: usage.updatedAt,
|
|
1340
|
+
yearMonth: usage.yearMonth
|
|
1341
|
+
};
|
|
1342
|
+
};
|
|
1343
|
+
var UsageClient = class {
|
|
1344
|
+
#transport;
|
|
1345
|
+
constructor(transport) {
|
|
1346
|
+
this.#transport = transport;
|
|
1347
|
+
}
|
|
1348
|
+
async getMonthlyApiKeyUsage(params = {}, options) {
|
|
1349
|
+
if (params.yearMonth !== void 0 && !YEAR_MONTH.test(params.yearMonth)) {
|
|
1350
|
+
throw new ErpcConfigError("yearMonth must use YYYY-MM format");
|
|
1351
|
+
}
|
|
1352
|
+
const response = await this.#transport.get(
|
|
1353
|
+
"/v3/user/api-keys/usage",
|
|
1354
|
+
{ yearMonth: params.yearMonth },
|
|
1355
|
+
options
|
|
1356
|
+
);
|
|
1357
|
+
const envelope = objectValue2(response);
|
|
1358
|
+
const usage = envelope?.success === true ? parseMonthlyUsage(envelope.message) : null;
|
|
1359
|
+
if (usage === null) {
|
|
1360
|
+
throw new ErpcInvalidResponseError(
|
|
1361
|
+
"ERPC returned an invalid monthly API key usage response"
|
|
1362
|
+
);
|
|
1363
|
+
}
|
|
1364
|
+
return usage;
|
|
1365
|
+
}
|
|
1366
|
+
};
|
|
1367
|
+
|
|
1201
1368
|
// src/client.ts
|
|
1202
1369
|
var createErpcClient = (config) => {
|
|
1203
1370
|
const resolved = resolveConfig(config);
|
|
@@ -1234,6 +1401,10 @@ var createErpcClient = (config) => {
|
|
|
1234
1401
|
...sharedTransport,
|
|
1235
1402
|
endpoint: resolved.accountEndpoint
|
|
1236
1403
|
});
|
|
1404
|
+
const userTransport = new RestTransport({
|
|
1405
|
+
...sharedTransport,
|
|
1406
|
+
endpoint: resolved.userEndpoint
|
|
1407
|
+
});
|
|
1237
1408
|
const solana = {
|
|
1238
1409
|
...createSolanaClient(solanaTransport),
|
|
1239
1410
|
subscriptions: new SolanaSubscriptions(solanaWebSocket)
|
|
@@ -1247,6 +1418,7 @@ var createErpcClient = (config) => {
|
|
|
1247
1418
|
ethereum,
|
|
1248
1419
|
price: new PriceClient(priceTransport),
|
|
1249
1420
|
account: new AccountClient(accountTransport),
|
|
1421
|
+
usage: new UsageClient(userTransport),
|
|
1250
1422
|
close: () => {
|
|
1251
1423
|
solana.subscriptions.close();
|
|
1252
1424
|
ethereum.subscriptions.close();
|
|
@@ -1254,10 +1426,230 @@ var createErpcClient = (config) => {
|
|
|
1254
1426
|
};
|
|
1255
1427
|
};
|
|
1256
1428
|
|
|
1429
|
+
// src/credit.ts
|
|
1430
|
+
var alertLevels = [
|
|
1431
|
+
"critical",
|
|
1432
|
+
"normal",
|
|
1433
|
+
"suspended",
|
|
1434
|
+
"warning"
|
|
1435
|
+
];
|
|
1436
|
+
var objectValue3 = (value) => typeof value === "object" && value !== null ? value : null;
|
|
1437
|
+
var isDateTime = (value) => typeof value === "string" && Number.isFinite(Date.parse(value));
|
|
1438
|
+
var parseCredit = (value) => {
|
|
1439
|
+
const credit = objectValue3(value);
|
|
1440
|
+
if (credit === null || typeof credit.balanceCents !== "number" || !Number.isInteger(credit.balanceCents) || typeof credit.burnRateCentsPerHour !== "number" || !Number.isInteger(credit.burnRateCentsPerHour) || credit.burnRateCentsPerHour < 0 || credit.timeToZeroHours !== null && (typeof credit.timeToZeroHours !== "number" || !Number.isFinite(credit.timeToZeroHours) || credit.timeToZeroHours < 0) || typeof credit.alertLevel !== "string" || !alertLevels.includes(credit.alertLevel) || !isDateTime(credit.quoteTimestamp) || !isDateTime(credit.quoteExpiresAt)) return null;
|
|
1441
|
+
return {
|
|
1442
|
+
alertLevel: credit.alertLevel,
|
|
1443
|
+
balanceCents: credit.balanceCents,
|
|
1444
|
+
burnRateCentsPerHour: credit.burnRateCentsPerHour,
|
|
1445
|
+
quoteExpiresAt: credit.quoteExpiresAt,
|
|
1446
|
+
quoteTimestamp: credit.quoteTimestamp,
|
|
1447
|
+
timeToZeroHours: credit.timeToZeroHours
|
|
1448
|
+
};
|
|
1449
|
+
};
|
|
1450
|
+
var CloudCreditClient = class {
|
|
1451
|
+
#transport;
|
|
1452
|
+
constructor(transport) {
|
|
1453
|
+
this.#transport = transport;
|
|
1454
|
+
}
|
|
1455
|
+
async get(options) {
|
|
1456
|
+
const response = await this.#transport.get(
|
|
1457
|
+
"/v4/cloud/credit",
|
|
1458
|
+
void 0,
|
|
1459
|
+
options
|
|
1460
|
+
);
|
|
1461
|
+
const envelope = objectValue3(response);
|
|
1462
|
+
const credit = envelope?.success === true ? parseCredit(envelope.message) : null;
|
|
1463
|
+
if (credit === null) {
|
|
1464
|
+
throw new ErpcInvalidResponseError(
|
|
1465
|
+
"ERPC returned an invalid Cloud credit snapshot"
|
|
1466
|
+
);
|
|
1467
|
+
}
|
|
1468
|
+
return credit;
|
|
1469
|
+
}
|
|
1470
|
+
};
|
|
1471
|
+
|
|
1472
|
+
// src/resources.ts
|
|
1473
|
+
var objectValue4 = (value) => typeof value === "object" && value !== null ? value : null;
|
|
1474
|
+
var resourceKinds2 = [
|
|
1475
|
+
"bare-metal",
|
|
1476
|
+
"solana-grpc",
|
|
1477
|
+
"solana-shredstream",
|
|
1478
|
+
"vps"
|
|
1479
|
+
];
|
|
1480
|
+
var resourceModes2 = [
|
|
1481
|
+
"dedicated",
|
|
1482
|
+
"direct",
|
|
1483
|
+
"shared"
|
|
1484
|
+
];
|
|
1485
|
+
var billingStatuses = [
|
|
1486
|
+
"active",
|
|
1487
|
+
"grace-period",
|
|
1488
|
+
"inactive",
|
|
1489
|
+
"suspended"
|
|
1490
|
+
];
|
|
1491
|
+
var isDateTime2 = (value) => typeof value === "string" && Number.isFinite(Date.parse(value));
|
|
1492
|
+
var parseStatusBilling = (value) => {
|
|
1493
|
+
const billing = objectValue4(value);
|
|
1494
|
+
if (billing === null || typeof billing.status !== "string" || !billingStatuses.includes(
|
|
1495
|
+
billing.status
|
|
1496
|
+
) || billing.hourlyCredits !== void 0 && (typeof billing.hourlyCredits !== "number" || !Number.isFinite(billing.hourlyCredits) || billing.hourlyCredits < 0) || billing.nextChargeAt !== void 0 && !isDateTime2(billing.nextChargeAt) || billing.graceEndsAt !== void 0 && !isDateTime2(billing.graceEndsAt)) return null;
|
|
1497
|
+
return {
|
|
1498
|
+
status: billing.status,
|
|
1499
|
+
...typeof billing.hourlyCredits === "number" ? { hourlyCredits: billing.hourlyCredits } : {},
|
|
1500
|
+
...typeof billing.nextChargeAt === "string" ? { nextChargeAt: billing.nextChargeAt } : {},
|
|
1501
|
+
...typeof billing.graceEndsAt === "string" ? { graceEndsAt: billing.graceEndsAt } : {}
|
|
1502
|
+
};
|
|
1503
|
+
};
|
|
1504
|
+
var parseResourceStatus = (value) => {
|
|
1505
|
+
const status = objectValue4(value);
|
|
1506
|
+
if (status === null || typeof status.id !== "string" || typeof status.status !== "string") return null;
|
|
1507
|
+
const billing = status.billing === void 0 ? void 0 : parseStatusBilling(status.billing);
|
|
1508
|
+
if (status.billing !== void 0 && billing === null) return null;
|
|
1509
|
+
return {
|
|
1510
|
+
id: status.id,
|
|
1511
|
+
status: status.status,
|
|
1512
|
+
...billing ? { billing } : {}
|
|
1513
|
+
};
|
|
1514
|
+
};
|
|
1515
|
+
var parseResource = (value) => {
|
|
1516
|
+
const resource = objectValue4(value);
|
|
1517
|
+
if (resource === null || typeof resource.id !== "string" || typeof resource.kind !== "string" || !resourceKinds2.includes(resource.kind) || typeof resource.status !== "string" || resource.mode !== void 0 && (typeof resource.mode !== "string" || !resourceModes2.includes(resource.mode)) || resource.name !== void 0 && typeof resource.name !== "string" || resource.region !== void 0 && typeof resource.region !== "string" || resource.createdAt !== void 0 && typeof resource.createdAt !== "string") return null;
|
|
1518
|
+
return {
|
|
1519
|
+
id: resource.id,
|
|
1520
|
+
kind: resource.kind,
|
|
1521
|
+
status: resource.status,
|
|
1522
|
+
...typeof resource.mode === "string" ? { mode: resource.mode } : {},
|
|
1523
|
+
...typeof resource.name === "string" ? { name: resource.name } : {},
|
|
1524
|
+
...typeof resource.region === "string" ? { region: resource.region } : {},
|
|
1525
|
+
...typeof resource.createdAt === "string" ? { createdAt: resource.createdAt } : {}
|
|
1526
|
+
};
|
|
1527
|
+
};
|
|
1528
|
+
var CloudResourcesClient = class {
|
|
1529
|
+
#transport;
|
|
1530
|
+
constructor(transport) {
|
|
1531
|
+
this.#transport = transport;
|
|
1532
|
+
}
|
|
1533
|
+
async list(options) {
|
|
1534
|
+
const response = await this.#transport.get(
|
|
1535
|
+
"/v4/cloud/resources",
|
|
1536
|
+
void 0,
|
|
1537
|
+
options
|
|
1538
|
+
);
|
|
1539
|
+
const envelope = objectValue4(response);
|
|
1540
|
+
const message = objectValue4(envelope?.message);
|
|
1541
|
+
if (envelope?.success !== true || !Array.isArray(message?.resources)) {
|
|
1542
|
+
throw new ErpcInvalidResponseError(
|
|
1543
|
+
"ERPC returned an invalid Cloud resource list"
|
|
1544
|
+
);
|
|
1545
|
+
}
|
|
1546
|
+
const resources = message.resources.map(parseResource);
|
|
1547
|
+
if (resources.some((resource) => resource === null)) {
|
|
1548
|
+
throw new ErpcInvalidResponseError(
|
|
1549
|
+
"ERPC returned an invalid Cloud resource list"
|
|
1550
|
+
);
|
|
1551
|
+
}
|
|
1552
|
+
return resources;
|
|
1553
|
+
}
|
|
1554
|
+
async get(resourceId, options) {
|
|
1555
|
+
const normalizedId = resourceId.trim();
|
|
1556
|
+
if (!normalizedId) {
|
|
1557
|
+
throw new ErpcConfigError("resourceId must not be empty");
|
|
1558
|
+
}
|
|
1559
|
+
const response = await this.#transport.get(
|
|
1560
|
+
`/v4/cloud/resources/${encodeURIComponent(normalizedId)}`,
|
|
1561
|
+
void 0,
|
|
1562
|
+
options
|
|
1563
|
+
);
|
|
1564
|
+
const envelope = objectValue4(response);
|
|
1565
|
+
const message = objectValue4(envelope?.message);
|
|
1566
|
+
const resource = envelope?.success === true ? parseResource(message?.resource) : null;
|
|
1567
|
+
if (resource === null) {
|
|
1568
|
+
throw new ErpcInvalidResponseError(
|
|
1569
|
+
"ERPC returned an invalid Cloud resource"
|
|
1570
|
+
);
|
|
1571
|
+
}
|
|
1572
|
+
return resource;
|
|
1573
|
+
}
|
|
1574
|
+
async getStatus(resourceId, options) {
|
|
1575
|
+
const normalizedId = resourceId.trim();
|
|
1576
|
+
if (!normalizedId) {
|
|
1577
|
+
throw new ErpcConfigError("resourceId must not be empty");
|
|
1578
|
+
}
|
|
1579
|
+
const response = await this.#transport.get(
|
|
1580
|
+
`/v4/cloud/resources/${encodeURIComponent(normalizedId)}/status`,
|
|
1581
|
+
void 0,
|
|
1582
|
+
options
|
|
1583
|
+
);
|
|
1584
|
+
const envelope = objectValue4(response);
|
|
1585
|
+
const status = envelope?.success === true ? parseResourceStatus(envelope.message) : null;
|
|
1586
|
+
if (status === null) {
|
|
1587
|
+
throw new ErpcInvalidResponseError(
|
|
1588
|
+
"ERPC returned an invalid Cloud resource status"
|
|
1589
|
+
);
|
|
1590
|
+
}
|
|
1591
|
+
return status;
|
|
1592
|
+
}
|
|
1593
|
+
};
|
|
1594
|
+
|
|
1595
|
+
// src/cloud.ts
|
|
1596
|
+
var requireFetch2 = (provided) => {
|
|
1597
|
+
const implementation = provided ?? globalThis.fetch;
|
|
1598
|
+
if (typeof implementation !== "function") {
|
|
1599
|
+
throw new ErpcConfigError(
|
|
1600
|
+
"A Fetch API implementation is required in this runtime"
|
|
1601
|
+
);
|
|
1602
|
+
}
|
|
1603
|
+
return implementation;
|
|
1604
|
+
};
|
|
1605
|
+
var cloudEndpoint = (value) => {
|
|
1606
|
+
let endpoint;
|
|
1607
|
+
try {
|
|
1608
|
+
endpoint = new URL(value ?? DEFAULT_USER_ENDPOINT);
|
|
1609
|
+
} catch {
|
|
1610
|
+
throw new ErpcConfigError("endpoint must be an absolute HTTP(S) URL");
|
|
1611
|
+
}
|
|
1612
|
+
const isLocalHttp = endpoint.protocol === "http:" && ["127.0.0.1", "::1", "[::1]", "localhost"].includes(endpoint.hostname);
|
|
1613
|
+
if (endpoint.protocol !== "https:" && !isLocalHttp) {
|
|
1614
|
+
throw new ErpcConfigError("endpoint must use HTTPS except on localhost");
|
|
1615
|
+
}
|
|
1616
|
+
endpoint.search = "";
|
|
1617
|
+
endpoint.hash = "";
|
|
1618
|
+
endpoint.pathname = endpoint.pathname.replace(/\/+$/, "") || "/";
|
|
1619
|
+
return endpoint;
|
|
1620
|
+
};
|
|
1621
|
+
var createErpcCloudClient = (config) => {
|
|
1622
|
+
const accessToken = config.accessToken.trim();
|
|
1623
|
+
if (!accessToken) {
|
|
1624
|
+
throw new ErpcConfigError("accessToken must not be empty");
|
|
1625
|
+
}
|
|
1626
|
+
const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
1627
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
1628
|
+
throw new ErpcConfigError("timeoutMs must be a positive finite number");
|
|
1629
|
+
}
|
|
1630
|
+
const transport = new RestTransport({
|
|
1631
|
+
apiKey: accessToken,
|
|
1632
|
+
endpoint: cloudEndpoint(config.endpoint),
|
|
1633
|
+
fetch: requireFetch2(config.fetch),
|
|
1634
|
+
headers: config.headers ?? {},
|
|
1635
|
+
timeoutMs
|
|
1636
|
+
});
|
|
1637
|
+
return {
|
|
1638
|
+
catalog: new CloudCatalogClient(transport),
|
|
1639
|
+
credit: new CloudCreditClient(transport),
|
|
1640
|
+
resources: new CloudResourcesClient(transport),
|
|
1641
|
+
usage: new UsageClient(transport)
|
|
1642
|
+
};
|
|
1643
|
+
};
|
|
1644
|
+
|
|
1257
1645
|
exports.AccountClient = AccountClient;
|
|
1646
|
+
exports.CloudCatalogClient = CloudCatalogClient;
|
|
1647
|
+
exports.CloudCreditClient = CloudCreditClient;
|
|
1648
|
+
exports.CloudResourcesClient = CloudResourcesClient;
|
|
1258
1649
|
exports.DEFAULT_ACCOUNT_ENDPOINT = DEFAULT_ACCOUNT_ENDPOINT;
|
|
1259
1650
|
exports.DEFAULT_ENDPOINT = DEFAULT_ENDPOINT;
|
|
1260
1651
|
exports.DEFAULT_TIMEOUT_MS = DEFAULT_TIMEOUT_MS;
|
|
1652
|
+
exports.DEFAULT_USER_ENDPOINT = DEFAULT_USER_ENDPOINT;
|
|
1261
1653
|
exports.ETHEREUM_RPC_METHODS = ETHEREUM_RPC_METHODS;
|
|
1262
1654
|
exports.ETHEREUM_SUBSCRIPTION_METHODS = ETHEREUM_SUBSCRIPTION_METHODS;
|
|
1263
1655
|
exports.ErpcAbortedError = ErpcAbortedError;
|
|
@@ -1281,6 +1673,8 @@ exports.SOLANA_HISTORY_METHODS = SOLANA_HISTORY_METHODS;
|
|
|
1281
1673
|
exports.SOLANA_LEADER_METHODS = SOLANA_LEADER_METHODS;
|
|
1282
1674
|
exports.SOLANA_RPC_METHODS = SOLANA_RPC_METHODS;
|
|
1283
1675
|
exports.SolanaSubscriptions = SolanaSubscriptions;
|
|
1676
|
+
exports.UsageClient = UsageClient;
|
|
1284
1677
|
exports.createErpcClient = createErpcClient;
|
|
1678
|
+
exports.createErpcCloudClient = createErpcCloudClient;
|
|
1285
1679
|
//# sourceMappingURL=index.cjs.map
|
|
1286
1680
|
//# sourceMappingURL=index.cjs.map
|