openapi: "3.1.1" info: title: Signer API version: "0.2.0" description: API that allows commit modules to request generic signatures from validators tags: - name: Signer - name: Management paths: /signer/v1/get_pubkeys: get: summary: Get a list of public keys for which signatures may be requested description: > This endpoint requires a valid JWT Bearer token. The token **must include** the following claims: - `exp` (integer): Expiration timestamp - `route` (string): The route being requested (must be `/signer/v1/get_pubkeys` for this endpoint). - `module` (string): The ID of the module making the request, which must match a module ID in the Commit-Boost configuration file. tags: - Signer security: - BearerAuth: [] responses: "200": description: "All public keys available to the module: consensus pubkeys (BLS) and proxies (BLS pubkeys and ECDSA addresses)" content: application/json: schema: type: object properties: keys: description: List of mappings between consensus pubkeys and their proxies type: array items: type: object properties: consensus: description: Consensus validator pubkey $ref: "#/components/schemas/BlsPubkey" proxy_bls: description: BLS proxy pubkeys type: array items: $ref: "#/components/schemas/BlsPubkey" proxy_ecdsa: description: ECDSA proxy addresses type: array items: $ref: "#/components/schemas/EcdsaAddress" "500": description: Internal error content: application/json: schema: type: object required: - code - message properties: code: type: number example: 500 message: type: string example: "Internal error" /signer/v1/request_signature/bls: post: summary: Request a signature for a 32-byte blob of data (typically a hash), signed by the BLS private key for the requested public key. description: > This endpoint requires a valid JWT Bearer token. The token **must include** the following claims: - `exp` (integer): Expiration timestamp - `module` (string): The ID of the module making the request, which must match a module ID in the Commit-Boost configuration file. - `route` (string): The route being requested (must be `/signer/v1/request_signature/bls` for this endpoint). - `payload_hash` (string): The Keccak-256 hash of the JSON-encoded request body, with optional `0x` prefix. This is required to prevent JWT replay attacks. tags: - Signer security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [pubkey, object_root, nonce] properties: pubkey: description: The 48-byte BLS public key, with optional `0x` prefix, of the proposer key that you want to request a signature from. $ref: "#/components/schemas/BlsPubkey" object_root: description: The 32-byte data you want to sign, with optional `0x` prefix. $ref: "#/components/schemas/B256" nonce: $ref: "#/components/schemas/Nonce" example: pubkey: "0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989" object_root: "0x3e9f4a78b5c21d64f0b8e3d9a7f5c02b4d1e67a3c8f29b5d6e4a3b1c8f72e6d9" responses: "200": description: A successful signature response. content: application/json: schema: $ref: "#/components/schemas/BlsSignatureResponse" example: pubkey: "0x883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4" object_root: "0x0123456789012345678901234567890123456789012345678901234567890123" module_signing_id: "0x6a33a23ef26a4836979edff86c493a69b26ccf0b4a16491a815a13787657431b" signature: "0xa43e623f009e615faa3987368f64d6286a4103de70e9a81d82562c50c91eae2d5d6fb9db9fe943aa8ee42fd92d8210c1149f25ed6aa72a557d74a0ed5646fdd0e8255ec58e3e2931695fe913863ba0cdf90d29f651bce0a34169a6f6ce5b3115" "400": description: | This can occur in several scenarios: - The Commit-Boost configuration file does not contain a signing ID for the module that made the request. - You requested an operation while using the Dirk signer mode instead of locally-managed signer mode, but Dirk doesn't support that operation. - Something went wrong while preparing your request; the error text will provide more information. content: application/json: schema: type: object required: - code - message properties: code: type: number example: 400 message: type: string example: "Bad request: Invalid pubkey format" "401": description: The requesting module did not provide a JWT string in the request's authorization header, or the JWT string was not configured in the signer service's configuration file as belonging to the module. content: application/json: schema: type: object required: - code - message properties: code: type: number example: 401 message: type: string example: "Unauthorized" "404": description: You either requested a route that doesn't exist, or you requested a signature from a key that does not exist. content: application/json: schema: type: object required: - code - message properties: code: type: number example: 404 message: type: string example: "Unknown pubkey" "429": description: Your module attempted and failed JWT authentication too many times recently, and is currently timed out. It cannot make any more requests until the timeout ends. content: application/json: schema: type: object required: - code - message properties: code: type: number example: 429 message: type: string example: "Too many requests" "500": description: Your request was valid, but something went wrong internally that prevented it from being fulfilled. content: application/json: schema: type: object required: - code - message properties: code: type: number example: 500 message: type: string example: "Internal error" "502": description: The signer service is running in Dirk signer mode, but Dirk could not be reached. content: application/json: schema: type: object required: - code - message properties: code: type: number example: 502 message: type: string example: "Bad gateway: Dirk signer service is unreachable" /signer/v1/request_signature/proxy-bls: post: summary: Request a signature for a 32-byte blob of data (typically a hash), signed by the BLS private key for the requested proxy public key. description: > This endpoint requires a valid JWT Bearer token. The token **must include** the following claims: - `exp` (integer): Expiration timestamp - `module` (string): The ID of the module making the request, which must match a module ID in the Commit-Boost configuration file. - `route` (string): The route being requested (must be `/signer/v1/request_signature/proxy-bls` for this endpoint). - `payload_hash` (string): The Keccak-256 hash of the JSON-encoded request body, with optional `0x` prefix. This is required to prevent JWT replay attacks. tags: - Signer security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [proxy, object_root, nonce] properties: proxy: description: The 48-byte BLS public key (for `proxy_bls` mode) or the 20-byte Ethereum address (for `proxy_ecdsa` mode), with optional `0x` prefix, of the proxy key that you want to request a signature from. $ref: "#/components/schemas/BlsPubkey" object_root: description: The 32-byte data you want to sign, with optional `0x` prefix. $ref: "#/components/schemas/B256" nonce: $ref: "#/components/schemas/Nonce" example: pubkey: "0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989" object_root: "0x3e9f4a78b5c21d64f0b8e3d9a7f5c02b4d1e67a3c8f29b5d6e4a3b1c8f72e6d9" responses: "200": description: A successful signature response. content: application/json: schema: $ref: "#/components/schemas/BlsSignatureResponse" example: pubkey: "0x883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4" object_root: "0x0123456789012345678901234567890123456789012345678901234567890123" module_signing_id: "0x6a33a23ef26a4836979edff86c493a69b26ccf0b4a16491a815a13787657431b" signature: "0xa43e623f009e615faa3987368f64d6286a4103de70e9a81d82562c50c91eae2d5d6fb9db9fe943aa8ee42fd92d8210c1149f25ed6aa72a557d74a0ed5646fdd0e8255ec58e3e2931695fe913863ba0cdf90d29f651bce0a34169a6f6ce5b3115" "400": description: | This can occur in several scenarios: - The Commit-Boost configuration file does not contain a signing ID for the module that made the request. - You requested an operation while using the Dirk signer mode instead of locally-managed signer mode, but Dirk doesn't support that operation. - Something went wrong while preparing your request; the error text will provide more information. content: application/json: schema: type: object required: - code - message properties: code: type: number example: 400 message: type: string example: "Bad request: Invalid pubkey format" "401": description: The requesting module did not provide a JWT string in the request's authorization header, or the JWT string was not configured in the signer service's configuration file as belonging to the module. content: application/json: schema: type: object required: - code - message properties: code: type: number example: 401 message: type: string example: "Unauthorized" "404": description: You either requested a route that doesn't exist, or you requested a signature from a key that does not exist. content: application/json: schema: type: object required: - code - message properties: code: type: number example: 404 message: type: string example: "Unknown pubkey" "429": description: Your module attempted and failed JWT authentication too many times recently, and is currently timed out. It cannot make any more requests until the timeout ends. content: application/json: schema: type: object required: - code - message properties: code: type: number example: 429 message: type: string example: "Too many requests" "500": description: Your request was valid, but something went wrong internally that prevented it from being fulfilled. content: application/json: schema: type: object required: - code - message properties: code: type: number example: 500 message: type: string example: "Internal error" "502": description: The signer service is running in Dirk signer mode, but Dirk could not be reached. content: application/json: schema: type: object required: - code - message properties: code: type: number example: 502 message: type: string example: "Bad gateway: Dirk signer service is unreachable" /signer/v1/request_signature/proxy-ecdsa: post: summary: Request a signature for a 32-byte blob of data (typically a hash), signed by the ECDSA private key for the requested proxy Ethereum address. description: > This endpoint requires a valid JWT Bearer token. The token **must include** the following claims: - `exp` (integer): Expiration timestamp - `module` (string): The ID of the module making the request, which must match a module ID in the Commit-Boost configuration file. - `route` (string): The route being requested (must be `/signer/v1/request_signature/proxy-ecdsa` for this endpoint). - `payload_hash` (string): The Keccak-256 hash of the JSON-encoded request body, with optional `0x` prefix. This is required to prevent JWT replay attacks. tags: - Signer security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [proxy, object_root, nonce] properties: proxy: description: The 20-byte Ethereum address, with optional `0x` prefix, of the proxy key that you want to request a signature from. $ref: "#/components/schemas/EcdsaAddress" object_root: description: The 32-byte data you want to sign, with optional `0x` prefix. $ref: "#/components/schemas/B256" nonce: $ref: "#/components/schemas/Nonce" example: proxy: "0x71f65e9f6336770e22d148bd5e89b391a1c3b0bb" object_root: "0x3e9f4a78b5c21d64f0b8e3d9a7f5c02b4d1e67a3c8f29b5d6e4a3b1c8f72e6d9" responses: "200": description: A successful signature response. content: application/json: schema: $ref: "#/components/schemas/EcdsaSignatureResponse" example: address: "0x71f65e9f6336770e22d148bd5e89b391a1c3b0bb" object_root: "0x3e9f4a78b5c21d64f0b8e3d9a7f5c02b4d1e67a3c8f29b5d6e4a3b1c8f72e6d9" module_signing_id: "0x6a33a23ef26a4836979edff86c493a69b26ccf0b4a16491a815a13787657431b" signature: "0x985b495f49d1b96db3bba3f6c5dd1810950317c10d4c2042bd316f338cdbe74359072e209b85e56ac492092d7860063dd096ca31b4e164ef27e3f8d508e656801c" "400": description: | This can occur in several scenarios: - The Commit-Boost configuration file does not contain a signing ID for the module that made the request. - You requested an operation while using the Dirk signer mode instead of locally-managed signer mode, but Dirk doesn't support that operation. - Something went wrong while preparing your request; the error text will provide more information. content: application/json: schema: type: object required: - code - message properties: code: type: number example: 400 message: type: string example: "Bad request: Invalid pubkey format" "401": description: The requesting module did not provide a JWT string in the request's authorization header, or the JWT string was not configured in the signer service's configuration file as belonging to the module. content: application/json: schema: type: object required: - code - message properties: code: type: number example: 401 message: type: string example: "Unauthorized" "404": description: You either requested a route that doesn't exist, or you requested a signature from a key that does not exist. content: application/json: schema: type: object required: - code - message properties: code: type: number example: 404 message: type: string example: "Unknown pubkey" "429": description: Your module attempted and failed JWT authentication too many times recently, and is currently timed out. It cannot make any more requests until the timeout ends. content: application/json: schema: type: object required: - code - message properties: code: type: number example: 429 message: type: string example: "Too many requests" "500": description: Your request was valid, but something went wrong internally that prevented it from being fulfilled. content: application/json: schema: type: object required: - code - message properties: code: type: number example: 500 message: type: string example: "Internal error" "502": description: The signer service is running in Dirk signer mode, but Dirk could not be reached. content: application/json: schema: type: object required: - code - message properties: code: type: number example: 502 message: type: string example: "Bad gateway: Dirk signer service is unreachable" /signer/v1/generate_proxy_key: post: summary: Request a proxy key be generated for a specific consensus pubkey description: > This endpoint requires a valid JWT Bearer token. The token **must include** the following claims: - `exp` (integer): Expiration timestamp - `module` (string): The ID of the module making the request, which must match a module ID in the Commit-Boost configuration file. - `route` (string): The route being requested (must be `/signer/v1/generate_proxy_key` for this endpoint). - `payload_hash` (string): The Keccak-256 hash of the JSON-encoded request body, with optional `0x` prefix. This is required to prevent JWT replay attacks. tags: - Signer security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [pubkey, scheme] properties: pubkey: description: a validator BLS public key for which to generate a proxy key allOf: - $ref: "#/components/schemas/BlsPubkey" scheme: description: signature scheme to generate proxy keypair for type: string enum: [bls, ecdsa] examples: Bls: value: pubkey: "0xa9e9cff900de07e295a044789fd4bdb6785eb0651ad282f9e76d12afd87e75180bdd64caf2e315b815d7322bd31ab48a" scheme: "bls" Ecdsa: value: pubkey: "0xa9e9cff900de07e295a044789fd4bdb6785eb0651ad282f9e76d12afd87e75180bdd64caf2e315b815d7322bd31ab48a" scheme: "ecdsa" responses: "200": description: Success content: application/json: schema: type: object properties: message: type: object properties: delegator: description: the validator BLS public key for which the proxy key was generated (the same one as requested) allOf: - $ref: "#/components/schemas/BlsPubkey" proxy: description: the generated proxy identifier (BLS pubkey or ECDSA address) oneOf: - $ref: "#/components/schemas/BlsPubkey" - $ref: "#/components/schemas/EcdsaAddress" signature: description: The signature of the proxy delegation allOf: - $ref: "#/components/schemas/BlsSignature" examples: Bls: value: message: delegator: "0xa9e9cff900de07e295a044789fd4bdb6785eb0651ad282f9e76d12afd87e75180bdd64caf2e315b815d7322bd31ab48a" proxy: "0xb646318d81b7cff3f8aae5040eab11927b4a99542c02970a1ab8069a83e5b76b302705d0b5e0054831ce2af72088bf30" signature: "0x88274f2d78d30ae429cc16f5c64657b491ccf26291c821cf953da34f16d60947d4f245decdce4a492e8d8f949482051b184aaa890d5dd97788387689335a1fee37cbe55c0227f81b073ce6e93b45f96169f497ed322d3d384d79ccaa7846d5ab" Ecdsa: value: message: delegator: "0xa9e9cff900de07e295a044789fd4bdb6785eb0651ad282f9e76d12afd87e75180bdd64caf2e315b815d7322bd31ab48a" proxy: "0x71f65e9f6336770e22d148bd5e89b391a1c3b0bb" signature: "0xb5b5b71d1701cc45086af3d3d86bf9d3c509442835e5b9f7734923edc9a6c538e743d70613cdef90b7e5b171fbbe6a29075b3f155e4bd66d81ff9dbc3b6d7fa677d169b2ceab727ffa079a31fe1fc0e478752e9da9566a9408e4db24ac6104db" "404": description: Unknown value (pubkey, etc.) content: application/json: schema: type: object required: - code - message properties: code: type: number example: 404 message: type: string example: "Unknown pubkey" "500": description: Internal error content: application/json: schema: type: object required: - code - message properties: code: type: number example: 500 message: type: string example: "Internal error" components: securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: JWT schemas: B256: type: string format: hex pattern: "^0x[a-fA-F0-9]{64}$" example: "0x3e9f4a78b5c21d64f0b8e3d9a7f5c02b4d1e67a3c8f29b5d6e4a3b1c8f72e6d9" BlsPubkey: type: string format: hex pattern: "^0x[a-fA-F0-9]{96}$" example: "0xa9e9cff900de07e295a044789fd4bdb6785eb0651ad282f9e76d12afd87e75180bdd64caf2e315b815d7322bd31ab48a" EcdsaAddress: type: string format: hex pattern: "^0x[a-fA-F0-9]{40}$" example: "0x71f65e9f6336770e22d148bd5e89b391a1c3b0bb" BlsSignature: type: string format: hex pattern: "^0x[a-fA-F0-9]{192}$" example: "0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989a3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989" EcdsaSignature: type: string format: hex pattern: "^0x[a-fA-F0-9]{130}$" example: "0x985b495f49d1b96db3bba3f6c5dd1810950317c10d4c2042bd316f338cdbe74359072e209b85e56ac492092d7860063dd096ca31b4e164ef27e3f8d508e656801c" BlsSignatureResponse: type: object properties: pubkey: description: The BLS public key corresponding to the private key that was used to sign the request $ref: "#/components/schemas/BlsPubkey" object_root: description: The 32-byte data that was signed, with `0x` prefix $ref: "#/components/schemas/B256" module_signing_id: description: The signing ID of the module that requested the signature, as specified in the Commit-Boost configuration $ref: "#/components/schemas/B256" nonce: $ref: "#/components/schemas/Nonce" chain_id: description: The chain ID that the signature is valid for, as specified in the Commit-Boost configuration type: integer example: 1 signature: description: The BLS signature of the Merkle root hash of the provided `object_root` field and the requesting module's Signing ID. For details on this signature, see the [signature structure documentation](https://commit-boost.github.io/commit-boost-client/developing/prop-commit-signing.md#structure-of-a-signature). $ref: "#/components/schemas/BlsSignature" EcdsaSignatureResponse: type: object properties: address: description: The ECDSA address corresponding to the private key that was used to sign the request $ref: "#/components/schemas/EcdsaAddress" object_root: description: The 32-byte data that was signed, with `0x` prefix $ref: "#/components/schemas/B256" module_signing_id: description: The signing ID of the module that requested the signature, as specified in the Commit-Boost configuration $ref: "#/components/schemas/B256" nonce: $ref: "#/components/schemas/Nonce" chain_id: description: The chain ID that the signature is valid for, as specified in the Commit-Boost configuration type: integer example: 1 signature: description: The ECDSA signature (in Ethereum RSV format) of the Merkle root hash of the provided `object_root` field and the requesting module's Signing ID. For details on this signature, see the [signature structure documentation](https://commit-boost.github.io/commit-boost-client/developing/prop-commit-signing.md#structure-of-a-signature). $ref: "#/components/schemas/EcdsaSignature" Nonce: type: integer description: | Replay-protection nonce, always mixed into the signing root via `PropCommitSigningInfo`. It must be an unsigned 64-bit integer between 0 and 2^64-2 (18446744073709551614), inclusive. Modules that track nonces for replay protection should use a monotonically increasing value per key. Modules that do not use replay protection should always send `0`. minimum: 0 maximum: 18446744073709551614 example: 1