From 9ff6edc037840bca6d634e94d245e9d9b6ef5552 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Mon, 31 Jan 2022 11:03:43 +0100 Subject: [PATCH 01/48] increase gas amplifier --- src/env.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/env.ts b/src/env.ts index b67d344118..f2f2975934 100644 --- a/src/env.ts +++ b/src/env.ts @@ -156,7 +156,7 @@ const envDefinitions = { desc: "location of the compound API", }, COSMOS_GAS_AMPLIFIER: { - def: 1.4, + def: 4, parser: intParser, desc: "estimate gas multiplier", }, From bb1888bd3a891001f62c882b87cfd9d3f4a8b4ba Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Mon, 31 Jan 2022 11:04:34 +0100 Subject: [PATCH 02/48] fix payload construction handle payload atomic construction --- src/families/cosmos/js-buildTransaction.ts | 207 ++++++++++++------- src/families/cosmos/js-prepareTransaction.ts | 11 +- 2 files changed, 138 insertions(+), 80 deletions(-) diff --git a/src/families/cosmos/js-buildTransaction.ts b/src/families/cosmos/js-buildTransaction.ts index a72ad636c3..14a74292f5 100644 --- a/src/families/cosmos/js-buildTransaction.ts +++ b/src/families/cosmos/js-buildTransaction.ts @@ -21,106 +21,160 @@ const buildTransaction = async ( const msg: Array<{ typeUrl: string; value: any }> = []; + // Ledger Live is able to build transaction atomically, + // Take care expected data are complete before push msg. + // Otherwise, the transaction is silently returned intact. + + let isComplete = true; + switch (transaction.mode) { case "send": - msg.push({ - typeUrl: "/cosmos.bank.v1beta1.MsgSend", - value: { - fromAddress: account.freshAddress, - toAddress: transaction.recipient, - amount: [ - { - denom: account.currency.units[1].code, - amount: transaction.amount.toString(), - }, - ], - }, - }); + if (!transaction.recipient || !transaction.amount) { + isComplete = false; + } else { + msg.push({ + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: { + fromAddress: account.freshAddress, + toAddress: transaction.recipient, + amount: [ + { + denom: account.currency.units[1].code, + amount: transaction.amount.toString(), + }, + ], + }, + }); + } break; case "delegate": - transaction.validators.forEach((validator) => { + if (!transaction.validators || transaction.validators.length < 1) { + isComplete = false; + } else { + transaction.validators.forEach((validator) => { + if (!validator.address || !validator.amount) { + isComplete = false; + } + + msg.push({ + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: { + delegatorAddress: account.freshAddress, + validatorAddress: validator.address, + amount: [ + { + denom: account.currency.units[1].code, + amount: validator.amount.toString(), + }, + ], + }, + }); + }); + } + break; + + case "undelegate": + if ( + !transaction.validators || + transaction.validators.length < 1 || + !transaction.validators[0].address || + !transaction.validators[0].amount + ) { + isComplete = false; + } else { msg.push({ - typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + typeUrl: "/cosmos.staking.v1beta1.MsgUndelegate", value: { delegatorAddress: account.freshAddress, - validatorAddress: validator.address, + validatorAddress: transaction.validators[0].address, amount: [ { denom: account.currency.units[1].code, - amount: validator.amount.toString(), + amount: transaction.validators[0].amount.toString(), }, ], }, }); - }); - break; - - case "undelegate": - msg.push({ - typeUrl: "/cosmos.staking.v1beta1.MsgUndelegate", - value: { - delegatorAddress: account.freshAddress, - validatorAddress: transaction.validators[0].address, - amount: [ - { - denom: account.currency.units[1].code, - amount: transaction.validators[0].amount.toString(), - }, - ], - }, - }); + } break; case "redelegate": - msg.push({ - typeUrl: "/cosmos.staking.v1beta1.MsgBeginRedelegate", - value: { - validatorSrcAddress: transaction.cosmosSourceValidator, - delegatorAddress: account.freshAddress, - validatorAddress: transaction.validators[0].address, - amount: [ - { - denom: account.currency.units[1].code, - amount: transaction.validators[0].amount.toString(), - }, - ], - }, - }); + if ( + !transaction.cosmosSourceValidator || + !transaction.validators || + transaction.validators.length < 1 || + !transaction.validators[0].address || + !transaction.validators[0].amount + ) { + isComplete = false; + } else { + msg.push({ + typeUrl: "/cosmos.staking.v1beta1.MsgBeginRedelegate", + value: { + validatorSrcAddress: transaction.cosmosSourceValidator, + delegatorAddress: account.freshAddress, + validatorAddress: transaction.validators[0].address, + amount: [ + { + denom: account.currency.units[1].code, + amount: transaction.validators[0].amount.toString(), + }, + ], + }, + }); + } break; case "claimReward": - msg.push({ - typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", - value: { - delegatorAddress: account.freshAddress, - validatorAddress: transaction.validators[0].address, - }, - }); + if ( + !transaction.validators || + transaction.validators.length < 1 || + !transaction.validators[0].address + ) { + isComplete = false; + } else { + msg.push({ + typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", + value: { + delegatorAddress: account.freshAddress, + validatorAddress: transaction.validators[0].address, + }, + }); + } break; case "claimRewardCompound": - msg.push({ - typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", - value: { - delegatorAddress: account.freshAddress, - validatorAddress: transaction.validators[0].address, - }, - }); - - msg.push({ - typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", - value: { - delegatorAddress: account.freshAddress, - validatorAddress: transaction.validators[0].address, - amount: [ - { - denom: account.currency.units[1].code, - amount: transaction.validators[0].amount.toString(), - }, - ], - }, - }); + if ( + !transaction.validators || + transaction.validators.length < 1 || + !transaction.validators[0].address || + !transaction.validators[0].amount + ) { + isComplete = false; + } else { + msg.push({ + typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", + value: { + delegatorAddress: account.freshAddress, + validatorAddress: transaction.validators[0].address, + }, + }); + + msg.push({ + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: { + delegatorAddress: account.freshAddress, + validatorAddress: transaction.validators[0].address, + amount: [ + { + denom: account.currency.units[1].code, + amount: transaction.validators[0].amount.toString(), + }, + ], + }, + }); + } break; } @@ -139,6 +193,7 @@ const buildTransaction = async ( return { messages: msg, auth: authInfoBytes, + isComplete, }; }; diff --git a/src/families/cosmos/js-prepareTransaction.ts b/src/families/cosmos/js-prepareTransaction.ts index 3444d80cf2..c74da18943 100644 --- a/src/families/cosmos/js-prepareTransaction.ts +++ b/src/families/cosmos/js-prepareTransaction.ts @@ -27,8 +27,15 @@ const prepareTransaction = async ( ); } + if (transaction.mode !== "send" && !transaction.memo) { + transaction.memo = "Ledger Live"; + } + const unsignedPayload = await buildTransaction(account, transaction); + // be sure payload is complete + if (!unsignedPayload.isComplete) return transaction; + const txBodyFields: TxBodyEncodeObject = { typeUrl: "/cosmos.tx.v1beta1.TxBody", value: { @@ -67,10 +74,6 @@ const prepareTransaction = async ( .multipliedBy(new BigNumber(getEnv("COSMOS_GAS_AMPLIFIER"))) .integerValue(BigNumber.ROUND_CEIL); - if (transaction.mode !== "send" && !transaction.memo) { - transaction.memo = "Ledger Live"; - } - return transaction; }; From 92f4d599d10d0f6dad8c52c0035104a4a296159a Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Mon, 31 Jan 2022 12:07:28 +0100 Subject: [PATCH 03/48] More accurate gas amplifier --- src/env.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/env.ts b/src/env.ts index f2f2975934..5b00aa326c 100644 --- a/src/env.ts +++ b/src/env.ts @@ -156,7 +156,7 @@ const envDefinitions = { desc: "location of the compound API", }, COSMOS_GAS_AMPLIFIER: { - def: 4, + def: 1.6, parser: intParser, desc: "estimate gas multiplier", }, From f29a4aee7389ddfa02b86bf73c1a86690d31718c Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Mon, 31 Jan 2022 16:15:50 +0100 Subject: [PATCH 04/48] increase gas amplifier --- src/env.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/env.ts b/src/env.ts index 5b00aa326c..7055907f62 100644 --- a/src/env.ts +++ b/src/env.ts @@ -156,7 +156,7 @@ const envDefinitions = { desc: "location of the compound API", }, COSMOS_GAS_AMPLIFIER: { - def: 1.6, + def: 1.8, parser: intParser, desc: "estimate gas multiplier", }, From 957a48f01ab580e2ec84910e2840382b5fcc42eb Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Mon, 31 Jan 2022 16:16:15 +0100 Subject: [PATCH 05/48] use same node for calculation and broadcast --- src/families/cosmos/api/Cosmos.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/families/cosmos/api/Cosmos.ts b/src/families/cosmos/api/Cosmos.ts index a0f05d798a..ff6f1102dd 100644 --- a/src/families/cosmos/api/Cosmos.ts +++ b/src/families/cosmos/api/Cosmos.ts @@ -265,7 +265,8 @@ export const simulate = async (tx_bytes: Array): Promise => { try { const { data } = await network({ method: "POST", - url: `${defaultEndpoint}/cosmos/tx/v1beta1/simulate`, + // url: `${defaultEndpoint}/cosmos/tx/v1beta1/simulate`, // FIXME LL-9159 + url: `https://node.atomscan.com/cosmos/tx/v1beta1/simulate`, data: { tx_bytes: tx_bytes, }, From b120a7663f6593093d06fcf0bdba9bb811d8db42 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Mon, 31 Jan 2022 16:20:43 +0100 Subject: [PATCH 06/48] fix amount payload --- src/families/cosmos/js-buildTransaction.ts | 40 +++++++++------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/src/families/cosmos/js-buildTransaction.ts b/src/families/cosmos/js-buildTransaction.ts index 14a74292f5..0f777b054b 100644 --- a/src/families/cosmos/js-buildTransaction.ts +++ b/src/families/cosmos/js-buildTransaction.ts @@ -62,12 +62,10 @@ const buildTransaction = async ( value: { delegatorAddress: account.freshAddress, validatorAddress: validator.address, - amount: [ - { - denom: account.currency.units[1].code, - amount: validator.amount.toString(), - }, - ], + amount: { + denom: account.currency.units[1].code, + amount: validator.amount.toString(), + }, }, }); }); @@ -88,12 +86,10 @@ const buildTransaction = async ( value: { delegatorAddress: account.freshAddress, validatorAddress: transaction.validators[0].address, - amount: [ - { - denom: account.currency.units[1].code, - amount: transaction.validators[0].amount.toString(), - }, - ], + amount: { + denom: account.currency.units[1].code, + amount: transaction.validators[0].amount.toString(), + }, }, }); } @@ -115,12 +111,10 @@ const buildTransaction = async ( validatorSrcAddress: transaction.cosmosSourceValidator, delegatorAddress: account.freshAddress, validatorAddress: transaction.validators[0].address, - amount: [ - { - denom: account.currency.units[1].code, - amount: transaction.validators[0].amount.toString(), - }, - ], + amount: { + denom: account.currency.units[1].code, + amount: transaction.validators[0].amount.toString(), + }, }, }); } @@ -166,12 +160,10 @@ const buildTransaction = async ( value: { delegatorAddress: account.freshAddress, validatorAddress: transaction.validators[0].address, - amount: [ - { - denom: account.currency.units[1].code, - amount: transaction.validators[0].amount.toString(), - }, - ], + amount: { + denom: account.currency.units[1].code, + amount: transaction.validators[0].amount.toString(), + }, }, }); } From aaa9494f26c2229c8b549345024cf0195cdab4ae Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Mon, 31 Jan 2022 17:36:14 +0100 Subject: [PATCH 07/48] fix fees/gas calculation --- src/env.ts | 2 +- src/families/cosmos/js-buildTransaction.ts | 2 +- src/families/cosmos/js-prepareTransaction.ts | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/env.ts b/src/env.ts index 7055907f62..b67d344118 100644 --- a/src/env.ts +++ b/src/env.ts @@ -156,7 +156,7 @@ const envDefinitions = { desc: "location of the compound API", }, COSMOS_GAS_AMPLIFIER: { - def: 1.8, + def: 1.4, parser: intParser, desc: "estimate gas multiplier", }, diff --git a/src/families/cosmos/js-buildTransaction.ts b/src/families/cosmos/js-buildTransaction.ts index 0f777b054b..7a311205a2 100644 --- a/src/families/cosmos/js-buildTransaction.ts +++ b/src/families/cosmos/js-buildTransaction.ts @@ -9,7 +9,7 @@ const buildTransaction = async ( account: Account, transaction: Transaction ): Promise => { - const defaultGas = new BigNumber(60000); + const defaultGas = new BigNumber(250000); const defaultFees = new BigNumber(2500); const { sequence } = await getAccount(account.freshAddress); diff --git a/src/families/cosmos/js-prepareTransaction.ts b/src/families/cosmos/js-prepareTransaction.ts index c74da18943..57d3e905bb 100644 --- a/src/families/cosmos/js-prepareTransaction.ts +++ b/src/families/cosmos/js-prepareTransaction.ts @@ -67,11 +67,12 @@ const prepareTransaction = async ( const gasPrice = new BigNumber(getEnv("COSMOS_GAS_PRICE")); - transaction.gas = new BigNumber(simulation?.gas_info?.gas_used || 60000); + transaction.gas = new BigNumber(simulation?.gas_info?.gas_used) + .multipliedBy(new BigNumber(getEnv("COSMOS_GAS_AMPLIFIER"))) + .integerValue(BigNumber.ROUND_CEIL); transaction.fees = gasPrice .multipliedBy(transaction.gas) - .multipliedBy(new BigNumber(getEnv("COSMOS_GAS_AMPLIFIER"))) .integerValue(BigNumber.ROUND_CEIL); return transaction; From 67a44147979f94fb80286ed509ef416cfd68f9fd Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Tue, 1 Feb 2022 13:32:27 +0100 Subject: [PATCH 08/48] fix signature fix public key when account is derivate --- src/families/cosmos/js-buildTransaction.ts | 7 +++++-- src/families/cosmos/js-signOperation.ts | 8 +++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/families/cosmos/js-buildTransaction.ts b/src/families/cosmos/js-buildTransaction.ts index 7a311205a2..42b58d4187 100644 --- a/src/families/cosmos/js-buildTransaction.ts +++ b/src/families/cosmos/js-buildTransaction.ts @@ -7,7 +7,8 @@ import BigNumber from "bignumber.js"; const buildTransaction = async ( account: Account, - transaction: Transaction + transaction: Transaction, + pubKey?: string ): Promise => { const defaultGas = new BigNumber(250000); const defaultFees = new BigNumber(2500); @@ -16,7 +17,9 @@ const buildTransaction = async ( const pubkey = encodePubkey({ type: "tendermint/PubKeySecp256k1", - value: Buffer.from(account.seedIdentifier, "hex").toString("base64"), + value: Buffer.from(pubKey || account.seedIdentifier, "hex").toString( + "base64" + ), }); const msg: Array<{ typeUrl: string; value: any }> = []; diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index f28e4faec1..fe7fc61c14 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -57,7 +57,13 @@ const signOperation = ({ o.next({ type: "device-signature-requested" }); - const unsignedPayload = await buildTransaction(account, transaction); + const accounts = await ledgerSigner.getAccounts(); + + const unsignedPayload = await buildTransaction( + account, + transaction, + Buffer.from(accounts[0].pubkey).toString("hex") + ); const msgs = unsignedPayload.messages.map((msg) => aminoTypes.toAmino(msg) From 75bd779e67d25cd9ae55cb64e46ae266c3353d44 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Thu, 3 Feb 2022 11:37:06 +0100 Subject: [PATCH 09/48] fix fees regression --- src/families/cosmos/js-prepareTransaction.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/families/cosmos/js-prepareTransaction.ts b/src/families/cosmos/js-prepareTransaction.ts index 57d3e905bb..e4868a64bc 100644 --- a/src/families/cosmos/js-prepareTransaction.ts +++ b/src/families/cosmos/js-prepareTransaction.ts @@ -67,7 +67,7 @@ const prepareTransaction = async ( const gasPrice = new BigNumber(getEnv("COSMOS_GAS_PRICE")); - transaction.gas = new BigNumber(simulation?.gas_info?.gas_used) + transaction.gas = new BigNumber(simulation?.gas_info?.gas_used || 60000) .multipliedBy(new BigNumber(getEnv("COSMOS_GAS_AMPLIFIER"))) .integerValue(BigNumber.ROUND_CEIL); From 014b551c4ba5ca253f94f408ab014e30544fb6a8 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Thu, 3 Feb 2022 18:08:21 +0100 Subject: [PATCH 10/48] More accurate pubkey selection --- src/families/cosmos/js-signOperation.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index fe7fc61c14..da39c86856 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -59,6 +59,14 @@ const signOperation = ({ const accounts = await ledgerSigner.getAccounts(); + let pubkey; + + accounts.forEach((a) => { + if (a.address == account.freshAddress) { + pubkey = accounts[0].pubkey; + } + }); + const unsignedPayload = await buildTransaction( account, transaction, From bed90f039b99df3e49f818356844aa7efd33ac74 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Thu, 3 Feb 2022 18:08:45 +0100 Subject: [PATCH 11/48] don't use extra.tx_bytes --- src/families/cosmos/api/Cosmos.ts | 4 +- src/families/cosmos/js-signOperation.ts | 49 +++++++++++-------------- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/families/cosmos/api/Cosmos.ts b/src/families/cosmos/api/Cosmos.ts index ff6f1102dd..62b72eeef5 100644 --- a/src/families/cosmos/api/Cosmos.ts +++ b/src/families/cosmos/api/Cosmos.ts @@ -222,14 +222,14 @@ export const getTransactions = async (address: string): Promise => { }; export const broadcast = async ({ - signedOperation: { operation }, + signedOperation: { operation, signature }, }): Promise => { const { data } = await network({ method: "POST", // url: `${defaultEndpoint}/cosmos/tx/v1beta1/txs`, // FIXME LL-9159 url: `https://node.atomscan.com/cosmos/tx/v1beta1/txs`, data: { - tx_bytes: operation.extra.tx_bytes, + tx_bytes: Array.from(Uint8Array.from(Buffer.from(signature, "hex"))), mode: "BROADCAST_MODE_SYNC", }, }); diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index da39c86856..f9edaffd29 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -70,7 +70,7 @@ const signOperation = ({ const unsignedPayload = await buildTransaction( account, transaction, - Buffer.from(accounts[0].pubkey).toString("hex") + Buffer.from(pubkey || null).toString("hex") ); const msgs = unsignedPayload.messages.map((msg) => @@ -83,25 +83,22 @@ const signOperation = ({ // Cosmos API expects a different sorting, resulting in a separate signature. // https://github.com/LedgerHQ/app-cosmos/blob/6c194daa28936e273f9548eabca9e72ba04bb632/app/src/tx_parser.c#L52 - const { signature } = await ledgerSigner.signAmino( - account.freshAddress, - { - chain_id: chainId, - account_number: accountNumber.toString(), - sequence: sequence.toString(), - fee: { - amount: [ - { - denom: account.currency.units[1].code, - amount: transaction.fees?.toString() as string, - }, - ], - gas: transaction.gas?.toString() as string, - }, - msgs: msgs, - memo: transaction.memo || "", - } - ); + const signed = await ledgerSigner.signAmino(account.freshAddress, { + chain_id: chainId, + account_number: accountNumber.toString(), + sequence: sequence.toString(), + fee: { + amount: [ + { + denom: account.currency.units[1].code, + amount: transaction.fees?.toString() as string, + }, + ], + gas: transaction.gas?.toString() as string, + }, + msgs: msgs, + memo: transaction.memo || "", + }); const txBodyFields: TxBodyEncodeObject = { typeUrl: "/cosmos.tx.v1beta1.TxBody", @@ -116,13 +113,13 @@ const signOperation = ({ bodyBytes: txBodyBytes, authInfoBytes: unsignedPayload.auth, signatures: [ - new Uint8Array(Buffer.from(signature.signature, "base64")), + new Uint8Array(Buffer.from(signed.signature.signature, "base64")), ], }); - const tx_bytes = Array.from( - Uint8Array.from(TxRaw.encode(txRaw).finish()) - ); + const signature = Buffer.from( + Array.from(Uint8Array.from(TxRaw.encode(txRaw).finish())) + ).toString("hex"); if (cancelled) { return; @@ -142,9 +139,7 @@ const signOperation = ({ type: "OUT", value: transaction.amount, fee: transaction.fees, - extra: { - tx_bytes: tx_bytes, - }, + extra: {}, blockHash: null, blockHeight: null, senders, From 4faf89dc14ed0c8fcadf603c1412100c905cb3cd Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Thu, 3 Feb 2022 18:21:02 +0100 Subject: [PATCH 12/48] fix pubkey selection --- src/families/cosmos/js-signOperation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index f9edaffd29..0fc93686ce 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -63,7 +63,7 @@ const signOperation = ({ accounts.forEach((a) => { if (a.address == account.freshAddress) { - pubkey = accounts[0].pubkey; + pubkey = a.pubkey; } }); From a49d4ffa1e299bdc7ff6efb55a17fb06acebcac3 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Fri, 4 Feb 2022 11:35:17 +0100 Subject: [PATCH 13/48] simplify hex serialization --- src/families/cosmos/js-signOperation.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index 0fc93686ce..02276e625f 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -117,9 +117,9 @@ const signOperation = ({ ], }); - const signature = Buffer.from( - Array.from(Uint8Array.from(TxRaw.encode(txRaw).finish())) - ).toString("hex"); + const signature = Buffer.from(TxRaw.encode(txRaw).finish()).toString( + "hex" + ); if (cancelled) { return; From e8ad8f3141c1076e01706f0a8590edbac5619b18 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Thu, 10 Feb 2022 22:02:47 +0100 Subject: [PATCH 14/48] update transaction: more strict types --- src/families/cosmos/js-updateTransaction.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/families/cosmos/js-updateTransaction.ts b/src/families/cosmos/js-updateTransaction.ts index d2d6d673d3..cab42dd6b1 100644 --- a/src/families/cosmos/js-updateTransaction.ts +++ b/src/families/cosmos/js-updateTransaction.ts @@ -1,11 +1,16 @@ -const updateTransaction = (t, patch) => { +import { Transaction } from "./types"; + +const updateTransaction = ( + t: Transaction, + patch: Partial +): Transaction => { if ("mode" in patch && patch.mode !== t.mode) { return { ...t, ...patch, gas: null, fees: null }; } if ( "validators" in patch && - patch.validators.length !== t.validators.length + patch.validators?.length !== t.validators.length ) { return { ...t, ...patch, gas: null, fees: null }; } From a03fd8fc8671ae8e87da0dd556fb833a99598e49 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Thu, 10 Feb 2022 22:04:45 +0100 Subject: [PATCH 15/48] many things restruct operation builder simulate now return int prepareTransaction use patch format --- src/families/cosmos/api/Cosmos.ts | 6 +- src/families/cosmos/js-buildTransaction.ts | 39 +------- src/families/cosmos/js-prepareTransaction.ts | 99 +++++++++++++------- src/families/cosmos/js-signOperation.ts | 39 +++++--- 4 files changed, 102 insertions(+), 81 deletions(-) diff --git a/src/families/cosmos/api/Cosmos.ts b/src/families/cosmos/api/Cosmos.ts index 62b72eeef5..bafaeaa458 100644 --- a/src/families/cosmos/api/Cosmos.ts +++ b/src/families/cosmos/api/Cosmos.ts @@ -261,7 +261,7 @@ export const getBlock = async (height: number): Promise => { } }; -export const simulate = async (tx_bytes: Array): Promise => { +export const simulate = async (tx_bytes: Array): Promise => { try { const { data } = await network({ method: "POST", @@ -272,9 +272,9 @@ export const simulate = async (tx_bytes: Array): Promise => { }, }); - return data; + return data?.gas_info?.gas_used || 0; } catch (e) { - return undefined; + return 0; } }; diff --git a/src/families/cosmos/js-buildTransaction.ts b/src/families/cosmos/js-buildTransaction.ts index 42b58d4187..fae6e18eb2 100644 --- a/src/families/cosmos/js-buildTransaction.ts +++ b/src/families/cosmos/js-buildTransaction.ts @@ -1,27 +1,10 @@ import { Account } from "../../types"; import { Transaction } from "./types"; -import { getAccount } from "./api/Cosmos"; -import { encodePubkey, makeAuthInfoBytes } from "@cosmjs/proto-signing"; -import { SignMode } from "cosmjs-types/cosmos/tx/signing/v1beta1/signing"; -import BigNumber from "bignumber.js"; const buildTransaction = async ( account: Account, - transaction: Transaction, - pubKey?: string + transaction: Transaction ): Promise => { - const defaultGas = new BigNumber(250000); - const defaultFees = new BigNumber(2500); - - const { sequence } = await getAccount(account.freshAddress); - - const pubkey = encodePubkey({ - type: "tendermint/PubKeySecp256k1", - value: Buffer.from(pubKey || account.seedIdentifier, "hex").toString( - "base64" - ), - }); - const msg: Array<{ typeUrl: string; value: any }> = []; // Ledger Live is able to build transaction atomically, @@ -173,23 +156,11 @@ const buildTransaction = async ( break; } - const authInfoBytes = makeAuthInfoBytes( - [{ pubkey, sequence }], - [ - { - amount: transaction.fees?.toString() || defaultFees.toString(), - denom: account.currency.units[1].code, - }, - ], - transaction.gas?.toNumber() || defaultGas.toNumber(), - SignMode.SIGN_MODE_LEGACY_AMINO_JSON - ); + if (!isComplete) { + return []; + } - return { - messages: msg, - auth: authInfoBytes, - isComplete, - }; + return msg; }; export default buildTransaction; diff --git a/src/families/cosmos/js-prepareTransaction.ts b/src/families/cosmos/js-prepareTransaction.ts index e4868a64bc..b48b8ef405 100644 --- a/src/families/cosmos/js-prepareTransaction.ts +++ b/src/families/cosmos/js-prepareTransaction.ts @@ -1,8 +1,14 @@ import { Account } from "../../types"; import { Transaction } from "./types"; import BigNumber from "bignumber.js"; -import { simulate } from "./api/Cosmos"; -import { Registry, TxBodyEncodeObject } from "@cosmjs/proto-signing"; +import { getAccount, simulate } from "./api/Cosmos"; +import { + encodePubkey, + makeAuthInfoBytes, + Registry, + TxBodyEncodeObject, +} from "@cosmjs/proto-signing"; +import { SignMode } from "cosmjs-types/cosmos/tx/signing/v1beta1/signing"; import { TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx"; import { MsgDelegate, @@ -18,8 +24,13 @@ const prepareTransaction = async ( account: Account, transaction: Transaction ): Promise => { + const patch: Partial = {}; + + let gasQty = new BigNumber(250000); + const gasPrice = new BigNumber(getEnv("COSMOS_GAS_PRICE")); + if (transaction.useAllAmount) { - transaction.amount = getMaxEstimatedBalance( + patch.amount = getMaxEstimatedBalance( account, account.balance .dividedBy(new BigNumber(getEnv("COSMOS_GAS_AMPLIFIER"))) @@ -28,54 +39,76 @@ const prepareTransaction = async ( } if (transaction.mode !== "send" && !transaction.memo) { - transaction.memo = "Ledger Live"; + patch.memo = "Ledger Live"; } const unsignedPayload = await buildTransaction(account, transaction); // be sure payload is complete - if (!unsignedPayload.isComplete) return transaction; + if (unsignedPayload) { + const txBodyFields: TxBodyEncodeObject = { + typeUrl: "/cosmos.tx.v1beta1.TxBody", + value: { + messages: unsignedPayload, + }, + }; - const txBodyFields: TxBodyEncodeObject = { - typeUrl: "/cosmos.tx.v1beta1.TxBody", - value: { - messages: unsignedPayload.messages, - }, - }; + const registry = new Registry([ + ["/cosmos.staking.v1beta1.MsgDelegate", MsgDelegate], + ["/cosmos.staking.v1beta1.MsgUndelegate", MsgUndelegate], + ["/cosmos.staking.v1beta1.MsgBeginRedelegate", MsgBeginRedelegate], + [ + "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", + MsgWithdrawDelegatorReward, + ], + ]); - const registry = new Registry([ - ["/cosmos.staking.v1beta1.MsgDelegate", MsgDelegate], - ["/cosmos.staking.v1beta1.MsgUndelegate", MsgUndelegate], - ["/cosmos.staking.v1beta1.MsgBeginRedelegate", MsgBeginRedelegate], - [ - "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", - MsgWithdrawDelegatorReward, - ], - ]); + const { sequence } = await getAccount(account.freshAddress); - const txBodyBytes = registry.encode(txBodyFields); + const pubkey = encodePubkey({ + type: "tendermint/PubKeySecp256k1", + value: Buffer.from(account.seedIdentifier, "hex").toString("base64"), + }); - const txRaw = TxRaw.fromPartial({ - bodyBytes: txBodyBytes, - authInfoBytes: unsignedPayload.auth, - signatures: [new Uint8Array(Buffer.from(account.seedIdentifier, "hex"))], - }); + const txBodyBytes = registry.encode(txBodyFields); - const tx_bytes = Array.from(Uint8Array.from(TxRaw.encode(txRaw).finish())); + const authInfoBytes = makeAuthInfoBytes( + [{ pubkey, sequence }], + [ + { + amount: + transaction.fees?.toString() || new BigNumber(2500).toString(), + denom: account.currency.units[1].code, + }, + ], + transaction.gas?.toNumber() || new BigNumber(250000).toNumber(), + SignMode.SIGN_MODE_LEGACY_AMINO_JSON + ); - const simulation = await simulate(tx_bytes); + const txRaw = TxRaw.fromPartial({ + bodyBytes: txBodyBytes, + authInfoBytes, + signatures: [new Uint8Array(Buffer.from(account.seedIdentifier, "hex"))], + }); - const gasPrice = new BigNumber(getEnv("COSMOS_GAS_PRICE")); + const tx_bytes = Array.from(Uint8Array.from(TxRaw.encode(txRaw).finish())); + + const gasUsed = await simulate(tx_bytes); + + if (gasUsed) { + gasQty = new BigNumber(gasUsed); + } + } - transaction.gas = new BigNumber(simulation?.gas_info?.gas_used || 60000) + patch.gas = gasQty .multipliedBy(new BigNumber(getEnv("COSMOS_GAS_AMPLIFIER"))) .integerValue(BigNumber.ROUND_CEIL); - transaction.fees = gasPrice - .multipliedBy(transaction.gas) + patch.fees = gasPrice + .multipliedBy(patch.gas) .integerValue(BigNumber.ROUND_CEIL); - return transaction; + return { ...transaction, ...patch }; }; export default prepareTransaction; diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index 02276e625f..8092ea0c2c 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -3,7 +3,13 @@ import type { Transaction } from "./types"; import { getAccount, getChainId } from "./api/Cosmos"; import { Observable } from "rxjs"; import { withDevice } from "../../hw/deviceAccess"; -import { Registry, TxBodyEncodeObject } from "@cosmjs/proto-signing"; +import { + encodePubkey, + makeAuthInfoBytes, + Registry, + TxBodyEncodeObject, +} from "@cosmjs/proto-signing"; +import { SignMode } from "cosmjs-types/cosmos/tx/signing/v1beta1/signing"; import { TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx"; import { encodeOperationId } from "../../operation"; import { LedgerSigner } from "@cosmjs/ledger-amino"; @@ -16,6 +22,7 @@ import { MsgBeginRedelegate, } from "cosmjs-types/cosmos/staking/v1beta1/tx"; import { MsgWithdrawDelegatorReward } from "cosmjs-types/cosmos/distribution/v1beta1/tx"; +import BigNumber from "bignumber.js"; const aminoTypes = new AminoTypes({ prefix: "cosmos" }); @@ -63,19 +70,16 @@ const signOperation = ({ accounts.forEach((a) => { if (a.address == account.freshAddress) { - pubkey = a.pubkey; + pubkey = encodePubkey({ + type: "tendermint/PubKeySecp256k1", + value: Buffer.from(a.pubkey).toString("base64"), + }); } }); - const unsignedPayload = await buildTransaction( - account, - transaction, - Buffer.from(pubkey || null).toString("hex") - ); + const unsignedPayload = await buildTransaction(account, transaction); - const msgs = unsignedPayload.messages.map((msg) => - aminoTypes.toAmino(msg) - ); + const msgs = unsignedPayload.map((msg) => aminoTypes.toAmino(msg)); // Note: // We don't use Cosmos App, @@ -109,9 +113,22 @@ const signOperation = ({ const txBodyBytes = registry.encode(txBodyFields); + const authInfoBytes = makeAuthInfoBytes( + [{ pubkey, sequence }], + [ + { + amount: + transaction.fees?.toString() || new BigNumber(2500).toString(), + denom: account.currency.units[1].code, + }, + ], + transaction.gas?.toNumber() || new BigNumber(250000).toNumber(), + SignMode.SIGN_MODE_LEGACY_AMINO_JSON + ); + const txRaw = TxRaw.fromPartial({ bodyBytes: txBodyBytes, - authInfoBytes: unsignedPayload.auth, + authInfoBytes, signatures: [ new Uint8Array(Buffer.from(signed.signature.signature, "base64")), ], From 27947b3bb00af49fdc392a2b852aaf6dc732c03a Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Thu, 10 Feb 2022 23:18:59 +0100 Subject: [PATCH 16/48] accuracy more accuracy int value small refactor --- src/families/cosmos/api/Cosmos.ts | 6 +++--- src/families/cosmos/js-prepareTransaction.ts | 16 +++++++--------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/families/cosmos/api/Cosmos.ts b/src/families/cosmos/api/Cosmos.ts index bafaeaa458..a307d724e0 100644 --- a/src/families/cosmos/api/Cosmos.ts +++ b/src/families/cosmos/api/Cosmos.ts @@ -261,7 +261,7 @@ export const getBlock = async (height: number): Promise => { } }; -export const simulate = async (tx_bytes: Array): Promise => { +export const simulate = async (tx_bytes: Array): Promise => { try { const { data } = await network({ method: "POST", @@ -272,9 +272,9 @@ export const simulate = async (tx_bytes: Array): Promise => { }, }); - return data?.gas_info?.gas_used || 0; + return new BigNumber(data?.gas_info?.gas_used || 0); } catch (e) { - return 0; + return new BigNumber(0); } }; diff --git a/src/families/cosmos/js-prepareTransaction.ts b/src/families/cosmos/js-prepareTransaction.ts index b48b8ef405..79c193b3bc 100644 --- a/src/families/cosmos/js-prepareTransaction.ts +++ b/src/families/cosmos/js-prepareTransaction.ts @@ -34,7 +34,7 @@ const prepareTransaction = async ( account, account.balance .dividedBy(new BigNumber(getEnv("COSMOS_GAS_AMPLIFIER"))) - .integerValue(BigNumber.ROUND_CEIL) + .integerValue() ); } @@ -95,18 +95,16 @@ const prepareTransaction = async ( const gasUsed = await simulate(tx_bytes); - if (gasUsed) { - gasQty = new BigNumber(gasUsed); + if (gasUsed.gt(0)) { + gasQty = gasUsed + .multipliedBy(new BigNumber(getEnv("COSMOS_GAS_AMPLIFIER"))) + .integerValue(); } } - patch.gas = gasQty - .multipliedBy(new BigNumber(getEnv("COSMOS_GAS_AMPLIFIER"))) - .integerValue(BigNumber.ROUND_CEIL); + patch.gas = gasQty; - patch.fees = gasPrice - .multipliedBy(patch.gas) - .integerValue(BigNumber.ROUND_CEIL); + patch.fees = gasPrice.multipliedBy(gasQty).integerValue(); return { ...transaction, ...patch }; }; From 1ea1afeb71febd54081721efbf952383e0ca897c Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Thu, 10 Feb 2022 23:19:15 +0100 Subject: [PATCH 17/48] remove useless isPreValidation --- .../cosmos/js-getTransactionStatus.ts | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/families/cosmos/js-getTransactionStatus.ts b/src/families/cosmos/js-getTransactionStatus.ts index 50d9570ba1..5acce2e087 100644 --- a/src/families/cosmos/js-getTransactionStatus.ts +++ b/src/families/cosmos/js-getTransactionStatus.ts @@ -28,14 +28,13 @@ import { isValidRecipent } from "./api/Cosmos"; export const getTransactionStatus = async ( a: Account, - t: Transaction, - isPreValidation = false + t: Transaction ): Promise => { if (t.mode === "send") { // We isolate the send transaction that it's a little bit different from the rest - return await getSendTransactionStatus(a, t, isPreValidation); + return await getSendTransactionStatus(a, t); } else if (t.mode === "delegate") { - return await getDelegateTransactionStatus(a, t, isPreValidation); + return await getDelegateTransactionStatus(a, t); } const errors: StatusErrorMap = {}; @@ -87,7 +86,7 @@ export const getTransactionStatus = async ( const estimatedFees = t.fees || new BigNumber(0); - if (!isPreValidation && !t.fees) { + if (!t.fees) { errors.fees = new FeeNotLoaded(); } @@ -129,8 +128,7 @@ export const getTransactionStatus = async ( const getDelegateTransactionStatus = async ( a: Account, - t: Transaction, - isPreValidation = false + t: Transaction ): Promise => { const errors: StatusErrorMap = {}; const warnings: StatusErrorMap = {}; @@ -159,7 +157,7 @@ const getDelegateTransactionStatus = async ( const estimatedFees = t.fees || new BigNumber(0); - if (!isPreValidation && !t.fees) { + if (!t.fees) { errors.fees = new FeeNotLoaded(); } @@ -190,8 +188,7 @@ const getDelegateTransactionStatus = async ( const getSendTransactionStatus = async ( a: Account, - t: Transaction, - isPreValidation = false + t: Transaction ): Promise => { const errors: StatusErrorMap = {}; const warnings: StatusErrorMap = {}; @@ -216,7 +213,7 @@ const getSendTransactionStatus = async ( const estimatedFees = t.fees || new BigNumber(0); - if (!isPreValidation && (!t.fees || !t.fees.gt(0))) { + if (!t.fees || !t.fees.gt(0)) { errors.fees = new FeeNotLoaded(); } From f941d0716eb07941a03464666ede284316bf59bd Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Thu, 10 Feb 2022 23:43:22 +0100 Subject: [PATCH 18/48] fix strange edge effect of ledger live desktop --- src/families/cosmos/js-prepareTransaction.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/families/cosmos/js-prepareTransaction.ts b/src/families/cosmos/js-prepareTransaction.ts index 79c193b3bc..319d6a2b4f 100644 --- a/src/families/cosmos/js-prepareTransaction.ts +++ b/src/families/cosmos/js-prepareTransaction.ts @@ -97,7 +97,12 @@ const prepareTransaction = async ( if (gasUsed.gt(0)) { gasQty = gasUsed - .multipliedBy(new BigNumber(getEnv("COSMOS_GAS_AMPLIFIER"))) + // Don't known what is going on, + // Ledger Live Desktop return half of what it should, + // Ledger Live Common CLI do the math correctly. + // Use coeff 2 as trick.. + // .multipliedBy(new BigNumber(getEnv("COSMOS_GAS_AMPLIFIER"))) + .multipliedBy(new BigNumber(getEnv("COSMOS_GAS_AMPLIFIER") * 2)) .integerValue(); } } From cda9bc1ccc18458c93823e958e319739a3ec04fd Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Mon, 14 Feb 2022 10:11:12 +0100 Subject: [PATCH 19/48] Update xpub during sync --- src/families/cosmos/js-synchronisation.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/families/cosmos/js-synchronisation.ts b/src/families/cosmos/js-synchronisation.ts index df943a5c27..33e7629267 100644 --- a/src/families/cosmos/js-synchronisation.ts +++ b/src/families/cosmos/js-synchronisation.ts @@ -165,6 +165,7 @@ export const getAccountShape: GetAccountShape = async (info) => { const shape = { id: accountId, + xpub: xpubOrAddress, balance: balance, spendableBalance, operationsCount: operations.length, From d65266d7967bf6ea0e6fd43fbf00d31115cd0441 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Mon, 14 Feb 2022 10:34:57 +0100 Subject: [PATCH 20/48] temporary enable log for bot --- src/families/cosmos/js-signOperation.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index 8092ea0c2c..1d1461d17f 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -23,6 +23,7 @@ import { } from "cosmjs-types/cosmos/staking/v1beta1/tx"; import { MsgWithdrawDelegatorReward } from "cosmjs-types/cosmos/distribution/v1beta1/tx"; import BigNumber from "bignumber.js"; +import { log } from "@ledgerhq/logs"; const aminoTypes = new AminoTypes({ prefix: "cosmos" }); @@ -68,8 +69,12 @@ const signOperation = ({ let pubkey; + log("engine", "look for pubkey for address", account.freshAddress); + log("engine", "path", account.freshAddressPath); + accounts.forEach((a) => { if (a.address == account.freshAddress) { + log("engine", "found pubkey with same address"); pubkey = encodePubkey({ type: "tendermint/PubKeySecp256k1", value: Buffer.from(a.pubkey).toString("base64"), From 8df4111eb045ea874124ebcf4731a2d23ac1855a Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Wed, 16 Feb 2022 17:21:14 +0100 Subject: [PATCH 21/48] LL-9159 cosmos node --- src/families/cosmos/api/Cosmos.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/families/cosmos/api/Cosmos.ts b/src/families/cosmos/api/Cosmos.ts index a307d724e0..28248d75ec 100644 --- a/src/families/cosmos/api/Cosmos.ts +++ b/src/families/cosmos/api/Cosmos.ts @@ -226,8 +226,7 @@ export const broadcast = async ({ }): Promise => { const { data } = await network({ method: "POST", - // url: `${defaultEndpoint}/cosmos/tx/v1beta1/txs`, // FIXME LL-9159 - url: `https://node.atomscan.com/cosmos/tx/v1beta1/txs`, + url: `${defaultEndpoint}/cosmos/tx/v1beta1/txs`, data: { tx_bytes: Array.from(Uint8Array.from(Buffer.from(signature, "hex"))), mode: "BROADCAST_MODE_SYNC", @@ -265,8 +264,7 @@ export const simulate = async (tx_bytes: Array): Promise => { try { const { data } = await network({ method: "POST", - // url: `${defaultEndpoint}/cosmos/tx/v1beta1/simulate`, // FIXME LL-9159 - url: `https://node.atomscan.com/cosmos/tx/v1beta1/simulate`, + url: `${defaultEndpoint}/cosmos/tx/v1beta1/simulate`, data: { tx_bytes: tx_bytes, }, From 804fccd2f987318cf987b8beed227a3fe85f1805 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Wed, 16 Feb 2022 17:21:39 +0100 Subject: [PATCH 22/48] Update js-signOperation.ts revert back test trace for bot --- src/families/cosmos/js-signOperation.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index 1d1461d17f..8092ea0c2c 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -23,7 +23,6 @@ import { } from "cosmjs-types/cosmos/staking/v1beta1/tx"; import { MsgWithdrawDelegatorReward } from "cosmjs-types/cosmos/distribution/v1beta1/tx"; import BigNumber from "bignumber.js"; -import { log } from "@ledgerhq/logs"; const aminoTypes = new AminoTypes({ prefix: "cosmos" }); @@ -69,12 +68,8 @@ const signOperation = ({ let pubkey; - log("engine", "look for pubkey for address", account.freshAddress); - log("engine", "path", account.freshAddressPath); - accounts.forEach((a) => { if (a.address == account.freshAddress) { - log("engine", "found pubkey with same address"); pubkey = encodePubkey({ type: "tendermint/PubKeySecp256k1", value: Buffer.from(a.pubkey).toString("base64"), From 35ecf590ddf3cca6bad52edc08baf8c9c9d7099d Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Wed, 16 Feb 2022 18:27:57 +0100 Subject: [PATCH 23/48] fix signature --- src/families/cosmos/js-prepareTransaction.ts | 1 + src/families/cosmos/js-signOperation.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/families/cosmos/js-prepareTransaction.ts b/src/families/cosmos/js-prepareTransaction.ts index 319d6a2b4f..100c1be426 100644 --- a/src/families/cosmos/js-prepareTransaction.ts +++ b/src/families/cosmos/js-prepareTransaction.ts @@ -50,6 +50,7 @@ const prepareTransaction = async ( typeUrl: "/cosmos.tx.v1beta1.TxBody", value: { messages: unsignedPayload, + memo: transaction.memo || patch.memo || "", }, }; diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index 8092ea0c2c..678b57c7ff 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -108,6 +108,7 @@ const signOperation = ({ typeUrl: "/cosmos.tx.v1beta1.TxBody", value: { messages: msgs.map((msg) => aminoTypes.fromAmino(msg)), + memo: transaction.memo || "", }, }; From 99dc4885503547fa61970fc1b5df240da140b2dc Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Thu, 17 Feb 2022 17:22:11 +0100 Subject: [PATCH 24/48] fix redelegate payload --- src/families/cosmos/js-buildTransaction.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/families/cosmos/js-buildTransaction.ts b/src/families/cosmos/js-buildTransaction.ts index fae6e18eb2..c9e3b5e85b 100644 --- a/src/families/cosmos/js-buildTransaction.ts +++ b/src/families/cosmos/js-buildTransaction.ts @@ -96,7 +96,7 @@ const buildTransaction = async ( value: { validatorSrcAddress: transaction.cosmosSourceValidator, delegatorAddress: account.freshAddress, - validatorAddress: transaction.validators[0].address, + validatorDstAddress: transaction.validators[0].address, amount: { denom: account.currency.units[1].code, amount: transaction.validators[0].amount.toString(), From 1800f029defdec5f7d302611324805a765bf60c7 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Thu, 17 Feb 2022 17:35:54 +0100 Subject: [PATCH 25/48] fix payload send transaction when sendmax --- src/families/cosmos/js-prepareTransaction.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/families/cosmos/js-prepareTransaction.ts b/src/families/cosmos/js-prepareTransaction.ts index 100c1be426..0bc88f1eb7 100644 --- a/src/families/cosmos/js-prepareTransaction.ts +++ b/src/families/cosmos/js-prepareTransaction.ts @@ -42,7 +42,10 @@ const prepareTransaction = async ( patch.memo = "Ledger Live"; } - const unsignedPayload = await buildTransaction(account, transaction); + const unsignedPayload = await buildTransaction(account, { + ...transaction, + ...patch, + }); // be sure payload is complete if (unsignedPayload) { From 3aca833984a04b5a734741d089f2860028ec6204 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Fri, 18 Feb 2022 11:34:48 +0100 Subject: [PATCH 26/48] fix optimistic operation type --- src/families/cosmos/js-signOperation.ts | 31 +++++++++++++++---------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index 678b57c7ff..770536cc4b 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -1,4 +1,4 @@ -import { Account, SignOperationEvent } from "../../types"; +import { Account, OperationType, SignOperationEvent } from "../../types"; import type { Transaction } from "./types"; import { getAccount, getChainId } from "./api/Cosmos"; import { Observable } from "rxjs"; @@ -145,24 +145,31 @@ const signOperation = ({ o.next({ type: "device-signature-granted" }); - // build optimistic operation - const txHash = ""; // resolved at broadcast time - const senders = [account.freshAddress]; - const recipients = [transaction.recipient]; - const accountId = account.id; + const txhash = ""; // resolved at broadcast time + const type: OperationType = + transaction.mode === "undelegate" + ? "UNDELEGATE" + : transaction.mode === "delegate" + ? "DELEGATE" + : transaction.mode === "redelegate" + ? "REDELEGATE" + : ["claimReward", "claimRewardCompound"].includes(transaction.mode) + ? "REWARD" + : "OUT"; + // build optimistic operation const operation = { - id: encodeOperationId(accountId, txHash, "OUT"), - hash: txHash, - type: "OUT", + id: encodeOperationId(account.id, txhash, type), + hash: txhash, + type: transaction.mode, value: transaction.amount, fee: transaction.fees, extra: {}, blockHash: null, blockHeight: null, - senders, - recipients, - accountId, + senders: [account.freshAddress], + recipients: [transaction.recipient], + account: account.id, date: new Date(), }; From e7fd38b120fce22a78c75185bc35eab5f37b9aa9 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Fri, 18 Feb 2022 11:54:59 +0100 Subject: [PATCH 27/48] fix typo --- src/families/cosmos/js-signOperation.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index 770536cc4b..0fe93bb7c9 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -145,7 +145,7 @@ const signOperation = ({ o.next({ type: "device-signature-granted" }); - const txhash = ""; // resolved at broadcast time + const txHash = ""; // resolved at broadcast time const type: OperationType = transaction.mode === "undelegate" ? "UNDELEGATE" @@ -159,8 +159,8 @@ const signOperation = ({ // build optimistic operation const operation = { - id: encodeOperationId(account.id, txhash, type), - hash: txhash, + id: encodeOperationId(account.id, txHash, type), + hash: txHash, type: transaction.mode, value: transaction.amount, fee: transaction.fees, From c7a0e69850f647c3e6795d536d2b168ca69d5652 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Fri, 18 Feb 2022 13:10:18 +0100 Subject: [PATCH 28/48] bugfix --- src/families/cosmos/js-signOperation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index 0fe93bb7c9..c045ac5b2d 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -161,7 +161,7 @@ const signOperation = ({ const operation = { id: encodeOperationId(account.id, txHash, type), hash: txHash, - type: transaction.mode, + type: type, value: transaction.amount, fee: transaction.fees, extra: {}, From b64368e8edf49a0c6006e962ccbb438f23f4b9a5 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Fri, 18 Feb 2022 13:43:15 +0100 Subject: [PATCH 29/48] fix regression --- src/families/cosmos/js-signOperation.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index c045ac5b2d..f427f402b3 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -146,6 +146,7 @@ const signOperation = ({ o.next({ type: "device-signature-granted" }); const txHash = ""; // resolved at broadcast time + const accountId = account.id; const type: OperationType = transaction.mode === "undelegate" ? "UNDELEGATE" @@ -159,7 +160,7 @@ const signOperation = ({ // build optimistic operation const operation = { - id: encodeOperationId(account.id, txHash, type), + id: encodeOperationId(accountId, txHash, type), hash: txHash, type: type, value: transaction.amount, @@ -169,7 +170,7 @@ const signOperation = ({ blockHeight: null, senders: [account.freshAddress], recipients: [transaction.recipient], - account: account.id, + account: accountId, date: new Date(), }; From 992193f13c7722b7a136b5f4622870d164f9064d Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Fri, 18 Feb 2022 15:40:14 +0100 Subject: [PATCH 30/48] update optimistic operation fix regression add operation type more consistent fee --- src/families/cosmos/js-signOperation.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index f427f402b3..8180bc1e09 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -1,4 +1,4 @@ -import { Account, OperationType, SignOperationEvent } from "../../types"; +import { Account, Operation, OperationType, SignOperationEvent } from "../../types"; import type { Transaction } from "./types"; import { getAccount, getChainId } from "./api/Cosmos"; import { Observable } from "rxjs"; @@ -159,18 +159,18 @@ const signOperation = ({ : "OUT"; // build optimistic operation - const operation = { + const operation: Operation = { id: encodeOperationId(accountId, txHash, type), hash: txHash, type: type, value: transaction.amount, - fee: transaction.fees, + fee: transaction.fees || new BigNumber(0), extra: {}, blockHash: null, blockHeight: null, senders: [account.freshAddress], recipients: [transaction.recipient], - account: accountId, + accountId: accountId, date: new Date(), }; From 71ea6f8b97effdea9c7aa741e87028fa1fe4795f Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Fri, 18 Feb 2022 16:18:51 +0100 Subject: [PATCH 31/48] fix prettier --- src/families/cosmos/js-signOperation.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index 8180bc1e09..55522f7be0 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -1,4 +1,9 @@ -import { Account, Operation, OperationType, SignOperationEvent } from "../../types"; +import { + Account, + Operation, + OperationType, + SignOperationEvent, +} from "../../types"; import type { Transaction } from "./types"; import { getAccount, getChainId } from "./api/Cosmos"; import { Observable } from "rxjs"; From e0f4fce74545fdb7b3e955432e435e56d5ccd709 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Fri, 18 Feb 2022 16:19:34 +0100 Subject: [PATCH 32/48] more deterministic transaction parsing --- src/families/cosmos/js-synchronisation.ts | 104 ++++++++++++++-------- 1 file changed, 67 insertions(+), 37 deletions(-) diff --git a/src/families/cosmos/js-synchronisation.ts b/src/families/cosmos/js-synchronisation.ts index 33e7629267..79ca7a8aba 100644 --- a/src/families/cosmos/js-synchronisation.ts +++ b/src/families/cosmos/js-synchronisation.ts @@ -42,56 +42,86 @@ const txToOps = (info: any, id: string, txs: any): Operation[] => { // https://docs.cosmos.network/v0.42/modules/staking/07_events.html switch (message.type) { case "transfer": - op.senders.push(attributes["sender"]); - op.recipients.push(attributes["recipient"]); - - op.value = op.value.plus( - attributes["amount"].replace(currency.units[1].code, "") - ); - - if (attributes["sender"] === address) { - op.type = "OUT"; - op.value = op.value.plus(fees); - } else if (attributes["recipient"] === address) { - op.type = "IN"; + if ( + attributes["sender"] && + attributes["recipient"] && + attributes["amount"] && + attributes["amount"].indexOf(currency.units[1].code) != -1 + ) { + op.senders.push(attributes["sender"]); + op.recipients.push(attributes["recipient"]); + + op.value = op.value.plus( + attributes["amount"].replace(currency.units[1].code, "") + ); + + if (attributes["sender"] === address) { + op.type = "OUT"; + op.value = op.value.plus(fees); + } else if (attributes["recipient"] === address) { + op.type = "IN"; + } } break; case "withdraw_rewards": - op.type = "REWARD"; - op.value = new BigNumber(fees); - op.extra.validators.push({ - amount: attributes["amount"].replace(currency.units[1].code, ""), - address: attributes.validator, - }); + if ( + attributes["amount"] && + attributes["amount"].indexOf(currency.units[1].code) != -1 + ) { + op.type = "REWARD"; + op.value = new BigNumber(fees); + op.extra.validators.push({ + amount: attributes["amount"].replace(currency.units[1].code, ""), + address: attributes.validator, + }); + } break; case "delegate": - op.type = "DELEGATE"; - op.value = new BigNumber(fees); - op.extra.validators.push({ - amount: attributes["amount"].replace(currency.units[1].code, ""), - address: attributes.validator, - }); + if ( + attributes["amount"] && + attributes["amount"].indexOf(currency.units[1].code) != -1 + ) { + op.type = "DELEGATE"; + op.value = new BigNumber(fees); + op.extra.validators.push({ + amount: attributes["amount"].replace(currency.units[1].code, ""), + address: attributes.validator, + }); + } break; case "redelegate": - op.type = "REDELEGATE"; - op.value = new BigNumber(fees); - op.extra.validators.push({ - amount: attributes["amount"].replace(currency.units[1].code, ""), - address: attributes.destination_validator, - }); - op.extra.cosmosSourceValidator = attributes.source_validator; + if ( + attributes["amount"] && + attributes["amount"].indexOf(currency.units[1].code) != -1 && + attributes.destination_validator && + attributes.source_validator + ) { + op.type = "REDELEGATE"; + op.value = new BigNumber(fees); + op.extra.validators.push({ + amount: attributes["amount"].replace(currency.units[1].code, ""), + address: attributes.destination_validator, + }); + op.extra.cosmosSourceValidator = attributes.source_validator; + } break; case "unbond": - op.type = "UNDELEGATE"; - op.value = new BigNumber(fees); - op.extra.validators.push({ - amount: attributes["amount"].replace(currency.units[1].code, ""), - address: attributes.validator, - }); + if ( + attributes["amount"] && + attributes["amount"].indexOf(currency.units[1].code) != -1 && + attributes.validator + ) { + op.type = "UNDELEGATE"; + op.value = new BigNumber(fees); + op.extra.validators.push({ + amount: attributes["amount"].replace(currency.units[1].code, ""), + address: attributes.validator, + }); + } break; } }); From 0d409caffc84f16e7e479f2d12cda44a6ec1040f Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Fri, 18 Feb 2022 16:46:11 +0100 Subject: [PATCH 33/48] clarify code readable --- src/families/cosmos/js-signOperation.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index 55522f7be0..47bedc4221 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -150,7 +150,7 @@ const signOperation = ({ o.next({ type: "device-signature-granted" }); - const txHash = ""; // resolved at broadcast time + const hash = ""; // resolved at broadcast time const accountId = account.id; const type: OperationType = transaction.mode === "undelegate" @@ -165,9 +165,9 @@ const signOperation = ({ // build optimistic operation const operation: Operation = { - id: encodeOperationId(accountId, txHash, type), - hash: txHash, - type: type, + id: encodeOperationId(accountId, hash, type), + hash, + type, value: transaction.amount, fee: transaction.fees || new BigNumber(0), extra: {}, @@ -175,7 +175,7 @@ const signOperation = ({ blockHeight: null, senders: [account.freshAddress], recipients: [transaction.recipient], - accountId: accountId, + accountId, date: new Date(), }; From 2823fcd692c7eb30e59ee1584db313399143d480 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Fri, 18 Feb 2022 16:46:36 +0100 Subject: [PATCH 34/48] adjust sender and recipient --- src/families/cosmos/js-signOperation.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index 47bedc4221..11c753a95d 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -163,6 +163,14 @@ const signOperation = ({ ? "REWARD" : "OUT"; + const senders = [] as any; + const recipients = [] as any; + + if (type === "OUT") { + senders.push(account.freshAddress); + recipients.push(transaction.recipient); + } + // build optimistic operation const operation: Operation = { id: encodeOperationId(accountId, hash, type), @@ -173,8 +181,8 @@ const signOperation = ({ extra: {}, blockHash: null, blockHeight: null, - senders: [account.freshAddress], - recipients: [transaction.recipient], + senders, + recipients, accountId, date: new Date(), }; From fd3f0aa7fda0d8136146f543bea444613167b5c9 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Fri, 18 Feb 2022 16:46:50 +0100 Subject: [PATCH 35/48] fix fees when is ibc transaction --- src/families/cosmos/js-synchronisation.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/families/cosmos/js-synchronisation.ts b/src/families/cosmos/js-synchronisation.ts index 79ca7a8aba..9f890c66ab 100644 --- a/src/families/cosmos/js-synchronisation.ts +++ b/src/families/cosmos/js-synchronisation.ts @@ -45,15 +45,16 @@ const txToOps = (info: any, id: string, txs: any): Operation[] => { if ( attributes["sender"] && attributes["recipient"] && - attributes["amount"] && - attributes["amount"].indexOf(currency.units[1].code) != -1 + attributes["amount"] ) { op.senders.push(attributes["sender"]); op.recipients.push(attributes["recipient"]); - op.value = op.value.plus( - attributes["amount"].replace(currency.units[1].code, "") - ); + if (attributes["amount"].indexOf(currency.units[1].code) != -1) { + op.value = op.value.plus( + attributes["amount"].replace(currency.units[1].code, "") + ); + } if (attributes["sender"] === address) { op.type = "OUT"; From 6685baa6646a59e4a2e8e06bb60b2fd18a1700dd Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Sat, 19 Feb 2022 09:15:30 +0100 Subject: [PATCH 36/48] fix redelegations data mapping --- src/families/cosmos/api/Cosmos.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/families/cosmos/api/Cosmos.ts b/src/families/cosmos/api/Cosmos.ts index 28248d75ec..de68c43ea8 100644 --- a/src/families/cosmos/api/Cosmos.ts +++ b/src/families/cosmos/api/Cosmos.ts @@ -143,12 +143,12 @@ export const getRedelegations = async (address: string): Promise => { }); data.redelegation_responses.forEach((elem) => { - elem.entries.forEach((entries) => { + elem.entries.forEach((entry) => { redelegations.push({ - validatorSrcAddress: elem.validator_src_address, - validatorDstAddress: elem.validator_dst_address, - amount: new BigNumber(entries.initial_balance), - completionDate: new Date(entries.completion_time), + validatorSrcAddress: elem.redelegation.validator_src_address, + validatorDstAddress: elem.redelegation.validator_dst_address, + amount: new BigNumber(entry.redelegation_entry.initial_balance), + completionDate: new Date(entry.redelegation_entry.completion_time), }); }); }); From 892148b6dc81a8928bb10c76699f4bd6f00c2bf9 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Mon, 21 Feb 2022 10:26:00 +0100 Subject: [PATCH 37/48] fix mixed styles --- src/families/cosmos/js-synchronisation.ts | 42 ++++++++++------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/src/families/cosmos/js-synchronisation.ts b/src/families/cosmos/js-synchronisation.ts index 9f890c66ab..846966f951 100644 --- a/src/families/cosmos/js-synchronisation.ts +++ b/src/families/cosmos/js-synchronisation.ts @@ -42,24 +42,20 @@ const txToOps = (info: any, id: string, txs: any): Operation[] => { // https://docs.cosmos.network/v0.42/modules/staking/07_events.html switch (message.type) { case "transfer": - if ( - attributes["sender"] && - attributes["recipient"] && - attributes["amount"] - ) { - op.senders.push(attributes["sender"]); - op.recipients.push(attributes["recipient"]); + if (attributes.sender && attributes.recipient && attributes.amount) { + op.senders.push(attributes.sender); + op.recipients.push(attributes.recipient); - if (attributes["amount"].indexOf(currency.units[1].code) != -1) { + if (attributes.amount.indexOf(currency.units[1].code) != -1) { op.value = op.value.plus( - attributes["amount"].replace(currency.units[1].code, "") + attributes.amount.replace(currency.units[1].code, "") ); } - if (attributes["sender"] === address) { + if (attributes.sender === address) { op.type = "OUT"; op.value = op.value.plus(fees); - } else if (attributes["recipient"] === address) { + } else if (attributes.recipient === address) { op.type = "IN"; } } @@ -67,13 +63,13 @@ const txToOps = (info: any, id: string, txs: any): Operation[] => { case "withdraw_rewards": if ( - attributes["amount"] && - attributes["amount"].indexOf(currency.units[1].code) != -1 + attributes.amount && + attributes.amount.indexOf(currency.units[1].code) != -1 ) { op.type = "REWARD"; op.value = new BigNumber(fees); op.extra.validators.push({ - amount: attributes["amount"].replace(currency.units[1].code, ""), + amount: attributes.amount.replace(currency.units[1].code, ""), address: attributes.validator, }); } @@ -81,13 +77,13 @@ const txToOps = (info: any, id: string, txs: any): Operation[] => { case "delegate": if ( - attributes["amount"] && - attributes["amount"].indexOf(currency.units[1].code) != -1 + attributes.amount && + attributes.amount.indexOf(currency.units[1].code) != -1 ) { op.type = "DELEGATE"; op.value = new BigNumber(fees); op.extra.validators.push({ - amount: attributes["amount"].replace(currency.units[1].code, ""), + amount: attributes.amount.replace(currency.units[1].code, ""), address: attributes.validator, }); } @@ -95,15 +91,15 @@ const txToOps = (info: any, id: string, txs: any): Operation[] => { case "redelegate": if ( - attributes["amount"] && - attributes["amount"].indexOf(currency.units[1].code) != -1 && + attributes.amount && + attributes.amount.indexOf(currency.units[1].code) != -1 && attributes.destination_validator && attributes.source_validator ) { op.type = "REDELEGATE"; op.value = new BigNumber(fees); op.extra.validators.push({ - amount: attributes["amount"].replace(currency.units[1].code, ""), + amount: attributes.amount.replace(currency.units[1].code, ""), address: attributes.destination_validator, }); op.extra.cosmosSourceValidator = attributes.source_validator; @@ -112,14 +108,14 @@ const txToOps = (info: any, id: string, txs: any): Operation[] => { case "unbond": if ( - attributes["amount"] && - attributes["amount"].indexOf(currency.units[1].code) != -1 && + attributes.amount && + attributes.amount.indexOf(currency.units[1].code) != -1 && attributes.validator ) { op.type = "UNDELEGATE"; op.value = new BigNumber(fees); op.extra.validators.push({ - amount: attributes["amount"].replace(currency.units[1].code, ""), + amount: attributes.amount.replace(currency.units[1].code, ""), address: attributes.validator, }); } From 744633738c87a036ba1ee816ddec272b4c81e333 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Mon, 21 Feb 2022 10:26:23 +0100 Subject: [PATCH 38/48] fix array cast type --- src/families/cosmos/js-signOperation.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index 11c753a95d..df442f667b 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -163,8 +163,8 @@ const signOperation = ({ ? "REWARD" : "OUT"; - const senders = [] as any; - const recipients = [] as any; + const senders: string[] = []; + const recipients: string[] = []; if (type === "OUT") { senders.push(account.freshAddress); From 890c0d4b0339a3601ef33b15269d2ecb202060a8 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Mon, 21 Feb 2022 11:04:35 +0100 Subject: [PATCH 39/48] fix more determinist operation data --- src/families/cosmos/js-synchronisation.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/families/cosmos/js-synchronisation.ts b/src/families/cosmos/js-synchronisation.ts index 846966f951..6829a91b0a 100644 --- a/src/families/cosmos/js-synchronisation.ts +++ b/src/families/cosmos/js-synchronisation.ts @@ -123,6 +123,11 @@ const txToOps = (info: any, id: string, txs: any): Operation[] => { } }); + if (!["IN", "OUT"].includes(op.type)) { + op.senders = []; + op.recipients = []; + } + op.id = encodeOperationId(id, tx.txhash, op.type); if (op.type) { From 289ef6dcb2547ce392baebcd0588243ed38df2d6 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Tue, 22 Feb 2022 09:12:17 +0100 Subject: [PATCH 40/48] fix could not find optimisticOperation in redelegate transaction --- src/families/cosmos/js-synchronisation.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/families/cosmos/js-synchronisation.ts b/src/families/cosmos/js-synchronisation.ts index 6829a91b0a..6386424476 100644 --- a/src/families/cosmos/js-synchronisation.ts +++ b/src/families/cosmos/js-synchronisation.ts @@ -52,10 +52,10 @@ const txToOps = (info: any, id: string, txs: any): Operation[] => { ); } - if (attributes.sender === address) { + if (!op.type && attributes.sender === address) { op.type = "OUT"; op.value = op.value.plus(fees); - } else if (attributes.recipient === address) { + } else if (!op.type && attributes.recipient === address) { op.type = "IN"; } } From c113968492533e9a217c44011cf9186c678aafa4 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Tue, 22 Feb 2022 13:38:54 +0100 Subject: [PATCH 41/48] restore getStargateRewardsState methode --- src/families/cosmos/validators.ts | 175 +++++++++++++++++------------- 1 file changed, 98 insertions(+), 77 deletions(-) diff --git a/src/families/cosmos/validators.ts b/src/families/cosmos/validators.ts index 1138d468c4..11946e1891 100644 --- a/src/families/cosmos/validators.ts +++ b/src/families/cosmos/validators.ts @@ -181,8 +181,8 @@ const getRewardsState = makeLRUCache( ); const getStargateRewardsState = makeLRUCache( - async (_currency: CryptoCurrency) => { - // Fake numbers until Gaia fixes its endpoints + async (currency: CryptoCurrency) => { + /* return { targetBondedRatio: 0.01, communityPoolCommission: 0.0, @@ -196,81 +196,102 @@ const getStargateRewardsState = makeLRUCache( averageDailyFees: 0, currentValueInflation: 0.01, }; - /* - // All obtained values are strings ; so sometimes we will need to parse them as numbers - const inflationUrl = `${getBaseApiUrl( - currency - )}/cosmos/mint/v1beta1/inflation`; - const { data: inflationData } = await network({ - url: inflationUrl, - method: "GET", - }); - const currentValueInflation = parseFloat(inflationData.inflation); - const inflationParametersUrl = `${getBaseApiUrl( - currency - )}/cosmos/mint/v1beta1/params`; - const { data: inflationParametersData } = await network({ - url: inflationParametersUrl, - method: "GET", - }); - const inflationRateChange = parseFloat( - inflationParametersData.params.inflation_rate_change - ); - const inflationMaxRate = parseFloat( - inflationParametersData.params.inflation_max - ); - const inflationMinRate = parseFloat( - inflationParametersData.params.inflation_min - ); - const targetBondedRatio = parseFloat( - inflationParametersData.params.goal_bonded - ); - // Source for seconds per year : https://github.com/gavinly/CosmosParametersWiki/blob/master/Mint.md#notes-3 - // 365.24 (days) * 24 (hours) * 60 (minutes) * 60 (seconds) = 31556736 seconds - const assumedTimePerBlock = - 31556736.0 / parseFloat(inflationParametersData.params.blocks_per_year); - const communityTaxUrl = `${getBaseApiUrl( - currency - )}/cosmos/distribution/v1beta1/params`; - const { data: communityTax } = await network({ - url: communityTaxUrl, - method: "GET", - }); - const communityPoolCommission = parseFloat( - communityTax.params.community_tax - ); - const supplyUrl = `${getBaseApiUrl(currency)}/cosmos/bank/v1beta1/supply/${ - currency.id == "cosmos_testnet" ? "umuon" : "uatom" - }`; - const { data: totalSupplyData } = await network({ - url: supplyUrl, - method: "GET", - }); - const totalSupply = parseUatomStrAsAtomNumber( - totalSupplyData.amount.amount - ); - const ratioUrl = `${getBaseApiUrl(currency)}/cosmos/staking/v1beta1/pool`; - const { data: ratioData } = await network({ url: ratioUrl, method: "GET" }); - const actualBondedRatio = - parseUatomStrAsAtomNumber(ratioData.pool.bonded_tokens) / totalSupply; - // Arbitrary value in ATOM. - const averageDailyFees = 20; - // Arbitrary value in seconds - const averageTimePerBlock = 7.5; - return { - targetBondedRatio, - communityPoolCommission, - assumedTimePerBlock, - inflationRateChange, - inflationMaxRate, - inflationMinRate, - actualBondedRatio, - averageTimePerBlock, - totalSupply, - averageDailyFees, - currentValueInflation, - }; - */ + */ + + // All obtained values are strings ; so sometimes we will need to parse them as numbers + const inflationUrl = `${getBaseApiUrl( + currency + )}/cosmos/mint/v1beta1/inflation`; + + const { data: inflationData } = await network({ + url: inflationUrl, + method: "GET", + }); + + const currentValueInflation = parseFloat(inflationData.inflation); + + const inflationParametersUrl = `${getBaseApiUrl( + currency + )}/cosmos/mint/v1beta1/params`; + + const { data: inflationParametersData } = await network({ + url: inflationParametersUrl, + method: "GET", + }); + + const inflationRateChange = parseFloat( + inflationParametersData.params.inflation_rate_change + ); + + const inflationMaxRate = parseFloat( + inflationParametersData.params.inflation_max + ); + + const inflationMinRate = parseFloat( + inflationParametersData.params.inflation_min + ); + + const targetBondedRatio = parseFloat( + inflationParametersData.params.goal_bonded + ); + + // Source for seconds per year : https://github.com/gavinly/CosmosParametersWiki/blob/master/Mint.md#notes-3 + // 365.24 (days) * 24 (hours) * 60 (minutes) * 60 (seconds) = 31556736 seconds + const assumedTimePerBlock = + 31556736.0 / parseFloat(inflationParametersData.params.blocks_per_year); + + const communityTaxUrl = `${getBaseApiUrl( + currency + )}/cosmos/distribution/v1beta1/params`; + + const { data: communityTax } = await network({ + url: communityTaxUrl, + method: "GET", + }); + + const communityPoolCommission = parseFloat( + communityTax.params.community_tax + ); + + const supplyUrl = `${getBaseApiUrl(currency)}/cosmos/bank/v1beta1/supply/${ + currency.id == "cosmos_testnet" ? "umuon" : "uatom" + }`; + + const { data: totalSupplyData } = await network({ + url: supplyUrl, + method: "GET", + }); + + const totalSupply = parseUatomStrAsAtomNumber( + totalSupplyData.amount.amount + ); + + const ratioUrl = `${getBaseApiUrl(currency)}/cosmos/staking/v1beta1/pool`; + + const { data: ratioData } = await network({ url: ratioUrl, method: "GET" }); + + const actualBondedRatio = + parseUatomStrAsAtomNumber(ratioData.pool.bonded_tokens) / totalSupply; + + // Arbitrary value in ATOM. + const averageDailyFees = 20; + + // Arbitrary value in seconds + const averageTimePerBlock = 7.5; + + return { + targetBondedRatio, + communityPoolCommission, + assumedTimePerBlock, + inflationRateChange, + inflationMaxRate, + inflationMinRate, + actualBondedRatio, + averageTimePerBlock, + totalSupply, + averageDailyFees, + currentValueInflation, + }; }, (currency: CryptoCurrency) => currency.id ); From c3e6853069a77cc859efd9045070662750410cc3 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Fri, 25 Feb 2022 12:39:04 +0100 Subject: [PATCH 42/48] amount of the operation more close --- src/families/cosmos/js-signOperation.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index df442f667b..cd19b1c01f 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -45,7 +45,7 @@ const signOperation = ({ let cancelled; async function main() { - const { accountNumber, sequence } = await getAccount( + const { accountNumber, sequence, spendableBalance } = await getAccount( account.freshAddress ); @@ -152,6 +152,8 @@ const signOperation = ({ const hash = ""; // resolved at broadcast time const accountId = account.id; + const fee = transaction.fees || new BigNumber(0); + const type: OperationType = transaction.mode === "undelegate" ? "UNDELEGATE" @@ -176,8 +178,10 @@ const signOperation = ({ id: encodeOperationId(accountId, hash, type), hash, type, - value: transaction.amount, - fee: transaction.fees || new BigNumber(0), + value: transaction.useAllAmount + ? spendableBalance + : transaction.amount.plus(fee), + fee, extra: {}, blockHash: null, blockHeight: null, From 66310730e7af728505c3f5cfb145fb709ac8dc82 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Fri, 25 Feb 2022 12:39:22 +0100 Subject: [PATCH 43/48] return transaction in prepareTransaction --- src/families/cosmos/js-prepareTransaction.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/families/cosmos/js-prepareTransaction.ts b/src/families/cosmos/js-prepareTransaction.ts index 0bc88f1eb7..3180a80ddc 100644 --- a/src/families/cosmos/js-prepareTransaction.ts +++ b/src/families/cosmos/js-prepareTransaction.ts @@ -39,13 +39,10 @@ const prepareTransaction = async ( } if (transaction.mode !== "send" && !transaction.memo) { - patch.memo = "Ledger Live"; + transaction.memo = "Ledger Live"; } - const unsignedPayload = await buildTransaction(account, { - ...transaction, - ...patch, - }); + const unsignedPayload = await buildTransaction(account, transaction); // be sure payload is complete if (unsignedPayload) { @@ -53,7 +50,7 @@ const prepareTransaction = async ( typeUrl: "/cosmos.tx.v1beta1.TxBody", value: { messages: unsignedPayload, - memo: transaction.memo || patch.memo || "", + memo: transaction.memo || "", }, }; @@ -111,11 +108,11 @@ const prepareTransaction = async ( } } - patch.gas = gasQty; + transaction.gas = gasQty; - patch.fees = gasPrice.multipliedBy(gasQty).integerValue(); + transaction.fees = gasPrice.multipliedBy(gasQty).integerValue(); - return { ...transaction, ...patch }; + return transaction; }; export default prepareTransaction; From a4b0c61c96517acb93cdd763978ca7e6ef46eafc Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Fri, 25 Feb 2022 13:12:06 +0100 Subject: [PATCH 44/48] keep immutable paradigm for prepareTransaction --- src/families/cosmos/js-prepareTransaction.ts | 28 +++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/families/cosmos/js-prepareTransaction.ts b/src/families/cosmos/js-prepareTransaction.ts index 3180a80ddc..06e63cc840 100644 --- a/src/families/cosmos/js-prepareTransaction.ts +++ b/src/families/cosmos/js-prepareTransaction.ts @@ -24,13 +24,16 @@ const prepareTransaction = async ( account: Account, transaction: Transaction ): Promise => { - const patch: Partial = {}; + let memo = transaction.memo; + let fees = transaction.fees; + let gas = transaction.gas; + let amount = transaction.amount; let gasQty = new BigNumber(250000); const gasPrice = new BigNumber(getEnv("COSMOS_GAS_PRICE")); if (transaction.useAllAmount) { - patch.amount = getMaxEstimatedBalance( + amount = getMaxEstimatedBalance( account, account.balance .dividedBy(new BigNumber(getEnv("COSMOS_GAS_AMPLIFIER"))) @@ -39,10 +42,13 @@ const prepareTransaction = async ( } if (transaction.mode !== "send" && !transaction.memo) { - transaction.memo = "Ledger Live"; + memo = "Ledger Live"; } - const unsignedPayload = await buildTransaction(account, transaction); + const unsignedPayload = await buildTransaction(account, { + ...transaction, + amount, + }); // be sure payload is complete if (unsignedPayload) { @@ -50,7 +56,7 @@ const prepareTransaction = async ( typeUrl: "/cosmos.tx.v1beta1.TxBody", value: { messages: unsignedPayload, - memo: transaction.memo || "", + memo: transaction.memo || memo || "", }, }; @@ -108,9 +114,17 @@ const prepareTransaction = async ( } } - transaction.gas = gasQty; + gas = gasQty; - transaction.fees = gasPrice.multipliedBy(gasQty).integerValue(); + fees = gasPrice.multipliedBy(gasQty).integerValue(); + + if ( + transaction.memo !== memo || + transaction.fees !== fees || + transaction.gas !== gas + ) { + return { ...transaction, memo, fees, gas }; + } return transaction; }; From 8780fb45452c663e3b516f5482f8632c530961dc Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Fri, 25 Feb 2022 15:50:01 +0100 Subject: [PATCH 45/48] fix amount update in prepareTransaction --- src/families/cosmos/js-prepareTransaction.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/families/cosmos/js-prepareTransaction.ts b/src/families/cosmos/js-prepareTransaction.ts index 06e63cc840..e77a31f270 100644 --- a/src/families/cosmos/js-prepareTransaction.ts +++ b/src/families/cosmos/js-prepareTransaction.ts @@ -121,9 +121,10 @@ const prepareTransaction = async ( if ( transaction.memo !== memo || transaction.fees !== fees || - transaction.gas !== gas + transaction.gas !== gas || + transaction.amount !== amount ) { - return { ...transaction, memo, fees, gas }; + return { ...transaction, memo, fees, gas, amount }; } return transaction; From e6637ddf8d619cae15ba51e4a15b68412b196867 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Fri, 25 Feb 2022 15:56:42 +0100 Subject: [PATCH 46/48] fix amount control to be more specific --- src/families/cosmos/js-buildTransaction.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/families/cosmos/js-buildTransaction.ts b/src/families/cosmos/js-buildTransaction.ts index c9e3b5e85b..4b86597563 100644 --- a/src/families/cosmos/js-buildTransaction.ts +++ b/src/families/cosmos/js-buildTransaction.ts @@ -15,7 +15,7 @@ const buildTransaction = async ( switch (transaction.mode) { case "send": - if (!transaction.recipient || !transaction.amount) { + if (!transaction.recipient || transaction.amount.lte(0)) { isComplete = false; } else { msg.push({ @@ -39,7 +39,7 @@ const buildTransaction = async ( isComplete = false; } else { transaction.validators.forEach((validator) => { - if (!validator.address || !validator.amount) { + if (!validator.address || validator.amount.lte(0)) { isComplete = false; } @@ -63,7 +63,7 @@ const buildTransaction = async ( !transaction.validators || transaction.validators.length < 1 || !transaction.validators[0].address || - !transaction.validators[0].amount + transaction.validators[0].amount.lte(0) ) { isComplete = false; } else { @@ -87,7 +87,7 @@ const buildTransaction = async ( !transaction.validators || transaction.validators.length < 1 || !transaction.validators[0].address || - !transaction.validators[0].amount + transaction.validators[0].amount.lte(0) ) { isComplete = false; } else { @@ -129,7 +129,7 @@ const buildTransaction = async ( !transaction.validators || transaction.validators.length < 1 || !transaction.validators[0].address || - !transaction.validators[0].amount + transaction.validators[0].amount.lte(0) ) { isComplete = false; } else { From 774230a2bfcbe64ca08c5ad443f908e34e4e9446 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Fri, 25 Feb 2022 16:16:30 +0100 Subject: [PATCH 47/48] fix BigNumber compare --- src/families/cosmos/js-prepareTransaction.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/families/cosmos/js-prepareTransaction.ts b/src/families/cosmos/js-prepareTransaction.ts index e77a31f270..8f75721b0a 100644 --- a/src/families/cosmos/js-prepareTransaction.ts +++ b/src/families/cosmos/js-prepareTransaction.ts @@ -120,9 +120,9 @@ const prepareTransaction = async ( if ( transaction.memo !== memo || - transaction.fees !== fees || - transaction.gas !== gas || - transaction.amount !== amount + !fees.eq(transaction.fees || new BigNumber(0)) || + !gas.eq(transaction.gas || new BigNumber(0)) || + !amount.eq(transaction.amount) ) { return { ...transaction, memo, fees, gas, amount }; } From 8ee49ac86447af831f789aeaac97279f704f8573 Mon Sep 17 00:00:00 2001 From: Alexandre Alouit Date: Fri, 25 Feb 2022 17:08:00 +0100 Subject: [PATCH 48/48] fix spendableBalance --- src/families/cosmos/js-signOperation.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/families/cosmos/js-signOperation.ts b/src/families/cosmos/js-signOperation.ts index cd19b1c01f..1e138af0ee 100644 --- a/src/families/cosmos/js-signOperation.ts +++ b/src/families/cosmos/js-signOperation.ts @@ -45,7 +45,7 @@ const signOperation = ({ let cancelled; async function main() { - const { accountNumber, sequence, spendableBalance } = await getAccount( + const { accountNumber, sequence } = await getAccount( account.freshAddress ); @@ -179,7 +179,7 @@ const signOperation = ({ hash, type, value: transaction.useAllAmount - ? spendableBalance + ? account.spendableBalance : transaction.amount.plus(fee), fee, extra: {},