@qidcloud/sdk 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +99 -256
- package/dist/components/QidSignInButton.d.ts +12 -0
- package/dist/index.d.ts +23 -4
- package/dist/index.js +2249 -5
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2243 -0
- package/dist/index.mjs.map +1 -0
- package/dist/modules/auth.d.ts +23 -0
- package/dist/modules/db.d.ts +21 -0
- package/dist/modules/edge.d.ts +33 -0
- package/dist/modules/logs.d.ts +20 -0
- package/dist/modules/vault.d.ts +34 -0
- package/dist/types.d.ts +46 -0
- package/package.json +36 -15
- package/dist/QidCloud.d.ts +0 -31
- package/dist/QidCloud.js +0 -142
- package/dist/crypto/pqc.d.ts +0 -12
- package/dist/crypto/pqc.js +0 -91
- package/dist/storage/index.d.ts +0 -18
- package/dist/storage/index.js +0 -58
- package/dist/utils.d.ts +0 -5
- package/dist/utils.js +0 -46
- package/src/QidCloud.ts +0 -171
- package/src/crypto/pqc.ts +0 -79
- package/src/index.ts +0 -7
- package/src/storage/index.ts +0 -49
- package/src/utils.ts +0 -48
- package/tsconfig.json +0 -20
- package/verify_sdk.ts +0 -53
package/README.md
CHANGED
|
@@ -1,310 +1,153 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @qidcloud/sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The official JavaScript/TypeScript SDK for QidCloud. Build PQC-secured, enclave-backed applications in minutes.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 🚀 30-Minute Quick Start
|
|
6
6
|
|
|
7
|
+
### 1. Install
|
|
7
8
|
```bash
|
|
8
|
-
npm install @
|
|
9
|
+
npm install @qidcloud/sdk
|
|
9
10
|
```
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
### 2. Initialize
|
|
13
13
|
```typescript
|
|
14
|
-
import {
|
|
14
|
+
import { QidCloud } from '@qidcloud/sdk';
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// baseUrl is optional, defaults to https://qgate.onrender.com
|
|
16
|
+
const qid = new QidCloud({
|
|
17
|
+
apiKey: 'your_api_key', // Found in QidCloud Console -> Settings
|
|
18
|
+
tenantId: 'your_project_id'
|
|
20
19
|
});
|
|
21
|
-
|
|
22
|
-
// Register a new user
|
|
23
|
-
const user = await qgate.register('alice');
|
|
24
|
-
|
|
25
|
-
// Login
|
|
26
|
-
const token = await qgate.login();
|
|
27
|
-
|
|
28
|
-
// Get user profile
|
|
29
|
-
const profile = await qgate.getProfile();
|
|
30
|
-
|
|
31
|
-
// Logout
|
|
32
|
-
await qgate.logout();
|
|
33
20
|
```
|
|
34
21
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
✅ **Quantum-Resistant** - Uses CRYSTALS-Dilithium and Kyber
|
|
38
|
-
✅ **Passwordless** - No passwords to remember or manage
|
|
39
|
-
✅ **Zero-Knowledge** - Keys never leave the device
|
|
40
|
-
✅ **TypeScript Support** - Full type definitions included
|
|
41
|
-
✅ **Browser & Node.js** - Works everywhere
|
|
22
|
+
---
|
|
42
23
|
|
|
43
|
-
##
|
|
24
|
+
## 🔑 Identity (`qid.auth`)
|
|
44
25
|
|
|
45
|
-
|
|
26
|
+
Enforce Pure Post-Quantum Identity with zero passwords.
|
|
46
27
|
|
|
47
|
-
|
|
28
|
+
### `createSession()`
|
|
29
|
+
Initiates a new QR handshake session.
|
|
30
|
+
- **Returns**: `Promise<QidAuthSession>`
|
|
31
|
+
- `sessionId`: String
|
|
32
|
+
- `qrData`: String (Format: `qid:handshake:...`)
|
|
33
|
+
- `expiresAt`: Number (Timestamp)
|
|
48
34
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
-
|
|
52
|
-
- `
|
|
35
|
+
### `listen(sessionId, onAuthorized, onDenied)`
|
|
36
|
+
Listens for the mobile app to approve the session.
|
|
37
|
+
- **`sessionId`**: String (from `createSession`)
|
|
38
|
+
- **`onAuthorized`**: `(token: string) => void` - Callback when login succeeds.
|
|
39
|
+
- **`onDenied`**: `(msg: string) => void` - Callback when user rejects.
|
|
53
40
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
baseUrl: 'https://custom-backend.com' // optional
|
|
59
|
-
});
|
|
60
|
-
```
|
|
41
|
+
### `getProfile(token)`
|
|
42
|
+
Fetches user details.
|
|
43
|
+
- **`token`**: String (The session token)
|
|
44
|
+
- **Returns**: `Promise<QidUser>`
|
|
61
45
|
|
|
62
46
|
---
|
|
63
47
|
|
|
64
|
-
|
|
48
|
+
## 🗄️ Enclave DB (`qid.db`)
|
|
65
49
|
|
|
66
|
-
|
|
50
|
+
Programmatic SQL access to your project's isolated Postgres schema.
|
|
67
51
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
- `
|
|
52
|
+
### `query(sql, params, userToken?)`
|
|
53
|
+
Executor for **all** SQL operations (Select, Insert, Update, Delete, and DDL).
|
|
54
|
+
- **`sql`**: String (e.g., `'INSERT INTO users (name) VALUES ($1) RETURNING *'`)
|
|
55
|
+
- **`params`**: Array (Parameterized values to prevent SQL injection)
|
|
56
|
+
- **`userToken`**: Optional String (Required if the user's role must be checked for Mutations/Schema changes)
|
|
57
|
+
- **Returns**: `Promise<QidDbResponse>`
|
|
71
58
|
|
|
72
|
-
**
|
|
59
|
+
**Examples:**
|
|
60
|
+
```javascript
|
|
61
|
+
// Mutation (Write)
|
|
62
|
+
await qid.db.query('INSERT INTO logs (message) VALUES ($1)', ['User logged in']);
|
|
73
63
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const user = await qgate.register('alice');
|
|
77
|
-
console.log(user);
|
|
78
|
-
// { userId: "uuid", username: "alice", role: "user" }
|
|
64
|
+
// Schema (DDL)
|
|
65
|
+
await qid.db.query('CREATE TABLE IF NOT EXISTS test (id SERIAL PRIMARY KEY)');
|
|
79
66
|
```
|
|
80
67
|
|
|
81
|
-
|
|
68
|
+
### `setup(userToken?)`
|
|
69
|
+
Ensures the project's isolated Postgres schema is properly initialized.
|
|
70
|
+
- **`userToken`**: Optional String
|
|
71
|
+
- **Returns**: `Promise<{ success: boolean; schemaName: string }>`
|
|
82
72
|
|
|
83
73
|
---
|
|
84
74
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
Authenticate using stored identity.
|
|
88
|
-
|
|
89
|
-
**Returns:** `Promise<string>` - Session token
|
|
90
|
-
|
|
91
|
-
**Example:**
|
|
92
|
-
```typescript
|
|
93
|
-
const token = await qgate.login();
|
|
94
|
-
// Use token for API requests
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
**Throws:**
|
|
98
|
-
- `NO_IDENTITY` - User must register first
|
|
99
|
-
- `MISSING_USER_ID` - Re-registration required
|
|
75
|
+
## ⚡ Edge Compute (`qid.edge`)
|
|
100
76
|
|
|
101
|
-
|
|
77
|
+
Invoke serverless functions within your enclave.
|
|
102
78
|
|
|
103
|
-
### `
|
|
79
|
+
### `invoke(name, params, userToken?)`
|
|
80
|
+
- **`name`**: String (Function name)
|
|
81
|
+
- **`params`**: Object (Arguments)
|
|
82
|
+
- **`userToken`**: Optional String
|
|
83
|
+
- **Returns**: `Promise<QidEdgeResponse>`
|
|
104
84
|
|
|
105
|
-
|
|
85
|
+
### `list()`
|
|
86
|
+
Lists all deployed functions in the project.
|
|
106
87
|
|
|
107
|
-
|
|
88
|
+
### `getLogs(name, userToken?)`
|
|
89
|
+
Fetches the latest execution logs for a specific function.
|
|
90
|
+
- **`name`**: String (Function name)
|
|
108
91
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const profile = await qgate.getProfile();
|
|
112
|
-
console.log(profile);
|
|
113
|
-
// { userId: "uuid", username: "alice", role: "user", status: "active" }
|
|
114
|
-
```
|
|
92
|
+
### `getProjectLogs(userToken?)`
|
|
93
|
+
Fetches all enclave-wide system logs. Great for debugging connectivity/auth issues.
|
|
115
94
|
|
|
116
|
-
|
|
95
|
+
### `delete(name, userToken?)`
|
|
96
|
+
Permanently destroys a function from the enclave.
|
|
117
97
|
|
|
118
98
|
---
|
|
119
99
|
|
|
120
|
-
|
|
100
|
+
## 📦 Vault Storage (`qid.vault`)
|
|
121
101
|
|
|
122
|
-
|
|
102
|
+
Secure file management.
|
|
123
103
|
|
|
124
|
-
|
|
104
|
+
### `upload(file, fileName, metadata?, userToken?)`
|
|
105
|
+
- **`file`**: Buffer | Blob
|
|
106
|
+
- **`fileName`**: String
|
|
107
|
+
- **`metadata`**: Object (Custom tags/E2EE keys)
|
|
108
|
+
- **`userToken`**: Optional String
|
|
125
109
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
await qgate.logout();
|
|
129
|
-
```
|
|
110
|
+
### `list(userToken?)`
|
|
111
|
+
Lists enclave files.
|
|
130
112
|
|
|
131
|
-
|
|
113
|
+
### `delete(fileId, userToken?)`
|
|
114
|
+
Permanently destroys a file from storage.
|
|
132
115
|
|
|
133
116
|
---
|
|
134
117
|
|
|
135
|
-
|
|
118
|
+
## 📝 App Logs (`qid.logs`)
|
|
136
119
|
|
|
137
|
-
|
|
120
|
+
Audit logs for your application logic.
|
|
138
121
|
|
|
139
|
-
|
|
122
|
+
### `write(message, source?, level?, metadata?)`
|
|
123
|
+
- **`message`**: String (Log content)
|
|
124
|
+
- **`source`**: String (Optional, e.g., 'frontend', 'auth-service')
|
|
125
|
+
- **`level`**: String (Default: `'info'`)
|
|
126
|
+
- **`metadata`**: Object (e.g., `{ userId: '123', event: 'checkout' }`)
|
|
140
127
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if (await qgate.hasIdentity()) {
|
|
144
|
-
await qgate.login();
|
|
145
|
-
} else {
|
|
146
|
-
await qgate.register('alice');
|
|
147
|
-
}
|
|
148
|
-
```
|
|
128
|
+
### `fetch(query?)`
|
|
129
|
+
- **`query`**: Object (e.g., `{ limit: 50, level: 'error' }`)
|
|
149
130
|
|
|
150
131
|
---
|
|
151
132
|
|
|
152
|
-
##
|
|
153
|
-
|
|
154
|
-
### Custom Storage
|
|
155
|
-
|
|
156
|
-
Provide your own storage implementation:
|
|
157
|
-
|
|
158
|
-
```typescript
|
|
159
|
-
import { QGateClient, IStorage } from '@pqcloud/sdk';
|
|
160
|
-
|
|
161
|
-
class CustomStorage implements IStorage {
|
|
162
|
-
async getItem(key: string): Promise<string | null> {
|
|
163
|
-
// Your implementation
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
async setItem(key: string, value: string): Promise<void> {
|
|
167
|
-
// Your implementation
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
async removeItem(key: string): Promise<void> {
|
|
171
|
-
// Your implementation
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const qgate = new QGateClient({
|
|
176
|
-
apiKey: 'your-key',
|
|
177
|
-
storage: new CustomStorage()
|
|
178
|
-
});
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
### Error Handling
|
|
133
|
+
## 🎨 UI Components (React)
|
|
182
134
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
if (error.message === 'NO_IDENTITY') {
|
|
188
|
-
console.log('User not registered');
|
|
189
|
-
} else if (error.response?.status === 401) {
|
|
190
|
-
console.log('Authentication failed');
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
### Session Management
|
|
196
|
-
|
|
197
|
-
```typescript
|
|
198
|
-
// Check if user is logged in
|
|
199
|
-
const hasIdentity = await qgate.hasIdentity();
|
|
200
|
-
|
|
201
|
-
// Auto-login on app start
|
|
202
|
-
if (hasIdentity) {
|
|
203
|
-
try {
|
|
204
|
-
await qgate.login();
|
|
205
|
-
} catch {
|
|
206
|
-
// Handle expired/invalid session
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
## TypeScript
|
|
212
|
-
|
|
213
|
-
Full TypeScript support included:
|
|
214
|
-
|
|
215
|
-
```typescript
|
|
216
|
-
import { QGateClient, QGateConfig, UserProfile } from '@pqcloud/sdk';
|
|
217
|
-
|
|
218
|
-
const config: QGateConfig = {
|
|
219
|
-
apiKey: 'your-key'
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
const qgate = new QGateClient(config);
|
|
223
|
-
|
|
224
|
-
const profile: UserProfile = await qgate.getProfile();
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
## Security Notes
|
|
228
|
-
|
|
229
|
-
🔒 **Private keys never leave the device**
|
|
230
|
-
🔒 **All communication is encrypted**
|
|
231
|
-
🔒 **Quantum-resistant cryptography**
|
|
232
|
-
🔒 **Store API keys securely (environment variables)**
|
|
135
|
+
### `QidSignInButton`
|
|
136
|
+
The easiest way to add QR login.
|
|
137
|
+
```tsx
|
|
138
|
+
import { QidSignInButton } from '@qidcloud/sdk';
|
|
233
139
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
import { QGateClient } from '@pqcloud/sdk';
|
|
241
|
-
|
|
242
|
-
const qgate = new QGateClient({ apiKey: process.env.REACT_APP_QGATE_KEY });
|
|
243
|
-
|
|
244
|
-
function App() {
|
|
245
|
-
const [user, setUser] = useState(null);
|
|
246
|
-
|
|
247
|
-
useEffect(() => {
|
|
248
|
-
async function init() {
|
|
249
|
-
if (await qgate.hasIdentity()) {
|
|
250
|
-
await qgate.login();
|
|
251
|
-
const profile = await qgate.getProfile();
|
|
252
|
-
setUser(profile);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
init();
|
|
256
|
-
}, []);
|
|
257
|
-
|
|
258
|
-
const register = async (username) => {
|
|
259
|
-
const user = await qgate.register(username);
|
|
260
|
-
setUser(user);
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
const logout = async () => {
|
|
264
|
-
await qgate.logout();
|
|
265
|
-
setUser(null);
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
return user ? (
|
|
269
|
-
<div>
|
|
270
|
-
<h1>Welcome, {user.username}!</h1>
|
|
271
|
-
<button onClick={logout}>Logout</button>
|
|
272
|
-
</div>
|
|
273
|
-
) : (
|
|
274
|
-
<button onClick={() => register('alice')}>Register</button>
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
### Node.js Backend
|
|
280
|
-
|
|
281
|
-
```javascript
|
|
282
|
-
const { QGateClient } = require('@pqcloud/sdk');
|
|
283
|
-
|
|
284
|
-
const qgate = new QGateClient({
|
|
285
|
-
apiKey: process.env.QGATE_API_KEY
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
async function authenticateUser(username) {
|
|
289
|
-
if (!await qgate.hasIdentity()) {
|
|
290
|
-
await qgate.register(username);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
const token = await qgate.login();
|
|
294
|
-
return token;
|
|
295
|
-
}
|
|
140
|
+
<QidSignInButton
|
|
141
|
+
sdk={qid}
|
|
142
|
+
onSuccess={(user, token) => console.log(user)}
|
|
143
|
+
onError={(err) => alert(err)}
|
|
144
|
+
buttonText="Authorize with QidCloud"
|
|
145
|
+
/>
|
|
296
146
|
```
|
|
297
147
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
## License
|
|
305
|
-
|
|
306
|
-
ISC
|
|
307
|
-
|
|
308
|
-
---
|
|
309
|
-
|
|
310
|
-
**Built with ❤️ by the Q-Gate Team**
|
|
148
|
+
**Props:**
|
|
149
|
+
- `sdk`: Instance of `QidCloud`
|
|
150
|
+
- `onSuccess`: `(user, token) => void`
|
|
151
|
+
- `onError`: `(error) => void`
|
|
152
|
+
- `buttonText`: String (Default: "Login with QidCloud")
|
|
153
|
+
- `className`: String (Custom CSS class)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { QidCloud } from '../index';
|
|
3
|
+
import { QidUser } from '../types';
|
|
4
|
+
interface QidSignInButtonProps {
|
|
5
|
+
sdk: QidCloud;
|
|
6
|
+
onSuccess: (user: QidUser, token: string) => void;
|
|
7
|
+
onError?: (error: string) => void;
|
|
8
|
+
className?: string;
|
|
9
|
+
buttonText?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const QidSignInButton: React.FC<QidSignInButtonProps>;
|
|
12
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
1
|
+
import { AxiosInstance } from 'axios';
|
|
2
|
+
import { QidConfig } from './types';
|
|
3
|
+
import { AuthModule } from './modules/auth';
|
|
4
|
+
import { DbModule } from './modules/db';
|
|
5
|
+
import { EdgeModule } from './modules/edge';
|
|
6
|
+
import { VaultModule } from './modules/vault';
|
|
7
|
+
import { LogsModule } from './modules/logs';
|
|
8
|
+
export declare class QidCloud {
|
|
9
|
+
private config;
|
|
10
|
+
api: AxiosInstance;
|
|
11
|
+
auth: AuthModule;
|
|
12
|
+
db: DbModule;
|
|
13
|
+
edge: EdgeModule;
|
|
14
|
+
vault: VaultModule;
|
|
15
|
+
logs: LogsModule;
|
|
16
|
+
constructor(config: QidConfig);
|
|
17
|
+
/**
|
|
18
|
+
* Get the current project configuration
|
|
19
|
+
*/
|
|
20
|
+
getConfig(): QidConfig;
|
|
21
|
+
}
|
|
5
22
|
export default QidCloud;
|
|
23
|
+
export * from './types';
|
|
24
|
+
export { QidSignInButton } from './components/QidSignInButton';
|