shogun-relay-sdk 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -76,6 +76,108 @@ const result = await sdk.ipfs.uploadFile(
76
76
  );
77
77
  ```
78
78
 
79
+ ## API Keys
80
+
81
+ Manage API keys for programmatic access to all relay services:
82
+
83
+ ```typescript
84
+ // List all API keys
85
+ const keys = await sdk.apiKeys.list();
86
+
87
+ // Create a new API key
88
+ const newKey = await sdk.apiKeys.create('My App Key', 30); // 30 days expiration
89
+ console.log('API Key:', newKey.token); // Save this, it's only shown once!
90
+
91
+ // Use the API key for authentication
92
+ sdk.apiKeys.useApiKey(newKey.token);
93
+
94
+ // Or use it directly
95
+ sdk.setToken(newKey.token);
96
+
97
+ // Revoke an API key
98
+ await sdk.apiKeys.revoke(newKey.keyId);
99
+ ```
100
+
101
+ **Note**: API keys work across all relay services (Drive, IPFS, etc.) and use the prefix `shogun-api-`.
102
+
103
+ ## Drive Operations
104
+
105
+ The Drive module provides file system operations for the admin drive:
106
+
107
+ ### List Files
108
+
109
+ ```typescript
110
+ // List root directory
111
+ const files = await sdk.drive.list();
112
+
113
+ // List specific directory
114
+ const files = await sdk.drive.list('folder/subfolder');
115
+ ```
116
+
117
+ ### Upload Files
118
+
119
+ ```typescript
120
+ // Upload single file
121
+ const result = await sdk.drive.uploadFile(
122
+ fileBuffer,
123
+ 'example.txt',
124
+ 'folder' // optional path
125
+ );
126
+
127
+ // Upload multiple files
128
+ const result = await sdk.drive.uploadFiles([
129
+ { file: fileBuffer1, filename: 'file1.txt' },
130
+ { file: fileBuffer2, filename: 'file2.txt' }
131
+ ], 'folder');
132
+ ```
133
+
134
+ ### Download Files
135
+
136
+ ```typescript
137
+ const fileBuffer = await sdk.drive.download('path/to/file.txt');
138
+ ```
139
+
140
+ ### Directory Operations
141
+
142
+ ```typescript
143
+ // Create directory
144
+ await sdk.drive.createDirectory('new-folder', 'parent-folder');
145
+
146
+ // Rename file/directory
147
+ await sdk.drive.rename('old-name.txt', 'new-name.txt');
148
+
149
+ // Move file/directory
150
+ await sdk.drive.move('source.txt', 'destination/folder/source.txt');
151
+
152
+ // Delete file/directory
153
+ await sdk.drive.delete('path/to/item');
154
+ ```
155
+
156
+ ### Storage Statistics
157
+
158
+ ```typescript
159
+ const stats = await sdk.drive.getStats();
160
+ console.log(`Total: ${stats.stats.totalSizeMB} MB`);
161
+ console.log(`Files: ${stats.stats.fileCount}`);
162
+ ```
163
+
164
+ ### Public Links
165
+
166
+ ```typescript
167
+ // Create a public sharing link
168
+ const link = await sdk.drive.createPublicLink('document.pdf', 7); // 7 days expiration
169
+ console.log('Public URL:', link.publicUrl);
170
+
171
+ // List all public links
172
+ const links = await sdk.drive.listPublicLinks();
173
+
174
+ // Revoke a link
175
+ await sdk.drive.revokePublicLink(link.linkId);
176
+
177
+ // Get public file URL (for direct access)
178
+ const publicUrl = sdk.drive.getPublicFileUrl(link.linkId, 'https://shogun-relay.scobrudot.dev');
179
+ ```
180
+
79
181
  ## IPFS Operations
80
182
 
81
183
  ### Upload Single File
@@ -290,6 +392,8 @@ See the main [API Documentation](../docs/API.md) for complete endpoint reference
290
392
 
291
393
  - **System**: Health checks, stats, system information
292
394
  - **IPFS**: File uploads, directory uploads, content retrieval, pinning
395
+ - **Drive**: Admin drive file system operations, public link sharing
396
+ - **API Keys**: API key management for programmatic access
293
397
  - **Deals**: Storage deal creation, activation, management
294
398
  - **Registry**: On-chain relay registry operations
295
399
  - **Network**: Network federation, reputation, relay discovery
package/dist/index.d.ts CHANGED
@@ -8,8 +8,12 @@ import { RegistryModule } from "./modules/registry";
8
8
  import { UploadsModule } from "./modules/uploads";
9
9
  import { BridgeModule } from "./modules/bridge";
10
10
  import { AnnasArchiveModule } from "./modules/annas-archive";
11
+ import { DriveModule } from "./modules/drive";
12
+ import { ApiKeysModule } from "./modules/api-keys";
11
13
  export * from "./types";
12
14
  export * from "./modules/annas-archive";
15
+ export * from "./modules/drive";
16
+ export * from "./modules/api-keys";
13
17
  export * from "./utils/wallet";
14
18
  export declare class ShogunRelaySDK {
15
19
  private client;
@@ -22,6 +26,8 @@ export declare class ShogunRelaySDK {
22
26
  uploads: UploadsModule;
23
27
  bridge: BridgeModule;
24
28
  annasArchive: AnnasArchiveModule;
29
+ drive: DriveModule;
30
+ apiKeys: ApiKeysModule;
25
31
  constructor(config: ApiClientConfig);
26
32
  setToken(token: string): void;
27
33
  }
package/dist/index.js CHANGED
@@ -25,9 +25,13 @@ const registry_1 = require("./modules/registry");
25
25
  const uploads_1 = require("./modules/uploads");
26
26
  const bridge_1 = require("./modules/bridge");
27
27
  const annas_archive_1 = require("./modules/annas-archive");
28
+ const drive_1 = require("./modules/drive");
29
+ const api_keys_1 = require("./modules/api-keys");
28
30
  // Export types
29
31
  __exportStar(require("./types"), exports);
30
32
  __exportStar(require("./modules/annas-archive"), exports);
33
+ __exportStar(require("./modules/drive"), exports);
34
+ __exportStar(require("./modules/api-keys"), exports);
31
35
  // Export wallet utilities
32
36
  __exportStar(require("./utils/wallet"), exports);
33
37
  class ShogunRelaySDK {
@@ -42,6 +46,8 @@ class ShogunRelaySDK {
42
46
  this.uploads = new uploads_1.UploadsModule(this.client);
43
47
  this.bridge = new bridge_1.BridgeModule(this.client);
44
48
  this.annasArchive = new annas_archive_1.AnnasArchiveModule(this.client);
49
+ this.drive = new drive_1.DriveModule(this.client);
50
+ this.apiKeys = new api_keys_1.ApiKeysModule(this.client);
45
51
  }
46
52
  setToken(token) {
47
53
  this.client.setToken(token);
@@ -0,0 +1,44 @@
1
+ import { ApiClient } from "../client";
2
+ export interface ApiKey {
3
+ keyId: string;
4
+ name: string;
5
+ createdAt: number;
6
+ lastUsedAt: number | null;
7
+ expiresAt: number | null;
8
+ }
9
+ export interface ApiKeyCreateResponse {
10
+ success: boolean;
11
+ keyId: string;
12
+ token: string;
13
+ name: string;
14
+ createdAt: number;
15
+ expiresAt: number | null;
16
+ message: string;
17
+ }
18
+ export interface ApiKeysListResponse {
19
+ success: boolean;
20
+ keys: ApiKey[];
21
+ }
22
+ export declare class ApiKeysModule {
23
+ private client;
24
+ constructor(client: ApiClient);
25
+ /**
26
+ * List all API keys
27
+ */
28
+ list(): Promise<ApiKeysListResponse>;
29
+ /**
30
+ * Create a new API key
31
+ */
32
+ create(name: string, expiresInDays?: number): Promise<ApiKeyCreateResponse>;
33
+ /**
34
+ * Revoke an API key
35
+ */
36
+ revoke(keyId: string): Promise<{
37
+ success: boolean;
38
+ message: string;
39
+ }>;
40
+ /**
41
+ * Set the API key as the authentication token for future requests
42
+ */
43
+ useApiKey(apiKeyToken: string): void;
44
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApiKeysModule = void 0;
4
+ class ApiKeysModule {
5
+ constructor(client) {
6
+ this.client = client;
7
+ }
8
+ /**
9
+ * List all API keys
10
+ */
11
+ async list() {
12
+ return this.client.get("/api/v1/api-keys");
13
+ }
14
+ /**
15
+ * Create a new API key
16
+ */
17
+ async create(name, expiresInDays) {
18
+ return this.client.post("/api/v1/api-keys", {
19
+ name,
20
+ expiresInDays,
21
+ });
22
+ }
23
+ /**
24
+ * Revoke an API key
25
+ */
26
+ async revoke(keyId) {
27
+ return this.client.delete(`/api/v1/api-keys/${keyId}`);
28
+ }
29
+ /**
30
+ * Set the API key as the authentication token for future requests
31
+ */
32
+ useApiKey(apiKeyToken) {
33
+ this.client.setToken(apiKeyToken);
34
+ }
35
+ }
36
+ exports.ApiKeysModule = ApiKeysModule;
@@ -0,0 +1,135 @@
1
+ import { ApiClient } from "../client";
2
+ export interface DriveFileItem {
3
+ name: string;
4
+ path: string;
5
+ type: "file" | "directory";
6
+ size: number;
7
+ modified: number;
8
+ }
9
+ export interface DriveListResponse {
10
+ success: boolean;
11
+ items: DriveFileItem[];
12
+ path: string;
13
+ }
14
+ export interface DriveStatsResponse {
15
+ success: boolean;
16
+ stats: {
17
+ totalBytes: number;
18
+ totalSizeMB: string;
19
+ totalSizeGB: string;
20
+ fileCount: number;
21
+ dirCount: number;
22
+ };
23
+ }
24
+ export interface PublicLink {
25
+ linkId: string;
26
+ filePath: string;
27
+ createdAt: number;
28
+ expiresAt: number | null;
29
+ accessCount: number;
30
+ lastAccessedAt: number | null;
31
+ }
32
+ export interface PublicLinkResponse {
33
+ success: boolean;
34
+ linkId: string;
35
+ filePath: string;
36
+ publicUrl: string;
37
+ createdAt: number;
38
+ expiresAt: number | null;
39
+ }
40
+ export interface PublicLinksListResponse {
41
+ success: boolean;
42
+ links: PublicLink[];
43
+ }
44
+ export declare class DriveModule {
45
+ private client;
46
+ constructor(client: ApiClient);
47
+ /**
48
+ * List files and folders in the specified directory
49
+ */
50
+ list(path?: string): Promise<DriveListResponse>;
51
+ /**
52
+ * Upload a single file
53
+ */
54
+ uploadFile(file: Buffer | Blob, filename: string, path?: string): Promise<{
55
+ success: boolean;
56
+ message: string;
57
+ files: Array<{
58
+ name: string;
59
+ path: string;
60
+ size: number;
61
+ }>;
62
+ }>;
63
+ /**
64
+ * Upload multiple files
65
+ */
66
+ uploadFiles(files: Array<{
67
+ file: Buffer | Blob;
68
+ filename: string;
69
+ }>, path?: string): Promise<{
70
+ success: boolean;
71
+ message: string;
72
+ files: Array<{
73
+ name: string;
74
+ path: string;
75
+ size: number;
76
+ }>;
77
+ }>;
78
+ /**
79
+ * Download a file
80
+ */
81
+ download(path: string): Promise<Buffer>;
82
+ /**
83
+ * Delete a file or directory
84
+ */
85
+ delete(path: string): Promise<{
86
+ success: boolean;
87
+ message: string;
88
+ }>;
89
+ /**
90
+ * Create a directory
91
+ */
92
+ createDirectory(name: string, path?: string): Promise<{
93
+ success: boolean;
94
+ message: string;
95
+ path: string;
96
+ }>;
97
+ /**
98
+ * Rename a file or directory
99
+ */
100
+ rename(oldPath: string, newName: string): Promise<{
101
+ success: boolean;
102
+ message: string;
103
+ }>;
104
+ /**
105
+ * Move a file or directory
106
+ */
107
+ move(sourcePath: string, destPath: string): Promise<{
108
+ success: boolean;
109
+ message: string;
110
+ }>;
111
+ /**
112
+ * Get storage statistics
113
+ */
114
+ getStats(): Promise<DriveStatsResponse>;
115
+ /**
116
+ * Create a public sharing link for a file
117
+ */
118
+ createPublicLink(filePath: string, expiresInDays?: number): Promise<PublicLinkResponse>;
119
+ /**
120
+ * List all public links
121
+ */
122
+ listPublicLinks(): Promise<PublicLinksListResponse>;
123
+ /**
124
+ * Revoke a public link
125
+ */
126
+ revokePublicLink(linkId: string): Promise<{
127
+ success: boolean;
128
+ message: string;
129
+ }>;
130
+ /**
131
+ * Get public file URL (for direct access without authentication)
132
+ * Note: This requires the baseURL from the SDK configuration to construct the full URL
133
+ */
134
+ getPublicFileUrl(linkId: string, baseURL?: string): string;
135
+ }
@@ -0,0 +1,125 @@
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.DriveModule = void 0;
7
+ const form_data_1 = __importDefault(require("form-data"));
8
+ class DriveModule {
9
+ constructor(client) {
10
+ this.client = client;
11
+ }
12
+ /**
13
+ * List files and folders in the specified directory
14
+ */
15
+ async list(path) {
16
+ const url = path ? `/api/v1/drive/list/${encodeURIComponent(path)}` : "/api/v1/drive/list";
17
+ return this.client.get(url);
18
+ }
19
+ /**
20
+ * Upload a single file
21
+ */
22
+ async uploadFile(file, filename, path) {
23
+ const formData = new form_data_1.default();
24
+ formData.append("file", file, filename);
25
+ const url = path ? `/api/v1/drive/upload/${encodeURIComponent(path)}` : "/api/v1/drive/upload";
26
+ return this.client.post(url, formData, {
27
+ headers: formData.getHeaders(),
28
+ });
29
+ }
30
+ /**
31
+ * Upload multiple files
32
+ */
33
+ async uploadFiles(files, path) {
34
+ const formData = new form_data_1.default();
35
+ files.forEach(({ file, filename }) => {
36
+ formData.append("files", file, filename);
37
+ });
38
+ const url = path ? `/api/v1/drive/upload/${encodeURIComponent(path)}` : "/api/v1/drive/upload";
39
+ return this.client.post(url, formData, {
40
+ headers: formData.getHeaders(),
41
+ });
42
+ }
43
+ /**
44
+ * Download a file
45
+ */
46
+ async download(path) {
47
+ const url = `/api/v1/drive/download/${encodeURIComponent(path)}`;
48
+ // Use the internal axios client to handle arraybuffer response
49
+ const response = await this.client.client.get(url, {
50
+ responseType: "arraybuffer",
51
+ });
52
+ return Buffer.from(response.data);
53
+ }
54
+ /**
55
+ * Delete a file or directory
56
+ */
57
+ async delete(path) {
58
+ const url = `/api/v1/drive/delete/${encodeURIComponent(path)}`;
59
+ return this.client.delete(url);
60
+ }
61
+ /**
62
+ * Create a directory
63
+ */
64
+ async createDirectory(name, path) {
65
+ const url = path ? `/api/v1/drive/mkdir/${encodeURIComponent(path)}` : "/api/v1/drive/mkdir";
66
+ return this.client.post(url, { name });
67
+ }
68
+ /**
69
+ * Rename a file or directory
70
+ */
71
+ async rename(oldPath, newName) {
72
+ return this.client.post("/api/v1/drive/rename", {
73
+ oldPath,
74
+ newName,
75
+ });
76
+ }
77
+ /**
78
+ * Move a file or directory
79
+ */
80
+ async move(sourcePath, destPath) {
81
+ return this.client.post("/api/v1/drive/move", {
82
+ sourcePath,
83
+ destPath,
84
+ });
85
+ }
86
+ /**
87
+ * Get storage statistics
88
+ */
89
+ async getStats() {
90
+ return this.client.get("/api/v1/drive/stats");
91
+ }
92
+ /**
93
+ * Create a public sharing link for a file
94
+ */
95
+ async createPublicLink(filePath, expiresInDays) {
96
+ return this.client.post("/api/v1/drive/links", {
97
+ filePath,
98
+ expiresInDays,
99
+ });
100
+ }
101
+ /**
102
+ * List all public links
103
+ */
104
+ async listPublicLinks() {
105
+ return this.client.get("/api/v1/drive/links");
106
+ }
107
+ /**
108
+ * Revoke a public link
109
+ */
110
+ async revokePublicLink(linkId) {
111
+ return this.client.delete(`/api/v1/drive/links/${linkId}`);
112
+ }
113
+ /**
114
+ * Get public file URL (for direct access without authentication)
115
+ * Note: This requires the baseURL from the SDK configuration to construct the full URL
116
+ */
117
+ getPublicFileUrl(linkId, baseURL) {
118
+ if (baseURL) {
119
+ return `${baseURL}/api/v1/drive/public/${linkId}`;
120
+ }
121
+ // If baseURL is not provided, return relative path
122
+ return `/api/v1/drive/public/${linkId}`;
123
+ }
124
+ }
125
+ exports.DriveModule = DriveModule;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shogun-relay-sdk",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "SDK for interacting with Shogun Relay API - HTTP client for IPFS, deals, registry, and network operations",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",