Search code examples
c#blockchainbitcoinhidtrezor

Error Getting Address from GetAddress - Trezor Development


I'm building a C# HID library for the Trezor. It's working well. I'm able to get past the pin entry and retrieve my xpub, and I can get addresses. However, none of the addresses that are getting returned match any of my addresses in the Trezor wallet website.

You can see the HID doco here: https://doc.satoshilabs.com/trezor-tech/api-workflows.html#passphrase-meta-workflow

This is not really a C# question. Rather, it's a general question for any Trezor HID developers. The big problem is that if I pass a HDNodePathType message as the Multisig property of the GetAddress method, I get the error "Can't encode address'". What do I need to pass with the GetAddress message to get a valid address?

Here is an Android repo: https://github.com/trezor/trezor-android


Solution

  • This problem has now been resolved. Trezor.Net has a working example can be cloned here.

    Here is the code for getting an address:

    public async Task<string> GetAddressAsync(IAddressPath addressPath, bool isPublicKey, bool display, AddressType addressType, InputScriptType inputScriptType, string coinName)
    {
        try
        {
            var path = addressPath.ToArray();
    
            if (isPublicKey)
            {
                var publicKey = await SendMessageAsync<PublicKey, GetPublicKey>(new GetPublicKey { CoinName = coinName, AddressNs = path, ShowDisplay = display, ScriptType = inputScriptType });
                return publicKey.Xpub;
            }
            else
            {
                switch (addressType)
                {
                    case AddressType.Bitcoin:
    
                        //Ultra hack to deal with a coin name change in Firmware Version 1.6.2
                        if ((Features.MajorVersion <= 1 && Features.MinorVersion < 6) && coinName == "Bgold")
                        {
                            coinName = "Bitcoin Gold";
                        }
    
                        return (await SendMessageAsync<Address, GetAddress>(new GetAddress { ShowDisplay = display, AddressNs = path, CoinName = coinName, ScriptType = inputScriptType })).address;
    
                    case AddressType.Ethereum:
    
                        var ethereumAddress = await SendMessageAsync<EthereumAddress, EthereumGetAddress>(new EthereumGetAddress { ShowDisplay = display, AddressNs = path });
    
                        var sb = new StringBuilder();
                        foreach (var b in ethereumAddress.Address)
                        {
                            sb.Append(b.ToString("X2").ToLower());
                        }
    
                        var hexString = sb.ToString();
    
                        return $"0x{hexString}";
                    default:
                        throw new NotImplementedException();
                }
            }
        }
        catch (Exception ex)
        {
            Logger?.Log("Error Getting Trezor Address", LogSection, ex, LogLevel.Error);
            throw;
        }
    }