2026-06-11 10:46:20 +02:00
|
|
|
namespace PalladiumWallet.Core.Chain;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2026-06-16 14:40:06 +02:00
|
|
|
/// Supported network type (single selector for the whole wallet, blueprint §3).
|
2026-06-11 10:46:20 +02:00
|
|
|
/// </summary>
|
|
|
|
|
public enum NetKind
|
|
|
|
|
{
|
|
|
|
|
Mainnet,
|
|
|
|
|
Testnet,
|
|
|
|
|
Regtest,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2026-06-16 14:40:06 +02:00
|
|
|
/// Supported script/address type (blueprint §4.3).
|
2026-06-11 10:46:20 +02:00
|
|
|
/// </summary>
|
|
|
|
|
public enum ScriptKind
|
|
|
|
|
{
|
|
|
|
|
/// <summary>P2PKH legacy.</summary>
|
|
|
|
|
Legacy,
|
|
|
|
|
|
|
|
|
|
/// <summary>P2SH-P2WPKH (segwit wrapped).</summary>
|
|
|
|
|
WrappedSegwit,
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>P2WPKH (native segwit) — recommended default.</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
NativeSegwit,
|
|
|
|
|
|
|
|
|
|
/// <summary>P2SH-P2WSH (multisig wrapped).</summary>
|
|
|
|
|
WrappedSegwitMultisig,
|
|
|
|
|
|
|
|
|
|
/// <summary>P2WSH (multisig native).</summary>
|
|
|
|
|
NativeSegwitMultisig,
|
2026-06-15 12:03:46 +02:00
|
|
|
|
|
|
|
|
/// <summary>P2TR key-path only (Taproot, BIP86) — witness v1, bech32m.</summary>
|
|
|
|
|
Taproot,
|
2026-06-11 10:46:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2026-06-16 14:40:06 +02:00
|
|
|
/// Pair of BIP32 version headers (4-byte big-endian) to serialize
|
|
|
|
|
/// xprv/xpub and SLIP-132 variants (y/z/Y/Z) — blueprint §3.
|
2026-06-11 10:46:20 +02:00
|
|
|
/// </summary>
|
|
|
|
|
public readonly record struct ExtKeyHeaders(uint Private, uint Public)
|
|
|
|
|
{
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>Private header as 4 big-endian bytes (to prepend to the BIP32 payload).</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public byte[] PrivateBytes() => ToBytes(Private);
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>Public header as 4 big-endian bytes.</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public byte[] PublicBytes() => ToBytes(Public);
|
|
|
|
|
|
|
|
|
|
internal static byte[] ToBytes(uint header) =>
|
|
|
|
|
[
|
|
|
|
|
(byte)(header >> 24),
|
|
|
|
|
(byte)(header >> 16),
|
|
|
|
|
(byte)(header >> 8),
|
|
|
|
|
(byte)header,
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2026-06-16 14:40:06 +02:00
|
|
|
/// Bootstrap indexing server: host + TCP port + SSL port (blueprint §3/§9).
|
2026-06-11 10:46:20 +02:00
|
|
|
/// </summary>
|
|
|
|
|
public readonly record struct ServerEndpoint(string Host, int TcpPort, int SslPort);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2026-06-16 14:40:06 +02:00
|
|
|
/// Chain checkpoint: anchors trust when PoW validation is disabled
|
|
|
|
|
/// (blueprint §7.3). Target serialized as compact "bits".
|
2026-06-11 10:46:20 +02:00
|
|
|
/// </summary>
|
|
|
|
|
public readonly record struct Checkpoint(int Height, string BlockHash, uint Bits);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2026-06-16 14:40:06 +02:00
|
|
|
/// Network/chain profile (blueprint §3): all chain-specific constants,
|
|
|
|
|
/// centralized in one place. No magic numbers elsewhere in the code.
|
2026-06-11 10:46:20 +02:00
|
|
|
/// </summary>
|
|
|
|
|
public sealed record ChainProfile
|
|
|
|
|
{
|
|
|
|
|
public required NetKind Kind { get; init; }
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>Network name, also used as the data subfolder.</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public required string NetName { get; init; }
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>Unit symbol (e.g. PLM).</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public required string CoinUnit { get; init; }
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>WIF prefix for private keys.</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public required byte WifPrefix { get; init; }
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>Version byte for P2PKH addresses.</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public required byte AddrP2pkh { get; init; }
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>Version byte for P2SH addresses.</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public required byte AddrP2sh { get; init; }
|
|
|
|
|
|
|
|
|
|
/// <summary>Human-readable part bech32/bech32m.</summary>
|
|
|
|
|
public required string SegwitHrp { get; init; }
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>HRP for BOLT11 invoices (Lightning, later phase — §11).</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public required string Bolt11Hrp { get; init; }
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>Genesis block hash (hex, explorer byte order).</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public required string GenesisHash { get; init; }
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>TCP port of the indexing server (not the node's P2P port).</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public required int DefaultTcpPort { get; init; }
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>SSL port of the indexing server.</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public required int DefaultSslPort { get; init; }
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>Node's P2P port — informational only: the SPV wallet does not use it.</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public required int NodeP2pPort { get; init; }
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>SLIP-0044 coin type in derivation paths (wallet convention).</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public required int Bip44CoinType { get; init; }
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>BIP21 payment URI scheme (without the colon).</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public required string UriScheme { get; init; }
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>Default block explorer.</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public required string ExplorerUrl { get; init; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2026-06-16 14:40:06 +02:00
|
|
|
/// The chain uses LWMA (per-block retargeting, 2 minutes): an SPV client cannot
|
|
|
|
|
/// recompute it, so bits/target validation must be skipped and trust anchored
|
|
|
|
|
/// to checkpoints (§3/§7). For the reference chain it is always true.
|
2026-06-11 10:46:20 +02:00
|
|
|
/// </summary>
|
|
|
|
|
public required bool SkipPowValidation { get; init; }
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>Target block time in seconds (LWMA v2: 120s).</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public required int BlockTimeSeconds { get; init; }
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>BIP32/SLIP-132 headers for each script type.</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public required IReadOnlyDictionary<ScriptKind, ExtKeyHeaders> ExtKeyHeaders { get; init; }
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>Indexing servers for first contact (bootstrap).</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public required IReadOnlyList<ServerEndpoint> BootstrapServers { get; init; }
|
|
|
|
|
|
2026-06-16 14:40:06 +02:00
|
|
|
/// <summary>Hardcoded checkpoints, updated at every release (§7.3).</summary>
|
2026-06-11 10:46:20 +02:00
|
|
|
public required IReadOnlyList<Checkpoint> Checkpoints { get; init; }
|
|
|
|
|
}
|