@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 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 with direct authentication
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 explicitly (also stores in secure cookie)
34
- await cookieClient.setAuthentication({
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 is authenticated
42
- if (cookieClient.isAuthenticated()) {
43
- console.log('Client is authenticated');
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
- - `createPost(request): Promise<CreatePostResponse>` - Creates a new post
182
- - `repost(request): Promise<RepostResponse>` - Reposts an existing post
183
- - `quotePost(request): Promise<QuotePostResponse>` - Quotes an existing post
184
- - `replyToPost(request): Promise<ReplyToPostResponse>` - Replies to a post
185
- - `likePost(request): Promise<LikePostResponse>` - Likes a post
186
- - `unlikePost(request): Promise<UnlikePostResponse>` - Unlikes a post
187
- - `deletePost(request): Promise<DeletePostResponse>` - Deletes a post
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 simple text post
249
+ // Create a text post on Twitter
253
250
  const textPostResponse = await client.post.createPost({
254
- content: {
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
- content: {
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
- type: 'image',
266
- url: 'https://example.com/image.jpg',
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 a post
313
+ // Delete posts
295
314
  await client.post.deletePost({
296
- postId: '1234567890',
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 Strategies
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
- ### Cookie Security
362
+ The SDK uses direct authentication with per-request signatures:
360
363
 
361
- When using cookie-based authentication, the SDK stores authentication data in a secure cookie with
362
- the following settings:
363
-
364
- - **Name**: `__crosspost_auth`
365
- - **Secure**: `true` (only sent over HTTPS)
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
- MIT
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
+ ```