@hypawave/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,279 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Hypawave: () => Hypawave,
24
+ HypawaveAPIError: () => HypawaveAPIError
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/errors.ts
29
+ var HypawaveAPIError = class extends Error {
30
+ constructor(status, body) {
31
+ super(body.message || body.error);
32
+ this.name = "HypawaveAPIError";
33
+ this.status = status;
34
+ this.code = body.error;
35
+ this.field = body.field;
36
+ }
37
+ get isAuth() {
38
+ return this.status === 401;
39
+ }
40
+ get isRateLimit() {
41
+ return this.status === 429;
42
+ }
43
+ get isValidation() {
44
+ return this.code === "validation_error";
45
+ }
46
+ get isOutstandingFee() {
47
+ return this.status === 402;
48
+ }
49
+ };
50
+
51
+ // src/client.ts
52
+ var DEFAULT_BASE_URL = "https://hypawave.com";
53
+ var DEFAULT_TIMEOUT = 3e4;
54
+ async function sha256hex(hex) {
55
+ const bytes = new Uint8Array(hex.match(/.{2}/g).map((b) => parseInt(b, 16)));
56
+ const hash = await crypto.subtle.digest("SHA-256", bytes);
57
+ return Array.from(new Uint8Array(hash)).map((b) => b.toString(16).padStart(2, "0")).join("");
58
+ }
59
+ var Hypawave = class {
60
+ constructor(config) {
61
+ if (!config.apiKey) {
62
+ throw new Error("apiKey is required");
63
+ }
64
+ if (!/^sk_(test|live)_.+/.test(config.apiKey)) {
65
+ throw new Error('apiKey must start with "sk_test_" or "sk_live_"');
66
+ }
67
+ this.apiKey = config.apiKey;
68
+ this.baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, "");
69
+ this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
70
+ }
71
+ async request(method, path, body, query) {
72
+ let url = `${this.baseUrl}${path}`;
73
+ if (query) {
74
+ const params = new URLSearchParams(query);
75
+ url += `?${params.toString()}`;
76
+ }
77
+ const controller = new AbortController();
78
+ const timer = setTimeout(() => controller.abort(), this.timeout);
79
+ try {
80
+ const res = await fetch(url, {
81
+ method,
82
+ headers: {
83
+ Authorization: `Bearer ${this.apiKey}`,
84
+ "Content-Type": "application/json",
85
+ Accept: "application/json"
86
+ },
87
+ body: body ? JSON.stringify(body) : void 0,
88
+ signal: controller.signal
89
+ });
90
+ const data = await res.json();
91
+ if (!res.ok) {
92
+ throw new HypawaveAPIError(res.status, data);
93
+ }
94
+ return data;
95
+ } catch (err) {
96
+ if (err instanceof HypawaveAPIError) throw err;
97
+ if (err instanceof DOMException && err.name === "AbortError") {
98
+ throw new HypawaveAPIError(408, {
99
+ error: "timeout",
100
+ message: `Request timed out after ${this.timeout}ms`
101
+ });
102
+ }
103
+ throw err;
104
+ } finally {
105
+ clearTimeout(timer);
106
+ }
107
+ }
108
+ async createInvoice(params) {
109
+ return this.request("POST", "/api/agent/create-invoice", params);
110
+ }
111
+ async getBolt11(accessToken) {
112
+ return this.request("GET", "/api/paystream-cb", void 0, { token: accessToken });
113
+ }
114
+ async confirmPayment(invoiceId, params) {
115
+ return this.request("POST", `/api/invoice/${invoiceId}/confirm`, params);
116
+ }
117
+ getPaymentPayload(params, response) {
118
+ return {
119
+ protocol: "hypawave/v1",
120
+ invoice_id: response.invoice_id,
121
+ amount: response.amount,
122
+ currency: response.currency,
123
+ sats: response.sats,
124
+ btc_usd_rate: response.btc_usd_rate,
125
+ description: params.description ?? null,
126
+ expires_at: response.expires_at,
127
+ bolt11_url: `${this.baseUrl}/api/paystream-cb?token=${response.access_token}`,
128
+ confirm_url: `${this.baseUrl}/api/invoice/${response.invoice_id}/confirm`,
129
+ payment_url: response.payment_url,
130
+ spec_url: `${this.baseUrl}/.well-known/openapi.json`,
131
+ instructions_url: `${this.baseUrl}/llms.txt`
132
+ };
133
+ }
134
+ async getBalance(currency) {
135
+ const query = currency ? { currency } : void 0;
136
+ return this.request("GET", "/api/agent/balance", void 0, query);
137
+ }
138
+ /**
139
+ * Request a fee-settlement top-up invoice. The server mints a bolt11 for
140
+ * exactly the amount owed — balance can never exceed 0. No arguments are
141
+ * needed; any amount fields in a passed params object are ignored.
142
+ *
143
+ * Throws API errors:
144
+ * - topup_not_needed — balance is already ≥ 0
145
+ * - duplicate_topup — a pending top-up invoice already exists
146
+ */
147
+ async topup(_params) {
148
+ return this.request("POST", "/api/agent/topup", {});
149
+ }
150
+ async getUnlockStatus(invoiceIds) {
151
+ return this.request("POST", "/api/get-unlock-status", {
152
+ invoice_ids: invoiceIds
153
+ });
154
+ }
155
+ async getKey(invoiceFileId, token) {
156
+ const query = { invoice_file_id: invoiceFileId };
157
+ if (token) query.token = token;
158
+ return this.request("GET", "/api/get-key", void 0, query);
159
+ }
160
+ async getUploadUrl(params) {
161
+ return this.request("POST", "/api/agent/upload-url", params);
162
+ }
163
+ async storeFile(params) {
164
+ return this.request("POST", "/api/agent/store-file", params);
165
+ }
166
+ async storeFileKey(params) {
167
+ return this.request("POST", "/api/agent/store-file-key", params);
168
+ }
169
+ async listInvoices(params) {
170
+ const query = {};
171
+ if (params?.limit !== void 0) query.limit = String(params.limit);
172
+ if (params?.offset !== void 0) query.offset = String(params.offset);
173
+ if (params?.status) query.status = params.status;
174
+ return this.request(
175
+ "GET",
176
+ "/api/agent/list-invoices",
177
+ void 0,
178
+ Object.keys(query).length ? query : void 0
179
+ );
180
+ }
181
+ async getInvoiceFiles(invoiceIds, token) {
182
+ const body = { invoice_ids: invoiceIds };
183
+ if (token) body.token = token;
184
+ return this.request("POST", "/api/get-invoice-files", body);
185
+ }
186
+ async getDownloadUrl(invoiceFileId, token) {
187
+ const body = { invoice_file_id: invoiceFileId };
188
+ if (token) body.token = token;
189
+ return this.request("POST", "/api/generate-download-url", body);
190
+ }
191
+ async getOfferDownloadUrl(paymentIntentId, params) {
192
+ return this.request(
193
+ "POST",
194
+ `/api/offers/payment-intent/${paymentIntentId}/download-url`,
195
+ params
196
+ );
197
+ }
198
+ async getReceipt(invoiceId) {
199
+ return this.request("GET", "/api/agent/receipt", void 0, {
200
+ invoice_id: String(invoiceId)
201
+ });
202
+ }
203
+ async getPayerReceipt(invoiceId, preimage) {
204
+ return this.request("GET", `/api/invoice/${invoiceId}/receipt`, void 0, {
205
+ preimage
206
+ });
207
+ }
208
+ async getSettings() {
209
+ return this.request("GET", "/api/public-settings");
210
+ }
211
+ async waitForSettlement(invoiceId, options) {
212
+ const interval = options?.pollInterval ?? 2e3;
213
+ const timeout = options?.timeout ?? 3e5;
214
+ const start = Date.now();
215
+ while (Date.now() - start < timeout) {
216
+ const status = await this.getUnlockStatus([invoiceId]);
217
+ const entry = status.statuses?.[String(invoiceId)];
218
+ if (entry?.unlocked) {
219
+ return entry;
220
+ }
221
+ if (entry?.status === "failed" || entry?.status === "expired") {
222
+ return entry;
223
+ }
224
+ await new Promise((r) => setTimeout(r, interval));
225
+ }
226
+ throw new HypawaveAPIError(408, {
227
+ error: "settlement_timeout",
228
+ message: `Settlement not confirmed within ${timeout}ms`
229
+ });
230
+ }
231
+ async payAndConfirm(params) {
232
+ const capability = params.wallet.capabilities?.returnsPreimage;
233
+ if (capability === false || capability === void 0) {
234
+ throw new HypawaveAPIError(400, {
235
+ error: "wallet_no_preimage_support",
236
+ message: "This wallet does not support returning the preimage. Hypawave requires the preimage for settlement confirmation. Use a supported adapter (NWC, LND, CLN, Alby, LNbits) from @hypawave/lightning-adapters."
237
+ });
238
+ }
239
+ if (capability === "conditional" && !params.allowConditionalPreimage) {
240
+ throw new HypawaveAPIError(400, {
241
+ error: "wallet_conditional_preimage",
242
+ message: "This wallet conditionally supports preimage return (depends on the backing node). Set allowConditionalPreimage: true to proceed at your own risk. If the preimage is not returned after payment, files will not unlock."
243
+ });
244
+ }
245
+ const { pr: bolt11, terms_hash } = await this.getBolt11(params.accessToken);
246
+ const payResult = await params.wallet.payInvoice(bolt11);
247
+ if (!payResult.preimage || !/^[0-9a-f]{64}$/i.test(payResult.preimage)) {
248
+ throw new HypawaveAPIError(400, {
249
+ error: "wallet_did_not_return_preimage",
250
+ message: "Wallet did not return a valid preimage. Hypawave requires a 64-char hex preimage for settlement confirmation."
251
+ });
252
+ }
253
+ const computedHash = await sha256hex(payResult.preimage);
254
+ if (payResult.payment_hash && computedHash.toLowerCase() !== payResult.payment_hash.toLowerCase()) {
255
+ throw new HypawaveAPIError(400, {
256
+ error: "preimage_hash_mismatch",
257
+ message: `Client-side verification failed: SHA256(preimage) does not match payment_hash. Expected ${payResult.payment_hash}, got ${computedHash}.`
258
+ });
259
+ }
260
+ const paymentHash = payResult.payment_hash || computedHash;
261
+ const confirmation = await this.confirmPayment(params.invoiceId, {
262
+ payment_hash: paymentHash,
263
+ preimage: payResult.preimage,
264
+ terms_hash
265
+ });
266
+ return {
267
+ payment_hash: paymentHash,
268
+ preimage: payResult.preimage,
269
+ terms_hash,
270
+ fees_paid_msat: payResult.fees_paid_msat,
271
+ confirmation
272
+ };
273
+ }
274
+ };
275
+ // Annotate the CommonJS export names for ESM import in node:
276
+ 0 && (module.exports = {
277
+ Hypawave,
278
+ HypawaveAPIError
279
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,251 @@
1
+ // src/errors.ts
2
+ var HypawaveAPIError = class extends Error {
3
+ constructor(status, body) {
4
+ super(body.message || body.error);
5
+ this.name = "HypawaveAPIError";
6
+ this.status = status;
7
+ this.code = body.error;
8
+ this.field = body.field;
9
+ }
10
+ get isAuth() {
11
+ return this.status === 401;
12
+ }
13
+ get isRateLimit() {
14
+ return this.status === 429;
15
+ }
16
+ get isValidation() {
17
+ return this.code === "validation_error";
18
+ }
19
+ get isOutstandingFee() {
20
+ return this.status === 402;
21
+ }
22
+ };
23
+
24
+ // src/client.ts
25
+ var DEFAULT_BASE_URL = "https://hypawave.com";
26
+ var DEFAULT_TIMEOUT = 3e4;
27
+ async function sha256hex(hex) {
28
+ const bytes = new Uint8Array(hex.match(/.{2}/g).map((b) => parseInt(b, 16)));
29
+ const hash = await crypto.subtle.digest("SHA-256", bytes);
30
+ return Array.from(new Uint8Array(hash)).map((b) => b.toString(16).padStart(2, "0")).join("");
31
+ }
32
+ var Hypawave = class {
33
+ constructor(config) {
34
+ if (!config.apiKey) {
35
+ throw new Error("apiKey is required");
36
+ }
37
+ if (!/^sk_(test|live)_.+/.test(config.apiKey)) {
38
+ throw new Error('apiKey must start with "sk_test_" or "sk_live_"');
39
+ }
40
+ this.apiKey = config.apiKey;
41
+ this.baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, "");
42
+ this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
43
+ }
44
+ async request(method, path, body, query) {
45
+ let url = `${this.baseUrl}${path}`;
46
+ if (query) {
47
+ const params = new URLSearchParams(query);
48
+ url += `?${params.toString()}`;
49
+ }
50
+ const controller = new AbortController();
51
+ const timer = setTimeout(() => controller.abort(), this.timeout);
52
+ try {
53
+ const res = await fetch(url, {
54
+ method,
55
+ headers: {
56
+ Authorization: `Bearer ${this.apiKey}`,
57
+ "Content-Type": "application/json",
58
+ Accept: "application/json"
59
+ },
60
+ body: body ? JSON.stringify(body) : void 0,
61
+ signal: controller.signal
62
+ });
63
+ const data = await res.json();
64
+ if (!res.ok) {
65
+ throw new HypawaveAPIError(res.status, data);
66
+ }
67
+ return data;
68
+ } catch (err) {
69
+ if (err instanceof HypawaveAPIError) throw err;
70
+ if (err instanceof DOMException && err.name === "AbortError") {
71
+ throw new HypawaveAPIError(408, {
72
+ error: "timeout",
73
+ message: `Request timed out after ${this.timeout}ms`
74
+ });
75
+ }
76
+ throw err;
77
+ } finally {
78
+ clearTimeout(timer);
79
+ }
80
+ }
81
+ async createInvoice(params) {
82
+ return this.request("POST", "/api/agent/create-invoice", params);
83
+ }
84
+ async getBolt11(accessToken) {
85
+ return this.request("GET", "/api/paystream-cb", void 0, { token: accessToken });
86
+ }
87
+ async confirmPayment(invoiceId, params) {
88
+ return this.request("POST", `/api/invoice/${invoiceId}/confirm`, params);
89
+ }
90
+ getPaymentPayload(params, response) {
91
+ return {
92
+ protocol: "hypawave/v1",
93
+ invoice_id: response.invoice_id,
94
+ amount: response.amount,
95
+ currency: response.currency,
96
+ sats: response.sats,
97
+ btc_usd_rate: response.btc_usd_rate,
98
+ description: params.description ?? null,
99
+ expires_at: response.expires_at,
100
+ bolt11_url: `${this.baseUrl}/api/paystream-cb?token=${response.access_token}`,
101
+ confirm_url: `${this.baseUrl}/api/invoice/${response.invoice_id}/confirm`,
102
+ payment_url: response.payment_url,
103
+ spec_url: `${this.baseUrl}/.well-known/openapi.json`,
104
+ instructions_url: `${this.baseUrl}/llms.txt`
105
+ };
106
+ }
107
+ async getBalance(currency) {
108
+ const query = currency ? { currency } : void 0;
109
+ return this.request("GET", "/api/agent/balance", void 0, query);
110
+ }
111
+ /**
112
+ * Request a fee-settlement top-up invoice. The server mints a bolt11 for
113
+ * exactly the amount owed — balance can never exceed 0. No arguments are
114
+ * needed; any amount fields in a passed params object are ignored.
115
+ *
116
+ * Throws API errors:
117
+ * - topup_not_needed — balance is already ≥ 0
118
+ * - duplicate_topup — a pending top-up invoice already exists
119
+ */
120
+ async topup(_params) {
121
+ return this.request("POST", "/api/agent/topup", {});
122
+ }
123
+ async getUnlockStatus(invoiceIds) {
124
+ return this.request("POST", "/api/get-unlock-status", {
125
+ invoice_ids: invoiceIds
126
+ });
127
+ }
128
+ async getKey(invoiceFileId, token) {
129
+ const query = { invoice_file_id: invoiceFileId };
130
+ if (token) query.token = token;
131
+ return this.request("GET", "/api/get-key", void 0, query);
132
+ }
133
+ async getUploadUrl(params) {
134
+ return this.request("POST", "/api/agent/upload-url", params);
135
+ }
136
+ async storeFile(params) {
137
+ return this.request("POST", "/api/agent/store-file", params);
138
+ }
139
+ async storeFileKey(params) {
140
+ return this.request("POST", "/api/agent/store-file-key", params);
141
+ }
142
+ async listInvoices(params) {
143
+ const query = {};
144
+ if (params?.limit !== void 0) query.limit = String(params.limit);
145
+ if (params?.offset !== void 0) query.offset = String(params.offset);
146
+ if (params?.status) query.status = params.status;
147
+ return this.request(
148
+ "GET",
149
+ "/api/agent/list-invoices",
150
+ void 0,
151
+ Object.keys(query).length ? query : void 0
152
+ );
153
+ }
154
+ async getInvoiceFiles(invoiceIds, token) {
155
+ const body = { invoice_ids: invoiceIds };
156
+ if (token) body.token = token;
157
+ return this.request("POST", "/api/get-invoice-files", body);
158
+ }
159
+ async getDownloadUrl(invoiceFileId, token) {
160
+ const body = { invoice_file_id: invoiceFileId };
161
+ if (token) body.token = token;
162
+ return this.request("POST", "/api/generate-download-url", body);
163
+ }
164
+ async getOfferDownloadUrl(paymentIntentId, params) {
165
+ return this.request(
166
+ "POST",
167
+ `/api/offers/payment-intent/${paymentIntentId}/download-url`,
168
+ params
169
+ );
170
+ }
171
+ async getReceipt(invoiceId) {
172
+ return this.request("GET", "/api/agent/receipt", void 0, {
173
+ invoice_id: String(invoiceId)
174
+ });
175
+ }
176
+ async getPayerReceipt(invoiceId, preimage) {
177
+ return this.request("GET", `/api/invoice/${invoiceId}/receipt`, void 0, {
178
+ preimage
179
+ });
180
+ }
181
+ async getSettings() {
182
+ return this.request("GET", "/api/public-settings");
183
+ }
184
+ async waitForSettlement(invoiceId, options) {
185
+ const interval = options?.pollInterval ?? 2e3;
186
+ const timeout = options?.timeout ?? 3e5;
187
+ const start = Date.now();
188
+ while (Date.now() - start < timeout) {
189
+ const status = await this.getUnlockStatus([invoiceId]);
190
+ const entry = status.statuses?.[String(invoiceId)];
191
+ if (entry?.unlocked) {
192
+ return entry;
193
+ }
194
+ if (entry?.status === "failed" || entry?.status === "expired") {
195
+ return entry;
196
+ }
197
+ await new Promise((r) => setTimeout(r, interval));
198
+ }
199
+ throw new HypawaveAPIError(408, {
200
+ error: "settlement_timeout",
201
+ message: `Settlement not confirmed within ${timeout}ms`
202
+ });
203
+ }
204
+ async payAndConfirm(params) {
205
+ const capability = params.wallet.capabilities?.returnsPreimage;
206
+ if (capability === false || capability === void 0) {
207
+ throw new HypawaveAPIError(400, {
208
+ error: "wallet_no_preimage_support",
209
+ message: "This wallet does not support returning the preimage. Hypawave requires the preimage for settlement confirmation. Use a supported adapter (NWC, LND, CLN, Alby, LNbits) from @hypawave/lightning-adapters."
210
+ });
211
+ }
212
+ if (capability === "conditional" && !params.allowConditionalPreimage) {
213
+ throw new HypawaveAPIError(400, {
214
+ error: "wallet_conditional_preimage",
215
+ message: "This wallet conditionally supports preimage return (depends on the backing node). Set allowConditionalPreimage: true to proceed at your own risk. If the preimage is not returned after payment, files will not unlock."
216
+ });
217
+ }
218
+ const { pr: bolt11, terms_hash } = await this.getBolt11(params.accessToken);
219
+ const payResult = await params.wallet.payInvoice(bolt11);
220
+ if (!payResult.preimage || !/^[0-9a-f]{64}$/i.test(payResult.preimage)) {
221
+ throw new HypawaveAPIError(400, {
222
+ error: "wallet_did_not_return_preimage",
223
+ message: "Wallet did not return a valid preimage. Hypawave requires a 64-char hex preimage for settlement confirmation."
224
+ });
225
+ }
226
+ const computedHash = await sha256hex(payResult.preimage);
227
+ if (payResult.payment_hash && computedHash.toLowerCase() !== payResult.payment_hash.toLowerCase()) {
228
+ throw new HypawaveAPIError(400, {
229
+ error: "preimage_hash_mismatch",
230
+ message: `Client-side verification failed: SHA256(preimage) does not match payment_hash. Expected ${payResult.payment_hash}, got ${computedHash}.`
231
+ });
232
+ }
233
+ const paymentHash = payResult.payment_hash || computedHash;
234
+ const confirmation = await this.confirmPayment(params.invoiceId, {
235
+ payment_hash: paymentHash,
236
+ preimage: payResult.preimage,
237
+ terms_hash
238
+ });
239
+ return {
240
+ payment_hash: paymentHash,
241
+ preimage: payResult.preimage,
242
+ terms_hash,
243
+ fees_paid_msat: payResult.fees_paid_msat,
244
+ confirmation
245
+ };
246
+ }
247
+ };
248
+ export {
249
+ Hypawave,
250
+ HypawaveAPIError
251
+ };
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@hypawave/sdk",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript SDK for Lightning settlement, preimage proof, and execution unlocks for AI agents.",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "keywords": [
25
+ "hypawave",
26
+ "lightning",
27
+ "lightning-sdk",
28
+ "lightning-api",
29
+ "lightning-network",
30
+ "bitcoin",
31
+ "bitcoin-payments",
32
+ "settlement",
33
+ "payments",
34
+ "paywall",
35
+ "non-custodial",
36
+ "agent",
37
+ "agent-payments",
38
+ "ai-agents",
39
+ "ai",
40
+ "llm",
41
+ "api",
42
+ "sdk",
43
+ "preimage",
44
+ "preimage-proof",
45
+ "wallet",
46
+ "nwc",
47
+ "bolt11",
48
+ "lnurl",
49
+ "x402",
50
+ "l402",
51
+ "micropayments"
52
+ ],
53
+ "author": "hypawave",
54
+ "license": "MIT",
55
+ "repository": {
56
+ "type": "git",
57
+ "url": "git+https://github.com/hypawave/sdk.git"
58
+ },
59
+ "homepage": "https://hypawave.com/docs",
60
+ "devDependencies": {
61
+ "tsup": "^8.0.0",
62
+ "typescript": "^5.0.0"
63
+ },
64
+ "engines": {
65
+ "node": ">=18"
66
+ }
67
+ }