diff --git a/.changeset/forty-students-eat.md b/.changeset/forty-students-eat.md new file mode 100644 index 000000000000..e0239ef67e0b --- /dev/null +++ b/.changeset/forty-students-eat.md @@ -0,0 +1,5 @@ +--- +"@ledgerhq/coin-framework": patch +--- + +update test snapshot for mantra diff --git a/.changeset/friendly-socks-hunt.md b/.changeset/friendly-socks-hunt.md new file mode 100644 index 000000000000..c0c30b56c0c6 --- /dev/null +++ b/.changeset/friendly-socks-hunt.md @@ -0,0 +1,14 @@ +--- +"@ledgerhq/types-cryptoassets": minor +"@ledgerhq/cryptoassets": minor +"@ledgerhq/types-live": minor +"@ledgerhq/coin-cosmos": minor +"@ledgerhq/crypto-icons-ui": minor +"ledger-live-desktop": minor +"live-mobile": minor +"@ledgerhq/live-common": minor +"@ledgerhq/web-tools": minor +"@ledgerhq/live-cli": minor +--- + +add mantra currency diff --git a/apps/cli/src/live-common-setup-base.ts b/apps/cli/src/live-common-setup-base.ts index a2fd0e238b57..96f297a0b9d0 100644 --- a/apps/cli/src/live-common-setup-base.ts +++ b/apps/cli/src/live-common-setup-base.ts @@ -99,6 +99,7 @@ setSupportedCurrencies([ "scroll", "scroll_sepolia", "etherlink", + "mantra", ]); for (const k in process.env) setEnvUnsafe(k as EnvName, process.env[k]); diff --git a/apps/ledger-live-desktop/src/live-common-set-supported-currencies.ts b/apps/ledger-live-desktop/src/live-common-set-supported-currencies.ts index f3b4a841705a..2f280eabe429 100644 --- a/apps/ledger-live-desktop/src/live-common-set-supported-currencies.ts +++ b/apps/ledger-live-desktop/src/live-common-set-supported-currencies.ts @@ -93,4 +93,5 @@ setSupportedCurrencies([ "scroll_sepolia", "ton", "etherlink", + "mantra", ]); diff --git a/apps/ledger-live-desktop/src/renderer/modals/AddAccounts/steps/StepChooseCurrency.tsx b/apps/ledger-live-desktop/src/renderer/modals/AddAccounts/steps/StepChooseCurrency.tsx index 8797137d853f..c1bca968a42b 100644 --- a/apps/ledger-live-desktop/src/renderer/modals/AddAccounts/steps/StepChooseCurrency.tsx +++ b/apps/ledger-live-desktop/src/renderer/modals/AddAccounts/steps/StepChooseCurrency.tsx @@ -82,6 +82,7 @@ const StepChooseCurrency = ({ currency, setCurrency }: StepProps) => { const icon = useFeature("currencyIcon"); const ton = useFeature("currencyTon"); const etherlink = useFeature("currencyEtherlink"); + const mantra = useFeature("currencyMantra"); const featureFlaggedCurrencies = useMemo( (): Partial | null>> => ({ @@ -132,6 +133,7 @@ const StepChooseCurrency = ({ currency, setCurrency }: StepProps) => { scroll_sepolia: scrollSepolia, icon, etherlink, + mantra, }), [ axelar, @@ -181,6 +183,7 @@ const StepChooseCurrency = ({ currency, setCurrency }: StepProps) => { scrollSepolia, icon, etherlink, + mantra, ], ); diff --git a/apps/ledger-live-desktop/tests/specs/services/wallet-api.spec.ts-snapshots/wallet-api-currencies-darwin.json b/apps/ledger-live-desktop/tests/specs/services/wallet-api.spec.ts-snapshots/wallet-api-currencies-darwin.json index d56fc140ba0d..2a9ea395d771 100644 --- a/apps/ledger-live-desktop/tests/specs/services/wallet-api.spec.ts-snapshots/wallet-api-currencies-darwin.json +++ b/apps/ledger-live-desktop/tests/specs/services/wallet-api.spec.ts-snapshots/wallet-api-currencies-darwin.json @@ -781,5 +781,14 @@ "family": "ethereum", "color": "#38FF9C", "decimals": 18 + }, + { + "type": "CryptoCurrency", + "id": "mantra", + "ticker": "OM", + "name": "Mantra", + "family": "cosmos", + "color": "#ffb386", + "decimals": 6 } ] \ No newline at end of file diff --git a/apps/ledger-live-desktop/tests/specs/services/wallet-api.spec.ts-snapshots/wallet-api-currencies-linux.json b/apps/ledger-live-desktop/tests/specs/services/wallet-api.spec.ts-snapshots/wallet-api-currencies-linux.json index d56fc140ba0d..2a9ea395d771 100644 --- a/apps/ledger-live-desktop/tests/specs/services/wallet-api.spec.ts-snapshots/wallet-api-currencies-linux.json +++ b/apps/ledger-live-desktop/tests/specs/services/wallet-api.spec.ts-snapshots/wallet-api-currencies-linux.json @@ -781,5 +781,14 @@ "family": "ethereum", "color": "#38FF9C", "decimals": 18 + }, + { + "type": "CryptoCurrency", + "id": "mantra", + "ticker": "OM", + "name": "Mantra", + "family": "cosmos", + "color": "#ffb386", + "decimals": 6 } ] \ No newline at end of file diff --git a/apps/ledger-live-mobile/src/live-common-setup.ts b/apps/ledger-live-mobile/src/live-common-setup.ts index 05815fd122a2..37bb22b8943d 100644 --- a/apps/ledger-live-mobile/src/live-common-setup.ts +++ b/apps/ledger-live-mobile/src/live-common-setup.ts @@ -126,6 +126,7 @@ setSupportedCurrencies([ "scroll_sepolia", "ton", "etherlink", + "mantra", ]); if (Config.BLE_LOG_LEVEL) BluetoothTransport.setLogLevel(Config.BLE_LOG_LEVEL); diff --git a/apps/ledger-live-mobile/src/screens/AddAccounts/01-SelectCrypto.tsx b/apps/ledger-live-mobile/src/screens/AddAccounts/01-SelectCrypto.tsx index c9f1b11a3052..441d45839f0d 100644 --- a/apps/ledger-live-mobile/src/screens/AddAccounts/01-SelectCrypto.tsx +++ b/apps/ledger-live-mobile/src/screens/AddAccounts/01-SelectCrypto.tsx @@ -104,6 +104,7 @@ export default function AddAccountsSelectCrypto({ navigation, route }: Props) { const icon = useFeature("currencyIcon"); const ton = useFeature("currencyTon"); const etherlink = useFeature("currencyEtherlink"); + const mantra = useFeature("currencyMantra"); const featureFlaggedCurrencies = useMemo( (): Partial | null>> => ({ @@ -154,6 +155,7 @@ export default function AddAccountsSelectCrypto({ navigation, route }: Props) { scroll_sepolia: scrollSepolia, icon, etherlink, + mantra, }), [ axelar, @@ -203,6 +205,7 @@ export default function AddAccountsSelectCrypto({ navigation, route }: Props) { scrollSepolia, icon, etherlink, + mantra, ], ); diff --git a/apps/web-tools/live-common-setup.ts b/apps/web-tools/live-common-setup.ts index b157df940854..c9d959db1272 100644 --- a/apps/web-tools/live-common-setup.ts +++ b/apps/web-tools/live-common-setup.ts @@ -69,4 +69,5 @@ setSupportedCurrencies([ "optimism_sepolia", "linea", "linea_sepolia", + "mantra", ]); diff --git a/libs/coin-framework/src/currencies/__snapshots__/formatCurrencyUnit.test.ts.snap b/libs/coin-framework/src/currencies/__snapshots__/formatCurrencyUnit.test.ts.snap index 520fc5d77e22..66fe5950dd5d 100644 --- a/libs/coin-framework/src/currencies/__snapshots__/formatCurrencyUnit.test.ts.snap +++ b/libs/coin-framework/src/currencies/__snapshots__/formatCurrencyUnit.test.ts.snap @@ -176,6 +176,8 @@ exports[`formatCurrencyUnit with custom options with locale de-DE should correct exports[`formatCurrencyUnit with custom options with locale de-DE should correctly format MIX Blockchain unit (MIX) 1`] = `"123.456.789,00000000- -MIX"`; +exports[`formatCurrencyUnit with custom options with locale de-DE should correctly format Mantra unit (Mantra) 1`] = `"12.345.678.900,000000- -OM"`; + exports[`formatCurrencyUnit with custom options with locale de-DE should correctly format Metis unit (METIS) 1`] = `"0,012345678900000000- -METIS"`; exports[`formatCurrencyUnit with custom options with locale de-DE should correctly format Monero unit (XMR) 1`] = `"12.345,678900000000- -XMR"`; @@ -502,6 +504,8 @@ exports[`formatCurrencyUnit with custom options with locale en-US should correct exports[`formatCurrencyUnit with custom options with locale en-US should correctly format MIX Blockchain unit (MIX) 1`] = `"123,456,789.00000000- -MIX"`; +exports[`formatCurrencyUnit with custom options with locale en-US should correctly format Mantra unit (Mantra) 1`] = `"12,345,678,900.000000- -OM"`; + exports[`formatCurrencyUnit with custom options with locale en-US should correctly format Metis unit (METIS) 1`] = `"0.012345678900000000- -METIS"`; exports[`formatCurrencyUnit with custom options with locale en-US should correctly format Monero unit (XMR) 1`] = `"12,345.678900000000- -XMR"`; @@ -828,6 +832,8 @@ exports[`formatCurrencyUnit with custom options with locale es-ES should correct exports[`formatCurrencyUnit with custom options with locale es-ES should correctly format MIX Blockchain unit (MIX) 1`] = `"123.456.789,00000000- -MIX"`; +exports[`formatCurrencyUnit with custom options with locale es-ES should correctly format Mantra unit (Mantra) 1`] = `"12.345.678.900,000000- -OM"`; + exports[`formatCurrencyUnit with custom options with locale es-ES should correctly format Metis unit (METIS) 1`] = `"0,012345678900000000- -METIS"`; exports[`formatCurrencyUnit with custom options with locale es-ES should correctly format Monero unit (XMR) 1`] = `"12.345,678900000000- -XMR"`; @@ -1154,6 +1160,8 @@ exports[`formatCurrencyUnit with custom options with locale fr-FR should correct exports[`formatCurrencyUnit with custom options with locale fr-FR should correctly format MIX Blockchain unit (MIX) 1`] = `"123 456 789,00000000- -MIX"`; +exports[`formatCurrencyUnit with custom options with locale fr-FR should correctly format Mantra unit (Mantra) 1`] = `"12 345 678 900,000000- -OM"`; + exports[`formatCurrencyUnit with custom options with locale fr-FR should correctly format Metis unit (METIS) 1`] = `"0,012345678900000000- -METIS"`; exports[`formatCurrencyUnit with custom options with locale fr-FR should correctly format Monero unit (XMR) 1`] = `"12 345,678900000000- -XMR"`; @@ -1480,6 +1488,8 @@ exports[`formatCurrencyUnit with custom options with locale ja-JP should correct exports[`formatCurrencyUnit with custom options with locale ja-JP should correctly format MIX Blockchain unit (MIX) 1`] = `"123,456,789.00000000- -MIX"`; +exports[`formatCurrencyUnit with custom options with locale ja-JP should correctly format Mantra unit (Mantra) 1`] = `"12,345,678,900.000000- -OM"`; + exports[`formatCurrencyUnit with custom options with locale ja-JP should correctly format Metis unit (METIS) 1`] = `"0.012345678900000000- -METIS"`; exports[`formatCurrencyUnit with custom options with locale ja-JP should correctly format Monero unit (XMR) 1`] = `"12,345.678900000000- -XMR"`; @@ -1806,6 +1816,8 @@ exports[`formatCurrencyUnit with custom options with locale ko-KR should correct exports[`formatCurrencyUnit with custom options with locale ko-KR should correctly format MIX Blockchain unit (MIX) 1`] = `"123,456,789.00000000- -MIX"`; +exports[`formatCurrencyUnit with custom options with locale ko-KR should correctly format Mantra unit (Mantra) 1`] = `"12,345,678,900.000000- -OM"`; + exports[`formatCurrencyUnit with custom options with locale ko-KR should correctly format Metis unit (METIS) 1`] = `"0.012345678900000000- -METIS"`; exports[`formatCurrencyUnit with custom options with locale ko-KR should correctly format Monero unit (XMR) 1`] = `"12,345.678900000000- -XMR"`; @@ -2132,6 +2144,8 @@ exports[`formatCurrencyUnit with custom options with locale pt-BR should correct exports[`formatCurrencyUnit with custom options with locale pt-BR should correctly format MIX Blockchain unit (MIX) 1`] = `"123.456.789,00000000- -MIX"`; +exports[`formatCurrencyUnit with custom options with locale pt-BR should correctly format Mantra unit (Mantra) 1`] = `"12.345.678.900,000000- -OM"`; + exports[`formatCurrencyUnit with custom options with locale pt-BR should correctly format Metis unit (METIS) 1`] = `"0,012345678900000000- -METIS"`; exports[`formatCurrencyUnit with custom options with locale pt-BR should correctly format Monero unit (XMR) 1`] = `"12.345,678900000000- -XMR"`; @@ -2458,6 +2472,8 @@ exports[`formatCurrencyUnit with custom options with locale ru-RU should correct exports[`formatCurrencyUnit with custom options with locale ru-RU should correctly format MIX Blockchain unit (MIX) 1`] = `"123 456 789,00000000- -MIX"`; +exports[`formatCurrencyUnit with custom options with locale ru-RU should correctly format Mantra unit (Mantra) 1`] = `"12 345 678 900,000000- -OM"`; + exports[`formatCurrencyUnit with custom options with locale ru-RU should correctly format Metis unit (METIS) 1`] = `"0,012345678900000000- -METIS"`; exports[`formatCurrencyUnit with custom options with locale ru-RU should correctly format Monero unit (XMR) 1`] = `"12 345,678900000000- -XMR"`; @@ -2784,6 +2800,8 @@ exports[`formatCurrencyUnit with custom options with locale tr-TR should correct exports[`formatCurrencyUnit with custom options with locale tr-TR should correctly format MIX Blockchain unit (MIX) 1`] = `"123.456.789,00000000- -MIX"`; +exports[`formatCurrencyUnit with custom options with locale tr-TR should correctly format Mantra unit (Mantra) 1`] = `"12.345.678.900,000000- -OM"`; + exports[`formatCurrencyUnit with custom options with locale tr-TR should correctly format Metis unit (METIS) 1`] = `"0,012345678900000000- -METIS"`; exports[`formatCurrencyUnit with custom options with locale tr-TR should correctly format Monero unit (XMR) 1`] = `"12.345,678900000000- -XMR"`; @@ -3110,6 +3128,8 @@ exports[`formatCurrencyUnit with custom options with locale zh-CN should correct exports[`formatCurrencyUnit with custom options with locale zh-CN should correctly format MIX Blockchain unit (MIX) 1`] = `"123,456,789.00000000- -MIX"`; +exports[`formatCurrencyUnit with custom options with locale zh-CN should correctly format Mantra unit (Mantra) 1`] = `"12,345,678,900.000000- -OM"`; + exports[`formatCurrencyUnit with custom options with locale zh-CN should correctly format Metis unit (METIS) 1`] = `"0.012345678900000000- -METIS"`; exports[`formatCurrencyUnit with custom options with locale zh-CN should correctly format Monero unit (XMR) 1`] = `"12,345.678900000000- -XMR"`; @@ -3436,6 +3456,8 @@ exports[`formatCurrencyUnit with default options should correctly format Lukso u exports[`formatCurrencyUnit with default options should correctly format MIX Blockchain unit (MIX) 1`] = `"123,456,789"`; +exports[`formatCurrencyUnit with default options should correctly format Mantra unit (Mantra) 1`] = `"12,345,678,900"`; + exports[`formatCurrencyUnit with default options should correctly format Metis unit (METIS) 1`] = `"0.0123456"`; exports[`formatCurrencyUnit with default options should correctly format Monero unit (XMR) 1`] = `"12,345.6"`; diff --git a/libs/coin-modules/coin-cosmos/src/chain/Mantra.ts b/libs/coin-modules/coin-cosmos/src/chain/Mantra.ts new file mode 100644 index 000000000000..332cacc64490 --- /dev/null +++ b/libs/coin-modules/coin-cosmos/src/chain/Mantra.ts @@ -0,0 +1,20 @@ +import CosmosBase from "./cosmosBase"; + +class Mantra extends CosmosBase { + stakingDocUrl: string; + unbondingPeriod: number; + prefix: string; + validatorPrefix: string; + // Provided by coin config + ledgerValidator!: string; + lcd!: string; + constructor() { + super(); + this.stakingDocUrl = ""; + this.unbondingPeriod = 21; + this.prefix = "mantra"; + this.validatorPrefix = `${this.prefix}valoper`; + } +} + +export default Mantra; diff --git a/libs/coin-modules/coin-cosmos/src/chain/chain.ts b/libs/coin-modules/coin-cosmos/src/chain/chain.ts index 254c7cbd4fcb..0eb41b83ad07 100644 --- a/libs/coin-modules/coin-cosmos/src/chain/chain.ts +++ b/libs/coin-modules/coin-cosmos/src/chain/chain.ts @@ -16,6 +16,7 @@ import BinanceBeaconChain from "./BinanceBeaconChain"; import Coreum from "./Coreum"; import Injective from "./Injective"; import Dydx from "./Dydx"; +import Mantra from "./Mantra"; const cosmosChainParams: { [key: string]: CosmosBase } = {}; export default function cryptoFactory(currencyId: string): CosmosBase { @@ -74,6 +75,9 @@ export default function cryptoFactory(currencyId: string): CosmosBase { case "injective": cosmosChainParams[currencyId] = new Injective(); break; + case "mantra": + cosmosChainParams[currencyId] = new Mantra(); + break; default: throw new Error(`${currencyId} is not supported`); } diff --git a/libs/coin-modules/coin-cosmos/src/chain/chain.unit.test.ts b/libs/coin-modules/coin-cosmos/src/chain/chain.unit.test.ts index 28850ed36ea7..0e129ac5e43e 100644 --- a/libs/coin-modules/coin-cosmos/src/chain/chain.unit.test.ts +++ b/libs/coin-modules/coin-cosmos/src/chain/chain.unit.test.ts @@ -20,6 +20,7 @@ describe("cryptoFactory test", () => { "sei_network", "stargaze", "stride", + "mantra", ]; currencies.forEach(currency => { expect(cryptoFactory(currency)).not.toBeNull(); diff --git a/libs/coin-modules/coin-cosmos/src/config.ts b/libs/coin-modules/coin-cosmos/src/config.ts index 2e01e2241ab0..01e6c0611c4a 100644 --- a/libs/coin-modules/coin-cosmos/src/config.ts +++ b/libs/coin-modules/coin-cosmos/src/config.ts @@ -158,6 +158,16 @@ export const cosmosConfig: CosmosConfig = { }, }, }, + config_currency_mantra: { + type: "object", + default: { + lcd: "https://api.mantrachain.io", + minGasPrice: 0.01, + status: { + type: "active", + }, + }, + }, }; import buildCoinConfig, { type CurrencyConfig } from "@ledgerhq/coin-framework/config"; diff --git a/libs/coin-modules/coin-cosmos/src/specs.ts b/libs/coin-modules/coin-cosmos/src/specs.ts index 4fda6693b83c..3bc3414d37ee 100644 --- a/libs/coin-modules/coin-cosmos/src/specs.ts +++ b/libs/coin-modules/coin-cosmos/src/specs.ts @@ -590,6 +590,15 @@ const injective = { }), }; +const mantraMinimalTransactionAmount = new BigNumber(20000); +const mantra = { + ...generateGenericCosmosTest("mantra", false, { + minViableAmount: mantraMinimalTransactionAmount, + mutations: cosmosLikeMutations(mantraMinimalTransactionAmount), + skipOperationHistory: true, + }), +}; + export default { axelar, cosmos, @@ -605,4 +614,5 @@ export default { stargaze, coreum, injective, + mantra, }; diff --git a/libs/ledger-live-common/src/__tests__/test-helpers/environment.ts b/libs/ledger-live-common/src/__tests__/test-helpers/environment.ts index 9a798679bb12..2999147f0ef9 100644 --- a/libs/ledger-live-common/src/__tests__/test-helpers/environment.ts +++ b/libs/ledger-live-common/src/__tests__/test-helpers/environment.ts @@ -89,6 +89,7 @@ setSupportedCurrencies([ "telos_evm", "coreum", "injective", + "mantra", "vechain", "casper", "neon_evm", diff --git a/libs/ledger-live-common/src/account/helpers.ts b/libs/ledger-live-common/src/account/helpers.ts index fbb05526884f..a08c1db8f86f 100644 --- a/libs/ledger-live-common/src/account/helpers.ts +++ b/libs/ledger-live-common/src/account/helpers.ts @@ -78,6 +78,7 @@ export const getVotesCount = ( case "osmosis": case "cosmos": case "coreum": + case "mantra": return (mainAccount as CosmosAccount)?.cosmosResources?.delegations.length || 0; default: return 0; diff --git a/libs/ledger-live-common/src/currencies/__snapshots__/sortByMarketcap.test.ts.snap b/libs/ledger-live-common/src/currencies/__snapshots__/sortByMarketcap.test.ts.snap index c43deb66e359..f6fadb85fdb3 100644 --- a/libs/ledger-live-common/src/currencies/__snapshots__/sortByMarketcap.test.ts.snap +++ b/libs/ledger-live-common/src/currencies/__snapshots__/sortByMarketcap.test.ts.snap @@ -1630,6 +1630,7 @@ exports[`sortCurrenciesByIds snapshot 1`] = ` "scroll", "binance_beacon_chain", "etherlink", + "mantra", "ethereum/erc20/$aapl", "ethereum/erc20/$based", "ethereum/erc20/$die", diff --git a/libs/ledger-live-common/src/currencies/mock.ts b/libs/ledger-live-common/src/currencies/mock.ts index 1317c6ea1f23..f05492cca109 100644 --- a/libs/ledger-live-common/src/currencies/mock.ts +++ b/libs/ledger-live-common/src/currencies/mock.ts @@ -39,6 +39,7 @@ export const IDS = [ "axelar", "persistence", "onomy", + "mantra", ]; export const CURRENCIES_LIST: CryptoCurrency[] = [ @@ -505,4 +506,33 @@ export const CURRENCIES_LIST: CryptoCurrency[] = [ }, ], }, + { + type: "CryptoCurrency", + id: "mantra", + coinType: 118, + name: "Mantra", + managerAppName: "Cosmos", + ticker: "OM", + scheme: "mantra", + color: "#ffb386", + family: "cosmos", + units: [ + { + name: "Mantra", + code: "OM", + magnitude: 6, + }, + { + name: "Micro-Mantra", + code: "uom", + magnitude: 0, + }, + ], + explorerViews: [ + { + tx: "https://www.mintscan.io/mantra/txs/$hash", + address: "https://www.mintscan.io/mantra/validators/$address", + }, + ], + }, ]; diff --git a/libs/ledger-live-common/src/currencies/sortByMarketcap.test.ts b/libs/ledger-live-common/src/currencies/sortByMarketcap.test.ts index 807fde84f434..903b0195de9f 100644 --- a/libs/ledger-live-common/src/currencies/sortByMarketcap.test.ts +++ b/libs/ledger-live-common/src/currencies/sortByMarketcap.test.ts @@ -31,6 +31,7 @@ test("sortCurrenciesByIds simulate staking from portfolio", () => { "axelar", "persistence", "onomy", + "mantra", "quicksilver", ]); }); diff --git a/libs/ledger-live-common/src/families/cosmos/datasets/__snapshots__/cosmos.integration.test.ts.snap b/libs/ledger-live-common/src/families/cosmos/datasets/__snapshots__/cosmos.integration.test.ts.snap index 728ae8fe0646..9b120777e1bb 100644 --- a/libs/ledger-live-common/src/families/cosmos/datasets/__snapshots__/cosmos.integration.test.ts.snap +++ b/libs/ledger-live-common/src/families/cosmos/datasets/__snapshots__/cosmos.integration.test.ts.snap @@ -3,7 +3,7 @@ exports[`cosmos currency bridge scanAccounts cosmos seed 1 1`] = ` [ { - "balance": "2816227", + "balance": "2582334", "currencyId": "cosmos", "derivationMode": "", "freshAddress": "cosmos1g84934jpu3v5de5yqukkkhxmcvsw3u2ajxvpdl", @@ -12,7 +12,7 @@ exports[`cosmos currency bridge scanAccounts cosmos seed 1 1`] = ` "index": 0, "pendingOperations": [], "seedIdentifier": "0388459b2653519948b12492f1a0b464720110c147a8155d23d423a5cc3c21d89a", - "spendableBalance": "1286619", + "spendableBalance": "1052726", "swapHistory": [], "syncHash": undefined, "used": true, @@ -1179,6 +1179,27 @@ exports[`cosmos currency bridge scanAccounts cosmos seed 1 2`] = ` "type": "REWARD", "value": "15935", }, + { + "accountId": "js:2:cosmos:cosmos1g84934jpu3v5de5yqukkkhxmcvsw3u2ajxvpdl:", + "blockHash": null, + "blockHeight": 22822064, + "extra": { + "memo": "FE", + }, + "fee": "5664", + "hasFailed": false, + "hash": "8A811D6CBD6BC296D029076AF3CEFD4E3ABC06D9E9DC966BEC52DCE65BFC1E2F", + "id": "js:2:cosmos:cosmos1g84934jpu3v5de5yqukkkhxmcvsw3u2ajxvpdl:-8A811D6CBD6BC296D029076AF3CEFD4E3ABC06D9E9DC966BEC52DCE65BFC1E2F-OUT", + "recipients": [ + "osmo1g84934jpu3v5de5yqukkkhxmcvsw3u2a6al3md", + ], + "senders": [ + "cosmos1g84934jpu3v5de5yqukkkhxmcvsw3u2ajxvpdl", + ], + "transactionSequenceNumber": 139, + "type": "OUT", + "value": "233893", + }, { "accountId": "js:2:cosmos:cosmos1g84934jpu3v5de5yqukkkhxmcvsw3u2ajxvpdl:", "blockHash": null, diff --git a/libs/ledger-live-common/src/families/cosmos/datasets/__snapshots__/mantra.integration.test.ts.snap b/libs/ledger-live-common/src/families/cosmos/datasets/__snapshots__/mantra.integration.test.ts.snap new file mode 100644 index 000000000000..9180ecd83478 --- /dev/null +++ b/libs/ledger-live-common/src/families/cosmos/datasets/__snapshots__/mantra.integration.test.ts.snap @@ -0,0 +1,143 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`mantra currency bridge scanAccounts mantra seed 1 1`] = ` +[ + { + "balance": "715363", + "currencyId": "mantra", + "derivationMode": "", + "freshAddress": "mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn", + "freshAddressPath": "44'/118'/0'/0/0", + "id": "js:2:mantra:mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn:", + "index": 0, + "pendingOperations": [], + "seedIdentifier": "03d5e0ebb3f1ae2afe87e5d5a24b5029a59cc12f8fd1056840091b2f0b97e54e83", + "spendableBalance": "215363", + "swapHistory": [], + "syncHash": undefined, + "used": true, + "xpub": "mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn", + }, + { + "balance": "0", + "currencyId": "mantra", + "derivationMode": "", + "freshAddress": "mantra1v2mp0m7k96dm9qv60fkspcqlzpkzrwnefwef05", + "freshAddressPath": "44'/118'/1'/0/0", + "id": "js:2:mantra:mantra1v2mp0m7k96dm9qv60fkspcqlzpkzrwnefwef05:", + "index": 1, + "pendingOperations": [], + "seedIdentifier": "03d5e0ebb3f1ae2afe87e5d5a24b5029a59cc12f8fd1056840091b2f0b97e54e83", + "spendableBalance": "0", + "swapHistory": [], + "syncHash": undefined, + "used": false, + "xpub": "mantra1v2mp0m7k96dm9qv60fkspcqlzpkzrwnefwef05", + }, +] +`; + +exports[`mantra currency bridge scanAccounts mantra seed 1 2`] = ` +[ + [ + { + "accountId": "js:2:mantra:mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn:", + "blockHash": null, + "blockHeight": 446099, + "extra": {}, + "fee": "1950", + "hasFailed": false, + "hash": "4855629335DD67EEB42CC089311697D7F5FAE587CD7E33F81E0AAE5227B4FB8F", + "id": "js:2:mantra:mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn:-4855629335DD67EEB42CC089311697D7F5FAE587CD7E33F81E0AAE5227B4FB8F-IN", + "recipients": [ + "mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn", + ], + "senders": [ + "mantra1g84934jpu3v5de5yqukkkhxmcvsw3u2aedx9w9", + ], + "transactionSequenceNumber": 6, + "type": "IN", + "value": "1000000", + }, + { + "accountId": "js:2:mantra:mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn:", + "blockHash": null, + "blockHeight": 446137, + "extra": {}, + "fee": "1949", + "hasFailed": false, + "hash": "8F9934B90FC0006941F24FA783970CCC6480F991725E8D7A0BFDB3E917DECCB0", + "id": "js:2:mantra:mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn:-8F9934B90FC0006941F24FA783970CCC6480F991725E8D7A0BFDB3E917DECCB0-OUT", + "recipients": [ + "mantra1g84934jpu3v5de5yqukkkhxmcvsw3u2aedx9w9", + ], + "senders": [ + "mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn", + ], + "transactionSequenceNumber": 1, + "type": "OUT", + "value": "301949", + }, + { + "accountId": "js:2:mantra:mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn:", + "blockHash": null, + "blockHeight": 446147, + "extra": { + "memo": "Ledger Live", + }, + "fee": "2385", + "hasFailed": false, + "hash": "AAC85BCAA8EB83298CABABB6A6574082C056092C7139FD8C8ED8849A207B8C8A", + "id": "js:2:mantra:mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn:-AAC85BCAA8EB83298CABABB6A6574082C056092C7139FD8C8ED8849A207B8C8A-REWARD", + "recipients": [], + "senders": [], + "transactionSequenceNumber": 2, + "type": "REWARD", + "value": "0", + }, + { + "accountId": "js:2:mantra:mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn:", + "blockHash": null, + "blockHeight": 446122, + "extra": { + "memo": "Ledger Live", + "validators": [ + { + "address": "mantravaloper1y8hxa8q0qk6h2fxtugkx67re38k03888eeqmpd", + "amount": "500000", + }, + ], + }, + "fee": "2906", + "hasFailed": false, + "hash": "B1FE340869D47C458F2B6CCD6029E9996B3CC957BE01E8426A7686E50B2987B4", + "id": "js:2:mantra:mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn:-B1FE340869D47C458F2B6CCD6029E9996B3CC957BE01E8426A7686E50B2987B4-DELEGATE", + "recipients": [], + "senders": [], + "transactionSequenceNumber": 0, + "type": "DELEGATE", + "value": "2906", + }, + { + "accountId": "js:2:mantra:mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn:", + "blockHash": null, + "blockHeight": 445531, + "extra": {}, + "fee": "2125", + "hasFailed": false, + "hash": "E6FA7ACE758FE1C371CDE0503651D07D3F25F65BE2A57B642CC5F3B3D6A3A5F7", + "id": "js:2:mantra:mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn:-E6FA7ACE758FE1C371CDE0503651D07D3F25F65BE2A57B642CC5F3B3D6A3A5F7-IN", + "recipients": [ + "mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn", + ], + "senders": [ + "mantra1g84934jpu3v5de5yqukkkhxmcvsw3u2aedx9w9", + ], + "transactionSequenceNumber": 5, + "type": "IN", + "value": "20000", + }, + ], + [], +] +`; diff --git a/libs/ledger-live-common/src/families/cosmos/datasets/mantra.integration.test.ts b/libs/ledger-live-common/src/families/cosmos/datasets/mantra.integration.test.ts new file mode 100644 index 000000000000..6461577f5410 --- /dev/null +++ b/libs/ledger-live-common/src/families/cosmos/datasets/mantra.integration.test.ts @@ -0,0 +1,14 @@ +import { DatasetTest } from "@ledgerhq/types-live"; +import { testBridge } from "../../../__tests__/test-helpers/bridge"; +import "../../../__tests__/test-helpers/setup"; +import type { Transaction } from "../types"; +import mantra from "./mantra"; + +const dataset: DatasetTest = { + implementations: ["js"], + currencies: { + mantra, + }, +}; + +testBridge(dataset); diff --git a/libs/ledger-live-common/src/families/cosmos/datasets/mantra.ts b/libs/ledger-live-common/src/families/cosmos/datasets/mantra.ts new file mode 100644 index 000000000000..4e80fdf421c2 --- /dev/null +++ b/libs/ledger-live-common/src/families/cosmos/datasets/mantra.ts @@ -0,0 +1,70 @@ +import { fromTransactionRaw } from "@ledgerhq/coin-cosmos/transaction"; +import { CurrenciesData } from "@ledgerhq/types-live"; +import { BigNumber } from "bignumber.js"; +import type { Transaction } from "../types"; + +const dataset: CurrenciesData = { + FIXME_ignoreAccountFields: ["cosmosResources", "operationsCount", "operations"], + FIXME_ignorePreloadFields: ["validators"], // the APY of validators changes over time + scanAccounts: [ + { + name: "mantra seed 1", + apdus: ` + => 550400001b066d616e7472612c00008076000080000000800000000000000000 + <= 03d5e0ebb3f1ae2afe87e5d5a24b5029a59cc12f8fd1056840091b2f0b97e54e836d616e7472613167796175766c3434713261706e33753361756a6d333671387a726a3734767279376e356e766e9000 + => 550400001b066d616e7472612c00008076000080000000800000000000000000 + <= 03d5e0ebb3f1ae2afe87e5d5a24b5029a59cc12f8fd1056840091b2f0b97e54e836d616e7472613167796175766c3434713261706e33753361756a6d333671387a726a3734767279376e356e766e9000 + => 550400001b066d616e7472612c00008076000080010000800000000000000000 + <= 02c8f29e73a2c99d11de0544615a87afc6c6575d22746af18a8ef733066f088b1f6d616e7472613176326d70306d376b3936646d3971763630666b737063716c7a706b7a72776e656677656630359000 + `, + }, + ], + accounts: [ + { + FIXME_tests: ["balance is sum of ops", "pendingOperations are cleaned up"], + raw: { + id: "js:2:mantra:mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn:", + seedIdentifier: "03d5e0ebb3f1ae2afe87e5d5a24b5029a59cc12f8fd1056840091b2f0b97e54e83", + xpub: "mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn", + derivationMode: "", + index: 0, + freshAddress: "mantra1gyauvl44q2apn3u3aujm36q8zrj74vry7n5nvn", + freshAddressPath: "44'/118'/0'/0/0", + name: "Mantra 1 - Nano X", + blockHeight: 446179, + balance: "715363", + spendableBalance: "215363", + operations: [], + operationsCount: 5, + pendingOperations: [], + currencyId: "mantra", + lastSyncDate: "", + }, + transactions: [ + { + name: "Normal transaction", + transaction: fromTransactionRaw({ + amount: "10000", + recipient: "mantra108uy5q9jt59gwugq5yrdhkzcd9jryslm2n604w", + useAllAmount: false, + family: "cosmos", + mode: "send", + networkInfo: null, + fees: "8744", + gas: "87440", + validators: [], + memo: "", + sourceValidator: "", + }), + expectedStatus: () => ({ + errors: {}, + warnings: {}, + amount: BigNumber("10000"), + }), + }, + ], + }, + ], +}; + +export default dataset; diff --git a/libs/ledger-live-common/src/featureFlags/defaultFeatures.ts b/libs/ledger-live-common/src/featureFlags/defaultFeatures.ts index 1821b3bbbedc..bb83c156a9b6 100644 --- a/libs/ledger-live-common/src/featureFlags/defaultFeatures.ts +++ b/libs/ledger-live-common/src/featureFlags/defaultFeatures.ts @@ -80,6 +80,7 @@ export const CURRENCY_DEFAULT_FEATURES = { currencyIcon: DEFAULT_FEATURE, currencyTon: DEFAULT_FEATURE, currencyEtherlink: DEFAULT_FEATURE, + currencyMantra: DEFAULT_FEATURE, }; /** diff --git a/libs/ledgerjs/packages/cryptoassets/src/abandonseed.ts b/libs/ledgerjs/packages/cryptoassets/src/abandonseed.ts index 768878395194..904e532ad68b 100644 --- a/libs/ledgerjs/packages/cryptoassets/src/abandonseed.ts +++ b/libs/ledgerjs/packages/cryptoassets/src/abandonseed.ts @@ -110,6 +110,7 @@ const abandonSeedAddresses: Partial> = { scroll: EVM_DEAD_ADDRESS, scroll_sepolia: EVM_DEAD_ADDRESS, etherlink: EVM_DEAD_ADDRESS, + mantra: "mantra12jypwtxm7npfszx5x9780fhz0j3ken696fdp33", }; /** diff --git a/libs/ledgerjs/packages/cryptoassets/src/currencies.ts b/libs/ledgerjs/packages/cryptoassets/src/currencies.ts index f58e1fe0a612..da7d2a0d5074 100644 --- a/libs/ledgerjs/packages/cryptoassets/src/currencies.ts +++ b/libs/ledgerjs/packages/cryptoassets/src/currencies.ts @@ -4275,6 +4275,35 @@ export const cryptocurrenciesById: Record = { }, ], }, + mantra: { + type: "CryptoCurrency", + id: "mantra", + coinType: CoinType.ATOM, + name: "Mantra", + managerAppName: "Cosmos", + ticker: "OM", + scheme: "mantra", + color: "#ffb386", + family: "cosmos", + units: [ + { + name: "Mantra", + code: "OM", + magnitude: 6, + }, + { + name: "Micro-Mantra", + code: "uom", + magnitude: 0, + }, + ], + explorerViews: [ + { + tx: "https://www.mintscan.io/mantra/txs/$hash", + address: "https://www.mintscan.io/mantra/validators/$address", + }, + ], + }, }; const cryptocurrenciesByScheme: Record = {}; diff --git a/libs/ledgerjs/packages/types-cryptoassets/src/index.ts b/libs/ledgerjs/packages/types-cryptoassets/src/index.ts index f8555ac0510c..255581d3f1a3 100644 --- a/libs/ledgerjs/packages/types-cryptoassets/src/index.ts +++ b/libs/ledgerjs/packages/types-cryptoassets/src/index.ts @@ -148,6 +148,7 @@ export type CryptoCurrencyId = | "syscoin" | "internet_computer" | "injective" + | "mantra" | "telos_evm" | "klaytn" | "polygon_zk_evm" diff --git a/libs/ledgerjs/packages/types-live/src/feature.ts b/libs/ledgerjs/packages/types-live/src/feature.ts index 408842b58745..b389d175a946 100644 --- a/libs/ledgerjs/packages/types-live/src/feature.ts +++ b/libs/ledgerjs/packages/types-live/src/feature.ts @@ -121,6 +121,7 @@ export type CurrencyFeatures = { currencyIcon: DefaultFeature; currencyTon: DefaultFeature; currencyEtherlink: DefaultFeature; + currencyMantra: DefaultFeature; }; /** diff --git a/libs/ui/packages/crypto-icons/src/svg/OM.svg b/libs/ui/packages/crypto-icons/src/svg/OM.svg new file mode 100644 index 000000000000..a37c03c4b34f --- /dev/null +++ b/libs/ui/packages/crypto-icons/src/svg/OM.svg @@ -0,0 +1,17 @@ + + + + + + + +