BIP32.fromBase58 constructor

BIP32.fromBase58(
  1. String string,
  2. [NetworkType? nw]
)

Implementation

factory BIP32.fromBase58(String string, [NetworkType? nw]) {
  Uint8List buffer = bs58check.decode(string);
  if (buffer.length != 78) throw new ArgumentError("Invalid buffer length");
  NetworkType network = nw ?? _BITCOIN;
  ByteData bytes = buffer.buffer.asByteData();
  // 4 bytes: version bytes
  var version = bytes.getUint32(0);
  if (version != network.bip32.private && version != network.bip32.public) {
    throw new ArgumentError("Invalid network version");
  }
  // 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ...
  var depth = buffer[4];

  // 4 bytes: the fingerprint of the parent's key (0x00000000 if master key)
  var parentFingerprint = bytes.getUint32(5);
  if (depth == 0) {
    if (parentFingerprint != 0x00000000) throw new ArgumentError("Invalid parent fingerprint");
  }

  // 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized.
  // This is encoded in MSB order. (0x00000000 if master key)
  var index = bytes.getUint32(9);
  if (depth == 0 && index != 0) throw new ArgumentError("Invalid index");

  // 32 bytes: the chain code
  Uint8List chainCode = buffer.sublist(13, 45);
  BIP32 hd;

  // 33 bytes: private key data (0x00 + k)
  if (version == network.bip32.private) {
    if (bytes.getUint8(45) != 0x00) throw new ArgumentError("Invalid private key");
    Uint8List k = buffer.sublist(46, 78);
    hd = BIP32.fromPrivateKey(k, chainCode, network);
  } else {
    // 33 bytes: public key data (0x02 + X or 0x03 + X)
    Uint8List X = buffer.sublist(45, 78);
    hd = BIP32.fromPublicKey(X, chainCode, network);
  }
  hd.depth = depth;
  hd.index = index;
  hd.parentFingerprint = parentFingerprint;
  return hd;
}