Changing A Wallet Policy Tutorial
What is a Policy
Each wallet has an associated policy that dictates the private/public keys which are allowed to spend from it. This key is called the Instruction Key and usually is kept in the secure enclave of the iPhone device that you onboarded with. However API users can change the Instruction Key so they sign transactions without the phone.
This tutorial is for users who:
- Wish to register their new Instruction Key (i.e. want to remove the iOS device from the signing process and manage their Instruction Key).
- Already manage their own Instruction Key and wish to rotate it.
For iPhone users changing phones then the recovery process is done via our app and the following tutorial is not relevant.
Brief outline of the process
Note: This process only needs to be done once for every wallet owned. (Although you can create a single external key for use across ALL your wallets)
- Create a new public/private key pair on the correct curve as your signing key. (All transactions in future will be signed with this key)
- For Production you MUST use a secure key storage solution (e.g. AWS KMS)
- Create a new wallet policy for your wallet that includes your new Instruction Key (Remember: ALL wallet policy delegates MUST sign (as well as Bitpanda Custody) before the new wallet policy can be used)
- Creating a new wallet policy can be done in few different ways
- Create the policy change via the SDK and use the sign call back to sign with your new external key
- OR
- Create the policy change via the GraphQL API and then call the AddSignature Mutation API endpoint to sign with your new external key
- OR
- Register your site to receive the
POLICY_CHANGE_REQUEST_CREATED
webhook (Ask Bitpanda Custody to set this up) and then ask Bitpanda Custody to create the policy change, wait for the webhook, and call the Add Signature Mutation API endpoint to sign with your new external key
- Create the policy change via the SDK and use the sign call back to sign with your new external key
- Creating a new wallet policy can be done in few different ways
- Which ever wallet policy change method is chosen, you will need to verify the response obtained from the policy change request is valid
- For testing purposes you can skip this step
- For Production we highly recommend you verify the data
- Sign the data. This confirms you have access to the private key just created and that you agree to the new wallet policy.
- If your signing solution requires the pre-image data then use the
unverifiedDigestData.signData
and use the SHA256 hashing algorithm - If your signing solution can sign hash data then use the
unverifiedDigestData.shaSignData
- If your signing solution requires the pre-image data then use the
- Submit the public key and signature by calling the Add Signature Mutation mutation
- Repeat this for all wallets that need to be updated with the new Instruction Key
Creating the public/private key
- The new keypair MUST be on on the
secp256r1
(also known asP-256
andprime256v1
) curve. Please note this is the “r” curve (sometimes called the “p” curve) which is different to the “k” curve that Bitcoin or Ethereum uses.- if you use AWS KMS you should use the following paramters:
- KeyType:
Asymmetric
- KeySpec:
ECC_NIST_P256
- Signing Algorithm:
ECDSA_SHA_256
- KeyType:
- if you use AWS KMS you should use the following paramters:
- To validate the curve you can use the SDK or the following tool to check (https://report-uri.com/home/pem_decoder) by uploading the public key PEM file. e.g.
1
2
3
4-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEI8zNvjURIX2LVEQn49icMqDaydvX
5ZLRxsL4M33gKAcZ4Nm4VlziXyyG2ddHCZ3vmp7UYtZGcr8Xa/8c4wuyYg==
-----END PUBLIC KEY-----
Gives the result:
1 | Array |
The prime256v1
confirms this is on the correct curve.
The x
value and the y
value can simply be concatenated with 04
at the front to produce the publicKey
in the format TrustVault requires.
i.e:
1 | 0423cccdbe3511217d8b544427e3d89c32a0dac9dbd7e592d1c6c2f8337de0280719e0d9b8565ce25f2c86d9d747099def9a9ed462d64672bf176bff1ce30bb262 |
Creating the new Wallet Policy and Signing it
Option 1 - Typescript (Javascript) example (used in conjunction with the SDK signed callback as a reference implementation)
The NodesJS SDK provides a reference implementation of how to use the GraphQL APIs and provides numerous helper methods such as webhook validation or DER encoding. (DER encoding is used for digest validation).
1 | // Construct the SDK |
Option 2 - GraphQL to create the Wallet Policy Change
If you don’t want to use the SDK you can use the GraphQL endpoint with any language required.
Mutation
1 | mutation($walletId: String!, $delegateSchedules: [[ScheduleInput!]!]!) { |
Variables
This creates a new delegateSchedule that includes a 1 of 1 for a single external key. Remember the key format should be that of a public key as defined in our glossary. i.e. An ECDSA public key in uncompressed hex format (first byte is always 04), exactly 130 hex characters. This will be the public Key obtained from your AWS KMS implementation.
For details on a more complex delegate schedule, or for how to find your walletId
, please reach out for help.
1 | { |
Once submitted you will have a the requestId
which you should save to use in the next mutation.
Add your signature to the wallet policy change
Mutation
1 | mutation( |
Variables
- The
requestId
is obtained from the mutation to create the policy change. - the
publicKey
is your publicKey in the format mentioned above. - the
signature
is your signature in raw format. This should be ther
ands
value concatenated.1
2
3
4
5
6
7
8
9{
"requestId": "e125d4ea-1ce5-0e69-275f-a11939c33e1a",
"publicKeySignaturePairs": [
{
"publicKey": "04fd8a5ac45dcdaa4a975e4cc1cc32d08c4f67705bd3bd61fe6d7e03f82af34c2881a287d625803d6ff4e7857904b75290e859f6c10f49f38f69fa77777672262a",
"signature": "2f660e6ae78cbfc33c21d1cd9ff9bc16f51b51163aa375ce1819aa8fdc199a2021dc85b41b86a7a5efc75b595dfa9b8d2e93553831cce86e4a727b6153dd253b"
}
]
}
Finishing up
Once you have created your new wallet policy and signed it with your external key you will need to wait for any other policy delegates to sign the request.
Once they have all signed the final step is for Bitpanda Custody to complete some checks before signing the change. Once that has been completed the new wallet policy is ready to be used for signing transactions.
NB: In our Sandbox environment Bitpanda Custody does not need to sign wallet change requests so they will be processed (if correctly signed) within a few minutes.