@layr-labs/ecloud-sdk 0.2.0-dev.3 → 0.2.1-dev
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/VERSION +2 -2
- package/dist/billing.cjs +34 -37
- package/dist/billing.cjs.map +1 -1
- package/dist/billing.d.cts +6 -3
- package/dist/billing.d.ts +6 -3
- package/dist/billing.js +511 -4
- package/dist/billing.js.map +1 -1
- package/dist/browser.cjs +2990 -0
- package/dist/browser.cjs.map +1 -0
- package/dist/browser.d.cts +42 -0
- package/dist/browser.d.ts +42 -0
- package/dist/browser.js +2922 -0
- package/dist/browser.js.map +1 -0
- package/dist/{compute-CF2HOXed.d.ts → compute-B85ikS78.d.ts} +15 -96
- package/dist/{compute-CbmjA8kJ.d.cts → compute-CC0R7HEu.d.cts} +15 -96
- package/dist/compute.cjs +655 -841
- package/dist/compute.cjs.map +1 -1
- package/dist/compute.d.cts +2 -2
- package/dist/compute.d.ts +2 -2
- package/dist/compute.js +6797 -7
- package/dist/compute.js.map +1 -1
- package/dist/eip7702-CXCYfOnk.d.ts +400 -0
- package/dist/eip7702-DeqoCP5b.d.cts +400 -0
- package/dist/{index-D2QufVB9.d.ts → index-D5oW73Dx.d.cts} +105 -15
- package/dist/{index-D2QufVB9.d.cts → index-D5oW73Dx.d.ts} +105 -15
- package/dist/index.cjs +1404 -1554
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +123 -388
- package/dist/index.d.ts +123 -388
- package/dist/index.js +7632 -124
- package/dist/index.js.map +1 -1
- package/package.json +6 -1
- package/dist/chunk-OUCNETHL.js +0 -434
- package/dist/chunk-OUCNETHL.js.map +0 -1
- package/dist/chunk-QN7KAUOB.js +0 -744
- package/dist/chunk-QN7KAUOB.js.map +0 -1
- package/dist/chunk-R44OVMCY.js +0 -6719
- package/dist/chunk-R44OVMCY.js.map +0 -1
package/dist/billing.js
CHANGED
|
@@ -1,7 +1,514 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
// src/client/common/utils/billingapi.ts
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
|
|
4
|
+
// src/client/common/utils/auth.ts
|
|
5
|
+
import { parseAbi } from "viem";
|
|
6
|
+
var APP_CONTROLLER_ABI = parseAbi([
|
|
7
|
+
"function calculateApiPermissionDigestHash(bytes4 permission, uint256 expiry) view returns (bytes32)"
|
|
8
|
+
]);
|
|
9
|
+
var generateBillingSigData = (product, expiry) => {
|
|
10
|
+
return {
|
|
11
|
+
domain: {
|
|
12
|
+
name: "EigenCloud Billing API",
|
|
13
|
+
version: "1"
|
|
14
|
+
},
|
|
15
|
+
types: {
|
|
16
|
+
BillingAuth: [
|
|
17
|
+
{ name: "product", type: "string" },
|
|
18
|
+
{ name: "expiry", type: "uint256" }
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
primaryType: "BillingAuth",
|
|
22
|
+
message: {
|
|
23
|
+
product,
|
|
24
|
+
expiry
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
async function calculateBillingAuthSignature(options) {
|
|
29
|
+
const { walletClient, product, expiry } = options;
|
|
30
|
+
const account = walletClient.account;
|
|
31
|
+
if (!account) {
|
|
32
|
+
throw new Error("WalletClient must have an account attached");
|
|
33
|
+
}
|
|
34
|
+
const signature = await walletClient.signTypedData({
|
|
35
|
+
account,
|
|
36
|
+
...generateBillingSigData(product, expiry)
|
|
37
|
+
});
|
|
38
|
+
return { signature, expiry };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// src/client/common/utils/billingapi.ts
|
|
42
|
+
var BillingApiClient = class {
|
|
43
|
+
constructor(config, walletClient) {
|
|
44
|
+
this.config = config;
|
|
45
|
+
this.walletClient = walletClient;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get the address of the connected wallet
|
|
49
|
+
*/
|
|
50
|
+
get address() {
|
|
51
|
+
const account = this.walletClient.account;
|
|
52
|
+
if (!account) {
|
|
53
|
+
throw new Error("WalletClient must have an account attached");
|
|
54
|
+
}
|
|
55
|
+
return account.address;
|
|
56
|
+
}
|
|
57
|
+
async createSubscription(productId = "compute") {
|
|
58
|
+
const endpoint = `${this.config.billingApiServerURL}/products/${productId}/subscription`;
|
|
59
|
+
const resp = await this.makeAuthenticatedRequest(endpoint, "POST", productId);
|
|
60
|
+
return resp.json();
|
|
61
|
+
}
|
|
62
|
+
async getSubscription(productId = "compute") {
|
|
63
|
+
const endpoint = `${this.config.billingApiServerURL}/products/${productId}/subscription`;
|
|
64
|
+
const resp = await this.makeAuthenticatedRequest(endpoint, "GET", productId);
|
|
65
|
+
return resp.json();
|
|
66
|
+
}
|
|
67
|
+
async cancelSubscription(productId = "compute") {
|
|
68
|
+
const endpoint = `${this.config.billingApiServerURL}/products/${productId}/subscription`;
|
|
69
|
+
await this.makeAuthenticatedRequest(endpoint, "DELETE", productId);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Make an authenticated request to the billing API
|
|
73
|
+
*/
|
|
74
|
+
async makeAuthenticatedRequest(url, method, productId) {
|
|
75
|
+
const expiry = BigInt(Math.floor(Date.now() / 1e3) + 5 * 60);
|
|
76
|
+
const { signature } = await calculateBillingAuthSignature({
|
|
77
|
+
walletClient: this.walletClient,
|
|
78
|
+
product: productId,
|
|
79
|
+
expiry
|
|
80
|
+
});
|
|
81
|
+
const headers = {
|
|
82
|
+
Authorization: `Bearer ${signature}`,
|
|
83
|
+
"X-Account": this.address,
|
|
84
|
+
"X-Expiry": expiry.toString()
|
|
85
|
+
};
|
|
86
|
+
try {
|
|
87
|
+
const response = await axios({
|
|
88
|
+
method,
|
|
89
|
+
url,
|
|
90
|
+
headers,
|
|
91
|
+
timeout: 3e4,
|
|
92
|
+
maxRedirects: 0,
|
|
93
|
+
validateStatus: () => true
|
|
94
|
+
// Don't throw on any status
|
|
95
|
+
});
|
|
96
|
+
const status = response.status;
|
|
97
|
+
const statusText = status >= 200 && status < 300 ? "OK" : "Error";
|
|
98
|
+
if (status < 200 || status >= 300) {
|
|
99
|
+
const body = typeof response.data === "string" ? response.data : JSON.stringify(response.data);
|
|
100
|
+
throw new Error(`BillingAPI request failed: ${status} ${statusText} - ${body}`);
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
json: async () => response.data,
|
|
104
|
+
text: async () => typeof response.data === "string" ? response.data : JSON.stringify(response.data)
|
|
105
|
+
};
|
|
106
|
+
} catch (error) {
|
|
107
|
+
if (error.message?.includes("fetch failed") || error.message?.includes("ECONNREFUSED") || error.message?.includes("ENOTFOUND") || error.cause) {
|
|
108
|
+
const cause = error.cause?.message || error.cause || error.message;
|
|
109
|
+
throw new Error(
|
|
110
|
+
`Failed to connect to BillingAPI at ${url}: ${cause}
|
|
111
|
+
Please check:
|
|
112
|
+
1. Your internet connection
|
|
113
|
+
2. The API server is accessible: ${this.config.billingApiServerURL}
|
|
114
|
+
3. Firewall/proxy settings`
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// src/client/common/config/environment.ts
|
|
123
|
+
var SEPOLIA_CHAIN_ID = 11155111;
|
|
124
|
+
var MAINNET_CHAIN_ID = 1;
|
|
125
|
+
var CommonAddresses = {
|
|
126
|
+
ERC7702Delegator: "0x63c0c19a282a1b52b07dd5a65b58948a07dae32b"
|
|
127
|
+
};
|
|
128
|
+
var ChainAddresses = {
|
|
129
|
+
[MAINNET_CHAIN_ID]: {
|
|
130
|
+
PermissionController: "0x25E5F8B1E7aDf44518d35D5B2271f114e081f0E5"
|
|
131
|
+
},
|
|
132
|
+
[SEPOLIA_CHAIN_ID]: {
|
|
133
|
+
PermissionController: "0x44632dfBdCb6D3E21EF613B0ca8A6A0c618F5a37"
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
var BILLING_ENVIRONMENTS = {
|
|
137
|
+
dev: {
|
|
138
|
+
billingApiServerURL: "https://billingapi-dev.eigencloud.xyz"
|
|
139
|
+
},
|
|
140
|
+
prod: {
|
|
141
|
+
billingApiServerURL: "https://billingapi.eigencloud.xyz"
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
var ENVIRONMENTS = {
|
|
145
|
+
"sepolia-dev": {
|
|
146
|
+
name: "sepolia",
|
|
147
|
+
build: "dev",
|
|
148
|
+
appControllerAddress: "0xa86DC1C47cb2518327fB4f9A1627F51966c83B92",
|
|
149
|
+
permissionControllerAddress: ChainAddresses[SEPOLIA_CHAIN_ID].PermissionController,
|
|
150
|
+
erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,
|
|
151
|
+
kmsServerURL: "http://10.128.0.57:8080",
|
|
152
|
+
userApiServerURL: "https://userapi-compute-sepolia-dev.eigencloud.xyz",
|
|
153
|
+
defaultRPCURL: "https://ethereum-sepolia-rpc.publicnode.com"
|
|
154
|
+
},
|
|
155
|
+
sepolia: {
|
|
156
|
+
name: "sepolia",
|
|
157
|
+
build: "prod",
|
|
158
|
+
appControllerAddress: "0x0dd810a6ffba6a9820a10d97b659f07d8d23d4E2",
|
|
159
|
+
permissionControllerAddress: ChainAddresses[SEPOLIA_CHAIN_ID].PermissionController,
|
|
160
|
+
erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,
|
|
161
|
+
kmsServerURL: "http://10.128.15.203:8080",
|
|
162
|
+
userApiServerURL: "https://userapi-compute-sepolia-prod.eigencloud.xyz",
|
|
163
|
+
defaultRPCURL: "https://ethereum-sepolia-rpc.publicnode.com"
|
|
164
|
+
},
|
|
165
|
+
"mainnet-alpha": {
|
|
166
|
+
name: "mainnet-alpha",
|
|
167
|
+
build: "prod",
|
|
168
|
+
appControllerAddress: "0xc38d35Fc995e75342A21CBd6D770305b142Fbe67",
|
|
169
|
+
permissionControllerAddress: ChainAddresses[MAINNET_CHAIN_ID].PermissionController,
|
|
170
|
+
erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,
|
|
171
|
+
kmsServerURL: "http://10.128.0.2:8080",
|
|
172
|
+
userApiServerURL: "https://userapi-compute.eigencloud.xyz",
|
|
173
|
+
defaultRPCURL: "https://ethereum-rpc.publicnode.com"
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
var CHAIN_ID_TO_ENVIRONMENT = {
|
|
177
|
+
[SEPOLIA_CHAIN_ID.toString()]: "sepolia",
|
|
178
|
+
[MAINNET_CHAIN_ID.toString()]: "mainnet-alpha"
|
|
179
|
+
};
|
|
180
|
+
function getBillingEnvironmentConfig(build) {
|
|
181
|
+
const config = BILLING_ENVIRONMENTS[build];
|
|
182
|
+
if (!config) {
|
|
183
|
+
throw new Error(`Unknown billing environment: ${build}`);
|
|
184
|
+
}
|
|
185
|
+
return config;
|
|
186
|
+
}
|
|
187
|
+
function getBuildType() {
|
|
188
|
+
const buildTimeType = true ? "dev"?.toLowerCase() : void 0;
|
|
189
|
+
const runtimeType = process.env.BUILD_TYPE?.toLowerCase();
|
|
190
|
+
const buildType = buildTimeType || runtimeType;
|
|
191
|
+
if (buildType === "dev") {
|
|
192
|
+
return "dev";
|
|
193
|
+
}
|
|
194
|
+
return "prod";
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// src/client/common/utils/logger.ts
|
|
198
|
+
var getLogger = (verbose) => ({
|
|
199
|
+
info: (...args) => console.info(...args),
|
|
200
|
+
warn: (...args) => console.warn(...args),
|
|
201
|
+
error: (...args) => console.error(...args),
|
|
202
|
+
debug: (...args) => verbose && console.debug(...args)
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// src/client/common/utils/userapi.ts
|
|
206
|
+
import axios2 from "axios";
|
|
207
|
+
|
|
208
|
+
// src/client/common/utils/helpers.ts
|
|
209
|
+
import { extractChain, createPublicClient, createWalletClient, http } from "viem";
|
|
210
|
+
import { sepolia as sepolia2 } from "viem/chains";
|
|
211
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
212
|
+
|
|
213
|
+
// src/client/common/constants.ts
|
|
214
|
+
import { sepolia, mainnet } from "viem/chains";
|
|
215
|
+
|
|
216
|
+
// src/client/common/utils/billing.ts
|
|
217
|
+
function isSubscriptionActive(status) {
|
|
218
|
+
return status === "active" || status === "trialing";
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// src/client/common/telemetry/noop.ts
|
|
222
|
+
var NoopClient = class {
|
|
223
|
+
/**
|
|
224
|
+
* AddMetric implements the TelemetryClient interface
|
|
225
|
+
*/
|
|
226
|
+
async addMetric(_metric) {
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Close implements the TelemetryClient interface
|
|
230
|
+
*/
|
|
231
|
+
async close() {
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
function isNoopClient(client) {
|
|
235
|
+
return client instanceof NoopClient;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// src/client/common/telemetry/posthog.ts
|
|
239
|
+
import { PostHog } from "posthog-node";
|
|
240
|
+
var PostHogClient = class {
|
|
241
|
+
constructor(environment, namespace, apiKey, endpoint) {
|
|
242
|
+
this.namespace = namespace;
|
|
243
|
+
this.appEnvironment = environment;
|
|
244
|
+
const host = endpoint || "https://us.i.posthog.com";
|
|
245
|
+
this.client = new PostHog(apiKey, {
|
|
246
|
+
host,
|
|
247
|
+
flushAt: 1,
|
|
248
|
+
// Flush immediately for CLI/SDK usage
|
|
249
|
+
flushInterval: 0
|
|
250
|
+
// Disable interval flushing
|
|
251
|
+
});
|
|
252
|
+
this.client.identify({
|
|
253
|
+
distinctId: environment.userUUID,
|
|
254
|
+
properties: {
|
|
255
|
+
os: environment.os,
|
|
256
|
+
arch: environment.arch,
|
|
257
|
+
...environment.cliVersion ? { cliVersion: environment.cliVersion } : {}
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* AddMetric implements the TelemetryClient interface
|
|
263
|
+
*/
|
|
264
|
+
async addMetric(metric) {
|
|
265
|
+
try {
|
|
266
|
+
const props = {
|
|
267
|
+
name: metric.name,
|
|
268
|
+
value: metric.value
|
|
269
|
+
};
|
|
270
|
+
for (const [k, v] of Object.entries(metric.dimensions)) {
|
|
271
|
+
props[k] = v;
|
|
272
|
+
}
|
|
273
|
+
this.client.capture({
|
|
274
|
+
distinctId: this.appEnvironment.userUUID,
|
|
275
|
+
event: this.namespace,
|
|
276
|
+
properties: props
|
|
277
|
+
});
|
|
278
|
+
} catch {
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Close implements the TelemetryClient interface
|
|
283
|
+
*/
|
|
284
|
+
async close() {
|
|
285
|
+
try {
|
|
286
|
+
this.client.shutdown();
|
|
287
|
+
} catch {
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
function getPostHogAPIKey() {
|
|
292
|
+
if (process.env.ECLOUD_POSTHOG_KEY) {
|
|
293
|
+
return process.env.ECLOUD_POSTHOG_KEY;
|
|
294
|
+
}
|
|
295
|
+
return true ? "phc_BiKfywNft5iBI8N7MxmuVCkb4GGZj4mDFXYPmOPUAI8" : void 0;
|
|
296
|
+
}
|
|
297
|
+
function getPostHogEndpoint() {
|
|
298
|
+
return process.env.ECLOUD_POSTHOG_ENDPOINT || "https://us.i.posthog.com";
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// src/client/common/telemetry/index.ts
|
|
302
|
+
import * as os from "os";
|
|
303
|
+
|
|
304
|
+
// src/client/common/telemetry/metricsContext.ts
|
|
305
|
+
function createMetricsContext() {
|
|
306
|
+
return {
|
|
307
|
+
startTime: /* @__PURE__ */ new Date(),
|
|
308
|
+
metrics: [],
|
|
309
|
+
properties: {}
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
function addMetric(context, name, value) {
|
|
313
|
+
addMetricWithDimensions(context, name, value, {});
|
|
314
|
+
}
|
|
315
|
+
function addMetricWithDimensions(context, name, value, dimensions) {
|
|
316
|
+
context.metrics.push({
|
|
317
|
+
name,
|
|
318
|
+
value,
|
|
319
|
+
dimensions
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// src/client/common/telemetry/index.ts
|
|
324
|
+
function createTelemetryClient(environment, namespace, options) {
|
|
325
|
+
const telemetryEnabled = options?.telemetryEnabled === true;
|
|
326
|
+
if (!telemetryEnabled) {
|
|
327
|
+
return new NoopClient();
|
|
328
|
+
}
|
|
329
|
+
const resolvedApiKey = options?.apiKey || getPostHogAPIKey();
|
|
330
|
+
if (!resolvedApiKey) {
|
|
331
|
+
return new NoopClient();
|
|
332
|
+
}
|
|
333
|
+
const endpoint = options?.endpoint || getPostHogEndpoint();
|
|
334
|
+
try {
|
|
335
|
+
return new PostHogClient(environment, namespace, resolvedApiKey, endpoint);
|
|
336
|
+
} catch {
|
|
337
|
+
return new NoopClient();
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
function createAppEnvironment(userUUID, cliVersion, osOverride, archOverride) {
|
|
341
|
+
return {
|
|
342
|
+
userUUID,
|
|
343
|
+
cliVersion,
|
|
344
|
+
os: osOverride || os.platform(),
|
|
345
|
+
arch: archOverride || os.arch()
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
async function emitMetrics(client, context) {
|
|
349
|
+
if (isNoopClient(client)) {
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
for (const metric of context.metrics) {
|
|
353
|
+
const dimensions = {
|
|
354
|
+
...metric.dimensions,
|
|
355
|
+
...context.properties
|
|
356
|
+
};
|
|
357
|
+
const metricWithProperties = {
|
|
358
|
+
...metric,
|
|
359
|
+
dimensions
|
|
360
|
+
};
|
|
361
|
+
try {
|
|
362
|
+
await client.addMetric(metricWithProperties);
|
|
363
|
+
} catch {
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// src/client/common/telemetry/wrapper.ts
|
|
369
|
+
import { randomUUID } from "crypto";
|
|
370
|
+
function generateRandomUUID() {
|
|
371
|
+
return randomUUID();
|
|
372
|
+
}
|
|
373
|
+
async function withSDKTelemetry(options, action) {
|
|
374
|
+
if (options.skipTelemetry) {
|
|
375
|
+
return action();
|
|
376
|
+
}
|
|
377
|
+
const userUUID = options.userUUID || generateRandomUUID();
|
|
378
|
+
const environment = createAppEnvironment(userUUID);
|
|
379
|
+
const client = createTelemetryClient(environment, "ecloud-sdk", {
|
|
380
|
+
telemetryEnabled: options.telemetryEnabled,
|
|
381
|
+
apiKey: options.apiKey,
|
|
382
|
+
endpoint: options.endpoint
|
|
383
|
+
});
|
|
384
|
+
const metrics = createMetricsContext();
|
|
385
|
+
metrics.properties["source"] = "ecloud-sdk";
|
|
386
|
+
metrics.properties["function"] = options.functionName;
|
|
387
|
+
if (options.properties) {
|
|
388
|
+
Object.assign(metrics.properties, options.properties);
|
|
389
|
+
}
|
|
390
|
+
addMetric(metrics, "Count", 1);
|
|
391
|
+
let actionError;
|
|
392
|
+
let result;
|
|
393
|
+
try {
|
|
394
|
+
result = await action();
|
|
395
|
+
return result;
|
|
396
|
+
} catch (err) {
|
|
397
|
+
actionError = err instanceof Error ? err : new Error(String(err));
|
|
398
|
+
throw err;
|
|
399
|
+
} finally {
|
|
400
|
+
const resultValue = actionError ? "Failure" : "Success";
|
|
401
|
+
const dimensions = {};
|
|
402
|
+
if (actionError) {
|
|
403
|
+
dimensions["error"] = actionError.message;
|
|
404
|
+
}
|
|
405
|
+
addMetricWithDimensions(metrics, resultValue, 1, dimensions);
|
|
406
|
+
const duration = Date.now() - metrics.startTime.getTime();
|
|
407
|
+
addMetric(metrics, "DurationMilliseconds", duration);
|
|
408
|
+
try {
|
|
409
|
+
await emitMetrics(client, metrics);
|
|
410
|
+
await client.close();
|
|
411
|
+
} catch {
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// src/client/modules/billing/index.ts
|
|
417
|
+
function createBillingModule(config) {
|
|
418
|
+
const { verbose = false, skipTelemetry = false, walletClient } = config;
|
|
419
|
+
if (!walletClient.account) {
|
|
420
|
+
throw new Error("WalletClient must have an account attached");
|
|
421
|
+
}
|
|
422
|
+
const address = walletClient.account.address;
|
|
423
|
+
const logger = getLogger(verbose);
|
|
424
|
+
const billingEnvConfig = getBillingEnvironmentConfig(getBuildType());
|
|
425
|
+
const billingApi = new BillingApiClient(billingEnvConfig, walletClient);
|
|
426
|
+
return {
|
|
427
|
+
address,
|
|
428
|
+
async subscribe(opts) {
|
|
429
|
+
return withSDKTelemetry(
|
|
430
|
+
{
|
|
431
|
+
functionName: "subscribe",
|
|
432
|
+
skipTelemetry,
|
|
433
|
+
// Skip if called from CLI
|
|
434
|
+
properties: { productId: opts?.productId || "compute" }
|
|
435
|
+
},
|
|
436
|
+
async () => {
|
|
437
|
+
const productId = opts?.productId || "compute";
|
|
438
|
+
logger.debug(`Checking existing subscription for ${productId}...`);
|
|
439
|
+
const currentStatus = await billingApi.getSubscription(productId);
|
|
440
|
+
if (isSubscriptionActive(currentStatus.subscriptionStatus)) {
|
|
441
|
+
logger.debug(`Subscription already active: ${currentStatus.subscriptionStatus}`);
|
|
442
|
+
return {
|
|
443
|
+
type: "already_active",
|
|
444
|
+
status: currentStatus.subscriptionStatus
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
if (currentStatus.subscriptionStatus === "past_due" || currentStatus.subscriptionStatus === "unpaid") {
|
|
448
|
+
logger.debug(`Subscription has payment issue: ${currentStatus.subscriptionStatus}`);
|
|
449
|
+
return {
|
|
450
|
+
type: "payment_issue",
|
|
451
|
+
status: currentStatus.subscriptionStatus,
|
|
452
|
+
portalUrl: currentStatus.portalUrl
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
logger.debug(`Creating subscription for ${productId}...`);
|
|
456
|
+
const result = await billingApi.createSubscription(productId);
|
|
457
|
+
logger.debug(`Checkout URL: ${result.checkoutUrl}`);
|
|
458
|
+
return {
|
|
459
|
+
type: "checkout_created",
|
|
460
|
+
checkoutUrl: result.checkoutUrl
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
);
|
|
464
|
+
},
|
|
465
|
+
async getStatus(opts) {
|
|
466
|
+
return withSDKTelemetry(
|
|
467
|
+
{
|
|
468
|
+
functionName: "getStatus",
|
|
469
|
+
skipTelemetry,
|
|
470
|
+
// Skip if called from CLI
|
|
471
|
+
properties: { productId: opts?.productId || "compute" }
|
|
472
|
+
},
|
|
473
|
+
async () => {
|
|
474
|
+
const productId = opts?.productId || "compute";
|
|
475
|
+
logger.debug(`Fetching subscription status for ${productId}...`);
|
|
476
|
+
const result = await billingApi.getSubscription(productId);
|
|
477
|
+
logger.debug(`Subscription status: ${result.subscriptionStatus}`);
|
|
478
|
+
return result;
|
|
479
|
+
}
|
|
480
|
+
);
|
|
481
|
+
},
|
|
482
|
+
async cancel(opts) {
|
|
483
|
+
return withSDKTelemetry(
|
|
484
|
+
{
|
|
485
|
+
functionName: "cancel",
|
|
486
|
+
skipTelemetry,
|
|
487
|
+
// Skip if called from CLI
|
|
488
|
+
properties: { productId: opts?.productId || "compute" }
|
|
489
|
+
},
|
|
490
|
+
async () => {
|
|
491
|
+
const productId = opts?.productId || "compute";
|
|
492
|
+
logger.debug(`Checking subscription status for ${productId}...`);
|
|
493
|
+
const currentStatus = await billingApi.getSubscription(productId);
|
|
494
|
+
if (!isSubscriptionActive(currentStatus.subscriptionStatus)) {
|
|
495
|
+
logger.debug(`No active subscription to cancel: ${currentStatus.subscriptionStatus}`);
|
|
496
|
+
return {
|
|
497
|
+
type: "no_active_subscription",
|
|
498
|
+
status: currentStatus.subscriptionStatus
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
logger.debug(`Canceling subscription for ${productId}...`);
|
|
502
|
+
await billingApi.cancelSubscription(productId);
|
|
503
|
+
logger.debug(`Subscription canceled successfully`);
|
|
504
|
+
return {
|
|
505
|
+
type: "canceled"
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
};
|
|
511
|
+
}
|
|
5
512
|
export {
|
|
6
513
|
createBillingModule
|
|
7
514
|
};
|