-
Notifications
You must be signed in to change notification settings - Fork 3
Substrate Signing Request Specification
0.1
A Substrate Signing Request is a request to sign a substrate transaction. A wallet implementing this standard can create SSR URLs and process SSR URLs.
A SSR has the following properties:
- Chain ID - a substrate Chain ID (insert link) specifying the chain the transaction should be signed on
- Type - identity or sign - The default type is sign. Standard 1.0 will have an identity type request that allows a user to authenticate themselves using their substrate account key.
- Callback URL - called for identity and also to inform a backend that a transaction has been made or has failed.
- Transactions - a list of extrinsics calls with data parameters to be executed.
- "signer" account template - allows the SSR to specify the "signer" account id without knowing this account ID - the client replaces all occurrences of signer with the signing account they choose to execute the transction.
- SSR is a JSON object, encoded as URL with a ssr:// prefix
- ssr URL can be encoded as QR code for convenient parsing with a wallet
Version 0.1 implements the standard to a minimal degree, it has the following limitations
- No identity request, only transactions
- Only a single extrinsics call, not more than 1
It implements the rest of the standard.
Sample
{
"chainId": "hashed",
"callback": "https://myserver.somwhere.com/?tx_id=$tx_id"
"transactions": [
{
"module": "recovery",
"call": "createRecovery",
"sender": "signer",
"params": "[[\"5Da6BeYLC3BRvS2H3bQ6JWgMGZtqKGdaoKMPhdtYMf56VaCU\",\"5EUqh98iKNwWQjpzYQPVw3LEQiiaVMaB4Yp2ugXA5fMKFDLk\",\"5GEbpz29EkSM3vKtzuUEXtwpK8vguYm2TRRsmekQufYJDJpz\"],2,3000]"
}
]
}
Corresponding encoded URL
ssr://H4sIAAAAAAAAE0WMu26DQBRE_-XWFBYEZLsLhpDwiAwO2AQormF5hKeXBRQs_7tXSpFudObM3CEtseo-MthDiWNJMhCAUexGTFnVdyPsozu0fTY1hCuUpP1M6C-XUmwaTlJKkBHvn4-kywjlzVgVHQ8CDEix5UcQRTHIGioqCe2DpHrzSXyXrq5ingvH-GY3y8iwt5xjmbHQyWUlwIMfg8BHun8rd9vK-lzO7s-whu4xWCRbd6sKAwfVl3AQp-LyKueO9abZ9d_I0K_DKu70-uRIs8XWydcvbBms7VxMYSt-ed7Yktqd8tDUzGGNIRFEQdpsNgk8kscTHuDEbRoBAAA=
- Take a json Object - either a dictionary / map style object, or an array.
- Convert it to a string using a JSON encoder
- Convert the string to bytes with UTF8 encoding.
- Compress the bytes with gzip
- Convert the zipped bytes to a string using the Base64Url standard - a subset of base64 suitable for URLs.
- Create URL with URL scheme ssr://
For decoding, the reverse.
Code example (dart)
static const urlScheme = "ssr";
String jsonToSigningRequestUrl(dynamic jsonObj) {
final string = json.encode(jsonObj);
final bytes = utf8.encode(string);
final zippedBytes = gzip.encode(bytes);
final base64url = base64Url.encode(zippedBytes);
return "$urlScheme://$base64url";
}
/// returns JSON object
dynamic signingRequestUrlToJson(String url) {
final urlComponents = url.split("://");
if (urlComponents.length == 2) {
if (urlComponents[0] == urlScheme) {
final payload = urlComponents[1];
final zippedBytes = base64Url.decode(payload);
final bytes = gzip.decode(zippedBytes);
final string = utf8.decode(bytes);
final result = json.decode(string);
return result;
} else {
throw "Unsupported URL scheme: ${urlComponents[0]}";
}
} else {
throw "Invalid URL: $url";
}
}
A full binary encoding would yield the perfect compressed data.
However, experiments show that binary is only around 30% more efficient than zipped json (Reference Link)
Binary encoding of all possible field values would significantly increase the complexity of implementing clients that can handle this format.
Whereas JSON, UTF8, and gzip are all readily available on all platforms, and easy and straightforward to test and to use.
QR codes are limited in size, so size is important.
However, the benefits of simplicity outweigh the drawbacks of a roughtly 30% larger payload.