Skip to content

Commit 0d3930d

Browse files
authored
Merge pull request #209 from BitGo/WCN-399
chore: add docs on Key Provider API Spec
2 parents f46a4c6 + 2f36f2c commit 0d3930d

2 files changed

Lines changed: 232 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ curl -X POST http://localhost:3081/ping/advancedWalletManager
180180
| ------------------------------ | ---------------------------------- | ------- | -------- |
181181
| `ADVANCED_WALLET_MANAGER_PORT` | Port to listen on | `3080` ||
182182
| `KEY_PROVIDER_URL` | URL to your key provider API implementation | - ||
183+
| `SIGNING_MODE` | Delegates key generation and signing to key provider (`local` or `external`) | `local` ||
183184

184185
> **Note:** The `KEY_PROVIDER_URL` points to your implementation of the key provider API interface. You must implement this interface to connect your KMS/HSM. See [Prerequisites](#prerequisites) for the specification and examples.
185186

key-provider-api-spec.yaml

Lines changed: 231 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ info:
1717
## Implementation Requirements
1818
1919
Your implementation must:
20-
- Expose all four endpoints defined in this specification
20+
- Expose all endpoints defined in this specification
2121
- Support the request/response schemas defined in this specification
2222
- Integrate with your chosen KMS/HSM provider backend
2323
- Handle encryption/decryption operations securely
@@ -141,6 +141,146 @@ paths:
141141
'500':
142142
$ref: '#/components/responses/InternalServerError'
143143

144+
/sign:
145+
post:
146+
tags:
147+
- Key Management
148+
summary: Sign a transaction or message
149+
description: |
150+
Sign data using a private key stored in your KMS/HSM provider. This is only applicable to Multisig wallets.
151+
152+
**Request:**
153+
- `pub`: Public key identifier
154+
- `source`: Key source (`user` or `backup`)
155+
- `signablePayload`: Data to sign (format varies by coin)
156+
- `algorithm`: `ecdsa` or `eddsa`
157+
158+
**Response:**
159+
- `signature`: Signed output (format varies by coin)
160+
operationId: signTransaction
161+
requestBody:
162+
required: true
163+
content:
164+
application/json:
165+
schema:
166+
$ref: '#/components/schemas/SignRequest'
167+
examples:
168+
btcPsbt:
169+
summary: Sign BTC PSBT (UTXO)
170+
value:
171+
pub: 'xpub1234567890abcdefABCDEF...'
172+
source: 'user'
173+
signablePayload: '70736274ff...'
174+
algorithm: 'ecdsa'
175+
ethOperationHash:
176+
summary: Sign ETH operation hash (account-based)
177+
value:
178+
pub: 'xpub9876543210zyxwvuZYXWVU...'
179+
source: 'user'
180+
signablePayload: '0x8a3f7c9e...'
181+
algorithm: 'ecdsa'
182+
responses:
183+
'200':
184+
description: Transaction or message signed successfully
185+
content:
186+
application/json:
187+
schema:
188+
$ref: '#/components/schemas/SignResponse'
189+
examples:
190+
btcSigned:
191+
summary: Signed BTC transaction
192+
value:
193+
signature: '020000...'
194+
ethSigned:
195+
summary: Signed ETH operation (r, s, v format)
196+
value:
197+
signature: '0x1a10d7ee...'
198+
'400':
199+
$ref: '#/components/responses/BadRequest'
200+
'404':
201+
description: Private key not found for the given pub and source
202+
content:
203+
application/json:
204+
schema:
205+
$ref: '#/components/schemas/ErrorResponse'
206+
example:
207+
message: 'Entry with pub xpub1234567890abcdefABCDEF... and source user not found in database'
208+
'500':
209+
$ref: '#/components/responses/InternalServerError'
210+
211+
/key/generate:
212+
post:
213+
tags:
214+
- Key Management
215+
summary: Generate a key pair
216+
description: |
217+
Generate a new key pair in your KMS/HSM provider for multisig wallets.
218+
219+
**Request:**
220+
- `coin`: Coin identifier (e.g., "tbtc", "hteth")
221+
- `source`: Key source (`user` or `backup`)
222+
- `type`: Key type (`independent` or `tss`)
223+
224+
**Response:**
225+
- `pub`: Public key (format varies by coin)
226+
- `coin`: Coin identifier
227+
- `source`: Key source
228+
- `type`: Key type
229+
operationId: generateKey
230+
requestBody:
231+
required: true
232+
content:
233+
application/json:
234+
schema:
235+
$ref: '#/components/schemas/GenerateKeyRequest'
236+
examples:
237+
btcUserKey:
238+
summary: Generate BTC user key
239+
value:
240+
coin: 'tbtc'
241+
source: 'user'
242+
type: 'independent'
243+
ethBackupKey:
244+
summary: Generate ETH backup key
245+
value:
246+
coin: 'hteth'
247+
source: 'backup'
248+
type: 'independent'
249+
responses:
250+
'200':
251+
description: Key pair generated successfully
252+
content:
253+
application/json:
254+
schema:
255+
$ref: '#/components/schemas/GenerateKeyResponse'
256+
examples:
257+
btcKey:
258+
summary: BTC key generated
259+
value:
260+
pub: 'xpub1234567890abcdefABCDEF...'
261+
coin: 'tbtc'
262+
source: 'user'
263+
type: 'independent'
264+
ethKey:
265+
summary: ETH key generated
266+
value:
267+
pub: 'xpub9876543210zyxwvuZYXWVU...'
268+
coin: 'hteth'
269+
source: 'backup'
270+
type: 'independent'
271+
'400':
272+
$ref: '#/components/responses/BadRequest'
273+
'409':
274+
description: Duplicate key - entry with same pub, source, and coin already exists
275+
content:
276+
application/json:
277+
schema:
278+
$ref: '#/components/schemas/ErrorResponse'
279+
example:
280+
message: 'Key with pub xpub1234567890abcdefABCDEF... and source user already exists for coin tbtc'
281+
'500':
282+
$ref: '#/components/responses/InternalServerError'
283+
144284
/generateDataKey:
145285
post:
146286
tags:
@@ -348,6 +488,96 @@ components:
348488
type:
349489
$ref: '#/components/schemas/KeyType'
350490

491+
SigningAlgorithm:
492+
type: string
493+
enum:
494+
- ecdsa
495+
- eddsa
496+
description: |
497+
The signing algorithm to use:
498+
- `ecdsa`: Elliptic Curve Digital Signature Algorithm
499+
- `eddsa`: Edwards-curve Digital Signature Algorithm
500+
501+
SignRequest:
502+
type: object
503+
required:
504+
- pub
505+
- source
506+
- signablePayload
507+
- algorithm
508+
properties:
509+
pub:
510+
type: string
511+
description: The public key identifying which private key to use for signing
512+
minLength: 1
513+
example: 'xpub9876543210zyxwvuZYXWVU...'
514+
source:
515+
$ref: '#/components/schemas/KeySource'
516+
signablePayload:
517+
type: string
518+
description: |
519+
The data to be signed. Format depends on coin type:
520+
- **UTXO coins** (BTC, LTC): Unsigned PSBT hex (e.g., '70736274ff01007d02000000...')
521+
- **Account-based coins** (ETH, Polygon): Operation hash with 0x prefix (e.g., '0x8a3f7c9e2b4d1a6f...')
522+
minLength: 1
523+
algorithm:
524+
$ref: '#/components/schemas/SigningAlgorithm'
525+
526+
SignResponse:
527+
type: object
528+
required:
529+
- signature
530+
properties:
531+
signature:
532+
type: string
533+
description: |
534+
The signature. Format depends on coin type:
535+
- **UTXO coins**: Signed PSBT hex or final transaction hex
536+
- **Account-based coins**: Ethereum-format signature `0x{r}{s}{v}` (65 bytes, 130 hex chars + prefix)
537+
- **EdDSA coins**: EdDSA signature in hex format
538+
example: '0x1a10d7eecc7f7ad9c627218639d56a36ebd723767c974bff1cd70aa1a4c288a15cdb8cdb9ae01243b2b6353bf3a2a1aa412d7d0a1435dfbecd3156acd22d229a1b'
539+
540+
GenerateKeyRequest:
541+
type: object
542+
required:
543+
- coin
544+
- source
545+
- type
546+
properties:
547+
coin:
548+
type: string
549+
description: The coin/blockchain type (e.g., "tbtc", "hteth")
550+
minLength: 1
551+
example: 'hteth'
552+
source:
553+
$ref: '#/components/schemas/KeySource'
554+
type:
555+
$ref: '#/components/schemas/KeyType'
556+
557+
GenerateKeyResponse:
558+
type: object
559+
required:
560+
- pub
561+
- coin
562+
- source
563+
- type
564+
properties:
565+
pub:
566+
type: string
567+
description: |
568+
The generated public key. Format depends on coin type:
569+
- **UTXO/Account-based coins**: Extended public key in BIP32 format (xpub...)
570+
- **EdDSA coins**: Base58-encoded public key or extended public key format
571+
example: 'xpub9876543210zyxwvuZYXWVU...'
572+
coin:
573+
type: string
574+
description: The coin type
575+
example: 'hteth'
576+
source:
577+
$ref: '#/components/schemas/KeySource'
578+
type:
579+
$ref: '#/components/schemas/KeyType'
580+
351581
GenerateDataKeyRequest:
352582
type: object
353583
required:

0 commit comments

Comments
 (0)