add export of xpub keys

This commit is contained in:
Michele Balistreri 2024-11-29 16:04:29 +09:00
parent 683ce8523b
commit adba9b37a6
No known key found for this signature in database
GPG Key ID: E9567DA33A4F791A
4 changed files with 38 additions and 12 deletions

View File

@ -326,16 +326,16 @@ func (kc *KeycardContext) SignWithPath(data []byte, path string) (*types.Signatu
return sig, nil
}
func (kc *KeycardContext) ExportKey(derive bool, makeCurrent bool, onlyPublic bool, path string) (*KeyPair, error) {
func (kc *KeycardContext) ExportKey(derive bool, makeCurrent bool, p2 uint8, path string) (*KeyPair, error) {
address := ""
privKey, pubKey, err := kc.cmdSet.ExportKey(derive, makeCurrent, onlyPublic, path)
exportedKey, err := kc.cmdSet.ExportKeyExtended(derive, makeCurrent, p2, path)
if err != nil {
Printf("exportKey failed %+v", err)
return nil, err
}
if pubKey != nil {
ecdsaPubKey, err := crypto.UnmarshalPubkey(pubKey)
if exportedKey.PubKey() != nil {
ecdsaPubKey, err := crypto.UnmarshalPubkey(exportedKey.PubKey())
if err != nil {
return nil, err
}
@ -343,7 +343,7 @@ func (kc *KeycardContext) ExportKey(derive bool, makeCurrent bool, onlyPublic bo
address = crypto.PubkeyToAddress(*ecdsaPubKey).Hex()
}
return &KeyPair{Address: address, PublicKey: pubKey, PrivateKey: privKey}, nil
return &KeyPair{Address: address, PublicKey: exportedKey.PubKey(), PrivateKey: exportedKey.PrivKey(), ChainCode: exportedKey.ChainCode()}, nil
}
func (kc *KeycardContext) loadSeed(seed []byte) ([]byte, error) {

View File

@ -53,6 +53,7 @@ type KeyPair struct {
Address string `json:"address"`
PublicKey HexString `json:"publicKey"`
PrivateKey HexString `json:"privateKey,omitempty"`
ChainCode HexString `json:"chainCode,omitempty"`
}
type Wallet struct {

View File

@ -5,6 +5,7 @@ import (
"io"
"strings"
keycard "github.com/status-im/keycard-go"
"github.com/status-im/keycard-go/apdu"
"github.com/status-im/keycard-go/derivationpath"
ktypes "github.com/status-im/keycard-go/types"
@ -34,6 +35,7 @@ func (f *KeycardFlow) selectKeycard(kc *internal.KeycardContext) error {
f.cardInfo.instanceUID = internal.Btox(appInfo.InstanceUID)
f.cardInfo.keyUID = internal.Btox(appInfo.KeyUID)
f.cardInfo.freeSlots = internal.BytesToInt(appInfo.AvailableSlots)
f.cardInfo.version = internal.BytesToInt(appInfo.Version)
if !appInfo.Installed {
return f.pauseAndRestart(SwapCard, internal.ErrorNotAKeycard)
@ -372,7 +374,18 @@ func (f *KeycardFlow) storeMetadata(kc *internal.KeycardContext) error {
}
func (f *KeycardFlow) exportKey(kc *internal.KeycardContext, path string, onlyPublic bool) (*internal.KeyPair, error) {
keyPair, err := kc.ExportKey(true, path == MasterPath, onlyPublic, path)
var p2 uint8
if onlyPublic {
p2 = keycard.P2ExportKeyPublicOnly
} else {
p2 = keycard.P2ExportKeyPrivateAndPublic
}
return f.exportKeyExtended(kc, path, p2)
}
func (f *KeycardFlow) exportKeyExtended(kc *internal.KeycardContext, path string, p2 uint8) (*internal.KeyPair, error) {
keyPair, err := kc.ExportKey(true, path == MasterPath, p2, path)
if internal.IsSCardError(err) {
return nil, restartErr()

View File

@ -4,9 +4,10 @@ import (
"errors"
"time"
"github.com/status-im/status-keycard-go/signal"
"github.com/status-im/keycard-go"
"github.com/status-im/status-keycard-go/internal"
"github.com/status-im/status-keycard-go/pkg/pairing"
"github.com/status-im/status-keycard-go/signal"
)
type cardStatus struct {
@ -15,6 +16,7 @@ type cardStatus struct {
freeSlots int
pinRetries int
pukRetries int
version int
}
type KeycardFlow struct {
@ -326,17 +328,27 @@ func (f *KeycardFlow) exportKeysFlow(kc *internal.KeycardContext, recover bool)
}
result[EIP1581Key] = key
key, err = f.exportKey(kc, WalletRoothPath, true)
var exportP2 uint8
if f.cardInfo.version < 0x0310 {
exportP2 = keycard.P2ExportKeyPublicOnly
} else {
exportP2 = keycard.P2ExportKeyExtendedPublic
}
key, err = f.exportKeyExtended(kc, WalletRoothPath, exportP2)
if err != nil {
return nil, err
}
result[WalleRootKey] = key
if key.ChainCode == nil {
key, err = f.exportKey(kc, WalletPath, true)
if err != nil {
return nil, err
}
result[WalletKey] = key
}
key, err = f.exportKey(kc, MasterPath, true)
if err != nil {