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