accounts, cmd, internal, mobile, node: canonical account URLs

This commit is contained in:
Péter Szilágyi
2017-02-08 15:53:02 +02:00
parent fad5eb0a87
commit c5215fdd48
19 changed files with 195 additions and 116 deletions

View File

@ -32,6 +32,9 @@ import (
"github.com/karalabe/gousb/usb"
)
// LedgerScheme is the protocol scheme prefixing account and wallet URLs.
var LedgerScheme = "ledger"
// ledgerDeviceIDs are the known device IDs that Ledger wallets use.
var ledgerDeviceIDs = []deviceID{
{Vendor: 0x2c97, Product: 0x0000}, // Ledger Blue
@ -124,23 +127,24 @@ func (hub *LedgerHub) refreshWallets() {
for i := 0; i < len(devIDs); i++ {
devID, busID := devIDs[i], busIDs[i]
url := fmt.Sprintf("ledger://%03d:%03d", busID>>8, busID&0xff)
url := accounts.URL{Scheme: LedgerScheme, Path: fmt.Sprintf("%03d:%03d", busID>>8, busID&0xff)}
// Drop wallets while they were in front of the next account
for len(hub.wallets) > 0 && hub.wallets[0].URL() < url {
for len(hub.wallets) > 0 && hub.wallets[0].URL().Cmp(url) < 0 {
events = append(events, accounts.WalletEvent{Wallet: hub.wallets[0], Arrive: false})
hub.wallets = hub.wallets[1:]
}
// If there are no more wallets or the account is before the next, wrap new wallet
if len(hub.wallets) == 0 || hub.wallets[0].URL() > url {
wallet := &ledgerWallet{context: hub.ctx, hardwareID: devID, locationID: busID, url: url}
if len(hub.wallets) == 0 || hub.wallets[0].URL().Cmp(url) > 0 {
wallet := &ledgerWallet{context: hub.ctx, hardwareID: devID, locationID: busID, url: &url}
events = append(events, accounts.WalletEvent{Wallet: wallet, Arrive: true})
wallets = append(wallets, wallet)
continue
}
// If the account is the same as the first wallet, keep it
if hub.wallets[0].URL() == url {
if hub.wallets[0].URL().Cmp(url) == 0 {
wallets = append(wallets, hub.wallets[0])
hub.wallets = hub.wallets[1:]
continue

View File

@ -72,10 +72,10 @@ const (
// ledgerWallet represents a live USB Ledger hardware wallet.
type ledgerWallet struct {
context *usb.Context // USB context to interface libusb through
hardwareID deviceID // USB identifiers to identify this device type
locationID uint16 // USB bus and address to identify this device instance
url string // Textual URL uniquely identifying this wallet
context *usb.Context // USB context to interface libusb through
hardwareID deviceID // USB identifiers to identify this device type
locationID uint16 // USB bus and address to identify this device instance
url *accounts.URL // Textual URL uniquely identifying this wallet
device *usb.Device // USB device advertising itself as a Ledger wallet
input usb.Endpoint // Input endpoint to send data to this device
@ -90,14 +90,9 @@ type ledgerWallet struct {
lock sync.RWMutex
}
// Type implements accounts.Wallet, returning the textual type of the wallet.
func (w *ledgerWallet) Type() string {
return "ledger"
}
// URL implements accounts.Wallet, returning the URL of the Ledger device.
func (w *ledgerWallet) URL() string {
return w.url
func (w *ledgerWallet) URL() accounts.URL {
return *w.url
}
// Status implements accounts.Wallet, always whether the Ledger is opened, closed
@ -113,9 +108,9 @@ func (w *ledgerWallet) Status() string {
return "Closed"
}
if w.version == [3]byte{0, 0, 0} {
return "Ethereum app not started"
return "Ethereum app offline"
}
return fmt.Sprintf("Ethereum app v%d.%d.%d", w.version[0], w.version[1], w.version[2])
return fmt.Sprintf("Ethereum app v%d.%d.%d online", w.version[0], w.version[1], w.version[2])
}
// Open implements accounts.Wallet, attempting to open a USB connection to the
@ -309,7 +304,7 @@ func (w *ledgerWallet) Derive(path string, pin bool) (accounts.Account, error) {
}
account := accounts.Account{
Address: address,
URL: fmt.Sprintf("%s/%s", w.url, path),
URL: accounts.URL{Scheme: w.url.Scheme, Path: fmt.Sprintf("%s/%s", w.url.Path, path)},
}
// If pinning was requested, track the account
if pin {