@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.d.mts +613 -0
- package/dist/index.d.ts +613 -0
- package/dist/index.js +631 -0
- package/dist/index.mjs +596 -0
- package/package.json +50 -0
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
|
+
});
|