voidai-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/README.md +119 -0
- package/dist/api/client.d.ts +27 -0
- package/dist/api/client.js +89 -0
- package/dist/auth/session.d.ts +50 -0
- package/dist/auth/session.js +110 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.js +35 -0
- package/dist/core/bridge.d.ts +17 -0
- package/dist/core/bridge.js +26 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +47 -0
- package/dist/types/index.d.ts +54 -0
- package/dist/types/index.js +2 -0
- package/dist/utils/validation.d.ts +2 -0
- package/dist/utils/validation.js +12 -0
- package/dist/wallet/bittensor.d.ts +59 -0
- package/dist/wallet/bittensor.js +143 -0
- package/dist/wallet/ethereum.d.ts +42 -0
- package/dist/wallet/ethereum.js +107 -0
- package/dist/wallet/solana.d.ts +36 -0
- package/dist/wallet/solana.js +100 -0
- package/dist-browser/voidai-sdk.js +2 -0
- package/dist-browser/voidai-sdk.js.LICENSE.txt +1 -0
- package/package.json +55 -0
package/README.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# VoidAI Bridge SDK
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for VoidAI Bridge - A bridge application that bridges TAO tokens between Bittensor and Ethereum blockchains.
|
|
4
|
+
|
|
5
|
+
## 📦 Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install voidai-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 🚀 Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { BridgeSDK } from 'voidai-sdk';
|
|
15
|
+
|
|
16
|
+
// Initialize the SDK
|
|
17
|
+
const sdk = new BridgeSDK({
|
|
18
|
+
apiKey: 'your-api-key',
|
|
19
|
+
environment: 'development' // or 'production', 'staging'
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
await sdk.init();
|
|
23
|
+
|
|
24
|
+
// Connect wallets
|
|
25
|
+
await sdk.wallets.bittensor.connect();
|
|
26
|
+
await sdk.wallets.ethereum.connect();
|
|
27
|
+
await sdk.wallets.solana.connect();
|
|
28
|
+
|
|
29
|
+
// Use API methods
|
|
30
|
+
const chains = await sdk.api.getSupportedChains();
|
|
31
|
+
const assets = await sdk.api.getAssetList();
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 📁 Project Structure
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
bridge-sdk/
|
|
38
|
+
├── src/ # SDK source code
|
|
39
|
+
│ ├── api/ # API client
|
|
40
|
+
│ ├── config.ts # Configuration
|
|
41
|
+
│ ├── core/ # Core bridge logic
|
|
42
|
+
│ ├── types/ # TypeScript types
|
|
43
|
+
│ ├── utils/ # Utilities
|
|
44
|
+
│ ├── wallet/ # Wallet integrations
|
|
45
|
+
│ └── index.ts # Main entry point
|
|
46
|
+
├── dist/ # Compiled SDK (Node.js)
|
|
47
|
+
├── dist-browser/ # Browser bundle
|
|
48
|
+
├── test/ # Test suite
|
|
49
|
+
├── examples/ # Example applications
|
|
50
|
+
│ └── frontend/ # Frontend demo
|
|
51
|
+
└── package.json
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## 🔧 Development
|
|
55
|
+
|
|
56
|
+
### Build
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# Build for Node.js
|
|
60
|
+
npm run build
|
|
61
|
+
|
|
62
|
+
# Build for browser
|
|
63
|
+
npm run build:browser
|
|
64
|
+
|
|
65
|
+
# Build both
|
|
66
|
+
npm run build:all
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Test
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npm test
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
See [TEST_COVERAGE.md](./TEST_COVERAGE.md) for detailed test coverage information.
|
|
76
|
+
|
|
77
|
+
## 📚 Documentation
|
|
78
|
+
|
|
79
|
+
- [Test Coverage](./TEST_COVERAGE.md) - Comprehensive test coverage documentation
|
|
80
|
+
- [Examples](./examples/README.md) - Example applications and demos
|
|
81
|
+
|
|
82
|
+
## 🌐 Browser Usage
|
|
83
|
+
|
|
84
|
+
For browser usage, include the bundled SDK:
|
|
85
|
+
|
|
86
|
+
```html
|
|
87
|
+
<script src="node_modules/voidai-sdk/dist-browser/voidai-sdk.js"></script>
|
|
88
|
+
<script>
|
|
89
|
+
const sdk = new VoidAISDK.BridgeSDK({
|
|
90
|
+
apiKey: 'your-api-key',
|
|
91
|
+
environment: 'development'
|
|
92
|
+
});
|
|
93
|
+
</script>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## 🔑 Features
|
|
97
|
+
|
|
98
|
+
- **Multi-Wallet Support**
|
|
99
|
+
- Bittensor (Talisman, Polkadot.js, Subwallet)
|
|
100
|
+
- Ethereum (MetaMask)
|
|
101
|
+
- Solana (Phantom)
|
|
102
|
+
|
|
103
|
+
- **API Methods**
|
|
104
|
+
- Get supported chains
|
|
105
|
+
- Get asset list
|
|
106
|
+
- Chain filtering (by chainId, isActive, isCcipSupported)
|
|
107
|
+
|
|
108
|
+
- **TypeScript Support**
|
|
109
|
+
- Full type definitions included
|
|
110
|
+
- IntelliSense support
|
|
111
|
+
|
|
112
|
+
## 📝 License
|
|
113
|
+
|
|
114
|
+
MIT
|
|
115
|
+
|
|
116
|
+
## 🤝 Contributing
|
|
117
|
+
|
|
118
|
+
Contributions are welcome! Please ensure all tests pass before submitting a pull request.
|
|
119
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BridgeConfig } from '../config';
|
|
2
|
+
import { Chain, Asset } from '../types';
|
|
3
|
+
export declare class VoidAIBridgeClient {
|
|
4
|
+
private config;
|
|
5
|
+
private client;
|
|
6
|
+
constructor(config: BridgeConfig);
|
|
7
|
+
private getUrl;
|
|
8
|
+
get<T>(path: string, params?: any): Promise<T>;
|
|
9
|
+
post<T>(path: string, data?: any): Promise<T>;
|
|
10
|
+
/**
|
|
11
|
+
* Get list of supported chains
|
|
12
|
+
* @param options - Optional query parameters
|
|
13
|
+
* @param options.isActive - Filter by active status
|
|
14
|
+
* @param options.isCcipSupported - Filter by CCIP support
|
|
15
|
+
* @param options.chainId - Filter by specific chain ID
|
|
16
|
+
*/
|
|
17
|
+
getSupportedChains(options?: {
|
|
18
|
+
isActive?: boolean;
|
|
19
|
+
isCcipSupported?: boolean;
|
|
20
|
+
chainId?: string;
|
|
21
|
+
}): Promise<Chain[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Get list of supported assets
|
|
24
|
+
*/
|
|
25
|
+
getAssetList(chainId?: string): Promise<Asset[]>;
|
|
26
|
+
private handleError;
|
|
27
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.VoidAIBridgeClient = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
class VoidAIBridgeClient {
|
|
9
|
+
constructor(config) {
|
|
10
|
+
this.config = config;
|
|
11
|
+
this.client = axios_1.default.create({
|
|
12
|
+
timeout: 10000,
|
|
13
|
+
headers: {
|
|
14
|
+
'Content-Type': 'application/json',
|
|
15
|
+
'x-api-key': this.config.apiKey,
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
getUrl(path) {
|
|
20
|
+
const baseUrl = this.config.getBaseUrl();
|
|
21
|
+
// Remove trailing slash from base and leading slash from path to avoid doubles
|
|
22
|
+
const cleanBase = baseUrl.replace(/\/$/, '');
|
|
23
|
+
const cleanPath = path.replace(/^\//, '');
|
|
24
|
+
return `${cleanBase}/${cleanPath}`;
|
|
25
|
+
}
|
|
26
|
+
async get(path, params) {
|
|
27
|
+
const url = this.getUrl(path);
|
|
28
|
+
try {
|
|
29
|
+
const response = await this.client.get(url, { params });
|
|
30
|
+
return response.data;
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
this.handleError(error);
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async post(path, data) {
|
|
38
|
+
const url = this.getUrl(path);
|
|
39
|
+
try {
|
|
40
|
+
const response = await this.client.post(url, data);
|
|
41
|
+
return response.data;
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
this.handleError(error);
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get list of supported chains
|
|
50
|
+
* @param options - Optional query parameters
|
|
51
|
+
* @param options.isActive - Filter by active status
|
|
52
|
+
* @param options.isCcipSupported - Filter by CCIP support
|
|
53
|
+
* @param options.chainId - Filter by specific chain ID
|
|
54
|
+
*/
|
|
55
|
+
async getSupportedChains(options) {
|
|
56
|
+
const params = {};
|
|
57
|
+
if (options?.isActive !== undefined) {
|
|
58
|
+
params.is_active = String(options.isActive);
|
|
59
|
+
}
|
|
60
|
+
if (options?.isCcipSupported !== undefined) {
|
|
61
|
+
params.is_ccip_supported = String(options.isCcipSupported);
|
|
62
|
+
}
|
|
63
|
+
if (options?.chainId !== undefined) {
|
|
64
|
+
params.chain_id = options.chainId;
|
|
65
|
+
}
|
|
66
|
+
const response = await this.get('api/chains', params);
|
|
67
|
+
return response.chains;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get list of supported assets
|
|
71
|
+
*/
|
|
72
|
+
async getAssetList(chainId) {
|
|
73
|
+
const response = await this.get('api/asset');
|
|
74
|
+
// Filter by chainId if provided
|
|
75
|
+
if (chainId !== undefined) {
|
|
76
|
+
return response.assets.filter(asset => asset.chainId === chainId);
|
|
77
|
+
}
|
|
78
|
+
return response.assets;
|
|
79
|
+
}
|
|
80
|
+
handleError(error) {
|
|
81
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
82
|
+
console.error('Bridge API Error:', error.response?.data || error.message);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
console.error('Unexpected Error:', error);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
exports.VoidAIBridgeClient = VoidAIBridgeClient;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { VoidAIBridgeClient } from '../api/client';
|
|
2
|
+
import { SignInResponse, RefreshTokenResponse } from '../types';
|
|
3
|
+
export declare class AuthSession {
|
|
4
|
+
private apiClient;
|
|
5
|
+
private accessToken;
|
|
6
|
+
private refreshToken;
|
|
7
|
+
private accessTokenWs;
|
|
8
|
+
private adminStatus;
|
|
9
|
+
constructor(apiClient: VoidAIBridgeClient);
|
|
10
|
+
/**
|
|
11
|
+
* Get nonce (signature) for wallet authentication
|
|
12
|
+
* @param wallet - Public key wallet address
|
|
13
|
+
*/
|
|
14
|
+
getNonce(wallet: string): Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Sign in with wallet
|
|
17
|
+
* @param publicKey - Wallet public key
|
|
18
|
+
* @param signature - Signed nonce
|
|
19
|
+
* @param chainId - Blockchain chain ID
|
|
20
|
+
*/
|
|
21
|
+
signIn(publicKey: string, signature: string, chainId: string): Promise<SignInResponse>;
|
|
22
|
+
/**
|
|
23
|
+
* Refresh access token using refresh token
|
|
24
|
+
*/
|
|
25
|
+
refreshAccessToken(): Promise<RefreshTokenResponse>;
|
|
26
|
+
/**
|
|
27
|
+
* Get current access token
|
|
28
|
+
*/
|
|
29
|
+
getAccessToken(): string | null;
|
|
30
|
+
/**
|
|
31
|
+
* Get current refresh token
|
|
32
|
+
*/
|
|
33
|
+
getRefreshToken(): string | null;
|
|
34
|
+
/**
|
|
35
|
+
* Get WebSocket access token
|
|
36
|
+
*/
|
|
37
|
+
getAccessTokenWs(): string | null;
|
|
38
|
+
/**
|
|
39
|
+
* Check if user is admin
|
|
40
|
+
*/
|
|
41
|
+
isAdmin(): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Check if user is authenticated
|
|
44
|
+
*/
|
|
45
|
+
isAuthenticated(): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Logout and clear session
|
|
48
|
+
*/
|
|
49
|
+
logout(): Promise<void>;
|
|
50
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AuthSession = void 0;
|
|
4
|
+
class AuthSession {
|
|
5
|
+
constructor(apiClient) {
|
|
6
|
+
this.accessToken = null;
|
|
7
|
+
this.refreshToken = null;
|
|
8
|
+
this.accessTokenWs = null;
|
|
9
|
+
this.adminStatus = false;
|
|
10
|
+
this.apiClient = apiClient;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Get nonce (signature) for wallet authentication
|
|
14
|
+
* @param wallet - Public key wallet address
|
|
15
|
+
*/
|
|
16
|
+
async getNonce(wallet) {
|
|
17
|
+
const response = await this.apiClient.post('/api/wallet/get-nonce', {
|
|
18
|
+
wallet,
|
|
19
|
+
});
|
|
20
|
+
return response.nonce;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Sign in with wallet
|
|
24
|
+
* @param publicKey - Wallet public key
|
|
25
|
+
* @param signature - Signed nonce
|
|
26
|
+
* @param chainId - Blockchain chain ID
|
|
27
|
+
*/
|
|
28
|
+
async signIn(publicKey, signature, chainId) {
|
|
29
|
+
const requestBody = {
|
|
30
|
+
publicKey,
|
|
31
|
+
signature,
|
|
32
|
+
chainId,
|
|
33
|
+
};
|
|
34
|
+
const response = await this.apiClient.post('/api/wallet/signin/wallet', requestBody);
|
|
35
|
+
// Store session data
|
|
36
|
+
this.accessToken = response.accessToken;
|
|
37
|
+
this.refreshToken = response.refreshToken;
|
|
38
|
+
this.accessTokenWs = response.accessTokenWs;
|
|
39
|
+
this.adminStatus = response.isAdmin;
|
|
40
|
+
// Update client with access token for future requests
|
|
41
|
+
this.apiClient.setAccessToken(response.accessToken);
|
|
42
|
+
return response;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Refresh access token using refresh token
|
|
46
|
+
*/
|
|
47
|
+
async refreshAccessToken() {
|
|
48
|
+
if (!this.refreshToken) {
|
|
49
|
+
throw new Error('VoidAI SDK: No refresh token available');
|
|
50
|
+
}
|
|
51
|
+
// Temporarily set refresh token as authorization
|
|
52
|
+
const previousToken = this.apiClient.getAccessToken();
|
|
53
|
+
this.apiClient.setAccessToken(this.refreshToken);
|
|
54
|
+
try {
|
|
55
|
+
const response = await this.apiClient.post('/api/wallet/refresh-token');
|
|
56
|
+
// Update stored tokens
|
|
57
|
+
this.accessToken = response.accessToken;
|
|
58
|
+
this.refreshToken = response.refreshToken;
|
|
59
|
+
// Update client with new access token
|
|
60
|
+
this.apiClient.setAccessToken(response.accessToken);
|
|
61
|
+
return response;
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
// Restore previous token on error
|
|
65
|
+
this.apiClient.setAccessToken(previousToken);
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get current access token
|
|
71
|
+
*/
|
|
72
|
+
getAccessToken() {
|
|
73
|
+
return this.accessToken;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get current refresh token
|
|
77
|
+
*/
|
|
78
|
+
getRefreshToken() {
|
|
79
|
+
return this.refreshToken;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get WebSocket access token
|
|
83
|
+
*/
|
|
84
|
+
getAccessTokenWs() {
|
|
85
|
+
return this.accessTokenWs;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Check if user is admin
|
|
89
|
+
*/
|
|
90
|
+
isAdmin() {
|
|
91
|
+
return this.adminStatus;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Check if user is authenticated
|
|
95
|
+
*/
|
|
96
|
+
isAuthenticated() {
|
|
97
|
+
return !!this.accessToken;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Logout and clear session
|
|
101
|
+
*/
|
|
102
|
+
async logout() {
|
|
103
|
+
this.accessToken = null;
|
|
104
|
+
this.refreshToken = null;
|
|
105
|
+
this.accessTokenWs = null;
|
|
106
|
+
this.adminStatus = false;
|
|
107
|
+
this.apiClient.setAccessToken(null);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
exports.AuthSession = AuthSession;
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BridgeSDKOptions, Environment } from './types';
|
|
2
|
+
export declare class BridgeConfig {
|
|
3
|
+
readonly apiKey: string;
|
|
4
|
+
readonly environment: Environment;
|
|
5
|
+
readonly baseUrl: string;
|
|
6
|
+
private static readonly DEFAULTS;
|
|
7
|
+
constructor(options: BridgeSDKOptions);
|
|
8
|
+
getBaseUrl(): string;
|
|
9
|
+
}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BridgeConfig = void 0;
|
|
4
|
+
class BridgeConfig {
|
|
5
|
+
constructor(options) {
|
|
6
|
+
if (!options.apiKey) {
|
|
7
|
+
throw new Error('BridgeSDK: apiKey is required');
|
|
8
|
+
}
|
|
9
|
+
this.apiKey = options.apiKey;
|
|
10
|
+
this.environment = options.environment || 'production';
|
|
11
|
+
// Ensure environment is valid, default to production if invalid
|
|
12
|
+
const validEnvironments = ['development', 'staging', 'production'];
|
|
13
|
+
if (!validEnvironments.includes(this.environment)) {
|
|
14
|
+
this.environment = 'production';
|
|
15
|
+
}
|
|
16
|
+
const defaults = BridgeConfig.DEFAULTS[this.environment];
|
|
17
|
+
// Allow custom base URL override
|
|
18
|
+
this.baseUrl = options.baseUrl || defaults.baseUrl;
|
|
19
|
+
}
|
|
20
|
+
getBaseUrl() {
|
|
21
|
+
return this.baseUrl;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.BridgeConfig = BridgeConfig;
|
|
25
|
+
BridgeConfig.DEFAULTS = {
|
|
26
|
+
development: {
|
|
27
|
+
baseUrl: 'https://api-dev.voidai.envistudios.com',
|
|
28
|
+
},
|
|
29
|
+
staging: {
|
|
30
|
+
baseUrl: 'https://api-staging.voidai.envistudios.com',
|
|
31
|
+
},
|
|
32
|
+
production: {
|
|
33
|
+
baseUrl: 'https://api.voidai.envistudios.com',
|
|
34
|
+
},
|
|
35
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { VoidAIBridgeClient } from '../api/client';
|
|
2
|
+
/**
|
|
3
|
+
* Bridge API Methods
|
|
4
|
+
* Provides read-only API methods for bridge operations
|
|
5
|
+
*/
|
|
6
|
+
export declare class Bridge {
|
|
7
|
+
private apiClient;
|
|
8
|
+
constructor(apiClient: VoidAIBridgeClient);
|
|
9
|
+
/**
|
|
10
|
+
* Get transaction status
|
|
11
|
+
*/
|
|
12
|
+
getTransactionStatus(txId: string): Promise<string>;
|
|
13
|
+
/**
|
|
14
|
+
* Get transaction history for an address
|
|
15
|
+
*/
|
|
16
|
+
getHistory(address: string): Promise<any[]>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Bridge = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Bridge API Methods
|
|
6
|
+
* Provides read-only API methods for bridge operations
|
|
7
|
+
*/
|
|
8
|
+
class Bridge {
|
|
9
|
+
constructor(apiClient) {
|
|
10
|
+
this.apiClient = apiClient;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Get transaction status
|
|
14
|
+
*/
|
|
15
|
+
async getTransactionStatus(txId) {
|
|
16
|
+
const { status } = await this.apiClient.get(`/transactions/${txId}/status`);
|
|
17
|
+
return status;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get transaction history for an address
|
|
21
|
+
*/
|
|
22
|
+
async getHistory(address) {
|
|
23
|
+
return this.apiClient.get(`/transactions/history/${address}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.Bridge = Bridge;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BridgeConfig } from './config';
|
|
2
|
+
import { VoidAIBridgeClient } from './api/client';
|
|
3
|
+
import { BittensorWallet } from './wallet/bittensor';
|
|
4
|
+
import { EthereumWallet } from './wallet/ethereum';
|
|
5
|
+
import { SolanaWallet } from './wallet/solana';
|
|
6
|
+
import { Bridge } from './core/bridge';
|
|
7
|
+
import { BridgeSDKOptions } from './types';
|
|
8
|
+
export * from './types';
|
|
9
|
+
export * from './config';
|
|
10
|
+
export * from './wallet/bittensor';
|
|
11
|
+
export * from './wallet/ethereum';
|
|
12
|
+
export * from './wallet/solana';
|
|
13
|
+
export declare class BridgeSDK {
|
|
14
|
+
readonly config: BridgeConfig;
|
|
15
|
+
readonly api: VoidAIBridgeClient;
|
|
16
|
+
readonly wallets: {
|
|
17
|
+
bittensor: BittensorWallet;
|
|
18
|
+
ethereum: EthereumWallet;
|
|
19
|
+
solana: SolanaWallet;
|
|
20
|
+
};
|
|
21
|
+
readonly bridge: Bridge;
|
|
22
|
+
constructor(options: BridgeSDKOptions);
|
|
23
|
+
/**
|
|
24
|
+
* Initialize the SDK
|
|
25
|
+
*/
|
|
26
|
+
init(): Promise<void>;
|
|
27
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.BridgeSDK = void 0;
|
|
18
|
+
const config_1 = require("./config");
|
|
19
|
+
const client_1 = require("./api/client");
|
|
20
|
+
const bittensor_1 = require("./wallet/bittensor");
|
|
21
|
+
const ethereum_1 = require("./wallet/ethereum");
|
|
22
|
+
const solana_1 = require("./wallet/solana");
|
|
23
|
+
const bridge_1 = require("./core/bridge");
|
|
24
|
+
__exportStar(require("./types"), exports);
|
|
25
|
+
__exportStar(require("./config"), exports);
|
|
26
|
+
__exportStar(require("./wallet/bittensor"), exports);
|
|
27
|
+
__exportStar(require("./wallet/ethereum"), exports);
|
|
28
|
+
__exportStar(require("./wallet/solana"), exports);
|
|
29
|
+
class BridgeSDK {
|
|
30
|
+
constructor(options) {
|
|
31
|
+
this.config = new config_1.BridgeConfig(options);
|
|
32
|
+
this.api = new client_1.VoidAIBridgeClient(this.config);
|
|
33
|
+
this.wallets = {
|
|
34
|
+
bittensor: new bittensor_1.BittensorWallet(),
|
|
35
|
+
ethereum: new ethereum_1.EthereumWallet(),
|
|
36
|
+
solana: new solana_1.SolanaWallet()
|
|
37
|
+
};
|
|
38
|
+
this.bridge = new bridge_1.Bridge(this.api);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Initialize the SDK
|
|
42
|
+
*/
|
|
43
|
+
async init() {
|
|
44
|
+
console.log('BridgeSDK initialized');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.BridgeSDK = BridgeSDK;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export type Environment = 'development' | 'production' | 'staging';
|
|
2
|
+
export interface BridgeSDKOptions {
|
|
3
|
+
apiKey: string;
|
|
4
|
+
environment?: Environment;
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface Chain {
|
|
8
|
+
id: number;
|
|
9
|
+
name: string;
|
|
10
|
+
chainId: string;
|
|
11
|
+
network: string;
|
|
12
|
+
isActive: boolean;
|
|
13
|
+
logoUri: string;
|
|
14
|
+
isCcipSupported: boolean;
|
|
15
|
+
ccipBridgeConfigurationStatus: string;
|
|
16
|
+
ccipChainSelector: string | null;
|
|
17
|
+
ccipRouterAddress: string | null;
|
|
18
|
+
ccipAdminRegistryContract: string | null;
|
|
19
|
+
ccipSupportedInBounds: string[];
|
|
20
|
+
ccipSupportedOutBounds: string[];
|
|
21
|
+
voidAiRouterAddress: string | null;
|
|
22
|
+
ccipRmnProxy?: string | null;
|
|
23
|
+
ccipRegistryModuleOwnerCustom?: string | null;
|
|
24
|
+
createdAt: string;
|
|
25
|
+
updatedAt: string;
|
|
26
|
+
}
|
|
27
|
+
export interface AssetBalance {
|
|
28
|
+
tokenAddress: string;
|
|
29
|
+
balance: string;
|
|
30
|
+
decimals: number;
|
|
31
|
+
formatted: string;
|
|
32
|
+
}
|
|
33
|
+
export interface Asset {
|
|
34
|
+
id: number;
|
|
35
|
+
chainId: string;
|
|
36
|
+
tokenName: string;
|
|
37
|
+
symbol: string;
|
|
38
|
+
decimal: number;
|
|
39
|
+
type: string;
|
|
40
|
+
tokenPoolAddress: string;
|
|
41
|
+
tokenPoolType: string;
|
|
42
|
+
tokenAddress: string;
|
|
43
|
+
isActive: boolean;
|
|
44
|
+
metadata: Record<string, any>;
|
|
45
|
+
subnetId: number;
|
|
46
|
+
createdAt: string;
|
|
47
|
+
updatedAt: string;
|
|
48
|
+
}
|
|
49
|
+
export interface ChainsApiResponse {
|
|
50
|
+
chains: Chain[];
|
|
51
|
+
}
|
|
52
|
+
export interface AssetsApiResponse {
|
|
53
|
+
assets: Asset[];
|
|
54
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isValidHash = exports.isValidAddress = void 0;
|
|
4
|
+
const isValidAddress = (address) => {
|
|
5
|
+
// Basic hex validation for generic blockchain address
|
|
6
|
+
return /^0x[a-fA-F0-9]{40,}$/.test(address);
|
|
7
|
+
};
|
|
8
|
+
exports.isValidAddress = isValidAddress;
|
|
9
|
+
const isValidHash = (hash) => {
|
|
10
|
+
return /^0x[a-fA-F0-9]{64}$/.test(hash);
|
|
11
|
+
};
|
|
12
|
+
exports.isValidHash = isValidHash;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bittensor Wallet Connection
|
|
3
|
+
* Handles connection to Bittensor-compatible wallets (Talisman, Subwallet, Polkadot.js)
|
|
4
|
+
*/
|
|
5
|
+
export interface BittensorAccount {
|
|
6
|
+
address: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
source: string;
|
|
9
|
+
}
|
|
10
|
+
export interface BittensorWalletExtension {
|
|
11
|
+
accounts: {
|
|
12
|
+
get: () => Promise<BittensorAccount[]>;
|
|
13
|
+
};
|
|
14
|
+
signer?: {
|
|
15
|
+
signRaw?: (options: {
|
|
16
|
+
address: string;
|
|
17
|
+
data: string;
|
|
18
|
+
}) => Promise<{
|
|
19
|
+
signature: string;
|
|
20
|
+
}>;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export declare class BittensorWallet {
|
|
24
|
+
private extension;
|
|
25
|
+
private account;
|
|
26
|
+
private extensionName;
|
|
27
|
+
/**
|
|
28
|
+
* Connect to a Bittensor-compatible wallet
|
|
29
|
+
* @param extensionName - Optional: specific extension name ('talisman', 'subwallet-js', 'polkadot-js')
|
|
30
|
+
* @returns Connected account information
|
|
31
|
+
*/
|
|
32
|
+
connect(extensionName?: string): Promise<BittensorAccount>;
|
|
33
|
+
/**
|
|
34
|
+
* Get currently connected account
|
|
35
|
+
*/
|
|
36
|
+
getAccount(): BittensorAccount | null;
|
|
37
|
+
/**
|
|
38
|
+
* Get extension name
|
|
39
|
+
*/
|
|
40
|
+
getExtensionName(): string | null;
|
|
41
|
+
/**
|
|
42
|
+
* Check if wallet is connected
|
|
43
|
+
*/
|
|
44
|
+
isConnected(): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Disconnect wallet
|
|
47
|
+
* Note: This only disconnects from the SDK. To fully disconnect from the extension,
|
|
48
|
+
* users need to disconnect accounts in their wallet extension settings.
|
|
49
|
+
*/
|
|
50
|
+
disconnect(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Check if wallet extension is available
|
|
53
|
+
*/
|
|
54
|
+
static isExtensionAvailable(extensionName?: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Get the wallet extension instance (for advanced usage)
|
|
57
|
+
*/
|
|
58
|
+
getExtension(): BittensorWalletExtension | null;
|
|
59
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Bittensor Wallet Connection
|
|
4
|
+
* Handles connection to Bittensor-compatible wallets (Talisman, Subwallet, Polkadot.js)
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.BittensorWallet = void 0;
|
|
8
|
+
class BittensorWallet {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.extension = null;
|
|
11
|
+
this.account = null;
|
|
12
|
+
this.extensionName = null;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Connect to a Bittensor-compatible wallet
|
|
16
|
+
* @param extensionName - Optional: specific extension name ('talisman', 'subwallet-js', 'polkadot-js')
|
|
17
|
+
* @returns Connected account information
|
|
18
|
+
*/
|
|
19
|
+
async connect(extensionName) {
|
|
20
|
+
// Check if running in browser environment
|
|
21
|
+
if (typeof window === 'undefined') {
|
|
22
|
+
throw new Error('BittensorWallet: Browser environment required for wallet connection');
|
|
23
|
+
}
|
|
24
|
+
// Check if any compatible extension is available
|
|
25
|
+
if (typeof window.injectedWeb3 === 'undefined') {
|
|
26
|
+
throw new Error('No compatible wallet extension found. Please install Talisman, Subwallet, or Polkadot.js extension.');
|
|
27
|
+
}
|
|
28
|
+
const injectedWeb3 = window.injectedWeb3;
|
|
29
|
+
const supportedExtensions = ['talisman', 'subwallet-js', 'polkadot-js'];
|
|
30
|
+
let targetExtension = null;
|
|
31
|
+
let selectedExtensionName = '';
|
|
32
|
+
// If specific extension requested, use it
|
|
33
|
+
if (extensionName && injectedWeb3[extensionName]) {
|
|
34
|
+
targetExtension = injectedWeb3[extensionName];
|
|
35
|
+
selectedExtensionName = extensionName;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
// Find the first available supported extension
|
|
39
|
+
for (const name of supportedExtensions) {
|
|
40
|
+
if (injectedWeb3[name]) {
|
|
41
|
+
targetExtension = injectedWeb3[name];
|
|
42
|
+
selectedExtensionName = name;
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Fallback: try to pick the first one available
|
|
47
|
+
if (!targetExtension) {
|
|
48
|
+
const available = Object.keys(injectedWeb3);
|
|
49
|
+
if (available.length > 0) {
|
|
50
|
+
selectedExtensionName = available[0];
|
|
51
|
+
targetExtension = injectedWeb3[selectedExtensionName];
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
throw new Error('No compatible wallet extension found.');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Request access to extension - this will trigger a popup for account authorization
|
|
59
|
+
let extension;
|
|
60
|
+
try {
|
|
61
|
+
extension = await targetExtension.enable('VoidAI Bridge SDK');
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
// Handle case where user rejects authorization or no accounts are authorized
|
|
65
|
+
if (error.message && error.message.includes('authorised')) {
|
|
66
|
+
throw new Error('No accounts are authorized. Please authorize accounts in your wallet extension and try again.');
|
|
67
|
+
}
|
|
68
|
+
throw new Error(`Failed to enable wallet extension: ${error.message || error}`);
|
|
69
|
+
}
|
|
70
|
+
if (!extension) {
|
|
71
|
+
throw new Error('Failed to enable wallet extension. Please try again.');
|
|
72
|
+
}
|
|
73
|
+
// Get all authorized accounts
|
|
74
|
+
let allAccounts;
|
|
75
|
+
try {
|
|
76
|
+
allAccounts = await extension.accounts.get();
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
throw new Error(`Failed to get accounts: ${error.message || error}`);
|
|
80
|
+
}
|
|
81
|
+
if (allAccounts.length === 0) {
|
|
82
|
+
throw new Error('No accounts found. Please authorize at least one account in your wallet extension and try again.');
|
|
83
|
+
}
|
|
84
|
+
// Store extension and use first account
|
|
85
|
+
this.extension = extension;
|
|
86
|
+
const account = allAccounts[0];
|
|
87
|
+
this.account = account;
|
|
88
|
+
this.extensionName = selectedExtensionName;
|
|
89
|
+
return account;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get currently connected account
|
|
93
|
+
*/
|
|
94
|
+
getAccount() {
|
|
95
|
+
return this.account;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get extension name
|
|
99
|
+
*/
|
|
100
|
+
getExtensionName() {
|
|
101
|
+
return this.extensionName;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Check if wallet is connected
|
|
105
|
+
*/
|
|
106
|
+
isConnected() {
|
|
107
|
+
return this.account !== null && this.extension !== null;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Disconnect wallet
|
|
111
|
+
* Note: This only disconnects from the SDK. To fully disconnect from the extension,
|
|
112
|
+
* users need to disconnect accounts in their wallet extension settings.
|
|
113
|
+
*/
|
|
114
|
+
disconnect() {
|
|
115
|
+
this.extension = null;
|
|
116
|
+
this.account = null;
|
|
117
|
+
this.extensionName = null;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Check if wallet extension is available
|
|
121
|
+
*/
|
|
122
|
+
static isExtensionAvailable(extensionName) {
|
|
123
|
+
if (typeof window === 'undefined') {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
const injectedWeb3 = window.injectedWeb3;
|
|
127
|
+
if (!injectedWeb3) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
if (extensionName) {
|
|
131
|
+
return !!injectedWeb3[extensionName];
|
|
132
|
+
}
|
|
133
|
+
const supportedExtensions = ['talisman', 'subwallet-js', 'polkadot-js'];
|
|
134
|
+
return supportedExtensions.some(name => !!injectedWeb3[name]) || Object.keys(injectedWeb3).length > 0;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Get the wallet extension instance (for advanced usage)
|
|
138
|
+
*/
|
|
139
|
+
getExtension() {
|
|
140
|
+
return this.extension;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
exports.BittensorWallet = BittensorWallet;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ethereum Wallet Connection (MetaMask)
|
|
3
|
+
*/
|
|
4
|
+
export interface EthereumAccount {
|
|
5
|
+
address: string;
|
|
6
|
+
chainId?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class EthereumWallet {
|
|
9
|
+
private account;
|
|
10
|
+
private chainId;
|
|
11
|
+
/**
|
|
12
|
+
* Check if MetaMask is installed
|
|
13
|
+
*/
|
|
14
|
+
static isMetaMaskInstalled(): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Connect to MetaMask wallet
|
|
17
|
+
* @returns Connected account information
|
|
18
|
+
*/
|
|
19
|
+
connect(): Promise<EthereumAccount>;
|
|
20
|
+
/**
|
|
21
|
+
* Get currently connected account
|
|
22
|
+
*/
|
|
23
|
+
getAccount(): EthereumAccount | null;
|
|
24
|
+
/**
|
|
25
|
+
* Get current chain ID
|
|
26
|
+
*/
|
|
27
|
+
getChainId(): string | null;
|
|
28
|
+
/**
|
|
29
|
+
* Check if wallet is connected
|
|
30
|
+
*/
|
|
31
|
+
isConnected(): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Disconnect wallet
|
|
34
|
+
*/
|
|
35
|
+
disconnect(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Get the ethereum provider (for advanced usage)
|
|
38
|
+
*/
|
|
39
|
+
getProvider(): any;
|
|
40
|
+
private handleAccountsChanged;
|
|
41
|
+
private handleChainChanged;
|
|
42
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Ethereum Wallet Connection (MetaMask)
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.EthereumWallet = void 0;
|
|
7
|
+
class EthereumWallet {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.account = null;
|
|
10
|
+
this.chainId = null;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Check if MetaMask is installed
|
|
14
|
+
*/
|
|
15
|
+
static isMetaMaskInstalled() {
|
|
16
|
+
if (typeof window === 'undefined') {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return typeof window.ethereum !== 'undefined' && window.ethereum.isMetaMask;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Connect to MetaMask wallet
|
|
23
|
+
* @returns Connected account information
|
|
24
|
+
*/
|
|
25
|
+
async connect() {
|
|
26
|
+
if (typeof window === 'undefined') {
|
|
27
|
+
throw new Error('EthereumWallet: Browser environment required');
|
|
28
|
+
}
|
|
29
|
+
if (!EthereumWallet.isMetaMaskInstalled()) {
|
|
30
|
+
throw new Error('MetaMask is not installed. Please install MetaMask extension from https://metamask.io/');
|
|
31
|
+
}
|
|
32
|
+
const ethereum = window.ethereum;
|
|
33
|
+
try {
|
|
34
|
+
// Request account access - this will trigger MetaMask popup
|
|
35
|
+
const accounts = await ethereum.request({ method: 'eth_requestAccounts' });
|
|
36
|
+
if (!accounts || accounts.length === 0) {
|
|
37
|
+
throw new Error('No accounts found. Please unlock MetaMask and try again.');
|
|
38
|
+
}
|
|
39
|
+
// Get chain ID
|
|
40
|
+
const chainId = await ethereum.request({ method: 'eth_chainId' });
|
|
41
|
+
this.account = {
|
|
42
|
+
address: accounts[0],
|
|
43
|
+
chainId: chainId
|
|
44
|
+
};
|
|
45
|
+
this.chainId = chainId;
|
|
46
|
+
// Listen for account changes
|
|
47
|
+
ethereum.on('accountsChanged', this.handleAccountsChanged.bind(this));
|
|
48
|
+
ethereum.on('chainChanged', this.handleChainChanged.bind(this));
|
|
49
|
+
return this.account;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
if (error.code === 4001) {
|
|
53
|
+
throw new Error('User rejected the connection request');
|
|
54
|
+
}
|
|
55
|
+
throw new Error(`Failed to connect to MetaMask: ${error.message || error}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get currently connected account
|
|
60
|
+
*/
|
|
61
|
+
getAccount() {
|
|
62
|
+
return this.account;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get current chain ID
|
|
66
|
+
*/
|
|
67
|
+
getChainId() {
|
|
68
|
+
return this.chainId;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Check if wallet is connected
|
|
72
|
+
*/
|
|
73
|
+
isConnected() {
|
|
74
|
+
return this.account !== null;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Disconnect wallet
|
|
78
|
+
*/
|
|
79
|
+
disconnect() {
|
|
80
|
+
this.account = null;
|
|
81
|
+
this.chainId = null;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get the ethereum provider (for advanced usage)
|
|
85
|
+
*/
|
|
86
|
+
getProvider() {
|
|
87
|
+
if (typeof window === 'undefined') {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
return window.ethereum;
|
|
91
|
+
}
|
|
92
|
+
handleAccountsChanged(accounts) {
|
|
93
|
+
if (accounts.length === 0) {
|
|
94
|
+
this.disconnect();
|
|
95
|
+
}
|
|
96
|
+
else if (this.account && accounts[0] !== this.account.address) {
|
|
97
|
+
this.account.address = accounts[0];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
handleChainChanged(chainId) {
|
|
101
|
+
this.chainId = chainId;
|
|
102
|
+
if (this.account) {
|
|
103
|
+
this.account.chainId = chainId;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.EthereumWallet = EthereumWallet;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Solana Wallet Connection (Phantom)
|
|
3
|
+
*/
|
|
4
|
+
export interface SolanaAccount {
|
|
5
|
+
address: string;
|
|
6
|
+
publicKey: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class SolanaWallet {
|
|
9
|
+
private account;
|
|
10
|
+
/**
|
|
11
|
+
* Check if Phantom is installed
|
|
12
|
+
*/
|
|
13
|
+
static isPhantomInstalled(): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Connect to Phantom wallet
|
|
16
|
+
* @returns Connected account information
|
|
17
|
+
*/
|
|
18
|
+
connect(): Promise<SolanaAccount>;
|
|
19
|
+
/**
|
|
20
|
+
* Get currently connected account
|
|
21
|
+
*/
|
|
22
|
+
getAccount(): SolanaAccount | null;
|
|
23
|
+
/**
|
|
24
|
+
* Check if wallet is connected
|
|
25
|
+
*/
|
|
26
|
+
isConnected(): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Disconnect wallet
|
|
29
|
+
*/
|
|
30
|
+
disconnect(): void;
|
|
31
|
+
/**
|
|
32
|
+
* Get the Solana provider (for advanced usage)
|
|
33
|
+
*/
|
|
34
|
+
getProvider(): any;
|
|
35
|
+
private handleDisconnect;
|
|
36
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Solana Wallet Connection (Phantom)
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SolanaWallet = void 0;
|
|
7
|
+
class SolanaWallet {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.account = null;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Check if Phantom is installed
|
|
13
|
+
*/
|
|
14
|
+
static isPhantomInstalled() {
|
|
15
|
+
if (typeof window === 'undefined') {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
return typeof window.solana !== 'undefined' && window.solana.isPhantom;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Connect to Phantom wallet
|
|
22
|
+
* @returns Connected account information
|
|
23
|
+
*/
|
|
24
|
+
async connect() {
|
|
25
|
+
if (typeof window === 'undefined') {
|
|
26
|
+
throw new Error('SolanaWallet: Browser environment required');
|
|
27
|
+
}
|
|
28
|
+
if (!SolanaWallet.isPhantomInstalled()) {
|
|
29
|
+
throw new Error('Phantom is not installed. Please install Phantom extension from https://phantom.app/');
|
|
30
|
+
}
|
|
31
|
+
const solana = window.solana;
|
|
32
|
+
try {
|
|
33
|
+
// Request connection - this will trigger Phantom popup
|
|
34
|
+
const response = await solana.connect();
|
|
35
|
+
if (!response || !response.publicKey) {
|
|
36
|
+
throw new Error('Failed to connect to Phantom wallet');
|
|
37
|
+
}
|
|
38
|
+
this.account = {
|
|
39
|
+
address: response.publicKey.toString(),
|
|
40
|
+
publicKey: response.publicKey.toString()
|
|
41
|
+
};
|
|
42
|
+
// Listen for disconnect
|
|
43
|
+
solana.on('disconnect', this.handleDisconnect.bind(this));
|
|
44
|
+
return this.account;
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
if (error.code === 4001) {
|
|
48
|
+
throw new Error('User rejected the connection request');
|
|
49
|
+
}
|
|
50
|
+
throw new Error(`Failed to connect to Phantom: ${error.message || error}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get currently connected account
|
|
55
|
+
*/
|
|
56
|
+
getAccount() {
|
|
57
|
+
return this.account;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Check if wallet is connected
|
|
61
|
+
*/
|
|
62
|
+
isConnected() {
|
|
63
|
+
return this.account !== null;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Disconnect wallet
|
|
67
|
+
*/
|
|
68
|
+
disconnect() {
|
|
69
|
+
if (this.account && typeof window !== 'undefined') {
|
|
70
|
+
const solana = window.solana;
|
|
71
|
+
if (solana && solana.disconnect && typeof solana.disconnect === 'function') {
|
|
72
|
+
try {
|
|
73
|
+
const disconnectResult = solana.disconnect();
|
|
74
|
+
if (disconnectResult && typeof disconnectResult.catch === 'function') {
|
|
75
|
+
disconnectResult.catch(() => {
|
|
76
|
+
// Ignore disconnect errors
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
// Ignore disconnect errors
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
this.account = null;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get the Solana provider (for advanced usage)
|
|
89
|
+
*/
|
|
90
|
+
getProvider() {
|
|
91
|
+
if (typeof window === 'undefined') {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
return window.solana;
|
|
95
|
+
}
|
|
96
|
+
handleDisconnect() {
|
|
97
|
+
this.disconnect();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.SolanaWallet = SolanaWallet;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! For license information please see voidai-sdk.js.LICENSE.txt */
|
|
2
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.VoidAISDK=t():e.VoidAISDK=t()}(this,()=>(()=>{"use strict";var e={28:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.BridgeConfig=void 0;class n{constructor(e){if(!e.apiKey)throw new Error("BridgeSDK: apiKey is required");this.apiKey=e.apiKey,this.environment=e.environment||"production",["development","staging","production"].includes(this.environment)||(this.environment="production");const t=n.DEFAULTS[this.environment];this.baseUrl=e.baseUrl||t.baseUrl}getBaseUrl(){return this.baseUrl}}t.BridgeConfig=n,n.DEFAULTS={development:{baseUrl:"https://api-dev.voidai.envistudios.com"},staging:{baseUrl:"https://api-staging.voidai.envistudios.com"},production:{baseUrl:"https://api.voidai.envistudios.com"}}},156:function(e,t,n){var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var o=Object.getOwnPropertyDescriptor(t,n);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,o)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),o=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||r(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),t.BridgeSDK=void 0;const i=n(28),s=n(436),a=n(570),c=n(967),l=n(318),u=n(925);o(n(574),t),o(n(28),t),o(n(570),t),o(n(967),t),o(n(318),t),t.BridgeSDK=class{constructor(e){this.config=new i.BridgeConfig(e),this.api=new s.VoidAIBridgeClient(this.config),this.wallets={bittensor:new a.BittensorWallet,ethereum:new c.EthereumWallet,solana:new l.SolanaWallet},this.bridge=new u.Bridge(this.api)}async init(){console.log("BridgeSDK initialized")}}},318:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.SolanaWallet=void 0;class n{constructor(){this.account=null}static isPhantomInstalled(){return"undefined"!=typeof window&&void 0!==window.solana&&window.solana.isPhantom}async connect(){if("undefined"==typeof window)throw new Error("SolanaWallet: Browser environment required");if(!n.isPhantomInstalled())throw new Error("Phantom is not installed. Please install Phantom extension from https://phantom.app/");const e=window.solana;try{const t=await e.connect();if(!t||!t.publicKey)throw new Error("Failed to connect to Phantom wallet");return this.account={address:t.publicKey.toString(),publicKey:t.publicKey.toString()},e.on("disconnect",this.handleDisconnect.bind(this)),this.account}catch(e){if(4001===e.code)throw new Error("User rejected the connection request");throw new Error(`Failed to connect to Phantom: ${e.message||e}`)}}getAccount(){return this.account}isConnected(){return null!==this.account}disconnect(){if(this.account&&"undefined"!=typeof window){const e=window.solana;if(e&&e.disconnect&&"function"==typeof e.disconnect)try{const t=e.disconnect();t&&"function"==typeof t.catch&&t.catch(()=>{})}catch(e){}}this.account=null}getProvider(){return"undefined"==typeof window?null:window.solana}handleDisconnect(){this.disconnect()}}t.SolanaWallet=n},425:(e,t,n)=>{function r(e,t){return function(){return e.apply(t,arguments)}}const{toString:o}=Object.prototype,{getPrototypeOf:i}=Object,{iterator:s,toStringTag:a}=Symbol,c=(l=Object.create(null),e=>{const t=o.call(e);return l[t]||(l[t]=t.slice(8,-1).toLowerCase())});var l;const u=e=>(e=e.toLowerCase(),t=>c(t)===e),d=e=>t=>typeof t===e,{isArray:f}=Array,h=d("undefined");function p(e){return null!==e&&!h(e)&&null!==e.constructor&&!h(e.constructor)&&g(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}const m=u("ArrayBuffer"),w=d("string"),g=d("function"),y=d("number"),b=e=>null!==e&&"object"==typeof e,E=e=>{if("object"!==c(e))return!1;const t=i(e);return!(null!==t&&t!==Object.prototype&&null!==Object.getPrototypeOf(t)||a in e||s in e)},O=u("Date"),v=u("File"),S=u("Blob"),R=u("FileList"),A=u("URLSearchParams"),[T,x,j,C]=["ReadableStream","Request","Response","Headers"].map(u);function P(e,t,{allOwnKeys:n=!1}={}){if(null==e)return;let r,o;if("object"!=typeof e&&(e=[e]),f(e))for(r=0,o=e.length;r<o;r++)t.call(null,e[r],r,e);else{if(p(e))return;const o=n?Object.getOwnPropertyNames(e):Object.keys(e),i=o.length;let s;for(r=0;r<i;r++)s=o[r],t.call(null,e[s],s,e)}}function _(e,t){if(p(e))return null;t=t.toLowerCase();const n=Object.keys(e);let r,o=n.length;for(;o-- >0;)if(r=n[o],t===r.toLowerCase())return r;return null}const U="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:n.g,N=e=>!h(e)&&e!==U,B=(k="undefined"!=typeof Uint8Array&&i(Uint8Array),e=>k&&e instanceof k);var k;const F=u("HTMLFormElement"),L=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),D=u("RegExp"),I=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),r={};P(n,(n,o)=>{let i;!1!==(i=t(n,o,e))&&(r[o]=i||n)}),Object.defineProperties(e,r)},M=u("AsyncFunction"),q=(W="function"==typeof setImmediate,z=g(U.postMessage),W?setImmediate:z?(K=`axios@${Math.random()}`,$=[],U.addEventListener("message",({source:e,data:t})=>{e===U&&t===K&&$.length&&$.shift()()},!1),e=>{$.push(e),U.postMessage(K,"*")}):e=>setTimeout(e));var W,z,K,$;const H="undefined"!=typeof queueMicrotask?queueMicrotask.bind(U):"undefined"!=typeof process&&process.nextTick||q;var V={isArray:f,isArrayBuffer:m,isBuffer:p,isFormData:e=>{let t;return e&&("function"==typeof FormData&&e instanceof FormData||g(e.append)&&("formdata"===(t=c(e))||"object"===t&&g(e.toString)&&"[object FormData]"===e.toString()))},isArrayBufferView:function(e){let t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&m(e.buffer),t},isString:w,isNumber:y,isBoolean:e=>!0===e||!1===e,isObject:b,isPlainObject:E,isEmptyObject:e=>{if(!b(e)||p(e))return!1;try{return 0===Object.keys(e).length&&Object.getPrototypeOf(e)===Object.prototype}catch(e){return!1}},isReadableStream:T,isRequest:x,isResponse:j,isHeaders:C,isUndefined:h,isDate:O,isFile:v,isBlob:S,isRegExp:D,isFunction:g,isStream:e=>b(e)&&g(e.pipe),isURLSearchParams:A,isTypedArray:B,isFileList:R,forEach:P,merge:function e(){const{caseless:t,skipUndefined:n}=N(this)&&this||{},r={},o=(o,i)=>{const s=t&&_(r,i)||i;E(r[s])&&E(o)?r[s]=e(r[s],o):E(o)?r[s]=e({},o):f(o)?r[s]=o.slice():n&&h(o)||(r[s]=o)};for(let e=0,t=arguments.length;e<t;e++)arguments[e]&&P(arguments[e],o);return r},extend:(e,t,n,{allOwnKeys:o}={})=>(P(t,(t,o)=>{n&&g(t)?e[o]=r(t,n):e[o]=t},{allOwnKeys:o}),e),trim:e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),stripBOM:e=>(65279===e.charCodeAt(0)&&(e=e.slice(1)),e),inherits:(e,t,n,r)=>{e.prototype=Object.create(t.prototype,r),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},toFlatObject:(e,t,n,r)=>{let o,s,a;const c={};if(t=t||{},null==e)return t;do{for(o=Object.getOwnPropertyNames(e),s=o.length;s-- >0;)a=o[s],r&&!r(a,e,t)||c[a]||(t[a]=e[a],c[a]=!0);e=!1!==n&&i(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},kindOf:c,kindOfTest:u,endsWith:(e,t,n)=>{e=String(e),(void 0===n||n>e.length)&&(n=e.length),n-=t.length;const r=e.indexOf(t,n);return-1!==r&&r===n},toArray:e=>{if(!e)return null;if(f(e))return e;let t=e.length;if(!y(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},forEachEntry:(e,t)=>{const n=(e&&e[s]).call(e);let r;for(;(r=n.next())&&!r.done;){const n=r.value;t.call(e,n[0],n[1])}},matchAll:(e,t)=>{let n;const r=[];for(;null!==(n=e.exec(t));)r.push(n);return r},isHTMLForm:F,hasOwnProperty:L,hasOwnProp:L,reduceDescriptors:I,freezeMethods:e=>{I(e,(t,n)=>{if(g(e)&&-1!==["arguments","caller","callee"].indexOf(n))return!1;const r=e[n];g(r)&&(t.enumerable=!1,"writable"in t?t.writable=!1:t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")}))})},toObjectSet:(e,t)=>{const n={},r=e=>{e.forEach(e=>{n[e]=!0})};return f(e)?r(e):r(String(e).split(t)),n},toCamelCase:e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(e,t,n){return t.toUpperCase()+n}),noop:()=>{},toFiniteNumber:(e,t)=>null!=e&&Number.isFinite(e=+e)?e:t,findKey:_,global:U,isContextDefined:N,isSpecCompliantForm:function(e){return!!(e&&g(e.append)&&"FormData"===e[a]&&e[s])},toJSONObject:e=>{const t=new Array(10),n=(e,r)=>{if(b(e)){if(t.indexOf(e)>=0)return;if(p(e))return e;if(!("toJSON"in e)){t[r]=e;const o=f(e)?[]:{};return P(e,(e,t)=>{const i=n(e,r+1);!h(i)&&(o[t]=i)}),t[r]=void 0,o}}return e};return n(e,0)},isAsyncFn:M,isThenable:e=>e&&(b(e)||g(e))&&g(e.then)&&g(e.catch),setImmediate:q,asap:H,isIterable:e=>null!=e&&g(e[s])};function J(e,t,n,r,o){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack,this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),r&&(this.request=r),o&&(this.response=o,this.status=o.status?o.status:null)}V.inherits(J,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:V.toJSONObject(this.config),code:this.code,status:this.status}}});const X=J.prototype,G={};function Q(e){return V.isPlainObject(e)||V.isArray(e)}function Z(e){return V.endsWith(e,"[]")?e.slice(0,-2):e}function Y(e,t,n){return e?e.concat(t).map(function(e,t){return e=Z(e),!n&&t?"["+e+"]":e}).join(n?".":""):t}["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach(e=>{G[e]={value:e}}),Object.defineProperties(J,G),Object.defineProperty(X,"isAxiosError",{value:!0}),J.from=(e,t,n,r,o,i)=>{const s=Object.create(X);V.toFlatObject(e,s,function(e){return e!==Error.prototype},e=>"isAxiosError"!==e);const a=e&&e.message?e.message:"Error",c=null==t&&e?e.code:t;return J.call(s,a,c,n,r,o),e&&null==s.cause&&Object.defineProperty(s,"cause",{value:e,configurable:!0}),s.name=e&&e.name||"Error",i&&Object.assign(s,i),s};const ee=V.toFlatObject(V,{},null,function(e){return/^is[A-Z]/.test(e)});function te(e,t,n){if(!V.isObject(e))throw new TypeError("target must be an object");t=t||new FormData;const r=(n=V.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(e,t){return!V.isUndefined(t[e])})).metaTokens,o=n.visitor||l,i=n.dots,s=n.indexes,a=(n.Blob||"undefined"!=typeof Blob&&Blob)&&V.isSpecCompliantForm(t);if(!V.isFunction(o))throw new TypeError("visitor must be a function");function c(e){if(null===e)return"";if(V.isDate(e))return e.toISOString();if(V.isBoolean(e))return e.toString();if(!a&&V.isBlob(e))throw new J("Blob is not supported. Use a Buffer instead.");return V.isArrayBuffer(e)||V.isTypedArray(e)?a&&"function"==typeof Blob?new Blob([e]):Buffer.from(e):e}function l(e,n,o){let a=e;if(e&&!o&&"object"==typeof e)if(V.endsWith(n,"{}"))n=r?n:n.slice(0,-2),e=JSON.stringify(e);else if(V.isArray(e)&&function(e){return V.isArray(e)&&!e.some(Q)}(e)||(V.isFileList(e)||V.endsWith(n,"[]"))&&(a=V.toArray(e)))return n=Z(n),a.forEach(function(e,r){!V.isUndefined(e)&&null!==e&&t.append(!0===s?Y([n],r,i):null===s?n:n+"[]",c(e))}),!1;return!!Q(e)||(t.append(Y(o,n,i),c(e)),!1)}const u=[],d=Object.assign(ee,{defaultVisitor:l,convertValue:c,isVisitable:Q});if(!V.isObject(e))throw new TypeError("data must be an object");return function e(n,r){if(!V.isUndefined(n)){if(-1!==u.indexOf(n))throw Error("Circular reference detected in "+r.join("."));u.push(n),V.forEach(n,function(n,i){!0===(!(V.isUndefined(n)||null===n)&&o.call(t,n,V.isString(i)?i.trim():i,r,d))&&e(n,r?r.concat(i):[i])}),u.pop()}}(e),t}function ne(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,function(e){return t[e]})}function re(e,t){this._pairs=[],e&&te(e,this,t)}const oe=re.prototype;function ie(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+")}function se(e,t,n){if(!t)return e;const r=n&&n.encode||ie;V.isFunction(n)&&(n={serialize:n});const o=n&&n.serialize;let i;if(i=o?o(t,n):V.isURLSearchParams(t)?t.toString():new re(t,n).toString(r),i){const t=e.indexOf("#");-1!==t&&(e=e.slice(0,t)),e+=(-1===e.indexOf("?")?"?":"&")+i}return e}oe.append=function(e,t){this._pairs.push([e,t])},oe.toString=function(e){const t=e?function(t){return e.call(this,t,ne)}:ne;return this._pairs.map(function(e){return t(e[0])+"="+t(e[1])},"").join("&")};var ae=class{constructor(){this.handlers=[]}use(e,t,n){return this.handlers.push({fulfilled:e,rejected:t,synchronous:!!n&&n.synchronous,runWhen:n?n.runWhen:null}),this.handlers.length-1}eject(e){this.handlers[e]&&(this.handlers[e]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(e){V.forEach(this.handlers,function(t){null!==t&&e(t)})}},ce={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},le={isBrowser:!0,classes:{URLSearchParams:"undefined"!=typeof URLSearchParams?URLSearchParams:re,FormData:"undefined"!=typeof FormData?FormData:null,Blob:"undefined"!=typeof Blob?Blob:null},protocols:["http","https","file","blob","url","data"]};const ue="undefined"!=typeof window&&"undefined"!=typeof document,de="object"==typeof navigator&&navigator||void 0,fe=ue&&(!de||["ReactNative","NativeScript","NS"].indexOf(de.product)<0),he="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&"function"==typeof self.importScripts,pe=ue&&window.location.href||"http://localhost";var me={...Object.freeze({__proto__:null,hasBrowserEnv:ue,hasStandardBrowserWebWorkerEnv:he,hasStandardBrowserEnv:fe,navigator:de,origin:pe}),...le};function we(e){function t(e,n,r,o){let i=e[o++];if("__proto__"===i)return!0;const s=Number.isFinite(+i),a=o>=e.length;return i=!i&&V.isArray(r)?r.length:i,a?(V.hasOwnProp(r,i)?r[i]=[r[i],n]:r[i]=n,!s):(r[i]&&V.isObject(r[i])||(r[i]=[]),t(e,n,r[i],o)&&V.isArray(r[i])&&(r[i]=function(e){const t={},n=Object.keys(e);let r;const o=n.length;let i;for(r=0;r<o;r++)i=n[r],t[i]=e[i];return t}(r[i])),!s)}if(V.isFormData(e)&&V.isFunction(e.entries)){const n={};return V.forEachEntry(e,(e,r)=>{t(function(e){return V.matchAll(/\w+|\[(\w*)]/g,e).map(e=>"[]"===e[0]?"":e[1]||e[0])}(e),r,n,0)}),n}return null}const ge={transitional:ce,adapter:["xhr","http","fetch"],transformRequest:[function(e,t){const n=t.getContentType()||"",r=n.indexOf("application/json")>-1,o=V.isObject(e);if(o&&V.isHTMLForm(e)&&(e=new FormData(e)),V.isFormData(e))return r?JSON.stringify(we(e)):e;if(V.isArrayBuffer(e)||V.isBuffer(e)||V.isStream(e)||V.isFile(e)||V.isBlob(e)||V.isReadableStream(e))return e;if(V.isArrayBufferView(e))return e.buffer;if(V.isURLSearchParams(e))return t.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),e.toString();let i;if(o){if(n.indexOf("application/x-www-form-urlencoded")>-1)return function(e,t){return te(e,new me.classes.URLSearchParams,{visitor:function(e,t,n,r){return me.isNode&&V.isBuffer(e)?(this.append(t,e.toString("base64")),!1):r.defaultVisitor.apply(this,arguments)},...t})}(e,this.formSerializer).toString();if((i=V.isFileList(e))||n.indexOf("multipart/form-data")>-1){const t=this.env&&this.env.FormData;return te(i?{"files[]":e}:e,t&&new t,this.formSerializer)}}return o||r?(t.setContentType("application/json",!1),function(e){if(V.isString(e))try{return(0,JSON.parse)(e),V.trim(e)}catch(e){if("SyntaxError"!==e.name)throw e}return(0,JSON.stringify)(e)}(e)):e}],transformResponse:[function(e){const t=this.transitional||ge.transitional,n=t&&t.forcedJSONParsing,r="json"===this.responseType;if(V.isResponse(e)||V.isReadableStream(e))return e;if(e&&V.isString(e)&&(n&&!this.responseType||r)){const n=!(t&&t.silentJSONParsing)&&r;try{return JSON.parse(e,this.parseReviver)}catch(e){if(n){if("SyntaxError"===e.name)throw J.from(e,J.ERR_BAD_RESPONSE,this,null,this.response);throw e}}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:me.classes.FormData,Blob:me.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};V.forEach(["delete","get","head","post","put","patch"],e=>{ge.headers[e]={}});var ye=ge;const be=V.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),Ee=Symbol("internals");function Oe(e){return e&&String(e).trim().toLowerCase()}function ve(e){return!1===e||null==e?e:V.isArray(e)?e.map(ve):String(e)}function Se(e,t,n,r,o){return V.isFunction(r)?r.call(this,t,n):(o&&(t=n),V.isString(t)?V.isString(r)?-1!==t.indexOf(r):V.isRegExp(r)?r.test(t):void 0:void 0)}class Re{constructor(e){e&&this.set(e)}set(e,t,n){const r=this;function o(e,t,n){const o=Oe(t);if(!o)throw new Error("header name must be a non-empty string");const i=V.findKey(r,o);(!i||void 0===r[i]||!0===n||void 0===n&&!1!==r[i])&&(r[i||t]=ve(e))}const i=(e,t)=>V.forEach(e,(e,n)=>o(e,n,t));if(V.isPlainObject(e)||e instanceof this.constructor)i(e,t);else if(V.isString(e)&&(e=e.trim())&&!/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim()))i((e=>{const t={};let n,r,o;return e&&e.split("\n").forEach(function(e){o=e.indexOf(":"),n=e.substring(0,o).trim().toLowerCase(),r=e.substring(o+1).trim(),!n||t[n]&&be[n]||("set-cookie"===n?t[n]?t[n].push(r):t[n]=[r]:t[n]=t[n]?t[n]+", "+r:r)}),t})(e),t);else if(V.isObject(e)&&V.isIterable(e)){let n,r,o={};for(const t of e){if(!V.isArray(t))throw TypeError("Object iterator must return a key-value pair");o[r=t[0]]=(n=o[r])?V.isArray(n)?[...n,t[1]]:[n,t[1]]:t[1]}i(o,t)}else null!=e&&o(t,e,n);return this}get(e,t){if(e=Oe(e)){const n=V.findKey(this,e);if(n){const e=this[n];if(!t)return e;if(!0===t)return function(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=n.exec(e);)t[r[1]]=r[2];return t}(e);if(V.isFunction(t))return t.call(this,e,n);if(V.isRegExp(t))return t.exec(e);throw new TypeError("parser must be boolean|regexp|function")}}}has(e,t){if(e=Oe(e)){const n=V.findKey(this,e);return!(!n||void 0===this[n]||t&&!Se(0,this[n],n,t))}return!1}delete(e,t){const n=this;let r=!1;function o(e){if(e=Oe(e)){const o=V.findKey(n,e);!o||t&&!Se(0,n[o],o,t)||(delete n[o],r=!0)}}return V.isArray(e)?e.forEach(o):o(e),r}clear(e){const t=Object.keys(this);let n=t.length,r=!1;for(;n--;){const o=t[n];e&&!Se(0,this[o],o,e,!0)||(delete this[o],r=!0)}return r}normalize(e){const t=this,n={};return V.forEach(this,(r,o)=>{const i=V.findKey(n,o);if(i)return t[i]=ve(r),void delete t[o];const s=e?function(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(e,t,n)=>t.toUpperCase()+n)}(o):String(o).trim();s!==o&&delete t[o],t[s]=ve(r),n[s]=!0}),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){const t=Object.create(null);return V.forEach(this,(n,r)=>{null!=n&&!1!==n&&(t[r]=e&&V.isArray(n)?n.join(", "):n)}),t}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([e,t])=>e+": "+t).join("\n")}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...t){const n=new this(e);return t.forEach(e=>n.set(e)),n}static accessor(e){const t=(this[Ee]=this[Ee]={accessors:{}}).accessors,n=this.prototype;function r(e){const r=Oe(e);t[r]||(function(e,t){const n=V.toCamelCase(" "+t);["get","set","has"].forEach(r=>{Object.defineProperty(e,r+n,{value:function(e,n,o){return this[r].call(this,t,e,n,o)},configurable:!0})})}(n,e),t[r]=!0)}return V.isArray(e)?e.forEach(r):r(e),this}}Re.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),V.reduceDescriptors(Re.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(e){this[n]=e}}}),V.freezeMethods(Re);var Ae=Re;function Te(e,t){const n=this||ye,r=t||n,o=Ae.from(r.headers);let i=r.data;return V.forEach(e,function(e){i=e.call(n,i,o.normalize(),t?t.status:void 0)}),o.normalize(),i}function xe(e){return!(!e||!e.__CANCEL__)}function je(e,t,n){J.call(this,null==e?"canceled":e,J.ERR_CANCELED,t,n),this.name="CanceledError"}function Ce(e,t,n){const r=n.config.validateStatus;n.status&&r&&!r(n.status)?t(new J("Request failed with status code "+n.status,[J.ERR_BAD_REQUEST,J.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n)):e(n)}V.inherits(je,J,{__CANCEL__:!0});const Pe=(e,t,n=3)=>{let r=0;const o=function(e,t){e=e||10;const n=new Array(e),r=new Array(e);let o,i=0,s=0;return t=void 0!==t?t:1e3,function(a){const c=Date.now(),l=r[s];o||(o=c),n[i]=a,r[i]=c;let u=s,d=0;for(;u!==i;)d+=n[u++],u%=e;if(i=(i+1)%e,i===s&&(s=(s+1)%e),c-o<t)return;const f=l&&c-l;return f?Math.round(1e3*d/f):void 0}}(50,250);return function(n,i){let s,a,c=0,l=1e3/i;const u=(n,i=Date.now())=>{c=i,s=null,a&&(clearTimeout(a),a=null),(n=>{const i=n.loaded,s=n.lengthComputable?n.total:void 0,a=i-r,c=o(a);r=i,e({loaded:i,total:s,progress:s?i/s:void 0,bytes:a,rate:c||void 0,estimated:c&&s&&i<=s?(s-i)/c:void 0,event:n,lengthComputable:null!=s,[t?"download":"upload"]:!0})})(...n)};return[(...e)=>{const t=Date.now(),n=t-c;n>=l?u(e,t):(s=e,a||(a=setTimeout(()=>{a=null,u(s)},l-n)))},()=>s&&u(s)]}(0,n)},_e=(e,t)=>{const n=null!=e;return[r=>t[0]({lengthComputable:n,total:e,loaded:r}),t[1]]},Ue=e=>(...t)=>V.asap(()=>e(...t));var Ne=me.hasStandardBrowserEnv?((e,t)=>n=>(n=new URL(n,me.origin),e.protocol===n.protocol&&e.host===n.host&&(t||e.port===n.port)))(new URL(me.origin),me.navigator&&/(msie|trident)/i.test(me.navigator.userAgent)):()=>!0,Be=me.hasStandardBrowserEnv?{write(e,t,n,r,o,i,s){if("undefined"==typeof document)return;const a=[`${e}=${encodeURIComponent(t)}`];V.isNumber(n)&&a.push(`expires=${new Date(n).toUTCString()}`),V.isString(r)&&a.push(`path=${r}`),V.isString(o)&&a.push(`domain=${o}`),!0===i&&a.push("secure"),V.isString(s)&&a.push(`SameSite=${s}`),document.cookie=a.join("; ")},read(e){if("undefined"==typeof document)return null;const t=document.cookie.match(new RegExp("(?:^|; )"+e+"=([^;]*)"));return t?decodeURIComponent(t[1]):null},remove(e){this.write(e,"",Date.now()-864e5,"/")}}:{write(){},read:()=>null,remove(){}};function ke(e,t,n){let r=!/^([a-z][a-z\d+\-.]*:)?\/\//i.test(t);return e&&(r||0==n)?function(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}(e,t):t}const Fe=e=>e instanceof Ae?{...e}:e;function Le(e,t){t=t||{};const n={};function r(e,t,n,r){return V.isPlainObject(e)&&V.isPlainObject(t)?V.merge.call({caseless:r},e,t):V.isPlainObject(t)?V.merge({},t):V.isArray(t)?t.slice():t}function o(e,t,n,o){return V.isUndefined(t)?V.isUndefined(e)?void 0:r(void 0,e,0,o):r(e,t,0,o)}function i(e,t){if(!V.isUndefined(t))return r(void 0,t)}function s(e,t){return V.isUndefined(t)?V.isUndefined(e)?void 0:r(void 0,e):r(void 0,t)}function a(n,o,i){return i in t?r(n,o):i in e?r(void 0,n):void 0}const c={url:i,method:i,data:i,baseURL:s,transformRequest:s,transformResponse:s,paramsSerializer:s,timeout:s,timeoutMessage:s,withCredentials:s,withXSRFToken:s,adapter:s,responseType:s,xsrfCookieName:s,xsrfHeaderName:s,onUploadProgress:s,onDownloadProgress:s,decompress:s,maxContentLength:s,maxBodyLength:s,beforeRedirect:s,transport:s,httpAgent:s,httpsAgent:s,cancelToken:s,socketPath:s,responseEncoding:s,validateStatus:a,headers:(e,t,n)=>o(Fe(e),Fe(t),0,!0)};return V.forEach(Object.keys({...e,...t}),function(r){const i=c[r]||o,s=i(e[r],t[r],r);V.isUndefined(s)&&i!==a||(n[r]=s)}),n}var De=e=>{const t=Le({},e);let{data:n,withXSRFToken:r,xsrfHeaderName:o,xsrfCookieName:i,headers:s,auth:a}=t;if(t.headers=s=Ae.from(s),t.url=se(ke(t.baseURL,t.url,t.allowAbsoluteUrls),e.params,e.paramsSerializer),a&&s.set("Authorization","Basic "+btoa((a.username||"")+":"+(a.password?unescape(encodeURIComponent(a.password)):""))),V.isFormData(n))if(me.hasStandardBrowserEnv||me.hasStandardBrowserWebWorkerEnv)s.setContentType(void 0);else if(V.isFunction(n.getHeaders)){const e=n.getHeaders(),t=["content-type","content-length"];Object.entries(e).forEach(([e,n])=>{t.includes(e.toLowerCase())&&s.set(e,n)})}if(me.hasStandardBrowserEnv&&(r&&V.isFunction(r)&&(r=r(t)),r||!1!==r&&Ne(t.url))){const e=o&&i&&Be.read(i);e&&s.set(o,e)}return t},Ie="undefined"!=typeof XMLHttpRequest&&function(e){return new Promise(function(t,n){const r=De(e);let o=r.data;const i=Ae.from(r.headers).normalize();let s,a,c,l,u,{responseType:d,onUploadProgress:f,onDownloadProgress:h}=r;function p(){l&&l(),u&&u(),r.cancelToken&&r.cancelToken.unsubscribe(s),r.signal&&r.signal.removeEventListener("abort",s)}let m=new XMLHttpRequest;function w(){if(!m)return;const r=Ae.from("getAllResponseHeaders"in m&&m.getAllResponseHeaders());Ce(function(e){t(e),p()},function(e){n(e),p()},{data:d&&"text"!==d&&"json"!==d?m.response:m.responseText,status:m.status,statusText:m.statusText,headers:r,config:e,request:m}),m=null}m.open(r.method.toUpperCase(),r.url,!0),m.timeout=r.timeout,"onloadend"in m?m.onloadend=w:m.onreadystatechange=function(){m&&4===m.readyState&&(0!==m.status||m.responseURL&&0===m.responseURL.indexOf("file:"))&&setTimeout(w)},m.onabort=function(){m&&(n(new J("Request aborted",J.ECONNABORTED,e,m)),m=null)},m.onerror=function(t){const r=new J(t&&t.message?t.message:"Network Error",J.ERR_NETWORK,e,m);r.event=t||null,n(r),m=null},m.ontimeout=function(){let t=r.timeout?"timeout of "+r.timeout+"ms exceeded":"timeout exceeded";const o=r.transitional||ce;r.timeoutErrorMessage&&(t=r.timeoutErrorMessage),n(new J(t,o.clarifyTimeoutError?J.ETIMEDOUT:J.ECONNABORTED,e,m)),m=null},void 0===o&&i.setContentType(null),"setRequestHeader"in m&&V.forEach(i.toJSON(),function(e,t){m.setRequestHeader(t,e)}),V.isUndefined(r.withCredentials)||(m.withCredentials=!!r.withCredentials),d&&"json"!==d&&(m.responseType=r.responseType),h&&([c,u]=Pe(h,!0),m.addEventListener("progress",c)),f&&m.upload&&([a,l]=Pe(f),m.upload.addEventListener("progress",a),m.upload.addEventListener("loadend",l)),(r.cancelToken||r.signal)&&(s=t=>{m&&(n(!t||t.type?new je(null,e,m):t),m.abort(),m=null)},r.cancelToken&&r.cancelToken.subscribe(s),r.signal&&(r.signal.aborted?s():r.signal.addEventListener("abort",s)));const g=function(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}(r.url);g&&-1===me.protocols.indexOf(g)?n(new J("Unsupported protocol "+g+":",J.ERR_BAD_REQUEST,e)):m.send(o||null)})},Me=(e,t)=>{const{length:n}=e=e?e.filter(Boolean):[];if(t||n){let n,r=new AbortController;const o=function(e){if(!n){n=!0,s();const t=e instanceof Error?e:this.reason;r.abort(t instanceof J?t:new je(t instanceof Error?t.message:t))}};let i=t&&setTimeout(()=>{i=null,o(new J(`timeout ${t} of ms exceeded`,J.ETIMEDOUT))},t);const s=()=>{e&&(i&&clearTimeout(i),i=null,e.forEach(e=>{e.unsubscribe?e.unsubscribe(o):e.removeEventListener("abort",o)}),e=null)};e.forEach(e=>e.addEventListener("abort",o));const{signal:a}=r;return a.unsubscribe=()=>V.asap(s),a}};const qe=function*(e,t){let n=e.byteLength;if(!t||n<t)return void(yield e);let r,o=0;for(;o<n;)r=o+t,yield e.slice(o,r),o=r},We=(e,t,n,r)=>{const o=async function*(e,t){for await(const n of async function*(e){if(e[Symbol.asyncIterator])return void(yield*e);const t=e.getReader();try{for(;;){const{done:e,value:n}=await t.read();if(e)break;yield n}}finally{await t.cancel()}}(e))yield*qe(n,t)}(e,t);let i,s=0,a=e=>{i||(i=!0,r&&r(e))};return new ReadableStream({async pull(e){try{const{done:t,value:r}=await o.next();if(t)return a(),void e.close();let i=r.byteLength;if(n){let e=s+=i;n(e)}e.enqueue(new Uint8Array(r))}catch(e){throw a(e),e}},cancel:e=>(a(e),o.return())},{highWaterMark:2})},{isFunction:ze}=V,Ke=(({Request:e,Response:t})=>({Request:e,Response:t}))(V.global),{ReadableStream:$e,TextEncoder:He}=V.global,Ve=(e,...t)=>{try{return!!e(...t)}catch(e){return!1}},Je=e=>{e=V.merge.call({skipUndefined:!0},Ke,e);const{fetch:t,Request:n,Response:r}=e,o=t?ze(t):"function"==typeof fetch,i=ze(n),s=ze(r);if(!o)return!1;const a=o&&ze($e),c=o&&("function"==typeof He?(l=new He,e=>l.encode(e)):async e=>new Uint8Array(await new n(e).arrayBuffer()));var l;const u=i&&a&&Ve(()=>{let e=!1;const t=new n(me.origin,{body:new $e,method:"POST",get duplex(){return e=!0,"half"}}).headers.has("Content-Type");return e&&!t}),d=s&&a&&Ve(()=>V.isReadableStream(new r("").body)),f={stream:d&&(e=>e.body)};o&&["text","arrayBuffer","blob","formData","stream"].forEach(e=>{!f[e]&&(f[e]=(t,n)=>{let r=t&&t[e];if(r)return r.call(t);throw new J(`Response type '${e}' is not supported`,J.ERR_NOT_SUPPORT,n)})});return async e=>{let{url:o,method:s,data:a,signal:l,cancelToken:h,timeout:p,onDownloadProgress:m,onUploadProgress:w,responseType:g,headers:y,withCredentials:b="same-origin",fetchOptions:E}=De(e),O=t||fetch;g=g?(g+"").toLowerCase():"text";let v=Me([l,h&&h.toAbortSignal()],p),S=null;const R=v&&v.unsubscribe&&(()=>{v.unsubscribe()});let A;try{if(w&&u&&"get"!==s&&"head"!==s&&0!==(A=await(async(e,t)=>{const r=V.toFiniteNumber(e.getContentLength());return null==r?(async e=>{if(null==e)return 0;if(V.isBlob(e))return e.size;if(V.isSpecCompliantForm(e)){const t=new n(me.origin,{method:"POST",body:e});return(await t.arrayBuffer()).byteLength}return V.isArrayBufferView(e)||V.isArrayBuffer(e)?e.byteLength:(V.isURLSearchParams(e)&&(e+=""),V.isString(e)?(await c(e)).byteLength:void 0)})(t):r})(y,a))){let e,t=new n(o,{method:"POST",body:a,duplex:"half"});if(V.isFormData(a)&&(e=t.headers.get("content-type"))&&y.setContentType(e),t.body){const[e,n]=_e(A,Pe(Ue(w)));a=We(t.body,65536,e,n)}}V.isString(b)||(b=b?"include":"omit");const t=i&&"credentials"in n.prototype,l={...E,signal:v,method:s.toUpperCase(),headers:y.normalize().toJSON(),body:a,duplex:"half",credentials:t?b:void 0};S=i&&new n(o,l);let h=await(i?O(S,E):O(o,l));const p=d&&("stream"===g||"response"===g);if(d&&(m||p&&R)){const e={};["status","statusText","headers"].forEach(t=>{e[t]=h[t]});const t=V.toFiniteNumber(h.headers.get("content-length")),[n,o]=m&&_e(t,Pe(Ue(m),!0))||[];h=new r(We(h.body,65536,n,()=>{o&&o(),R&&R()}),e)}g=g||"text";let T=await f[V.findKey(f,g)||"text"](h,e);return!p&&R&&R(),await new Promise((t,n)=>{Ce(t,n,{data:T,headers:Ae.from(h.headers),status:h.status,statusText:h.statusText,config:e,request:S})})}catch(t){if(R&&R(),t&&"TypeError"===t.name&&/Load failed|fetch/i.test(t.message))throw Object.assign(new J("Network Error",J.ERR_NETWORK,e,S),{cause:t.cause||t});throw J.from(t,t&&t.code,e,S)}}},Xe=new Map,Ge=e=>{let t=e&&e.env||{};const{fetch:n,Request:r,Response:o}=t,i=[r,o,n];let s,a,c=i.length,l=Xe;for(;c--;)s=i[c],a=l.get(s),void 0===a&&l.set(s,a=c?new Map:Je(t)),l=a;return a};Ge();const Qe={http:null,xhr:Ie,fetch:{get:Ge}};V.forEach(Qe,(e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch(e){}Object.defineProperty(e,"adapterName",{value:t})}});const Ze=e=>`- ${e}`,Ye=e=>V.isFunction(e)||null===e||!1===e;var et=function(e,t){e=V.isArray(e)?e:[e];const{length:n}=e;let r,o;const i={};for(let s=0;s<n;s++){let n;if(r=e[s],o=r,!Ye(r)&&(o=Qe[(n=String(r)).toLowerCase()],void 0===o))throw new J(`Unknown adapter '${n}'`);if(o&&(V.isFunction(o)||(o=o.get(t))))break;i[n||"#"+s]=o}if(!o){const e=Object.entries(i).map(([e,t])=>`adapter ${e} `+(!1===t?"is not supported by the environment":"is not available in the build"));throw new J("There is no suitable adapter to dispatch the request "+(n?e.length>1?"since :\n"+e.map(Ze).join("\n"):" "+Ze(e[0]):"as no adapter specified"),"ERR_NOT_SUPPORT")}return o};function tt(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new je(null,e)}function nt(e){return tt(e),e.headers=Ae.from(e.headers),e.data=Te.call(e,e.transformRequest),-1!==["post","put","patch"].indexOf(e.method)&&e.headers.setContentType("application/x-www-form-urlencoded",!1),et(e.adapter||ye.adapter,e)(e).then(function(t){return tt(e),t.data=Te.call(e,e.transformResponse,t),t.headers=Ae.from(t.headers),t},function(t){return xe(t)||(tt(e),t&&t.response&&(t.response.data=Te.call(e,e.transformResponse,t.response),t.response.headers=Ae.from(t.response.headers))),Promise.reject(t)})}const rt="1.13.2",ot={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{ot[e]=function(n){return typeof n===e||"a"+(t<1?"n ":" ")+e}});const it={};ot.transitional=function(e,t,n){function r(e,t){return"[Axios v"+rt+"] Transitional option '"+e+"'"+t+(n?". "+n:"")}return(n,o,i)=>{if(!1===e)throw new J(r(o," has been removed"+(t?" in "+t:"")),J.ERR_DEPRECATED);return t&&!it[o]&&(it[o]=!0,console.warn(r(o," has been deprecated since v"+t+" and will be removed in the near future"))),!e||e(n,o,i)}},ot.spelling=function(e){return(t,n)=>(console.warn(`${n} is likely a misspelling of ${e}`),!0)};var st={assertOptions:function(e,t,n){if("object"!=typeof e)throw new J("options must be an object",J.ERR_BAD_OPTION_VALUE);const r=Object.keys(e);let o=r.length;for(;o-- >0;){const i=r[o],s=t[i];if(s){const t=e[i],n=void 0===t||s(t,i,e);if(!0!==n)throw new J("option "+i+" must be "+n,J.ERR_BAD_OPTION_VALUE);continue}if(!0!==n)throw new J("Unknown option "+i,J.ERR_BAD_OPTION)}},validators:ot};const at=st.validators;class ct{constructor(e){this.defaults=e||{},this.interceptors={request:new ae,response:new ae}}async request(e,t){try{return await this._request(e,t)}catch(e){if(e instanceof Error){let t={};Error.captureStackTrace?Error.captureStackTrace(t):t=new Error;const n=t.stack?t.stack.replace(/^.+\n/,""):"";try{e.stack?n&&!String(e.stack).endsWith(n.replace(/^.+\n.+\n/,""))&&(e.stack+="\n"+n):e.stack=n}catch(e){}}throw e}}_request(e,t){"string"==typeof e?(t=t||{}).url=e:t=e||{},t=Le(this.defaults,t);const{transitional:n,paramsSerializer:r,headers:o}=t;void 0!==n&&st.assertOptions(n,{silentJSONParsing:at.transitional(at.boolean),forcedJSONParsing:at.transitional(at.boolean),clarifyTimeoutError:at.transitional(at.boolean)},!1),null!=r&&(V.isFunction(r)?t.paramsSerializer={serialize:r}:st.assertOptions(r,{encode:at.function,serialize:at.function},!0)),void 0!==t.allowAbsoluteUrls||(void 0!==this.defaults.allowAbsoluteUrls?t.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:t.allowAbsoluteUrls=!0),st.assertOptions(t,{baseUrl:at.spelling("baseURL"),withXsrfToken:at.spelling("withXSRFToken")},!0),t.method=(t.method||this.defaults.method||"get").toLowerCase();let i=o&&V.merge(o.common,o[t.method]);o&&V.forEach(["delete","get","head","post","put","patch","common"],e=>{delete o[e]}),t.headers=Ae.concat(i,o);const s=[];let a=!0;this.interceptors.request.forEach(function(e){"function"==typeof e.runWhen&&!1===e.runWhen(t)||(a=a&&e.synchronous,s.unshift(e.fulfilled,e.rejected))});const c=[];let l;this.interceptors.response.forEach(function(e){c.push(e.fulfilled,e.rejected)});let u,d=0;if(!a){const e=[nt.bind(this),void 0];for(e.unshift(...s),e.push(...c),u=e.length,l=Promise.resolve(t);d<u;)l=l.then(e[d++],e[d++]);return l}u=s.length;let f=t;for(;d<u;){const e=s[d++],t=s[d++];try{f=e(f)}catch(e){t.call(this,e);break}}try{l=nt.call(this,f)}catch(e){return Promise.reject(e)}for(d=0,u=c.length;d<u;)l=l.then(c[d++],c[d++]);return l}getUri(e){return se(ke((e=Le(this.defaults,e)).baseURL,e.url,e.allowAbsoluteUrls),e.params,e.paramsSerializer)}}V.forEach(["delete","get","head","options"],function(e){ct.prototype[e]=function(t,n){return this.request(Le(n||{},{method:e,url:t,data:(n||{}).data}))}}),V.forEach(["post","put","patch"],function(e){function t(t){return function(n,r,o){return this.request(Le(o||{},{method:e,headers:t?{"Content-Type":"multipart/form-data"}:{},url:n,data:r}))}}ct.prototype[e]=t(),ct.prototype[e+"Form"]=t(!0)});var lt=ct;class ut{constructor(e){if("function"!=typeof e)throw new TypeError("executor must be a function.");let t;this.promise=new Promise(function(e){t=e});const n=this;this.promise.then(e=>{if(!n._listeners)return;let t=n._listeners.length;for(;t-- >0;)n._listeners[t](e);n._listeners=null}),this.promise.then=e=>{let t;const r=new Promise(e=>{n.subscribe(e),t=e}).then(e);return r.cancel=function(){n.unsubscribe(t)},r},e(function(e,r,o){n.reason||(n.reason=new je(e,r,o),t(n.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){this.reason?e(this.reason):this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const t=this._listeners.indexOf(e);-1!==t&&this._listeners.splice(t,1)}toAbortSignal(){const e=new AbortController,t=t=>{e.abort(t)};return this.subscribe(t),e.signal.unsubscribe=()=>this.unsubscribe(t),e.signal}static source(){let e;return{token:new ut(function(t){e=t}),cancel:e}}}var dt=ut;const ft={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(ft).forEach(([e,t])=>{ft[t]=e});var ht=ft;const pt=function e(t){const n=new lt(t),o=r(lt.prototype.request,n);return V.extend(o,lt.prototype,n,{allOwnKeys:!0}),V.extend(o,n,null,{allOwnKeys:!0}),o.create=function(n){return e(Le(t,n))},o}(ye);pt.Axios=lt,pt.CanceledError=je,pt.CancelToken=dt,pt.isCancel=xe,pt.VERSION=rt,pt.toFormData=te,pt.AxiosError=J,pt.Cancel=pt.CanceledError,pt.all=function(e){return Promise.all(e)},pt.spread=function(e){return function(t){return e.apply(null,t)}},pt.isAxiosError=function(e){return V.isObject(e)&&!0===e.isAxiosError},pt.mergeConfig=Le,pt.AxiosHeaders=Ae,pt.formToJSON=e=>we(V.isHTMLForm(e)?new FormData(e):e),pt.getAdapter=et,pt.HttpStatusCode=ht,pt.default=pt,e.exports=pt},436:function(e,t,n){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.VoidAIBridgeClient=void 0;const o=r(n(425));t.VoidAIBridgeClient=class{constructor(e){this.config=e,this.client=o.default.create({timeout:1e4,headers:{"Content-Type":"application/json","x-api-key":this.config.apiKey}})}getUrl(e){return`${this.config.getBaseUrl().replace(/\/$/,"")}/${e.replace(/^\//,"")}`}async get(e,t){const n=this.getUrl(e);try{return(await this.client.get(n,{params:t})).data}catch(e){throw this.handleError(e),e}}async post(e,t){const n=this.getUrl(e);try{return(await this.client.post(n,t)).data}catch(e){throw this.handleError(e),e}}async getSupportedChains(e){const t={};return void 0!==e?.isActive&&(t.is_active=String(e.isActive)),void 0!==e?.isCcipSupported&&(t.is_ccip_supported=String(e.isCcipSupported)),void 0!==e?.chainId&&(t.chain_id=e.chainId),(await this.get("api/chains",t)).chains}async getAssetList(e){const t=await this.get("api/asset");return void 0!==e?t.assets.filter(t=>t.chainId===e):t.assets}handleError(e){o.default.isAxiosError(e)?console.error("Bridge API Error:",e.response?.data||e.message):console.error("Unexpected Error:",e)}}},570:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.BittensorWallet=void 0,t.BittensorWallet=class{constructor(){this.extension=null,this.account=null,this.extensionName=null}async connect(e){if("undefined"==typeof window)throw new Error("BittensorWallet: Browser environment required for wallet connection");if(void 0===window.injectedWeb3)throw new Error("No compatible wallet extension found. Please install Talisman, Subwallet, or Polkadot.js extension.");const t=window.injectedWeb3,n=["talisman","subwallet-js","polkadot-js"];let r,o,i=null,s="";if(e&&t[e])i=t[e],s=e;else{for(const e of n)if(t[e]){i=t[e],s=e;break}if(!i){const e=Object.keys(t);if(!(e.length>0))throw new Error("No compatible wallet extension found.");s=e[0],i=t[s]}}try{r=await i.enable("VoidAI Bridge SDK")}catch(e){if(e.message&&e.message.includes("authorised"))throw new Error("No accounts are authorized. Please authorize accounts in your wallet extension and try again.");throw new Error(`Failed to enable wallet extension: ${e.message||e}`)}if(!r)throw new Error("Failed to enable wallet extension. Please try again.");try{o=await r.accounts.get()}catch(e){throw new Error(`Failed to get accounts: ${e.message||e}`)}if(0===o.length)throw new Error("No accounts found. Please authorize at least one account in your wallet extension and try again.");this.extension=r;const a=o[0];return this.account=a,this.extensionName=s,a}getAccount(){return this.account}getExtensionName(){return this.extensionName}isConnected(){return null!==this.account&&null!==this.extension}disconnect(){this.extension=null,this.account=null,this.extensionName=null}static isExtensionAvailable(e){if("undefined"==typeof window)return!1;const t=window.injectedWeb3;return!!t&&(e?!!t[e]:["talisman","subwallet-js","polkadot-js"].some(e=>!!t[e])||Object.keys(t).length>0)}getExtension(){return this.extension}}},574:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})},925:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Bridge=void 0,t.Bridge=class{constructor(e){this.apiClient=e}async getTransactionStatus(e){const{status:t}=await this.apiClient.get(`/transactions/${e}/status`);return t}async getHistory(e){return this.apiClient.get(`/transactions/history/${e}`)}}},967:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.EthereumWallet=void 0;class n{constructor(){this.account=null,this.chainId=null}static isMetaMaskInstalled(){return"undefined"!=typeof window&&void 0!==window.ethereum&&window.ethereum.isMetaMask}async connect(){if("undefined"==typeof window)throw new Error("EthereumWallet: Browser environment required");if(!n.isMetaMaskInstalled())throw new Error("MetaMask is not installed. Please install MetaMask extension from https://metamask.io/");const e=window.ethereum;try{const t=await e.request({method:"eth_requestAccounts"});if(!t||0===t.length)throw new Error("No accounts found. Please unlock MetaMask and try again.");const n=await e.request({method:"eth_chainId"});return this.account={address:t[0],chainId:n},this.chainId=n,e.on("accountsChanged",this.handleAccountsChanged.bind(this)),e.on("chainChanged",this.handleChainChanged.bind(this)),this.account}catch(e){if(4001===e.code)throw new Error("User rejected the connection request");throw new Error(`Failed to connect to MetaMask: ${e.message||e}`)}}getAccount(){return this.account}getChainId(){return this.chainId}isConnected(){return null!==this.account}disconnect(){this.account=null,this.chainId=null}getProvider(){return"undefined"==typeof window?null:window.ethereum}handleAccountsChanged(e){0===e.length?this.disconnect():this.account&&e[0]!==this.account.address&&(this.account.address=e[0])}handleChainChanged(e){this.chainId=e,this.account&&(this.account.chainId=e)}}t.EthereumWallet=n}},t={};function n(r){var o=t[r];if(void 0!==o)return o.exports;var i=t[r]={exports:{}};return e[r].call(i.exports,i,i.exports,n),i.exports}return n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n(156)})());
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! Axios v1.13.2 Copyright (c) 2025 Matt Zabriskie and contributors */
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "voidai-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "TypeScript SDK for VoidAI Bridge - Blockchain wallet authentication and API integration",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"browser": "dist-browser/voidai-sdk.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"dist-browser",
|
|
11
|
+
"README.md"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"build:browser": "webpack",
|
|
16
|
+
"build:all": "npm run build && npm run build:browser",
|
|
17
|
+
"test": "jest",
|
|
18
|
+
"lint": "eslint src/**/*.ts",
|
|
19
|
+
"prepare": "npm run build:all",
|
|
20
|
+
"prepublishOnly": "npm test"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"blockchain",
|
|
24
|
+
"bridge",
|
|
25
|
+
"sdk",
|
|
26
|
+
"typescript",
|
|
27
|
+
"voidai",
|
|
28
|
+
"polkadot",
|
|
29
|
+
"ethereum",
|
|
30
|
+
"wallet",
|
|
31
|
+
"authentication"
|
|
32
|
+
],
|
|
33
|
+
"author": "VoidAI",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/your-org/bridge-sdk"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/jest": "^29.5.12",
|
|
41
|
+
"@types/node": "^20.11.24",
|
|
42
|
+
"eslint": "^8.57.0",
|
|
43
|
+
"jest": "^29.7.0",
|
|
44
|
+
"ts-jest": "^29.1.2",
|
|
45
|
+
"ts-loader": "^9.5.4",
|
|
46
|
+
"typescript": "^5.3.3",
|
|
47
|
+
"webpack": "^5.103.0",
|
|
48
|
+
"webpack-cli": "^6.0.1"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"axios": "^1.6.7",
|
|
52
|
+
"cors": "^2.8.5",
|
|
53
|
+
"zod": "^3.22.4"
|
|
54
|
+
}
|
|
55
|
+
}
|