@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 +10 -0
- package/LICENSE +21 -0
- package/README.md +337 -0
- package/dist/index.d.mts +512 -0
- package/dist/index.d.ts +512 -0
- package/dist/index.js +486 -0
- package/dist/index.mjs +454 -0
- package/examples/usage.ts +221 -0
- package/package.json +41 -0
- package/tsup.config.ts +9 -0
package/.eslintrc.cjs
ADDED
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` |
|