MetacoSA / NBitcoin

Comprehensive Bitcoin library for the .NET framework.
MIT License
1.85k stars 839 forks source link

I cant create BIP84 Account Extended Public Key #1205

Open Sytehel-1337 opened 3 months ago

Sytehel-1337 commented 3 months ago

I tried many methods but I couldn't succeed. Can I do this with nbitcoin? if i can how can i do it (must be start with "zpub")

public static string GenerateExtendedPublicKeyFromMnemonic(string mnemonic)
    {

        ExtKey extendedKey = new Mnemonic(mnemonic).DeriveExtKey();

        KeyPath keyPath = new KeyPath("m/44'/0'/0'/0");
        ExtKey hardenedKey = extendedKey.Derive(keyPath);

        ExtPubKey extendedPublicKey = hardenedKey.Neuter();

        return extendedPublicKey.ToString(Network.Main);
    }

This code creates the extended public address very well for bip44, but when it comes to bip84 it does not create it.

Z-fly commented 2 months ago
using System;
using System.Runtime.InteropServices;
using NBitcoin;

namespace BitcoinAddressLib
{
    [ComVisible(true)]
    [Guid("12345678-90AB-CDEF-1234-567890ABCDEF")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface Ibtc
    {
        string GenerateAddressWrapper(string mnemonic, int bipType, int account, int chain, int addressIndex);
    }

    [ComVisible(true)]
    [Guid("ABCDEF12-3456-7890-CDEF-1234567890AB")]
    [ClassInterface(ClassInterfaceType.None)]
    public class BitcoinAddressGenerator : Ibtc
    {
        public string GenerateAddressWrapper(string mnemonic, int bipType, int account, int chain, int addressIndex)
        {
            ScriptPubKeyType addressType;
            switch (bipType)
            {
                case 44:
                    addressType = ScriptPubKeyType.Legacy;
                    break;
                case 49:
                    addressType = ScriptPubKeyType.SegwitP2SH;
                    break;
                case 84:
                    addressType = ScriptPubKeyType.Segwit;
                    break;
                default:
                    throw new ArgumentException("Unsupport");
            }

            BitcoinAddress address = GenerateBtcAddress(mnemonic, addressType, account, chain, addressIndex);
            System.Diagnostics.Debug.WriteLine($"Address: {address}");
            return address.ToString();
        }

        private static BitcoinAddress GenerateBtcAddress(string mnemonic, ScriptPubKeyType addressType, int account, int chain, int addressIndex)
        {
            Mnemonic mnemo = new Mnemonic(mnemonic, Wordlist.English);
            ExtKey masterKey = mnemo.DeriveExtKey();
            string derivationPath = $"m/{44}'/0'/{account}'/{chain}/{addressIndex}";
            if (addressType == ScriptPubKeyType.SegwitP2SH)
            {
                derivationPath = $"m/{49}'/0'/{account}'/{chain}/{addressIndex}";
            }
            else if (addressType == ScriptPubKeyType.Segwit)
            {
                derivationPath = $"m/{84}'/0'/{account}'/{chain}/{addressIndex}";
            }
            ExtKey key = masterKey.Derive(new KeyPath(derivationPath));
            return key.Neuter().PubKey.GetAddress(addressType, Network.Main);
        }
    }
}

Try this?