> ## Documentation Index
> Fetch the complete documentation index at: https://docs.portalhq.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a presignature

> Pre-computes MPC signing data for faster subsequent transaction signing.
Each presignature can only be used once. You can have up to 100 active
presignatures per client.

Presignatures currently only support the `SECP256K1` curve (EVM, Bitcoin).
ED25519 (Solana) support is coming soon.




## OpenAPI

````yaml /openapi/enclave-mpc-api.yaml post /v1/presign/{curve}
openapi: 3.1.0
info:
  title: Portal Enclave MPC API
  version: '1.0'
  description: |
    The Enclave MPC API provides endpoints for MPC wallet generation, signing,
    backup, and recovery. All endpoints require a Client API Key or Client
    Session Token as a Bearer token.

    ## Base URL
    `https://mpc-client.portalhq.io`
servers:
  - url: https://mpc-client.portalhq.io
security:
  - bearerAuth: []
tags:
  - name: MPC Operations
    description: MPC wallet generation, signing, asset transfers, backup, and recovery
paths:
  /v1/presign/{curve}:
    post:
      tags:
        - MPC Operations
      summary: Create a presignature
      description: >
        Pre-computes MPC signing data for faster subsequent transaction signing.

        Each presignature can only be used once. You can have up to 100 active

        presignatures per client.


        Presignatures currently only support the `SECP256K1` curve (EVM,
        Bitcoin).

        ED25519 (Solana) support is coming soon.
      operationId: presign
      parameters:
        - $ref: '#/components/parameters/Curve'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PresignRequest'
            examples:
              clientStored:
                summary: Client-stored presignature
                value:
                  share: eyJjbG...
              portalManaged:
                summary: Portal-managed presignature
                value:
                  share: eyJjbG...
                  managed: true
      responses:
        '200':
          description: Presignature created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PresignResponse'
              examples:
                clientStored:
                  summary: Client-stored presignature
                  value:
                    id: <UUID>
                    expiresAt: '2025-03-18T10:00:00Z'
                    data: <PRESIGNATURE_DATA>
                portalManaged:
                  summary: Portal-managed presignature
                  value:
                    id: <UUID>
                    expiresAt: '2025-03-18T10:00:00Z'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MpcErrorResponse'
              example:
                id: BAD_REQUEST
                message: Can't parse the request body
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                type: string
              example: Incorrect API key format
        '409':
          description: |
            Portal-managed presign request with this idempotency key is either
            still in progress or previously failed before activation. When the
            original attempt is still in progress, the response includes a
            `Retry-After` header; a 409 without `Retry-After` means the previous
            attempt has failed and the caller should retry with a new
            idempotency key.
          headers:
            Retry-After:
              description: >-
                Seconds to wait before retrying when the original attempt is
                still in progress.
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MpcErrorResponse'
        '422':
          description: Idempotency key reused with a different signing share pair
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MpcErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MpcErrorResponse'
components:
  parameters:
    Curve:
      name: curve
      in: path
      required: true
      description: The elliptic curve to use.
      schema:
        type: string
        enum:
          - SECP256K1
          - ED25519
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      description: |
        A caller-provided key used for safe retries. Behavior depends on the
        endpoint:

        - **`POST /v1/presign/{curve}` with `managed: true`** — retrying a
          completed request with the same key returns the same
          `{id, expiresAt}` (200). If the original attempt is still in
          progress, the retry returns 409 with a `Retry-After` header; if
          the original attempt failed before completing, it returns 409
          without `Retry-After` (caller should retry with a new key).
          Reusing a key after the wallet's signing share has changed (for
          example, after a reshare or recovery) returns 422.
        - **`POST /v1/sign`** — only honored for broadcast methods (for
          example `eth_sendTransaction`, `sol_signAndSendTransaction`).
          Supplying the header with a non-broadcast method returns 400.
          For broadcast methods, retrying a completed request returns 409
          (`IDEMPOTENT_REQUEST_ALREADY_COMPLETED`), and reuse with a
          different payload returns 422. On 409, the response body does
          not include the original signing result — the header prevents
          double-execution, it does not replay the prior response.
        - **`POST /v1/assets/send`** — retrying a completed request returns
          409 (`IDEMPOTENT_REQUEST_ALREADY_COMPLETED`), and reuse with a
          different payload returns 422. On 409, the response body does
          not include the original `transactionHash` — the header prevents
          double-submission, it does not replay the prior response.

        Client-stored presignature creation does not currently honor this
        header.
      schema:
        type: string
  schemas:
    PresignRequest:
      type: object
      description: Request body for creating a presignature.
      properties:
        share:
          type: string
          description: The JSON-serialized MPC share for the wallet.
        expirationTs:
          type: number
          description: |
            Unix timestamp for when the presignature expires. Defaults to 7 days
            from creation. Maximum 365 days.
        managed:
          type: boolean
          default: false
          description: |
            Set to `true` to create a Portal-managed presignature, where Portal
            stores the encrypted payload and returns only an `id`. Defaults to
            `false`, which creates a client-stored presignature and returns the
            opaque payload as `data`.
      required:
        - share
    PresignResponse:
      type: object
      description: Response containing the created presignature.
      properties:
        id:
          type: string
          description: Unique identifier for the presignature.
        expiresAt:
          type: string
          format: date-time
          description: RFC 3339 expiration timestamp.
        data:
          type: string
          description: |
            Base64-encoded opaque presignature payload for client-stored
            presignatures. Pass this as the `presignature` field in signing
            requests. Omitted for Portal-managed presignatures.
      required:
        - id
        - expiresAt
    MpcErrorResponse:
      type: object
      description: Standard error response from the Enclave MPC API.
      properties:
        id:
          type: string
          description: >-
            Short error identifier (e.g. `DKG_FAILED`, `BAD_REQUEST`,
            `RPC_OP_FAILED`).
        message:
          type: string
          description: Human-readable error details.
      required:
        - id
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Client API Key or Client Session Token

````