voidai-sdk 0.1.1 → 0.2.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/README.md CHANGED
@@ -1,53 +1,303 @@
1
1
  # VoidAI Bridge SDK
2
2
 
3
- TypeScript SDK for VoidAI Bridge - A bridge application that bridges TAO tokens between Bittensor and Ethereum blockchains.
3
+ [![npm version](https://img.shields.io/npm/v/voidai-sdk.svg)](https://www.npmjs.com/package/voidai-sdk)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ **TypeScript SDK for VoidAI Bridge** - Cross-chain asset bridging and routing across Bittensor, Ethereum, Solana, and other supported chains.
7
+
8
+ ## 🎯 What is VoidAI Bridge SDK?
9
+
10
+ The VoidAI Bridge SDK provides a unified interface to:
11
+
12
+ - **Bridge assets** between chains (TAO ↔ wTAO, Alpha ↔ wAlpha, cross-chain transfers)
13
+ - **Route transactions** via SWAP, BRIDGE, or CCIP operations
14
+ - **Estimate fees** before executing transactions
15
+ - **Connect wallets** (Bittensor, Ethereum/MetaMask, Solana/Phantom)
16
+ - **Build EVM transactions** automatically for bridge burn operations
17
+
18
+ Perfect for building DeFi applications, cross-chain DEXs, or any app that needs to move assets between Bittensor, EVM chains, and Solana.
4
19
 
5
20
  ## 📦 Installation
6
21
 
7
22
  ```bash
8
23
  npm install voidai-sdk
24
+ # or
25
+ yarn add voidai-sdk
26
+ # or
27
+ pnpm add voidai-sdk
9
28
  ```
10
29
 
30
+ ### Requirements
31
+
32
+ - **Node.js**: ≥ 18 (for backend usage)
33
+ - **Browser**: Modern browsers with ES6+ support
34
+ - **API Key**: Get your VoidAI Bridge API key from the [VoidAI Console](https://console.voidai.com)
35
+
11
36
  ## 🚀 Quick Start
12
37
 
38
+ ### 1. Initialize the SDK
39
+
13
40
  ```typescript
14
41
  import { BridgeSDK } from 'voidai-sdk';
15
42
 
16
- // Initialize the SDK
17
43
  const sdk = new BridgeSDK({
18
- apiKey: 'your-api-key',
19
- environment: 'development' // or 'production', 'staging'
44
+ apiKey: process.env.VOIDAI_API_KEY!,
45
+ environment: 'testnet', // 'devnet' | 'testnet' | 'mainnet'
20
46
  });
21
47
 
22
- await sdk.init();
48
+ // Wait for authentication & API key validation
49
+ await sdk.ready;
50
+ ```
51
+
52
+ > **Backend?** Use `BridgeSDKServer` instead – it requires `apiKey` + `secretKey` and has no wallet integrations. See [Backend Usage](#-backend-usage-nodejs) below.
53
+
54
+ ### 2. Fetch Supported Chains & Assets
55
+
56
+ ```typescript
57
+ // Get all active chains
58
+ const chains = await sdk.api.getSupportedChains({
59
+ isActive: true,
60
+ isCcipSupported: true,
61
+ });
62
+
63
+ // Get assets (optionally filtered by chain)
64
+ const assets = await sdk.api.getAssetList('ETHEREUM_SEPOLIA');
65
+ ```
66
+
67
+ ### 3. Connect Wallets (Browser Only)
68
+
69
+ ```typescript
70
+ // Connect MetaMask
71
+ const ethAccount = await sdk.wallets.ethereum.connect();
72
+ console.log('Connected:', ethAccount.address);
73
+
74
+ // Connect Bittensor wallet (Talisman/Subwallet/Polkadot.js)
75
+ const bittensorAccount = await sdk.wallets.bittensor.connect();
76
+ console.log('Connected:', bittensorAccount.address);
77
+
78
+ // Connect Phantom (Solana)
79
+ const solanaAccount = await sdk.wallets.solana.connect();
80
+ console.log('Connected:', solanaAccount.address);
81
+ ```
82
+
83
+ ### 4. Execute a Bridge Operation
84
+
85
+ ```typescript
86
+ // Bridge TAO from Bittensor to Ethereum
87
+ const result = await sdk.bridge.bridge({
88
+ fromWallet: '5DqAEsZi...', // Bittensor address
89
+ toWallet: '0x742d35...', // Ethereum address
90
+ fromToken: 'tao',
91
+ toToken: 'wtao',
92
+ fromChain: 'BITTENSOR',
93
+ toChain: 'ETHEREUM_SEPOLIA',
94
+ amount: 1.0,
95
+ });
96
+
97
+ console.log('Bridge identifier:', result.identifier);
98
+
99
+ // For EVM burn flows (wTAO → TAO), use the pre-built transaction
100
+ if (result.evmTransaction) {
101
+ const txHash = await window.ethereum.request({
102
+ method: 'eth_sendTransaction',
103
+ params: [{
104
+ from: ethAccount.address,
105
+ to: result.evmTransaction.to,
106
+ data: result.evmTransaction.data,
107
+ value: result.evmTransaction.value,
108
+ }],
109
+ });
110
+ console.log('Transaction sent:', txHash);
111
+ }
112
+ ```
113
+
114
+ ### 5. Route a Swap Transaction
115
+
116
+ ```typescript
117
+ const route = await sdk.bridge.routeSwap({
118
+ operationType: 'SWAP',
119
+ originAssetId: 1,
120
+ destinationAssetId: 2,
121
+ fromAddress: '0xSource...',
122
+ toAddress: '0xDestination...',
123
+ amount: 0.5,
124
+ });
125
+
126
+ if (route.success && route.data) {
127
+ // Execute via MetaMask
128
+ await window.ethereum.request({
129
+ method: 'eth_sendTransaction',
130
+ params: [{
131
+ from: '0xSource...',
132
+ to: route.data.to,
133
+ data: route.data.data,
134
+ value: route.data.value,
135
+ }],
136
+ });
137
+ }
138
+ ```
139
+
140
+ ### 6. Estimate Fees
141
+
142
+ ```typescript
143
+ // Bridge fee estimate
144
+ const bridgeFee = await sdk.bridge.getBridgeFeeEstimate({
145
+ fromToken: 'tao',
146
+ toToken: 'wtao',
147
+ amount: 2.5,
148
+ });
149
+
150
+ console.log('Bridge fee:', bridgeFee.data.fee);
151
+ console.log('Recipient will receive:', bridgeFee.data.recipientAmount);
152
+
153
+ // Router swap fee estimate
154
+ const swapFee = await sdk.bridge.getRouterSwapFeeEstimate({
155
+ originAssetId: 1,
156
+ destinationAssetId: 2,
157
+ amount: 0.75,
158
+ operationType: 'SWAP',
159
+ toAddress: '0xDestination...',
160
+ });
161
+
162
+ console.log('Total fee:', swapFee.totalFee);
163
+ ```
164
+
165
+ ## 📚 Documentation
166
+
167
+ **📖 [Full Documentation](docs/README.md)** - Complete API reference, guides, and examples
168
+
169
+ - [Getting Started Guide](docs/getting-started.md)
170
+ - [SDK Initialization](docs/sdk-initialization.md)
171
+ - [API Reference](docs/api/overview.md)
172
+ - [Frontend Integration Examples](docs/frontend-integration.md)
173
+ - [Error Handling](docs/error-handling.md)
174
+ - [Best Practices](docs/best-practices.md)
175
+
176
+ ## 💡 Key Features
177
+
178
+ ### ✅ Multi-Chain Support
179
+ - **Bittensor** (TAO, Alpha)
180
+ - **Ethereum** (Mainnet, Sepolia)
181
+ - **Base** (Mainnet, Sepolia)
182
+ - **Solana**
183
+ - More chains added regularly
184
+
185
+ ### ✅ Wallet Integration
186
+ - **Bittensor**: Talisman, Subwallet, Polkadot.js
187
+ - **Ethereum**: MetaMask
188
+ - **Solana**: Phantom
189
+
190
+ ### ✅ Bridge Operations
191
+ - TAO ↔ wTAO (Bittensor ↔ Ethereum)
192
+ - Alpha ↔ wAlpha
193
+ - Cross-chain asset transfers
194
+ - Automatic EVM transaction building for burn operations
195
+
196
+ ### ✅ Routing & Swaps
197
+ - Unified route-transaction API
198
+ - SWAP, BRIDGE, and CCIP operations
199
+ - Fee estimation before execution
23
200
 
24
- // Connect wallets
25
- await sdk.wallets.bittensor.connect();
26
- await sdk.wallets.ethereum.connect();
27
- await sdk.wallets.solana.connect();
201
+ ### Frontend vs Backend
202
+ - **BridgeSDK** – Frontend usage (apiKey only, no secretKey)
203
+ - **BridgeSDKServer** – Backend usage (apiKey + secretKey for JWT auth, no wallets)
28
204
 
29
- // Use API methods
205
+ ### Production Ready
206
+ - TypeScript-first with full type definitions
207
+ - Automatic JWT refresh on token expiry
208
+ - Normalized error messages
209
+ - Environment-aware configuration
210
+ - Works in Node.js and browsers
211
+
212
+ ## 🖥️ Backend Usage (Node.js)
213
+
214
+ For server-side or backend integrations, use `BridgeSDKServer` with both `apiKey` and `secretKey`:
215
+
216
+ ```typescript
217
+ import { BridgeSDKServer } from 'voidai-sdk';
218
+
219
+ const sdk = new BridgeSDKServer({
220
+ apiKey: process.env.VOIDAI_API_KEY!,
221
+ secretKey: process.env.VOIDAI_SECRET_KEY!,
222
+ environment: 'production',
223
+ });
224
+
225
+ await sdk.ready;
226
+
227
+ // Same bridge/api API, no wallets
30
228
  const chains = await sdk.api.getSupportedChains();
31
- const assets = await sdk.api.getAssetList();
229
+ const result = await sdk.bridge.bridge({ /* ... */ });
32
230
  ```
33
231
 
34
- ## 🔑 Features
232
+ `BridgeSDKServer` exposes `config`, `api`, `bridge`, and `ready` – no `wallets` (use `BridgeSDK` in frontend for that).
233
+
234
+ ## 🔧 Environment Configuration
235
+
236
+ The SDK supports three environments:
237
+
238
+ | Environment | Base URL | Use Case |
239
+ |---------------|-----------------------------------------------|-----------------------|
240
+ | `development` | `http://localhost:3003` | Local development |
241
+ | `staging` | `https://api-staging.voidai.envistudios.com` | Testing & QA |
242
+ | `production` | `https://api.voidai.envistudios.com` | Live applications |
35
243
 
36
- - **Multi-Wallet Support**
37
- - Bittensor (Talisman, Polkadot.js, Subwallet)
38
- - Ethereum (MetaMask)
39
- - Solana (Phantom)
244
+ ## 📝 Example: Complete Bridge Flow
245
+
246
+ ```typescript
247
+ import { BridgeSDK } from 'voidai-sdk';
40
248
 
41
- - **API Methods**
42
- - Get supported chains
43
- - Get asset list
44
- - Chain filtering (by chainId, isActive, isCcipSupported)
249
+ async function bridgeTAO() {
250
+ // 1. Initialize SDK
251
+ const sdk = new BridgeSDK({
252
+ apiKey: process.env.VOIDAI_API_KEY!,
253
+ environment: 'staging',
254
+ });
255
+
256
+ await sdk.ready;
45
257
 
46
- - **TypeScript Support**
47
- - Full type definitions included
48
- - IntelliSense support
258
+ // 2. Connect wallets
259
+ const bittensorAccount = await sdk.wallets.bittensor.connect();
260
+ const ethAccount = await sdk.wallets.ethereum.connect();
49
261
 
50
- ## 🔧 Development
262
+ // 3. Estimate fees
263
+ const fee = await sdk.bridge.getBridgeFeeEstimate({
264
+ fromToken: 'tao',
265
+ toToken: 'wtao',
266
+ amount: 1.0,
267
+ });
268
+
269
+ console.log(`Fee: ${fee.data.fee}, You'll receive: ${fee.data.recipientAmount}`);
270
+
271
+ // 4. Execute bridge
272
+ const result = await sdk.bridge.bridge({
273
+ fromWallet: bittensorAccount.address,
274
+ toWallet: ethAccount.address,
275
+ fromToken: 'tao',
276
+ toToken: 'wtao',
277
+ fromChain: 'BITTENSOR',
278
+ toChain: 'ETHEREUM_SEPOLIA',
279
+ amount: 1.0,
280
+ });
281
+
282
+ console.log('Bridge initiated:', result.identifier);
283
+
284
+ // 5. Execute on-chain transaction (if EVM burn flow)
285
+ if (result.evmTransaction) {
286
+ const txHash = await window.ethereum.request({
287
+ method: 'eth_sendTransaction',
288
+ params: [{
289
+ from: ethAccount.address,
290
+ ...result.evmTransaction,
291
+ }],
292
+ });
293
+ console.log('On-chain tx:', txHash);
294
+ }
295
+ }
296
+
297
+ bridgeTAO().catch(console.error);
298
+ ```
299
+
300
+ ## 🛠️ Development
51
301
 
52
302
  ### Build
53
303
 
@@ -68,44 +318,118 @@ npm run build:all
68
318
  npm test
69
319
  ```
70
320
 
321
+ ### Lint
322
+
323
+ ```bash
324
+ npm run lint
325
+ ```
326
+
71
327
  ## 📁 Project Structure
72
328
 
73
329
  ```
74
330
  bridge-sdk/
75
331
  ├── src/ # SDK source code
76
- │ ├── api/ # API client
332
+ │ ├── api/ # HTTP client
77
333
  │ ├── config.ts # Configuration
78
- │ ├── core/ # Core bridge logic
334
+ │ ├── core/ # Bridge domain logic
79
335
  │ ├── types/ # TypeScript types
80
336
  │ ├── utils/ # Utilities
81
337
  │ ├── wallet/ # Wallet integrations
82
338
  │ └── index.ts # Main entry point
83
339
  ├── dist/ # Compiled SDK (Node.js)
84
340
  ├── dist-browser/ # Browser bundle
341
+ ├── docs/ # Full documentation (mdBook)
85
342
  ├── test/ # Test suite
86
343
  ├── examples/ # Example applications
87
- │ └── frontend/ # Frontend demo
344
+ │ └── frontend/ # Frontend demo app
88
345
  └── package.json
89
346
  ```
90
347
 
91
348
  ## 🌐 Browser Usage
92
349
 
93
- For browser usage, include the bundled SDK:
350
+ ### ES Modules
94
351
 
95
352
  ```html
96
- <script src="node_modules/voidai-sdk/dist-browser/voidai-sdk.js"></script>
97
- <script>
98
- const sdk = new VoidAISDK.BridgeSDK({
99
- apiKey: 'your-api-key',
100
- environment: 'development'
101
- });
353
+ <script type="module">
354
+ import { BridgeSDK } from './node_modules/voidai-sdk/dist-browser/voidai-sdk.js';
355
+
356
+ const sdk = new BridgeSDK({
357
+ apiKey: 'your-api-key',
358
+ environment: 'staging',
359
+ });
102
360
  </script>
103
361
  ```
104
362
 
105
- ## 📝 License
363
+ ### Bundler (Webpack/Vite/Rollup)
364
+
365
+ ```typescript
366
+ import { BridgeSDK } from 'voidai-sdk';
367
+
368
+ // Use normally - bundler will handle it
369
+ const sdk = new BridgeSDK({ apiKey, environment: 'production' });
370
+ ```
371
+
372
+ ## ⚠️ Error Handling
373
+
374
+ The SDK throws `Error` instances with user-friendly messages:
375
+
376
+ ```typescript
377
+ try {
378
+ await sdk.bridge.bridge({ /* ... */ });
379
+ } catch (error) {
380
+ // error.message contains a clear, actionable message
381
+ console.error('Bridge failed:', error.message);
382
+
383
+ // Common errors:
384
+ // - "Session expired or unauthorized..." → Check API key
385
+ // - "Failed to execute bridge swap" → Check parameters
386
+ // - "User rejected the connection request" → User cancelled wallet
387
+ }
388
+ ```
389
+
390
+ See [Error Handling Guide](docs/error-handling.md) for detailed patterns.
391
+
392
+ ## 🔐 Security Best Practices
393
+
394
+ - ✅ **Never commit API keys** - Use environment variables
395
+ - ✅ **Use BridgeSDKServer for backend** - Pass secretKey only in server code; use BridgeSDK (no secretKey) in frontend
396
+ - ✅ **Validate user inputs** before passing to SDK
397
+ - ✅ **Keep dependencies updated** - Monitor security advisories
398
+
399
+ See [Best Practices](docs/best-practices.md) for more guidance.
400
+
401
+ ## 📖 Examples
402
+
403
+ Check out the [example frontend app](examples/frontend/) for a complete integration example including:
404
+
405
+ - SDK initialization
406
+ - Wallet connections
407
+ - Bridge operations
408
+ - Swap routing
409
+ - Fee estimation
410
+ - Error handling
411
+
412
+ ## 🤝 Support
413
+
414
+ - **Documentation**: [Full docs](docs/README.md)
415
+ - **Issues**: [GitHub Issues](https://github.com/your-org/bridge-sdk/issues)
416
+ - **FAQ**: [Troubleshooting Guide](docs/faq.md)
417
+
418
+ ## 📄 License
106
419
 
107
420
  MIT
108
421
 
109
- ## 🤝 Contributing
422
+ ## 🙏 Contributing
110
423
 
111
424
  Contributions are welcome! Please ensure all tests pass before submitting a pull request.
425
+
426
+ ```bash
427
+ # Run tests
428
+ npm test
429
+
430
+ # Run linter
431
+ npm run lint
432
+
433
+ # Build before committing
434
+ npm run build:all
435
+ ```
@@ -1,12 +1,89 @@
1
1
  import { BridgeConfig } from '../config';
2
- import { Chain, Asset } from '../types';
2
+ import { Chain, Asset, ApiKeyValidationData, BridgeSwapRequest, BridgeSwapResponse, RouteTransactionRequest, RouteTransactionResponse, BridgeFeeEstimateRequest, BridgeFeeEstimateResponse, RouterSwapFeeEstimateRequest, RouterSwapFeeEstimateResponse, CancelCcipRequest, CancelRouterSwapRequest, CancelBridgeSwapRequest, CancelOperationResponse, ApiTransactionsResponse, ValidateBurnRequest, ValidateBurnResponse, CcipTxConfirmationRequest, CcipTxConfirmationResponse } from '../types';
3
3
  export declare class VoidAIBridgeClient {
4
4
  private config;
5
5
  private client;
6
+ private validatedApiKeyData;
7
+ private accessToken;
8
+ readonly ready: Promise<void>;
6
9
  constructor(config: BridgeConfig);
10
+ /**
11
+ * Authenticate and set Authorization header for subsequent requests.
12
+ * New flow: POST /api/v1/auth/login
13
+ * Fallback: GET /api/v1/auth/validate-api-key (legacy)
14
+ */
15
+ private authenticate;
16
+ private setAccessToken;
17
+ /**
18
+ * Get access token (available after successful auth)
19
+ */
20
+ getAccessToken(): string | null;
21
+ private getLoginUrl;
22
+ /**
23
+ * Get EVM bridge contract address for burn operations.
24
+ */
25
+ getBridgeContractAddress(): string;
26
+ /**
27
+ * Login to obtain JWT access token.
28
+ * Frontend usage: { apiKey }
29
+ * Backend usage: { apiKey, secretKey }
30
+ */
31
+ login(): Promise<string>;
32
+ private tryDecodeTokenToValidationData;
33
+ private base64UrlDecode;
34
+ /**
35
+ * Validate API key with the backend
36
+ * @throws Error if API key is invalid
37
+ */
38
+ validateApiKey(): Promise<ApiKeyValidationData>;
39
+ /**
40
+ * Get validation URL - uses baseUrl from config
41
+ */
42
+ private getValidationUrl;
43
+ /**
44
+ * Get validated API key data
45
+ */
46
+ getValidatedApiKeyData(): ApiKeyValidationData | null;
7
47
  private getUrl;
8
- get<T>(path: string, params?: any): Promise<T>;
9
- post<T>(path: string, data?: any): Promise<T>;
48
+ get<T>(path: string, params?: any, retryAttempted?: boolean): Promise<T>;
49
+ post<T>(path: string, data?: any, retryAttempted?: boolean): Promise<T>;
50
+ delete<T>(path: string, params?: any, retryAttempted?: boolean): Promise<T>;
51
+ patch<T>(path: string, data?: any, retryAttempted?: boolean): Promise<T>;
52
+ /**
53
+ * Bridge swap operation
54
+ */
55
+ bridgeSwap(payload: BridgeSwapRequest): Promise<BridgeSwapResponse>;
56
+ /**
57
+ * Route transaction operation (SWAP / BRIDGE / CCIP)
58
+ */
59
+ routeTransaction(payload: RouteTransactionRequest): Promise<RouteTransactionResponse>;
60
+ /**
61
+ * Cancel a CCIP route transaction
62
+ */
63
+ cancelCcip(params: CancelCcipRequest): Promise<CancelOperationResponse>;
64
+ /**
65
+ * Cancel a router swap transaction
66
+ */
67
+ cancelRouterSwap(params: CancelRouterSwapRequest): Promise<CancelOperationResponse>;
68
+ /**
69
+ * Cancel a bridge swap transaction
70
+ */
71
+ cancelBridgeSwap(params: CancelBridgeSwapRequest): Promise<CancelOperationResponse>;
72
+ /**
73
+ * Get recent API transactions (tenant-level)
74
+ *
75
+ * Maps to:
76
+ * POST /api/v1/bridge/api-transactions?page={page}&limit={limit}
77
+ */
78
+ getApiTransactions(page?: number, limit?: number): Promise<ApiTransactionsResponse>;
79
+ /**
80
+ * Manually validate a bridge burn transaction (EVM burn completion)
81
+ */
82
+ validateBurn(params: ValidateBurnRequest): Promise<ValidateBurnResponse>;
83
+ /**
84
+ * Manually confirm a CCIP transaction
85
+ */
86
+ confirmCcipTransaction(params: CcipTxConfirmationRequest): Promise<CcipTxConfirmationResponse>;
10
87
  /**
11
88
  * Get list of supported chains
12
89
  * @param options - Optional query parameters
@@ -23,5 +100,19 @@ export declare class VoidAIBridgeClient {
23
100
  * Get list of supported assets
24
101
  */
25
102
  getAssetList(chainId?: string): Promise<Asset[]>;
103
+ /**
104
+ * Get bridge fee estimate
105
+ * @param params - Fee estimation parameters
106
+ */
107
+ getBridgeFeeEstimate(params: BridgeFeeEstimateRequest): Promise<BridgeFeeEstimateResponse>;
108
+ /**
109
+ * Get router swap fee estimate
110
+ * @param params - Fee estimation parameters
111
+ */
112
+ getRouterSwapFeeEstimate(params: RouterSwapFeeEstimateRequest): Promise<RouterSwapFeeEstimateResponse>;
113
+ /**
114
+ * Normalize and rethrow errors with backend message (if available) so
115
+ * integrators can surface meaningful reasons to their users.
116
+ */
26
117
  private handleError;
27
118
  }