How to stamp requests

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:

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:

  1. Generate and store a P256 Public Private Key Pair (TEK) on device for future API requests
    1. The public key will be used as the targetPublicKey in Wallet API requests like Create Wallet.
  2. Generate a private key bundle
    1. Exchange the targetPublicKey for an encrypted bundle by calling create wallet (e.g., OAuth, email login)
  3. Decrypt the bundle using Hybrid Public Key Encryption (HPKE).
    1. Take the received bundle and decode it using Base58Check. The decoded bundle consists of:
      1. The first 33 bytes: an ephemeral public key.
        1. Convert into NIST P256 uncompressed format to be used in HPKE as ephemeralUncompressedPublicKeyBytes.
      2. The remaining bytes: the ciphertext to decrypt.
    2. Pass the above in to HPKE decrypt using the TEK private key
      1. KemId: DHKEM_P256_HKDF_SHA256
      2. KdfId: HKDF_SHA256
      3. AeadId: AES_256_GCM
      4. info: turnkey_hpke
      5. aad: ephemeralUncompressedPublicKeyBytes + tekPublicKeyBytes
  4. Sign the JSON-encoded POST body with your private key (generated in step 3) to produce a signature (DER-encoded)
    1. And hex encode the signature
  5. Create a JSON-encoded stamp:
    • publicKey: the public key of TEK Key Pair
    • signature: the signature produced in step 2
    • schemeSIGNATURE_SCHEME_TK_API_P256
  6. Base64URL encode the stamp
  7. 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.
      }
    }
    
  8. 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:

If you have more questions, please reach out.

ReadMe