@solrouter/sdk 1.0.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 +115 -0
- package/dist/client.d.ts +41 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +168 -0
- package/dist/client.js.map +1 -0
- package/dist/encryption.d.ts +35 -0
- package/dist/encryption.d.ts.map +1 -0
- package/dist/encryption.js +154 -0
- package/dist/encryption.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +56 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# @solrouter/sdk
|
|
2
|
+
|
|
3
|
+
Privacy-first AI API client with end-to-end encryption.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @solrouter/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { SolRouter } from '@solrouter/sdk';
|
|
15
|
+
|
|
16
|
+
const client = new SolRouter({
|
|
17
|
+
apiKey: 'sk_solrouter_your_key_here'
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// Your prompt is encrypted client-side before being sent
|
|
21
|
+
const response = await client.chat('Explain quantum computing');
|
|
22
|
+
console.log(response.message);
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## How It Works
|
|
26
|
+
|
|
27
|
+
1. **Client-side Encryption**: Your prompt is encrypted using Arcium's RescueCipher before leaving your device
|
|
28
|
+
2. **Blind Backend**: The server only sees encrypted data - it cannot read your prompt
|
|
29
|
+
3. **TEE Processing**: Decryption only happens inside a Trusted Execution Environment (hardware-isolated)
|
|
30
|
+
4. **Encrypted Response**: The AI response is encrypted back to you
|
|
31
|
+
|
|
32
|
+
## API Reference
|
|
33
|
+
|
|
34
|
+
### `new SolRouter(config)`
|
|
35
|
+
|
|
36
|
+
Create a new SolRouter client.
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
const client = new SolRouter({
|
|
40
|
+
apiKey: 'sk_solrouter_...', // Required: Your API key
|
|
41
|
+
baseUrl: 'https://...', // Optional: Custom API URL
|
|
42
|
+
encrypted: true, // Optional: Enable encryption (default: true)
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### `client.chat(prompt, options?)`
|
|
47
|
+
|
|
48
|
+
Send a chat message.
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
const response = await client.chat('Hello!', {
|
|
52
|
+
model: 'gpt-oss-20b', // Model to use
|
|
53
|
+
encrypted: true, // Override encryption setting
|
|
54
|
+
systemPrompt: 'You are...', // System prompt
|
|
55
|
+
chatId: 'conv-123', // For multi-turn conversations
|
|
56
|
+
useRAG: false, // Enable knowledge retrieval
|
|
57
|
+
useLiveSearch: false, // Enable web search
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
console.log(response.message); // AI response
|
|
61
|
+
console.log(response.encrypted); // Was request encrypted?
|
|
62
|
+
console.log(response.usage); // Token usage
|
|
63
|
+
console.log(response.cost); // Cost in USDC
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Available Models
|
|
67
|
+
|
|
68
|
+
| Model | Description |
|
|
69
|
+
|-------|-------------|
|
|
70
|
+
| `gpt-oss-20b` | Open-source GPT 20B (default, cheapest) |
|
|
71
|
+
| `qwen3-8b` | Qwen 3 8B parameters |
|
|
72
|
+
| `gemini-flash` | Google Gemini Flash |
|
|
73
|
+
| `claude-sonnet` | Anthropic Claude Sonnet |
|
|
74
|
+
| `gpt-4o-mini` | OpenAI GPT-4o Mini |
|
|
75
|
+
|
|
76
|
+
### `client.getBalance()`
|
|
77
|
+
|
|
78
|
+
Check your account balance.
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
const balance = await client.getBalance();
|
|
82
|
+
console.log(balance.balanceFormatted); // "$10.5000"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Pricing
|
|
86
|
+
|
|
87
|
+
| Model | Input (per 1M tokens) | Output (per 1M tokens) |
|
|
88
|
+
|-------|----------------------|------------------------|
|
|
89
|
+
| gpt-oss-20b | $0.15 | $0.30 |
|
|
90
|
+
| qwen3-8b | $0.05 | $0.10 |
|
|
91
|
+
| gemini-flash | $0.075 | $0.30 |
|
|
92
|
+
| claude-sonnet | $3.00 | $15.00 |
|
|
93
|
+
| gpt-4o-mini | $0.15 | $0.60 |
|
|
94
|
+
|
|
95
|
+
## Privacy Guarantee
|
|
96
|
+
|
|
97
|
+
When encryption is enabled (default):
|
|
98
|
+
|
|
99
|
+
- Your prompts are encrypted on your device using Arcium's MPC encryption
|
|
100
|
+
- The SolRouter backend NEVER sees your plaintext prompts
|
|
101
|
+
- Decryption only happens inside a hardware-isolated TEE
|
|
102
|
+
- On-chain privacy attestations are available for verification
|
|
103
|
+
|
|
104
|
+
## Get an API Key
|
|
105
|
+
|
|
106
|
+
1. Visit [solrouter.com/api](https://solrouter.com/api)
|
|
107
|
+
2. Connect your wallet
|
|
108
|
+
3. Generate an API key
|
|
109
|
+
4. Deposit USDC to fund your account
|
|
110
|
+
|
|
111
|
+
## Links
|
|
112
|
+
|
|
113
|
+
- [Documentation](https://docs.solrouter.com)
|
|
114
|
+
- [API Dashboard](https://solrouter.com/api)
|
|
115
|
+
- [GitHub](https://github.com/solrouter/sdk)
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SolRouter SDK - Main Client
|
|
3
|
+
*
|
|
4
|
+
* Privacy-first AI API client with end-to-end encryption.
|
|
5
|
+
*/
|
|
6
|
+
import type { SolRouterConfig, ChatOptions, ChatResponse, BalanceResponse } from './types.js';
|
|
7
|
+
export declare class SolRouter {
|
|
8
|
+
private apiKey;
|
|
9
|
+
private baseUrl;
|
|
10
|
+
private encrypted;
|
|
11
|
+
constructor(config: SolRouterConfig);
|
|
12
|
+
/**
|
|
13
|
+
* Send a chat message with optional encryption
|
|
14
|
+
*
|
|
15
|
+
* @param prompt - The user's message
|
|
16
|
+
* @param options - Chat options (model, encryption, etc.)
|
|
17
|
+
* @returns The AI response
|
|
18
|
+
*/
|
|
19
|
+
chat(prompt: string, options?: ChatOptions): Promise<ChatResponse>;
|
|
20
|
+
/**
|
|
21
|
+
* Encrypted chat - prompt is encrypted client-side
|
|
22
|
+
*/
|
|
23
|
+
private encryptedChat;
|
|
24
|
+
/**
|
|
25
|
+
* Plain chat - no encryption (for non-sensitive requests)
|
|
26
|
+
*/
|
|
27
|
+
private plainChat;
|
|
28
|
+
/**
|
|
29
|
+
* Get endpoint for a given model
|
|
30
|
+
*/
|
|
31
|
+
private getEndpointForModel;
|
|
32
|
+
/**
|
|
33
|
+
* Get account balance
|
|
34
|
+
*/
|
|
35
|
+
getBalance(): Promise<BalanceResponse>;
|
|
36
|
+
/**
|
|
37
|
+
* Clear encryption session (call on logout/cleanup)
|
|
38
|
+
*/
|
|
39
|
+
clearSession(): void;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EACV,eAAe,EACf,WAAW,EACX,YAAY,EACZ,eAAe,EAChB,MAAM,YAAY,CAAC;AAcpB,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAU;gBAEf,MAAM,EAAE,eAAe;IASnC;;;;;;OAMG;IACG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAW5E;;OAEG;YACW,aAAa;IAgE3B;;OAEG;YACW,SAAS;IAqDvB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAQ3B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,eAAe,CAAC;IAmB5C;;OAEG;IACH,YAAY,IAAI,IAAI;CAGrB"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SolRouter SDK - Main Client
|
|
3
|
+
*
|
|
4
|
+
* Privacy-first AI API client with end-to-end encryption.
|
|
5
|
+
*/
|
|
6
|
+
import { encrypt, decrypt, packageForTEE, clearSession } from './encryption.js';
|
|
7
|
+
const DEFAULT_BASE_URL = 'https://solrouter-obb4.onrender.com';
|
|
8
|
+
const DEFAULT_MODEL = 'gpt-oss-20b';
|
|
9
|
+
// Model mapping for API
|
|
10
|
+
const MODEL_MAP = {
|
|
11
|
+
'gpt-oss-20b': 'nosana:gpt-oss:20b',
|
|
12
|
+
'qwen3-8b': 'nosana:qwen3:8b',
|
|
13
|
+
'gemini-flash': 'gemini:gemini-2.0-flash-exp',
|
|
14
|
+
'claude-sonnet': 'claude:claude-3-5-sonnet-20241022',
|
|
15
|
+
'gpt-4o-mini': 'openai:gpt-4o-mini',
|
|
16
|
+
};
|
|
17
|
+
export class SolRouter {
|
|
18
|
+
apiKey;
|
|
19
|
+
baseUrl;
|
|
20
|
+
encrypted;
|
|
21
|
+
constructor(config) {
|
|
22
|
+
if (!config.apiKey) {
|
|
23
|
+
throw new Error('SolRouter: apiKey is required');
|
|
24
|
+
}
|
|
25
|
+
this.apiKey = config.apiKey;
|
|
26
|
+
this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
|
|
27
|
+
this.encrypted = config.encrypted !== false; // Default to true
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Send a chat message with optional encryption
|
|
31
|
+
*
|
|
32
|
+
* @param prompt - The user's message
|
|
33
|
+
* @param options - Chat options (model, encryption, etc.)
|
|
34
|
+
* @returns The AI response
|
|
35
|
+
*/
|
|
36
|
+
async chat(prompt, options = {}) {
|
|
37
|
+
const useEncryption = options.encrypted ?? this.encrypted;
|
|
38
|
+
const model = MODEL_MAP[options.model || DEFAULT_MODEL] || options.model || MODEL_MAP[DEFAULT_MODEL];
|
|
39
|
+
if (useEncryption) {
|
|
40
|
+
return this.encryptedChat(prompt, model, options);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
return this.plainChat(prompt, model, options);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Encrypted chat - prompt is encrypted client-side
|
|
48
|
+
*/
|
|
49
|
+
async encryptedChat(prompt, model, options) {
|
|
50
|
+
// Encrypt the prompt
|
|
51
|
+
const encryptedData = await encrypt(prompt, this.baseUrl);
|
|
52
|
+
const encryptedPackage = packageForTEE(encryptedData);
|
|
53
|
+
// Send to TEE endpoint
|
|
54
|
+
const response = await fetch(`${this.baseUrl}/tee/process`, {
|
|
55
|
+
method: 'POST',
|
|
56
|
+
headers: {
|
|
57
|
+
'Content-Type': 'application/json',
|
|
58
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
59
|
+
},
|
|
60
|
+
body: JSON.stringify({
|
|
61
|
+
encryptedPrompt: encryptedPackage,
|
|
62
|
+
model: model,
|
|
63
|
+
chatId: options.chatId,
|
|
64
|
+
systemPrompt: options.systemPrompt,
|
|
65
|
+
useRAG: options.useRAG,
|
|
66
|
+
ragCollection: options.ragCollection,
|
|
67
|
+
useLiveSearch: options.useLiveSearch,
|
|
68
|
+
}),
|
|
69
|
+
});
|
|
70
|
+
if (!response.ok) {
|
|
71
|
+
const error = await response.json().catch(() => ({ error: 'Unknown error' }));
|
|
72
|
+
throw new Error(`SolRouter API error: ${error.error || error.message || response.statusText}`);
|
|
73
|
+
}
|
|
74
|
+
const data = await response.json();
|
|
75
|
+
// Decrypt the response
|
|
76
|
+
const decryptedMessage = await decrypt(JSON.parse(data.encryptedResponse), encryptedData.ephemeralPrivateKey);
|
|
77
|
+
return {
|
|
78
|
+
message: decryptedMessage,
|
|
79
|
+
model: data.metadata?.model || model,
|
|
80
|
+
usage: data.metadata ? {
|
|
81
|
+
promptTokens: data.metadata.promptTokens || 0,
|
|
82
|
+
completionTokens: data.metadata.completionTokens || 0,
|
|
83
|
+
totalTokens: (data.metadata.promptTokens || 0) + (data.metadata.completionTokens || 0),
|
|
84
|
+
} : undefined,
|
|
85
|
+
cost: data.cost,
|
|
86
|
+
encrypted: true,
|
|
87
|
+
privacyAttestationId: data.privacyAttestationId || data.attestationHash,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Plain chat - no encryption (for non-sensitive requests)
|
|
92
|
+
*/
|
|
93
|
+
async plainChat(prompt, model, options) {
|
|
94
|
+
// Determine the correct endpoint based on model
|
|
95
|
+
const endpoint = this.getEndpointForModel(model);
|
|
96
|
+
const response = await fetch(`${this.baseUrl}${endpoint}`, {
|
|
97
|
+
method: 'POST',
|
|
98
|
+
headers: {
|
|
99
|
+
'Content-Type': 'application/json',
|
|
100
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
101
|
+
},
|
|
102
|
+
body: JSON.stringify({
|
|
103
|
+
prompt: prompt,
|
|
104
|
+
model: model.split(':').pop(), // Extract model name
|
|
105
|
+
chatId: options.chatId,
|
|
106
|
+
systemPrompt: options.systemPrompt,
|
|
107
|
+
useRAG: options.useRAG,
|
|
108
|
+
ragCollection: options.ragCollection,
|
|
109
|
+
useLiveSearch: options.useLiveSearch,
|
|
110
|
+
}),
|
|
111
|
+
});
|
|
112
|
+
if (!response.ok) {
|
|
113
|
+
const error = await response.json().catch(() => ({ error: 'Unknown error' }));
|
|
114
|
+
throw new Error(`SolRouter API error: ${error.error || error.message || response.statusText}`);
|
|
115
|
+
}
|
|
116
|
+
const data = await response.json();
|
|
117
|
+
return {
|
|
118
|
+
message: data.reply,
|
|
119
|
+
model: data.model || model,
|
|
120
|
+
usage: data.tokenUsage ? {
|
|
121
|
+
promptTokens: data.tokenUsage.promptTokens,
|
|
122
|
+
completionTokens: data.tokenUsage.completionTokens,
|
|
123
|
+
totalTokens: data.tokenUsage.promptTokens + data.tokenUsage.completionTokens,
|
|
124
|
+
} : undefined,
|
|
125
|
+
cost: data.cost,
|
|
126
|
+
encrypted: false,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Get endpoint for a given model
|
|
131
|
+
*/
|
|
132
|
+
getEndpointForModel(model) {
|
|
133
|
+
if (model.startsWith('nosana:'))
|
|
134
|
+
return '/nosana';
|
|
135
|
+
if (model.startsWith('gemini:'))
|
|
136
|
+
return '/gemini';
|
|
137
|
+
if (model.startsWith('claude:'))
|
|
138
|
+
return '/claude';
|
|
139
|
+
if (model.startsWith('openai:'))
|
|
140
|
+
return '/openai';
|
|
141
|
+
return '/router'; // Default intelligent routing
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Get account balance
|
|
145
|
+
*/
|
|
146
|
+
async getBalance() {
|
|
147
|
+
const response = await fetch(`${this.baseUrl}/payments/balance`, {
|
|
148
|
+
headers: {
|
|
149
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
if (!response.ok) {
|
|
153
|
+
throw new Error('Failed to fetch balance');
|
|
154
|
+
}
|
|
155
|
+
const data = await response.json();
|
|
156
|
+
return {
|
|
157
|
+
balance: data.balance,
|
|
158
|
+
balanceFormatted: `$${data.balance.toFixed(4)}`,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Clear encryption session (call on logout/cleanup)
|
|
163
|
+
*/
|
|
164
|
+
clearSession() {
|
|
165
|
+
clearSession();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SolRouter SDK - Arcium Encryption
|
|
3
|
+
*
|
|
4
|
+
* Handles client-side encryption using Arcium's RescueCipher.
|
|
5
|
+
* No wallet signatures required - uses ephemeral X25519 key exchange.
|
|
6
|
+
*/
|
|
7
|
+
import type { EncryptedData } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Fetch TEE public key from server
|
|
10
|
+
*/
|
|
11
|
+
export declare function fetchTeePublicKey(baseUrl: string): Promise<Uint8Array>;
|
|
12
|
+
/**
|
|
13
|
+
* Encrypt a message using Arcium's RescueCipher
|
|
14
|
+
*
|
|
15
|
+
* @param message - The plaintext message to encrypt
|
|
16
|
+
* @param baseUrl - API base URL (for fetching TEE public key)
|
|
17
|
+
* @returns Encrypted data bundle
|
|
18
|
+
*/
|
|
19
|
+
export declare function encrypt(message: string, baseUrl: string): Promise<EncryptedData>;
|
|
20
|
+
/**
|
|
21
|
+
* Decrypt a response from TEE
|
|
22
|
+
*
|
|
23
|
+
* @param encryptedData - The encrypted response from TEE
|
|
24
|
+
* @param clientPrivateKey - The ephemeral private key (optional, uses session key)
|
|
25
|
+
*/
|
|
26
|
+
export declare function decrypt(encryptedData: EncryptedData, clientPrivateKey?: string): Promise<string>;
|
|
27
|
+
/**
|
|
28
|
+
* Package encrypted data for TEE transmission
|
|
29
|
+
*/
|
|
30
|
+
export declare function packageForTEE(encryptedData: EncryptedData): string;
|
|
31
|
+
/**
|
|
32
|
+
* Clear session keypair (for logout/cleanup)
|
|
33
|
+
*/
|
|
34
|
+
export declare function clearSession(): void;
|
|
35
|
+
//# sourceMappingURL=encryption.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.d.ts","sourceRoot":"","sources":["../src/encryption.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAoBhD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAoB5E;AAED;;;;;;GAMG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAwCtF;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAC3B,aAAa,EAAE,aAAa,EAC5B,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,MAAM,CAAC,CAgDjB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,aAAa,EAAE,aAAa,GAAG,MAAM,CAQlE;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAGnC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SolRouter SDK - Arcium Encryption
|
|
3
|
+
*
|
|
4
|
+
* Handles client-side encryption using Arcium's RescueCipher.
|
|
5
|
+
* No wallet signatures required - uses ephemeral X25519 key exchange.
|
|
6
|
+
*/
|
|
7
|
+
import { RescueCipher, x25519 } from '@arcium-hq/client';
|
|
8
|
+
// Session keypair (generated once per SDK instance)
|
|
9
|
+
let sessionKeypair = null;
|
|
10
|
+
// Cached TEE public key
|
|
11
|
+
let cachedTeePublicKey = null;
|
|
12
|
+
/**
|
|
13
|
+
* Initialize or get the session keypair
|
|
14
|
+
*/
|
|
15
|
+
function getSessionKeypair() {
|
|
16
|
+
if (!sessionKeypair) {
|
|
17
|
+
const privateKey = x25519.utils.randomSecretKey();
|
|
18
|
+
const publicKey = x25519.getPublicKey(privateKey);
|
|
19
|
+
sessionKeypair = { privateKey, publicKey };
|
|
20
|
+
}
|
|
21
|
+
return sessionKeypair;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Fetch TEE public key from server
|
|
25
|
+
*/
|
|
26
|
+
export async function fetchTeePublicKey(baseUrl) {
|
|
27
|
+
if (cachedTeePublicKey) {
|
|
28
|
+
return cachedTeePublicKey;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const response = await fetch(`${baseUrl}/tee/public-key`);
|
|
32
|
+
if (response.ok) {
|
|
33
|
+
const data = await response.json();
|
|
34
|
+
cachedTeePublicKey = Buffer.from(data.publicKey, 'base64');
|
|
35
|
+
return cachedTeePublicKey;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Fall through to fallback
|
|
40
|
+
}
|
|
41
|
+
// Fallback to dev TEE key
|
|
42
|
+
const TEE_PRIVATE_KEY_TEMP = new Uint8Array(32).fill(42);
|
|
43
|
+
cachedTeePublicKey = x25519.getPublicKey(TEE_PRIVATE_KEY_TEMP);
|
|
44
|
+
return cachedTeePublicKey;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Encrypt a message using Arcium's RescueCipher
|
|
48
|
+
*
|
|
49
|
+
* @param message - The plaintext message to encrypt
|
|
50
|
+
* @param baseUrl - API base URL (for fetching TEE public key)
|
|
51
|
+
* @returns Encrypted data bundle
|
|
52
|
+
*/
|
|
53
|
+
export async function encrypt(message, baseUrl) {
|
|
54
|
+
// Get session keypair
|
|
55
|
+
const { privateKey, publicKey } = getSessionKeypair();
|
|
56
|
+
// Get TEE public key
|
|
57
|
+
const teePublicKey = await fetchTeePublicKey(baseUrl);
|
|
58
|
+
// Convert message to BigInt array
|
|
59
|
+
const messageBytes = new TextEncoder().encode(message);
|
|
60
|
+
const plaintextBigInts = Array.from(messageBytes).map(BigInt);
|
|
61
|
+
// Create shared secret with TEE
|
|
62
|
+
const sharedSecret = x25519.getSharedSecret(privateKey, teePublicKey);
|
|
63
|
+
// Generate random nonce
|
|
64
|
+
const nonce = crypto.getRandomValues(new Uint8Array(16));
|
|
65
|
+
// Encrypt with RescueCipher
|
|
66
|
+
const cipher = new RescueCipher(sharedSecret);
|
|
67
|
+
const ciphertext = cipher.encrypt(plaintextBigInts, nonce);
|
|
68
|
+
// Flatten and preserve shape for reconstruction
|
|
69
|
+
const shape = ciphertext.map(chunk => chunk.length);
|
|
70
|
+
const flatCiphertext = ciphertext.flat();
|
|
71
|
+
const ciphertextStrings = flatCiphertext.map(num => String(num));
|
|
72
|
+
const serialized = {
|
|
73
|
+
data: ciphertextStrings,
|
|
74
|
+
shape: shape
|
|
75
|
+
};
|
|
76
|
+
const ciphertextJson = JSON.stringify(serialized);
|
|
77
|
+
const ciphertextBase64 = Buffer.from(ciphertextJson).toString('base64');
|
|
78
|
+
return {
|
|
79
|
+
ciphertext: ciphertextBase64,
|
|
80
|
+
nonce: Buffer.from(nonce).toString('base64'),
|
|
81
|
+
publicKey: Buffer.from(publicKey).toString('base64'),
|
|
82
|
+
ephemeralPrivateKey: Buffer.from(privateKey).toString('base64'),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Decrypt a response from TEE
|
|
87
|
+
*
|
|
88
|
+
* @param encryptedData - The encrypted response from TEE
|
|
89
|
+
* @param clientPrivateKey - The ephemeral private key (optional, uses session key)
|
|
90
|
+
*/
|
|
91
|
+
export async function decrypt(encryptedData, clientPrivateKey) {
|
|
92
|
+
// Decode the encrypted data
|
|
93
|
+
const ciphertextJson = Buffer.from(encryptedData.ciphertext, 'base64').toString('utf8');
|
|
94
|
+
const parsed = JSON.parse(ciphertextJson);
|
|
95
|
+
// Reconstruct the 2D array
|
|
96
|
+
const flatData = parsed.data.map((str) => Number(str));
|
|
97
|
+
const shape = parsed.shape;
|
|
98
|
+
const ciphertext = [];
|
|
99
|
+
let offset = 0;
|
|
100
|
+
for (const chunkSize of shape) {
|
|
101
|
+
ciphertext.push(flatData.slice(offset, offset + chunkSize));
|
|
102
|
+
offset += chunkSize;
|
|
103
|
+
}
|
|
104
|
+
const nonce = Buffer.from(encryptedData.nonce, 'base64');
|
|
105
|
+
const teePublicKey = Buffer.from(encryptedData.publicKey, 'base64');
|
|
106
|
+
// Get private key
|
|
107
|
+
let privateKey;
|
|
108
|
+
if (clientPrivateKey) {
|
|
109
|
+
privateKey = new Uint8Array(Buffer.from(clientPrivateKey, 'base64'));
|
|
110
|
+
}
|
|
111
|
+
else if (encryptedData.ephemeralPrivateKey) {
|
|
112
|
+
privateKey = new Uint8Array(Buffer.from(encryptedData.ephemeralPrivateKey, 'base64'));
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
const session = getSessionKeypair();
|
|
116
|
+
privateKey = session.privateKey;
|
|
117
|
+
}
|
|
118
|
+
// Recreate shared secret
|
|
119
|
+
const sharedSecret = x25519.getSharedSecret(privateKey, teePublicKey);
|
|
120
|
+
// Decrypt with RescueCipher
|
|
121
|
+
const cipher = new RescueCipher(sharedSecret);
|
|
122
|
+
const decryptedBigInts = cipher.decrypt(ciphertext, nonce);
|
|
123
|
+
// Convert back to string
|
|
124
|
+
const decryptedBytes = new Uint8Array(decryptedBigInts.map(Number));
|
|
125
|
+
const decryptedText = new TextDecoder().decode(decryptedBytes);
|
|
126
|
+
// Parse response object
|
|
127
|
+
try {
|
|
128
|
+
const responseObj = JSON.parse(decryptedText);
|
|
129
|
+
return responseObj.response || responseObj.message || decryptedText;
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return decryptedText;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Package encrypted data for TEE transmission
|
|
137
|
+
*/
|
|
138
|
+
export function packageForTEE(encryptedData) {
|
|
139
|
+
return JSON.stringify({
|
|
140
|
+
ciphertext: encryptedData.ciphertext,
|
|
141
|
+
nonce: encryptedData.nonce,
|
|
142
|
+
publicKey: encryptedData.publicKey,
|
|
143
|
+
algorithm: 'Arcium-RescueCipher',
|
|
144
|
+
version: '1.0',
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Clear session keypair (for logout/cleanup)
|
|
149
|
+
*/
|
|
150
|
+
export function clearSession() {
|
|
151
|
+
sessionKeypair = null;
|
|
152
|
+
cachedTeePublicKey = null;
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=encryption.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.js","sourceRoot":"","sources":["../src/encryption.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @solrouter/sdk
|
|
3
|
+
*
|
|
4
|
+
* Privacy-first AI API client with end-to-end encryption.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { SolRouter } from '@solrouter/sdk';
|
|
9
|
+
*
|
|
10
|
+
* const client = new SolRouter({
|
|
11
|
+
* apiKey: 'sk_solrouter_your_key_here'
|
|
12
|
+
* });
|
|
13
|
+
*
|
|
14
|
+
* // Encrypted by default
|
|
15
|
+
* const response = await client.chat('Explain quantum computing');
|
|
16
|
+
* console.log(response.message);
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export { SolRouter } from './client.js';
|
|
20
|
+
export type { SolRouterConfig, ChatOptions, ChatResponse, EncryptedData, BalanceResponse, } from './types.js';
|
|
21
|
+
export { encrypt, decrypt, packageForTEE, clearSession, fetchTeePublicKey, } from './encryption.js';
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,YAAY,EACV,eAAe,EACf,WAAW,EACX,YAAY,EACZ,aAAa,EACb,eAAe,GAChB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,OAAO,EACP,OAAO,EACP,aAAa,EACb,YAAY,EACZ,iBAAiB,GAClB,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @solrouter/sdk
|
|
3
|
+
*
|
|
4
|
+
* Privacy-first AI API client with end-to-end encryption.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { SolRouter } from '@solrouter/sdk';
|
|
9
|
+
*
|
|
10
|
+
* const client = new SolRouter({
|
|
11
|
+
* apiKey: 'sk_solrouter_your_key_here'
|
|
12
|
+
* });
|
|
13
|
+
*
|
|
14
|
+
* // Encrypted by default
|
|
15
|
+
* const response = await client.chat('Explain quantum computing');
|
|
16
|
+
* console.log(response.message);
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export { SolRouter } from './client.js';
|
|
20
|
+
// Re-export encryption utilities for advanced use cases
|
|
21
|
+
export { encrypt, decrypt, packageForTEE, clearSession, fetchTeePublicKey, } from './encryption.js';
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAUxC,wDAAwD;AACxD,OAAO,EACL,OAAO,EACP,OAAO,EACP,aAAa,EACb,YAAY,EACZ,iBAAiB,GAClB,MAAM,iBAAiB,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SolRouter SDK Types
|
|
3
|
+
*/
|
|
4
|
+
export interface SolRouterConfig {
|
|
5
|
+
/** Your SolRouter API key (starts with sk_solrouter_) */
|
|
6
|
+
apiKey: string;
|
|
7
|
+
/** API base URL (defaults to https://solrouter-obb4.onrender.com) */
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
/** Enable encryption (defaults to true) */
|
|
10
|
+
encrypted?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface ChatOptions {
|
|
13
|
+
/** Model to use (defaults to gpt-oss-20b) */
|
|
14
|
+
model?: 'gpt-oss-20b' | 'qwen3-8b' | 'gemini-flash' | 'claude-sonnet' | 'gpt-4o-mini';
|
|
15
|
+
/** System prompt */
|
|
16
|
+
systemPrompt?: string;
|
|
17
|
+
/** Enable encryption for this request (overrides client setting) */
|
|
18
|
+
encrypted?: boolean;
|
|
19
|
+
/** Conversation ID for multi-turn conversations */
|
|
20
|
+
chatId?: string;
|
|
21
|
+
/** Enable RAG (knowledge base retrieval) */
|
|
22
|
+
useRAG?: boolean;
|
|
23
|
+
/** RAG collection to use */
|
|
24
|
+
ragCollection?: string;
|
|
25
|
+
/** Enable live web search */
|
|
26
|
+
useLiveSearch?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface ChatResponse {
|
|
29
|
+
/** The AI response message */
|
|
30
|
+
message: string;
|
|
31
|
+
/** Model used for generation */
|
|
32
|
+
model: string;
|
|
33
|
+
/** Token usage statistics */
|
|
34
|
+
usage?: {
|
|
35
|
+
promptTokens: number;
|
|
36
|
+
completionTokens: number;
|
|
37
|
+
totalTokens: number;
|
|
38
|
+
};
|
|
39
|
+
/** Cost of this request in USDC */
|
|
40
|
+
cost?: number;
|
|
41
|
+
/** Whether the request was encrypted */
|
|
42
|
+
encrypted: boolean;
|
|
43
|
+
/** Privacy attestation ID (if encrypted) */
|
|
44
|
+
privacyAttestationId?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface EncryptedData {
|
|
47
|
+
ciphertext: string;
|
|
48
|
+
nonce: string;
|
|
49
|
+
publicKey: string;
|
|
50
|
+
ephemeralPrivateKey?: string;
|
|
51
|
+
}
|
|
52
|
+
export interface BalanceResponse {
|
|
53
|
+
balance: number;
|
|
54
|
+
balanceFormatted: string;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,eAAe;IAC9B,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,6CAA6C;IAC7C,KAAK,CAAC,EAAE,aAAa,GAAG,UAAU,GAAG,cAAc,GAAG,eAAe,GAAG,aAAa,CAAC;IACtF,oBAAoB;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,4BAA4B;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6BAA6B;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,KAAK,CAAC,EAAE;QACN,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,SAAS,EAAE,OAAO,CAAC;IACnB,4CAA4C;IAC5C,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;CAC1B"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@solrouter/sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "SolRouter Privacy SDK - End-to-end encrypted AI API calls",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"dev": "tsc --watch",
|
|
22
|
+
"prepublishOnly": "npm run build"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"solrouter",
|
|
26
|
+
"privacy",
|
|
27
|
+
"ai",
|
|
28
|
+
"encryption",
|
|
29
|
+
"arcium",
|
|
30
|
+
"llm"
|
|
31
|
+
],
|
|
32
|
+
"author": "SolRouter",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/solrouter/sdk"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@arcium-hq/client": "^0.1.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"typescript": "^5.4.0",
|
|
43
|
+
"@types/node": "^20.0.0"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=18.0.0"
|
|
47
|
+
}
|
|
48
|
+
}
|