this repo has no description
1import { err, ok, type Result } from "./types/result.ts"; 2import type { 3 AccessToken, 4 Did, 5 EmailAddress, 6 Handle, 7 Nsid, 8 RefreshToken, 9 Rkey, 10} from "./types/branded.ts"; 11import { 12 unsafeAsAccessToken, 13 unsafeAsDid, 14 unsafeAsEmail, 15 unsafeAsHandle, 16 unsafeAsISODate, 17 unsafeAsRefreshToken, 18} from "./types/branded.ts"; 19import type { 20 AccountInfo, 21 ApiErrorCode, 22 AppPassword, 23 CompletePasskeySetupResponse, 24 ConfirmSignupResult, 25 CreateAccountParams, 26 CreateAccountResult, 27 CreateBackupResponse, 28 CreatedAppPassword, 29 CreateRecordResponse, 30 DidDocument, 31 DidType, 32 EmailUpdateResponse, 33 EnableTotpResponse, 34 FinishPasskeyRegistrationResponse, 35 GetInviteCodesResponse, 36 InviteCodeInfo, 37 LegacyLoginPreference, 38 ListBackupsResponse, 39 ListPasskeysResponse, 40 ListRecordsResponse, 41 ListReposResponse, 42 ListSessionsResponse, 43 ListTrustedDevicesResponse, 44 NotificationHistoryResponse, 45 NotificationPrefs, 46 PasskeyAccountCreateResponse, 47 PasswordStatus, 48 ReauthPasskeyStartResponse, 49 ReauthResponse, 50 ReauthStatus, 51 RecommendedDidCredentials, 52 RecordResponse, 53 RegenerateBackupCodesResponse, 54 RepoDescription, 55 ResendMigrationVerificationResponse, 56 ReserveSigningKeyResponse, 57 SearchAccountsResponse, 58 ServerConfig, 59 ServerDescription, 60 ServerStats, 61 Session, 62 SetBackupEnabledResponse, 63 StartPasskeyRegistrationResponse, 64 SuccessResponse, 65 TotpSecret, 66 TotpStatus, 67 UpdateLegacyLoginResponse, 68 UpdateLocaleResponse, 69 UploadBlobResponse, 70 VerificationChannel, 71 VerifyMigrationEmailResponse, 72 VerifyTokenResponse, 73} from "./types/api.ts"; 74 75const API_BASE = "/xrpc"; 76 77export class ApiError extends Error { 78 public did?: Did; 79 public reauthMethods?: string[]; 80 constructor( 81 public status: number, 82 public error: ApiErrorCode, 83 message: string, 84 did?: string, 85 reauthMethods?: string[], 86 ) { 87 super(message); 88 this.name = "ApiError"; 89 this.did = did ? unsafeAsDid(did) : undefined; 90 this.reauthMethods = reauthMethods; 91 } 92} 93 94let tokenRefreshCallback: (() => Promise<string | null>) | null = null; 95 96export function setTokenRefreshCallback( 97 callback: () => Promise<string | null>, 98) { 99 tokenRefreshCallback = callback; 100} 101 102interface XrpcOptions { 103 method?: "GET" | "POST"; 104 params?: Record<string, string>; 105 body?: unknown; 106 token?: string; 107 skipRetry?: boolean; 108} 109 110async function xrpc<T>(method: string, options?: XrpcOptions): Promise<T> { 111 const { method: httpMethod = "GET", params, body, token, skipRetry } = 112 options ?? {}; 113 let url = `${API_BASE}/${method}`; 114 if (params) { 115 const searchParams = new URLSearchParams(params); 116 url += `?${searchParams}`; 117 } 118 const headers: Record<string, string> = {}; 119 if (token) { 120 headers["Authorization"] = `Bearer ${token}`; 121 } 122 if (body) { 123 headers["Content-Type"] = "application/json"; 124 } 125 const res = await fetch(url, { 126 method: httpMethod, 127 headers, 128 body: body ? JSON.stringify(body) : undefined, 129 }); 130 if (!res.ok) { 131 const errData = await res.json().catch(() => ({ 132 error: "Unknown", 133 message: res.statusText, 134 })); 135 if ( 136 res.status === 401 && 137 (errData.error === "AuthenticationFailed" || 138 errData.error === "ExpiredToken") && 139 token && tokenRefreshCallback && !skipRetry 140 ) { 141 const newToken = await tokenRefreshCallback(); 142 if (newToken && newToken !== token) { 143 return xrpc(method, { ...options, token: newToken, skipRetry: true }); 144 } 145 } 146 throw new ApiError( 147 res.status, 148 errData.error as ApiErrorCode, 149 errData.message, 150 errData.did, 151 errData.reauthMethods, 152 ); 153 } 154 return res.json(); 155} 156 157async function xrpcResult<T>( 158 method: string, 159 options?: XrpcOptions, 160): Promise<Result<T, ApiError>> { 161 try { 162 const value = await xrpc<T>(method, options); 163 return ok(value); 164 } catch (e) { 165 if (e instanceof ApiError) { 166 return err(e); 167 } 168 return err( 169 new ApiError(0, "Unknown", e instanceof Error ? e.message : String(e)), 170 ); 171 } 172} 173 174export interface VerificationMethod { 175 id: string; 176 type: string; 177 publicKeyMultibase: string; 178} 179 180export type { AppPassword, DidDocument, InviteCodeInfo as InviteCode, Session }; 181export type { 182 ConfirmSignupResult, 183 CreateAccountParams, 184 CreateAccountResult, 185 DidType, 186 VerificationChannel, 187}; 188 189function castSession(raw: unknown): Session { 190 const s = raw as Record<string, unknown>; 191 return { 192 did: unsafeAsDid(s.did as string), 193 handle: unsafeAsHandle(s.handle as string), 194 email: s.email ? unsafeAsEmail(s.email as string) : undefined, 195 emailConfirmed: s.emailConfirmed as boolean | undefined, 196 preferredChannel: s.preferredChannel as VerificationChannel | undefined, 197 preferredChannelVerified: s.preferredChannelVerified as boolean | undefined, 198 isAdmin: s.isAdmin as boolean | undefined, 199 active: s.active as boolean | undefined, 200 status: s.status as Session["status"], 201 migratedToPds: s.migratedToPds as string | undefined, 202 migratedAt: s.migratedAt 203 ? unsafeAsISODate(s.migratedAt as string) 204 : undefined, 205 accessJwt: unsafeAsAccessToken(s.accessJwt as string), 206 refreshJwt: unsafeAsRefreshToken(s.refreshJwt as string), 207 }; 208} 209 210export const api = { 211 async createAccount( 212 params: CreateAccountParams, 213 byodToken?: string, 214 ): Promise<CreateAccountResult> { 215 const url = `${API_BASE}/com.atproto.server.createAccount`; 216 const headers: Record<string, string> = { 217 "Content-Type": "application/json", 218 }; 219 if (byodToken) { 220 headers["Authorization"] = `Bearer ${byodToken}`; 221 } 222 const response = await fetch(url, { 223 method: "POST", 224 headers, 225 body: JSON.stringify({ 226 handle: params.handle, 227 email: params.email, 228 password: params.password, 229 inviteCode: params.inviteCode, 230 didType: params.didType, 231 did: params.did, 232 signingKey: params.signingKey, 233 verificationChannel: params.verificationChannel, 234 discordId: params.discordId, 235 telegramUsername: params.telegramUsername, 236 signalNumber: params.signalNumber, 237 }), 238 }); 239 const data = await response.json(); 240 if (!response.ok) { 241 throw new ApiError(response.status, data.error, data.message); 242 } 243 return data; 244 }, 245 246 async createAccountWithServiceAuth( 247 serviceAuthToken: string, 248 params: { 249 did: Did; 250 handle: Handle; 251 email: EmailAddress; 252 password: string; 253 inviteCode?: string; 254 }, 255 ): Promise<Session> { 256 const url = `${API_BASE}/com.atproto.server.createAccount`; 257 const response = await fetch(url, { 258 method: "POST", 259 headers: { 260 "Content-Type": "application/json", 261 "Authorization": `Bearer ${serviceAuthToken}`, 262 }, 263 body: JSON.stringify({ 264 did: params.did, 265 handle: params.handle, 266 email: params.email, 267 password: params.password, 268 inviteCode: params.inviteCode, 269 }), 270 }); 271 const data = await response.json(); 272 if (!response.ok) { 273 throw new ApiError(response.status, data.error, data.message); 274 } 275 return castSession(data); 276 }, 277 278 confirmSignup( 279 did: Did, 280 verificationCode: string, 281 ): Promise<ConfirmSignupResult> { 282 return xrpc("com.atproto.server.confirmSignup", { 283 method: "POST", 284 body: { did, verificationCode }, 285 }); 286 }, 287 288 resendVerification(did: Did): Promise<{ success: boolean }> { 289 return xrpc("com.atproto.server.resendVerification", { 290 method: "POST", 291 body: { did }, 292 }); 293 }, 294 295 async createSession(identifier: string, password: string): Promise<Session> { 296 const raw = await xrpc<unknown>("com.atproto.server.createSession", { 297 method: "POST", 298 body: { identifier, password }, 299 }); 300 return castSession(raw); 301 }, 302 303 checkEmailVerified(identifier: string): Promise<{ verified: boolean }> { 304 return xrpc("_checkEmailVerified", { 305 method: "POST", 306 body: { identifier }, 307 }); 308 }, 309 310 async getSession(token: AccessToken): Promise<Session> { 311 const raw = await xrpc<unknown>("com.atproto.server.getSession", { token }); 312 return castSession(raw); 313 }, 314 315 async refreshSession(refreshJwt: RefreshToken): Promise<Session> { 316 const raw = await xrpc<unknown>("com.atproto.server.refreshSession", { 317 method: "POST", 318 token: refreshJwt, 319 }); 320 return castSession(raw); 321 }, 322 323 async deleteSession(token: AccessToken): Promise<void> { 324 await xrpc("com.atproto.server.deleteSession", { 325 method: "POST", 326 token, 327 }); 328 }, 329 330 listAppPasswords(token: AccessToken): Promise<{ passwords: AppPassword[] }> { 331 return xrpc("com.atproto.server.listAppPasswords", { token }); 332 }, 333 334 createAppPassword( 335 token: AccessToken, 336 name: string, 337 scopes?: string, 338 ): Promise<CreatedAppPassword> { 339 return xrpc("com.atproto.server.createAppPassword", { 340 method: "POST", 341 token, 342 body: { name, scopes }, 343 }); 344 }, 345 346 async revokeAppPassword(token: AccessToken, name: string): Promise<void> { 347 await xrpc("com.atproto.server.revokeAppPassword", { 348 method: "POST", 349 token, 350 body: { name }, 351 }); 352 }, 353 354 getAccountInviteCodes( 355 token: AccessToken, 356 ): Promise<{ codes: InviteCodeInfo[] }> { 357 return xrpc("com.atproto.server.getAccountInviteCodes", { token }); 358 }, 359 360 createInviteCode( 361 token: AccessToken, 362 useCount: number = 1, 363 ): Promise<{ code: string }> { 364 return xrpc("com.atproto.server.createInviteCode", { 365 method: "POST", 366 token, 367 body: { useCount }, 368 }); 369 }, 370 371 async requestPasswordReset(email: EmailAddress): Promise<void> { 372 await xrpc("com.atproto.server.requestPasswordReset", { 373 method: "POST", 374 body: { email }, 375 }); 376 }, 377 378 async resetPassword(token: string, password: string): Promise<void> { 379 await xrpc("com.atproto.server.resetPassword", { 380 method: "POST", 381 body: { token, password }, 382 }); 383 }, 384 385 requestEmailUpdate(token: AccessToken): Promise<EmailUpdateResponse> { 386 return xrpc("com.atproto.server.requestEmailUpdate", { 387 method: "POST", 388 token, 389 }); 390 }, 391 392 async updateEmail( 393 token: AccessToken, 394 email: string, 395 emailToken?: string, 396 ): Promise<void> { 397 await xrpc("com.atproto.server.updateEmail", { 398 method: "POST", 399 token, 400 body: { email, token: emailToken }, 401 }); 402 }, 403 404 async updateHandle(token: AccessToken, handle: Handle): Promise<void> { 405 await xrpc("com.atproto.identity.updateHandle", { 406 method: "POST", 407 token, 408 body: { handle }, 409 }); 410 }, 411 412 async requestAccountDelete(token: AccessToken): Promise<void> { 413 await xrpc("com.atproto.server.requestAccountDelete", { 414 method: "POST", 415 token, 416 }); 417 }, 418 419 async deleteAccount( 420 did: Did, 421 password: string, 422 deleteToken: string, 423 ): Promise<void> { 424 await xrpc("com.atproto.server.deleteAccount", { 425 method: "POST", 426 body: { did, password, token: deleteToken }, 427 }); 428 }, 429 430 describeServer(): Promise<ServerDescription> { 431 return xrpc("com.atproto.server.describeServer"); 432 }, 433 434 listRepos(limit?: number): Promise<ListReposResponse> { 435 const params: Record<string, string> = {}; 436 if (limit) params.limit = String(limit); 437 return xrpc("com.atproto.sync.listRepos", { params }); 438 }, 439 440 getNotificationPrefs(token: AccessToken): Promise<NotificationPrefs> { 441 return xrpc("_account.getNotificationPrefs", { token }); 442 }, 443 444 updateNotificationPrefs(token: AccessToken, prefs: { 445 preferredChannel?: string; 446 discordId?: string; 447 telegramUsername?: string; 448 signalNumber?: string; 449 }): Promise<SuccessResponse> { 450 return xrpc("_account.updateNotificationPrefs", { 451 method: "POST", 452 token, 453 body: prefs, 454 }); 455 }, 456 457 confirmChannelVerification( 458 token: AccessToken, 459 channel: string, 460 identifier: string, 461 code: string, 462 ): Promise<SuccessResponse> { 463 return xrpc("_account.confirmChannelVerification", { 464 method: "POST", 465 token, 466 body: { channel, identifier, code }, 467 }); 468 }, 469 470 getNotificationHistory( 471 token: AccessToken, 472 ): Promise<NotificationHistoryResponse> { 473 return xrpc("_account.getNotificationHistory", { token }); 474 }, 475 476 getServerStats(token: AccessToken): Promise<ServerStats> { 477 return xrpc("_admin.getServerStats", { token }); 478 }, 479 480 getServerConfig(): Promise<ServerConfig> { 481 return xrpc("_server.getConfig"); 482 }, 483 484 updateServerConfig( 485 token: AccessToken, 486 config: { 487 serverName?: string; 488 primaryColor?: string; 489 primaryColorDark?: string; 490 secondaryColor?: string; 491 secondaryColorDark?: string; 492 logoCid?: string; 493 }, 494 ): Promise<SuccessResponse> { 495 return xrpc("_admin.updateServerConfig", { 496 method: "POST", 497 token, 498 body: config, 499 }); 500 }, 501 502 async uploadBlob( 503 token: AccessToken, 504 file: File, 505 ): Promise<UploadBlobResponse> { 506 const res = await fetch("/xrpc/com.atproto.repo.uploadBlob", { 507 method: "POST", 508 headers: { 509 "Authorization": `Bearer ${token}`, 510 "Content-Type": file.type, 511 }, 512 body: file, 513 }); 514 if (!res.ok) { 515 const errData = await res.json().catch(() => ({ 516 error: "Unknown", 517 message: res.statusText, 518 })); 519 throw new ApiError(res.status, errData.error, errData.message); 520 } 521 return res.json(); 522 }, 523 524 async changePassword( 525 token: AccessToken, 526 currentPassword: string, 527 newPassword: string, 528 ): Promise<void> { 529 await xrpc("_account.changePassword", { 530 method: "POST", 531 token, 532 body: { currentPassword, newPassword }, 533 }); 534 }, 535 536 removePassword(token: AccessToken): Promise<SuccessResponse> { 537 return xrpc("_account.removePassword", { 538 method: "POST", 539 token, 540 }); 541 }, 542 543 getPasswordStatus(token: AccessToken): Promise<PasswordStatus> { 544 return xrpc("_account.getPasswordStatus", { token }); 545 }, 546 547 getLegacyLoginPreference(token: AccessToken): Promise<LegacyLoginPreference> { 548 return xrpc("_account.getLegacyLoginPreference", { token }); 549 }, 550 551 updateLegacyLoginPreference( 552 token: AccessToken, 553 allowLegacyLogin: boolean, 554 ): Promise<UpdateLegacyLoginResponse> { 555 return xrpc("_account.updateLegacyLoginPreference", { 556 method: "POST", 557 token, 558 body: { allowLegacyLogin }, 559 }); 560 }, 561 562 updateLocale( 563 token: AccessToken, 564 preferredLocale: string, 565 ): Promise<UpdateLocaleResponse> { 566 return xrpc("_account.updateLocale", { 567 method: "POST", 568 token, 569 body: { preferredLocale }, 570 }); 571 }, 572 573 listSessions(token: AccessToken): Promise<ListSessionsResponse> { 574 return xrpc("_account.listSessions", { token }); 575 }, 576 577 async revokeSession(token: AccessToken, sessionId: string): Promise<void> { 578 await xrpc("_account.revokeSession", { 579 method: "POST", 580 token, 581 body: { sessionId }, 582 }); 583 }, 584 585 revokeAllSessions(token: AccessToken): Promise<{ revokedCount: number }> { 586 return xrpc("_account.revokeAllSessions", { 587 method: "POST", 588 token, 589 }); 590 }, 591 592 searchAccounts(token: AccessToken, options?: { 593 handle?: string; 594 cursor?: string; 595 limit?: number; 596 }): Promise<SearchAccountsResponse> { 597 const params: Record<string, string> = {}; 598 if (options?.handle) params.handle = options.handle; 599 if (options?.cursor) params.cursor = options.cursor; 600 if (options?.limit) params.limit = String(options.limit); 601 return xrpc("com.atproto.admin.searchAccounts", { token, params }); 602 }, 603 604 getInviteCodes(token: AccessToken, options?: { 605 sort?: "recent" | "usage"; 606 cursor?: string; 607 limit?: number; 608 }): Promise<GetInviteCodesResponse> { 609 const params: Record<string, string> = {}; 610 if (options?.sort) params.sort = options.sort; 611 if (options?.cursor) params.cursor = options.cursor; 612 if (options?.limit) params.limit = String(options.limit); 613 return xrpc("com.atproto.admin.getInviteCodes", { token, params }); 614 }, 615 616 async disableInviteCodes( 617 token: AccessToken, 618 codes?: string[], 619 accounts?: string[], 620 ): Promise<void> { 621 await xrpc("com.atproto.admin.disableInviteCodes", { 622 method: "POST", 623 token, 624 body: { codes, accounts }, 625 }); 626 }, 627 628 getAccountInfo(token: AccessToken, did: Did): Promise<AccountInfo> { 629 return xrpc("com.atproto.admin.getAccountInfo", { token, params: { did } }); 630 }, 631 632 async disableAccountInvites(token: AccessToken, account: Did): Promise<void> { 633 await xrpc("com.atproto.admin.disableAccountInvites", { 634 method: "POST", 635 token, 636 body: { account }, 637 }); 638 }, 639 640 async enableAccountInvites(token: AccessToken, account: Did): Promise<void> { 641 await xrpc("com.atproto.admin.enableAccountInvites", { 642 method: "POST", 643 token, 644 body: { account }, 645 }); 646 }, 647 648 async adminDeleteAccount(token: AccessToken, did: Did): Promise<void> { 649 await xrpc("com.atproto.admin.deleteAccount", { 650 method: "POST", 651 token, 652 body: { did }, 653 }); 654 }, 655 656 describeRepo(token: AccessToken, repo: Did): Promise<RepoDescription> { 657 return xrpc("com.atproto.repo.describeRepo", { 658 token, 659 params: { repo }, 660 }); 661 }, 662 663 listRecords(token: AccessToken, repo: Did, collection: Nsid, options?: { 664 limit?: number; 665 cursor?: string; 666 reverse?: boolean; 667 }): Promise<ListRecordsResponse> { 668 const params: Record<string, string> = { repo, collection }; 669 if (options?.limit) params.limit = String(options.limit); 670 if (options?.cursor) params.cursor = options.cursor; 671 if (options?.reverse) params.reverse = "true"; 672 return xrpc("com.atproto.repo.listRecords", { token, params }); 673 }, 674 675 getRecord( 676 token: AccessToken, 677 repo: Did, 678 collection: Nsid, 679 rkey: Rkey, 680 ): Promise<RecordResponse> { 681 return xrpc("com.atproto.repo.getRecord", { 682 token, 683 params: { repo, collection, rkey }, 684 }); 685 }, 686 687 createRecord( 688 token: AccessToken, 689 repo: Did, 690 collection: Nsid, 691 record: unknown, 692 rkey?: Rkey, 693 ): Promise<CreateRecordResponse> { 694 return xrpc("com.atproto.repo.createRecord", { 695 method: "POST", 696 token, 697 body: { repo, collection, record, rkey }, 698 }); 699 }, 700 701 putRecord( 702 token: AccessToken, 703 repo: Did, 704 collection: Nsid, 705 rkey: Rkey, 706 record: unknown, 707 ): Promise<CreateRecordResponse> { 708 return xrpc("com.atproto.repo.putRecord", { 709 method: "POST", 710 token, 711 body: { repo, collection, rkey, record }, 712 }); 713 }, 714 715 async deleteRecord( 716 token: AccessToken, 717 repo: Did, 718 collection: Nsid, 719 rkey: Rkey, 720 ): Promise<void> { 721 await xrpc("com.atproto.repo.deleteRecord", { 722 method: "POST", 723 token, 724 body: { repo, collection, rkey }, 725 }); 726 }, 727 728 getTotpStatus(token: AccessToken): Promise<TotpStatus> { 729 return xrpc("com.atproto.server.getTotpStatus", { token }); 730 }, 731 732 createTotpSecret(token: AccessToken): Promise<TotpSecret> { 733 return xrpc("com.atproto.server.createTotpSecret", { 734 method: "POST", 735 token, 736 }); 737 }, 738 739 enableTotp(token: AccessToken, code: string): Promise<EnableTotpResponse> { 740 return xrpc("com.atproto.server.enableTotp", { 741 method: "POST", 742 token, 743 body: { code }, 744 }); 745 }, 746 747 disableTotp( 748 token: AccessToken, 749 password: string, 750 code: string, 751 ): Promise<SuccessResponse> { 752 return xrpc("com.atproto.server.disableTotp", { 753 method: "POST", 754 token, 755 body: { password, code }, 756 }); 757 }, 758 759 regenerateBackupCodes( 760 token: AccessToken, 761 password: string, 762 code: string, 763 ): Promise<RegenerateBackupCodesResponse> { 764 return xrpc("com.atproto.server.regenerateBackupCodes", { 765 method: "POST", 766 token, 767 body: { password, code }, 768 }); 769 }, 770 771 startPasskeyRegistration( 772 token: AccessToken, 773 friendlyName?: string, 774 ): Promise<StartPasskeyRegistrationResponse> { 775 return xrpc("com.atproto.server.startPasskeyRegistration", { 776 method: "POST", 777 token, 778 body: { friendlyName }, 779 }); 780 }, 781 782 finishPasskeyRegistration( 783 token: AccessToken, 784 credential: unknown, 785 friendlyName?: string, 786 ): Promise<FinishPasskeyRegistrationResponse> { 787 return xrpc("com.atproto.server.finishPasskeyRegistration", { 788 method: "POST", 789 token, 790 body: { credential, friendlyName }, 791 }); 792 }, 793 794 listPasskeys(token: AccessToken): Promise<ListPasskeysResponse> { 795 return xrpc("com.atproto.server.listPasskeys", { token }); 796 }, 797 798 async deletePasskey(token: AccessToken, id: string): Promise<void> { 799 await xrpc("com.atproto.server.deletePasskey", { 800 method: "POST", 801 token, 802 body: { id }, 803 }); 804 }, 805 806 async updatePasskey( 807 token: AccessToken, 808 id: string, 809 friendlyName: string, 810 ): Promise<void> { 811 await xrpc("com.atproto.server.updatePasskey", { 812 method: "POST", 813 token, 814 body: { id, friendlyName }, 815 }); 816 }, 817 818 listTrustedDevices(token: AccessToken): Promise<ListTrustedDevicesResponse> { 819 return xrpc("_account.listTrustedDevices", { token }); 820 }, 821 822 revokeTrustedDevice( 823 token: AccessToken, 824 deviceId: string, 825 ): Promise<SuccessResponse> { 826 return xrpc("_account.revokeTrustedDevice", { 827 method: "POST", 828 token, 829 body: { deviceId }, 830 }); 831 }, 832 833 updateTrustedDevice( 834 token: AccessToken, 835 deviceId: string, 836 friendlyName: string, 837 ): Promise<SuccessResponse> { 838 return xrpc("_account.updateTrustedDevice", { 839 method: "POST", 840 token, 841 body: { deviceId, friendlyName }, 842 }); 843 }, 844 845 getReauthStatus(token: AccessToken): Promise<ReauthStatus> { 846 return xrpc("_account.getReauthStatus", { token }); 847 }, 848 849 reauthPassword( 850 token: AccessToken, 851 password: string, 852 ): Promise<ReauthResponse> { 853 return xrpc("_account.reauthPassword", { 854 method: "POST", 855 token, 856 body: { password }, 857 }); 858 }, 859 860 reauthTotp(token: AccessToken, code: string): Promise<ReauthResponse> { 861 return xrpc("_account.reauthTotp", { 862 method: "POST", 863 token, 864 body: { code }, 865 }); 866 }, 867 868 reauthPasskeyStart(token: AccessToken): Promise<ReauthPasskeyStartResponse> { 869 return xrpc("_account.reauthPasskeyStart", { 870 method: "POST", 871 token, 872 }); 873 }, 874 875 reauthPasskeyFinish( 876 token: AccessToken, 877 credential: unknown, 878 ): Promise<ReauthResponse> { 879 return xrpc("_account.reauthPasskeyFinish", { 880 method: "POST", 881 token, 882 body: { credential }, 883 }); 884 }, 885 886 reserveSigningKey(did?: Did): Promise<ReserveSigningKeyResponse> { 887 return xrpc("com.atproto.server.reserveSigningKey", { 888 method: "POST", 889 body: { did }, 890 }); 891 }, 892 893 getRecommendedDidCredentials( 894 token: AccessToken, 895 ): Promise<RecommendedDidCredentials> { 896 return xrpc("com.atproto.identity.getRecommendedDidCredentials", { token }); 897 }, 898 899 async activateAccount(token: AccessToken): Promise<void> { 900 await xrpc("com.atproto.server.activateAccount", { 901 method: "POST", 902 token, 903 }); 904 }, 905 906 async createPasskeyAccount(params: { 907 handle: Handle; 908 email?: EmailAddress; 909 inviteCode?: string; 910 didType?: DidType; 911 did?: Did; 912 signingKey?: string; 913 verificationChannel?: VerificationChannel; 914 discordId?: string; 915 telegramUsername?: string; 916 signalNumber?: string; 917 }, byodToken?: string): Promise<PasskeyAccountCreateResponse> { 918 const url = `${API_BASE}/_account.createPasskeyAccount`; 919 const headers: Record<string, string> = { 920 "Content-Type": "application/json", 921 }; 922 if (byodToken) { 923 headers["Authorization"] = `Bearer ${byodToken}`; 924 } 925 const res = await fetch(url, { 926 method: "POST", 927 headers, 928 body: JSON.stringify(params), 929 }); 930 if (!res.ok) { 931 const errData = await res.json().catch(() => ({ 932 error: "Unknown", 933 message: res.statusText, 934 })); 935 throw new ApiError(res.status, errData.error, errData.message); 936 } 937 return res.json(); 938 }, 939 940 startPasskeyRegistrationForSetup( 941 did: Did, 942 setupToken: string, 943 friendlyName?: string, 944 ): Promise<StartPasskeyRegistrationResponse> { 945 return xrpc("_account.startPasskeyRegistrationForSetup", { 946 method: "POST", 947 body: { did, setupToken, friendlyName }, 948 }); 949 }, 950 951 completePasskeySetup( 952 did: Did, 953 setupToken: string, 954 passkeyCredential: unknown, 955 passkeyFriendlyName?: string, 956 ): Promise<CompletePasskeySetupResponse> { 957 return xrpc("_account.completePasskeySetup", { 958 method: "POST", 959 body: { did, setupToken, passkeyCredential, passkeyFriendlyName }, 960 }); 961 }, 962 963 requestPasskeyRecovery(email: EmailAddress): Promise<SuccessResponse> { 964 return xrpc("_account.requestPasskeyRecovery", { 965 method: "POST", 966 body: { email }, 967 }); 968 }, 969 970 recoverPasskeyAccount( 971 did: Did, 972 recoveryToken: string, 973 newPassword: string, 974 ): Promise<SuccessResponse> { 975 return xrpc("_account.recoverPasskeyAccount", { 976 method: "POST", 977 body: { did, recoveryToken, newPassword }, 978 }); 979 }, 980 981 verifyMigrationEmail( 982 token: string, 983 email: EmailAddress, 984 ): Promise<VerifyMigrationEmailResponse> { 985 return xrpc("com.atproto.server.verifyMigrationEmail", { 986 method: "POST", 987 body: { token, email }, 988 }); 989 }, 990 991 resendMigrationVerification( 992 email: EmailAddress, 993 ): Promise<ResendMigrationVerificationResponse> { 994 return xrpc("com.atproto.server.resendMigrationVerification", { 995 method: "POST", 996 body: { email }, 997 }); 998 }, 999 1000 verifyToken( 1001 token: string, 1002 identifier: string, 1003 accessToken?: AccessToken, 1004 ): Promise<VerifyTokenResponse> { 1005 return xrpc("_account.verifyToken", { 1006 method: "POST", 1007 body: { token, identifier }, 1008 token: accessToken, 1009 }); 1010 }, 1011 1012 getDidDocument(token: AccessToken): Promise<DidDocument> { 1013 return xrpc("_account.getDidDocument", { token }); 1014 }, 1015 1016 updateDidDocument( 1017 token: AccessToken, 1018 params: { 1019 verificationMethods?: VerificationMethod[]; 1020 alsoKnownAs?: string[]; 1021 serviceEndpoint?: string; 1022 }, 1023 ): Promise<SuccessResponse> { 1024 return xrpc("_account.updateDidDocument", { 1025 method: "POST", 1026 token, 1027 body: params, 1028 }); 1029 }, 1030 1031 async deactivateAccount( 1032 token: AccessToken, 1033 deleteAfter?: string, 1034 ): Promise<void> { 1035 await xrpc("com.atproto.server.deactivateAccount", { 1036 method: "POST", 1037 token, 1038 body: { deleteAfter }, 1039 }); 1040 }, 1041 1042 async getRepo(token: AccessToken, did: Did): Promise<ArrayBuffer> { 1043 const url = `${API_BASE}/com.atproto.sync.getRepo?did=${ 1044 encodeURIComponent(did) 1045 }`; 1046 const res = await fetch(url, { 1047 headers: { Authorization: `Bearer ${token}` }, 1048 }); 1049 if (!res.ok) { 1050 const errData = await res.json().catch(() => ({ 1051 error: "Unknown", 1052 message: res.statusText, 1053 })); 1054 throw new ApiError(res.status, errData.error, errData.message); 1055 } 1056 return res.arrayBuffer(); 1057 }, 1058 1059 listBackups(token: AccessToken): Promise<ListBackupsResponse> { 1060 return xrpc("_backup.listBackups", { token }); 1061 }, 1062 1063 async getBackup(token: AccessToken, id: string): Promise<Blob> { 1064 const url = `${API_BASE}/_backup.getBackup?id=${encodeURIComponent(id)}`; 1065 const res = await fetch(url, { 1066 headers: { Authorization: `Bearer ${token}` }, 1067 }); 1068 if (!res.ok) { 1069 const errData = await res.json().catch(() => ({ 1070 error: "Unknown", 1071 message: res.statusText, 1072 })); 1073 throw new ApiError(res.status, errData.error, errData.message); 1074 } 1075 return res.blob(); 1076 }, 1077 1078 createBackup(token: AccessToken): Promise<CreateBackupResponse> { 1079 return xrpc("_backup.createBackup", { 1080 method: "POST", 1081 token, 1082 }); 1083 }, 1084 1085 async deleteBackup(token: AccessToken, id: string): Promise<void> { 1086 await xrpc("_backup.deleteBackup", { 1087 method: "POST", 1088 token, 1089 params: { id }, 1090 }); 1091 }, 1092 1093 setBackupEnabled( 1094 token: AccessToken, 1095 enabled: boolean, 1096 ): Promise<SetBackupEnabledResponse> { 1097 return xrpc("_backup.setEnabled", { 1098 method: "POST", 1099 token, 1100 body: { enabled }, 1101 }); 1102 }, 1103 1104 async importRepo(token: AccessToken, car: Uint8Array): Promise<void> { 1105 const url = `${API_BASE}/com.atproto.repo.importRepo`; 1106 const res = await fetch(url, { 1107 method: "POST", 1108 headers: { 1109 Authorization: `Bearer ${token}`, 1110 "Content-Type": "application/vnd.ipld.car", 1111 }, 1112 body: car as unknown as BodyInit, 1113 }); 1114 if (!res.ok) { 1115 const errData = await res.json().catch(() => ({ 1116 error: "Unknown", 1117 message: res.statusText, 1118 })); 1119 throw new ApiError(res.status, errData.error, errData.message); 1120 } 1121 }, 1122}; 1123 1124export const typedApi = { 1125 createSession( 1126 identifier: string, 1127 password: string, 1128 ): Promise<Result<Session, ApiError>> { 1129 return xrpcResult<Session>("com.atproto.server.createSession", { 1130 method: "POST", 1131 body: { identifier, password }, 1132 }).then((r) => r.ok ? ok(castSession(r.value)) : r); 1133 }, 1134 1135 getSession(token: AccessToken): Promise<Result<Session, ApiError>> { 1136 return xrpcResult<Session>("com.atproto.server.getSession", { token }) 1137 .then((r) => r.ok ? ok(castSession(r.value)) : r); 1138 }, 1139 1140 refreshSession(refreshJwt: RefreshToken): Promise<Result<Session, ApiError>> { 1141 return xrpcResult<Session>("com.atproto.server.refreshSession", { 1142 method: "POST", 1143 token: refreshJwt, 1144 }).then((r) => r.ok ? ok(castSession(r.value)) : r); 1145 }, 1146 1147 describeServer(): Promise<Result<ServerDescription, ApiError>> { 1148 return xrpcResult("com.atproto.server.describeServer"); 1149 }, 1150 1151 listAppPasswords( 1152 token: AccessToken, 1153 ): Promise<Result<{ passwords: AppPassword[] }, ApiError>> { 1154 return xrpcResult("com.atproto.server.listAppPasswords", { token }); 1155 }, 1156 1157 createAppPassword( 1158 token: AccessToken, 1159 name: string, 1160 scopes?: string, 1161 ): Promise<Result<CreatedAppPassword, ApiError>> { 1162 return xrpcResult("com.atproto.server.createAppPassword", { 1163 method: "POST", 1164 token, 1165 body: { name, scopes }, 1166 }); 1167 }, 1168 1169 revokeAppPassword( 1170 token: AccessToken, 1171 name: string, 1172 ): Promise<Result<void, ApiError>> { 1173 return xrpcResult<void>("com.atproto.server.revokeAppPassword", { 1174 method: "POST", 1175 token, 1176 body: { name }, 1177 }); 1178 }, 1179 1180 listSessions( 1181 token: AccessToken, 1182 ): Promise<Result<ListSessionsResponse, ApiError>> { 1183 return xrpcResult("_account.listSessions", { token }); 1184 }, 1185 1186 revokeSession( 1187 token: AccessToken, 1188 sessionId: string, 1189 ): Promise<Result<void, ApiError>> { 1190 return xrpcResult<void>("_account.revokeSession", { 1191 method: "POST", 1192 token, 1193 body: { sessionId }, 1194 }); 1195 }, 1196 1197 getTotpStatus(token: AccessToken): Promise<Result<TotpStatus, ApiError>> { 1198 return xrpcResult("com.atproto.server.getTotpStatus", { token }); 1199 }, 1200 1201 createTotpSecret(token: AccessToken): Promise<Result<TotpSecret, ApiError>> { 1202 return xrpcResult("com.atproto.server.createTotpSecret", { 1203 method: "POST", 1204 token, 1205 }); 1206 }, 1207 1208 enableTotp( 1209 token: AccessToken, 1210 code: string, 1211 ): Promise<Result<EnableTotpResponse, ApiError>> { 1212 return xrpcResult("com.atproto.server.enableTotp", { 1213 method: "POST", 1214 token, 1215 body: { code }, 1216 }); 1217 }, 1218 1219 disableTotp( 1220 token: AccessToken, 1221 password: string, 1222 code: string, 1223 ): Promise<Result<SuccessResponse, ApiError>> { 1224 return xrpcResult("com.atproto.server.disableTotp", { 1225 method: "POST", 1226 token, 1227 body: { password, code }, 1228 }); 1229 }, 1230 1231 listPasskeys( 1232 token: AccessToken, 1233 ): Promise<Result<ListPasskeysResponse, ApiError>> { 1234 return xrpcResult("com.atproto.server.listPasskeys", { token }); 1235 }, 1236 1237 deletePasskey( 1238 token: AccessToken, 1239 id: string, 1240 ): Promise<Result<void, ApiError>> { 1241 return xrpcResult<void>("com.atproto.server.deletePasskey", { 1242 method: "POST", 1243 token, 1244 body: { id }, 1245 }); 1246 }, 1247 1248 listTrustedDevices( 1249 token: AccessToken, 1250 ): Promise<Result<ListTrustedDevicesResponse, ApiError>> { 1251 return xrpcResult("_account.listTrustedDevices", { token }); 1252 }, 1253 1254 getReauthStatus(token: AccessToken): Promise<Result<ReauthStatus, ApiError>> { 1255 return xrpcResult("_account.getReauthStatus", { token }); 1256 }, 1257 1258 getNotificationPrefs( 1259 token: AccessToken, 1260 ): Promise<Result<NotificationPrefs, ApiError>> { 1261 return xrpcResult("_account.getNotificationPrefs", { token }); 1262 }, 1263 1264 updateHandle( 1265 token: AccessToken, 1266 handle: Handle, 1267 ): Promise<Result<void, ApiError>> { 1268 return xrpcResult<void>("com.atproto.identity.updateHandle", { 1269 method: "POST", 1270 token, 1271 body: { handle }, 1272 }); 1273 }, 1274 1275 describeRepo( 1276 token: AccessToken, 1277 repo: Did, 1278 ): Promise<Result<RepoDescription, ApiError>> { 1279 return xrpcResult("com.atproto.repo.describeRepo", { 1280 token, 1281 params: { repo }, 1282 }); 1283 }, 1284 1285 listRecords( 1286 token: AccessToken, 1287 repo: Did, 1288 collection: Nsid, 1289 options?: { limit?: number; cursor?: string; reverse?: boolean }, 1290 ): Promise<Result<ListRecordsResponse, ApiError>> { 1291 const params: Record<string, string> = { repo, collection }; 1292 if (options?.limit) params.limit = String(options.limit); 1293 if (options?.cursor) params.cursor = options.cursor; 1294 if (options?.reverse) params.reverse = "true"; 1295 return xrpcResult("com.atproto.repo.listRecords", { token, params }); 1296 }, 1297 1298 getRecord( 1299 token: AccessToken, 1300 repo: Did, 1301 collection: Nsid, 1302 rkey: Rkey, 1303 ): Promise<Result<RecordResponse, ApiError>> { 1304 return xrpcResult("com.atproto.repo.getRecord", { 1305 token, 1306 params: { repo, collection, rkey }, 1307 }); 1308 }, 1309 1310 deleteRecord( 1311 token: AccessToken, 1312 repo: Did, 1313 collection: Nsid, 1314 rkey: Rkey, 1315 ): Promise<Result<void, ApiError>> { 1316 return xrpcResult<void>("com.atproto.repo.deleteRecord", { 1317 method: "POST", 1318 token, 1319 body: { repo, collection, rkey }, 1320 }); 1321 }, 1322 1323 searchAccounts( 1324 token: AccessToken, 1325 options?: { handle?: string; cursor?: string; limit?: number }, 1326 ): Promise<Result<SearchAccountsResponse, ApiError>> { 1327 const params: Record<string, string> = {}; 1328 if (options?.handle) params.handle = options.handle; 1329 if (options?.cursor) params.cursor = options.cursor; 1330 if (options?.limit) params.limit = String(options.limit); 1331 return xrpcResult("com.atproto.admin.searchAccounts", { token, params }); 1332 }, 1333 1334 getAccountInfo( 1335 token: AccessToken, 1336 did: Did, 1337 ): Promise<Result<AccountInfo, ApiError>> { 1338 return xrpcResult("com.atproto.admin.getAccountInfo", { 1339 token, 1340 params: { did }, 1341 }); 1342 }, 1343 1344 getServerStats(token: AccessToken): Promise<Result<ServerStats, ApiError>> { 1345 return xrpcResult("_admin.getServerStats", { token }); 1346 }, 1347 1348 listBackups( 1349 token: AccessToken, 1350 ): Promise<Result<ListBackupsResponse, ApiError>> { 1351 return xrpcResult("_backup.listBackups", { token }); 1352 }, 1353 1354 createBackup( 1355 token: AccessToken, 1356 ): Promise<Result<CreateBackupResponse, ApiError>> { 1357 return xrpcResult("_backup.createBackup", { 1358 method: "POST", 1359 token, 1360 }); 1361 }, 1362 1363 getDidDocument(token: AccessToken): Promise<Result<DidDocument, ApiError>> { 1364 return xrpcResult("_account.getDidDocument", { token }); 1365 }, 1366 1367 deleteSession(token: AccessToken): Promise<Result<void, ApiError>> { 1368 return xrpcResult<void>("com.atproto.server.deleteSession", { 1369 method: "POST", 1370 token, 1371 }); 1372 }, 1373 1374 revokeAllSessions( 1375 token: AccessToken, 1376 ): Promise<Result<{ revokedCount: number }, ApiError>> { 1377 return xrpcResult("_account.revokeAllSessions", { 1378 method: "POST", 1379 token, 1380 }); 1381 }, 1382 1383 getAccountInviteCodes( 1384 token: AccessToken, 1385 ): Promise<Result<{ codes: InviteCodeInfo[] }, ApiError>> { 1386 return xrpcResult("com.atproto.server.getAccountInviteCodes", { token }); 1387 }, 1388 1389 createInviteCode( 1390 token: AccessToken, 1391 useCount: number = 1, 1392 ): Promise<Result<{ code: string }, ApiError>> { 1393 return xrpcResult("com.atproto.server.createInviteCode", { 1394 method: "POST", 1395 token, 1396 body: { useCount }, 1397 }); 1398 }, 1399 1400 changePassword( 1401 token: AccessToken, 1402 currentPassword: string, 1403 newPassword: string, 1404 ): Promise<Result<void, ApiError>> { 1405 return xrpcResult<void>("_account.changePassword", { 1406 method: "POST", 1407 token, 1408 body: { currentPassword, newPassword }, 1409 }); 1410 }, 1411 1412 getPasswordStatus( 1413 token: AccessToken, 1414 ): Promise<Result<PasswordStatus, ApiError>> { 1415 return xrpcResult("_account.getPasswordStatus", { token }); 1416 }, 1417 1418 getServerConfig(): Promise<Result<ServerConfig, ApiError>> { 1419 return xrpcResult("_server.getConfig"); 1420 }, 1421 1422 getLegacyLoginPreference( 1423 token: AccessToken, 1424 ): Promise<Result<LegacyLoginPreference, ApiError>> { 1425 return xrpcResult("_account.getLegacyLoginPreference", { token }); 1426 }, 1427 1428 updateLegacyLoginPreference( 1429 token: AccessToken, 1430 allowLegacyLogin: boolean, 1431 ): Promise<Result<UpdateLegacyLoginResponse, ApiError>> { 1432 return xrpcResult("_account.updateLegacyLoginPreference", { 1433 method: "POST", 1434 token, 1435 body: { allowLegacyLogin }, 1436 }); 1437 }, 1438 1439 getNotificationHistory( 1440 token: AccessToken, 1441 ): Promise<Result<NotificationHistoryResponse, ApiError>> { 1442 return xrpcResult("_account.getNotificationHistory", { token }); 1443 }, 1444 1445 updateNotificationPrefs( 1446 token: AccessToken, 1447 prefs: { 1448 preferredChannel?: string; 1449 discordId?: string; 1450 telegramUsername?: string; 1451 signalNumber?: string; 1452 }, 1453 ): Promise<Result<SuccessResponse, ApiError>> { 1454 return xrpcResult("_account.updateNotificationPrefs", { 1455 method: "POST", 1456 token, 1457 body: prefs, 1458 }); 1459 }, 1460 1461 revokeTrustedDevice( 1462 token: AccessToken, 1463 deviceId: string, 1464 ): Promise<Result<SuccessResponse, ApiError>> { 1465 return xrpcResult("_account.revokeTrustedDevice", { 1466 method: "POST", 1467 token, 1468 body: { deviceId }, 1469 }); 1470 }, 1471 1472 updateTrustedDevice( 1473 token: AccessToken, 1474 deviceId: string, 1475 friendlyName: string, 1476 ): Promise<Result<SuccessResponse, ApiError>> { 1477 return xrpcResult("_account.updateTrustedDevice", { 1478 method: "POST", 1479 token, 1480 body: { deviceId, friendlyName }, 1481 }); 1482 }, 1483 1484 reauthPassword( 1485 token: AccessToken, 1486 password: string, 1487 ): Promise<Result<ReauthResponse, ApiError>> { 1488 return xrpcResult("_account.reauthPassword", { 1489 method: "POST", 1490 token, 1491 body: { password }, 1492 }); 1493 }, 1494 1495 reauthTotp( 1496 token: AccessToken, 1497 code: string, 1498 ): Promise<Result<ReauthResponse, ApiError>> { 1499 return xrpcResult("_account.reauthTotp", { 1500 method: "POST", 1501 token, 1502 body: { code }, 1503 }); 1504 }, 1505 1506 reauthPasskeyStart( 1507 token: AccessToken, 1508 ): Promise<Result<ReauthPasskeyStartResponse, ApiError>> { 1509 return xrpcResult("_account.reauthPasskeyStart", { 1510 method: "POST", 1511 token, 1512 }); 1513 }, 1514 1515 reauthPasskeyFinish( 1516 token: AccessToken, 1517 credential: unknown, 1518 ): Promise<Result<ReauthResponse, ApiError>> { 1519 return xrpcResult("_account.reauthPasskeyFinish", { 1520 method: "POST", 1521 token, 1522 body: { credential }, 1523 }); 1524 }, 1525 1526 confirmSignup( 1527 did: Did, 1528 verificationCode: string, 1529 ): Promise<Result<ConfirmSignupResult, ApiError>> { 1530 return xrpcResult("com.atproto.server.confirmSignup", { 1531 method: "POST", 1532 body: { did, verificationCode }, 1533 }); 1534 }, 1535 1536 resendVerification( 1537 did: Did, 1538 ): Promise<Result<{ success: boolean }, ApiError>> { 1539 return xrpcResult("com.atproto.server.resendVerification", { 1540 method: "POST", 1541 body: { did }, 1542 }); 1543 }, 1544 1545 requestEmailUpdate( 1546 token: AccessToken, 1547 ): Promise<Result<EmailUpdateResponse, ApiError>> { 1548 return xrpcResult("com.atproto.server.requestEmailUpdate", { 1549 method: "POST", 1550 token, 1551 }); 1552 }, 1553 1554 updateEmail( 1555 token: AccessToken, 1556 email: string, 1557 emailToken?: string, 1558 ): Promise<Result<void, ApiError>> { 1559 return xrpcResult<void>("com.atproto.server.updateEmail", { 1560 method: "POST", 1561 token, 1562 body: { email, token: emailToken }, 1563 }); 1564 }, 1565 1566 requestAccountDelete(token: AccessToken): Promise<Result<void, ApiError>> { 1567 return xrpcResult<void>("com.atproto.server.requestAccountDelete", { 1568 method: "POST", 1569 token, 1570 }); 1571 }, 1572 1573 deleteAccount( 1574 did: Did, 1575 password: string, 1576 deleteToken: string, 1577 ): Promise<Result<void, ApiError>> { 1578 return xrpcResult<void>("com.atproto.server.deleteAccount", { 1579 method: "POST", 1580 body: { did, password, token: deleteToken }, 1581 }); 1582 }, 1583 1584 updateDidDocument( 1585 token: AccessToken, 1586 params: { 1587 verificationMethods?: VerificationMethod[]; 1588 alsoKnownAs?: string[]; 1589 serviceEndpoint?: string; 1590 }, 1591 ): Promise<Result<SuccessResponse, ApiError>> { 1592 return xrpcResult("_account.updateDidDocument", { 1593 method: "POST", 1594 token, 1595 body: params, 1596 }); 1597 }, 1598 1599 deactivateAccount( 1600 token: AccessToken, 1601 deleteAfter?: string, 1602 ): Promise<Result<void, ApiError>> { 1603 return xrpcResult<void>("com.atproto.server.deactivateAccount", { 1604 method: "POST", 1605 token, 1606 body: { deleteAfter }, 1607 }); 1608 }, 1609 1610 activateAccount(token: AccessToken): Promise<Result<void, ApiError>> { 1611 return xrpcResult<void>("com.atproto.server.activateAccount", { 1612 method: "POST", 1613 token, 1614 }); 1615 }, 1616 1617 setBackupEnabled( 1618 token: AccessToken, 1619 enabled: boolean, 1620 ): Promise<Result<SetBackupEnabledResponse, ApiError>> { 1621 return xrpcResult("_backup.setEnabled", { 1622 method: "POST", 1623 token, 1624 body: { enabled }, 1625 }); 1626 }, 1627 1628 deleteBackup( 1629 token: AccessToken, 1630 id: string, 1631 ): Promise<Result<void, ApiError>> { 1632 return xrpcResult<void>("_backup.deleteBackup", { 1633 method: "POST", 1634 token, 1635 params: { id }, 1636 }); 1637 }, 1638 1639 createRecord( 1640 token: AccessToken, 1641 repo: Did, 1642 collection: Nsid, 1643 record: unknown, 1644 rkey?: Rkey, 1645 ): Promise<Result<CreateRecordResponse, ApiError>> { 1646 return xrpcResult("com.atproto.repo.createRecord", { 1647 method: "POST", 1648 token, 1649 body: { repo, collection, record, rkey }, 1650 }); 1651 }, 1652 1653 putRecord( 1654 token: AccessToken, 1655 repo: Did, 1656 collection: Nsid, 1657 rkey: Rkey, 1658 record: unknown, 1659 ): Promise<Result<CreateRecordResponse, ApiError>> { 1660 return xrpcResult("com.atproto.repo.putRecord", { 1661 method: "POST", 1662 token, 1663 body: { repo, collection, rkey, record }, 1664 }); 1665 }, 1666 1667 getInviteCodes( 1668 token: AccessToken, 1669 options?: { sort?: "recent" | "usage"; cursor?: string; limit?: number }, 1670 ): Promise<Result<GetInviteCodesResponse, ApiError>> { 1671 const params: Record<string, string> = {}; 1672 if (options?.sort) params.sort = options.sort; 1673 if (options?.cursor) params.cursor = options.cursor; 1674 if (options?.limit) params.limit = String(options.limit); 1675 return xrpcResult("com.atproto.admin.getInviteCodes", { token, params }); 1676 }, 1677 1678 disableAccountInvites( 1679 token: AccessToken, 1680 account: Did, 1681 ): Promise<Result<void, ApiError>> { 1682 return xrpcResult<void>("com.atproto.admin.disableAccountInvites", { 1683 method: "POST", 1684 token, 1685 body: { account }, 1686 }); 1687 }, 1688 1689 enableAccountInvites( 1690 token: AccessToken, 1691 account: Did, 1692 ): Promise<Result<void, ApiError>> { 1693 return xrpcResult<void>("com.atproto.admin.enableAccountInvites", { 1694 method: "POST", 1695 token, 1696 body: { account }, 1697 }); 1698 }, 1699 1700 adminDeleteAccount( 1701 token: AccessToken, 1702 did: Did, 1703 ): Promise<Result<void, ApiError>> { 1704 return xrpcResult<void>("com.atproto.admin.deleteAccount", { 1705 method: "POST", 1706 token, 1707 body: { did }, 1708 }); 1709 }, 1710 1711 startPasskeyRegistration( 1712 token: AccessToken, 1713 friendlyName?: string, 1714 ): Promise<Result<StartPasskeyRegistrationResponse, ApiError>> { 1715 return xrpcResult("com.atproto.server.startPasskeyRegistration", { 1716 method: "POST", 1717 token, 1718 body: { friendlyName }, 1719 }); 1720 }, 1721 1722 finishPasskeyRegistration( 1723 token: AccessToken, 1724 credential: unknown, 1725 friendlyName?: string, 1726 ): Promise<Result<FinishPasskeyRegistrationResponse, ApiError>> { 1727 return xrpcResult("com.atproto.server.finishPasskeyRegistration", { 1728 method: "POST", 1729 token, 1730 body: { credential, friendlyName }, 1731 }); 1732 }, 1733 1734 updatePasskey( 1735 token: AccessToken, 1736 id: string, 1737 friendlyName: string, 1738 ): Promise<Result<void, ApiError>> { 1739 return xrpcResult<void>("com.atproto.server.updatePasskey", { 1740 method: "POST", 1741 token, 1742 body: { id, friendlyName }, 1743 }); 1744 }, 1745 1746 regenerateBackupCodes( 1747 token: AccessToken, 1748 password: string, 1749 code: string, 1750 ): Promise<Result<RegenerateBackupCodesResponse, ApiError>> { 1751 return xrpcResult("com.atproto.server.regenerateBackupCodes", { 1752 method: "POST", 1753 token, 1754 body: { password, code }, 1755 }); 1756 }, 1757 1758 updateLocale( 1759 token: AccessToken, 1760 preferredLocale: string, 1761 ): Promise<Result<UpdateLocaleResponse, ApiError>> { 1762 return xrpcResult("_account.updateLocale", { 1763 method: "POST", 1764 token, 1765 body: { preferredLocale }, 1766 }); 1767 }, 1768 1769 confirmChannelVerification( 1770 token: AccessToken, 1771 channel: string, 1772 identifier: string, 1773 code: string, 1774 ): Promise<Result<SuccessResponse, ApiError>> { 1775 return xrpcResult("_account.confirmChannelVerification", { 1776 method: "POST", 1777 token, 1778 body: { channel, identifier, code }, 1779 }); 1780 }, 1781 1782 removePassword( 1783 token: AccessToken, 1784 ): Promise<Result<SuccessResponse, ApiError>> { 1785 return xrpcResult("_account.removePassword", { 1786 method: "POST", 1787 token, 1788 }); 1789 }, 1790};