@crosspost/sdk 0.1.3 → 0.1.5
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/LICENSE +21 -0
- package/README.md +85 -93
- package/dist/index.cjs +82 -169
- package/dist/index.d.cts +18 -43
- package/dist/index.d.ts +18 -43
- package/dist/index.js +78 -150
- package/package.json +2 -4
- package/src/core/client.ts +3 -5
- package/src/core/request.ts +1 -11
- package/src/index.ts +3 -12
- package/src/utils/error.ts +300 -0
- package/src/utils/cookie.ts +0 -91
- package/src/utils/error-utils.ts +0 -310
package/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 Open Crosspost
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
@@ -13,34 +13,22 @@ bun install @crosspost/sdk
|
|
13
13
|
```typescript
|
14
14
|
import { ApiError, CrosspostClient, isAuthError, PlatformError } from '@crosspost/sdk';
|
15
15
|
|
16
|
-
// Initialize the client
|
16
|
+
// Initialize the client (authentication can be provided later)
|
17
17
|
const client = new CrosspostClient({
|
18
18
|
baseUrl: 'https://your-crosspost-api.com', // Optional: Defaults to official API
|
19
|
-
nearAuthData: {
|
20
|
-
accountId: 'your-account.near',
|
21
|
-
publicKey: 'ed25519:...',
|
22
|
-
signature: '...',
|
23
|
-
message: '...',
|
24
|
-
},
|
25
|
-
});
|
26
|
-
|
27
|
-
// Or initialize with cookie-based authentication (will auto-load from cookie if available)
|
28
|
-
const cookieClient = new CrosspostClient({
|
29
|
-
baseUrl: 'https://your-crosspost-api.com',
|
30
|
-
// No nearAuthData provided - will check for cookie
|
31
19
|
});
|
32
20
|
|
33
|
-
// Set authentication
|
34
|
-
|
21
|
+
// Set authentication with fresh signature for the request
|
22
|
+
client.setAuthentication({
|
35
23
|
accountId: 'your-account.near',
|
36
24
|
publicKey: 'ed25519:...',
|
37
25
|
signature: '...',
|
38
26
|
message: '...',
|
39
27
|
});
|
40
28
|
|
41
|
-
// Check if client
|
42
|
-
if (
|
43
|
-
console.log('Client
|
29
|
+
// Check if client has authentication data set
|
30
|
+
if (client.isAuthenticated()) {
|
31
|
+
console.log('Client has authentication data');
|
44
32
|
}
|
45
33
|
|
46
34
|
// NEAR Account Authorization
|
@@ -110,6 +98,7 @@ async function revokePlatformAuth(platform) {
|
|
110
98
|
async function createPost() {
|
111
99
|
try {
|
112
100
|
const response = await client.post.createPost({
|
101
|
+
targets: [{ platform: 'twitter', userId: 'your-twitter-id' }],
|
113
102
|
content: {
|
114
103
|
text: 'Hello from Crosspost SDK!',
|
115
104
|
},
|
@@ -178,13 +167,21 @@ constructor(config?: {
|
|
178
167
|
|
179
168
|
### Post API (client.post)
|
180
169
|
|
181
|
-
|
182
|
-
|
183
|
-
- `
|
184
|
-
-
|
185
|
-
|
186
|
-
|
187
|
-
|
170
|
+
Each post operation accepts a request object that includes:
|
171
|
+
|
172
|
+
- `targets`: Array of `{ platform: string, userId: string }` specifying where to perform the action
|
173
|
+
- Additional parameters specific to each operation
|
174
|
+
|
175
|
+
Available methods:
|
176
|
+
|
177
|
+
- `createPost(request: CreatePostRequest): Promise<CreatePostResponse>` - Creates posts on specified
|
178
|
+
platforms
|
179
|
+
- `repost(request: RepostRequest): Promise<RepostResponse>` - Reposts an existing post
|
180
|
+
- `quotePost(request: QuotePostRequest): Promise<QuotePostResponse>` - Quotes an existing post
|
181
|
+
- `replyToPost(request: ReplyToPostRequest): Promise<ReplyToPostResponse>` - Replies to a post
|
182
|
+
- `likePost(request: LikePostRequest): Promise<LikePostResponse>` - Likes a post
|
183
|
+
- `unlikePost(request: UnlikePostRequest): Promise<UnlikePostResponse>` - Unlikes a post
|
184
|
+
- `deletePost(request: DeletePostRequest): Promise<DeletePostResponse>` - Deletes posts
|
188
185
|
|
189
186
|
### Activity API (client.activity)
|
190
187
|
|
@@ -249,51 +246,81 @@ const result = await apiWrapper(
|
|
249
246
|
### Creating a Post
|
250
247
|
|
251
248
|
```typescript
|
252
|
-
// Create a
|
249
|
+
// Create a text post on Twitter
|
253
250
|
const textPostResponse = await client.post.createPost({
|
254
|
-
|
251
|
+
targets: [{
|
252
|
+
platform: 'twitter',
|
253
|
+
userId: 'your-twitter-id',
|
254
|
+
}],
|
255
|
+
content: [{
|
255
256
|
text: 'Hello from Crosspost SDK!',
|
256
|
-
},
|
257
|
+
}],
|
257
258
|
});
|
258
259
|
|
259
|
-
// Create a post with media
|
260
|
+
// Create a post with media on multiple platforms
|
260
261
|
const mediaPostResponse = await client.post.createPost({
|
261
|
-
|
262
|
+
targets: [
|
263
|
+
{ platform: 'twitter', userId: 'your-twitter-id' },
|
264
|
+
{ platform: 'facebook', userId: 'your-facebook-id' },
|
265
|
+
],
|
266
|
+
content: [{
|
262
267
|
text: 'Check out this image!',
|
263
|
-
media: [
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
},
|
268
|
+
media: [{
|
269
|
+
data: imageBlob,
|
270
|
+
mimeType: 'image/jpeg',
|
271
|
+
altText: 'A beautiful sunset',
|
272
|
+
}],
|
273
|
+
}],
|
270
274
|
});
|
271
275
|
```
|
272
276
|
|
273
277
|
### Post Interactions
|
274
278
|
|
275
279
|
```typescript
|
276
|
-
// Like a post
|
280
|
+
// Like a post on Twitter
|
277
281
|
await client.post.likePost({
|
282
|
+
targets: [{
|
283
|
+
platform: 'twitter',
|
284
|
+
userId: 'your-twitter-id',
|
285
|
+
}],
|
286
|
+
platform: 'twitter',
|
278
287
|
postId: '1234567890',
|
279
288
|
});
|
280
289
|
|
281
|
-
// Repost
|
290
|
+
// Repost on multiple platforms
|
282
291
|
await client.post.repost({
|
292
|
+
targets: [
|
293
|
+
{ platform: 'twitter', userId: 'your-twitter-id' },
|
294
|
+
{ platform: 'facebook', userId: 'your-facebook-id' },
|
295
|
+
],
|
296
|
+
platform: 'twitter',
|
283
297
|
postId: '1234567890',
|
284
298
|
});
|
285
299
|
|
286
300
|
// Reply to a post
|
287
301
|
await client.post.replyToPost({
|
302
|
+
targets: [{
|
303
|
+
platform: 'twitter',
|
304
|
+
userId: 'your-twitter-id',
|
305
|
+
}],
|
306
|
+
platform: 'twitter',
|
288
307
|
postId: '1234567890',
|
289
|
-
content: {
|
308
|
+
content: [{
|
290
309
|
text: 'This is a reply!',
|
291
|
-
},
|
310
|
+
}],
|
292
311
|
});
|
293
312
|
|
294
|
-
// Delete
|
313
|
+
// Delete posts
|
295
314
|
await client.post.deletePost({
|
296
|
-
|
315
|
+
targets: [{
|
316
|
+
platform: 'twitter',
|
317
|
+
userId: 'your-twitter-id',
|
318
|
+
}],
|
319
|
+
posts: [{
|
320
|
+
platform: 'twitter',
|
321
|
+
userId: 'your-twitter-id',
|
322
|
+
postId: '1234567890',
|
323
|
+
}],
|
297
324
|
});
|
298
325
|
```
|
299
326
|
|
@@ -330,56 +357,21 @@ const postRateLimit = await client.system.getEndpointRateLimit('post');
|
|
330
357
|
|
331
358
|
## Authentication and Security
|
332
359
|
|
333
|
-
### Authentication
|
334
|
-
|
335
|
-
The SDK supports two authentication strategies:
|
336
|
-
|
337
|
-
1. **Direct Authentication**: Provide `nearAuthData` directly in the constructor.
|
338
|
-
```typescript
|
339
|
-
const client = new CrosspostClient({
|
340
|
-
nearAuthData: {
|
341
|
-
accountId: 'your-account.near',
|
342
|
-
publicKey: 'ed25519:...',
|
343
|
-
signature: '...',
|
344
|
-
message: '...',
|
345
|
-
},
|
346
|
-
});
|
347
|
-
```
|
348
|
-
|
349
|
-
2. **Cookie-Based Authentication**: Automatically read/write authentication data from a secure
|
350
|
-
cookie.
|
351
|
-
```typescript
|
352
|
-
// Initialize without auth data (will check for cookie)
|
353
|
-
const client = new CrosspostClient();
|
354
|
-
|
355
|
-
// Set authentication (also stores in cookie)
|
356
|
-
client.setAuthentication(nearAuthData);
|
357
|
-
```
|
360
|
+
### Authentication Strategy
|
358
361
|
|
359
|
-
|
362
|
+
The SDK uses direct authentication with per-request signatures:
|
360
363
|
|
361
|
-
|
362
|
-
the
|
363
|
-
|
364
|
-
-
|
365
|
-
|
366
|
-
- **SameSite**: `Lax` (sent with same-site requests and top-level navigations)
|
367
|
-
- **Path**: `/` (available across the entire domain)
|
368
|
-
- **Expires**: 30 days
|
369
|
-
|
370
|
-
### CSRF Protection
|
371
|
-
|
372
|
-
The SDK implements CSRF protection for state-changing requests (non-GET) using the Double Submit
|
373
|
-
Cookie pattern:
|
374
|
-
|
375
|
-
1. The backend API sets a CSRF token in a non-HttpOnly cookie (`XSRF-TOKEN`)
|
376
|
-
2. The SDK reads this token and includes it in the `X-CSRF-Token` header for all state-changing
|
377
|
-
requests
|
378
|
-
3. The backend validates that the token in the header matches the token in the cookie
|
379
|
-
|
380
|
-
This protection is automatically enabled when using cookie-based authentication and requires no
|
381
|
-
additional configuration from the client side.
|
382
|
-
|
383
|
-
## License
|
364
|
+
```typescript
|
365
|
+
// Initialize the client
|
366
|
+
const client = new CrosspostClient({
|
367
|
+
baseUrl: 'https://your-crosspost-api.com',
|
368
|
+
});
|
384
369
|
|
385
|
-
|
370
|
+
// Before making authenticated requests, set fresh signature
|
371
|
+
client.setAuthentication({
|
372
|
+
accountId: 'your-account.near',
|
373
|
+
publicKey: 'ed25519:...',
|
374
|
+
signature: '...',
|
375
|
+
message: '...',
|
376
|
+
});
|
377
|
+
```
|