Skip to main content


How do I generate an Avatar?

As in glossary, technically, Avatar is the same as Ethereum wallet: they're both secp256k1 elliptic curve asymmetric keypair.

So, generating and managing Avatar should be the same as generating / managing wallets. Search for an secp256k1 SDK in your project's programming language to generate one.



  • secret key should be 32-bytes long
  • public key has 2 shapes:
    • Uncompressed(65-bytes, started with 0x04), or
    • compressed(33-bytes, started with 0x02 or 0x03, in most case 0x02)

I got "bad signature" error in POST /v1/proof

  1. Check if created_at and uuid is the same as POST /v1/proof/payload result.
  2. Check if you're using Ethereum Personal Sign.
    • If your DApp is using wallet SDK (e.g. MetaMask), make sure you're using correct signature RPC method.
How do I implement personal sign by myself?
  • In pseudo-code, personal_sign is:
sign(keccak256("\x19Ethereum Signed Message:\n" + dataToSign.length + dataToSign)))
  • Make sure dataToSign.length is length of bytes (Buffer length in some language), not UTF-8 code point length.
    assert.Equal(4, len([]byte("🐎"))) // Not 1
  • Signature should be 65-bytes long.
<<r::binary-size(32), s::binary-size(32), v::binary-size(1)>> = signature_binary
# v should be 0x00 or 0x01 or 0x1B or 0x1C
# 0x00 is equivalent to 0x1B
# 0x01 is equivalent to 0x1C

Here's a test case.

// Psuedo-code
// Given a signature payload
payload := "Test123123!"
// And a secret key
secret_key := "0x9deba3488458c0314e5fef8920d3b117dd76415569cf270db8fd864896c02732"
// The personal sign result should be
personal_sign(secret_key, payload).ToHexString()

I got public key mismatch error in POST /v1/kv

See ProofService FAQ.

Double check dataToSign.length part.

Does KVService rely on an existed Avatar / binding on ProofService?

Not really! You can use this as a storage for every secp256k1 keypair (platform == nextid && identity == "0xPUBLIC_KEY") without even using it on ProofService.

But, if you want to save data related to a specific account, we still encourage you to put it under precise platform and identity.

A typical case is, your DApp allows user to set different NFT avatar on Twitter and Github. In this case, platform and identity should be specified (instead of being put under an ambiguous Avatar pubkey).