Skip to main content

Serializer V2

Because of the limited size of QR codes that are being used to communicate between Wallet and Vault, we send as little data as possible. We use RLP and base58check to encode the data more efficiently.

note

The next major release will introduce the Serializer V3, which will use bc-ur to encode the data as QR codes.

Deserialize#

The following example shows the deserialization of a message that was encoded using Serializer V2.

import { Serializer } from "@airgap/coinlib-core";
const serializer = new Serializer();
// This is the AccountShareResponse for the following mnemonic
// abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about
// Single QR
const qrData =
"airgap-wallet://?d=66ds3Rvy92D8gFd9dpatACJrYj3goYAhEZkY6NoX4AAZfetmZ95NoLEyL5L9bUKtvonnnEFmiBhu5YPqVSsU7Nzd9WWEdJNcGzHnzHCne6CN9kzE7nkQHes78VafWwHqJmjfrnzix1xorBMmGXFq792cjof3pGMAjeUWPqW6YyNtvkRuogp2vnMtHCpXxbESojgd9wg9tCEWoxYyDZTP8gb";
// Paged QRs
// const qrData =
// "5LogPgc9Kvs7dVratQJaJcradjCUzyDF,5LogPgcKwnDGiwfMwnALTeFiRBsWTGKW,5LogPgcWZdZRo4YrWLmR7mx7eaxngQLj,5LogPgchBUuatt63m5hQqJYaRtWaGuy5,5LogPgcsoLFjzUqs65uArQYMUtiK2m23,5LogPgd4RBbu5sNFkYKx1Zje9gh7Ert4,5LogPgdF32x4B2FZxPzCuKMFRJWTnmpU,5LogPgdRetJDGWfDhY7JavQLAqw2xHXV,5LogPgdcGjeNMpQLTnsRnLNTpTpZda1z,5LogPgdntazXTbgqrYfE5tqo9fafssP1,2UPEHD4AvBBjV1JwgM3raLeciupVL3gKYcb,2UPEHD4AvBNMLMU2vjXSmYCBkadvFZzoGkq,2UPEHD4AvBYyBhd8WJ38TfKpiN5B87cZKm6,2UPEHD4AvBjb33nDcc9vnzeExdqwgVYVaUY,LFhi4KqPsLB5xobt589oqGKDbc5Rnm3bv";
const data = (() => {
try {
const url = new URL(qrData);
return [url.searchParams.get("d")];
} catch (e) {
return qrData.split(",");
}
})();
const output = await serializer.deserialize(data);
console.log(output);
https://example.com

Serialize#

The following example shows the serialization of a message with the Serializer V2.

import {
IACMessageType,
MainProtocolSymbols,
Serializer,
} from "@airgap/coinlib-core";
const serializer = new Serializer();
// This is the AccountShareResponse for the following mnemonic
// abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about
const publicKey =
"xpub6BosfCnifzxcFwrSzQiqu2DBVTshkCXacvNsWGYJVVhhawA7d4R5WSWGFNbi8Aw6ZRc1brxMyWMzG3DSSSSoekkudhUd9yLb6qx39T9nMdj";
const derivationPath = "m/44'/0'/0'";
const data = {
type: IACMessageType.AccountShareResponse,
protocol: MainProtocolSymbols.BTC,
id: "0000000000", // Random ID to match request / response
payload: {
derivationPath,
isExtendedPublicKey: true,
publicKey,
},
};
const output = await serializer.serialize([data]);
console.log(output[0]);
https://example.com

The output from the code above can be converted to a QR code and then scanned with AirGap Wallet to import the account.

Verify the data#

The serialized data and the content of the QR codes can easily be verified using third party tools.

Let's take a look at an account share message from the Vault. It was generated by using the following mnemonic and deriving a bitcoin account.

abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about

This results in the following "share account" message:

66ds3Rvy92D8gFd9dpatACJrYj3goYAhEZkY6NoX4AAZfetmZ95NoLEyL5L9bUKtvonnnEFmiBhu5YPqVSsU7Nzd9WWEdJNcGzHnzHCne6CN9kzE7nkQHes78VafWwHqJmjfrnzix1xorBMmGXFq792cjof3pGMAjeUWPqW6YyNtvkRuogp2vnMtHCpXxbESojgd9wg9tCEWoxYyDZTP8gb

This is base58check encoded RLP. So we first have to base58check decode it. We can use this online tool to do it, but you can also use any base58check library:

https://www.better-converter.com/Encoders-Decoders/Base58Check-to-Hexadecimal-Decoder

Entering the string above will give you the following hex representation.

f8973230f893f891313483627463f87e8b6d2f3434272f30272f302731b86f7870756236426f7366436e69667a7863467772537a51697175324442565473686b43586163764e735747594a56566868617741376434523557535747464e6269384177365a5263316272784d79574d7a473344535353536f656b6b756468556439794c62367178333954396e4d646a8a716674666d4858547837cee76804

When using the online tool mentioned above, the last 8 characters (checksum) have to be removed, giving us this string:

f8973230f893f891313483627463f87e8b6d2f3434272f30272f302731b86f7870756236426f7366436e69667a7863467772537a51697175324442565473686b43586163764e735747594a56566868617741376434523557535747464e6269384177365a5263316272784d79574d7a473344535353536f656b6b756468556439794c62367178333954396e4d646a8a716674666d4858547837

We can now use another online tool (or RLP library) to decode the hex string:

https://codechain-io.github.io/rlp-debugger/

The result will be a nested array of hex values. In the tool online, you have to set the value of most fields to "string" to see the correct values.

[
<Buffer 32>, // "2", Serializer Version (string)
<Buffer 30>, // "0", Serializer Message Type (string)
[
[
<Buffer 31>, // "1", Message Version (string)
<Buffer 34>, // "4", Message Type (string)
<Buffer 62 74 63>, // "btc", Protocol (string)
[
<Buffer 6d 2f 34 34 27 2f 30 27 2f 30 27>, // "m/44'/0'/0'", Derivation Path (string)
<Buffer 31>, "1", Extended PublicKey (yes/no) (string)
<Buffer 78 70 75 62 36 42 6f 73 66 43 6e 69 66 7a 78 63 46 77 72 53 7a 51 69 71 75 32 44 42 56 54 73 68 6b 43 58 61 63 76 4e 73 57 47 59 4a 56 56 68 68 61 77 ... 61 more bytes> "xpub6BosfCnifzxcFwrSzQiqu2DBVTshkCXacvNsWGYJVVhhawA7d4R5WSWGFNbi8Aw6ZRc1brxMyWMzG3DSSSSoekkudhUd9yLb6qx39T9nMdj", Extended Public Key (string)
],
<Buffer 71 66 74 66 6d 48 58 54 78 37> // "qftfmHXTx7", Random identifier of the message
]
]
]

Once fully parsed with the schema included in our serializer, the output looks like this:

[
{
type: 4,
protocol: "btc",
id: "qftfmHXTx7",
payload: {
derivationPath: "m/44'/0'/0'",
isExtendedPublicKey: true,
publicKey:
"xpub6BosfCnifzxcFwrSzQiqu2DBVTshkCXacvNsWGYJVVhhawA7d4R5WSWGFNbi8Aw6ZRc1brxMyWMzG3DSSSSoekkudhUd9yLb6qx39T9nMdj",
},
},
];

The only thing that happens in the last step is that all the values are converted to the proper type (eg. string "4" is converted to number 4, "1" is converted to true, etc.) and the value is added to the corresponding "key" in the JSON.