rotur-sdk 1.0.0 → 1.0.1

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.
Files changed (2) hide show
  1. package/README.md +302 -0
  2. package/package.json +2 -2
package/README.md ADDED
@@ -0,0 +1,302 @@
1
+ # rotur-sdk
2
+
3
+ The official TypeScript SDK for the [Rotur](https://rotur.dev) platform. Covers auth, profiles, posts, credits, keys, groups, items, gifts, tokens, validators, status, files, cosmetics, push notifications, and more — all with full type safety.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install rotur-sdk
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```ts
14
+ import { Rotur } from "rotur-sdk";
15
+
16
+ const rotur = new Rotur();
17
+
18
+ // Browser auth - opens the Rotur login popup
19
+ await rotur.login();
20
+
21
+ // Or provide a token you already have
22
+ const rotur = new Rotur({ token: "your-token-here" });
23
+ ```
24
+
25
+ ## API Reference
26
+
27
+ ### Authentication
28
+
29
+ ```ts
30
+ // Popup-based OAuth flow (browser only)
31
+ await rotur.login({ system: "my-app", timeout: 60_000 });
32
+
33
+ // Check current auth state
34
+ rotur.loggedIn; // boolean
35
+ rotur.token; // string | null
36
+
37
+ // Set/refresh token manually
38
+ rotur.setToken("new-token");
39
+
40
+ // Logout (clears token + disconnects socket)
41
+ rotur.logout();
42
+ ```
43
+
44
+ ### Link-based Auth (for CLI / server)
45
+
46
+ ```ts
47
+ const code = await rotur.link.getCode();
48
+ console.log(`Visit https://rotur.dev/link and enter: ${code}`);
49
+
50
+ // Polls until the user links on the website
51
+ const token = await rotur.link.pollUntilLinked(code);
52
+ ```
53
+
54
+ ### Profiles
55
+
56
+ ```ts
57
+ const profile = await rotur.profiles.get("username");
58
+ const { exists } = await rotur.profiles.exists("username");
59
+ const avatarUrl = rotur.profiles.getAvatarUrl("username");
60
+ ```
61
+
62
+ ### Account (me)
63
+
64
+ ```ts
65
+ await rotur.me.get();
66
+ await rotur.me.update("bio", "hello world");
67
+ await rotur.me.transfer("recipient", 100, "a note");
68
+ await rotur.me.claimDaily();
69
+ await rotur.me.badges();
70
+ await rotur.me.block("username");
71
+ await rotur.me.unblock("username");
72
+ await rotur.me.checkAuth();
73
+ ```
74
+
75
+ ### Posts
76
+
77
+ ```ts
78
+ const post = await rotur.posts.create("Hello from the SDK!");
79
+ await rotur.posts.reply(post.id, "Nice post!");
80
+ await rotur.posts.like(post.id);
81
+ await rotur.posts.repost(post.id);
82
+ await rotur.posts.pin(post.id);
83
+
84
+ const feed = await rotur.posts.feed(100, 0);
85
+ const top = await rotur.posts.top(50, 24);
86
+ const results = await rotur.posts.search("query");
87
+ ```
88
+
89
+ ### Friends
90
+
91
+ ```ts
92
+ const { friends } = await rotur.friends.list();
93
+ await rotur.friends.request("username");
94
+ await rotur.friends.accept("username");
95
+ await rotur.friends.remove("username");
96
+ ```
97
+
98
+ ### Following
99
+
100
+ ```ts
101
+ await rotur.following.follow("username");
102
+ await rotur.following.unfollow("username");
103
+ const { followers } = await rotur.following.followers("username");
104
+ const { following } = await rotur.following.following("username");
105
+ ```
106
+
107
+ ### Keys
108
+
109
+ ```ts
110
+ await rotur.keys.create("my-key", { price: 50, subscription: true });
111
+ const myKeys = await rotur.keys.mine();
112
+ const key = await rotur.keys.get("key-id");
113
+ const { owned } = await rotur.keys.check("username", "key-name");
114
+ await rotur.keys.buy("key-id");
115
+ ```
116
+
117
+ ### Items
118
+
119
+ ```ts
120
+ const item = await rotur.items.create({ name: "sword", price: 100, selling: true });
121
+ const item = await rotur.items.get("sword");
122
+ const items = await rotur.items.list("username");
123
+ await rotur.items.buy("sword");
124
+ await rotur.items.sell("sword");
125
+ ```
126
+
127
+ ### Gifts
128
+
129
+ ```ts
130
+ await rotur.gifts.create(500, { note: "Happy birthday!", expiresInHrs: 48 });
131
+ const { gift } = await rotur.gifts.get("code");
132
+ await rotur.gifts.claim("code");
133
+ ```
134
+
135
+ ### Tokens (sub-tokens / scoped access)
136
+
137
+ ```ts
138
+ const { permissions, groups } = await rotur.tokens.permissions();
139
+ const { tokens } = await rotur.tokens.list();
140
+
141
+ const sub = await rotur.tokens.create("bot-token", [
142
+ "posts:view", "posts:create", "account:profile"
143
+ ], { expiresInHrs: 24, origin: "my-app" });
144
+
145
+ await rotur.tokens.revoke(sub.id);
146
+ ```
147
+
148
+ ### Groups
149
+
150
+ ```ts
151
+ const group = await rotur.groups.create("devs", "Developers", {
152
+ description: "A group for devs",
153
+ public: true,
154
+ joinPolicy: "OPEN",
155
+ });
156
+
157
+ await rotur.groups.join("devs");
158
+ await rotur.groups.represent("devs");
159
+ const announcements = await rotur.groups.announcements("devs");
160
+ const roles = await rotur.groups.roles("devs");
161
+ await rotur.groups.assignRole("devs", userId, roleId);
162
+ ```
163
+
164
+ ### Cosmetics
165
+
166
+ ```ts
167
+ const shop = await rotur.cosmetics.shop({ sort: "newest", limit: 20 });
168
+ const mine = await rotur.cosmetics.mine();
169
+ await rotur.cosmetics.purchase("cosmetic-id");
170
+ await rotur.cosmetics.equip("cosmetic-id");
171
+ await rotur.cosmetics.unequip("hat");
172
+ ```
173
+
174
+ ### Files
175
+
176
+ ```ts
177
+ const files = await rotur.files.index();
178
+ const { used, max } = await rotur.files.usage();
179
+ const file = await rotur.files.getByUUID("uuid");
180
+ const file = await rotur.files.getByPath("path/to/file");
181
+ await rotur.files.upload({ /* file data */ });
182
+ ```
183
+
184
+ ### Push Notifications
185
+
186
+ ```ts
187
+ const { public_key } = await rotur.push.vapidKeys();
188
+ await rotur.push.register(endpoint, p256dh, auth, "my-app", "fingerprint");
189
+ const { endpoints } = await rotur.push.endpoints();
190
+ await rotur.push.send("username", "my-app", { title: "Hi!", body: "You have a message" });
191
+ ```
192
+
193
+ ### Status & Validators
194
+
195
+ ```ts
196
+ const status = await rotur.status.get("username");
197
+ const { validator } = await rotur.validators.generate("key");
198
+ const result = await rotur.validators.validate(validator, "key");
199
+ ```
200
+
201
+ ### Standing, Stats, DevFund, Check
202
+
203
+ ```ts
204
+ const standing = await rotur.standing.get("username");
205
+ const economy = await rotur.stats.economy();
206
+ await rotur.devfund.escrowTransfer(100, "petition-id");
207
+ const { banned } = await rotur.check.banned(["user1", "user2"]);
208
+ ```
209
+
210
+ ## WebSocket (Real-time)
211
+
212
+ ```ts
213
+ // Connect after login
214
+ const { user_id, username } = await rotur.connectSocket();
215
+
216
+ // Join presence rooms
217
+ rotur.socket.join(["lobby", "chat"]);
218
+
219
+ // Listen for events
220
+ rotur.socket.on("member_join", (msg) => {
221
+ console.log(`${msg.username} joined ${msg.room}`);
222
+ });
223
+
224
+ rotur.socket.on("status_update", (msg) => {
225
+ console.log(`${msg.username} is now ${msg.presence}`);
226
+ });
227
+
228
+ // Set your own status
229
+ rotur.socket.setStatus("Building something cool", "online");
230
+
231
+ // Rich presence — "Playing" activity
232
+ rotur.socket.setPlaying("My Game", {
233
+ title: "Level 3",
234
+ status: "In-game",
235
+ url: "https://mygame.com",
236
+ });
237
+
238
+ // "Listening to" activity
239
+ rotur.socket.setMusic("Spotify", {
240
+ title: "Song Name",
241
+ artist: "Artist",
242
+ album: "Album",
243
+ start: Date.now(),
244
+ end: Date.now() + 180_000,
245
+ });
246
+
247
+ // Wildcard — receive every message
248
+ rotur.socket.on("*", (msg) => console.log(msg.cmd, msg));
249
+
250
+ // Disconnect
251
+ rotur.socket.disconnect();
252
+ ```
253
+
254
+ The socket auto-reconnects with exponential backoff and sends heartbeats every 25s.
255
+
256
+ ## Error Handling
257
+
258
+ ```ts
259
+ import { ApiError, AuthError } from "rotur-sdk";
260
+
261
+ try {
262
+ await rotur.me.transfer("user", 1000);
263
+ } catch (e) {
264
+ if (e instanceof ApiError) {
265
+ console.log(e.status); // HTTP status code
266
+ console.log(e.data); // response body
267
+ console.log(e.message); // human-readable error
268
+ }
269
+ }
270
+
271
+ try {
272
+ await rotur.login();
273
+ } catch (e) {
274
+ if (e instanceof AuthError) {
275
+ console.log(e.code); // "timeout" | "aborted" | "popup_blocked" | "no_token"
276
+ }
277
+ }
278
+ ```
279
+
280
+ ## Building
281
+
282
+ ```bash
283
+ npm run build # build CJS + ESM + types via tsup
284
+ npm run dev # watch mode
285
+ npm run typecheck # tsc --noEmit
286
+ npm test # vitest
287
+ ```
288
+
289
+ ## Exports
290
+
291
+ | Export | Description |
292
+ |---|---|
293
+ | `Rotur` | Main client class |
294
+ | `RoturSocket` | WebSocket connection (real-time presence) |
295
+ | `ApiError` | HTTP error with `status` and `data` |
296
+ | `performAuth`, `AuthError` | Browser auth flow |
297
+ | `AuthOptions`, `AuthResult` | Auth option types |
298
+ | All types from `types.ts` | `UserProfile`, `NetPost`, `GroupPublic`, `WSMessage`, etc. |
299
+
300
+ ## License
301
+
302
+ MIT
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rotur-sdk",
3
- "version": "1.0.0",
4
- "description": "The official SDK for the Rotur platform auth, profiles, posts, credits, keys, groups, items, gifts, tokens, validators, status, files, cosmetics, push notifications, and more",
3
+ "version": "1.0.1",
4
+ "description": "The official SDK for the Rotur platform - auth, profiles, posts, credits, keys, groups, items, gifts, tokens, validators, status, files, cosmetics, push notifications, and more",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",