Link Search Menu Expand Document

Table of Contents

  1. Abstract
  2. Definitions
  3. Multiaccount creation
  4. Multiaccount restoring via pairing
  5. Multiaccount unlocking
  6. Transaction signing
  7. Account derivation
  8. Reset pin
  9. Unblock pin
  10. Status go calls
  11. Where are the keys stored?
  12. Copyright

Abstract

In this specification, we describe how Status communicates with Keycard to create, store and use multiaccount.

Definitions

Term Description
Keycard Hardwallet https://keycard.tech/docs/
   

Multiaccount creation/restoring

Creation and restoring via mnemonic

  1. status-im.hardwallet.card/get-application-info request: nil response: {"initialized?" false}
  2. status-im.hardwallet.card/init-card request: {:pin 123123} response:
    {"password" "nEJXqf6VWbqeC5oN", 
     "puk" "411810112887", 
     "pin" "123123"}
    
  3. status-im.hardwallet.card/get-application-info request: nil response:
     {"free-pairing-slots" 5, 
      "app-version" "2.2", 
      "secure-channel-pub-key" "04e70d7af7d91b8cd23adbefdfc242c096adee6c1b5ad27a4013a8f926864c1a4f816b338238dc4a04226ab42f23672585c6dca03627885530643f1656ee69b025", 
      "key-uid" "", 
      "instance-uid" "9f149d438988a7af5e1a186f650c9328", 
      "paired?" false, 
      "has-master-key?" false, 
      "initialized?" true}
    
  4. status-im.hardwallet.card/pair params: {:password "nEJXqf6VWbqeC5oN"} response: AAVefVX0kPGsxnvQV5OXRbRTLGI3k8/S27rpsq/lZrVR (pairing)

  5. status-im.hardwallet.card/generate-and-load-keys
     {:mnemonic "lift mansion moment version card type uncle sunny lock gather nerve math", 
      :pairing "AAVefVX0kPGsxnvQV5OXRbRTLGI3k8/S27rpsq/lZrVR", 
      :pin "123123"}
    

    response:

     {"whisper-address" "1f29a1a60c8a12f80c397a91c6ae0323f420e609", 
      "whisper-private-key" "123123123123123", 
      "wallet-root-public-key" "04eb9d01990a106a65a6dfaa48300f72aecfeabe502d9f4f7aeaccb146dc2f16e2dec81dcec0a1a52c1df4450f441a48c210e1a73777c0161030378df22e4ae015", 
      "encryption-public-key" "045ee42f012d72be74b31a28ce320df617e0cd5b9b343fad34fcd61e2f5dfa89ab23d880473ba4e95401a191764c7f872b7af92ea0d8c39462147df6f3f05c2a11", 
      "wallet-root-address" "132dd67ff47cc1c376879c474fd2afd0f1eee6de", 
      "whisper-public-key" "0450ad84bb95f32c64f4e5027cc11d1b363a0566a0cfc475c5653e8af9964c5c9b0661129b75e6e1bc6e96ba2443238e53e7f49f2c5f2d16fcf04aca4826765d46", 
      "address" "bf93eb43fea2ce94bf3a6463c16680b56aa4a08a", 
      "wallet-address" "7eee1060d8e4722d36c99f30ff8291caa3cfc40c", 
      "key-uid" "472d8436ccedb64bcbd897bed5895ec3458b306352e1bcee377df87db32ef2c2", 
      "wallet-public-key" "0495ab02978ea1f8b059140e0be5a87aad9b64bb7d9706735c47dda6e182fd5ca41744ca37583b9a10c316b01d4321d6c85760c61301874089acab041037246294", 
      "public-key" "0465d452d12171711f32bb931f9ea26fe1b88fe2511a7909a042b914fde10a99719136365d506e2d1694fc14627f9d557da33865efc6001da3942fc1d4d2469ca1", 
      "instance-uid" "9f149d438988a7af5e1a186f650c9328"}
    

Multiaccount restoring via pairing

This flow is required in case if a user want to pair a card with an existing multiaccount on it.

  1. status-im.hardwallet.card/get-application-info request: nil response:
     {"free-pairing-slots" 4, 
      "app-version" "2.2", 
      "secure-channel-pub-key" "04e70d7af7d91b8cd23adbefdfc242c096adee6c1b5ad27a4013a8f926864c1a4f816b338238dc4a04226ab42f23672585c6dca03627885530643f1656ee69b025", 
      "key-uid" "", 
      "instance-uid" "9f149d438988a7af5e1a186f650c9328", 
      "paired?" false, 
      "has-master-key?" false, 
      "initialized?" true}
    
  2. status-im.hardwallet.card/pair params: {:password "nEJXqf6VWbqeC5oN"} response: AAVefVX0kPGsxnvQV5OXRbRTLGI3k8/S27rpsq/lZrVR (pairing)

  3. status-im.hardwallet.card/generate-and-load-keys
     {:mnemonic "lift mansion moment version card type uncle sunny lock gather nerve math", 
      :pairing "AAVefVX0kPGsxnvQV5OXRbRTLGI3k8/S27rpsq/lZrVR", 
      :pin "123123"}
    

    response:

     {"whisper-address" "1f29a1a60c8a12f80c397a91c6ae0323f420e609", 
      "whisper-private-key" "123123123123123123123", 
      "wallet-root-public-key" "04eb9d01990a106a65a6dfaa48300f72aecfeabe502d9f4f7aeaccb146dc2f16e2dec81dcec0a1a52c1df4450f441a48c210e1a73777c0161030378df22e4ae015", 
      "encryption-public-key" "045ee42f012d72be74b31a28ce320df617e0cd5b9b343fad34fcd61e2f5dfa89ab23d880473ba4e95401a191764c7f872b7af92ea0d8c39462147df6f3f05c2a11", 
      "wallet-root-address" "132dd67ff47cc1c376879c474fd2afd0f1eee6de", 
      "whisper-public-key" "0450ad84bb95f32c64f4e5027cc11d1b363a0566a0cfc475c5653e8af9964c5c9b0661129b75e6e1bc6e96ba2443238e53e7f49f2c5f2d16fcf04aca4826765d46", 
      "address" "bf93eb43fea2ce94bf3a6463c16680b56aa4a08a", 
      "wallet-address" "7eee1060d8e4722d36c99f30ff8291caa3cfc40c", 
      "key-uid" "472d8436ccedb64bcbd897bed5895ec3458b306352e1bcee377df87db32ef2c2", 
      "wallet-public-key" "0495ab02978ea1f8b059140e0be5a87aad9b64bb7d9706735c47dda6e182fd5ca41744ca37583b9a10c316b01d4321d6c85760c61301874089acab041037246294", 
      "public-key" "0465d452d12171711f32bb931f9ea26fe1b88fe2511a7909a042b914fde10a99719136365d506e2d1694fc14627f9d557da33865efc6001da3942fc1d4d2469ca1", 
      "instance-uid" "9f149d438988a7af5e1a186f650c9328"}
    

Multiaccount unlocking

  1. status-im.hardwallet.card/get-application-info params:
     {:pairing nil, :on-success nil}
    

    response:

     {"free-pairing-slots" 4, 
      "app-version" "2.2", 
      "secure-channel-pub-key" "04b079ac513d5e0ebbe9becbae1618503419f5cb59edddc7d7bb09ce0db069a8e6dec1fb40c6b8e5454f7e1fcd0bb4a0b9750256afb4e4390e169109f3ea3ba91d", 
      "key-uid" "a5424fb033f5cc66dce9cbbe464426b6feff70ca40aa952c56247aaeaf4764a9", 
      "instance-uid" "2268254e3ed7898839abe0b40e1b4200", 
      "paired?" false, 
      "has-master-key?" true, 
      "initialized?" true}
    
  2. status-im.hardwallet.card/get-keys params:
     {:pairing "ACEWbvUlordYWOE6M1Narn/AXICRltjyuKIAn4kkPXQG",
      :pin "123123"}
    

    response:

     {"whisper-address" "ec83f7354ca112203d2ce3e0b77b47e6e33258aa", 
      "whisper-private-key" "123123123123123123123123",
      "wallet-root-public-key" "0424a93fe62a271ad230eb2957bf221b4644670589f5c0d69bd11f3371034674bf7875495816095006c2c0d5f834d628b87691a8bbe3bcc2225269020febd65a19", 
      "encryption-public-key" "0437eef85e669f800570f444e64baa2d0580e61cf60c0e9236b4108455ec1943f385043f759fcb5bd8348e32d6d6550a844cf24e57f68e9397a0f7c824a8caee2d", 
      "wallet-root-address" "6ff915f9f31f365511b1b8c1e40ce7f266caa5ce", 
      "whisper-public-key" "04b195df4336c596cca1b89555dc55dd6bb4c5c4491f352f6fdfae140a2349213423042023410f73a862aa188f6faa05c80b0344a1e39c253756cb30d8753f9f8324", 
      "address" "73509a1bb5f3b74d0dba143705cd9b4b55b8bba1", 
      "wallet-address" "2f0cc0e0859e7a05f319d902624649c7e0f48955", 
      "key-uid" "a5424fb033f5cc66dce9cbbe464426b6feff70ca40aa952c56247aaeaf4764a9", 
      "wallet-public-key" "04d6fab73772933215872c239787b2281f3b10907d099d04b88c861e713bd2b95883e0b1710a266830da29e76bbf6b87ed034ab139e36cc235a1b2a5b5ddfd4e91", 
      "public-key" "0437eef85e669f800570f444e64baa2d0580e61cf60c0e9236b4108455ec1943f385043f759fcb5bd8348e32d6d6550a844cf24e57f68e9397a0f7c824a8caee2d", 
      "instance-uid" "2268254e3ed7898839abe0b40e1b4200"}
    
  3. status-im.hardwallet.card/get-application-info params:
     {:pairing "ACEWbvUlordYWOE6M1Narn/AXICRltjyuKIAn4kkPXQG"}
    

    response:

     {"paired?" true, 
      "has-master-key?" true, 
      "app-version" "2.2", 
      "free-pairing-slots" 4, 
      "pin-retry-counter" 3, 
      "puk-retry-counter" 5, 
      "initialized?" true, 
      "secure-channel-pub-key" "04b079ac513d5e0ebbe9becbae1618503419f5cb59edddc7d7bb09ce0db069a8e6dec1fb40c6b8e5454f7e1fcd0bb4a0b9750256afb4e4390e169109f3ea3ba91d", 
      "key-uid" "a5424fb033f5cc66dce9cbbe464426b6feff70ca40aa952c56247aaeaf4764a9", 
      "instance-uid" "2268254e3ed7898839abe0b40e1b4200"}
    

Transaction signing

  1. status-im.hardwallet.card/get-application-info params:
    {:pairing "ALecvegKyOW4szknl01yYWx60GLDK5gDhxMgJECRZ+7h", 
     :on-success :hardwallet/sign}
    

    response:

     {"paired?" true, 
      "has-master-key?" true, 
      "app-version" "2.2", 
      "free-pairing-slots" 4, 
      "pin-retry-counter" 3, 
      "puk-retry-counter" 5, 
      "initialized?" true, 
      "secure-channel-pub-key" "0476d11f2ccdad4e7779b95a1ce063d7280cb6c09afe2c0e48ca0c64ab9cf2b3c901d12029d6c266bfbe227c73a802561302b2330ac07a3270fc638ad258fced4a", 
      "key-uid" "d5c8cde8085e7a3fcf95aafbcbd7b3cfe32f61b85c2a8f662f60e76bdc100718", 
      "instance-uid" "e20e27bfee115b431e6e81b8e9dcf04c"}
    
  2. status-im.hardwallet.card/sign params:
    {:hash "92fc7ef54c3e0c42de256b93fbf2c49dc6948ee089406e204dec943b7a0142a9", 
     :pairing "ALecvegKyOW4szknl01yYWx60GLDK5gDhxMgJECRZ+7h", 
     :pin "123123", 
     :path "m/44'/60'/0'/0/0"}
    

    response: 5d2ca075593cf50aa34007a0a1df7df14a369534450fce4a2ae8d023a9d9c0e216b5e5e3f64f81bee91613318d01601573fdb15c11887a3b8371e3291e894de600

Account derivation

  1. status-im.hardwallet.card/verify-pin params:
     {:pin "123123", 
      :pairing "ALecvegKyOW4szknl01yYWx60GLDK5gDhxMgJECRZ+7h"}
    

    response: 3

  2. status-im.hardwallet.card/export-key params:
     {:pin "123123", 
      :pairing "ALecvegKyOW4szknl01yYWx60GLDK5gDhxMgJECRZ+7h", 
      :path "m/44'/60'/0'/0/1"}
    

    response: 046d1bcd2310a5e0094bc515b0ec995a8cb59e23d564094443af10011b6c00bdde44d160cdd32b4b6341ddd7dc83a4f31fdf60ec2276455649ccd7a22fa4ea01d8 (account’s public-key)

Reset pin

  1. status-im.hardwallet.card/change-pin params:
    {:new-pin "111111", 
     :current-pin "222222", 
     :pairing "AA0sKxPkN+jMHXZZeI8Rgz04AaY5Fg0CzVbm9189Khob"}
    

    response: true

Unblock pin

If user enters a wrong pin three times in a row a card gets blocked. The user can use puk code then to unblock the card and set a new pin.

  1. status-im.hardwallet.card/unblock-pin params:
    {:puk "120702722103", 
     :new-pin "111111", 
     :pairing "AIoQl0OtCL0/uSN7Ct1/FHRMEk/eM2Lrhn0bw7f8sgOe"}
    

    response true

Status go calls

In order to use the card in the app we need to use some parts of status-go API, specifically:

  1. SaveAccountAndLoginWithKeycard after multiaccount creation/restoring to store multiaccount and login into it
  2. LoginWithKeycard to log into already existing account
  3. HashTransaction and HashMessage for hashing transaction/message before signing
  4. SendTransactionWithSignature to send transaction

Where are the keys stored?

  1. When we create a regular multiaccount all its keys are stored on device and are encrypted via key which is derived from user’s password. In case if account was created using keycard all keys are stored on the card and are retrieved from it during signing into multiaccount.
  2. When we create a regular multiaccount we also create a separate database for it and this database is encrypted using key which is derived from user’s password. For a keycard account we use encryption-public-key (returned by status-im.hardwallet.card/get-keys/status-im.hardwallet.card/generate-and-load-keys) as a password.

Copyright and related rights waived via CC0.