openapi: 3.1.0
info:
  title: Bridge Server — Minka Ledger
  version: "2"
  description: |
    Endpoints your bridge server must implement to participate in the
    two-phase commit protocol. The ledger calls these to prepare, commit,
    and abort debits and credits on external bank accounts.

servers:
  - url: https://your-bridge-server.example.com
    description: Your bridge server — playground uses simulated responses

tags:
  - name: Bridge Server
    description: |
      Endpoints your bridge server must implement to participate in the two-phase
      commit protocol — the ledger calls these to prepare and commit debits and
      credits on external bank accounts.

paths:

  /debits:
    post:
      operationId: bridgePrepareDebit
      tags: [Bridge Server]
      summary: Prepare debit
      description: |
        The hub calls this to reserve / debit funds from the source wallet.
        Respond `202 Accepted` immediately, then asynchronously submit a proof
        to `POST /intents/{handle}/proofs` with `custom.status: "prepared"` or
        `"failed"`.

        - `data.handle` is the idempotency key — receiving the same handle again
          is a retry; acknowledge with `202` without reprocessing.
        - `data.intent.data.claims` carries the full payment detail (source,
          target, amount, symbol, custom metadata).
        - Verify the hub's Ed25519 signature before processing:
          `sdk.proofs.ledger().verify(body)`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: './openapi.yaml#/components/schemas/BridgeDebitRequest'
            examples:
              prepare:
                summary: Hub requests debit reservation at Banco Rojo
                $ref: './openapi.yaml#/components/examples/BridgeDebitPrepare'
      responses:
        '202':
          description: Debit accepted for async processing

  /debits/{handle}/commit:
    post:
      operationId: bridgeCommitDebit
      tags: [Bridge Server]
      summary: Commit debit
      description: |
        The hub calls this after all bridge proofs confirm `prepared`.
        Finalise the debit (make it irrevocable). Respond `202 Accepted`,
        then submit a proof with `custom.status: "committed"`.

        **Contract:** commit must always succeed. If the banking core is
        temporarily unavailable, retry internally — never respond with failure.
        The `data.intent.meta.status` will be `prepared` and `meta.proofs`
        will contain the prepare proofs from all participating bridges.
      parameters:
        - name: handle
          in: path
          required: true
          schema:
            type: string
          description: Debit entry handle
          example: deb_01u9RGCevt4rEkRMV
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: './openapi.yaml#/components/schemas/BridgeCommitRequest'
            examples:
              commit:
                summary: Hub commits debit after all bridges prepared
                $ref: './openapi.yaml#/components/examples/BridgeDebitCommit'
      responses:
        '202':
          description: Commit accepted

  /debits/{handle}/abort:
    post:
      operationId: bridgeAbortDebit
      tags: [Bridge Server]
      summary: Abort debit
      description: |
        The hub calls this to reverse a prepared debit. Release any reserved
        funds or create a reversal transaction. Respond `202 Accepted`, then
        submit a proof with `custom.status: "aborted"`.

        **Contract:** abort must always succeed. If no funds moved during
        prepare, this is a no-op — still submit the aborted proof.
      parameters:
        - name: handle
          in: path
          required: true
          schema:
            type: string
          description: Debit entry handle
          example: deb_01u9RGCevt4rEkRMV
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: './openapi.yaml#/components/schemas/BridgeAbortRequest'
            examples:
              abort:
                summary: Hub aborts debit — transaction failed
                $ref: './openapi.yaml#/components/examples/BridgeDebitAbort'
      responses:
        '202':
          description: Abort accepted

  /credits:
    post:
      operationId: bridgePrepareCredit
      tags: [Bridge Server]
      summary: Prepare credit
      description: |
        The hub calls this to validate the target account. Verify the target
        wallet exists and can receive funds. Respond `202 Accepted`, then
        submit a proof with `custom.status: "prepared"` or `"failed"`.

        Typically validation-only — no funds move yet. The actual credit
        happens in commit. `data.handle` (prefixed `cre_`) is the idempotency key.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: './openapi.yaml#/components/schemas/BridgeCreditRequest'
            examples:
              prepare:
                summary: Hub requests credit validation at Banco Amarillo
                $ref: './openapi.yaml#/components/examples/BridgeCreditPrepare'
      responses:
        '202':
          description: Credit accepted for async processing

  /credits/{handle}/commit:
    post:
      operationId: bridgeCommitCredit
      tags: [Bridge Server]
      summary: Commit credit
      description: |
        The hub calls this to deposit funds into the target account after all
        bridges have prepared. Execute the credit transaction. Respond
        `202 Accepted`, then submit a proof with `custom.status: "committed"`.

        **Contract:** commit must always succeed. Retry the banking core
        operation internally if needed — never fail at this phase.
      parameters:
        - name: handle
          in: path
          required: true
          schema:
            type: string
          description: Credit entry handle
          example: cre_baC0LUTVW9lzYA284
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: './openapi.yaml#/components/schemas/BridgeCommitRequest'
            examples:
              commit:
                summary: Hub commits credit — deposit funds to target account
                $ref: './openapi.yaml#/components/examples/BridgeCreditCommit'
      responses:
        '202':
          description: Commit accepted

  /credits/{handle}/abort:
    post:
      operationId: bridgeAbortCredit
      tags: [Bridge Server]
      summary: Abort credit
      description: |
        The hub calls this to cancel a prepared credit before deposit.
        Reverse any holds or preliminary entries from prepare. Respond
        `202 Accepted`, then submit a proof with `custom.status: "aborted"`.

        For credits where prepare was validation-only, this is typically a
        no-op — still submit the aborted proof.
      parameters:
        - name: handle
          in: path
          required: true
          schema:
            type: string
          description: Credit entry handle
          example: cre_baC0LUTVW9lzYA284
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: './openapi.yaml#/components/schemas/BridgeAbortRequest'
            examples:
              abort:
                summary: Hub aborts credit — transaction cancelled
                $ref: './openapi.yaml#/components/examples/BridgeCreditAbort'
      responses:
        '202':
          description: Abort accepted
