@clawdvault/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.mjs ADDED
@@ -0,0 +1,596 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/wallet.ts
9
+ import {
10
+ Keypair,
11
+ PublicKey,
12
+ Transaction,
13
+ VersionedTransaction
14
+ } from "@solana/web3.js";
15
+ import bs58 from "bs58";
16
+ var KeypairSigner = class _KeypairSigner {
17
+ constructor(keypairOrSecretKey) {
18
+ if (keypairOrSecretKey instanceof Keypair) {
19
+ this._keypair = keypairOrSecretKey;
20
+ } else if (typeof keypairOrSecretKey === "string") {
21
+ if (keypairOrSecretKey.startsWith("[")) {
22
+ const secretKey = new Uint8Array(JSON.parse(keypairOrSecretKey));
23
+ this._keypair = Keypair.fromSecretKey(secretKey);
24
+ } else {
25
+ const secretKey = bs58.decode(keypairOrSecretKey);
26
+ this._keypair = Keypair.fromSecretKey(secretKey);
27
+ }
28
+ } else {
29
+ this._keypair = Keypair.fromSecretKey(keypairOrSecretKey);
30
+ }
31
+ }
32
+ get publicKey() {
33
+ return this._keypair.publicKey;
34
+ }
35
+ /**
36
+ * Get the underlying Keypair (use with caution)
37
+ */
38
+ get keypair() {
39
+ return this._keypair;
40
+ }
41
+ async signTransaction(tx) {
42
+ if (tx instanceof Transaction) {
43
+ tx.sign(this._keypair);
44
+ } else {
45
+ tx.sign([this._keypair]);
46
+ }
47
+ return tx;
48
+ }
49
+ async signMessage(message) {
50
+ const nacl = __require("tweetnacl");
51
+ const signature = nacl.sign.detached(message, this._keypair.secretKey);
52
+ return signature;
53
+ }
54
+ /**
55
+ * Load keypair from file path (e.g., Solana CLI wallet)
56
+ */
57
+ static fromFile(path) {
58
+ const fs = __require("fs");
59
+ const data = fs.readFileSync(path, "utf-8");
60
+ const secretKey = new Uint8Array(JSON.parse(data));
61
+ return new _KeypairSigner(secretKey);
62
+ }
63
+ /**
64
+ * Load from environment variable
65
+ */
66
+ static fromEnv(envVar = "SOLANA_PRIVATE_KEY") {
67
+ const key = process.env[envVar];
68
+ if (!key) {
69
+ throw new Error(`Environment variable ${envVar} not set`);
70
+ }
71
+ return new _KeypairSigner(key);
72
+ }
73
+ };
74
+ var PhantomSigner = class _PhantomSigner {
75
+ constructor(phantom) {
76
+ this.phantom = phantom;
77
+ }
78
+ get publicKey() {
79
+ return this.phantom.publicKey;
80
+ }
81
+ async signTransaction(tx) {
82
+ return this.phantom.signTransaction(tx);
83
+ }
84
+ async signMessage(message) {
85
+ const { signature } = await this.phantom.signMessage(message);
86
+ return signature;
87
+ }
88
+ /**
89
+ * Get Phantom from window object (browser only)
90
+ */
91
+ static async fromWindow() {
92
+ if (typeof window === "undefined") {
93
+ throw new Error("PhantomSigner.fromWindow() only works in browser");
94
+ }
95
+ const phantom = window.phantom?.solana;
96
+ if (!phantom) {
97
+ throw new Error("Phantom wallet not found. Please install Phantom extension.");
98
+ }
99
+ if (!phantom.isConnected) {
100
+ await phantom.connect();
101
+ }
102
+ return new _PhantomSigner(phantom);
103
+ }
104
+ };
105
+ async function signAndSerialize(transaction, signer) {
106
+ const txBuffer = Buffer.from(transaction, "base64");
107
+ try {
108
+ const versionedTx = VersionedTransaction.deserialize(txBuffer);
109
+ const signedTx = await signer.signTransaction(versionedTx);
110
+ return Buffer.from(signedTx.serialize()).toString("base64");
111
+ } catch {
112
+ const legacyTx = Transaction.from(txBuffer);
113
+ const signedTx = await signer.signTransaction(legacyTx);
114
+ return Buffer.from(signedTx.serialize()).toString("base64");
115
+ }
116
+ }
117
+ async function createAuthSignature(signer, payload) {
118
+ const message = JSON.stringify(payload);
119
+ const messageBytes = new TextEncoder().encode(message);
120
+ const signatureBytes = await signer.signMessage(messageBytes);
121
+ return {
122
+ signature: bs58.encode(signatureBytes),
123
+ wallet: signer.publicKey.toBase58()
124
+ };
125
+ }
126
+ function verifySignature(message, signature, publicKey) {
127
+ try {
128
+ const messageBytes = new TextEncoder().encode(message);
129
+ const signatureBytes = bs58.decode(signature);
130
+ const pubkey = new PublicKey(publicKey);
131
+ const nacl = __require("tweetnacl");
132
+ return nacl.sign.detached.verify(messageBytes, signatureBytes, pubkey.toBytes());
133
+ } catch {
134
+ return false;
135
+ }
136
+ }
137
+
138
+ // src/client.ts
139
+ var ClawdVaultClient = class {
140
+ constructor(config = {}) {
141
+ this.baseUrl = config.baseUrl?.replace(/\/$/, "") || "https://clawdvault.com/api";
142
+ this.signer = config.signer;
143
+ this.sessionToken = config.sessionToken;
144
+ this.onError = config.onError;
145
+ }
146
+ /**
147
+ * Set the wallet signer for authenticated operations
148
+ */
149
+ setSigner(signer) {
150
+ this.signer = signer;
151
+ }
152
+ /**
153
+ * Set session token for authenticated operations
154
+ */
155
+ setSessionToken(token) {
156
+ this.sessionToken = token;
157
+ }
158
+ /**
159
+ * Get wallet address
160
+ */
161
+ getWalletAddress() {
162
+ return this.signer?.publicKey.toBase58() ?? null;
163
+ }
164
+ async request(method, path, options = {}) {
165
+ const { params, body, auth, formData } = options;
166
+ let url = `${this.baseUrl}${path}`;
167
+ if (params) {
168
+ const searchParams = new URLSearchParams();
169
+ for (const [key, value] of Object.entries(params)) {
170
+ if (value !== void 0 && value !== null) {
171
+ searchParams.set(key, String(value));
172
+ }
173
+ }
174
+ const qs = searchParams.toString();
175
+ if (qs) url += `?${qs}`;
176
+ }
177
+ const headers = {};
178
+ if (auth) {
179
+ if (this.sessionToken) {
180
+ headers["Authorization"] = `Bearer ${this.sessionToken}`;
181
+ } else if (this.signer && body) {
182
+ const { signature, wallet } = await createAuthSignature(this.signer, body);
183
+ headers["X-Wallet"] = wallet;
184
+ headers["X-Signature"] = signature;
185
+ }
186
+ }
187
+ let requestBody;
188
+ if (formData) {
189
+ requestBody = formData;
190
+ } else if (body) {
191
+ headers["Content-Type"] = "application/json";
192
+ requestBody = JSON.stringify(body);
193
+ }
194
+ const response = await fetch(url, {
195
+ method,
196
+ headers,
197
+ body: requestBody
198
+ });
199
+ if (!response.ok) {
200
+ const error = await response.json().catch(() => ({ error: response.statusText }));
201
+ const err = new Error(error.error || error.message || `HTTP ${response.status}`);
202
+ err.status = response.status;
203
+ err.response = error;
204
+ this.onError?.(err);
205
+ throw err;
206
+ }
207
+ return response.json();
208
+ }
209
+ // ============ Token Operations ============
210
+ /**
211
+ * List tokens with optional filters
212
+ */
213
+ async listTokens(params = {}) {
214
+ return this.request("GET", "/tokens", { params });
215
+ }
216
+ /**
217
+ * Get token details
218
+ */
219
+ async getToken(mint) {
220
+ return this.request("GET", `/tokens/${mint}`);
221
+ }
222
+ /**
223
+ * Get token metadata (Metaplex format)
224
+ */
225
+ async getMetadata(mint) {
226
+ return this.request("GET", `/metadata/${mint}`);
227
+ }
228
+ /**
229
+ * Prepare token creation (step 1)
230
+ */
231
+ async prepareCreate(params) {
232
+ return this.request("POST", "/token/prepare-create", { body: params });
233
+ }
234
+ /**
235
+ * Execute token creation (step 2)
236
+ */
237
+ async executeCreate(params) {
238
+ return this.request("POST", "/token/execute-create", { body: params });
239
+ }
240
+ /**
241
+ * Create token with automatic signing
242
+ * Combines prepare + sign + execute in one call
243
+ */
244
+ async createToken(params) {
245
+ if (!this.signer) {
246
+ throw new Error("Signer required for createToken");
247
+ }
248
+ const wallet = this.signer.publicKey.toBase58();
249
+ const prepared = await this.prepareCreate({
250
+ creator: wallet,
251
+ name: params.name,
252
+ symbol: params.symbol,
253
+ initialBuy: params.initialBuy
254
+ });
255
+ const signedTx = await signAndSerialize(prepared.transaction, this.signer);
256
+ return this.executeCreate({
257
+ signedTransaction: signedTx,
258
+ mint: prepared.mint,
259
+ creator: wallet,
260
+ name: params.name,
261
+ symbol: params.symbol,
262
+ description: params.description,
263
+ image: params.image,
264
+ twitter: params.twitter,
265
+ telegram: params.telegram,
266
+ website: params.website
267
+ });
268
+ }
269
+ // ============ Trading Operations ============
270
+ /**
271
+ * Get price quote
272
+ */
273
+ async getQuote(params) {
274
+ return this.request("GET", "/trade", { params });
275
+ }
276
+ /**
277
+ * Prepare trade transaction (step 1)
278
+ */
279
+ async prepareTrade(params) {
280
+ return this.request("POST", "/trade/prepare", { body: params });
281
+ }
282
+ /**
283
+ * Execute trade (step 2)
284
+ */
285
+ async executeTrade(params) {
286
+ return this.request("POST", "/trade/execute", { body: params });
287
+ }
288
+ /**
289
+ * Buy tokens with automatic signing
290
+ */
291
+ async buy(mint, solAmount, slippage = 0.01) {
292
+ if (!this.signer) {
293
+ throw new Error("Signer required for buy");
294
+ }
295
+ const wallet = this.signer.publicKey.toBase58();
296
+ const prepared = await this.prepareTrade({
297
+ mint,
298
+ type: "buy",
299
+ amount: solAmount,
300
+ wallet,
301
+ slippage
302
+ });
303
+ const signedTx = await signAndSerialize(prepared.transaction, this.signer);
304
+ return this.executeTrade({
305
+ signedTransaction: signedTx,
306
+ mint,
307
+ type: "buy",
308
+ wallet
309
+ });
310
+ }
311
+ /**
312
+ * Sell tokens with automatic signing
313
+ */
314
+ async sell(mint, tokenAmount, slippage = 0.01) {
315
+ if (!this.signer) {
316
+ throw new Error("Signer required for sell");
317
+ }
318
+ const wallet = this.signer.publicKey.toBase58();
319
+ const prepared = await this.prepareTrade({
320
+ mint,
321
+ type: "sell",
322
+ amount: tokenAmount,
323
+ wallet,
324
+ slippage
325
+ });
326
+ const signedTx = await signAndSerialize(prepared.transaction, this.signer);
327
+ return this.executeTrade({
328
+ signedTransaction: signedTx,
329
+ mint,
330
+ type: "sell",
331
+ wallet
332
+ });
333
+ }
334
+ /**
335
+ * Sell percentage of token holdings
336
+ */
337
+ async sellPercent(mint, percent, slippage = 0.01) {
338
+ if (!this.signer) {
339
+ throw new Error("Signer required for sellPercent");
340
+ }
341
+ const wallet = this.signer.publicKey.toBase58();
342
+ const { balance } = await this.getBalance(wallet, mint);
343
+ if (balance <= 0) {
344
+ throw new Error("No tokens to sell");
345
+ }
346
+ const tokenAmount = balance * (percent / 100);
347
+ return this.sell(mint, tokenAmount, slippage);
348
+ }
349
+ // ============ Price Data ============
350
+ /**
351
+ * Get trade history
352
+ */
353
+ async getTrades(params) {
354
+ return this.request("GET", "/trades", { params });
355
+ }
356
+ /**
357
+ * Get OHLCV candles
358
+ */
359
+ async getCandles(params) {
360
+ return this.request("GET", "/candles", { params });
361
+ }
362
+ /**
363
+ * Get on-chain stats
364
+ */
365
+ async getStats(mint) {
366
+ return this.request("GET", "/stats", { params: { mint } });
367
+ }
368
+ /**
369
+ * Get top holders
370
+ */
371
+ async getHolders(mint, creator) {
372
+ return this.request("GET", "/holders", { params: { mint, creator } });
373
+ }
374
+ /**
375
+ * Get wallet token balance
376
+ */
377
+ async getBalance(wallet, mint) {
378
+ return this.request("GET", "/balance", { params: { wallet, mint } });
379
+ }
380
+ /**
381
+ * Get my balance for a token
382
+ */
383
+ async getMyBalance(mint) {
384
+ if (!this.signer) {
385
+ throw new Error("Signer required for getMyBalance");
386
+ }
387
+ return this.getBalance(this.signer.publicKey.toBase58(), mint);
388
+ }
389
+ /**
390
+ * Get SOL/USD price
391
+ */
392
+ async getSolPrice() {
393
+ return this.request("GET", "/sol-price");
394
+ }
395
+ // ============ Graduation / Jupiter ============
396
+ /**
397
+ * Check graduation status
398
+ */
399
+ async getGraduationStatus(mint) {
400
+ return this.request("GET", "/graduate", { params: { mint } });
401
+ }
402
+ /**
403
+ * Check Jupiter availability
404
+ */
405
+ async getJupiterStatus(mint) {
406
+ return this.request("GET", "/trade/jupiter", { params: { mint } });
407
+ }
408
+ /**
409
+ * Get Jupiter swap quote
410
+ */
411
+ async getJupiterQuote(params) {
412
+ return this.request("POST", "/trade/jupiter", { body: params });
413
+ }
414
+ /**
415
+ * Execute Jupiter swap
416
+ */
417
+ async executeJupiterSwap(params) {
418
+ return this.request("POST", "/trade/jupiter/execute", { body: params });
419
+ }
420
+ /**
421
+ * Buy graduated token via Jupiter
422
+ */
423
+ async buyJupiter(mint, solAmount, slippageBps = 50) {
424
+ if (!this.signer) {
425
+ throw new Error("Signer required for buyJupiter");
426
+ }
427
+ const wallet = this.signer.publicKey.toBase58();
428
+ const lamports = Math.floor(solAmount * 1e9);
429
+ const quote = await this.getJupiterQuote({
430
+ mint,
431
+ action: "buy",
432
+ amount: lamports.toString(),
433
+ userPublicKey: wallet,
434
+ slippageBps
435
+ });
436
+ const signedTx = await signAndSerialize(quote.transaction, this.signer);
437
+ return this.executeJupiterSwap({
438
+ mint,
439
+ signedTransaction: signedTx,
440
+ type: "buy",
441
+ wallet
442
+ });
443
+ }
444
+ /**
445
+ * Sell graduated token via Jupiter
446
+ */
447
+ async sellJupiter(mint, tokenAmount, slippageBps = 50) {
448
+ if (!this.signer) {
449
+ throw new Error("Signer required for sellJupiter");
450
+ }
451
+ const wallet = this.signer.publicKey.toBase58();
452
+ const quote = await this.getJupiterQuote({
453
+ mint,
454
+ action: "sell",
455
+ amount: Math.floor(tokenAmount * 1e6).toString(),
456
+ // Assuming 6 decimals
457
+ userPublicKey: wallet,
458
+ slippageBps
459
+ });
460
+ const signedTx = await signAndSerialize(quote.transaction, this.signer);
461
+ return this.executeJupiterSwap({
462
+ mint,
463
+ signedTransaction: signedTx,
464
+ type: "sell",
465
+ wallet
466
+ });
467
+ }
468
+ /**
469
+ * Smart buy - automatically routes to bonding curve or Jupiter
470
+ */
471
+ async smartBuy(mint, solAmount, slippage = 0.01) {
472
+ const status = await this.getJupiterStatus(mint);
473
+ if (status.graduated) {
474
+ return this.buyJupiter(mint, solAmount, Math.floor(slippage * 1e4));
475
+ }
476
+ return this.buy(mint, solAmount, slippage);
477
+ }
478
+ /**
479
+ * Smart sell - automatically routes to bonding curve or Jupiter
480
+ */
481
+ async smartSell(mint, tokenAmount, slippage = 0.01) {
482
+ const status = await this.getJupiterStatus(mint);
483
+ if (status.graduated) {
484
+ return this.sellJupiter(mint, tokenAmount, Math.floor(slippage * 1e4));
485
+ }
486
+ return this.sell(mint, tokenAmount, slippage);
487
+ }
488
+ // ============ Chat ============
489
+ /**
490
+ * Get chat messages
491
+ */
492
+ async getChat(params) {
493
+ return this.request("GET", "/chat", { params });
494
+ }
495
+ /**
496
+ * Send chat message
497
+ */
498
+ async sendChat(params) {
499
+ return this.request("POST", "/chat", { body: params, auth: true });
500
+ }
501
+ /**
502
+ * Add reaction
503
+ */
504
+ async addReaction(messageId, emoji) {
505
+ await this.request("POST", "/reactions", {
506
+ body: { messageId, emoji },
507
+ auth: true
508
+ });
509
+ }
510
+ /**
511
+ * Remove reaction
512
+ */
513
+ async removeReaction(messageId, emoji) {
514
+ await this.request("DELETE", "/reactions", {
515
+ params: { messageId, emoji },
516
+ auth: true
517
+ });
518
+ }
519
+ // ============ User / Auth ============
520
+ /**
521
+ * Get user profile
522
+ */
523
+ async getProfile(wallet) {
524
+ return this.request("GET", "/profile", { params: { wallet } });
525
+ }
526
+ /**
527
+ * Update profile
528
+ */
529
+ async updateProfile(params) {
530
+ await this.request("POST", "/profile", { body: params, auth: true });
531
+ }
532
+ /**
533
+ * Create session token
534
+ */
535
+ async createSession() {
536
+ return this.request("POST", "/auth/session", { body: {}, auth: true });
537
+ }
538
+ /**
539
+ * Validate session token
540
+ */
541
+ async validateSession() {
542
+ return this.request("GET", "/auth/session", { auth: true });
543
+ }
544
+ // ============ Uploads ============
545
+ /**
546
+ * Upload image file
547
+ */
548
+ async uploadImage(file, filename = "image.png") {
549
+ const formData = new FormData();
550
+ if (file instanceof Blob) {
551
+ formData.append("file", file, filename);
552
+ } else {
553
+ const blob = new Blob([file]);
554
+ formData.append("file", blob, filename);
555
+ }
556
+ return this.request("POST", "/upload", { formData });
557
+ }
558
+ /**
559
+ * Upload image from file path (Node.js only)
560
+ */
561
+ async uploadImageFromPath(filePath) {
562
+ const fs = __require("fs");
563
+ const path = __require("path");
564
+ const buffer = fs.readFileSync(filePath);
565
+ const filename = path.basename(filePath);
566
+ return this.uploadImage(buffer, filename);
567
+ }
568
+ // ============ Network ============
569
+ /**
570
+ * Get network status
571
+ */
572
+ async getNetworkStatus() {
573
+ return this.request("GET", "/network");
574
+ }
575
+ };
576
+ function createClient(config) {
577
+ return new ClawdVaultClient(config);
578
+ }
579
+
580
+ // src/index.ts
581
+ import { PublicKey as PublicKey2, Keypair as Keypair2 } from "@solana/web3.js";
582
+ var PROGRAM_ID = "GUyF2TVe32Cid4iGVt2F6wPYDhLSVmTUZBj2974outYM";
583
+ var DEFAULT_BASE_URL = "https://clawdvault.com/api";
584
+ export {
585
+ ClawdVaultClient,
586
+ DEFAULT_BASE_URL,
587
+ Keypair2 as Keypair,
588
+ KeypairSigner,
589
+ PROGRAM_ID,
590
+ PhantomSigner,
591
+ PublicKey2 as PublicKey,
592
+ createAuthSignature,
593
+ createClient,
594
+ signAndSerialize,
595
+ verifySignature
596
+ };
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@clawdvault/sdk",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript SDK for ClawdVault - Solana token launchpad",
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
+ ],
18
+ "scripts": {
19
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean",
20
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
21
+ "test": "vitest run",
22
+ "clean": "rm -rf dist"
23
+ },
24
+ "dependencies": {
25
+ "@solana/web3.js": "^1.91.0",
26
+ "@solana/spl-token": "^0.4.0",
27
+ "bs58": "^5.0.0",
28
+ "tweetnacl": "^1.0.3"
29
+ },
30
+ "devDependencies": {
31
+ "tsup": "^8.0.1",
32
+ "typescript": "^5.3.3",
33
+ "vitest": "^1.2.0"
34
+ },
35
+ "keywords": [
36
+ "clawdvault",
37
+ "solana",
38
+ "token",
39
+ "launchpad",
40
+ "pump",
41
+ "sdk"
42
+ ],
43
+ "author": "ClawdVault",
44
+ "license": "MIT",
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "https://github.com/clawdvault/clawdvault-sdk"
48
+ },
49
+ "homepage": "https://clawdvault.com"
50
+ }