Skip to content

Commit d5089ae

Browse files
authored
Merge pull request #2 from mintlayer/feature/ledger-coin-type
Add CoinType used for Ledger and encode/decode utils
2 parents 4e21bf8 + 13b10db commit d5089ae

8 files changed

Lines changed: 203 additions & 21 deletions

File tree

.github/workflows/code_checks.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
- name: Install Rust
3737
run: |
3838
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \
39-
--default-toolchain $(python ./build-tools/cargo-info-extractor/extract.py --rust-version)
39+
--default-toolchain $(python ./build-tools/cargo-info-extractor/extract.py --rust-version-for-checks)
4040
4141
- name: Install Clippy
4242
run: rustup component add clippy
@@ -63,7 +63,7 @@ jobs:
6363
- name: Install Rust
6464
run: |
6565
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \
66-
--default-toolchain $(python ./build-tools/cargo-info-extractor/extract.py --rust-version)
66+
--default-toolchain $(python ./build-tools/cargo-info-extractor/extract.py --rust-version-for-checks)
6767
6868
- name: Install Clippy
6969
run: rustup component add clippy
@@ -99,7 +99,7 @@ jobs:
9999
shell: bash
100100
run: |
101101
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \
102-
--default-toolchain $(python ./build-tools/cargo-info-extractor/extract.py --rust-version)
102+
--default-toolchain $(python ./build-tools/cargo-info-extractor/extract.py --rust-version-for-checks)
103103
104104
- name: Install Clippy
105105
run: rustup component add clippy

Cargo.lock

Lines changed: 2 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,29 @@ repository = "https://github.com/mintlayer/mintlayer-core-primitives"
66
readme = "README.md"
77
license = "MIT"
88
version = "1.0.0"
9-
edition = "2024"
10-
rust-version = "1.88"
9+
edition = "2021"
10+
# Note: the maximum Rust version we can use here is limited by the Rust toolchains available
11+
# in the Nix packages and Docker images used by the Trezor firmware and Ledger app repositories.
12+
# There is also another Rust version hard-coded in `build-tools/cargo-info-extractor/extract.py` -
13+
# `RUST_VERSION_FOR_CHECKS`; it's used to run `do_checks.sh` and it may be higher than this one.
14+
rust-version = "1.85"
1115

1216
[dependencies]
13-
derive_more = { version = "2.0", default-features = false, features = ["debug"] }
17+
derive_more = { version = "2.0", default-features = false, features = [
18+
"debug",
19+
] }
1420
fixed-hash = { version = "0.8", default-features = false }
15-
parity-scale-codec = { version = "3.7", default-features = false, features = ["derive"] }
21+
22+
# Use the specific commit "5021525697edc0661591ebc71392c48d950a10b0",
23+
# which includes a fix for NanoX devices that do not support certain
24+
# atomic operations.
25+
#
26+
# Fix reference: https://github.com/paritytech/parity-scale-codec/pull/751
27+
# This fix should be included in releases after version 3.7.5.
28+
parity-scale-codec = { git = "https://github.com/paritytech/parity-scale-codec.git", rev = "5021525697edc0661591ebc71392c48d950a10b0", default-features = false, features = [
29+
"derive",
30+
] }
31+
1632
strum = { version = "0.27", default-features = false, features = ["derive"] }
1733

1834
[dev-dependencies]

build-tools/cargo-info-extractor/extract.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,14 @@
1212
ROOT_DIR = pathlib.Path(__file__).resolve().parent.parent.parent
1313
ROOT_CARGO_TOML = ROOT_DIR.joinpath("Cargo.toml")
1414

15+
# Note: running `do_checks.sh` may need a Rust version that is higher than the one we can use
16+
# for compilation. In particular, at the time of writing this, installing the latest cargo-deny
17+
# requires Rust 1.88.
18+
# TODO: put it elsewhere?
19+
RUST_VERSION_FOR_CHECKS = "1.88.0"
1520

16-
def get_rust_version(cargo_toml_root):
21+
22+
def get_rust_version_from_cargo_toml(cargo_toml_root):
1723
version = cargo_toml_root["package"]["rust-version"]
1824

1925
if len(version.split('.')) == 2:
@@ -23,17 +29,31 @@ def get_rust_version(cargo_toml_root):
2329

2430

2531
def main():
26-
parser = argparse.ArgumentParser()
32+
parser = argparse.ArgumentParser(
33+
# Use a bigger max_help_position, so that each parameter's help fits into one line.
34+
formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=30)
35+
)
2736
mutex_group = parser.add_mutually_exclusive_group(required=True)
28-
mutex_group.add_argument('--rust-version', action='store_true', help='extract Rust version')
37+
mutex_group.add_argument(
38+
'--rust-version',
39+
action='store_true',
40+
help='extract Rust version from Cargo.toml; this is the version that should be used for compilation'
41+
)
42+
mutex_group.add_argument(
43+
'--rust-version-for-checks',
44+
action='store_true',
45+
help='return the Rust version needed to run do_checks.sh'
46+
)
2947
args = parser.parse_args()
3048

3149
with open(ROOT_CARGO_TOML, "rb") as file:
3250
cargo_toml_root = tomllib.load(file)
3351

3452
if args.rust_version:
35-
result = get_rust_version(cargo_toml_root)
53+
result = get_rust_version_from_cargo_toml(cargo_toml_root)
3654
print(result)
55+
elif args.rust_version_for_checks:
56+
print(RUST_VERSION_FOR_CHECKS)
3757

3858

3959
if __name__ == "__main__":

src/coin_type.rs

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
// Copyright (c) 2024-2025 RBB S.r.l
2+
// opensource@mintlayer.org
3+
// SPDX-License-Identifier: MIT
4+
// Licensed under the MIT License;
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// https://github.com/mintlayer/mintlayer-core-primitives/blob/master/LICENSE
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
use crate::DestinationTag;
17+
18+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
19+
pub enum CoinType {
20+
Mainnet,
21+
Testnet,
22+
Regtest,
23+
Signet,
24+
}
25+
26+
impl CoinType {
27+
pub const fn coin_ticker(&self) -> &'static str {
28+
match self {
29+
Self::Mainnet => "ML",
30+
Self::Testnet => "TML",
31+
Self::Regtest => "RML",
32+
Self::Signet => "SML",
33+
}
34+
}
35+
36+
pub const fn bip44_coin_type(&self) -> u32 {
37+
let hardened_bit = 1 << 31;
38+
match self {
39+
Self::Mainnet => 19788 + hardened_bit,
40+
Self::Testnet | Self::Regtest | Self::Signet => 1 + hardened_bit,
41+
}
42+
}
43+
44+
pub const fn coin_decimals(&self) -> u8 {
45+
11
46+
}
47+
48+
pub const fn address_prefix(&self, destination: DestinationTag) -> &'static str {
49+
match self {
50+
Self::Mainnet => match destination {
51+
DestinationTag::AnyoneCanSpend => "mxanyonecanspend",
52+
DestinationTag::PublicKeyHash => "mtc",
53+
DestinationTag::PublicKey => "mptc",
54+
DestinationTag::ScriptHash => "mstc",
55+
DestinationTag::ClassicMultisig => "mmtc",
56+
},
57+
Self::Testnet => match destination {
58+
DestinationTag::AnyoneCanSpend => "txanyonecanspend",
59+
DestinationTag::PublicKeyHash => "tmt",
60+
DestinationTag::PublicKey => "tpmt",
61+
DestinationTag::ScriptHash => "tstc",
62+
DestinationTag::ClassicMultisig => "tmtc",
63+
},
64+
Self::Regtest => match destination {
65+
DestinationTag::AnyoneCanSpend => "rxanyonecanspend",
66+
DestinationTag::PublicKeyHash => "rmt",
67+
DestinationTag::PublicKey => "rpmt",
68+
DestinationTag::ScriptHash => "rstc",
69+
DestinationTag::ClassicMultisig => "rmtc",
70+
},
71+
Self::Signet => match destination {
72+
DestinationTag::AnyoneCanSpend => "sxanyonecanspend",
73+
DestinationTag::PublicKeyHash => "smt",
74+
DestinationTag::PublicKey => "spmt",
75+
DestinationTag::ScriptHash => "sstc",
76+
DestinationTag::ClassicMultisig => "smtc",
77+
},
78+
}
79+
}
80+
81+
pub const fn pool_id_address_prefix(&self) -> &'static str {
82+
match self {
83+
Self::Mainnet => "mpool",
84+
Self::Testnet => "tpool",
85+
Self::Regtest => "rpool",
86+
Self::Signet => "spool",
87+
}
88+
}
89+
90+
pub const fn delegation_id_address_prefix(&self) -> &'static str {
91+
match self {
92+
Self::Mainnet => "mdelg",
93+
Self::Testnet => "tdelg",
94+
Self::Regtest => "rdelg",
95+
Self::Signet => "sdelg",
96+
}
97+
}
98+
99+
pub const fn token_id_address_prefix(&self) -> &'static str {
100+
match self {
101+
Self::Mainnet => "mmltk",
102+
Self::Testnet => "tmltk",
103+
Self::Regtest => "rmltk",
104+
Self::Signet => "smltk",
105+
}
106+
}
107+
108+
pub const fn order_id_address_prefix(&self) -> &'static str {
109+
match self {
110+
Self::Mainnet => "mordr",
111+
Self::Testnet => "tordr",
112+
Self::Regtest => "rordr",
113+
Self::Signet => "sordr",
114+
}
115+
}
116+
117+
pub const fn vrf_public_key_address_prefix(&self) -> &'static str {
118+
match self {
119+
Self::Mainnet => "mvrfpk",
120+
Self::Testnet => "tvrfpk",
121+
Self::Regtest => "rvrfpk",
122+
Self::Signet => "svrfpk",
123+
}
124+
}
125+
}

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#![no_std]
1717

1818
mod accounts;
19+
mod coin_type;
1920
mod crypto;
2021
mod destination;
2122
mod id;
@@ -30,6 +31,7 @@ mod utxo_outpoint;
3031
mod tests;
3132

3233
pub use accounts::*;
34+
pub use coin_type::*;
3335
pub use crypto::*;
3436
pub use destination::*;
3537
pub use id::*;

src/misc.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// See the License for the specific language governing permissions and
1414
// limitations under the License.
1515

16-
use parity_scale_codec::{Decode, Encode};
16+
use parity_scale_codec::{Decode, DecodeAll, Encode};
1717

1818
use crate::TokenId;
1919

@@ -32,6 +32,8 @@ pub struct Amount {
3232
}
3333

3434
impl Amount {
35+
pub const ZERO: Self = Self::from_atoms(0);
36+
3537
pub const fn from_atoms(v: AmountUIntType) -> Self {
3638
Amount { atoms: v }
3739
}
@@ -89,3 +91,22 @@ pub type SecondsCountUIntType = u64;
8991

9092
#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Encode, Decode)]
9193
pub struct SecondsCount(#[codec(compact)] pub SecondsCountUIntType);
94+
95+
pub fn encode<T: Encode>(t: &T) -> PscVec<u8> {
96+
t.encode()
97+
}
98+
99+
pub fn encode_to<T: Encode>(t: &T, buf: &mut PscVec<u8>) {
100+
t.encode_to(buf)
101+
}
102+
103+
pub fn decode_all<T: Decode>(mut bytes: &[u8]) -> Result<T, parity_scale_codec::Error> {
104+
T::decode_all(&mut bytes)
105+
}
106+
107+
pub fn encode_as_compact<T>(num: T) -> PscVec<u8>
108+
where
109+
for<'a> parity_scale_codec::CompactRef<'a, T>: Encode + From<&'a T>,
110+
{
111+
parity_scale_codec::Compact::<T>::encode(&num.into())
112+
}

src/tests/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ use parity_scale_codec::Encode;
2525
use strum::IntoEnumIterator as _;
2626

2727
use crate::tests::utils::{
28+
SCALE_CODEC_COMPACT_ENC_10_BYTE_VAL_START, SCALE_CODEC_COMPACT_ENC_11_BYTE_VAL_START,
29+
SCALE_CODEC_COMPACT_ENC_12_BYTE_VAL_START, SCALE_CODEC_COMPACT_ENC_13_BYTE_VAL_START,
30+
SCALE_CODEC_COMPACT_ENC_14_BYTE_VAL_START, SCALE_CODEC_COMPACT_ENC_15_BYTE_VAL_START,
31+
SCALE_CODEC_COMPACT_ENC_16_BYTE_VAL_START, SCALE_CODEC_COMPACT_ENC_17_BYTE_VAL_START,
2832
SCALE_CODEC_COMPACT_ENC_2_BYTE_VAL_START, SCALE_CODEC_COMPACT_ENC_4_BYTE_VAL_START,
2933
SCALE_CODEC_COMPACT_ENC_5_BYTE_VAL_START, SCALE_CODEC_COMPACT_ENC_6_BYTE_VAL_START,
3034
SCALE_CODEC_COMPACT_ENC_7_BYTE_VAL_START, SCALE_CODEC_COMPACT_ENC_8_BYTE_VAL_START,
31-
SCALE_CODEC_COMPACT_ENC_9_BYTE_VAL_START, SCALE_CODEC_COMPACT_ENC_10_BYTE_VAL_START,
32-
SCALE_CODEC_COMPACT_ENC_11_BYTE_VAL_START, SCALE_CODEC_COMPACT_ENC_12_BYTE_VAL_START,
33-
SCALE_CODEC_COMPACT_ENC_13_BYTE_VAL_START, SCALE_CODEC_COMPACT_ENC_14_BYTE_VAL_START,
34-
SCALE_CODEC_COMPACT_ENC_15_BYTE_VAL_START, SCALE_CODEC_COMPACT_ENC_16_BYTE_VAL_START,
35-
SCALE_CODEC_COMPACT_ENC_17_BYTE_VAL_START,
35+
SCALE_CODEC_COMPACT_ENC_9_BYTE_VAL_START,
3636
};
3737

3838
use super::*;

0 commit comments

Comments
 (0)