Pure MoonBit Bech32/Bech32m codec and SegWit address validator.
本地准备状态:代码、测试、CI、示例和 Mooncakes 元数据已完成;GitHub 推送和 Mooncakes 正式发布仍需由参赛者使用正确账号完成并核验。
moon add SWJ-ai-srw/bech32-kitSWJ-ai-srw/bech32-kitlet encoded = @bech32.encode("moon", [0, 1, 2, 3, 4]).unwrap()
let decoded = @bech32.decode(encoded).unwrap()
println(decoded.hrp)let report = @bech32.validation_report("A12UEL5L")
println(report.valid)
println(report.variant)
let info = @bech32.inspect("A12UEL5L").unwrap()
println(@bech32.case_style_name(info.case_style))let report = @bech32.scan_segwit_text("pay bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4")
println(report.segwit_valid)
let policy = @bech32.bitcoin_mainnet_segwit_policy()
let check = @bech32.check_with_policy(
"bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4",
policy,
)
println(check.accepted)moon run cmd/mainbc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4moon fmt --check
moon check
moon build
moon test
moon run cmd/main
moon check --deny-warn
moon test --deny-warn
moon infopub(all) enum Bech32Error {
EmptyInput
TooLong(Int)
MissingSeparator
EmptyHrp
EmptyData
MixedCase
InvalidHrpChar(Char, Int)
InvalidDataChar(Char, Int)
InvalidDataValue(Int, Int)
InvalidChecksum
InvalidBitGroup(Int, Int)
InvalidPadding
InvalidWitnessVersion(Int)
InvalidWitnessProgramLength(Int, Int)
InvalidWitnessEncoding(Variant, Variant)
UnexpectedHrp(String, String)
UnexpectedNetwork(SegwitNetwork, SegwitNetwork)
} derive(Eq, Debug)pub(all) struct Bech32Info {
input : String
normalized : String
hrp : String
data : Array[Int]
checksum : Array[Int]
variant : Variant
total_length : Int
separator_index : Int
data_part_length : Int
data_length : Int
checksum_length : Int
case_style : CaseStyle
segwit_valid : Bool
} derive(Eq, Debug)pub(all) struct Bech32Policy {
name : String
allow_any_hrp : Bool
allowed_hrps : Array[String]
allow_bech32 : Bool
allow_bech32m : Bool
require_canonical : Bool
require_segwit : Bool
allow_any_network : Bool
allowed_networks : Array[String]
allow_any_program_kind : Bool
allowed_program_kinds : Array[String]
min_payload_words : Int
max_payload_words : Int
} derive(Eq, Debug)pub(all) struct ComparisonReport {
left_input : String
right_input : String
left_valid : Bool
right_valid : Bool
left_segwit_valid : Bool
right_segwit_valid : Bool
left_canonical : Bool
right_canonical : Bool
left_variant : String
right_variant : String
left_case_style : CaseStyle
right_case_style : CaseStyle
left_hrp : String
right_hrp : String
left_network : String
right_network : String
left_program_kind : String
right_program_kind : String
left_error_code : String
right_error_code : String
same_validity : Bool
same_segwit_validity : Bool
same_canonicality : Bool
same_variant : Bool
same_case_style : Bool
same_hrp : Bool
same_network : Bool
same_program_kind : Bool
same_error_code : Bool
same_length : Bool
difference_count : Int
} derive(Eq, Debug)pub(all) struct Diagnostic {
input : String
normalized : String
valid : Bool
segwit_valid : Bool
canonical : Bool
severity : DiagnosticSeverity
recommendation : DiagnosticRecommendation
case_style : CaseStyle
variant : String
hrp : String
network : String
program_kind : String
error_code : String
error_message : String
hints : Array[String]
} derive(Eq, Debug)pub(all) enum DiagnosticRecommendation {
RecommendNone
RecommendNormalizeInput
RecommendLowercaseInput
RecommendCheckSeparator
RecommendCheckHrp
RecommendCheckCharset
RecommendCheckChecksum
RecommendCheckPadding
RecommendCheckWitnessVersion
RecommendCheckWitnessProgramLength
RecommendUseBech32
RecommendUseBech32m
RecommendCheckNetwork
RecommendCheckByteConversion
} derive(Eq, Debug)pub(all) struct PolicyCheck {
input : String
policy_name : String
accepted : Bool
valid : Bool
segwit_valid : Bool
canonical : Bool
variant : String
hrp : String
network : String
program_kind : String
payload_words : Int
failure : PolicyFailureKind
failure_code : String
failure_message : String
recommendation : String
} derive(Eq, Debug)pub(all) enum PolicyFailureKind {
PolicyFailureNone
PolicyFailureInvalidBech32(String)
PolicyFailureNotCanonical
PolicyFailureVariantNotAllowed(String)
PolicyFailureHrpNotAllowed(String)
PolicyFailurePayloadTooShort(Int, Int)
PolicyFailurePayloadTooLong(Int, Int)
PolicyFailureSegwitRequired
PolicyFailureNetworkNotAllowed(String)
PolicyFailureProgramKindNotAllowed(String)
} derive(Eq, Debug)pub(all) struct PolicySummary {
policy_name : String
total : Int
accepted : Int
rejected : Int
rejected_invalid : Int
rejected_not_canonical : Int
rejected_variant : Int
rejected_hrp : Int
rejected_payload_too_short : Int
rejected_payload_too_long : Int
rejected_segwit_required : Int
rejected_network : Int
rejected_program_kind : Int
} derive(Eq, Debug)pub(all) struct ScanFinding {
span : CandidateSpan
diagnostic : Diagnostic
accepted : Bool
reason : String
duplicate_of : Int
} derive(Eq, Debug)pub(all) struct ScanIssue {
kind : ScanIssueKind
severity : DiagnosticSeverity
finding_index : Int
related_index : Int
input : String
normalized : String
message : String
recommendation : DiagnosticRecommendation
} derive(Eq, Debug)pub(all) struct ScanOptions {
min_length : Int
max_length : Int
include_invalid : Bool
mode : ScanMode
require_canonical : Bool
require_standard_segwit_hrp : Bool
expected_hrp : String
expected_network : String
accept_uppercase : Bool
accept_mixed_case : Bool
boundary_style : ScanBoundaryStyle
deduplicate : Bool
} derive(Eq, Debug)pub(all) struct ScanReport {
source : String
findings : Array[ScanFinding]
summary : ValidationSummary
total_candidates : Int
accepted : Int
rejected : Int
valid : Int
invalid : Int
segwit_valid : Int
canonical : Int
duplicate : Int
} derive(Eq, Debug)pub(all) struct SegwitInfo {
input : String
normalized : String
hrp : String
version : Int
program : Array[Int]
program_length : Int
variant : Variant
network : SegwitNetwork
program_kind : WitnessProgramKind
} derive(Eq, Debug)pub(all) struct ValidationSummary {
total : Int
valid : Int
invalid : Int
segwit_valid : Int
canonical : Int
ok : Int
info : Int
warning : Int
error : Int
case_no_letters : Int
case_lower : Int
case_upper : Int
case_mixed : Int
variant_bech32 : Int
variant_bech32m : Int
network_mainnet : Int
network_testnet : Int
network_regtest : Int
network_unknown : Int
program_p2wpkh : Int
program_p2wsh : Int
program_taproot : Int
program_other : Int
recommend_none : Int
recommend_normalize_input : Int
recommend_lowercase_input : Int
recommend_check_separator : Int
recommend_check_hrp : Int
recommend_check_charset : Int
recommend_check_checksum : Int
recommend_check_padding : Int
recommend_check_witness_version : Int
recommend_check_witness_program_length : Int
recommend_use_bech32 : Int
recommend_use_bech32m : Int
recommend_check_network : Int
recommend_check_byte_conversion : Int
error_empty_input : Int
error_too_long : Int
error_missing_separator : Int
error_empty_hrp : Int
error_empty_data : Int
error_mixed_case : Int
error_invalid_hrp_char : Int
error_invalid_data_char : Int
error_invalid_data_value : Int
error_invalid_checksum : Int
error_invalid_bit_group : Int
error_invalid_padding : Int
error_invalid_witness_version : Int
error_invalid_witness_program_length : Int
error_invalid_witness_encoding : Int
error_unexpected_hrp : Int
error_unexpected_network : Int
} derive(Eq, Debug)fn convert_bits(data : Array[Int], from_bits : Int, to_bits : Int, pad : Bool) -> Result[Array[Int], Bech32Error]fn decode_segwit_on_network(input : String, expected : SegwitNetwork) -> Result[SegwitAddress, Bech32Error]fn encode_with_variant(hrp : String, data : Array[Int], variant : Variant) -> Result[String, Bech32Error]fn filter_scan_findings_by_network(findings : Array[ScanFinding], network : String) -> Array[ScanFinding]fn is_canonical(input : String) -> Boolfn is_standard_segwit_hrp(hrp : String) -> Boolfn is_valid(input : String) -> Boolfn is_valid_segwit(input : String) -> Boolfn policy_with_payload_bounds(policy : Bech32Policy, min_payload_words : Int, max_payload_words : Int) -> Bech32Policyfn scan_options_boundary_style(options : ScanOptions, boundary_style : ScanBoundaryStyle) -> ScanOptionsfn scan_options_require_standard_segwit_hrp(options : ScanOptions, require_standard_segwit_hrp : Bool) -> ScanOptionsPure MoonBit Bech32/Bech32m codec and SegWit address validator.