open Base58 open Hash open Lwt.Infix type generator = Generator : { encoding: 'h encoding ; generator: string -> 'h list ; } -> generator let generators = ref [] let register_generator (type a) (encoding : a encoding) (generator : string -> a list) = generators := Generator { encoding ; generator } :: !generators let register (type t) (enc: t Base58.encoding) = register_generator enc (fun s -> match enc.of_raw (s ^ Sodium.Random.Bytes.generate (enc.length - String.length s)) with | Some x -> [x] | None -> []) let generate ?alphabet request = let rec find s = function | [] -> [] | Generator { encoding ; generator } :: generators -> if not (Utils.has_prefix ~prefix:encoding.encoded_prefix s) then find s generators else let prefix = partial_decode ?alphabet request encoding.encoded_length in let len = String.length prefix in let ignored = String.length encoding.prefix in if len <= ignored then [] else begin (* assert (String.sub prefix 0 ignored = encoding.prefix) ; *) let msg = String.sub prefix ignored (len - ignored) in let msgs = generator msg in List.map (fun msg -> simple_encode encoding ?alphabet msg) msgs end in find request !generators let () = register Hash.Block_hash.b58check_encoding ; register Hash.Protocol_hash.b58check_encoding ; if not (!Sys.interactive) then begin for i = 1 to Array.length Sys.argv - 1 do List.iter (Format.printf "%S@.") (generate Sys.argv.(i)) done end