@crosspost/sdk 0.1.2 → 0.1.4
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 +308 -205
- package/dist/index.cjs +427 -170
- package/dist/index.d.cts +193 -37
- package/dist/index.d.ts +193 -37
- package/dist/index.js +404 -150
- package/package.json +1 -3
- package/src/api/activity.ts +77 -0
- package/src/api/system.ts +55 -0
- package/src/core/client.ts +20 -19
- package/src/core/config.ts +4 -4
- package/src/core/request.ts +112 -96
- package/src/index.ts +24 -14
- package/src/utils/error.ts +300 -0
- package/src/utils/cookie.ts +0 -75
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
@@ -2,273 +2,376 @@
|
|
2
2
|
|
3
3
|
SDK for interacting with the Crosspost API.
|
4
4
|
|
5
|
-
## Overview
|
6
|
-
|
7
|
-
This package provides a client for interacting with the Crosspost API, allowing you to easily
|
8
|
-
integrate social media posting capabilities into your applications. The SDK is designed to be
|
9
|
-
flexible and easy to use, with support for multiple authentication methods and platforms.
|
10
|
-
|
11
|
-
## Features
|
12
|
-
|
13
|
-
- Unified client for all supported platforms
|
14
|
-
- Flexible authentication:
|
15
|
-
- Direct `nearAuthData` injection
|
16
|
-
- Automatic cookie-based authentication (`__crosspost_auth`)
|
17
|
-
- Explicit authentication via `setAuthentication` method
|
18
|
-
- Platform-specific clients (Twitter, with more to come)
|
19
|
-
- Type-safe request/response handling using `@crosspost/types`
|
20
|
-
- Comprehensive error handling with specific `ApiError` and `PlatformError` types
|
21
|
-
- CSRF protection via Double Submit Cookie pattern
|
22
|
-
|
23
5
|
## Installation
|
24
6
|
|
25
7
|
```bash
|
26
8
|
bun install @crosspost/sdk
|
27
9
|
```
|
28
10
|
|
29
|
-
##
|
30
|
-
|
31
|
-
### Initializing the SDK
|
32
|
-
|
33
|
-
The SDK can be initialized in several ways depending on how you manage authentication:
|
34
|
-
|
35
|
-
**1. Cookie-Based Authentication (Recommended for Browsers)**
|
36
|
-
|
37
|
-
If the user has previously authenticated via the API, the SDK can automatically use the
|
38
|
-
authentication data stored in the `__crosspost_auth` cookie.
|
11
|
+
## Quick Start
|
39
12
|
|
40
13
|
```typescript
|
41
|
-
import { CrosspostClient } from '@crosspost/sdk';
|
14
|
+
import { ApiError, CrosspostClient, isAuthError, PlatformError } from '@crosspost/sdk';
|
42
15
|
|
43
|
-
//
|
16
|
+
// Initialize the client (authentication can be provided later)
|
44
17
|
const client = new CrosspostClient({
|
45
18
|
baseUrl: 'https://your-crosspost-api.com', // Optional: Defaults to official API
|
46
19
|
});
|
47
20
|
|
48
|
-
//
|
49
|
-
|
50
|
-
|
21
|
+
// Set authentication with fresh signature for the request
|
22
|
+
client.setAuthentication({
|
23
|
+
accountId: 'your-account.near',
|
24
|
+
publicKey: 'ed25519:...',
|
25
|
+
signature: '...',
|
26
|
+
message: '...',
|
27
|
+
});
|
28
|
+
|
29
|
+
// Check if client has authentication data set
|
30
|
+
if (client.isAuthenticated()) {
|
31
|
+
console.log('Client has authentication data');
|
32
|
+
}
|
51
33
|
|
52
|
-
|
34
|
+
// NEAR Account Authorization
|
35
|
+
async function authorizeNearAccount() {
|
36
|
+
try {
|
37
|
+
// Authorize with NEAR account
|
38
|
+
const authResponse = await client.auth.authorizeNearAccount();
|
39
|
+
console.log('NEAR authorization successful');
|
40
|
+
console.log('Account ID:', authResponse.accountId);
|
41
|
+
console.log('Status:', authResponse.status);
|
42
|
+
console.log('Connected platforms:', authResponse.connectedPlatforms);
|
43
|
+
return true;
|
44
|
+
} catch (error) {
|
45
|
+
console.error('NEAR authorization failed');
|
46
|
+
if (error instanceof ApiError) {
|
47
|
+
console.error('Error code:', error.code);
|
48
|
+
console.error('Status:', error.status);
|
49
|
+
console.error('Details:', error.details);
|
50
|
+
console.error('Recoverable:', error.recoverable);
|
51
|
+
}
|
52
|
+
return false;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
// Unauthorize NEAR Account
|
57
|
+
async function unauthorizeNearAccount() {
|
58
|
+
try {
|
59
|
+
// Unauthorize NEAR account (removes all platform connections)
|
60
|
+
const response = await client.auth.unauthorizeNearAccount();
|
61
|
+
console.log('NEAR account unauthorized');
|
62
|
+
console.log('Status:', response.status);
|
63
|
+
console.log('Message:', response.message);
|
64
|
+
return true;
|
65
|
+
} catch (error) {
|
66
|
+
console.error('Failed to unauthorize NEAR account');
|
67
|
+
if (error instanceof ApiError) {
|
68
|
+
console.error('Error code:', error.code);
|
69
|
+
console.error('Status:', error.status);
|
70
|
+
console.error('Details:', error.details);
|
71
|
+
}
|
72
|
+
return false;
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
// Revoke Platform Authorization
|
77
|
+
async function revokePlatformAuth(platform) {
|
78
|
+
try {
|
79
|
+
// Revoke specific platform authorization
|
80
|
+
const response = await client.auth.revokeAuth(platform);
|
81
|
+
console.log(`${platform} authorization revoked`);
|
82
|
+
console.log('Status:', response.status);
|
83
|
+
console.log('Platform:', response.platform);
|
84
|
+
console.log('Message:', response.message);
|
85
|
+
return true;
|
86
|
+
} catch (error) {
|
87
|
+
console.error(`Failed to revoke ${platform} authorization`);
|
88
|
+
if (error instanceof ApiError) {
|
89
|
+
console.error('Error code:', error.code);
|
90
|
+
console.error('Status:', error.status);
|
91
|
+
console.error('Details:', error.details);
|
92
|
+
}
|
93
|
+
return false;
|
94
|
+
}
|
95
|
+
}
|
53
96
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
97
|
+
// Example usage
|
98
|
+
async function createPost() {
|
99
|
+
try {
|
100
|
+
const response = await client.post.createPost({
|
101
|
+
targets: [{ platform: 'twitter', userId: 'your-twitter-id' }],
|
102
|
+
content: {
|
103
|
+
text: 'Hello from Crosspost SDK!',
|
104
|
+
},
|
105
|
+
});
|
106
|
+
console.log('Post created successfully');
|
107
|
+
console.log('Post ID:', response.id);
|
108
|
+
console.log('Platform:', response.platform);
|
109
|
+
console.log('URL:', response.url);
|
110
|
+
console.log('Created at:', response.createdAt);
|
111
|
+
} catch (error) {
|
112
|
+
// Check if it's an authentication error
|
113
|
+
if (isAuthError(error)) {
|
114
|
+
console.error('Authentication required. Attempting to authorize...');
|
115
|
+
const authorized = await authorizeNearAccount();
|
116
|
+
if (authorized) {
|
117
|
+
// Retry the operation
|
118
|
+
return createPost();
|
119
|
+
}
|
120
|
+
} else {
|
121
|
+
// Handle other error types
|
122
|
+
console.error('Error creating post:', error);
|
123
|
+
if (error instanceof ApiError) {
|
124
|
+
console.error('Error code:', error.code);
|
125
|
+
console.error('Status:', error.status);
|
126
|
+
console.error('Details:', error.details);
|
127
|
+
console.error('Recoverable:', error.recoverable);
|
128
|
+
} else if (error instanceof PlatformError) {
|
129
|
+
console.error('Platform:', error.platform);
|
130
|
+
console.error('Error code:', error.code);
|
131
|
+
console.error('Original error:', error.originalError);
|
132
|
+
}
|
133
|
+
}
|
134
|
+
}
|
135
|
+
}
|
136
|
+
```
|
58
137
|
|
59
|
-
|
138
|
+
## API Reference
|
60
139
|
|
61
|
-
|
62
|
-
server-side flow, manual signing).
|
140
|
+
### CrosspostClient
|
63
141
|
|
64
142
|
```typescript
|
65
|
-
|
66
|
-
|
143
|
+
constructor(config?: {
|
144
|
+
baseUrl?: string;
|
145
|
+
nearAuthData?: NearAuthData;
|
146
|
+
timeout?: number;
|
147
|
+
retries?: number;
|
148
|
+
})
|
149
|
+
```
|
67
150
|
|
68
|
-
|
69
|
-
account_id: 'example.near',
|
70
|
-
public_key: 'ed25519:...',
|
71
|
-
signature: '...',
|
72
|
-
message: '...',
|
73
|
-
nonce: '...',
|
74
|
-
recipient: 'crosspost-api.near',
|
75
|
-
// callback_url and state are optional
|
76
|
-
};
|
151
|
+
#### Methods
|
77
152
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
153
|
+
- `setAuthentication(nearAuthData: NearAuthData): Promise<void>` - Sets authentication data
|
154
|
+
- `isAuthenticated(): boolean` - Checks if client is authenticated
|
155
|
+
|
156
|
+
### Auth API (client.auth)
|
157
|
+
|
158
|
+
- `authorizeNearAccount(): Promise<NearAuthorizationResponse>` - Authorizes NEAR account
|
159
|
+
- `unauthorizeNearAccount(): Promise<NearAuthorizationResponse>` - Unauthorizes NEAR account
|
160
|
+
- `getNearAuthorizationStatus(): Promise<NearAuthorizationResponse>` - Checks authorization status
|
161
|
+
- `loginToPlatform(platform, options?): Promise<EnhancedApiResponse<any>>` - Initiates OAuth flow
|
162
|
+
- `refreshToken(platform): Promise<EnhancedApiResponse<any>>` - Refreshes platform token
|
163
|
+
- `refreshProfile(platform): Promise<EnhancedApiResponse<any>>` - Refreshes user profile
|
164
|
+
- `getAuthStatus(platform): Promise<AuthStatusResponse>` - Gets authentication status
|
165
|
+
- `revokeAuth(platform): Promise<AuthRevokeResponse>` - Revokes platform access
|
166
|
+
- `getConnectedAccounts(): Promise<ConnectedAccountsResponse>` - Lists connected accounts
|
167
|
+
|
168
|
+
### Post API (client.post)
|
169
|
+
|
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
|
185
|
+
|
186
|
+
### Activity API (client.activity)
|
83
187
|
|
84
|
-
|
188
|
+
- `getLeaderboard(options): Promise<LeaderboardResponse>` - Gets activity leaderboard
|
189
|
+
- `getAccountActivity(signerId, options): Promise<AccountActivityResponse>` - Gets account activity
|
190
|
+
- `getAccountPosts(signerId, options): Promise<AccountPostsResponse>` - Gets account posts
|
85
191
|
|
86
|
-
|
87
|
-
|
88
|
-
|
192
|
+
### System API (client.system)
|
193
|
+
|
194
|
+
- `getRateLimits(): Promise<RateLimitsResponse>` - Gets all rate limits
|
195
|
+
- `getEndpointRateLimit(endpoint): Promise<EndpointRateLimitResponse>` - Gets endpoint rate limit
|
196
|
+
- `getHealthStatus(): Promise<HealthStatusResponse>` - Gets API health status
|
197
|
+
|
198
|
+
### Error Handling Utilities
|
89
199
|
|
90
200
|
```typescript
|
91
|
-
import {
|
92
|
-
|
201
|
+
import {
|
202
|
+
apiWrapper,
|
203
|
+
enrichErrorWithContext,
|
204
|
+
getErrorDetails,
|
205
|
+
getErrorMessage,
|
206
|
+
isAuthError,
|
207
|
+
isContentError,
|
208
|
+
isMediaError,
|
209
|
+
isNetworkError,
|
210
|
+
isPlatformError,
|
211
|
+
isPostError,
|
212
|
+
isRateLimitError,
|
213
|
+
isRecoverableError,
|
214
|
+
isValidationError,
|
215
|
+
} from '@crosspost/sdk';
|
216
|
+
|
217
|
+
// Check error types
|
218
|
+
if (isAuthError(error)) {
|
219
|
+
// Handle authentication errors
|
220
|
+
}
|
93
221
|
|
94
|
-
|
95
|
-
|
222
|
+
// Get user-friendly error message
|
223
|
+
const message = getErrorMessage(error, 'Default message');
|
224
|
+
|
225
|
+
// Get error details
|
226
|
+
const details = getErrorDetails(error);
|
227
|
+
|
228
|
+
// Add context to errors
|
229
|
+
const enrichedError = enrichErrorWithContext(error, {
|
230
|
+
operation: 'createPost',
|
231
|
+
timestamp: Date.now(),
|
96
232
|
});
|
97
233
|
|
98
|
-
//
|
99
|
-
|
100
|
-
|
101
|
-
//
|
102
|
-
await
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
console.error('Authentication failed:', error);
|
107
|
-
}
|
108
|
-
}
|
234
|
+
// Wrap API calls with error handling
|
235
|
+
const result = await apiWrapper(
|
236
|
+
async () => {
|
237
|
+
// API call implementation
|
238
|
+
return await fetch('/api/endpoint');
|
239
|
+
},
|
240
|
+
{ operation: 'fetchData' }, // Optional context
|
241
|
+
);
|
109
242
|
```
|
110
243
|
|
111
|
-
|
244
|
+
## Usage Examples
|
245
|
+
|
246
|
+
### Creating a Post
|
112
247
|
|
113
248
|
```typescript
|
114
|
-
// Create a post
|
115
|
-
const
|
116
|
-
|
249
|
+
// Create a text post on Twitter
|
250
|
+
const textPostResponse = await client.post.createPost({
|
251
|
+
targets: [{
|
252
|
+
platform: 'twitter',
|
253
|
+
userId: 'your-twitter-id',
|
254
|
+
}],
|
255
|
+
content: [{
|
117
256
|
text: 'Hello from Crosspost SDK!',
|
118
|
-
},
|
257
|
+
}],
|
119
258
|
});
|
120
259
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
260
|
+
// Create a post with media on multiple platforms
|
261
|
+
const mediaPostResponse = await client.post.createPost({
|
262
|
+
targets: [
|
263
|
+
{ platform: 'twitter', userId: 'your-twitter-id' },
|
264
|
+
{ platform: 'facebook', userId: 'your-facebook-id' },
|
265
|
+
],
|
266
|
+
content: [{
|
126
267
|
text: 'Check out this image!',
|
127
|
-
media: [
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
},
|
268
|
+
media: [{
|
269
|
+
data: imageBlob,
|
270
|
+
mimeType: 'image/jpeg',
|
271
|
+
altText: 'A beautiful sunset',
|
272
|
+
}],
|
273
|
+
}],
|
134
274
|
});
|
275
|
+
```
|
135
276
|
|
136
|
-
|
137
|
-
|
277
|
+
### Post Interactions
|
278
|
+
|
279
|
+
```typescript
|
280
|
+
// Like a post on Twitter
|
281
|
+
await client.post.likePost({
|
282
|
+
targets: [{
|
283
|
+
platform: 'twitter',
|
284
|
+
userId: 'your-twitter-id',
|
285
|
+
}],
|
286
|
+
platform: 'twitter',
|
138
287
|
postId: '1234567890',
|
139
288
|
});
|
140
289
|
|
141
|
-
// Repost
|
142
|
-
await client.
|
290
|
+
// Repost on multiple platforms
|
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',
|
143
297
|
postId: '1234567890',
|
144
298
|
});
|
145
299
|
|
146
300
|
// Reply to a post
|
147
|
-
await client.
|
301
|
+
await client.post.replyToPost({
|
302
|
+
targets: [{
|
303
|
+
platform: 'twitter',
|
304
|
+
userId: 'your-twitter-id',
|
305
|
+
}],
|
306
|
+
platform: 'twitter',
|
148
307
|
postId: '1234567890',
|
149
|
-
content: {
|
308
|
+
content: [{
|
150
309
|
text: 'This is a reply!',
|
151
|
-
},
|
310
|
+
}],
|
152
311
|
});
|
153
312
|
|
154
|
-
// Delete
|
155
|
-
await client.
|
156
|
-
|
313
|
+
// Delete posts
|
314
|
+
await client.post.deletePost({
|
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
|
+
}],
|
157
324
|
});
|
158
325
|
```
|
159
326
|
|
160
|
-
###
|
327
|
+
### Getting Activity Data
|
161
328
|
|
162
329
|
```typescript
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
targets: [{ platform: 'twitter', userId: 'twitter_user_id' }], // Example target
|
169
|
-
content: {
|
170
|
-
text: 'Hello from Crosspost SDK!',
|
171
|
-
},
|
172
|
-
});
|
173
|
-
|
174
|
-
console.log(`Post created with ID: ${response.id}`);
|
175
|
-
} catch (error) {
|
176
|
-
if (error instanceof ApiError) {
|
177
|
-
// Handle authentication errors
|
178
|
-
if (error.code === ApiErrorCode.UNAUTHORIZED) {
|
179
|
-
console.error('Authentication required. Please sign in with your NEAR wallet.');
|
180
|
-
// Redirect to authentication flow or show login UI
|
181
|
-
} else {
|
182
|
-
console.error(`API Error: ${error.message}`);
|
183
|
-
console.error(`Error Code: ${error.code}`); // e.g., RATE_LIMITED
|
184
|
-
console.error(`Status: ${error.status}`); // HTTP status code
|
185
|
-
console.error(`Details:`, error.details); // Additional context
|
186
|
-
console.error(`Recoverable: ${error.recoverable}`);
|
187
|
-
}
|
188
|
-
} else if (error instanceof PlatformError) {
|
189
|
-
// Handle errors specific to a platform (e.g., Twitter API error)
|
190
|
-
console.error(`Platform Error (${error.platform}): ${error.message}`);
|
191
|
-
console.error(`Original Error:`, error.originalError);
|
192
|
-
} else {
|
193
|
-
console.error(`Unexpected error:`, error);
|
194
|
-
}
|
195
|
-
}
|
196
|
-
```
|
197
|
-
|
198
|
-
## API Reference
|
199
|
-
|
200
|
-
### `CrosspostClient`
|
201
|
-
|
202
|
-
The main client for interacting with the Crosspost API.
|
330
|
+
// Get leaderboard
|
331
|
+
const leaderboard = await client.activity.getLeaderboard({
|
332
|
+
timeframe: 'week',
|
333
|
+
limit: 10,
|
334
|
+
});
|
203
335
|
|
204
|
-
|
336
|
+
// Get account activity
|
337
|
+
const activity = await client.activity.getAccountActivity('user.near', {
|
338
|
+
timeframe: 'month',
|
339
|
+
});
|
205
340
|
|
206
|
-
|
207
|
-
|
341
|
+
// Get account posts
|
342
|
+
const posts = await client.activity.getAccountPosts('user.near', {
|
343
|
+
limit: 20,
|
344
|
+
offset: 0,
|
345
|
+
});
|
208
346
|
```
|
209
347
|
|
210
|
-
|
211
|
-
|
212
|
-
- `baseUrl?: string`: Base URL of the Crosspost API. Defaults to the official endpoint.
|
213
|
-
- `nearAuthData?: NearAuthData`: NEAR authentication data object. If not provided, the client
|
214
|
-
attempts to load from the `__crosspost_auth` cookie.
|
215
|
-
- `timeout?: number`: Request timeout in milliseconds (default: 30000).
|
216
|
-
- `retries?: number`: Number of retries for failed requests (network/5xx errors) (default: 2).
|
217
|
-
|
218
|
-
#### Methods
|
219
|
-
|
220
|
-
- `setAuthentication(nearAuthData: NearAuthData): Promise<void>`: Sets the provided `NearAuthData`
|
221
|
-
in the client and stores it in the `__crosspost_auth` cookie for future use.
|
222
|
-
|
223
|
-
#### Properties
|
224
|
-
|
225
|
-
- `auth`: Instance of `AuthApi` for authentication-related operations.
|
226
|
-
- `post`: Instance of `PostApi` for post-related operations.
|
227
|
-
|
228
|
-
### API Modules
|
348
|
+
### Checking Rate Limits
|
229
349
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
(requires `nearAuthData` to be set).
|
234
|
-
- `getNearAuthorizationStatus(): Promise<NearAuthorizationResponse>`: Checks if the current NEAR
|
235
|
-
account is authorized.
|
236
|
-
- `loginToPlatform(platform, options?): Promise<EnhancedApiResponse<any>>`: Initiates the OAuth
|
237
|
-
login flow for a platform.
|
238
|
-
- `refreshToken(platform): Promise<EnhancedApiResponse<any>>`: Refreshes the platform token.
|
239
|
-
- `refreshProfile(platform): Promise<EnhancedApiResponse<any>>`: Refreshes the user's profile from
|
240
|
-
the platform.
|
241
|
-
- `getAuthStatus(platform): Promise<AuthStatusResponse>`: Gets the authentication status for a
|
242
|
-
specific platform.
|
243
|
-
- `revokeAuth(platform): Promise<AuthRevokeResponse>`: Revokes access for a specific platform.
|
244
|
-
- `getConnectedAccounts(): Promise<ConnectedAccountsResponse>`: Lists all platform accounts
|
245
|
-
connected to the NEAR account.
|
246
|
-
|
247
|
-
#### `PostApi` (`client.post`)
|
248
|
-
|
249
|
-
- `createPost(request: CreatePostRequest): Promise<CreatePostResponse>`: Creates a new post.
|
250
|
-
- `repost(request: RepostRequest): Promise<RepostResponse>`: Reposts an existing post.
|
251
|
-
- `quotePost(request: QuotePostRequest): Promise<QuotePostResponse>`: Quotes an existing post.
|
252
|
-
- `replyToPost(request: ReplyToPostRequest): Promise<ReplyToPostResponse>`: Replies to an existing
|
253
|
-
post.
|
254
|
-
- `likePost(request: LikePostRequest): Promise<LikePostResponse>`: Likes a post.
|
255
|
-
- `unlikePost(request: UnlikePostRequest): Promise<UnlikePostResponse>`: Unlikes a post.
|
256
|
-
- `deletePost(request: DeletePostRequest): Promise<DeletePostResponse>`: Deletes one or more posts.
|
257
|
-
|
258
|
-
### CSRF Protection
|
350
|
+
```typescript
|
351
|
+
// Get all rate limits
|
352
|
+
const rateLimits = await client.system.getRateLimits();
|
259
353
|
|
260
|
-
|
354
|
+
// Get rate limit for a specific endpoint
|
355
|
+
const postRateLimit = await client.system.getEndpointRateLimit('post');
|
356
|
+
```
|
261
357
|
|
262
|
-
|
263
|
-
2. The SDK automatically reads this token and includes it in the `X-CSRF-Token` header for all
|
264
|
-
state-changing requests (non-GET)
|
265
|
-
3. The backend API validates that the token in the header matches the token in the cookie
|
358
|
+
## Authentication and Security
|
266
359
|
|
267
|
-
|
360
|
+
### Authentication Strategy
|
268
361
|
|
269
|
-
|
270
|
-
generic `client.post` API with platform targets specified in the request body.)_
|
362
|
+
The SDK uses direct authentication with per-request signatures:
|
271
363
|
|
272
|
-
|
364
|
+
```typescript
|
365
|
+
// Initialize the client
|
366
|
+
const client = new CrosspostClient({
|
367
|
+
baseUrl: 'https://your-crosspost-api.com',
|
368
|
+
});
|
273
369
|
|
274
|
-
|
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
|
+
```
|