Skip to content

Commit

Permalink
Add units to prompts
Browse files Browse the repository at this point in the history
  • Loading branch information
alexfmpe committed Feb 8, 2021
1 parent a22fb48 commit 8f504ae
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 55 deletions.
2 changes: 1 addition & 1 deletion src/evm_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void init_rlp_item(struct EVM_RLP_item_state *const state) {
static void output_evm_prompt_to_string(char *const out, size_t const out_size, output_prompt_t const *const in) {
check_null(out);
check_null(in);
size_t ix = nano_avax_to_string(out, out_size, in->amount);
size_t ix = wei_to_gwei_string(out, out_size, in->amount);

static char const to[] = " to ";
if (ix + sizeof(to) > out_size) THROW_(EXC_MEMORY_ERROR, "Can't fit ' to ' into prompt value string");
Expand Down
26 changes: 23 additions & 3 deletions src/to_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,17 @@ size_t number_to_string(char *const dest, uint64_t number) {

#define DECIMAL_DIGITS 9
#define NANO_AVAX_SCALE 1000000000
#define WEI_GWEI_SCALE 1000000000

// Display avax in human readable form
size_t nano_avax_to_string(char *const dest, size_t const buff_size, uint64_t nano_avax) {
size_t subunit_to_unit_string(char *const dest, size_t const buff_size, uint64_t subunits, uint64_t scale) {
check_null(dest);

if (buff_size < MAX_INT_DIGITS + 2)
THROW(EXC_WRONG_LENGTH); // terminating null
uint64_t whole_avax = nano_avax / NANO_AVAX_SCALE;
uint64_t fractional_avax = nano_avax % NANO_AVAX_SCALE;

uint64_t whole_avax = subunits / scale;
uint64_t fractional_avax = subunits % scale;
size_t off = number_to_string(dest, whole_avax);
if (fractional_avax == 0) {
return off;
Expand All @@ -207,6 +210,23 @@ size_t nano_avax_to_string(char *const dest, size_t const buff_size, uint64_t na
return off;
}

size_t nano_avax_to_string(char *const dest, size_t const buff_size, uint64_t nano_avax) {
static char const unit[] = " AVAX";
size_t ix = subunit_to_unit_string(dest, buff_size, nano_avax, NANO_AVAX_SCALE);
if (ix + sizeof(unit) > buff_size) THROW_(EXC_MEMORY_ERROR, "Can't fit ' AVAX' into prompt value string");
memcpy(&dest[ix], unit, sizeof(unit));
ix += sizeof(unit) - 1;
return ix;
}
size_t wei_to_gwei_string(char *const dest, size_t const buff_size, uint64_t wei) {
static char const unit[] = " GWEI";
size_t ix = subunit_to_unit_string(dest, buff_size, wei, WEI_GWEI_SCALE);
if (ix + sizeof(unit) > buff_size) THROW_(EXC_MEMORY_ERROR, "Can't fit ' AVAX' into prompt value string");
memcpy(&dest[ix], unit, sizeof(unit));
ix += sizeof(unit) - 1;
return ix;
}

void nano_avax_to_string_indirect64(char *const dest, size_t const buff_size, uint64_t const *const number) {
check_null(number);
nano_avax_to_string(dest, buff_size, *number);
Expand Down
50 changes: 25 additions & 25 deletions tests/basic-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@ describe("Basic Tests", () => {
const pathSuffixes = ["0/0", "0/1", "1/100"];
const ui = await flowMultiPrompt(this.speculos, [
[{header:"Sign",body:"Transaction"}],
[{header:"Transfer",body:"0.000012345 to fuji12yp9cc0melq83a5nxnurf0nd6fk4t224unmnwx"}],
[{header:"Fee",body:"0.123444444"}],
[{header:"Transfer",body:"0.000012345 AVAX to fuji12yp9cc0melq83a5nxnurf0nd6fk4t224unmnwx"}],
[{header:"Fee",body:"0.123444444 AVAX"}],
[{header:"Finalize",body:"Transaction"}],
]);
const sigPromise = signTransaction(this.ava, pathPrefix, pathSuffixes);
Expand All @@ -177,8 +177,8 @@ describe("Basic Tests", () => {
const pathSuffixes = ["0/0", "0/1", "1/100"];
const ui = await flowMultiPrompt(this.speculos, [
[{header:"Sign",body:"Transaction"}],
[{header:"Transfer",body:"0.123456789 to fuji12yp9cc0melq83a5nxnurf0nd6fk4t224unmnwx"}],
[{header:"Fee",body:"0.876543211"}],
[{header:"Transfer",body:"0.123456789 AVAX to fuji12yp9cc0melq83a5nxnurf0nd6fk4t224unmnwx"}],
[{header:"Fee",body:"0.876543211 AVAX"}],
[{header:"Finalize",body:"Transaction"}],
]);
const sigPromise = signTransaction(this.ava, pathPrefix, pathSuffixes, {
Expand All @@ -194,8 +194,8 @@ describe("Basic Tests", () => {
const pathSuffixes = ["0/0", "0/1", "1/100"];
const ui = await flowMultiPrompt(this.speculos, [
[{header:"Sign",body:"Transaction"}],
[{header:"Transfer",body:"1 to fuji12yp9cc0melq83a5nxnurf0nd6fk4t224unmnwx"}],
[{header:"Fee",body:"1"}],
[{header:"Transfer",body:"1 AVAX to fuji12yp9cc0melq83a5nxnurf0nd6fk4t224unmnwx"}],
[{header:"Fee",body:"1 AVAX"}],
[{header:"Finalize",body:"Transaction"}],
]);
const sigPromise = signTransaction(this.ava, pathPrefix, pathSuffixes, {
Expand Down Expand Up @@ -287,9 +287,9 @@ describe("Basic Tests", () => {
const pathSuffixes = ["0/0", "0/1", "1/100"];
const ui = await flowMultiPrompt(this.speculos, [
[{header:"Sign",body:"Transaction"}],
[{header:"Transfer",body:"0.000001 to fuji10an3cucdfqru984pnvv6y0rspvvclz634xwwhs"}],
[{header:"Transfer",body:"0.006999 to fuji15jh6hlessx2jtxvs48jnr0vzxrg34x32vuc7jc"}],
[{header:"Fee",body:"0.001"}],
[{header:"Transfer",body:"0.000001 AVAX to fuji10an3cucdfqru984pnvv6y0rspvvclz634xwwhs"}],
[{header:"Transfer",body:"0.006999 AVAX to fuji15jh6hlessx2jtxvs48jnr0vzxrg34x32vuc7jc"}],
[{header:"Fee",body:"0.001 AVAX"}],
[{header:"Finalize",body:"Transaction"}],
]);
const sigPromise = this.ava.signTransaction(
Expand Down Expand Up @@ -382,9 +382,9 @@ describe("Basic Tests", () => {
const pathSuffixes = ["0/0", "0/1", "1/100"];
const ui = await flowMultiPrompt(this.speculos, [
[{header:"Sign",body:"Transaction"}],
[{header:"Transfer",body:"0.000001 to fuji10an3cucdfqru984pnvv6y0rspvvclz634xwwhs"}],
[{header:"Transfer",body:"0.006999 to fuji179xfr036ym3uuv8ewrv8y4la97ealwmlfg8yrr"}],
[{header:"Fee",body:"0.001"}],
[{header:"Transfer",body:"0.000001 AVAX to fuji10an3cucdfqru984pnvv6y0rspvvclz634xwwhs"}],
[{header:"Transfer",body:"0.006999 AVAX to fuji179xfr036ym3uuv8ewrv8y4la97ealwmlfg8yrr"}],
[{header:"Fee",body:"0.001 AVAX"}],
[{header:"Finalize",body:"Transaction"}],
]);
const sigPromise = this.ava.signTransaction(
Expand All @@ -401,8 +401,8 @@ describe("Basic Tests", () => {
try {
const ui = await flowMultiPrompt(this.speculos, [
[{header:"Sign",body:"Transaction"}],
[{header:"Transfer",body:"0.000012345 to fuji12yp9cc0melq83a5nxnurf0nd6fk4t224unmnwx"}],
[{header:"Fee",body:"0.123444444"}],
[{header:"Transfer",body:"0.000012345 AVAX to fuji12yp9cc0melq83a5nxnurf0nd6fk4t224unmnwx"}],
[{header:"Fee",body:"0.123444444 AVAX"}],
], "Next", "Next");
await signTransaction(this.ava, "44'/9000'/0'", ["0/0"], {
extraEndBytes: Buffer.from([0x00])
Expand Down Expand Up @@ -466,7 +466,7 @@ describe("Basic Tests", () => {
{ inputTypeId: Buffer.from([0x01, 0x00, 0x00, 0x00]) },
[
[{header:"Sign",body:"Transaction"}],
[{header:"Transfer",body:"0.000012345 to fuji12yp9cc0melq83a5nxnurf0nd6fk4t224unmnwx"}],
[{header:"Transfer",body:"0.000012345 AVAX to fuji12yp9cc0melq83a5nxnurf0nd6fk4t224unmnwx"}],
],
);
});
Expand Down Expand Up @@ -610,9 +610,9 @@ describe("Basic Tests", () => {
it("Can sign a P->X Import transaction", async function() {
const ui = await flowMultiPrompt(this.speculos, [
[{header:"Sign",body:"Import"}],
[{header:"Sending",body: "0.000012345 to fuji1cv6yz28qvqfgah34yw3y53su39p6kzzehw5pj3"}],
[{header:"Sending",body: "0.000012345 AVAX to fuji1cv6yz28qvqfgah34yw3y53su39p6kzzehw5pj3"}],
[{header:"From",body: "P-chain"}],
[{header:"Fee",body:"0.246901233"}],
[{header:"Fee",body:"0.246901233 AVAX"}],
[{header:"Finalize",body:"Transaction"}],
]);
const sigPromise = this.ava.signTransaction(
Expand All @@ -627,9 +627,9 @@ describe("Basic Tests", () => {
it("Can sign a C->X Import transaction", async function() {
const ui = await flowMultiPrompt(this.speculos, [
[{header:"Sign",body:"Import"}],
[{header:"Sending",body: "0.000012345 to fuji1cv6yz28qvqfgah34yw3y53su39p6kzzehw5pj3"}],
[{header:"Sending",body: "0.000012345 AVAX to fuji1cv6yz28qvqfgah34yw3y53su39p6kzzehw5pj3"}],
[{header:"From",body: "C-chain"}],
[{header:"Fee",body:"0.246901233"}],
[{header:"Fee",body:"0.246901233 AVAX"}],
[{header:"Finalize",body:"Transaction"}],
]);
const sigPromise = this.ava.signTransaction(
Expand Down Expand Up @@ -692,9 +692,9 @@ describe("Basic Tests", () => {
it("Can sign a X->P Export transaction", async function() {
const ui = await flowMultiPrompt(this.speculos, [
[{header:"Sign",body:"Export"}],
[{header:"Transfer",body: "0.000012345 to fuji1cv6yz28qvqfgah34yw3y53su39p6kzzehw5pj3"}],
[{header:"X to P chain",body:"0.000012345 to fuji12yp9cc0melq83a5nxnurf0nd6fk4t224unmnwx"}],
[{header:"Fee",body:"0.123432099"}],
[{header:"Transfer",body: "0.000012345 AVAX to fuji1cv6yz28qvqfgah34yw3y53su39p6kzzehw5pj3"}],
[{header:"X to P chain",body:"0.000012345 AVAX to fuji12yp9cc0melq83a5nxnurf0nd6fk4t224unmnwx"}],
[{header:"Fee",body:"0.123432099 AVAX"}],
[{header:"Finalize",body:"Transaction"}],
]);
const sigPromise = this.ava.signTransaction(
Expand All @@ -709,9 +709,9 @@ describe("Basic Tests", () => {
it("Can sign a X->C Export transaction", async function() {
const ui = await flowMultiPrompt(this.speculos, [
[{header:"Sign",body:"Export"}],
[{header:"Transfer",body: "0.000012345 to fuji1cv6yz28qvqfgah34yw3y53su39p6kzzehw5pj3"}],
[{header:"X to C chain",body:"0.000012345 to fuji12yp9cc0melq83a5nxnurf0nd6fk4t224unmnwx"}],
[{header:"Fee",body:"0.123432099"}],
[{header:"Transfer",body: "0.000012345 AVAX to fuji1cv6yz28qvqfgah34yw3y53su39p6kzzehw5pj3"}],
[{header:"X to C chain",body:"0.000012345 AVAX to fuji12yp9cc0melq83a5nxnurf0nd6fk4t224unmnwx"}],
[{header:"Fee",body:"0.123432099 AVAX"}],
[{header:"Finalize",body:"Transaction"}],
]);
const sigPromise = this.ava.signTransaction(
Expand Down
8 changes: 4 additions & 4 deletions tests/c-chain-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ describe("C-chain import and export tests", () => {
const pathSuffixes = ["0/0", "0/1", "100/100"];
const ui = await flowMultiPrompt(this.speculos, [
[{header:"Sign", body:"Import"}],
[{header:"From X chain",body:"0.268435456 to local1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqljssag"}],
[{header:"Fee", body:"0"}],
[{header:"From X chain",body:"0.268435456 AVAX to local1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqljssag"}],
[{header:"Fee", body:"0 AVAX"}],
[{header:"Finalize",body:"Transaction"}],
]);
const sigPromise = this.ava.signTransaction(
Expand Down Expand Up @@ -130,8 +130,8 @@ describe("C-chain import and export tests", () => {
const pathSuffixes = ["0/0", "0/1", "100/100"];
const ui = await flowMultiPrompt(this.speculos, [
[{header:"Sign",body:"Export"}],
[{header:"C to X chain",body:'0.001 to local1vmusmdsn0fu0w6ekj0ml90zs09td4etrp5d6p7'}],
[{header:"Fee",body:"0.001"}],
[{header:"C to X chain",body:'0.001 AVAX to local1vmusmdsn0fu0w6ekj0ml90zs09td4etrp5d6p7'}],
[{header:"Fee",body:"0.001 AVAX"}],
[{header:"Finalize",body:"Transaction"}],
]);
const sigPromise = this.ava.signTransaction(
Expand Down
6 changes: 3 additions & 3 deletions tests/eth-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ describe("Eth app compatibility tests", () => {
it('can sign a transaction via the ethereum ledgerjs module', async function() {
await testSigning(this, 43114,
transferPrompts('0x28ee52a8f3d6e5d15f8b131996950d7f296c7952',
'12340000'),
'12340000 GWEI'),
'ed018504e3b292008252089428ee52a8f3d6e5d15f8b131996950d7f296c7952872bd72a248740008082a86a8080'
);
})
Expand All @@ -62,7 +62,7 @@ describe("Eth app compatibility tests", () => {

it('can sign a transaction with calldata via the ethereum ledgerjs module', async function() {
await testSigning(this, 43112,
[[{header:"Transfer",body:"0.000000001 to 0x0102030400000000000000000000000000000002"}],
[[{header:"Transfer",body:"0.000000001 GWEI to 0x0102030400000000000000000000000000000002"}],
[{header:"Contract Data",body:"Is Present (unsafe)"}],
[{header:"Finalize",body:"Transaction"}]
],
Expand Down Expand Up @@ -90,7 +90,7 @@ describe("Eth app compatibility tests", () => {
it('can provide an ERC20 Token and sign with the ethereum ledgerjs module', async function() {
const flow = await flowMultiPrompt(this.speculos,
[
[{header:"Transfer", body: "12340000 to 0x28ee52a8f3d6e5d15f8b131996950d7f296c7952"}],
[{header:"Transfer", body: "12340000 GWEI to 0x28ee52a8f3d6e5d15f8b131996950d7f296c7952"}],
[{header:"Finalize", body: "Transaction"}]
]);
ethTx = Buffer.from('ed018504e3b292008252089428ee52a8f3d6e5d15f8b131996950d7f296c7952872bd72a248740008082a86a8080', 'hex');
Expand Down
38 changes: 19 additions & 19 deletions tests/p-chain-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ describe("P-chain import and export tests", () => {
const pathSuffixes = ["0/0", "0/1", "100/100"];
const ui = await flowMultiPrompt(this.speculos, [
[{header:"Sign",body:"Import"}],
[{header:"From X chain",body:"19999.999 to fuji18jma8ppw3nhx5r4ap8clazz0dps7rv5u6wmu4t"}],
[{header:"Fee",body:"15188.373088832"}],
[{header:"From X chain",body:"19999.999 AVAX to fuji18jma8ppw3nhx5r4ap8clazz0dps7rv5u6wmu4t"}],
[{header:"Fee",body:"15188.373088832 AVAX"}],
[{header:"Finalize",body:"Transaction"}],
]);
const sigPromise = this.ava.signTransaction(
Expand Down Expand Up @@ -125,9 +125,9 @@ describe("P-chain import and export tests", () => {
const pathSuffixes = ["0/0", "0/1", "100/100"];
const ui = await flowMultiPrompt(this.speculos, [
[{header:"Sign",body:"Export"}],
[{header:"Transfer",body:'0.000012345 to fuji1cv6yz28qvqfgah34yw3y53su39p6kzzehw5pj3'}],
[{header:"P to X chain",body:'0.000012345 to fuji12yp9cc0melq83a5nxnurf0nd6fk4t224unmnwx'}],
[{header:"Fee",body:"0.123432099"}],
[{header:"Transfer",body:'0.000012345 AVAX to fuji1cv6yz28qvqfgah34yw3y53su39p6kzzehw5pj3'}],
[{header:"P to X chain",body:'0.000012345 AVAX to fuji12yp9cc0melq83a5nxnurf0nd6fk4t224unmnwx'}],
[{header:"Fee",body:"0.123432099 AVAX"}],
[{header:"Finalize",body:"Transaction"}],
]);
const sigPromise = this.ava.signTransaction(
Expand Down Expand Up @@ -215,15 +215,15 @@ describe('Staking tests', async function () {
const pathSuffixes = ["0/0", "0/1", "100/100"];
const ui = await flowMultiPrompt(this.speculos, [
[{header: 'Sign', body: 'Add Validator'}],
[{header: 'Transfer', body: '3.999 to local1mg47uqd7stkvqrp57ds7m28txra45u2uzkta8n'}],
[{header: 'Transfer', body: '3.999 AVAX to local1mg47uqd7stkvqrp57ds7m28txra45u2uzkta8n'}],
[{header: 'Validator', body: 'NodeID-NFBbbJ4qCmNaCzeW7sxErhvWqvEQMnYcN' }],
[{header: 'Start time', body: '2020-07-29 22:07:25 UTC' }],
[{header: 'End time', body: '2020-08-28 21:57:26 UTC' }],
[{header: 'Total Stake', body: '2000' }],
[{header: 'Stake',body: '2000 to local18jma8ppw3nhx5r4ap8clazz0dps7rv5u00z96u'}],
[{header: 'Total Stake', body: '2000 AVAX' }],
[{header: 'Stake',body: '2000 AVAX to local18jma8ppw3nhx5r4ap8clazz0dps7rv5u00z96u'}],
[{header: 'Rewards To', body: 'local1mg47uqd7stkvqrp57ds7m28txra45u2uzkta8n' }],
[{header: 'Delegation Fee', body: '0.01%' }],
[{header: 'Fee',body: '0.001'}],
[{header: 'Fee',body: '0.001 AVAX'}],
[{header: 'Finalize',body: 'Transaction'}],
]);
const sigPromise = this.ava.signTransaction(
Expand Down Expand Up @@ -310,12 +310,12 @@ describe('Staking tests', async function () {
const pathSuffixes = ["0/0", "0/1", "100/100"];
const ui = await flowMultiPrompt(this.speculos, [
[{header: 'Sign', body: 'Add Validator'}],
[{header: 'Transfer', body: '3.999 to local1mg47uqd7stkvqrp57ds7m28txra45u2uzkta8n'}],
[{header: 'Transfer', body: '3.999 AVAX to local1mg47uqd7stkvqrp57ds7m28txra45u2uzkta8n'}],
[{header: 'Validator', body: 'NodeID-NFBbbJ4qCmNaCzeW7sxErhvWqvEQMnYcN' }],
[{header: 'Start time', body: '2020-07-29 22:07:25 UTC' }],
[{header: 'End time', body: '2020-08-28 21:57:26 UTC' }],
[{header: 'Total Stake', body: '0.000054321' }],
[{header: 'Stake',body: '2000 to local18jma8ppw3nhx5r4ap8clazz0dps7rv5u00z96u'}],
[{header: 'Total Stake', body: '0.000054321 AVAX' }],
[{header: 'Stake',body: '2000 AVAX to local18jma8ppw3nhx5r4ap8clazz0dps7rv5u00z96u'}],
], "Next", "Next");
const sigPromise = this.ava.signTransaction(
BIPPath.fromString(pathPrefix),
Expand Down Expand Up @@ -393,14 +393,14 @@ describe('Staking tests', async function () {
const pathSuffixes = ["0/0", "0/1", "100/100"];
const ui = await flowMultiPrompt(this.speculos, [
[{header: 'Sign', body: 'Add Delegator'}],
[{header: 'Transfer', body: '3.999 to local1mg47uqd7stkvqrp57ds7m28txra45u2uzkta8n'}],
[{header: 'Transfer', body: '3.999 AVAX to local1mg47uqd7stkvqrp57ds7m28txra45u2uzkta8n'}],
[{header: 'Validator', body: 'NodeID-NFBbbJ4qCmNaCzeW7sxErhvWqvEQMnYcN' }],
[{header: 'Start time', body: '2020-07-29 22:07:25 UTC' }],
[{header: 'End time', body: '2020-08-28 21:57:26 UTC' }],
[{header: 'Total Stake', body: '2000' }],
[{header: 'Stake', body: '2000 to local18jma8ppw3nhx5r4ap8clazz0dps7rv5u00z96u'}],
[{header: 'Total Stake', body: '2000 AVAX' }],
[{header: 'Stake', body: '2000 AVAX to local18jma8ppw3nhx5r4ap8clazz0dps7rv5u00z96u'}],
[{header: 'Rewards To', body: 'local1mg47uqd7stkvqrp57ds7m28txra45u2uzkta8n' }],
[{header: 'Fee', body: '0.001'}],
[{header: 'Fee', body: '0.001 AVAX'}],
[{header: 'Finalize', body: 'Transaction'}],
]);
const sigPromise = this.ava.signTransaction(
Expand Down Expand Up @@ -476,12 +476,12 @@ describe('Staking tests', async function () {
const pathSuffixes = ["0/0", "0/1", "100/100"];
const ui = await flowMultiPrompt(this.speculos, [
[{header: 'Sign', body: 'Add Delegator'}],
[{header: 'Transfer', body: '3.999 to local1mg47uqd7stkvqrp57ds7m28txra45u2uzkta8n'}],
[{header: 'Transfer', body: '3.999 AVAX to local1mg47uqd7stkvqrp57ds7m28txra45u2uzkta8n'}],
[{header: 'Validator', body: 'NodeID-NFBbbJ4qCmNaCzeW7sxErhvWqvEQMnYcN' }],
[{header: 'Start time', body: '2020-07-29 22:07:25 UTC' }],
[{header: 'End time', body: '2020-08-28 21:57:26 UTC' }],
[{header: 'Total Stake', body: '0.000054321' }],
[{header: 'Stake', body: '2000 to local18jma8ppw3nhx5r4ap8clazz0dps7rv5u00z96u'}],
[{header: 'Total Stake', body: '0.000054321 AVAX' }],
[{header: 'Stake', body: '2000 AVAX to local18jma8ppw3nhx5r4ap8clazz0dps7rv5u00z96u'}],
], "Next", "Next");
const sigPromise = this.ava.signTransaction(
BIPPath.fromString(pathPrefix),
Expand Down

0 comments on commit 8f504ae

Please sign in to comment.