@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/.eslintrc.cjs ADDED
@@ -0,0 +1,10 @@
1
+ /** @type {import("eslint").Linter.Config} */
2
+ module.exports = {
3
+ root: true,
4
+ extends: ["@usesend/eslint-config/library.js"],
5
+ parser: "@typescript-eslint/parser",
6
+ parserOptions: {
7
+ project: "./tsconfig.json",
8
+ tsconfigRootDir: __dirname,
9
+ },
10
+ };
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 UseSend
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,337 @@
1
+ # @vaultkey/sdk
2
+
3
+ Official TypeScript / JavaScript SDK for the [VaultKey](https://vaultkey.com) API.
4
+
5
+ VaultKey lets you create and manage crypto wallets, sign messages and transactions, transfer stablecoins, and sweep funds — all through a simple API.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @vaultkey/sdk
11
+ # or
12
+ pnpm add @vaultkey/sdk
13
+ # or
14
+ yarn add @vaultkey/sdk
15
+ ```
16
+
17
+ ## Requirements
18
+
19
+ - Node.js 18+
20
+ - A VaultKey API key and secret from your [dashboard](https://app.vaultkeys.com)
21
+
22
+ ---
23
+
24
+ ## Quick Start
25
+
26
+ ```ts
27
+ import { VaultKey } from "@vaultkey/sdk";
28
+
29
+ const vk = new VaultKey({
30
+ apiKey: "vk_live_...",
31
+ apiSecret: "...",
32
+ });
33
+
34
+ // Create a wallet
35
+ const { data: wallet, error } = await vk.wallets.create({
36
+ userId: "user_123",
37
+ chainType: "evm",
38
+ });
39
+
40
+ if (error) {
41
+ console.error(error.message);
42
+ } else {
43
+ console.log(wallet.address); // "0x..."
44
+ }
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Configuration
50
+
51
+ ```ts
52
+ const vk = new VaultKey({
53
+ apiKey: "vk_live_...", // or set VAULTKEY_API_KEY env var
54
+ apiSecret: "...", // or set VAULTKEY_API_SECRET env var
55
+ baseUrl: "https://...", // optional — override for self-hosted deployments
56
+ });
57
+ ```
58
+
59
+ **API key prefixes:**
60
+ - `testnet_` — testnet environment
61
+ - `vk_live_` — mainnet / production
62
+
63
+ The SDK will warn you at construction time if your key prefix does not match the detected environment.
64
+
65
+ ---
66
+
67
+ ## Response Shape
68
+
69
+ Every method returns `{ data, error }`. Exactly one will be non-null.
70
+
71
+ ```ts
72
+ const { data, error } = await vk.wallets.get("wallet_id");
73
+
74
+ if (error) {
75
+ console.error(error.code, error.message);
76
+ return;
77
+ }
78
+
79
+ console.log(data.address);
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Wallets
85
+
86
+ ### Create a wallet
87
+
88
+ ```ts
89
+ const { data: wallet } = await vk.wallets.create({
90
+ userId: "user_123",
91
+ chainType: "evm", // "evm" | "solana"
92
+ label: "Primary", // optional
93
+ });
94
+ ```
95
+
96
+ ### Get a wallet
97
+
98
+ ```ts
99
+ const { data: wallet } = await vk.wallets.get("wallet_id");
100
+ ```
101
+
102
+ ### List wallets for a user
103
+
104
+ ```ts
105
+ const { data } = await vk.wallets.listByUser("user_123");
106
+
107
+ // Paginate
108
+ if (data.hasMore) {
109
+ const { data: page2 } = await vk.wallets.listByUser("user_123", {
110
+ after: data.nextCursor,
111
+ });
112
+ }
113
+ ```
114
+
115
+ ---
116
+
117
+ ## Signing
118
+
119
+ Signing operations are **asynchronous**. They return a `jobId` which you poll via `vk.jobs.get()`.
120
+
121
+ ### Sign an EVM message
122
+
123
+ ```ts
124
+ const { data: job } = await vk.wallets
125
+ .signing("wallet_id")
126
+ .evmMessage({
127
+ payload: { message: "Hello from VaultKey" },
128
+ idempotencyKey: "unique-key-123", // optional — safe to retry
129
+ });
130
+
131
+ // Poll until done
132
+ const result = await pollJob(vk, job.jobId);
133
+ ```
134
+
135
+ ### Sign a Solana message
136
+
137
+ ```ts
138
+ const { data: job } = await vk.wallets
139
+ .signing("wallet_id")
140
+ .solanaMessage({
141
+ payload: { data: "SGVsbG8=" },
142
+ });
143
+ ```
144
+
145
+ ---
146
+
147
+ ## Balances
148
+
149
+ ### EVM balance
150
+
151
+ ```ts
152
+ // Preferred: use chain name
153
+ const { data } = await vk.wallets.evmBalance("wallet_id", {
154
+ chainName: "base",
155
+ });
156
+
157
+ // Fallback: use chain ID
158
+ const { data } = await vk.wallets.evmBalance("wallet_id", {
159
+ chainId: "8453",
160
+ });
161
+
162
+ console.log(data.balance); // "0.05"
163
+ console.log(data.symbol); // "ETH"
164
+ console.log(data.chainName); // "base"
165
+ ```
166
+
167
+ ### Solana balance
168
+
169
+ ```ts
170
+ const { data } = await vk.wallets.solanaBalance("wallet_id");
171
+ console.log(data.balance); // "1.5"
172
+ console.log(data.symbol); // "SOL"
173
+ ```
174
+
175
+ ---
176
+
177
+ ## Broadcast
178
+
179
+ Send a pre-signed transaction to the network.
180
+
181
+ ### EVM
182
+
183
+ ```ts
184
+ const { data } = await vk.wallets.broadcastEVM("wallet_id", {
185
+ signedTx: "0x...",
186
+ chainName: "base",
187
+ });
188
+ console.log(data.txHash);
189
+ ```
190
+
191
+ ### Solana
192
+
193
+ ```ts
194
+ const { data } = await vk.wallets.broadcastSolana("wallet_id", {
195
+ signedTx: "base58encodedtx...",
196
+ });
197
+ console.log(data.signature);
198
+ ```
199
+
200
+ ---
201
+
202
+ ## Sweep
203
+
204
+ Move all funds from a wallet to the configured master wallet. Async — poll the returned job.
205
+
206
+ ```ts
207
+ // EVM sweep
208
+ const { data: job } = await vk.wallets.sweep("wallet_id", {
209
+ chainType: "evm",
210
+ chainName: "base",
211
+ });
212
+
213
+ // Solana sweep
214
+ const { data: job } = await vk.wallets.sweep("wallet_id", {
215
+ chainType: "solana",
216
+ });
217
+
218
+ const result = await pollJob(vk, job.jobId);
219
+ ```
220
+
221
+ ---
222
+
223
+ ## Stablecoin
224
+
225
+ Transfer USDC or USDT, and check stablecoin balances.
226
+
227
+ ### Transfer
228
+
229
+ ```ts
230
+ // EVM — gasless (relayer pays gas)
231
+ const { data } = await vk.stablecoin.transfer("wallet_id", {
232
+ token: "usdc",
233
+ to: "0xRecipient",
234
+ amount: "50.00",
235
+ chainType: "evm",
236
+ chainName: "base",
237
+ gasless: true,
238
+ speed: "fast", // "slow" | "normal" | "fast"
239
+ idempotencyKey: "tx-001", // optional — prevents double sends on retry
240
+ });
241
+
242
+ // Solana — omit chain fields
243
+ const { data } = await vk.stablecoin.transfer("wallet_id", {
244
+ token: "usdc",
245
+ to: "RecipientBase58...",
246
+ amount: "50.00",
247
+ chainType: "solana",
248
+ });
249
+
250
+ // Poll the async job
251
+ const result = await pollJob(vk, data.jobId);
252
+ ```
253
+
254
+ ### Balance
255
+
256
+ ```ts
257
+ const { data } = await vk.stablecoin.balance("wallet_id", {
258
+ token: "usdc",
259
+ chainType: "evm",
260
+ chainName: "polygon",
261
+ });
262
+ console.log(data.balance); // "50.00"
263
+ ```
264
+
265
+ ---
266
+
267
+ ## Jobs
268
+
269
+ Poll the status of any async operation.
270
+
271
+ ```ts
272
+ const { data } = await vk.jobs.get("job_id");
273
+ // data.status: "pending" | "processing" | "completed" | "failed"
274
+ ```
275
+
276
+ ### Polling helper
277
+
278
+ ```ts
279
+ async function pollJob(vk: VaultKey, jobId: string, intervalMs = 1000) {
280
+ while (true) {
281
+ const { data, error } = await vk.jobs.get(jobId);
282
+ if (error) throw new Error(error.message);
283
+ if (data.status === "completed") return data;
284
+ if (data.status === "failed") throw new Error(data.error ?? "Job failed");
285
+ await new Promise((r) => setTimeout(r, intervalMs));
286
+ }
287
+ }
288
+ ```
289
+
290
+ ---
291
+
292
+ ## Chains
293
+
294
+ Discover supported chains for the current environment.
295
+
296
+ ```ts
297
+ const { data: chains } = await vk.chains.list();
298
+ // [{ name: "base", chainId: "8453", nativeSymbol: "ETH", testnet: false }, ...]
299
+ ```
300
+
301
+ **Supported EVM chains:**
302
+
303
+ | Mainnet | Testnet |
304
+ |---|---|
305
+ | ethereum | sepolia |
306
+ | polygon | amoy |
307
+ | arbitrum | arbitrum-sepolia |
308
+ | base | base-sepolia |
309
+ | optimism | optimism-sepolia |
310
+ | avalanche | avalanche-fuji |
311
+ | bsc | bsc-testnet |
312
+ | linea | — |
313
+ | scroll | — |
314
+ | zksync | zksync-sepolia |
315
+
316
+ ---
317
+
318
+ ## Environment Variables
319
+
320
+ | Variable | Description |
321
+ |---|---|
322
+ | `VAULTKEY_API_KEY` | Your API key (fallback if not passed to constructor) |
323
+ | `VAULTKEY_API_SECRET` | Your API secret (fallback if not passed to constructor) |
324
+ | `VAULTKEY_BASE_URL` | Override base URL (optional) |
325
+ | `ENVIRONMENT` | `"testnet"` or `"mainnet"` — used for key prefix validation warnings |
326
+
327
+ ---
328
+
329
+ ## Available Resources
330
+
331
+ | Resource | Methods |
332
+ |---|---|
333
+ | `vk.wallets` | `create`, `get`, `listByUser`, `evmBalance`, `solanaBalance`, `broadcastEVM`, `broadcastSolana`, `sweep` |
334
+ | `vk.wallets.signing(id)` | `evmMessage`, `solanaMessage` |
335
+ | `vk.stablecoin` | `transfer`, `balance` |
336
+ | `vk.jobs` | `get` |
337
+ | `vk.chains` | `list` |