@velociti/sdk 0.1.0 → 0.2.1

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/client.js CHANGED
@@ -6,7 +6,7 @@
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.VelocitiClient = void 0;
8
8
  const DEFAULT_MAINNET_URL = 'https://velociti.fun/api/sdk';
9
- const DEFAULT_DEVNET_URL = 'https://devnet.velociti.fun/api/sdk';
9
+ const DEFAULT_DEVNET_URL = 'https://velociti.fun/api/sdk'; // Same URL, network param handled internally
10
10
  class VelocitiClient {
11
11
  constructor(config) {
12
12
  this.rateLimitInfo = null;
@@ -14,73 +14,92 @@ class VelocitiClient {
14
14
  throw new Error('API key is required. Get one at velociti.fun/developers');
15
15
  }
16
16
  this.apiKey = config.apiKey;
17
- this.network = config.network || 'mainnet';
17
+ this.network = config.network || 'devnet';
18
18
  this.baseUrl = config.baseUrl ||
19
19
  (this.network === 'mainnet' ? DEFAULT_MAINNET_URL : DEFAULT_DEVNET_URL);
20
+ // Retry configuration
21
+ this.enableRetry = config.enableRetry ?? true;
22
+ this.maxRetries = config.maxRetries ?? 3;
23
+ this.retryDelay = config.retryDelay ?? 1000;
20
24
  }
21
25
  /**
22
- * Make an authenticated request to the VELOCITI API
26
+ * Sleep helper for retry logic
27
+ */
28
+ sleep(ms) {
29
+ return new Promise(resolve => setTimeout(resolve, ms));
30
+ }
31
+ /**
32
+ * Make an authenticated request to the VELOCITI API with retry logic
23
33
  */
24
34
  async request(endpoint, options = {}) {
25
- const url = `${this.baseUrl}${endpoint}`;
26
- const response = await fetch(url, {
27
- ...options,
28
- headers: {
29
- 'Content-Type': 'application/json',
30
- 'X-API-Key': this.apiKey,
31
- ...options.headers,
32
- },
33
- });
34
- // Update rate limit info from headers
35
- const remaining = response.headers.get('X-RateLimit-Remaining');
36
- const limit = response.headers.get('X-RateLimit-Limit');
37
- const reset = response.headers.get('X-RateLimit-Reset');
38
- if (remaining && limit && reset) {
39
- this.rateLimitInfo = {
40
- remaining: parseInt(remaining, 10),
41
- limit: parseInt(limit, 10),
42
- reset: parseInt(reset, 10),
43
- };
44
- }
45
- if (response.status === 429) {
46
- return {
47
- success: false,
48
- error: 'Rate limit exceeded. Please try again later.',
49
- };
50
- }
51
- if (!response.ok) {
52
- const errorData = await response.json().catch(() => ({}));
53
- return {
54
- success: false,
55
- error: errorData.error || `HTTP ${response.status}: ${response.statusText}`,
56
- };
35
+ let lastError = null;
36
+ const attempts = this.enableRetry ? this.maxRetries : 1;
37
+ for (let attempt = 1; attempt <= attempts; attempt++) {
38
+ try {
39
+ const url = `${this.baseUrl}${endpoint}`;
40
+ const response = await fetch(url, {
41
+ ...options,
42
+ headers: {
43
+ 'Content-Type': 'application/json',
44
+ 'X-API-Key': this.apiKey,
45
+ ...options.headers,
46
+ },
47
+ });
48
+ // Update rate limit info from headers
49
+ const remaining = response.headers.get('X-RateLimit-Remaining');
50
+ const limit = response.headers.get('X-RateLimit-Limit');
51
+ const reset = response.headers.get('X-RateLimit-Reset');
52
+ if (remaining && limit && reset) {
53
+ this.rateLimitInfo = {
54
+ remaining: parseInt(remaining, 10),
55
+ limit: parseInt(limit, 10),
56
+ reset: parseInt(reset, 10),
57
+ };
58
+ }
59
+ if (response.status === 429) {
60
+ // Rate limited - retry with exponential backoff
61
+ if (attempt < attempts) {
62
+ await this.sleep(this.retryDelay * Math.pow(2, attempt - 1));
63
+ continue;
64
+ }
65
+ return {
66
+ success: false,
67
+ error: 'Rate limit exceeded. Please try again later.',
68
+ };
69
+ }
70
+ if (response.status >= 500 && attempt < attempts) {
71
+ // Server error - retry
72
+ await this.sleep(this.retryDelay * Math.pow(2, attempt - 1));
73
+ continue;
74
+ }
75
+ if (!response.ok) {
76
+ const errorData = await response.json().catch(() => ({}));
77
+ return {
78
+ success: false,
79
+ error: errorData.error || `HTTP ${response.status}: ${response.statusText}`,
80
+ };
81
+ }
82
+ const data = await response.json();
83
+ return { success: true, data };
84
+ }
85
+ catch (error) {
86
+ lastError = error;
87
+ if (attempt < attempts) {
88
+ await this.sleep(this.retryDelay * Math.pow(2, attempt - 1));
89
+ continue;
90
+ }
91
+ }
57
92
  }
58
- const data = await response.json();
59
- return { success: true, data };
93
+ return {
94
+ success: false,
95
+ error: lastError?.message || 'Request failed after retries',
96
+ };
60
97
  }
61
98
  /**
62
99
  * Prepare a token deployment transaction (Step 1)
63
100
  *
64
101
  * Returns an unsigned transaction that you must sign with your wallet.
65
102
  * After signing, call submitTransaction() to complete the deployment.
66
- *
67
- * @example
68
- * ```typescript
69
- * // Step 1: Prepare the transaction
70
- * const prepared = await client.prepareTokenDeploy({
71
- * name: 'My Token',
72
- * symbol: 'MTK',
73
- * taxRate: 5,
74
- * payerAddress: 'YourWalletAddress...'
75
- * });
76
- *
77
- * // Step 2: Sign with your wallet (example using @solana/web3.js)
78
- * const tx = Transaction.from(Buffer.from(prepared.data.transaction, 'base64'));
79
- * const signedTx = await wallet.signTransaction(tx);
80
- *
81
- * // Step 3: Submit the signed transaction
82
- * const result = await client.submitTransaction(signedTx.serialize().toString('base64'));
83
- * ```
84
103
  */
85
104
  async prepareTokenDeploy(params) {
86
105
  // Validate params
@@ -114,40 +133,47 @@ class VelocitiClient {
114
133
  }
115
134
  /**
116
135
  * Convenience method: Deploy token in one call (requires wallet adapter)
117
- *
118
- * This combines prepareTokenDeploy and submitTransaction.
119
- * You must provide a signTransaction function from your wallet.
120
- *
121
- * @example
122
- * ```typescript
123
- * const result = await client.deployToken({
124
- * name: 'My Token',
125
- * symbol: 'MTK',
126
- * taxRate: 5,
127
- * payerAddress: wallet.publicKey.toBase58()
128
- * }, async (tx) => {
129
- * return await wallet.signTransaction(tx);
130
- * });
131
- * ```
132
136
  */
133
137
  async deployToken(params, signTransaction) {
134
- // Step 1: Prepare
135
138
  const prepared = await this.prepareTokenDeploy(params);
136
139
  if (!prepared.success || !prepared.data) {
137
140
  return { success: false, error: prepared.error || 'Failed to prepare transaction' };
138
141
  }
139
- // Step 2: Sign
140
142
  try {
141
- const txBytes = Uint8Array.from(atob(prepared.data.transaction), c => c.charCodeAt(0));
143
+ const txBytes = Uint8Array.from(atob(prepared.data.transaction), (c) => c.charCodeAt(0));
142
144
  const signedBytes = await signTransaction(txBytes);
143
145
  const signedBase64 = btoa(String.fromCharCode(...signedBytes));
144
- // Step 3: Submit
145
146
  return this.submitTransaction(signedBase64);
146
147
  }
147
148
  catch (error) {
148
- return { success: false, error: `Signing failed: ${error.message}` };
149
+ const message = error instanceof Error ? error.message : 'Unknown error';
150
+ return { success: false, error: `Signing failed: ${message}` };
151
+ }
152
+ }
153
+ // ============================================
154
+ // BATCH DEPLOY
155
+ // ============================================
156
+ /**
157
+ * Prepare multiple token deployments in batch
158
+ */
159
+ async prepareBatchDeploy(params) {
160
+ if (!params.tokens || params.tokens.length === 0) {
161
+ return { success: false, error: 'At least one token is required' };
162
+ }
163
+ if (params.tokens.length > 10) {
164
+ return { success: false, error: 'Maximum 10 tokens per batch' };
165
+ }
166
+ if (!params.payerAddress) {
167
+ return { success: false, error: 'Payer address is required' };
149
168
  }
169
+ return this.request('/deploy/batch', {
170
+ method: 'POST',
171
+ body: JSON.stringify(params),
172
+ });
150
173
  }
174
+ // ============================================
175
+ // TOKEN ANALYTICS
176
+ // ============================================
151
177
  /**
152
178
  * Get token information by mint address
153
179
  */
@@ -160,6 +186,23 @@ class VelocitiClient {
160
186
  async getMyTokens() {
161
187
  return this.request('/tokens/mine');
162
188
  }
189
+ /**
190
+ * Get detailed analytics for a token
191
+ */
192
+ async getTokenAnalytics(mintAddress) {
193
+ return this.request(`/tokens/${mintAddress}/analytics`);
194
+ }
195
+ /**
196
+ * Get price history for a token
197
+ * @param mintAddress - Token mint address
198
+ * @param period - Time period: '1h', '24h', '7d', '30d'
199
+ */
200
+ async getPriceHistory(mintAddress, period = '24h') {
201
+ return this.request(`/tokens/${mintAddress}/price-history?period=${period}`);
202
+ }
203
+ // ============================================
204
+ // FEE CLAIMING
205
+ // ============================================
163
206
  /**
164
207
  * Prepare fee claim transaction
165
208
  */
@@ -171,7 +214,6 @@ class VelocitiClient {
171
214
  }
172
215
  /**
173
216
  * Claim accumulated transfer fees for a token
174
- * Combines prepare + sign + submit
175
217
  */
176
218
  async claimFees(mintAddress, walletAddress, signTransaction) {
177
219
  const prepared = await this.prepareClaimFees(mintAddress, walletAddress);
@@ -179,7 +221,7 @@ class VelocitiClient {
179
221
  return { success: false, error: prepared.error || 'Failed to prepare claim' };
180
222
  }
181
223
  try {
182
- const txBytes = Uint8Array.from(atob(prepared.data.transaction), c => c.charCodeAt(0));
224
+ const txBytes = Uint8Array.from(atob(prepared.data.transaction), (c) => c.charCodeAt(0));
183
225
  const signedBytes = await signTransaction(txBytes);
184
226
  const signedBase64 = btoa(String.fromCharCode(...signedBytes));
185
227
  return this.request('/fees/submit', {
@@ -188,7 +230,8 @@ class VelocitiClient {
188
230
  });
189
231
  }
190
232
  catch (error) {
191
- return { success: false, error: `Signing failed: ${error.message}` };
233
+ const message = error instanceof Error ? error.message : 'Unknown error';
234
+ return { success: false, error: `Signing failed: ${message}` };
192
235
  }
193
236
  }
194
237
  /**
@@ -197,6 +240,43 @@ class VelocitiClient {
197
240
  async getUnclaimedFees(mintAddress) {
198
241
  return this.request(`/fees/${mintAddress}`);
199
242
  }
243
+ // ============================================
244
+ // WEBHOOKS
245
+ // ============================================
246
+ /**
247
+ * Register a webhook to receive events
248
+ */
249
+ async registerWebhook(config) {
250
+ return this.request('/webhooks', {
251
+ method: 'POST',
252
+ body: JSON.stringify(config),
253
+ });
254
+ }
255
+ /**
256
+ * List all registered webhooks
257
+ */
258
+ async listWebhooks() {
259
+ return this.request('/webhooks');
260
+ }
261
+ /**
262
+ * Delete a webhook
263
+ */
264
+ async deleteWebhook(webhookId) {
265
+ return this.request(`/webhooks/${webhookId}`, {
266
+ method: 'DELETE',
267
+ });
268
+ }
269
+ /**
270
+ * Test a webhook endpoint
271
+ */
272
+ async testWebhook(webhookId) {
273
+ return this.request(`/webhooks/${webhookId}/test`, {
274
+ method: 'POST',
275
+ });
276
+ }
277
+ // ============================================
278
+ // UTILITY METHODS
279
+ // ============================================
200
280
  /**
201
281
  * Get current rate limit status
202
282
  */
@@ -209,5 +289,11 @@ class VelocitiClient {
209
289
  getNetwork() {
210
290
  return this.network;
211
291
  }
292
+ /**
293
+ * Check if API key is valid
294
+ */
295
+ async validateApiKey() {
296
+ return this.request('/auth/validate');
297
+ }
212
298
  }
213
299
  exports.VelocitiClient = VelocitiClient;
package/dist/index.d.ts CHANGED
@@ -17,6 +17,9 @@
17
17
  * taxRate: 5
18
18
  * });
19
19
  * ```
20
+ *
21
+ * @packageDocumentation
20
22
  */
21
23
  export { VelocitiClient } from './client';
22
24
  export * from './types';
25
+ export * from './react';
package/dist/index.js CHANGED
@@ -18,6 +18,8 @@
18
18
  * taxRate: 5
19
19
  * });
20
20
  * ```
21
+ *
22
+ * @packageDocumentation
21
23
  */
22
24
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
23
25
  if (k2 === undefined) k2 = k;
@@ -38,3 +40,5 @@ exports.VelocitiClient = void 0;
38
40
  var client_1 = require("./client");
39
41
  Object.defineProperty(exports, "VelocitiClient", { enumerable: true, get: function () { return client_1.VelocitiClient; } });
40
42
  __exportStar(require("./types"), exports);
43
+ // React hooks (for client-side use)
44
+ __exportStar(require("./react"), exports);
@@ -0,0 +1,65 @@
1
+ /**
2
+ * React Hooks for VELOCITI SDK
3
+ *
4
+ * Usage with Solana wallet adapter:
5
+ *
6
+ * import { useVelocitiDeploy } from '@velociti/sdk/react';
7
+ * import { useWallet } from '@solana/wallet-adapter-react';
8
+ *
9
+ * function DeployButton() {
10
+ * const { signTransaction } = useWallet();
11
+ * const { deploy, loading, error } = useVelocitiDeploy('your-api-key');
12
+ *
13
+ * const handleDeploy = async () => {
14
+ * const result = await deploy({
15
+ * name: 'MyToken',
16
+ * symbol: 'MTK',
17
+ * taxRate: 5,
18
+ * payerAddress: wallet.publicKey.toBase58()
19
+ * }, signTransaction);
20
+ *
21
+ * if (result.success) {
22
+ * console.log('Deployed!', result.data);
23
+ * }
24
+ * };
25
+ * }
26
+ */
27
+ import { VelocitiClient } from './client';
28
+ import { DeployTokenParams, TokenInfo, TokenAnalytics, ApiResponse, SubmitResult } from './types';
29
+ export declare function useVelocitiDeploy(apiKey: string, network?: 'mainnet' | 'devnet'): {
30
+ deploy: (params: DeployTokenParams, signTransaction: (transaction: Uint8Array) => Promise<Uint8Array>) => Promise<ApiResponse<SubmitResult>>;
31
+ prepareTransaction: (params: DeployTokenParams) => Promise<ApiResponse<import("./types").PreparedTransaction>>;
32
+ submitTransaction: (signedTransaction: string) => Promise<ApiResponse<SubmitResult>>;
33
+ loading: boolean;
34
+ error: null;
35
+ result: null;
36
+ client: VelocitiClient;
37
+ };
38
+ export declare function useVelocitiToken(apiKey: string, mintAddress: string, network?: 'mainnet' | 'devnet'): {
39
+ fetch: () => Promise<TokenInfo | null>;
40
+ refresh: () => Promise<TokenInfo | null>;
41
+ loading: boolean;
42
+ error: null;
43
+ token: null;
44
+ };
45
+ export declare function useVelocitiAnalytics(apiKey: string, mintAddress: string, network?: 'mainnet' | 'devnet'): {
46
+ fetch: () => Promise<TokenAnalytics | null>;
47
+ loading: boolean;
48
+ error: null;
49
+ analytics: null;
50
+ };
51
+ export declare function useVelocitiMyTokens(apiKey: string, network?: 'mainnet' | 'devnet'): {
52
+ fetch: () => Promise<TokenInfo[]>;
53
+ loading: boolean;
54
+ error: null;
55
+ tokens: TokenInfo[];
56
+ };
57
+ export declare function useVelocitiFees(apiKey: string, mintAddress: string, network?: 'mainnet' | 'devnet'): {
58
+ getUnclaimedFees: () => Promise<ApiResponse<{
59
+ amount: string;
60
+ valueInSol: number;
61
+ }>>;
62
+ claim: (walletAddress: string, signTransaction: (transaction: Uint8Array) => Promise<Uint8Array>) => Promise<ApiResponse<import("./types").ClaimFeesResult>>;
63
+ loading: boolean;
64
+ error: null;
65
+ };
package/dist/react.js ADDED
@@ -0,0 +1,235 @@
1
+ "use strict";
2
+ /**
3
+ * React Hooks for VELOCITI SDK
4
+ *
5
+ * Usage with Solana wallet adapter:
6
+ *
7
+ * import { useVelocitiDeploy } from '@velociti/sdk/react';
8
+ * import { useWallet } from '@solana/wallet-adapter-react';
9
+ *
10
+ * function DeployButton() {
11
+ * const { signTransaction } = useWallet();
12
+ * const { deploy, loading, error } = useVelocitiDeploy('your-api-key');
13
+ *
14
+ * const handleDeploy = async () => {
15
+ * const result = await deploy({
16
+ * name: 'MyToken',
17
+ * symbol: 'MTK',
18
+ * taxRate: 5,
19
+ * payerAddress: wallet.publicKey.toBase58()
20
+ * }, signTransaction);
21
+ *
22
+ * if (result.success) {
23
+ * console.log('Deployed!', result.data);
24
+ * }
25
+ * };
26
+ * }
27
+ */
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.useVelocitiFees = exports.useVelocitiMyTokens = exports.useVelocitiAnalytics = exports.useVelocitiToken = exports.useVelocitiDeploy = void 0;
30
+ const client_1 = require("./client");
31
+ // React hook for token deployment
32
+ function useVelocitiDeploy(apiKey, network = 'devnet') {
33
+ let loading = false;
34
+ let error = null;
35
+ let result = null;
36
+ const client = new client_1.VelocitiClient({ apiKey, network });
37
+ async function deploy(params, signTransaction) {
38
+ loading = true;
39
+ error = null;
40
+ try {
41
+ const response = await client.deployToken(params, signTransaction);
42
+ if (response.success && response.data) {
43
+ result = response.data;
44
+ }
45
+ else {
46
+ error = response.error || 'Unknown error';
47
+ }
48
+ return response;
49
+ }
50
+ catch (e) {
51
+ const message = e instanceof Error ? e.message : 'Unknown error';
52
+ error = message;
53
+ return { success: false, error: message };
54
+ }
55
+ finally {
56
+ loading = false;
57
+ }
58
+ }
59
+ async function prepareTransaction(params) {
60
+ loading = true;
61
+ try {
62
+ return await client.prepareTokenDeploy(params);
63
+ }
64
+ finally {
65
+ loading = false;
66
+ }
67
+ }
68
+ async function submitTransaction(signedTransaction) {
69
+ loading = true;
70
+ try {
71
+ return await client.submitTransaction(signedTransaction);
72
+ }
73
+ finally {
74
+ loading = false;
75
+ }
76
+ }
77
+ return {
78
+ deploy,
79
+ prepareTransaction,
80
+ submitTransaction,
81
+ loading,
82
+ error,
83
+ result,
84
+ client,
85
+ };
86
+ }
87
+ exports.useVelocitiDeploy = useVelocitiDeploy;
88
+ // React hook for fetching token info
89
+ function useVelocitiToken(apiKey, mintAddress, network = 'devnet') {
90
+ let loading = false;
91
+ let error = null;
92
+ let token = null;
93
+ const client = new client_1.VelocitiClient({ apiKey, network });
94
+ async function fetch() {
95
+ loading = true;
96
+ error = null;
97
+ try {
98
+ const response = await client.getToken(mintAddress);
99
+ if (response.success && response.data) {
100
+ token = response.data;
101
+ return token;
102
+ }
103
+ else {
104
+ error = response.error || 'Failed to fetch token';
105
+ return null;
106
+ }
107
+ }
108
+ catch (e) {
109
+ error = e instanceof Error ? e.message : 'Unknown error';
110
+ return null;
111
+ }
112
+ finally {
113
+ loading = false;
114
+ }
115
+ }
116
+ async function refresh() {
117
+ return fetch();
118
+ }
119
+ return {
120
+ fetch,
121
+ refresh,
122
+ loading,
123
+ error,
124
+ token,
125
+ };
126
+ }
127
+ exports.useVelocitiToken = useVelocitiToken;
128
+ // React hook for token analytics
129
+ function useVelocitiAnalytics(apiKey, mintAddress, network = 'devnet') {
130
+ let loading = false;
131
+ let error = null;
132
+ let analytics = null;
133
+ const client = new client_1.VelocitiClient({ apiKey, network });
134
+ async function fetch() {
135
+ loading = true;
136
+ error = null;
137
+ try {
138
+ const response = await client.getTokenAnalytics(mintAddress);
139
+ if (response.success && response.data) {
140
+ analytics = response.data;
141
+ return analytics;
142
+ }
143
+ else {
144
+ error = response.error || 'Failed to fetch analytics';
145
+ return null;
146
+ }
147
+ }
148
+ catch (e) {
149
+ error = e instanceof Error ? e.message : 'Unknown error';
150
+ return null;
151
+ }
152
+ finally {
153
+ loading = false;
154
+ }
155
+ }
156
+ return {
157
+ fetch,
158
+ loading,
159
+ error,
160
+ analytics,
161
+ };
162
+ }
163
+ exports.useVelocitiAnalytics = useVelocitiAnalytics;
164
+ // React hook for listing user's tokens
165
+ function useVelocitiMyTokens(apiKey, network = 'devnet') {
166
+ let loading = false;
167
+ let error = null;
168
+ let tokens = [];
169
+ const client = new client_1.VelocitiClient({ apiKey, network });
170
+ async function fetch() {
171
+ loading = true;
172
+ error = null;
173
+ try {
174
+ const response = await client.getMyTokens();
175
+ if (response.success && response.data) {
176
+ tokens = response.data;
177
+ return tokens;
178
+ }
179
+ else {
180
+ error = response.error || 'Failed to fetch tokens';
181
+ return [];
182
+ }
183
+ }
184
+ catch (e) {
185
+ error = e instanceof Error ? e.message : 'Unknown error';
186
+ return [];
187
+ }
188
+ finally {
189
+ loading = false;
190
+ }
191
+ }
192
+ return {
193
+ fetch,
194
+ loading,
195
+ error,
196
+ tokens,
197
+ };
198
+ }
199
+ exports.useVelocitiMyTokens = useVelocitiMyTokens;
200
+ // React hook for fee claiming
201
+ function useVelocitiFees(apiKey, mintAddress, network = 'mainnet') {
202
+ let loading = false;
203
+ let error = null;
204
+ const client = new client_1.VelocitiClient({ apiKey, network });
205
+ async function getUnclaimedFees() {
206
+ loading = true;
207
+ try {
208
+ return await client.getUnclaimedFees(mintAddress);
209
+ }
210
+ finally {
211
+ loading = false;
212
+ }
213
+ }
214
+ async function claim(walletAddress, signTransaction) {
215
+ loading = true;
216
+ error = null;
217
+ try {
218
+ return await client.claimFees(mintAddress, walletAddress, signTransaction);
219
+ }
220
+ catch (e) {
221
+ error = e instanceof Error ? e.message : 'Unknown error';
222
+ return { success: false, error };
223
+ }
224
+ finally {
225
+ loading = false;
226
+ }
227
+ }
228
+ return {
229
+ getUnclaimedFees,
230
+ claim,
231
+ loading,
232
+ error,
233
+ };
234
+ }
235
+ exports.useVelocitiFees = useVelocitiFees;