Skip to content

Commit 18f7887

Browse files
neithanmoabenso
andauthored
subaccount formatting (#267)
* Add token information registry and helper functions * Add formatting function to be use for registry look-up * Add commands to retrieve token registry * Add support to JS package to retrieve token registry from ledger devices * Add zemu test to retrieve device's token registry * Proper check to decide if using tokenInfo from table or default to Tokens marker for amount and fee * Apply the rigth format to Fees * Fix fee formatting for known and unknown tokens * Use token formatting according to token table for sns transactions * Update neuron tests * Update tests * Fix warnings * Bump version and update snapshots * Add token decimal tests * Fix token display title and update test vector(fixed) * Add support for neuron voting power updates * Fix parser and complete UI for voting power transaction * feat(manageneuron): Add neuron refresh voting power test in zemu * Add support to handle the configuration operation to set neuron visibility * Add zemu test to check neuron visibility transaction * Reduce title length to Max fee + token name * Fix fee title and update tests * Update snapshots to reproduce a change from Maximun fee to Max fee * Remove commented code which is not used * Update snapshots * Fix(candid): created time field in transaction must be optional Fix(fmt): Fix subaccounts formatting fix(tests): Remove token_decimals tests and move them into icrc transfers tests as provided by icp team * Bump app version * Add boundary checks * Fix field name with the shorter version --------- Co-authored-by: Andrés Benso <[email protected]>
1 parent c678fe9 commit 18f7887

File tree

115 files changed

+821
-331
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

115 files changed

+821
-331
lines changed

app/Makefile.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ APPVERSION_M=3
33
# This is the minor version of this release
44
APPVERSION_N=2
55
# This is the patch version of this release
6-
APPVERSION_P=5
6+
APPVERSION_P=6

app/src/candid/candid_parser.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -421,10 +421,9 @@ parser_error_t readCandidICRCTransfer(parser_tx_t *tx, const uint8_t *input, uin
421421

422422
// Read has_created_at_time
423423
CHECK_PARSER_ERR(readCandidByte(&ctx, &icrc->has_created_at_time))
424-
if (!icrc->has_created_at_time) {
425-
return parser_required_method;
424+
if (icrc->has_created_at_time) {
425+
CHECK_PARSER_ERR(readCandidNat64(&ctx, &icrc->created_at_time))
426426
}
427-
CHECK_PARSER_ERR(readCandidNat64(&ctx, &icrc->created_at_time)) // assume has_created_at_time
428427

429428
// Read amount
430429
CHECK_PARSER_ERR(readCandidLEB128(&ctx, &icrc->amount))

app/src/coin.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ extern "C" {
4949
#define DFINITY_SUBACCOUNT_LEN 32u
5050
#define DFINITY_PRINCIPAL_LEN 29u
5151
#define DFINITY_TEXTUAL_SIZE 100u
52+
// From an account we just display the first 16 bytes:
53+
// including the '.' prefix
54+
// 2 | From account [3/3] : .d7e8516 52cd032b a5ed76b1 7f626aa4"
55+
#define DFINITY_SUBACCOUNT_MAX_BYTES_TO_TEXTUAL 16u
5256

5357
#define MAX_CHARS_PER_VALUE_LINE 18u
5458

app/src/parser_print_candid.c

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -134,24 +134,41 @@ __Z_INLINE parser_error_t print_follow_topic(int32_t topic, char *outVal,
134134
return parser_ok;
135135
}
136136

137+
// Stick to the spec for printing accounts
138+
// https://internetcomputer.org/docs/current/references/icrc1-standard#textual-encoding-of-accounts
137139
__Z_INLINE parser_error_t print_accountBytes(
138140
sender_t sender, const candid_transfer_t *sendrequest, char *outVal,
139141
uint16_t outValLen, uint8_t pageIdx, uint8_t *pageCount) {
140-
uint8_t address[32] = {0};
142+
143+
// First check if we have a subaccount and if it's non-zero
144+
bool has_subaccount = sendrequest->has_from_subaccount;
145+
bool is_default_subaccount = true;
146+
147+
if (has_subaccount) {
148+
// Check if subaccount is all zeros
149+
for (uint16_t i = 0; i < sendrequest->from_subaccount.len; i++) {
150+
if (sendrequest->from_subaccount.p[i] != 0) {
151+
is_default_subaccount = false;
152+
break;
153+
}
154+
}
155+
}
156+
157+
// If no subaccount or all zeros, just print the principal
158+
if (!has_subaccount || is_default_subaccount) {
159+
return print_principal(sender.data, (uint16_t)sender.len, outVal, outValLen,
160+
pageIdx, pageCount);
161+
}
162+
163+
// For non-default subaccount, we need to handle the full format
141164
uint8_t subaccount[32] = {0};
142-
if (sendrequest->has_from_subaccount) {
165+
if (has_subaccount) {
143166
MEMCPY(subaccount, sendrequest->from_subaccount.p,
144167
(size_t)sendrequest->from_subaccount.len);
145168
}
146169

147-
zxerr_t err = crypto_principalToSubaccount(sender.data, (uint16_t)sender.len,
148-
subaccount, sizeof(subaccount),
149-
address, sizeof(address));
150-
if (err != zxerr_ok) {
151-
return parser_unexpected_error;
152-
}
153-
154-
return page_hexstring_with_delimiters(address, sizeof(address), outVal,
170+
return page_principal_with_subaccount(sender.data, (uint16_t)sender.len,
171+
subaccount, sizeof(subaccount), outVal,
155172
outValLen, pageIdx, pageCount);
156173
}
157174

@@ -1602,7 +1619,7 @@ parser_error_t parser_getItemCandid(const parser_context_t *ctx,
16021619
}
16031620

16041621
default:
1605-
ZEMU_LOGF(50, "Candid type not supported\n")
1622+
zemu_log("Candid type not supported\n");
16061623
break;
16071624
}
16081625

app/src/parser_print_helper.c

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -221,14 +221,18 @@ parser_error_t page_principal_with_subaccount(
221221
// print principal
222222
uint16_t principalLen = sizeof(text);
223223
zxerr_t err = zxerr_unknown;
224+
224225
err = crypto_principalToTextual(sender, senderLen, text_ptr, &principalLen);
226+
225227
// maximum length without separators is 53
226228
if (err != zxerr_ok || principalLen > 53) {
227229
return parser_unexpected_error;
228230
}
231+
229232
// every 5 chars there's a separator, and last block has no separator after it
230233
const uint8_t principalTextLen =
231234
(uint8_t)(principalLen + principalLen / 5 - (principalLen % 5 ? 0 : 1));
235+
232236
for (uint8_t i = 5; i < principalTextLen; i += 6) {
233237
// two blocks separated with dash, 3rd with SEPARATOR
234238
if ((i + 1) % 18 == 0)
@@ -240,11 +244,13 @@ parser_error_t page_principal_with_subaccount(
240244
return parser_unexpected_error;
241245
}
242246
}
247+
243248
// we are sure it's going to be up to 63 (53 + 10)
244249
principalLen = (uint16_t)strnlen(text, sizeof(text));
245250
if (principalLen > 63) {
246251
return parser_unexpected_value;
247252
}
253+
248254
*(text_ptr + principalLen) = '-';
249255
text_ptr += principalLen + 1;
250256

@@ -253,14 +259,17 @@ parser_error_t page_principal_with_subaccount(
253259
char crc_text[10] = {0};
254260
uint8_t tmpArray[DFINITY_PRINCIPAL_LEN + DFINITY_SUBACCOUNT_LEN + 1] = {0};
255261
MEMCPY(tmpArray, sender, senderLen);
262+
256263
// crc is computed with full subaccount with all zeros at the beginning
257264
MEMCPY(tmpArray + senderLen, fromSubaccount, fromSubaccountLen);
258265
uint32_t crc = 0;
266+
259267
crc32_small(tmpArray, senderLen + fromSubaccountLen, &crc);
260268
crc_array[0] = (uint8_t)((crc & 0xFF000000) >> 24);
261269
crc_array[1] = (uint8_t)((crc & 0x00FF0000) >> 16);
262270
crc_array[2] = (uint8_t)((crc & 0x0000FF00) >> 8);
263271
crc_array[3] = (uint8_t)((crc & 0x000000FF) >> 0);
272+
264273
uint8_t crcLen =
265274
(uint8_t)base32_encode(crc_array, 4, crc_text, sizeof(crc_text));
266275
if (crcLen == 0) {
@@ -271,6 +280,7 @@ parser_error_t page_principal_with_subaccount(
271280
MEMCPY(text_ptr, crc_text, crcLen);
272281
*(text_ptr + crcLen) = SEPARATOR;
273282
text_ptr += crcLen + 1;
283+
274284
#if !defined(TARGET_STAX) && \
275285
!defined(TARGET_FLEX) // needed if crc32 length is < 7
276286
for (uint8_t i = crcLen; i < 7; i++) {
@@ -280,28 +290,41 @@ parser_error_t page_principal_with_subaccount(
280290
#endif
281291
crcLen = 8; // also counting separator
282292

283-
// print subaccount
293+
*text_ptr = '.';
294+
text_ptr++;
295+
296+
uint16_t bytesToShow = subaccTrimLen;
297+
if (subaccTrimLen > DFINITY_SUBACCOUNT_MAX_BYTES_TO_TEXTUAL) {
298+
bytesToShow = DFINITY_SUBACCOUNT_MAX_BYTES_TO_TEXTUAL;
299+
}
300+
284301
array_to_hexstr(text_ptr, (uint16_t)sizeof(text) - principalLen - crcLen,
285-
subaccTrim, subaccTrimLen);
302+
subaccTrim, bytesToShow);
303+
286304
const uint8_t subaccountTextLen =
287-
2 * subaccTrimLen // 1 hex byte ==> 2 chars
288-
+ subaccTrimLen / 4 - 1 // separator for every block except last one
289-
+ (subaccTrimLen % 4 ? 1 : 0);
290-
// text_ptr is right at the start of subaccount
291-
for (uint8_t i = 8; i < subaccountTextLen; i += 9) {
292-
if ((i + 1) % 18 == 0)
293-
err = inplace_insert_char(text_ptr, sizeof(text), i,
294-
SEPARATOR); // line break
295-
else
296-
err = inplace_insert_char(text_ptr, sizeof(text), i, ' ');
305+
2 * bytesToShow + bytesToShow / 4 - 1 + (bytesToShow % 4 ? 1 : 0);
306+
307+
const uint8_t FIRST_BLOCK = 7;
308+
const uint8_t OTHER_BLOCKS = 8;
309+
// Add boundary check before inserting spaces
310+
if (subaccountTextLen < FIRST_BLOCK) {
311+
return parser_unexpected_error;
312+
}
313+
314+
for (uint8_t i = 0, pos = FIRST_BLOCK; i < 3 && pos < subaccountTextLen;
315+
i++) {
316+
err = inplace_insert_char(text_ptr, sizeof(text), pos, ' ');
297317
if (err != zxerr_ok) {
298318
return parser_unexpected_error;
299319
}
320+
// +1 for the space we just inserted
321+
pos += OTHER_BLOCKS + 1;
300322
}
301323

302324
uint8_t finalStrLen = (uint8_t)strnlen(text, sizeof(text));
303-
// [principal (<=64 chars) | crc32 (8 chars) | subaccount (<=71 chars)]
304-
if (finalStrLen > 143) {
325+
// [principal (<=64 chars) | crc32 (8 chars) | subaccount (<=71 chars) + 1
326+
// ('.')]
327+
if (finalStrLen > 144) {
305328
return parser_unexpected_error;
306329
}
307330

@@ -311,11 +334,13 @@ parser_error_t page_principal_with_subaccount(
311334
*pageCount =
312335
finalStrLen / CHARS_PER_PAGE + (finalStrLen % CHARS_PER_PAGE ? 1 : 0);
313336
const char *textToPrint = text + pageIdx * CHARS_PER_PAGE;
337+
314338
// we don't want to print last separator for each page
315339
if (CHARS_PER_PAGE > outValLen) {
316340
return parser_unexpected_error;
317341
}
318342
snprintf(outVal, CHARS_PER_PAGE, "%.*s", CHARS_PER_PAGE - 1, textToPrint);
343+
319344
return parser_ok;
320345
}
321346

tests/candid_send.json

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
"blob": "d9d9f7a167636f6e74656e74a663617267587a4449444c066d7b6c01e0a9b302786e006c01d6f68e8001786e036c06fbca0100c6fcb60201ba89e5c20478a2de94eb060282f3f3910c04d8a38ca80d01010520d3e13d4777e22367532053190b6c6ccf57444a61337e996242b1abfb52cf92c810270000000000000000000000000000000000ca9a3b000000006b63616e69737465725f69644a000000000000000201016e696e67726573735f6578706972791b176077308e9795c06b6d6574686f645f6e616d65687472616e736665726c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302",
66
"output": [
77
"0 | Transaction type : Send ICP",
8-
"1 | From account [1/2] : 4f3d4b40 cdb85273 2601fccf 8bd24dff",
9-
"1 | From account [2/2] : e44957a6 47cb8679 13e982d9 8cf85676",
8+
"1 | From account [1/2] : 5upke-tazvi-6ufqc i3v6r-j4gpu-dpwti",
9+
"1 | From account [2/2] : obhal-yb5xj-ue32x ktkql-rqe",
1010
"2 | To account [1/2] : d3e13d47 77e22367 53205319 0b6c6ccf",
1111
"2 | To account [2/2] : 57444a61 337e9962 42b1abfb 52cf92c8",
1212
"3 | Amount (Tokens) : 1000000000",
@@ -18,8 +18,8 @@
1818
"1 | Sender [1/2] : 5upke-tazvi-6ufqc i3v6r-j4gpu-dpwti",
1919
"1 | Sender [2/2] : obhal-yb5xj-ue32x ktkql-rqe",
2020
"2 | Subaccount : Not set",
21-
"3 | From account [1/2] : 4f3d4b40 cdb85273 2601fccf 8bd24dff",
22-
"3 | From account [2/2] : e44957a6 47cb8679 13e982d9 8cf85676",
21+
"3 | From account [1/2] : 5upke-tazvi-6ufqc i3v6r-j4gpu-dpwti",
22+
"3 | From account [2/2] : obhal-yb5xj-ue32x ktkql-rqe",
2323
"4 | To account [1/2] : d3e13d47 77e22367 53205319 0b6c6ccf",
2424
"4 | To account [2/2] : 57444a61 337e9962 42b1abfb 52cf92c8",
2525
"5 | Amount (Tokens) : 1000000000",
@@ -33,8 +33,9 @@
3333
"blob": "d9d9f7a167636f6e74656e74a663617267589b4449444c066d7b6c01e0a9b302786e006c01d6f68e8001786e036c06fbca0100c6fcb60201ba89e5c20478a2de94eb060282f3f3910c04d8a38ca80d01010520df4ad42194201b15ecbbe66ff68559a126854d8141fd935c5bd53433c2fb28d41027000000000000000000000000000001200a000000000030004b01010000000000000000000000000000000000000000000000c258884d0000006b63616e69737465725f69644a000000000000000201016e696e67726573735f6578706972791b17620a22c9b169c06b6d6574686f645f6e616d65687472616e736665726c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302",
3434
"output": [
3535
"0 | Transaction type : Send ICP",
36-
"1 | From account [1/2] : e934e0e3 7eb96d71 41f7489e b87c3541",
37-
"1 | From account [2/2] : f98b2c36 4b304229 8b684a36 44722b3d",
36+
"1 | From account [1/3] : 5upke-tazvi-6ufqc i3v6r-j4gpu-dpwti",
37+
"1 | From account [2/3] : obhal-yb5xj-ue32x ktkql-rqe-gipanwi",
38+
"1 | From account [3/3] : .0a00000 00000300 04b01010 00000000",
3839
"2 | To account [1/2] : df4ad421 94201b15 ecbbe66f f68559a1",
3940
"2 | To account [2/2] : 26854d81 41fd935c 5bd53433 c2fb28d4",
4041
"3 | Amount (Tokens) : 333000000000",
@@ -47,8 +48,9 @@
4748
"1 | Sender [2/2] : obhal-yb5xj-ue32x ktkql-rqe",
4849
"2 | Subaccount [1/2] : 0a000000 00003000 4b010100 00000000",
4950
"2 | Subaccount [2/2] : 00000000 00000000 00000000 00000000",
50-
"3 | From account [1/2] : e934e0e3 7eb96d71 41f7489e b87c3541",
51-
"3 | From account [2/2] : f98b2c36 4b304229 8b684a36 44722b3d",
51+
"3 | From account [1/3] : 5upke-tazvi-6ufqc i3v6r-j4gpu-dpwti",
52+
"3 | From account [2/3] : obhal-yb5xj-ue32x ktkql-rqe-gipanwi",
53+
"3 | From account [3/3] : .0a00000 00000300 04b01010 00000000",
5254
"4 | To account [1/2] : df4ad421 94201b15 ecbbe66f f68559a1",
5355
"4 | To account [2/2] : 26854d81 41fd935c 5bd53433 c2fb28d4",
5456
"5 | Amount (Tokens) : 333000000000",
@@ -62,8 +64,8 @@
6264
"blob": "d9d9f7a167636f6e74656e74a66361726758824449444c066d7b6c01e0a9b302786e006c01d6f68e8001786e036c06fbca0100c6fcb60201ba89e5c20478a2de94eb060282f3f3910c04d8a38ca80d01010520df4ad42194201b15ecbbe66ff68559a126854d8141fd935c5bd53433c2fb28d41027000000000000000000000000000000010038a7d84e9acd0930f95d55000000006b63616e69737465725f69644a000000000000000201016e696e67726573735f6578706972791b17620a22c9b169c06b6d6574686f645f6e616d65687472616e736665726c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302",
6365
"output": [
6466
"0 | Transaction type : Send ICP",
65-
"1 | From account [1/2] : 4f3d4b40 cdb85273 2601fccf 8bd24dff",
66-
"1 | From account [2/2] : e44957a6 47cb8679 13e982d9 8cf85676",
67+
"1 | From account [1/2] : 5upke-tazvi-6ufqc i3v6r-j4gpu-dpwti",
68+
"1 | From account [2/2] : obhal-yb5xj-ue32x ktkql-rqe",
6769
"2 | To account [1/2] : df4ad421 94201b15 ecbbe66f f68559a1",
6870
"2 | To account [2/2] : 26854d81 41fd935c 5bd53433 c2fb28d4",
6971
"3 | Amount (Tokens) : 1432222000",
@@ -75,8 +77,8 @@
7577
"1 | Sender [1/2] : 5upke-tazvi-6ufqc i3v6r-j4gpu-dpwti",
7678
"1 | Sender [2/2] : obhal-yb5xj-ue32x ktkql-rqe",
7779
"2 | Subaccount : Not set",
78-
"3 | From account [1/2] : 4f3d4b40 cdb85273 2601fccf 8bd24dff",
79-
"3 | From account [2/2] : e44957a6 47cb8679 13e982d9 8cf85676",
80+
"3 | From account [1/2] : 5upke-tazvi-6ufqc i3v6r-j4gpu-dpwti",
81+
"3 | From account [2/2] : obhal-yb5xj-ue32x ktkql-rqe",
8082
"4 | To account [1/2] : df4ad421 94201b15 ecbbe66f f68559a1",
8183
"4 | To account [2/2] : 26854d81 41fd935c 5bd53433 c2fb28d4",
8284
"5 | Amount (Tokens) : 1432222000",
@@ -90,8 +92,8 @@
9092
"blob": "d9d9f7a167636f6e74656e74a66361726758824449444c066d7b6c01e0a9b302786e006c01d6f68e8001786e036c06fbca0100c6fcb60201ba89e5c20478a2de94eb060282f3f3910c04d8a38ca80d01010520d3e13d4777e22367532053190b6c6ccf57444a61337e996242b1abfb52cf92c8102700000000000021caa60700000000000100d82c3c3807221200943577000000006b63616e69737465725f69644a000000000000000201016e696e67726573735f6578706972791b17620a22c9c0ac006b6d6574686f645f6e616d65687472616e736665726c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302",
9193
"output": [
9294
"0 | Transaction type : Send ICP",
93-
"1 | From account [1/2] : 4f3d4b40 cdb85273 2601fccf 8bd24dff",
94-
"1 | From account [2/2] : e44957a6 47cb8679 13e982d9 8cf85676",
95+
"1 | From account [1/2] : 5upke-tazvi-6ufqc i3v6r-j4gpu-dpwti",
96+
"1 | From account [2/2] : obhal-yb5xj-ue32x ktkql-rqe",
9597
"2 | To account [1/2] : d3e13d47 77e22367 53205319 0b6c6ccf",
9698
"2 | To account [2/2] : 57444a61 337e9962 42b1abfb 52cf92c8",
9799
"3 | Amount (Tokens) : 2000000000",
@@ -103,8 +105,8 @@
103105
"1 | Sender [1/2] : 5upke-tazvi-6ufqc i3v6r-j4gpu-dpwti",
104106
"1 | Sender [2/2] : obhal-yb5xj-ue32x ktkql-rqe",
105107
"2 | Subaccount : Not set",
106-
"3 | From account [1/2] : 4f3d4b40 cdb85273 2601fccf 8bd24dff",
107-
"3 | From account [2/2] : e44957a6 47cb8679 13e982d9 8cf85676",
108+
"3 | From account [1/2] : 5upke-tazvi-6ufqc i3v6r-j4gpu-dpwti",
109+
"3 | From account [2/2] : obhal-yb5xj-ue32x ktkql-rqe",
108110
"4 | To account [1/2] : d3e13d47 77e22367 53205319 0b6c6ccf",
109111
"4 | To account [2/2] : 57444a61 337e9962 42b1abfb 52cf92c8",
110112
"5 | Amount (Tokens) : 2000000000",
@@ -118,8 +120,9 @@
118120
"blob": "d9d9f7a167636f6e74656e74a663617267589b4449444c066d7b6c01e0a9b302786e006c01d6f68e8001786e036c06fbca0100c6fcb60201ba89e5c20478a2de94eb060282f3f3910c04d8a38ca80d01010520df4ad42194201b15ecbbe66ff68559a126854d8141fd935c5bd53433c2fb28d4102700000000000013726eab1e01000001201d02dc69531d6e8375cf08e80e6ecdd73b93b0ff60cc297b8a3fea531c0200000000e87648170000006b63616e69737465725f69644a000000000000000201016e696e67726573735f6578706972791b17620a22c9cfee406b6d6574686f645f6e616d65687472616e736665726c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302",
119121
"output": [
120122
"0 | Transaction type : Send ICP",
121-
"1 | From account [1/2] : eb94123b 55a5cf10 9982da44 a3cb35db",
122-
"1 | From account [2/2] : 38a41b86 979acf20 ce44a97a c13ba2a2",
123+
"1 | From account [1/3] : 5upke-tazvi-6ufqc i3v6r-j4gpu-dpwti",
124+
"1 | From account [2/3] : obhal-yb5xj-ue32x ktkql-rqe-vxtx5wq",
125+
"1 | From account [3/3] : .1d02dc6 9531d6e8 375cf08e 80e6ecdd",
123126
"2 | To account [1/2] : df4ad421 94201b15 ecbbe66f f68559a1",
124127
"2 | To account [2/2] : 26854d81 41fd935c 5bd53433 c2fb28d4",
125128
"3 | Amount (Tokens) : 100000000000",
@@ -132,8 +135,9 @@
132135
"1 | Sender [2/2] : obhal-yb5xj-ue32x ktkql-rqe",
133136
"2 | Subaccount [1/2] : 1d02dc69 531d6e83 75cf08e8 0e6ecdd7",
134137
"2 | Subaccount [2/2] : 3b93b0ff 60cc297b 8a3fea53 1c020000",
135-
"3 | From account [1/2] : eb94123b 55a5cf10 9982da44 a3cb35db",
136-
"3 | From account [2/2] : 38a41b86 979acf20 ce44a97a c13ba2a2",
138+
"3 | From account [1/3] : 5upke-tazvi-6ufqc i3v6r-j4gpu-dpwti",
139+
"3 | From account [2/3] : obhal-yb5xj-ue32x ktkql-rqe-vxtx5wq",
140+
"3 | From account [3/3] : .1d02dc6 9531d6e8 375cf08e 80e6ecdd",
137141
"4 | To account [1/2] : df4ad421 94201b15 ecbbe66f f68559a1",
138142
"4 | To account [2/2] : 26854d81 41fd935c 5bd53433 c2fb28d4",
139143
"5 | Amount (Tokens) : 100000000000",

0 commit comments

Comments
 (0)