Overview for how to send stamped (or verified) requests required for using Wallet APIs directly.
What is stamping?
Stamping, or verifying requests, is used to verify the integrity and authenticity of the requests in order to manage and use wallets in a secure and non-custodial manner.
Every request made to create, authenticate, and sign Wallet APIs must include a signature over the POST body attached as a HTTP header. You’ll need to stamp with either a targetPublicKey
in the body and/or an X-Stamp
attached to the HTTP POST request headers. A secure enclave will use these parameters to verify and encrypt the authenticity of your requests, ensuring that there are no man in the middle attacks.
SDKs
We provide SDKs to abstract this stamping logic and simplify your integration:
- React
- React Native
- Vanilla JS
- Java (Coming soon)
How to stamp in another language
If we do not have an out of the box SDK in the language you need, you can build your own custom stamping logic to use our Wallet APIs.
For any endpoint the requires a stampedRequest
body for the verification logic you’ll need to:
- Generate and store a P256 Public Private Key Pair (TEK) on device for future API requests
- The public key will be used as the
targetPublicKey
in Wallet API requests like Create Wallet.
- The public key will be used as the
- Generate a private key bundle
- Exchange the
targetPublicKey
for an encryptedbundle
by calling create wallet (e.g., OAuth, email login)
- Exchange the
- Decrypt the bundle using Hybrid Public Key Encryption (HPKE).
- Take the received bundle and decode it using Base58Check. The decoded bundle consists of:
- The first 33 bytes: an ephemeral public key.
- Convert into NIST P256 uncompressed format to be used in HPKE as
ephemeralUncompressedPublicKeyBytes
.
- Convert into NIST P256 uncompressed format to be used in HPKE as
- The remaining bytes: the ciphertext to decrypt.
- The first 33 bytes: an ephemeral public key.
- Pass the above in to HPKE decrypt using the TEK private key
- KemId:
DHKEM_P256_HKDF_SHA256
- KdfId:
HKDF_SHA256
- AeadId:
AES_256_GCM
- info:
turnkey_hpke
- aad:
ephemeralUncompressedPublicKeyBytes + tekPublicKeyBytes
- KemId:
- Take the received bundle and decode it using Base58Check. The decoded bundle consists of:
- Sign the JSON-encoded POST body with your private key (generated in step 3) to produce a
signature
(DER-encoded)- And hex encode the
signature
- And hex encode the
- Create a JSON-encoded stamp:
publicKey
: the public key of TEK Key Pairsignature
: the signature produced in step 2scheme
:SIGNATURE_SCHEME_TK_API_P256
Base64URL
encode the stamp- Attach the encoded string to your request as a
stampedRequest
body as such:{ "stampedRequest": { "body": "{\"organizationId\": ...}, // the JSON stringified body of the request "stamp": { "stampHeaderName": "X-Stamp", // this is hardcoded "stampHeaderValue": "eyJ..." // generated from step 5 }, "url": "https://example.com" // this doesn't matter you can hard code this. } }
- Submit the stamped request to our APIs
If you're building in React, Vanilla JS, or (soon) Java, use our SDK to which will handle this stamping logic for you. If you're building in another language not supported by our SDKs see the following implementations:
- (Coming soon) Java SDK
- JS SDK stamper
- Specify the body parameters for a request
- Given a TEK generate the payloads and generate the signatures for the request.
- JS SDK React Native stamper
- More examples of stamping via our partner Turnkey
If you have more questions, please reach out.