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