@recursiv/sdk 0.7.152 → 0.7.195

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.
@@ -1,6 +1,7 @@
1
1
  import type { HttpClient } from '../client.js';
2
2
  import type { CompassFilterMeta, DiscoveryLayout, PaginatedResponse, PaginationParams, SingleResponse, StoryOutlets } from '../types.js';
3
3
  import type { CuratorStoryPostsPage } from './curator.js';
4
+ import type { CategorySurface } from './discovery.js';
4
5
  import type { NativeWriteProtocol, SocialProtocolId } from '../social-protocol-ids.js';
5
6
  /** Canonical protocol operation names returned by the adapter registry. */
6
7
  export declare const PROTOCOL_CAPABILITY_OPERATIONS: readonly ["discover", "stream", "backfill", "search", "resolveIdentity", "fetchProfile", "fetchThread", "publish", "reply", "react", "repost", "follow", "delete", "health", "checkpoint"];
@@ -375,7 +376,7 @@ export interface HostedNostrIdentityProof {
375
376
  created_at: number;
376
377
  tags: string[][];
377
378
  }
378
- export type NativeNostrPrepareInput = {
379
+ export type NativeNostrPrepareInput = ({
379
380
  action: 'publish';
380
381
  content: string;
381
382
  /** Your own post in this app (sdk.posts) that this note copies, so deleting it can offer this copy. */
@@ -403,6 +404,13 @@ export type NativeNostrPrepareInput = {
403
404
  } | {
404
405
  action: 'delete';
405
406
  postId: string;
407
+ }) & {
408
+ /**
409
+ * A key Minds holds (`signing: 'server'`, 0.7.192): `true` once the member approved, and Minds signs the exact event
410
+ * and sends it in this call (the answer carries `receipt`). Without it a prepare is a preview for every key: nothing
411
+ * is signed, sent or deleted. Ignored for the member's own key, which they sign on their device as before.
412
+ */
413
+ send?: true;
406
414
  };
407
415
  export type NativeSocialProtocol = 'bluesky' | 'activitypub';
408
416
  export interface NativeSocialAccount {
@@ -435,7 +443,7 @@ export type NativeNetwork = 'activitypub' | 'atproto' | 'nostr';
435
443
  * for the setup budget (`retryAt`). `off`: the member turned it off (`reason: 'opted_out'`), it is not available to them
436
444
  * yet (`not_rolled_out`), or their profile is private (`private_profile`, AT Protocol and Nostr only; `setNetwork`
437
445
  * with `enabled: true` turns it on). `needs_action`: the member must act first (`age_band_required`,
438
- * `needs_verified_email`). `locked`: held off by a rule the member cannot change.
446
+ * `needs_verified_email`, `needs_atproto_grant`: `grantAtproto`). `locked`: held off by a rule the member cannot change.
439
447
  */
440
448
  export type NativeNetworkState = 'ready' | 'on' | 'pending' | 'off' | 'error' | 'locked' | 'needs_action';
441
449
  export interface NativeNetworkPresence {
@@ -447,8 +455,20 @@ export interface NativeNetworkPresence {
447
455
  mode: 'hosted' | 'managed' | 'attached';
448
456
  /** The member's address on the network, set up or not, when the server can say it. */
449
457
  handle: string | null;
450
- /** Which identity a one-tap like, repost, reply or follow uses when the member also linked an outside account. */
458
+ /**
459
+ * Which identity a one-tap like, repost, reply or follow without `identity` acts as now: the member's choice
460
+ * (`setEngageDefault`) when it can act, else `linked` while they have an account there linked before the cutover, else
461
+ * `native` while their native identity can act, else `linked` when they have a linked account (the fallback). When
462
+ * nothing can act, their choice, else `native`.
463
+ */
451
464
  engageDefault: 'native' | 'linked';
465
+ /**
466
+ * Where engageDefault comes from (0.7.191): the member's choice, their linked account, the default, or the fallback
467
+ * (the native identity cannot act, so a tap acts as the linked account whatever the member chose).
468
+ */
469
+ engageDefaultSource?: 'chosen' | 'linked_account' | 'default' | 'fallback';
470
+ /** Whether the member linked an outside account on this network (0.7.191; only `networks()` reports it). */
471
+ linked?: boolean;
452
472
  activatedAt: string | null;
453
473
  optedOutAt: string | null;
454
474
  removePast: boolean;
@@ -470,6 +490,137 @@ export interface SetNativeNetworkInput {
470
490
  /** Turning off: also remove what was already shared there (the Settings sheet checks this by default). */
471
491
  removePast?: boolean;
472
492
  }
493
+ /**
494
+ * A Minds step-up for "Get my AT Protocol password" (0.7.191): the member's password, or, for an account with no password, the
495
+ * code from `POST /settings/confirmation-code` with purpose `atproto_password`. Exactly one.
496
+ */
497
+ export type AtprotoPasswordClaimProof = {
498
+ password: string;
499
+ } | {
500
+ emailCode: string;
501
+ };
502
+ /** Where the reset code went: the member's verified email, masked (`o***@example.com`), and the account's handle. */
503
+ export interface AtprotoPasswordClaim {
504
+ handle: string;
505
+ sentTo: string;
506
+ }
507
+ /**
508
+ * What `grantAtproto` answers (0.7.191): the account's handle, and the member's AT Protocol presence after the grant
509
+ * (set up as "Set up now" would: `on`, unless the member turned the network off).
510
+ */
511
+ export interface AtprotoGrant {
512
+ handle: string;
513
+ presence: NativeNetworkPresence;
514
+ }
515
+ /** Which identity a one-tap action acts as (0.7.191): the member's own on that network, or an outside account they linked. */
516
+ export type EngageIdentity = 'native' | 'linked';
517
+ /** Who acted, on every engage answer. `handle` is the address on the network, null when the server cannot say it. */
518
+ export interface EngageActedAs {
519
+ network: NativeNetwork;
520
+ handle: string | null;
521
+ identity: EngageIdentity;
522
+ }
523
+ /**
524
+ * What a linked review adds (0.7.191): who acted, and `notice: 'engage_default_linked'` once, the first time a member who
525
+ * linked an account before acts as it while they also have a native identity there (say so, and link to Settings).
526
+ */
527
+ export interface EngageLinkedFields {
528
+ identity?: 'linked';
529
+ actedAs?: EngageActedAs | null;
530
+ notice?: 'engage_default_linked';
531
+ }
532
+ /** A native one-tap action the network was sent (200). A `failed` delivery with `retryable` may be tried again. */
533
+ export interface NativeEngageSent {
534
+ identity: 'native';
535
+ queued: false;
536
+ delivery: {
537
+ state: 'sent';
538
+ } | {
539
+ state: 'skipped';
540
+ code: string;
541
+ } | {
542
+ state: 'failed';
543
+ code: string;
544
+ retryable: boolean;
545
+ };
546
+ actedAs: EngageActedAs;
547
+ }
548
+ /**
549
+ * A native one-tap action kept while the member's identity there is set up (202). It is sent, in the order the member
550
+ * took their actions, once the identity is on; if it cannot be by `expiresAt` the member is notified. `retryAt`: when the
551
+ * setup budget frees, when that is known. List them with `pendingInteractions()`.
552
+ */
553
+ export interface NativeEngageQueued {
554
+ identity: 'native';
555
+ queued: true;
556
+ interactionId: string;
557
+ expiresAt: string;
558
+ retryAt: string | null;
559
+ actedAs: EngageActedAs;
560
+ }
561
+ /** An engage answer: the native action sent or queued, or the linked review to approve (submit) as before. */
562
+ export type EngageAnswer<Review> = NativeEngageSent | NativeEngageQueued | (Review & EngageLinkedFields & {
563
+ identity: 'linked';
564
+ });
565
+ /** One one-tap action waiting for the member's native identity (`pendingInteractions()`). */
566
+ export interface PendingNativeInteraction {
567
+ id: string;
568
+ network: NativeNetwork;
569
+ action: string;
570
+ target: string;
571
+ state: 'queued';
572
+ createdAt: string;
573
+ expiresAt: string;
574
+ }
575
+ /**
576
+ * A one-tap like, repost or follow (0.7.191). Without `identity` the server decides: the member's choice, their linked
577
+ * account when they had one, else their native identity. `accountId` names a linked account (identity `linked` only).
578
+ * `protocol` is a network the API writes to (NativeWriteProtocol): a Farcaster post can be read, not yet engaged with.
579
+ */
580
+ export interface EngageOneInput<Action extends string> {
581
+ protocol: NativeWriteProtocol;
582
+ nativeId: string;
583
+ clientMutationId: string;
584
+ action: Action;
585
+ identity?: EngageIdentity;
586
+ accountId?: string;
587
+ }
588
+ /**
589
+ * The step-up the Nostr key actions ask for: the account's password, or, for an account with no password, the code
590
+ * from `settings.requestConfirmationCode('nostr_key')` (sent to the account's own address). Five tries an hour.
591
+ */
592
+ export type NostrKeyStepUp = {
593
+ password: string;
594
+ emailCode?: never;
595
+ } | {
596
+ emailCode: string;
597
+ password?: never;
598
+ };
599
+ /** The member's managed Nostr key, to import into a signer on their device. Minds keeps its copy and keeps signing. */
600
+ export interface ManagedNostrKeyExport {
601
+ pubkey: string;
602
+ npub: string;
603
+ /** The private key (NIP-19). Show it to the member alone, once; never log, store or send it anywhere. */
604
+ nsec: string;
605
+ /** Their NIP-05 address, `name@<app host>`. */
606
+ handle: string;
607
+ }
608
+ /** What the member's signer signs (NIP-07) to show it holds the same key as their Nostr identity. */
609
+ export interface NostrRebindChallenge extends HostedNostrChallenge {
610
+ /** The identity's key: the signer must sign with this one. */
611
+ pubkey: string;
612
+ }
613
+ export interface NostrRebindResult {
614
+ mode: 'attached';
615
+ pubkey: string;
616
+ }
617
+ /** Minds deleted its copy of the key: from now on every Nostr action is signed on the member's device. */
618
+ export interface ManagedNostrCopyDeleted {
619
+ deleted: true;
620
+ mode: 'attached';
621
+ pubkey: string;
622
+ signing: 'device';
623
+ }
473
624
  export interface SocialSourceRef {
474
625
  /**
475
626
  * 0.7.87: any SOCIAL_PROTOCOL_IDS network, Farcaster (an FID, or a `<fid>:0x<hash>` CastId) before its reader serves a
@@ -1034,12 +1185,28 @@ export interface NativeNostrPrepared {
1034
1185
  textTruncated: boolean;
1035
1186
  relay: string;
1036
1187
  };
1188
+ /**
1189
+ * A key Minds holds (0.7.192): there is nothing to sign or submit. Without `send` this is the preview to show the
1190
+ * member (nothing was signed or sent); prepare again with `send: true` once they approve. With `send: true`, Minds
1191
+ * signed `event` and sent it in this call, and `receipt` says what the relay did.
1192
+ */
1193
+ signing?: 'server';
1194
+ receipt?: NativeNostrReceipt;
1037
1195
  }
1038
1196
  export interface NativeNostrAccount {
1039
1197
  enabled: boolean;
1040
1198
  identity: HostedProtocolIdentity | null;
1041
1199
  capabilities: Array<'publish_original_text' | 'request_own_post_deletion' | 'reply_text_note' | 'publish_linked_text' | 'quote' | 'like' | 'unlike' | 'repost' | 'unrepost' | 'follow' | 'unfollow'>;
1042
- signing?: 'client';
1200
+ /**
1201
+ * Who signs (0.7.192). `client`: the member's own key, on their device (NIP-07): prepare, sign the exact event, submit.
1202
+ * `server`: a key Minds holds for the member (`mode: 'managed'`): Minds signs. A prepare is a preview, and a prepare
1203
+ * with `send: true` signs and sends in the same call (answering the `receipt`); a like, repost or follow review needs
1204
+ * no `event` on submit, and the one-tap `engage*` methods with `identity: 'native'` act as it. `enabled` then follows
1205
+ * the member's Nostr presence: false, with no capabilities, while Nostr is not rolled out to them. For either key,
1206
+ * `like`, `repost` and `follow` (and their undos) are listed only while the app's review route for them is on.
1207
+ */
1208
+ signing?: 'client' | 'server';
1209
+ mode?: 'managed';
1043
1210
  }
1044
1211
  export interface NativeNostrPostState {
1045
1212
  postId: string;
@@ -1253,6 +1420,8 @@ export interface SocialPost {
1253
1420
  width?: number;
1254
1421
  height?: number;
1255
1422
  sensitive?: true;
1423
+ /** A video's length in whole seconds, where the source declares it (PeerTube; server 0.7.155). */
1424
+ durationSec?: number;
1256
1425
  }>;
1257
1426
  hasAdditionalContent: boolean;
1258
1427
  /**
@@ -1285,6 +1454,14 @@ export interface SocialPost {
1285
1454
  authorOptOut?: true;
1286
1455
  /** A bridge (Bridgy Fed, Mostr, a NIP-48 proxy tag) made this post from one on another network (SocialBridge). Present only on a copy read live. */
1287
1456
  bridge?: SocialBridge;
1457
+ /**
1458
+ * The Fediverse software that published the post, where the server knows it (0.7.155): `peertube` for a PeerTube
1459
+ * video read off its own instance. Its `author` is the video's channel (follow it as any Fediverse account) and its
1460
+ * one `media` entry is the video's stream, a progressive MP4 (never an HLS playlist: a plain video element plays it)
1461
+ * with the poster on the API's media proxy. Label it as the Fediverse, from PeerTube; play it in place, never open
1462
+ * `sourceUrl`.
1463
+ */
1464
+ software?: 'peertube';
1288
1465
  }
1289
1466
  export interface SocialPostSearch {
1290
1467
  items: SocialPost[];
@@ -1557,6 +1734,37 @@ export interface SocialRadar {
1557
1734
  compass_filter?: CompassFilterMeta;
1558
1735
  };
1559
1736
  }
1737
+ /**
1738
+ * A category's surface for a signed-out visitor (`getSharedCategorySurface`, 0.7.165; GET /protocols/public/:projectId/category):
1739
+ * the category's stories, its open-network posts and its clips, the three sections a member's `discovery.category()` reads
1740
+ * from the same server cache, never people or groups. Every visitor floor runs again on each read: stories lose tier-1,
1741
+ * held and blocked-instance members and show media only from outlets and members marked `visitorMedia`; network posts
1742
+ * keep their pictures (with their `width` and `height`) only where cleared for visitors (`visitorMedia: true`), lose a
1743
+ * post marked sensitive or on a blocked instance, and pass the safety and term floors; clips are the anonymous floor's
1744
+ * (never NSFW). A section that is short or failed says why in `reason` (`timeout`, `error`, `off`).
1745
+ */
1746
+ export interface SharedCategorySurface extends Omit<CategorySurface, 'people' | 'groups'> {
1747
+ /**
1748
+ * Present when `compass` named a filtering choice: what Hide politics left out of the three sections together (stories
1749
+ * by their `political` mark and theme, network posts and clips by their category, words and author), with
1750
+ * `basis: 'flags'` until the operator serves visitors the full filter; or `status: 'unavailable'` for a side or Mix,
1751
+ * which no section can apply (the sections are Everything's).
1752
+ */
1753
+ meta?: {
1754
+ compass_filter?: CompassFilterMeta;
1755
+ };
1756
+ }
1757
+ export interface SharedCategorySurfaceParams {
1758
+ /** A browse category the app serves (a network catalog's `categories`); any other is a 400 `categories_unavailable`. */
1759
+ category: string;
1760
+ /**
1761
+ * A visitor's Politics choice: `all` or `hide`; a side or Mix only where the app's catalog lists `compass_sides` for
1762
+ * visitors (`sharedNetworks`: the operator serves them the full filter), and it is a 400 `invalid_input` everywhere else.
1763
+ * No section carries a placement, so an accepted side or Mix answers Everything's sections with
1764
+ * `meta.compass_filter.status: 'unavailable'`, as the radar, the trends, the viral read and Watch answer it.
1765
+ */
1766
+ compass?: string;
1767
+ }
1560
1768
  export interface SocialRadarParams {
1561
1769
  category?: string;
1562
1770
  limit?: number;
@@ -2032,6 +2240,13 @@ export declare class ProtocolsResource {
2032
2240
  * failure throws. Cacheable for a minute by a shared cache.
2033
2241
  */
2034
2242
  getSharedViral(projectId: string, params?: ViralReadParams, options?: SocialReadOptions): Promise<SingleResponse<ViralReadResponse>>;
2243
+ /**
2244
+ * A category's stories, open-network posts and clips for a signed-out visitor, in one keyless read (SharedCategorySurface).
2245
+ * The answer is the same for every visitor of the app, category and Politics choice, and the URL carries nothing else,
2246
+ * so a shared cache may keep it for 30 s. Only `category` and `compass` are sent: the server refuses any other
2247
+ * parameter. An API that predates the route answers 401 `missing_api_key` (it falls through to the keyed routes) or 404.
2248
+ */
2249
+ getSharedCategorySurface(projectId: string, params: SharedCategorySurfaceParams, options?: SocialReadOptions): Promise<SingleResponse<SharedCategorySurface>>;
2035
2250
  publicNetworks(): Promise<SingleResponse<SocialNetwork[]>>;
2036
2251
  /** Query the live public network. It does not import users or posts. */
2037
2252
  searchPublicPosts(params: SearchPublicPostsParams): Promise<SingleResponse<SocialPostSearch>>;
@@ -2150,7 +2365,7 @@ export declare class ProtocolsResource {
2150
2365
  */
2151
2366
  nativeFollowStates(input: Omit<NativeFollowSourceInput, 'accountId'>): Promise<SingleResponse<NativeFollowStates>>;
2152
2367
  /** Prepare a follow/unfollow for explicit approval. Preserve the mutation ID after a lost response. */
2153
- prepareNativeFollow(input: NativeFollowPrepareInput): Promise<SingleResponse<NativeFollowReview>>;
2368
+ prepareNativeFollow(input: NativeFollowPrepareInput): Promise<SingleResponse<NativeFollowReview & EngageLinkedFields>>;
2154
2369
  /** Submit one approved action. Only Nostr supplies a public signed event. Automatic retries are disabled. */
2155
2370
  submitNativeFollow(id: string, input: {
2156
2371
  approve: true;
@@ -2161,7 +2376,7 @@ export declare class ProtocolsResource {
2161
2376
  /** Read this connected account's current native like; never infer it from a public count. */
2162
2377
  nativeLikeState(input: NativeLikeSourceInput): Promise<SingleResponse<NativeLikeState>>;
2163
2378
  /** Prepare a like/unlike for explicit approval. Preserve the mutation ID after a lost response. */
2164
- prepareNativeLike(input: NativeLikePrepareInput): Promise<SingleResponse<NativeLikeReview>>;
2379
+ prepareNativeLike(input: NativeLikePrepareInput): Promise<SingleResponse<NativeLikeReview & EngageLinkedFields>>;
2165
2380
  /** Submit one approved action. Only Nostr supplies a public signed event. Automatic retries are disabled. */
2166
2381
  submitNativeLike(id: string, input: {
2167
2382
  approve: true;
@@ -2172,7 +2387,7 @@ export declare class ProtocolsResource {
2172
2387
  /** Read this connected account's current native repost; never infer it from a public count. */
2173
2388
  nativeRepostState(input: NativeRepostSourceInput): Promise<SingleResponse<NativeRepostState>>;
2174
2389
  /** Prepare a repost/unrepost for explicit approval. Preserve the mutation ID after a lost response. */
2175
- prepareNativeRepost(input: NativeRepostPrepareInput): Promise<SingleResponse<NativeRepostReview>>;
2390
+ prepareNativeRepost(input: NativeRepostPrepareInput): Promise<SingleResponse<NativeRepostReview & EngageLinkedFields>>;
2176
2391
  /** Submit one approved action. Only Nostr supplies a public signed event. Automatic retries are disabled. */
2177
2392
  submitNativeRepost(id: string, input: {
2178
2393
  approve: true;
@@ -2181,7 +2396,7 @@ export declare class ProtocolsResource {
2181
2396
  /** Reconcile the saved action without sending another native write. */
2182
2397
  nativeRepostStatus(id: string): Promise<SingleResponse<NativeRepostReview>>;
2183
2398
  /** Prepare exact public text, reviewed images and an optional native quote for selected connected Bluesky/ActivityPub accounts. */
2184
- prepareNativePost(input: NativePostPrepareInput): Promise<SingleResponse<NativePostBatch>>;
2399
+ prepareNativePost(input: NativePostPrepareInput): Promise<SingleResponse<NativePostBatch & EngageLinkedFields>>;
2185
2400
  /** Explicitly approve selected deliveries; never auto-retry an uncertain write. */
2186
2401
  submitNativePost(id: string, input: {
2187
2402
  approve: true;
@@ -2224,7 +2439,7 @@ export declare class ProtocolsResource {
2224
2439
  }>;
2225
2440
  }>>;
2226
2441
  /** Prepare one exact shared reply preview. Keep the mutation ID across uncertain responses. */
2227
- prepareNativeReply(input: NativeReplyPrepareInput): Promise<SingleResponse<NativeReplyBatch>>;
2442
+ prepareNativeReply(input: NativeReplyPrepareInput): Promise<SingleResponse<NativeReplyBatch & EngageLinkedFields>>;
2228
2443
  /** Send only explicitly approved delivery IDs from this preview. Repeated submissions reconcile; they do not replay a write. */
2229
2444
  submitNativeReply(id: string, input: {
2230
2445
  approve: true;
@@ -2344,6 +2559,113 @@ export declare class ProtocolsResource {
2344
2559
  * `age_band_required`. Needs `users:write`.
2345
2560
  */
2346
2561
  setNetwork(network: NativeNetwork, input: SetNativeNetworkInput): Promise<SingleResponse<NativeNetworkActivation | NativeNetworkOff>>;
2562
+ /**
2563
+ * Which identity a one-tap action uses on a network when the member also linked an outside account there (0.7.191).
2564
+ * `linked` needs a linked account (409 `linked_account_required`); `native` needs the network on, ready or pending
2565
+ * (409 `native_network_off`) and a network that can send a tap as the member's identity (503
2566
+ * `native_network_unavailable`, reason `adapter_missing`, otherwise), and sets the identity up now when that is what the
2567
+ * choice needs. Needs `users:write`.
2568
+ */
2569
+ setEngageDefault(network: NativeNetwork, engageDefault: EngageIdentity): Promise<SingleResponse<{
2570
+ network: NativeNetwork;
2571
+ engageDefault: EngageIdentity;
2572
+ presence: NativeNetworkPresence | null;
2573
+ }>>;
2574
+ /**
2575
+ * "Get my AT Protocol password" (0.7.191): the PDS emails a reset code to the member's verified address, the one their hosted AT
2576
+ * Protocol account uses; Minds never holds or shows that password (it keeps only a revocable app password, which the
2577
+ * member can revoke from any AT Protocol app). Needs a step-up (403 `step_up_required` / `step_up_failed`). Other
2578
+ * refusals: 404 `no_identity`, 409 `needs_verified_email` or `email_changed`, 429 `rate_limited`. Needs `users:write`.
2579
+ * Never auto-retried.
2580
+ */
2581
+ claimAtprotoPassword(proof: AtprotoPasswordClaimProof): Promise<SingleResponse<AtprotoPasswordClaim>>;
2582
+ /**
2583
+ * "Let Minds act as your AT Protocol account" (0.7.191): the way back when AT Protocol reads `needs_action` with reason
2584
+ * `needs_atproto_grant` (an account made before Minds ran it natively) or `error` with `app_password_revoked`. The member
2585
+ * enters their AT Protocol account's password once (the main one, which `claimAtprotoPassword` lets them set, or a
2586
+ * non-privileged app password they made); Minds keeps only a new revocable app password and drops the password given.
2587
+ * Refusals: 403 `password_failed`, 400 `privileged_app_password` (one that can read direct messages), 409
2588
+ * `identity_mismatch`, 404 `no_identity`, 429 `rate_limited`. Needs `users:write`. Never auto-retried.
2589
+ */
2590
+ grantAtproto(input: {
2591
+ password: string;
2592
+ }): Promise<SingleResponse<AtprotoGrant>>;
2593
+ /** The member's one-tap actions waiting for their native identity to be set up, oldest first (0.7.191). Needs `users:read`. */
2594
+ pendingInteractions(): Promise<SingleResponse<{
2595
+ interactions: PendingNativeInteraction[];
2596
+ }>>;
2597
+ /**
2598
+ * One-tap like or unlike (0.7.191). A native answer is sent (`NativeEngageSent`) or queued (`NativeEngageQueued`, 202)
2599
+ * while the identity is set up; a linked answer is the review to submit with `submitNativeLike`, as before. Refusals:
2600
+ * 409 `native_network_off` (with `reason`), 409 `linked_account_required`, 429 `too_many_pending`, and 503
2601
+ * `native_network_unavailable` with reason `adapter_missing` while the network cannot send a tap as the member's identity
2602
+ * (a linked account acts instead when there is one; nothing is set up or queued). Keep
2603
+ * `clientMutationId` across retries: a retried tap is never sent twice, and once it expired unsent the retry answers
2604
+ * `delivery: { state: 'failed', code: 'interaction_expired' }` (a new tap takes a new id). The same id on a different
2605
+ * action, target or words is 409 `client_mutation_reused`. A tap whose identity went off before it was sent answers
2606
+ * `delivery: { state: 'failed', code: 'native_network_off' }`. Never auto-retried.
2607
+ */
2608
+ engageLike(input: EngageOneInput<'like' | 'unlike'>): Promise<SingleResponse<EngageAnswer<NativeLikeReview>>>;
2609
+ /** One-tap repost or unrepost (0.7.191); answers as `engageLike` does (linked: submit with `submitNativeRepost`). */
2610
+ engageRepost(input: EngageOneInput<'repost' | 'unrepost'>): Promise<SingleResponse<EngageAnswer<NativeRepostReview>>>;
2611
+ /** One-tap follow or unfollow (0.7.191); answers as `engageLike` does (linked: submit with `submitNativeFollow`). */
2612
+ engageFollow(input: EngageOneInput<'follow' | 'unfollow'>): Promise<SingleResponse<EngageAnswer<NativeFollowReview>>>;
2613
+ /**
2614
+ * A reply as the member's own identity on the parent's network, or (identity `linked`, or `accountIds`) the shared
2615
+ * reply review as `prepareNativeReply` (0.7.191). Answers as `engageLike` does. `media` takes only the member's own
2616
+ * Minds uploads, native or linked (400 `invalid_reply` otherwise; 422 `media_unsupported` for a GIF with other images
2617
+ * on ActivityPub).
2618
+ */
2619
+ engageReply(input: {
2620
+ clientMutationId: string;
2621
+ text: string;
2622
+ parent: {
2623
+ protocol: NativeWriteProtocol;
2624
+ nativeId: string;
2625
+ readRef?: string;
2626
+ };
2627
+ media?: NativeMediaInput[];
2628
+ identity?: EngageIdentity;
2629
+ accountIds?: string[];
2630
+ }): Promise<SingleResponse<EngageAnswer<NativeReplyBatch>>>;
2631
+ /**
2632
+ * A quote of a post as the member's own identity on its network, or (identity `linked`, or `accountIds`) the post
2633
+ * review as `prepareNativePost` (0.7.191). A post with no quote is never native: the member's posts in the app reach
2634
+ * their networks on their own (409 `native_post_from_app`). Answers as `engageLike` does.
2635
+ */
2636
+ engageQuote(input: {
2637
+ clientMutationId: string;
2638
+ text: string;
2639
+ quote: {
2640
+ protocol: NativeWriteProtocol;
2641
+ nativeId: string;
2642
+ };
2643
+ media?: NativeMediaInput[];
2644
+ identity?: EngageIdentity;
2645
+ accountIds?: string[];
2646
+ }): Promise<SingleResponse<EngageAnswer<NativePostBatch>>>;
2647
+ /**
2648
+ * Takes the member's managed Nostr key home, step 1: the key as an `nsec`, after a step-up (403 `step_up_required`
2649
+ * or `step_up_failed`, 429 `rate_limited`, 404 `no_managed_key`). Minds keeps its copy. Never retried. Needs
2650
+ * `users:write`.
2651
+ */
2652
+ exportNostrKey(stepUp: NostrKeyStepUp): Promise<SingleResponse<ManagedNostrKeyExport>>;
2653
+ /** Step 2a: a single-use challenge for the member's signer to sign with the same key (NIP-07, never published). */
2654
+ nostrRebindChallenge(): Promise<SingleResponse<NostrRebindChallenge>>;
2655
+ /**
2656
+ * Step 2b: the signed challenge. A signature from the identity's own key sets the mode to `attached` (409
2657
+ * `rebind_mismatch` for another key; 400 `invalid_proof`, `expired_proof` or `used_proof`). Minds still holds its copy.
2658
+ */
2659
+ rebindNostrKey(event: HostedNostrIdentityProof): Promise<SingleResponse<NostrRebindResult>>;
2660
+ /**
2661
+ * Step 3: after a step-up, and only once rebound (409 `rebind_required`), Minds deletes its encrypted copy of the
2662
+ * key. First it signs, with the copy, a takedown for everything it published with the key, kept so a post deletion,
2663
+ * "Remove what I already shared" or the account's deletion still takes Minds' notes down (409 `too_many_published`
2664
+ * when there is too much: the copy is kept). The NIP-05 address keeps the same key; every later Nostr action is a
2665
+ * signing request for the member's device. Not undoable by Minds: make sure their signer holds the key first. Never
2666
+ * retried.
2667
+ */
2668
+ deleteManagedNostrCopy(stepUp: NostrKeyStepUp): Promise<SingleResponse<ManagedNostrCopyDeleted>>;
2347
2669
  /** Current Minds-hosted ActivityPub state for this app user; never provisions. */
2348
2670
  federationIdentity(): Promise<SingleResponse<FederationIdentityView>>;
2349
2671
  /** Explicit opt-in; the platform provisions once and never rotates keys or re-enables a disabled identity on retry. */
@@ -2397,9 +2719,11 @@ export declare class ProtocolsResource {
2397
2719
  *
2398
2720
  * Failures to expect: `handle_unavailable` (409, taken or reserved; choose
2399
2721
  * another), `identity_conflict` (409, the member already has one),
2400
- * `creation_in_progress` (409), and the operator-side 503s
2401
- * `handle_dns_unavailable`, `handle_unresolvable`, `handle_unverified` and
2402
- * `hosted_server_unavailable`, which succeed unchanged once the operator is done.
2722
+ * `creation_in_progress` (409), `outbound_refused` (403, the server's one
2723
+ * outbound guard said no before the PDS was asked anything; nothing was
2724
+ * created), and the operator-side 503s `handle_dns_unavailable`,
2725
+ * `handle_unresolvable`, `handle_unverified` and `hosted_server_unavailable`,
2726
+ * which succeed unchanged once the operator is done.
2403
2727
  */
2404
2728
  createHostedIdentity(input: CreateHostedIdentityInput): Promise<SingleResponse<CreatedHostedProtocolIdentity>>;
2405
2729
  disconnectHostedIdentity(id: string): Promise<SingleResponse<{