@vaultkey/sdk 1.0.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,486 @@
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
+ // index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Chains: () => Chains,
24
+ Jobs: () => Jobs,
25
+ Signing: () => Signing,
26
+ Stablecoin: () => Stablecoin,
27
+ VaultKey: () => VaultKey,
28
+ Wallets: () => Wallets
29
+ });
30
+ module.exports = __toCommonJS(index_exports);
31
+
32
+ // src/signing.ts
33
+ var Signing = class {
34
+ constructor(client, walletId) {
35
+ this.client = client;
36
+ this.walletId = walletId;
37
+ }
38
+ /**
39
+ * Sign an EVM message or typed data (EIP-712).
40
+ *
41
+ * @example
42
+ * const { data } = await vaultkey.wallets.signing("wallet_id").evmMessage({
43
+ * payload: { message: "Hello from VaultKey" },
44
+ * });
45
+ * // Poll: await vaultkey.jobs.get(data.jobId)
46
+ */
47
+ async evmMessage(params) {
48
+ const { idempotencyKey, ...rest } = params;
49
+ return this.client.post(
50
+ `/wallets/${this.walletId}/sign/message/evm`,
51
+ {
52
+ payload: rest.payload,
53
+ idempotency_key: idempotencyKey
54
+ }
55
+ );
56
+ }
57
+ /**
58
+ * Sign a Solana message.
59
+ *
60
+ * @example
61
+ * const { data } = await vaultkey.wallets.signing("wallet_id").solanaMessage({
62
+ * payload: { message: "Hello from VaultKey" },
63
+ * });
64
+ */
65
+ async solanaMessage(params) {
66
+ const { idempotencyKey, ...rest } = params;
67
+ return this.client.post(
68
+ `/wallets/${this.walletId}/sign/message/solana`,
69
+ {
70
+ payload: rest.payload,
71
+ idempotency_key: idempotencyKey
72
+ }
73
+ );
74
+ }
75
+ };
76
+
77
+ // src/wallets.ts
78
+ var Wallets = class {
79
+ constructor(client) {
80
+ this.client = client;
81
+ }
82
+ /**
83
+ * Create a new wallet for a user.
84
+ *
85
+ * @example
86
+ * const { data, error } = await vaultkey.wallets.create({
87
+ * userId: "user_123",
88
+ * chainType: "evm",
89
+ * label: "Primary wallet",
90
+ * });
91
+ */
92
+ async create(params) {
93
+ const body = {
94
+ user_id: params.userId,
95
+ chain_type: params.chainType
96
+ };
97
+ if (params.label) body.label = params.label;
98
+ return this.client.post("/wallets", body);
99
+ }
100
+ /**
101
+ * Retrieve a wallet by its ID.
102
+ *
103
+ * @example
104
+ * const { data } = await vaultkey.wallets.get("wallet_abc123");
105
+ */
106
+ async get(walletId) {
107
+ return this.client.get(`/wallets/${walletId}`);
108
+ }
109
+ /**
110
+ * List all wallets belonging to a user.
111
+ * Results are paginated — use `nextCursor` to fetch the next page.
112
+ *
113
+ * @example
114
+ * const { data } = await vaultkey.wallets.listByUser("user_123");
115
+ * // Next page:
116
+ * const { data: page2 } = await vaultkey.wallets.listByUser("user_123", {
117
+ * after: data.nextCursor,
118
+ * });
119
+ */
120
+ async listByUser(userId, pagination) {
121
+ const params = new URLSearchParams();
122
+ if (pagination?.after) params.set("after", pagination.after);
123
+ if (pagination?.limit) params.set("limit", String(pagination.limit));
124
+ const qs = params.toString();
125
+ return this.client.get(
126
+ `/users/${userId}/wallets${qs ? `?${qs}` : ""}`
127
+ );
128
+ }
129
+ /**
130
+ * Returns a signing interface scoped to the given wallet.
131
+ * Use this to sign EVM or Solana messages.
132
+ *
133
+ * @example
134
+ * const { data } = await vaultkey.wallets
135
+ * .signing("wallet_id")
136
+ * .evmMessage({ payload: { message: "Hello" } });
137
+ */
138
+ signing(walletId) {
139
+ return new Signing(this.client, walletId);
140
+ }
141
+ /**
142
+ * Get the native token balance for an EVM wallet.
143
+ * Provide chainName (preferred) or chainId.
144
+ *
145
+ * @example
146
+ * const { data } = await vaultkey.wallets.evmBalance("wallet_id", {
147
+ * chainName: "base",
148
+ * });
149
+ * console.log(data.balance); // "0.05"
150
+ */
151
+ async evmBalance(walletId, chain) {
152
+ const params = new URLSearchParams();
153
+ if ("chainName" in chain && chain.chainName) {
154
+ params.set("chain_name", chain.chainName);
155
+ } else if ("chainId" in chain && chain.chainId) {
156
+ params.set("chain_id", chain.chainId);
157
+ }
158
+ return this.client.get(
159
+ `/wallets/${walletId}/balance/evm?${params.toString()}`
160
+ );
161
+ }
162
+ /**
163
+ * Get the SOL balance for a Solana wallet.
164
+ *
165
+ * @example
166
+ * const { data } = await vaultkey.wallets.solanaBalance("wallet_id");
167
+ * console.log(data.balance); // "1.5"
168
+ */
169
+ async solanaBalance(walletId) {
170
+ return this.client.get(
171
+ `/wallets/${walletId}/balance/solana`
172
+ );
173
+ }
174
+ /**
175
+ * Broadcast a pre-signed EVM transaction.
176
+ * Provide chainName (preferred) or chainId.
177
+ *
178
+ * @example
179
+ * const { data } = await vaultkey.wallets.broadcastEVM("wallet_id", {
180
+ * signedTx: "0x...",
181
+ * chainName: "base",
182
+ * });
183
+ * console.log(data.txHash);
184
+ */
185
+ async broadcastEVM(walletId, params) {
186
+ const body = { signed_tx: params.signedTx };
187
+ if ("chainName" in params && params.chainName) {
188
+ body.chain_name = params.chainName;
189
+ } else if ("chainId" in params && params.chainId) {
190
+ body.chain_id = params.chainId;
191
+ }
192
+ return this.client.post(
193
+ `/wallets/${walletId}/broadcast`,
194
+ body
195
+ );
196
+ }
197
+ /**
198
+ * Broadcast a pre-signed Solana transaction.
199
+ *
200
+ * @example
201
+ * const { data } = await vaultkey.wallets.broadcastSolana("wallet_id", {
202
+ * signedTx: "base58encodedtx...",
203
+ * });
204
+ * console.log(data.signature);
205
+ */
206
+ async broadcastSolana(walletId, params) {
207
+ return this.client.post(
208
+ `/wallets/${walletId}/broadcast`,
209
+ { signed_tx: params.signedTx }
210
+ );
211
+ }
212
+ /**
213
+ * Trigger a sweep — move all funds from this wallet to the configured
214
+ * master wallet. The operation is asynchronous; poll via `vaultkey.jobs.get`.
215
+ *
216
+ * @example
217
+ * // EVM sweep
218
+ * const { data } = await vaultkey.wallets.sweep("wallet_id", {
219
+ * chainType: "evm",
220
+ * chainName: "base",
221
+ * });
222
+ *
223
+ * // Solana sweep
224
+ * const { data } = await vaultkey.wallets.sweep("wallet_id", {
225
+ * chainType: "solana",
226
+ * });
227
+ */
228
+ async sweep(walletId, params) {
229
+ const body = {
230
+ chain_type: params.chainType
231
+ };
232
+ if (params.chainType === "evm") {
233
+ if (params.chainName) {
234
+ body.chain_name = params.chainName;
235
+ } else if (params.chainId) {
236
+ body.chain_id = params.chainId;
237
+ }
238
+ }
239
+ return this.client.post(`/wallets/${walletId}/sweep`, body);
240
+ }
241
+ };
242
+
243
+ // src/jobs.ts
244
+ var Jobs = class {
245
+ constructor(client) {
246
+ this.client = client;
247
+ }
248
+ /**
249
+ * Retrieve the current state of an async job.
250
+ *
251
+ * @example
252
+ * const { data, error } = await vaultkey.jobs.get("job_abc123");
253
+ * if (data?.status === "completed") {
254
+ * console.log("Done!", data.result);
255
+ * }
256
+ */
257
+ async get(jobId) {
258
+ return this.client.get(`/jobs/${jobId}`);
259
+ }
260
+ };
261
+
262
+ // src/stablecoin.ts
263
+ var Stablecoin = class {
264
+ constructor(client) {
265
+ this.client = client;
266
+ }
267
+ /**
268
+ * Transfer a stablecoin from a wallet.
269
+ *
270
+ * - For EVM: provide chainName (preferred) or chainId.
271
+ * - For Solana: omit chainName and chainId.
272
+ * - The operation is async — poll `vaultkey.jobs.get(data.jobId)`.
273
+ * - Use `idempotencyKey` to safely retry without double-sending.
274
+ *
275
+ * @example
276
+ * // EVM (gasless)
277
+ * const { data } = await vaultkey.stablecoin.transfer("wallet_id", {
278
+ * token: "usdc",
279
+ * to: "0xRecipient",
280
+ * amount: "100.00",
281
+ * chainType: "evm",
282
+ * chainName: "base",
283
+ * gasless: true,
284
+ * speed: "fast",
285
+ * });
286
+ *
287
+ * // Solana
288
+ * const { data } = await vaultkey.stablecoin.transfer("wallet_id", {
289
+ * token: "usdc",
290
+ * to: "RecipientBase58",
291
+ * amount: "100.00",
292
+ * chainType: "solana",
293
+ * });
294
+ */
295
+ async transfer(walletId, params) {
296
+ const body = {
297
+ token: params.token,
298
+ to: params.to,
299
+ amount: params.amount
300
+ };
301
+ if (params.chainType === "evm") {
302
+ if (params.chainName) {
303
+ body.chain_name = params.chainName;
304
+ } else if (params.chainId) {
305
+ body.chain_id = params.chainId;
306
+ }
307
+ }
308
+ if (params.gasless !== void 0) body.gasless = params.gasless;
309
+ if (params.speed) body.speed = params.speed;
310
+ if (params.idempotencyKey) body.idempotency_key = params.idempotencyKey;
311
+ return this.client.post(
312
+ `/wallets/${walletId}/stablecoin/transfer/${params.chainType}`,
313
+ body
314
+ );
315
+ }
316
+ /**
317
+ * Get the stablecoin balance for a wallet.
318
+ *
319
+ * - For EVM: provide chainName (preferred) or chainId.
320
+ * - For Solana: omit chainName and chainId.
321
+ *
322
+ * @example
323
+ * const { data } = await vaultkey.stablecoin.balance("wallet_id", {
324
+ * token: "usdc",
325
+ * chainType: "evm",
326
+ * chainName: "polygon",
327
+ * });
328
+ * console.log(data.balance); // "50.00"
329
+ */
330
+ async balance(walletId, params) {
331
+ const query = { token: params.token };
332
+ if (params.chainType === "evm") {
333
+ if (params.chainName) {
334
+ query.chain_name = params.chainName;
335
+ } else if (params.chainId) {
336
+ query.chain_id = params.chainId;
337
+ }
338
+ }
339
+ const qs = new URLSearchParams(
340
+ Object.entries(query).filter(([, v]) => v !== void 0)
341
+ ).toString();
342
+ return this.client.get(
343
+ `/wallets/${walletId}/stablecoin/balance/${params.chainType}?${qs}`
344
+ );
345
+ }
346
+ };
347
+
348
+ // src/chains.ts
349
+ var Chains = class {
350
+ constructor(client) {
351
+ this.client = client;
352
+ }
353
+ /**
354
+ * List all supported EVM chains for the current environment
355
+ * (testnet or mainnet, determined by your API key).
356
+ *
357
+ * @example
358
+ * const { data, error } = await vaultkey.chains.list();
359
+ */
360
+ async list() {
361
+ return this.client.get("/chains");
362
+ }
363
+ };
364
+
365
+ // src/vaultkey.ts
366
+ var MAINNET_BASE_URL = "https://app.vaultkeys.com";
367
+ var TESTNET_BASE_URL = "https://testnet.vaultkeys.com";
368
+ function resolveBaseUrl(apiKey, override) {
369
+ if (override) return override;
370
+ return apiKey.startsWith("testnet_") ? TESTNET_BASE_URL : MAINNET_BASE_URL;
371
+ }
372
+ function isVaultKeyErrorResponse(resp) {
373
+ return typeof resp === "object" && resp !== null && "error" in resp && typeof resp.error === "object";
374
+ }
375
+ var VaultKey = class {
376
+ apiKey;
377
+ apiSecret;
378
+ baseUrl;
379
+ /** Wallet management — create, retrieve, and list wallets. */
380
+ wallets;
381
+ /** Async job polling — check the status of signing and sweep operations. */
382
+ jobs;
383
+ /** Stablecoin transfers and balance lookups (USDC, USDT). */
384
+ stablecoin;
385
+ /** Chain discovery — list supported EVM chains for the current environment. */
386
+ chains;
387
+ constructor(config = {}) {
388
+ const apiKey = config.apiKey ?? (typeof process !== "undefined" ? process.env?.VAULTKEY_API_KEY : void 0);
389
+ const apiSecret = config.apiSecret ?? (typeof process !== "undefined" ? process.env?.VAULTKEY_API_SECRET : void 0);
390
+ if (!apiKey) {
391
+ throw new Error(
392
+ 'Missing API key. Pass it via config: new VaultKey({ apiKey: "vk_live_..." }) or set the VAULTKEY_API_KEY environment variable.'
393
+ );
394
+ }
395
+ if (!apiSecret) {
396
+ throw new Error(
397
+ 'Missing API secret. Pass it via config: new VaultKey({ apiSecret: "..." }) or set the VAULTKEY_API_SECRET environment variable.'
398
+ );
399
+ }
400
+ this.apiKey = apiKey;
401
+ this.apiSecret = apiSecret;
402
+ this.baseUrl = `${resolveBaseUrl(apiKey, config.baseUrl)}/api/v1/sdk`;
403
+ this.wallets = new Wallets(this);
404
+ this.jobs = new Jobs(this);
405
+ this.stablecoin = new Stablecoin(this);
406
+ this.chains = new Chains(this);
407
+ }
408
+ async fetchRequest(path, options = {}) {
409
+ const headers = new Headers({
410
+ "Content-Type": "application/json",
411
+ "X-API-Key": this.apiKey,
412
+ "X-API-Secret": this.apiSecret,
413
+ ...Object.fromEntries(new Headers(options.headers ?? {}))
414
+ });
415
+ const response = await fetch(`${this.baseUrl}${path}`, {
416
+ ...options,
417
+ headers
418
+ });
419
+ const defaultError = {
420
+ code: "INTERNAL_SERVER_ERROR",
421
+ message: response.statusText
422
+ };
423
+ if (!response.ok) {
424
+ try {
425
+ const body = await response.json();
426
+ if (isVaultKeyErrorResponse(body)) {
427
+ return { data: null, error: body.error };
428
+ }
429
+ if (typeof body?.error === "string") {
430
+ return {
431
+ data: null,
432
+ error: { code: String(response.status), message: body.error }
433
+ };
434
+ }
435
+ return { data: null, error: defaultError };
436
+ } catch {
437
+ return { data: null, error: defaultError };
438
+ }
439
+ }
440
+ const data = await response.json();
441
+ return { data, error: null };
442
+ }
443
+ async get(path, options) {
444
+ return this.fetchRequest(path, {
445
+ method: "GET",
446
+ headers: options?.headers
447
+ });
448
+ }
449
+ async post(path, body, options) {
450
+ return this.fetchRequest(path, {
451
+ method: "POST",
452
+ body: JSON.stringify(body),
453
+ headers: options?.headers
454
+ });
455
+ }
456
+ async put(path, body, options) {
457
+ return this.fetchRequest(path, {
458
+ method: "PUT",
459
+ body: JSON.stringify(body),
460
+ headers: options?.headers
461
+ });
462
+ }
463
+ async patch(path, body, options) {
464
+ return this.fetchRequest(path, {
465
+ method: "PATCH",
466
+ body: JSON.stringify(body),
467
+ headers: options?.headers
468
+ });
469
+ }
470
+ async delete(path, body, options) {
471
+ return this.fetchRequest(path, {
472
+ method: "DELETE",
473
+ body: body !== void 0 ? JSON.stringify(body) : void 0,
474
+ headers: options?.headers
475
+ });
476
+ }
477
+ };
478
+ // Annotate the CommonJS export names for ESM import in node:
479
+ 0 && (module.exports = {
480
+ Chains,
481
+ Jobs,
482
+ Signing,
483
+ Stablecoin,
484
+ VaultKey,
485
+ Wallets
486
+ });