/**
 * `transfers` namespace — the unified project-transfer noun (v1.93+;
 * owned-org recipient shape v1.96+).
 *
 * Exposed as `r.admin.transfers.*`. Project transfer is ONE capability,
 * body-discriminated by recipient kind: a wallet recipient (`toWallet`, SIWX
 * bilateral signing), an email recipient (`toEmail`, the recipient accepts into
 * an org), or an owned org recipient (`toOrgId`, same-actor org move). All ride
 * the same `/transfers` surface — there is no separate `/handoffs` noun (the
 * gateway removed it in `unify-project-transfer-surface`).
 *
 * Gateway endpoints:
 *   POST /projects/v1/:project_id/transfers      — initiate; body { to_wallet } XOR { to_email } XOR { to_org_id }
 *   GET  /agent/v1/transfers/incoming            — inbox (pending kinds, unioned)
 *   GET  /agent/v1/transfers/outgoing            — outbox (pending kinds, unioned)
 *   GET  /agent/v1/transfers/:transfer_id        — preview (kind-agnostic)
 *   POST /agent/v1/transfers/:transfer_id/accept — the ONE completion; the row's recipient kind
 *                                                  picks the credential (wallet: to_wallet's SIWX;
 *                                                  email: a principal whose verified email matches,
 *                                                  body { org_id?, accept_retained_member? })
 *   POST /agent/v1/transfers/:transfer_id/cancel — cancel (kind-agnostic)
 *   POST /agent/v1/transfers/:transfer_id/vault-handover — the recipient names the principal that receives the project's vault
 *
 * Owner-side mutations against a project with a pending transfer return
 * 409 `PROJECT_HAS_PENDING_TRANSFER`. The SDK kernel surfaces that as
 * {@link TransferFreezeError} so agents can guide the user to cancel. Accepting
 * with the wrong credential for a row's kind (e.g. a wallet signature on an
 * email-addressed row) returns 409 `WRONG_COMPLETION_FOR_TRANSFER_KIND`; the
 * thrown error exposes an `accept_transfer` next action naming the credential
 * the row needs, on the SAME `transfer_id`.
 */
import type { OperationActorSnapshot, PrincipalRepresentation } from "./identity-links.types.js";
import type { Client } from "../kernel.js";
/** Phase 1A only supports the `migrate` policy — B's wallet must already be on a organization, and the project moves into it. */
export type TransferBillingPolicy = "migrate";
export type TransferStatus = "pending" | "accepted" | "cancelled" | "expired";
export type TransferCancelledBy = "from_wallet" | "to_wallet" | "system";
/** Which kind of recipient a transfer row is addressed to. */
export type RecipientKind = "wallet" | "email" | "org";
/** Options for {@link Transfers.cancel} — the canonical `cancel(transferId, { reason })` shape. */
export interface CancelTransferOptions {
    /** Optional free-text cancellation reason recorded on the transfer row. */
    reason?: string;
}
/** Initiate a transfer addressed to a wallet (two-party SIWX completion via `accept`). */
export interface InitiateWalletTransferInput {
    /** Project id to transfer. Caller must currently own/admin it (gateway re-checks against fresh DB, not cache). */
    projectId: string;
    /** Recipient wallet (any case — gateway lowercases). Must differ from the current owner. */
    toWallet: string;
    /** Mutually exclusive with {@link InitiateWalletTransferInput.toWallet}; not allowed on the wallet path. */
    toEmail?: never;
    /** Mutually exclusive with {@link InitiateWalletTransferInput.toWallet}; not allowed on the wallet path. */
    toOrgId?: never;
    /**
     * Billing policy. Defaults to `"migrate"`. Phase 1A only supports
     * `"migrate"`; future phases may add `"inherit"` as a separate spec.
     */
    billingPolicy?: TransferBillingPolicy;
    /** Optional free-text note shown to the recipient in the preview + emails (HTML-escaped server-side). */
    message?: string;
    /** Optional KySigned record id (Phase 1A: informational only, stored verbatim, not verified). */
    kysignedRecordId?: string;
    /** Retention is an email-only opt-in; not allowed on the wallet path. */
    retainMember?: never;
}
/** Initiate a transfer addressed to an email (the recipient accepts into an org via `accept`). */
export interface InitiateEmailTransferInput {
    /** Project id to transfer. Caller must currently own/admin it. */
    projectId: string;
    /** Recipient email; accepted by a principal whose verified email matches. */
    toEmail: string;
    /** Mutually exclusive with {@link InitiateEmailTransferInput.toEmail}; not allowed on the email path. */
    toWallet?: never;
    /** Mutually exclusive with {@link InitiateEmailTransferInput.toEmail}; not allowed on the email path. */
    toOrgId?: never;
    /** Optional note shown to the recipient (HTML-escaped server-side). */
    message?: string;
    /**
     * Opt in (v1.91) to retaining a `developer` membership in the recipient's org
     * after the transfer completes. Only `role: "developer"` is accepted, and the
     * subject is always the initiating owner (you can only retain yourself). The
     * recipient must explicitly accept it at accept time (see
     * {@link AcceptTransferOptions.acceptRetainedMember}); omitting this is a
     * full severance, the default.
     */
    retainMember?: {
        role: "developer";
    } | null;
    /** Billing policy is wallet-path only; not allowed on the email path. */
    billingPolicy?: never;
    /** KySigned record id is wallet-path only; not allowed on the email path. */
    kysignedRecordId?: never;
}
/** Initiate an immediate move to an organization the caller already owns. */
export interface InitiateOrgTransferInput {
    /** Project id to transfer. Caller must be an active owner of the source org. */
    projectId: string;
    /**
     * Destination organization id. The first gateway release is same-actor only:
     * caller must be an active owner of both source and destination orgs.
     */
    toOrgId: string;
    /** Mutually exclusive with {@link InitiateOrgTransferInput.toOrgId}; not allowed on the org path. */
    toWallet?: never;
    /** Mutually exclusive with {@link InitiateOrgTransferInput.toOrgId}; not allowed on the org path. */
    toEmail?: never;
    /** Optional free-text note recorded with the transfer audit row. */
    message?: string;
    /** Billing policy is wallet-path only; not allowed on the org path. */
    billingPolicy?: never;
    /** KySigned record id is wallet-path only; not allowed on the org path. */
    kysignedRecordId?: never;
    /** Retention is an email-only opt-in; not allowed on the org path. */
    retainMember?: never;
}
/** Inputs to `r.admin.transfers.initiate(...)` — wallet XOR email XOR org. */
export type InitiateTransferInput = InitiateWalletTransferInput | InitiateEmailTransferInput | InitiateOrgTransferInput;
/** Result of a wallet-addressed `initiate`. */
export interface InitiateTransferResult {
    transfer_id: string;
    expires_at: string;
    project_summary: {
        project_id: string;
        project_name: string | null;
        billing_policy: TransferBillingPolicy;
        from_wallet: string;
        to_wallet: string;
    };
    your_unused_lease_days: number;
    lease_refundable: false;
    terms_sha256: string;
}
/** Result of an email-addressed `initiate`. The recipient completes via `accept`. */
export interface InitiateEmailTransferResult {
    status: "ok";
    transfer_id: string;
    to_email: string;
    expires_at: string;
}
/**
 * Result of an owned-org `initiate`. Same-actor org moves complete
 * synchronously in the first gateway release and return project keys so the
 * caller can continue operating the project without a follow-up fetch.
 */
export interface InitiateOrgTransferResult {
    status: "accepted";
    project_id: string;
    /** The org the project left. */
    from_org_id: string;
    /** The org that now owns the project. */
    to_org_id: string;
    /** Present when the gateway materializes an audit transfer row. */
    transfer_id?: string;
    /** Present when the gateway returns the completion timestamp inline. */
    completed_at?: string;
    anon_key: string;
    service_key: string;
    secrets_rotation_advised?: true;
    secret_names_inherited?: string[];
    secrets_count_inherited?: number;
    github_repo_note?: string;
    [key: string]: unknown;
}
/**
 * The vault handover a transfer requires (project-transfer-vault-handover).
 * A transfer moves the project's KyGit vault, and the gateway never holds its
 * key: the recipient names the principal that receives the source
 * ({@link Transfers.nominateVaultRecipient}), the sender's writer admits that
 * principal's key and wraps the source key for it (`r.repos.completeTransferHandover`),
 * and only then does accept succeed. `null` when the project has no vault.
 */
export interface TransferVaultHandover {
    repo_id: string;
    state: "awaiting_recipient" | "awaiting_sender" | "complete";
    recipient_principal_id: string | null;
    /** The nominee's published keystore identity — public keys only. */
    recipient: {
        principal_id: string;
        writer_key_id: string;
        signing_pubkey: string;
        ek_fingerprint: string;
        public_key: string;
    } | null;
    /** The vault's current epoch (16 lowercase hex). */
    current_epoch: string;
    writer_admitted: boolean;
    envelope_current_epoch: boolean;
}
/** The project's vault and its footprint in the recipient's pool (preview). */
export interface TransferVaultPreview {
    repo_id: string;
    storage_profile: "managed" | "byo";
    source_bytes: number;
    source: string;
    recipient_vault_usage_after_accept: {
        source_bytes: number;
        source: string;
        source_bytes_limit: number | null;
        source_limit: string | null;
    };
    over_limit: boolean;
}
/** Present on an accept result when the project had a vault: it moved with the project. */
export interface TransferVaultMoved {
    repo_id: string;
    /** The previous owner's writers keep their key until `r.repos.retirePreviousOwnerWriters` runs. */
    previous_owner_writers_retained: true;
}
/** Result of {@link Transfers.nominateVaultRecipient}. */
export interface NominateVaultRecipientResult {
    transfer_id: string;
    vault_handover: TransferVaultHandover;
    next_actions: Array<{
        type: string;
        method?: string;
        path?: string;
        command?: string;
        why?: string;
    }>;
}
/** Result of accepting a WALLET-addressed transfer. */
export interface AcceptWalletTransferResult {
    project_id: string;
    from_wallet: string;
    to_wallet: string;
    new_org_id: string | null;
    completed_at: string;
    /** New owner's project anon key (stateless JWT). The SDK persists it on accept. */
    anon_key: string;
    /** New owner's project service key (stateless JWT). Full project access; persisted on accept. */
    service_key: string;
    secrets_rotation_advised: true;
    /** Names of secrets that carried over with the project. Values are never returned. */
    secret_names_inherited: string[];
    secrets_count_inherited: number;
    /** Verbatim reminder that GitHub repo ownership is NOT part of the transfer. */
    github_repo_note: string;
    /** Present when the project had a vault. */
    vault?: TransferVaultMoved;
    next_actions?: Array<{
        type: string;
        method?: string;
        path?: string;
        command?: string;
        why?: string;
    }>;
}
/**
 * Result of accepting an EMAIL-addressed transfer. Symmetric with the wallet
 * result: the completion returns the new owner's project keys
 * (`project-transfer-accept-credentials`), and `accept` persists them to the
 * keystore so the new owner can operate the project immediately.
 */
export interface AcceptEmailTransferResult {
    status: "accepted";
    project_id: string;
    to_org_id: string;
    created_new_org: boolean;
    /**
     * The sender's principal id retained as a `developer` of the new org, or
     * `null` when no membership was retained (declined, not offered, or no-op).
     */
    retained_member_principal_id: string | null;
    /** Present when the gateway reports the credential rotation it performed. */
    credentials_revoked?: boolean;
    credentials_issued?: boolean;
    /** New owner's project anon key (stateless `project_id`-derived JWT). `accept` persists it. */
    anon_key: string;
    /** New owner's project service key (stateless `project_id`-derived JWT). Full project access; persisted on accept. */
    service_key: string;
    /** Present when the project had a vault. */
    vault?: TransferVaultMoved;
    next_actions?: Array<{
        type: string;
        method?: string;
        path?: string;
        command?: string;
        why?: string;
    }>;
}
/** Result of {@link Transfers.accept} — the row's recipient kind decides which shape comes back. */
export type AcceptTransferResult = AcceptWalletTransferResult | AcceptEmailTransferResult;
export interface CancelTransferResult {
    transfer_id: string;
    status: "cancelled";
    cancelled_by: TransferCancelledBy;
    cancellation_reason: string | null;
    cancelled_at: string;
}
/**
 * Summary row used in `/agent/v1/transfers/incoming` and `/outgoing`. The list
 * is kind-agnostic: `recipient_kind` discriminates wallet, email, and future
 * org rows. Wallet rows carry `from_wallet`/`to_wallet`; email rows carry
 * `to_email` + `from_org_id`; future org rows carry `to_org_id`.
 */
export interface TransferSummary {
    transfer_id: string;
    project_id: string;
    project_name_snapshot: string | null;
    recipient_kind: RecipientKind;
    billing_policy: TransferBillingPolicy;
    message: string | null;
    expires_at: string;
    /** API path for the full preview document. */
    preview_path: string;
    /** Wallet rows only. */
    from_wallet?: string;
    /** Wallet rows only; `null`/absent for email rows. */
    to_wallet?: string | null;
    /** Wallet rows only. */
    initiated_at?: string;
    /** Wallet rows only. */
    kysigned_record_id?: string | null;
    /** Email rows only. */
    to_email?: string;
    /** Email rows only. */
    from_org_id?: string | null;
    /** Org rows only (future non-same-actor org transfers). */
    to_org_id?: string;
    initiated_by?: OperationActorSnapshot | null;
    source_organization?: {
        org_id: string;
    } | null;
    destination_organization?: {
        org_id: string;
    } | null;
    /** The vault handover this transfer requires; `null` when it carries no vault. */
    vault_handover?: TransferVaultHandover | null;
}
export interface ListTransfersOptions {
    /** Page size; defaults to 50 on the gateway. */
    limit?: number;
    /** Opaque keyset cursor — page forward from a prior page's `next_cursor`. */
    after?: string;
}
/** Result of {@link Transfers.listIncoming} / {@link Transfers.listOutgoing} — a keyset page. */
export interface ListTransfersResult {
    transfers: TransferSummary[];
    has_more: boolean;
    next_cursor: string | null;
}
export interface CustomDomainPreview {
    hostname: string;
    status: string | null;
}
export interface SubdomainPreview {
    name: string;
    status: string | null;
}
export interface FunctionPreview {
    name: string;
    runtime: string | null;
    timeout_ms: number | null;
    memory_mb: number | null;
    scheduled: boolean;
}
export interface MailboxSummary {
    count: number;
    slugs_truncated: string[];
}
export interface CiBindingPreview {
    id: string;
    github_repository: string | null;
    github_subject_pattern: string;
    created_at: string;
}
export interface SignerPreview {
    /** Always an empty array in Phase 1A. Reserved for future project-scoped KMS signers. */
    address: string;
    chain: string;
}
/** One priced route the recipient org must be able to receive payouts for. */
export interface PricedTransferRouteSummary {
    pattern: string;
    methods: string[] | null;
    target_function: string | null;
    amount_usd_micros: number;
    networks: string[];
    pay_to: "org_default_payout";
}
/**
 * Whether the receiving org can take the project's priced-route payouts.
 * `required` / `ambiguous` block acceptance with `RECIPIENT_PAYOUT_WALLET_REQUIRED`,
 * whose details repeat `recipient_org_id` and `next_actions`.
 */
export interface RecipientPricedRoutePayoutCheck {
    required: boolean;
    status: "not_required" | "ready" | "recipient_org_unknown" | "required" | "ambiguous";
    code: string | null;
    project_id: string;
    current_release_id: string | null;
    recipient_org_id: string | null;
    priced_routes: PricedTransferRouteSummary[];
    resolved_wallet_address: string | null;
    payout_failure_code: string | null;
    message: string | null;
    next_actions: Array<{
        type: string;
        method: string;
        path: string;
        auth: string;
        why: string;
    }>;
}
export interface BillingImplications {
    from_org_id: string | null;
    target_org_id: string | null;
    tier: string | null;
    secrets_count: number;
    functions_count: number;
    custom_domains_count: number;
}
/**
 * The sender-retained-membership offer block on an email transfer preview,
 * or `null` when the sender requested no retention. `accept_field` names the
 * accept body field the recipient sets to accept
 * (`"accept_retained_member"`).
 */
export interface RetainMemberPreview {
    principal_id: string;
    role: "developer";
    sender_label: string;
    scope: string;
    note?: string;
    accept_field: string;
    [key: string]: unknown;
}
/**
 * Kind-agnostic preview document. Wallet-identity fields are `null` on email
 * and org rows; `to_email` and `retain_member` are populated on email
 * rows, while org rows carry `to_org_id` when returned.
 */
export interface ProjectTransferPreview {
    transfer_id: string;
    project_id: string;
    project_name_snapshot: string | null;
    status: TransferStatus;
    recipient_kind: RecipientKind;
    from_wallet: string | null;
    from_wallet_display: string | null;
    to_wallet: string | null;
    to_wallet_display: string | null;
    /** Email rows only. */
    to_email?: string;
    /** Org rows only (future non-same-actor org transfers). */
    to_org_id?: string;
    billing_policy: TransferBillingPolicy;
    message: string | null;
    initiated_at: string;
    expires_at: string;
    kysigned_record_id: string | null;
    terms_sha256: string;
    custom_domains: CustomDomainPreview[];
    subdomains: SubdomainPreview[];
    functions: FunctionPreview[];
    /** Secret NAMES only — values are never returned. */
    secret_names: string[];
    mailbox_summary: MailboxSummary;
    ci_bindings_to_be_revoked: CiBindingPreview[];
    signers: SignerPreview[];
    github_repo_note: string;
    billing_implications: BillingImplications;
    /** Whether the receiving org can take priced-route payouts after the transfer. */
    priced_route_payout?: RecipientPricedRoutePayoutCheck;
    /** Sender-retained-membership offer (email rows), or `null` when none was requested. */
    retain_member?: RetainMemberPreview | null;
    initiated_by?: OperationActorSnapshot | null;
    source_organization?: {
        org_id: string;
    } | null;
    destination_organization?: {
        org_id: string;
    } | null;
    recipient_principal?: PrincipalRepresentation | null;
    /** The project's vault and its footprint in the recipient's pool; `null` when the project has no vault. */
    vault?: TransferVaultPreview | null;
    /** The vault handover this transfer requires; `null` when it carries no vault. */
    vault_handover?: TransferVaultHandover | null;
}
/** Options to {@link Transfers.accept}; both fields apply to EMAIL-addressed rows only. */
export interface AcceptTransferOptions {
    /** Org to receive the project. Omit to create a brand-new wallet-less org. */
    orgId?: string;
    /**
     * Accept the sender's retained-`developer`-membership offer (see the
     * preview's `retain_member` block). Only an explicit `true` materializes the
     * membership in the new org; omitting it (the default) is a full severance.
     */
    acceptRetainedMember?: boolean;
}
export declare class Transfers {
    private readonly client;
    constructor(client: Client);
    /**
     * Initiate a project transfer — addressed to a wallet (`toWallet`), an email
     * (`toEmail`), OR an owned org (`toOrgId`), exactly one. Caller must
     * currently own/admin `projectId` (gateway re-reads owner from DB, not cache).
     * Wallet/email recipients create a `pending` row with a 72h expiry and freeze
     * owner-side mutations until accepted/cancelled/expired. The first
     * org-recipient gateway release is same-actor only and completes immediately.
     */
    initiate(input: InitiateWalletTransferInput): Promise<InitiateTransferResult>;
    initiate(input: InitiateEmailTransferInput): Promise<InitiateEmailTransferResult>;
    initiate(input: InitiateOrgTransferInput): Promise<InitiateOrgTransferResult>;
    /**
     * Fetch the preview document for a pending or terminal transfer of either
     * kind. The caller must be a party to it (wallet signer, addressed-email
     * principal, or offering-org member); other callers receive 403. Preview
     * lists secret NAMES (not values), custom domains, functions, CI bindings
     * that will be revoked at completion, the billing implications, and — on
     * email rows — the `retain_member` offer.
     */
    preview(transferId: string): Promise<ProjectTransferPreview>;
    /**
     * Accept an incoming transfer — the ONE completion, whatever the row's
     * address. A wallet-addressed row is accepted by the `to_wallet`'s SIWX
     * signature; an email-addressed row by a principal (sign-in session or
     * SIWX) whose verified email matches, into an org it owns (`orgId`) or,
     * omitted, a newly created wallet-less org. Both paths run the same atomic
     * transaction: ownership flip, grant/CI revoke, notification enqueue, the
     * persistent `secrets_rotation_advised` advisory, and an audit row. Both
     * return the new owner's project keys, which `accept` persists to the
     * keystore so the new owner can operate the project immediately.
     */
    accept(transferId: string, opts?: AcceptTransferOptions): Promise<AcceptTransferResult>;
    /**
     * Name the caller as the principal that receives a transferred project's
     * vault (project-transfer-vault-handover). Authorized like accept for the
     * row's kind. The caller must have a published keystore identity
     * (`r.repos.publishKeystoreIdentity()`); the CLI's `run402 transfer accept`
     * does both. Idempotent for the same principal. The sender then runs
     * `r.repos.completeTransferHandover(transferId)`, and accept succeeds.
     */
    nominateVaultRecipient(transferId: string): Promise<NominateVaultRecipientResult>;
    /**
     * Cancel a pending transfer of any kind. The caller must be authorized for
     * the row's kind (a wallet signer, or an owner/admin of the offering org /
     * the addressed-email principal). Already-processed transfers return 409
     * `TRANSFER_ALREADY_PROCESSED`.
     */
    cancel(transferId: string, opts?: CancelTransferOptions): Promise<CancelTransferResult>;
    /** Pending transfers OFFERED TO the caller — wallet/email/future org rows, unioned. */
    listIncoming(opts?: ListTransfersOptions): Promise<ListTransfersResult>;
    /** Pending transfers INITIATED BY the caller — wallet/email/future org rows, unioned. */
    listOutgoing(opts?: ListTransfersOptions): Promise<ListTransfersResult>;
}
//# sourceMappingURL=transfers.d.ts.map