chore: drop Omni support from Core and Legacy firmware
What changed, and why it matters
This commit removes support for the old Omni Layer protocol from Trezor hardware wallets. Omni was used for assets like USDT (Tether) on Bitcoin before those tokens moved to other blockchains. After this change, any transaction that previously showed a friendly 'Simple send of X USDT' message will instead be shown as raw 'OP_RETURN' data. This is a deliberate feature removal, not a security fix, and it does not introduce a vulnerability.
No security action required. Users who still hold Omni-based assets should be aware that Trezor will no longer display human-readable Omni transaction summaries and will instead show raw OP_RETURN data, so they should verify such transactions carefully before signing.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit deletes the Omni parsing modules (core/src/apps/bitcoin/sign_tx/omni.py, legacy/firmware/layout2.c’s layoutConfirmOmni, and related tests/qstr entries) and removes ‘misc:OMNI’ from coin definition/support tables. For OP_RETURN outputs, both Core and Legacy firmware now always use the generic confirm_blob / layoutConfirmOpReturn flow instead of the special-case Omni flow. The change is framed as a chore because Tether no longer supports Omni.
Changed components
core/src/apps/bitcoin/sign_tx/layout.pycore/src/apps/bitcoin/sign_tx/omni.pylegacy/firmware/layout2.clegacy/firmware/signing.ccommon/defs/misc/misc.jsoncommon/defs/support.jsonInspect captured patch +11 / −166
### common/defs/misc/misc.json
@@ -62,13 +62,6 @@
"curve": "secp256k1",
"decimals": 4
},
- {
- "name": "Omni",
- "shortcut": "OMNI",
- "slip44": 0,
- "curve": "secp256k1",
- "decimals": 2
- },
{
"name": "MaidSafeCoin",
"shortcut": "MAID",
### common/defs/support.json
@@ -91,7 +91,6 @@
"eth:tHOD:560048": "2.9.3",
"eth:tSEP:11155111": "1.11.3",
"misc:MAID": "1.7.2",
- "misc:OMNI": "1.7.2",
"misc:USDT": "1.7.2",
"misc:XLM": "1.7.1",
"nem:BREEZE": "1.6.2",
@@ -206,7 +205,6 @@
"misc:BNB": "2.6.1",
"misc:DSOL": "2.6.4",
"misc:MAID": "2.6.1",
- "misc:OMNI": "2.6.1",
"misc:SOL": "2.6.4",
"misc:USDT": "2.6.1",
"misc:XLM": "2.6.1",
@@ -337,7 +335,6 @@
"misc:DSOL": "2.6.4",
"misc:EOS": "2.1.1",
"misc:MAID": "2.0.10",
- "misc:OMNI": "2.0.10",
"misc:SOL": "2.6.4",
"misc:USDT": "2.0.10",
"misc:XLM": "2.0.8",
@@ -448,7 +445,6 @@
"misc:BNB": "2.8.1",
"misc:DSOL": "2.8.1",
"misc:MAID": "2.8.1",
- "misc:OMNI": "2.8.1",
"misc:SOL": "2.8.1",
"misc:USDT": "2.8.1",
"misc:XLM": "2.8.1",
@@ -569,7 +565,6 @@
"misc:BNB": "2.6.1",
"misc:DSOL": "2.6.4",
"misc:MAID": "2.6.1",
- "misc:OMNI": "2.6.1",
"misc:SOL": "2.6.4",
"misc:USDT": "2.6.1",
"misc:XLM": "2.6.1",
@@ -690,7 +685,6 @@
"misc:BNB": "2.6.1",
"misc:DSOL": "2.6.4",
"misc:MAID": "2.6.1",
- "misc:OMNI": "2.6.1",
"misc:SOL": "2.6.4",
"misc:USDT": "2.6.1",
"misc:XLM": "2.6.1",
@@ -812,7 +806,6 @@
"misc:BNB": "2.6.1",
"misc:DSOL": "2.6.4",
"misc:MAID": "2.6.1",
- "misc:OMNI": "2.6.1",
"misc:SOL": "2.6.4",
"misc:USDT": "2.6.1",
"misc:XLM": "2.6.1",
@@ -934,7 +927,6 @@
"misc:BNB": "2.6.1",
"misc:DSOL": "2.6.4",
"misc:MAID": "2.6.1",
- "misc:OMNI": "2.6.1",
"misc:SOL": "2.6.4",
"misc:USDT": "2.6.1",
"misc:XLM": "2.6.1",
### core/.changelog.d/7968.removed
@@ -0,0 +1 @@
+Remove Omni support.
### core/embed/upymod/qstrdefsport.h
@@ -89,7 +89,6 @@ Q(apps.bitcoin.sign_tx.decred)
Q(apps.bitcoin.sign_tx.helpers)
Q(apps.bitcoin.sign_tx.layout)
Q(apps.bitcoin.sign_tx.matchcheck)
-Q(apps.bitcoin.sign_tx.omni)
Q(apps.bitcoin.sign_tx.progress)
Q(apps.bitcoin.sign_tx.sig_hasher)
Q(apps.bitcoin.sign_tx.tx_info)
@@ -266,7 +265,6 @@ Q(messages)
Q(misc)
Q(multisig)
Q(nostr)
-Q(omni)
Q(ownership)
Q(pair_new_device)
Q(passphrase)
### core/src/apps/bitcoin/sign_tx/layout.py
@@ -5,7 +5,6 @@
from trezor.enums import ButtonRequestType
from trezor.strings import format_amount, format_amount_unit
from trezor.ui import layouts
-from trezor.ui.layouts import confirm_metadata
from apps.common.paths import address_n_to_str
@@ -68,28 +67,16 @@ async def confirm_output(
) -> None:
from trezor.enums import OutputScriptType
- from . import omni
-
if output.script_type == OutputScriptType.PAYTOOPRETURN:
data = output.op_return_data
assert data is not None
- if omni.is_valid(data):
- # OMNI transaction
- layout = confirm_metadata(
- "omni_transaction",
- "OMNI transaction",
- omni.parse(data),
- verb=TR.buttons__confirm,
- br_code=ButtonRequestType.ConfirmOutput,
- )
- else:
- # generic OP_RETURN
- layout = layouts.confirm_blob(
- "op_return",
- "OP_RETURN",
- data,
- br_code=ButtonRequestType.ConfirmOutput,
- )
+ # generic OP_RETURN
+ layout = layouts.confirm_blob(
+ "op_return",
+ "OP_RETURN",
+ data,
+ br_code=ButtonRequestType.ConfirmOutput,
+ )
else:
assert output.address is not None
address_short = addresses.address_short(coin, output.address)
### core/src/apps/bitcoin/sign_tx/omni.py
@@ -1,37 +0,0 @@
-from micropython import const
-from typing import TYPE_CHECKING
-
-if TYPE_CHECKING:
- from buffer_types import AnyBytes
-
-
-_OMNI_DECIMALS = const(8)
-
-currencies = {
- 1: ("OMNI", _OMNI_DECIMALS),
- 2: ("tOMNI", _OMNI_DECIMALS),
- 3: ("MAID", 0),
- 31: ("USDT", _OMNI_DECIMALS),
-}
-
-
-def is_valid(data: AnyBytes) -> bool:
- return len(data) >= 8 and data[:4] == b"omni"
-
-
-def parse(data: AnyBytes) -> str:
- from struct import unpack
-
- from trezor import TR
- from trezor.strings import format_amount, format_amount_unit
-
- if not is_valid(data):
- raise ValueError # tried to parse data that fails validation
- tx_version, tx_type = unpack(">HH", data[4:8])
- if tx_version == 0 and tx_type == 0 and len(data) == 20: # OMNI simple send
- currency, amount = unpack(">IQ", data[8:20])
- suffix, decimals = currencies.get(currency, ("UNKN", 0))
- return f"{TR.bitcoin__simple_send_of} {format_amount_unit(format_amount(amount, decimals), suffix)}"
- else:
- # unknown OMNI transaction
- return TR.bitcoin__unknown_transaction
### core/tests/test_apps.bitcoin.signtx.omni.py
@@ -1,36 +0,0 @@
-# flake8: noqa: F403,F405
-from common import * # isort:skip
-
-from apps.bitcoin.sign_tx.omni import is_valid, parse
-
-
-class TestSignTxOmni(unittest.TestCase):
- def test_is_valid(self):
- VECTORS = {
- "6f6d6e69": False,
- "6f6d6e69000000": False,
- "6f6d6e6900000000": True,
- "6f6d6e69000000000000001f0000000020c85580": True,
- "0f6d6e69000000000000001f0000000020c85580": False,
- "6f6d6e69000000000000001f0000000020c8558000": True,
- "6f6d6e69000000000000001f0000000020c855": True,
- }
- for k, v in VECTORS.items():
- k = bytes.fromhex(k)
- self.assertEqual(is_valid(k), v)
-
- def test_parse(self):
- VECTORS = {
- "6f6d6e69000000000000001f000000002b752ee0": "Simple send of 7.291 USDT",
- "6f6d6e69000000000000001f0000000020c85580": "Simple send of 5.5 USDT",
- "6f6d6e690000000000000003000000002b752ee0": "Simple send of 729,100,000 MAID",
- "6f6d6e690000000000000000000000002b752ee0": "Simple send of 729,100,000 UNKN",
- "6f6d6e6901000000": "Unknown transaction",
- }
- for k, v in VECTORS.items():
- k = bytes.fromhex(k)
- self.assertEqual(parse(k), v)
-
-
-if __name__ == "__main__":
- unittest.main()
### core/tools/upysize_ignore.json
@@ -72,9 +72,6 @@
"output_script_p2pkh",
"output_script_p2sh"
],
- "src/apps/bitcoin/sign_tx/omni.py": [
- "is_valid"
- ],
"src/apps/bitcoin/sign_tx/progress.py": [
"report_init"
],
### legacy/firmware/.changelog.d/7968.removed
@@ -0,0 +1 @@
+Remove Omni support.
### legacy/firmware/layout2.c
@@ -486,48 +486,6 @@ void layoutConfirmOutput(const CoinInfo *coin, AmountUnit amount_unit,
extra_line);
}
-void layoutConfirmOmni(const uint8_t *data, uint32_t size) {
- const char *desc = NULL;
- char str_out[32] = {0};
- uint32_t tx_type = 0, currency = 0;
- REVERSE32(*(const uint32_t *)(data + 4), tx_type);
- if (tx_type == 0x00000000 && size == 20) { // OMNI simple send
- desc = _("Simple send of ");
- REVERSE32(*(const uint32_t *)(data + 8), currency);
- const char *suffix = " UNKN";
- bool divisible = false;
- switch (currency) {
- case 1:
- suffix = " OMNI";
- divisible = true;
- break;
- case 2:
- suffix = " tOMNI";
- divisible = true;
- break;
- case 3:
- suffix = " MAID";
- divisible = false;
- break;
- case 31:
- suffix = " USDT";
- divisible = true;
- break;
- }
- uint64_t amount_be = 0, amount = 0;
- memcpy(&amount_be, data + 12, sizeof(uint64_t));
- REVERSE64(amount_be, amount);
- bn_format_amount(amount, NULL, suffix, divisible ? 8 : 0, str_out,
- sizeof(str_out));
- } else {
- desc = _("Unknown transaction");
- str_out[0] = 0;
- }
- layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL,
- _("Confirm OMNI Transaction:"), NULL, desc, NULL, str_out,
- NULL);
-}
-
bool is_valid_ascii(const uint8_t *data, uint32_t size) {
for (uint32_t i = 0; i < size; i++) {
if (data[i] < ' ' || data[i] > '~') {
### legacy/firmware/layout2.h
@@ -59,7 +59,6 @@ void layoutBusyscreen(void);
void layoutHome(void);
void layoutConfirmOutput(const CoinInfo *coin, AmountUnit amount_unit,
const TxOutputType *out);
-void layoutConfirmOmni(const uint8_t *data, uint32_t size);
void layoutConfirmOpReturn(const uint8_t *data, uint32_t size);
void layoutConfirmTx(const CoinInfo *coin, AmountUnit amount_unit,
uint64_t total_in, uint64_t external_in,
### legacy/firmware/signing.c
@@ -2027,14 +2027,7 @@ static bool compile_output(TxOutputType *in, TxOutputBinType *out,
return false;
}
if (needs_confirm) {
- if (in->op_return_data.size >= 8 &&
- memcmp(in->op_return_data.bytes, "omni", 4) ==
- 0) { // OMNI transaction
- layoutConfirmOmni(in->op_return_data.bytes, in->op_return_data.size);
- } else {
- layoutConfirmOpReturn(in->op_return_data.bytes,
- in->op_return_data.size);
- }
+ layoutConfirmOpReturn(in->op_return_data.bytes, in->op_return_data.size);
if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput,
false)) {
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
### tests/device_tests/bitcoin/test_op_return.py
@@ -132,7 +132,7 @@ def test_opreturn_address(session: Session):
out1 = messages.TxOutputType(
address_n=parse_path("m/44h/0h/0h/1/2"),
amount=0,
- op_return_data=b"OMNI TRANSACTION GOES HERE",
+ op_return_data=b"OP RETURN DATA",
script_type=messages.OutputScriptType.PAYTOOPRETURN,
)
### tools/check-bitcoin-only
@@ -3,7 +3,6 @@ RETURN=0
EXCEPTIONS=()
EXCEPTIONS+=( "decred" ) # "decred" figures in field names used by the bitcoin app
-EXCEPTIONS+=( "omni" ) # OMNI is part of the bitcoin app
EXCEPTIONS+=( "derive_cardano" ) # field name in Initialize message
# BIP39 or SLIP39 words that have "dash" and "ripple" in them
EXCEPTIONS+=( "dash" "ripple" )Why this scored 19/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.