diff --git a/cmd/account/show/allowances.go b/cmd/account/show/allowances.go index 5369a0b2..5bd22b30 100644 --- a/cmd/account/show/allowances.go +++ b/cmd/account/show/allowances.go @@ -10,6 +10,8 @@ import ( "github.com/oasisprotocol/oasis-sdk/client-sdk/go/config" "github.com/oasisprotocol/oasis-sdk/client-sdk/go/helpers" "github.com/oasisprotocol/oasis-sdk/client-sdk/go/types" + + "github.com/oasisprotocol/cli/cmd/common" ) // allowanceDescription is a description of an allowance. @@ -61,7 +63,8 @@ func prettyPrintAllowanceDescriptions( lenLongest := lenLongestString(beneficiaryFieldName, amountFieldName) for _, desc := range allowDescriptions { - fmt.Fprintf(w, "%s - %-*s %s", prefix, lenLongest, beneficiaryFieldName, desc.beneficiary) + ppAddr := common.PrettyAddress(network, types.NewAddressFromConsensus(desc.beneficiary)) + fmt.Fprintf(w, "%s - %-*s %s", prefix, lenLongest, beneficiaryFieldName, ppAddr) if desc.self { fmt.Fprintf(w, " (self)") } diff --git a/cmd/account/show/delegations.go b/cmd/account/show/delegations.go index 14d84ec2..d1c1c33f 100644 --- a/cmd/account/show/delegations.go +++ b/cmd/account/show/delegations.go @@ -105,7 +105,8 @@ func prettyPrintDelegationDescriptions( } for _, desc := range delDescriptions { - fmt.Fprintf(w, "%s - %-*s %s", prefix, lenLongest, addressFieldName, desc.address) + ppAddr := common.PrettyAddress(network, types.NewAddressFromConsensus(desc.address)) + fmt.Fprintf(w, "%s - %-*s %s", prefix, lenLongest, addressFieldName, ppAddr) if desc.self { fmt.Fprintf(w, " (self)") } diff --git a/cmd/account/show/show.go b/cmd/account/show/show.go index 9db3ec03..8c4595f8 100644 --- a/cmd/account/show/show.go +++ b/cmd/account/show/show.go @@ -57,8 +57,9 @@ var ( nativeAddr, ethAddr, err := common.ResolveLocalAccountOrAddress(npa.Network, targetAddress) cobra.CheckErr(err) - if name := common.FindAccountName(nativeAddr.String()); name != "" { - fmt.Printf("Name: %s\n", name) + if name := common.FindAccountNameForNetwork(npa.Network, nativeAddr.String()); name != "" { + // Show name along with preferred address (Ethereum first if available). + fmt.Printf("Name: %s\n", common.PrettyAddress(npa.Network, *nativeAddr)) } height, err := common.GetActualHeight( diff --git a/cmd/common/helpers.go b/cmd/common/helpers.go index 3f62d760..6443b94b 100644 --- a/cmd/common/helpers.go +++ b/cmd/common/helpers.go @@ -5,9 +5,13 @@ import ( "github.com/spf13/cobra" + staking "github.com/oasisprotocol/oasis-core/go/staking/api" + configSdk "github.com/oasisprotocol/oasis-sdk/client-sdk/go/config" + sdkhelpers "github.com/oasisprotocol/oasis-sdk/client-sdk/go/helpers" "github.com/oasisprotocol/oasis-sdk/client-sdk/go/testing" "github.com/oasisprotocol/oasis-sdk/client-sdk/go/types" + buildRoflProvider "github.com/oasisprotocol/cli/build/rofl/provider" "github.com/oasisprotocol/cli/config" ) @@ -48,8 +52,76 @@ func GenAccountNames() types.AccountNames { return an } +func GenAccountNamesForNetwork(net *configSdk.Network) types.AccountNames { + an := GenAccountNames() + + // Include ParaTime native addresses as paratime: for the selected network. + if net != nil { + for ptName, pt := range net.ParaTimes.All { + rtAddr := types.NewAddressFromConsensus(staking.NewRuntimeAddress(pt.Namespace())) + if _, exists := an[rtAddr.String()]; !exists { + an[rtAddr.String()] = fmt.Sprintf("paratime:%s", ptName) + } + } + + // Include ROFL default provider addresses as rofl:provider:. + for ptName, pt := range net.ParaTimes.All { + if svc, ok := buildRoflProvider.DefaultRoflServices[pt.ID]; ok { + if svc.Provider != "" { + if a, _, err := sdkhelpers.ResolveEthOrOasisAddress(svc.Provider); err == nil && a != nil { + if _, exists := an[a.String()]; !exists { + an[a.String()] = fmt.Sprintf("rofl:provider:%s", ptName) + } + } + } + } + } + } + + return an +} + +func GenAccountEthMap(_ *configSdk.Network) map[string]string { + em := make(map[string]string) + + // Address book entries which may carry an Ethereum address. + for _, entry := range config.Global().AddressBook.All { + if ea := entry.GetEthAddress(); ea != nil { + em[entry.GetAddress().String()] = ea.Hex() + } + } + + // Built-in test accounts (many have both forms). + for _, acc := range testing.TestAccounts { + if acc.EthAddress != nil { + em[acc.Address.String()] = acc.EthAddress.Hex() + } + } + + return em +} + +func PrettyAddress(net *configSdk.Network, addr types.Address) string { + name := GenAccountNamesForNetwork(net)[addr.String()] + if name == "" { + // Unknown address; return the native form as-is. + return addr.String() + } + + if eth := GenAccountEthMap(net)[addr.String()]; eth != "" { + return fmt.Sprintf("%s (%s)", name, eth) + } + return fmt.Sprintf("%s (%s)", name, addr.String()) +} + // FindAccountName finds account's name (if exists). func FindAccountName(address string) string { an := GenAccountNames() return an[address] } + +// FindAccountNameForNetwork finds account's name in the context of a specific network. +func FindAccountNameForNetwork(net *configSdk.Network, address string) string { + an := GenAccountNamesForNetwork(net) + return an[address] +} diff --git a/cmd/common/json.go b/cmd/common/json.go index b14eb038..e5451df7 100644 --- a/cmd/common/json.go +++ b/cmd/common/json.go @@ -172,7 +172,10 @@ func PrettyPrint(npa *NPASelection, prefix string, blob interface{}) string { ctx = context.WithValue(ctx, config.ContextKeyParaTimeCfg, npa.ParaTime) } ctx = context.WithValue(ctx, signature.ContextKeySigContext, &sigCtx) - ctx = context.WithValue(ctx, types.ContextKeyAccountNames, GenAccountNames()) + + // Provide names (network-aware) and native->ETH mapping for Ethereum-preferred parentheses. + ctx = context.WithValue(ctx, types.ContextKeyAccountNames, GenAccountNamesForNetwork(npa.Network)) + ctx = context.WithValue(ctx, types.ContextKeyAccountEthMap, GenAccountEthMap(npa.Network)) // Set up chain context for signature verification during pretty-printing. coreSignature.UnsafeResetChainContext() diff --git a/cmd/rofl/deploy.go b/cmd/rofl/deploy.go index dff29e51..694bbacd 100644 --- a/cmd/rofl/deploy.go +++ b/cmd/rofl/deploy.go @@ -127,7 +127,7 @@ var ( cobra.CheckErr(fmt.Sprintf("Invalid provider address: %s", err)) } - fmt.Printf("Using provider: %s (%s)\n", machine.Provider, providerAddr) + fmt.Printf("Using provider: %s\n", common.PrettyAddress(npa.Network, *providerAddr)) if deployShowOffers { // Display all offers supported by the provider. diff --git a/cmd/rofl/machine/mgmt.go b/cmd/rofl/machine/mgmt.go index ec344a81..e928d8c9 100644 --- a/cmd/rofl/machine/mgmt.go +++ b/cmd/rofl/machine/mgmt.go @@ -87,7 +87,7 @@ var ( cobra.CheckErr(err) } - fmt.Printf("Using provider: %s (%s)\n", machine.Provider, providerAddr) + fmt.Printf("Using provider: %s\n", common.PrettyAddress(npa.Network, *providerAddr)) fmt.Printf("Canceling machine: %s [%s]\n", machineName, machine.ID) fmt.Printf("WARNING: Canceling a machine will permanently destroy it including any persistent storage!\n") roflCommon.PrintRentRefundWarning() @@ -163,7 +163,7 @@ var ( cobra.CheckErr(err) } - fmt.Printf("Provider: %s (%s)\n", machine.Provider, providerAddr) + fmt.Printf("Provider: %s\n", common.PrettyAddress(npa.Network, *providerAddr)) fmt.Printf("Machine: %s [%s]\n", machineName, machine.ID) // Resolve old admin in online mode. @@ -171,10 +171,10 @@ var ( insDsc, err := conn.Runtime(npa.ParaTime).ROFLMarket.Instance(ctx, client.RoundLatest, *providerAddr, machineID) cobra.CheckErr(err) - fmt.Printf("Old admin: %s\n", insDsc.Admin) + fmt.Printf("Old admin: %s\n", common.PrettyAddress(npa.Network, insDsc.Admin)) } - fmt.Printf("New admin: %s\n", newAdminAddr) + fmt.Printf("New admin: %s\n", common.PrettyAddress(npa.Network, *newAdminAddr)) // Prepare transaction. tx := roflmarket.NewInstanceChangeAdmin(nil, &roflmarket.InstanceChangeAdmin{ @@ -254,7 +254,7 @@ var ( } } - fmt.Printf("Using provider: %s (%s)\n", machine.Provider, providerAddr) + fmt.Printf("Using provider: %s\n", common.PrettyAddress(npa.Network, *providerAddr)) fmt.Printf("Top-up machine: %s [%s]\n", machineName, machine.ID) if txCfg.Offline { fmt.Printf("Top-up term: %d x %s\n", roflCommon.TermCount, roflCommon.Term) @@ -356,7 +356,7 @@ func queueCommand(cliArgs []string, method string, args any, msgAfter string) { cobra.CheckErr(err) } - fmt.Printf("Using provider: %s (%s)\n", machine.Provider, providerAddr) + fmt.Printf("Using provider: %s\n", common.PrettyAddress(npa.Network, *providerAddr)) fmt.Printf("Machine: %s [%s]\n", machineName, machine.ID) fmt.Printf("Command: %s\n", method) fmt.Printf("Args:\n") diff --git a/cmd/rofl/machine/show.go b/cmd/rofl/machine/show.go index 1eaca3d8..f99121df 100644 --- a/cmd/rofl/machine/show.go +++ b/cmd/rofl/machine/show.go @@ -81,12 +81,12 @@ var showCmd = &cobra.Command{ } fmt.Printf("Name: %s\n", machineName) - fmt.Printf("Provider: %s\n", insDsc.Provider) + fmt.Printf("Provider: %s\n", common.PrettyAddress(npa.Network, insDsc.Provider)) fmt.Printf("ID: %s\n", insDsc.ID) fmt.Printf("Offer: %s\n", insDsc.Offer) fmt.Printf("Status: %s\n", insDsc.Status) - fmt.Printf("Creator: %s\n", insDsc.Creator) - fmt.Printf("Admin: %s\n", insDsc.Admin) + fmt.Printf("Creator: %s\n", common.PrettyAddress(npa.Network, insDsc.Creator)) + fmt.Printf("Admin: %s\n", common.PrettyAddress(npa.Network, insDsc.Admin)) switch insDsc.NodeID { case nil: fmt.Printf("Node ID: \n") diff --git a/cmd/wallet/show.go b/cmd/wallet/show.go index 14dab7b0..9a8d2b35 100644 --- a/cmd/wallet/show.go +++ b/cmd/wallet/show.go @@ -30,7 +30,13 @@ func showPublicWalletInfo(name string, wallet wallet.Account, accCfg *config.Acc kind = accCfg.PrettyKind() } - fmt.Printf("Name: %s\n", name) + // Prefer Ethereum address in parentheses when available (Ticket #523). + preferred := wallet.Address().String() + if eth := wallet.EthAddress(); eth != nil { + preferred = eth.Hex() + } + + fmt.Printf("Name: %s (%s)\n", name, preferred) fmt.Printf("Kind: %s\n", kind) if signer := wallet.Signer(); signer != nil { fmt.Printf("Public Key: %s\n", signer.Public())