feat: `keypairs` table added and necessary endpoints exposed via accounts api

This commit is contained in:
Sale Djenic 2022-09-06 09:10:40 +02:00 committed by saledjenic
parent 41f3a19a49
commit 00aa103788
7 changed files with 386 additions and 3 deletions

View File

@ -1 +1 @@
0.108.4
0.108.5

View File

@ -31,6 +31,7 @@
// 1660134070_add_wakuv2_store.up.sql (269B)
// 1660134072_waku2_store_messages.up.sql (497B)
// 1662365868_add_key_uid_accounts.up.sql (68B)
// 1662447680_add_keypairs_table.up.sql (218B)
// 1662738097_add_base_fee_transaction.up.sql (112B)
// doc.go (74B)
@ -721,6 +722,26 @@ func _1662365868_add_key_uid_accountsUpSql() (*asset, error) {
return a, nil
}
var __1662447680_add_keypairs_tableUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x0e\x72\x75\x0c\x71\x55\x08\x71\x74\xf2\x71\x55\xf0\x74\x53\xf0\xf3\x0f\x51\x70\x8d\xf0\x0c\x0e\x09\x56\xc8\x4e\xad\x2c\x48\xcc\x2c\x2a\x56\xd0\xe0\x52\x50\x50\x00\x71\x93\x13\x8b\x52\xe2\x4b\x33\x53\x14\xc2\x1c\x83\x9c\x3d\x1c\x83\xc0\xaa\xfd\x42\x7d\x7c\x74\x50\x54\xe4\x25\xe6\xa6\x12\x50\x92\x93\x9f\x9c\x9d\x9a\xa2\xe0\xe4\xef\xef\xe3\xea\xe8\xa7\xe0\xe2\xea\xe6\x18\xea\x13\xa2\xe0\xe6\xe8\x13\xec\x0a\x51\x99\x98\x9c\x9c\x5f\x9a\x57\x12\x9f\x98\x92\x52\x94\x5a\x5c\x8c\xdb\x3c\xac\x0e\xe2\xd2\xb4\x06\x04\x00\x00\xff\xff\x6d\xd5\x43\xca\xda\x00\x00\x00")
func _1662447680_add_keypairs_tableUpSqlBytes() ([]byte, error) {
return bindataRead(
__1662447680_add_keypairs_tableUpSql,
"1662447680_add_keypairs_table.up.sql",
)
}
func _1662447680_add_keypairs_tableUpSql() (*asset, error) {
bytes, err := _1662447680_add_keypairs_tableUpSqlBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "1662447680_add_keypairs_table.up.sql", size: 218, mode: os.FileMode(0644), modTime: time.Unix(1662964340, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xdc, 0x25, 0xa9, 0xc7, 0x63, 0x27, 0x97, 0x35, 0x5f, 0x6b, 0xab, 0x26, 0xcb, 0xf9, 0xbd, 0x5e, 0xac, 0x3, 0xa0, 0x5e, 0xb9, 0x71, 0xa3, 0x1f, 0xb3, 0x4f, 0x7f, 0x79, 0x28, 0x48, 0xbe, 0xc}}
return a, nil
}
var __1662738097_add_base_fee_transactionUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\x28\x29\x4a\xcc\x2b\x4e\x4b\x2d\x2a\x56\x70\x74\x71\x51\x70\xf6\xf7\x09\xf5\xf5\x53\x48\x4a\x2c\x4e\x8d\x4f\x4f\x2c\x8e\x4f\x4b\x4d\x55\x08\x71\x8d\x08\x51\xf0\xf3\x0f\x51\xf0\x0b\xf5\xf1\x51\x70\x71\x75\x73\x0c\xf5\x09\x51\x50\x52\xb2\xe6\x0a\x0d\x70\x71\x0c\x41\x36\x22\xd8\x35\x04\x55\xaf\x2d\x58\x1d\x20\x00\x00\xff\xff\x3f\x07\xa7\xa2\x70\x00\x00\x00")
func _1662738097_add_base_fee_transactionUpSqlBytes() ([]byte, error) {
@ -736,7 +757,7 @@ func _1662738097_add_base_fee_transactionUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1662738097_add_base_fee_transaction.up.sql", size: 112, mode: os.FileMode(0644), modTime: time.Unix(1662964111, 0)}
info := bindataFileInfo{name: "1662738097_add_base_fee_transaction.up.sql", size: 112, mode: os.FileMode(0644), modTime: time.Unix(1662964340, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x6b, 0xfb, 0x10, 0xae, 0xfc, 0x77, 0x70, 0x98, 0x6f, 0xec, 0xaa, 0xcd, 0x7, 0xc7, 0x74, 0x23, 0xc, 0xd5, 0x1e, 0x82, 0xdd, 0xfe, 0xff, 0x3b, 0xd2, 0x49, 0x10, 0x5b, 0x30, 0xc, 0x2d, 0xb0}}
return a, nil
}
@ -914,6 +935,8 @@ var _bindata = map[string]func() (*asset, error){
"1662365868_add_key_uid_accounts.up.sql": _1662365868_add_key_uid_accountsUpSql,
"1662447680_add_keypairs_table.up.sql": _1662447680_add_keypairs_tableUpSql,
"1662738097_add_base_fee_transaction.up.sql": _1662738097_add_base_fee_transactionUpSql,
"doc.go": docGo,
@ -991,6 +1014,7 @@ var _bintree = &bintree{nil, map[string]*bintree{
"1660134070_add_wakuv2_store.up.sql": &bintree{_1660134070_add_wakuv2_storeUpSql, map[string]*bintree{}},
"1660134072_waku2_store_messages.up.sql": &bintree{_1660134072_waku2_store_messagesUpSql, map[string]*bintree{}},
"1662365868_add_key_uid_accounts.up.sql": &bintree{_1662365868_add_key_uid_accountsUpSql, map[string]*bintree{}},
"1662447680_add_keypairs_table.up.sql": &bintree{_1662447680_add_keypairs_tableUpSql, map[string]*bintree{}},
"1662738097_add_base_fee_transaction.up.sql": &bintree{_1662738097_add_base_fee_transactionUpSql, map[string]*bintree{}},
"doc.go": &bintree{docGo, map[string]*bintree{}},
}}

View File

@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS keypairs (
keycard_uid VARCHAR NOT NULL,
keycard_name VARCHAR NOT NULL,
keycard_locked BOOLEAN DEFAULT FALSE,
account_address VARCHAR NOT NULL,
key_uid VARCHAR NOT NULL
);

View File

@ -6,6 +6,7 @@ import (
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/multiaccounts/errors"
"github.com/status-im/status-go/multiaccounts/keypairs"
"github.com/status-im/status-go/multiaccounts/settings"
notificationssettings "github.com/status-im/status-go/multiaccounts/settings_notifications"
sociallinkssettings "github.com/status-im/status-go/multiaccounts/settings_social_links"
@ -101,6 +102,7 @@ type Database struct {
*settings.Database
*notificationssettings.NotificationsSettings
*sociallinkssettings.SocialLinksSettings
*keypairs.KeyPairs
db *sql.DB
}
@ -112,8 +114,9 @@ func NewDB(db *sql.DB) (*Database, error) {
}
sn := notificationssettings.NewNotificationsSettings(db)
ssl := sociallinkssettings.NewSocialLinksSettings(db)
kp := keypairs.NewKeyPairs(db)
return &Database{sDB, sn, ssl, db}, nil
return &Database{sDB, sn, ssl, kp, db}, nil
}
// DB Gets db sql.DB

View File

@ -9,6 +9,7 @@ import (
"github.com/status-im/status-go/appdatabase"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/multiaccounts/errors"
"github.com/status-im/status-go/multiaccounts/keypairs"
)
func setupTestDB(t *testing.T) (*Database, func()) {
@ -190,3 +191,110 @@ func TestAddressDoesntExist(t *testing.T) {
require.NoError(t, err)
require.False(t, exists)
}
func TestKeypairs(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
keyPair1 := keypairs.KeyPair{
KeycardUID: "00000000000000000000000000000001",
KeycardName: "Card01",
KeycardLocked: false,
AccountsAddresses: []types.Address{{0x01}, {0x02}, {0x03}},
KeyUID: "0000000000000000000000000000000000000000000000000000000000000001",
}
keyPair2 := keypairs.KeyPair{
KeycardUID: "00000000000000000000000000000002",
KeycardName: "Card02",
KeycardLocked: false,
AccountsAddresses: []types.Address{{0x01}, {0x02}},
KeyUID: "0000000000000000000000000000000000000000000000000000000000000002",
}
// Test adding key pairs
err := db.AddMigratedKeyPair(keyPair1.KeycardUID, keyPair1.KeycardName, keyPair1.KeyUID, keyPair1.AccountsAddresses)
require.NoError(t, err)
err = db.AddMigratedKeyPair(keyPair2.KeycardUID, keyPair2.KeycardName, keyPair2.KeyUID, keyPair2.AccountsAddresses)
require.NoError(t, err)
// Test reading migrated key pairs
rows, err := db.GetAllMigratedKeyPairs()
require.NoError(t, err)
require.Equal(t, 2, len(rows))
for _, kp := range rows {
if kp.KeyUID == keyPair1.KeyUID {
require.Equal(t, keyPair1.KeycardUID, kp.KeycardUID)
require.Equal(t, keyPair1.KeycardName, kp.KeycardName)
require.Equal(t, keyPair1.KeycardLocked, kp.KeycardLocked)
require.Equal(t, len(keyPair1.AccountsAddresses), len(kp.AccountsAddresses))
} else {
require.Equal(t, keyPair2.KeycardUID, kp.KeycardUID)
require.Equal(t, keyPair2.KeycardName, kp.KeycardName)
require.Equal(t, keyPair2.KeycardLocked, kp.KeycardLocked)
require.Equal(t, len(keyPair2.AccountsAddresses), len(kp.AccountsAddresses))
}
}
rows, err = db.GetMigratedKeyPairByKeyUID(keyPair1.KeyUID)
require.NoError(t, err)
require.Equal(t, 1, len(rows))
require.Equal(t, keyPair1.KeyUID, rows[0].KeyUID)
require.Equal(t, keyPair1.KeycardUID, rows[0].KeycardUID)
require.Equal(t, keyPair1.KeycardName, rows[0].KeycardName)
require.Equal(t, keyPair1.KeycardLocked, rows[0].KeycardLocked)
require.Equal(t, len(keyPair1.AccountsAddresses), len(rows[0].AccountsAddresses))
// Test seting a new keycard name
err = db.SetKeycardName(keyPair1.KeycardUID, "Card101")
require.NoError(t, err)
rows, err = db.GetAllMigratedKeyPairs()
require.NoError(t, err)
newKeycardName := ""
for _, kp := range rows {
if kp.KeyUID == keyPair1.KeyUID {
newKeycardName = kp.KeycardName
}
}
require.Equal(t, "Card101", newKeycardName)
// Test locking a keycard
err = db.KeycardLocked(keyPair1.KeycardUID)
require.NoError(t, err)
rows, err = db.GetAllMigratedKeyPairs()
require.NoError(t, err)
locked := false
for _, kp := range rows {
if kp.KeyUID == keyPair1.KeyUID {
locked = kp.KeycardLocked
}
}
require.Equal(t, true, locked)
// Test unlocking a locked keycard
err = db.KeycardUnlocked(keyPair1.KeycardUID)
require.NoError(t, err)
rows, err = db.GetAllMigratedKeyPairs()
require.NoError(t, err)
locked = true
for _, kp := range rows {
if kp.KeyUID == keyPair1.KeyUID {
locked = kp.KeycardLocked
}
}
require.Equal(t, false, locked)
// Test detleting a keycard
err = db.DeleteKeycard(keyPair1.KeycardUID)
require.NoError(t, err)
rows, err = db.GetAllMigratedKeyPairs()
require.NoError(t, err)
require.Equal(t, 1, len(rows))
// Test if correct keycard is deleted
deletedKeyPair1 := true
for _, kp := range rows {
if kp.KeyUID == keyPair1.KeyUID {
deletedKeyPair1 = false
}
}
require.Equal(t, true, deletedKeyPair1)
}

View File

@ -0,0 +1,207 @@
package keypairs
import (
"database/sql"
"github.com/status-im/status-go/eth-node/types"
)
type KeyPair struct {
KeycardUID string `json:"keycard-uid"`
KeycardName string `json:"keycard-name"`
KeycardLocked bool `json:"keycard-locked"`
AccountsAddresses []types.Address `json:"accounts-addresses"`
KeyUID string `json:"key-uid"`
}
type KeyPairs struct {
db *sql.DB
}
func NewKeyPairs(db *sql.DB) *KeyPairs {
return &KeyPairs{
db: db,
}
}
func (kp *KeyPairs) processResult(rows *sql.Rows) ([]*KeyPair, error) {
keyPairs := []*KeyPair{}
for rows.Next() {
keyPair := &KeyPair{}
addr := types.Address{}
err := rows.Scan(&keyPair.KeycardUID, &keyPair.KeycardName, &keyPair.KeycardLocked, &addr, &keyPair.KeyUID)
if err != nil {
return nil, err
}
foundAtIndex := -1
for i := range keyPairs {
if keyPairs[i].KeyUID == keyPair.KeyUID {
foundAtIndex = i
break
}
}
if foundAtIndex == -1 {
keyPair.AccountsAddresses = append(keyPair.AccountsAddresses, addr)
keyPairs = append(keyPairs, keyPair)
} else {
keyPairs[foundAtIndex].AccountsAddresses = append(keyPairs[foundAtIndex].AccountsAddresses, addr)
}
}
return keyPairs, nil
}
func (kp *KeyPairs) GetAllMigratedKeyPairs() ([]*KeyPair, error) {
rows, err := kp.db.Query(`
SELECT
keycard_uid,
keycard_name,
keycard_locked,
account_address,
key_uid
FROM
keypairs
ORDER BY
key_uid
`)
if err != nil {
return nil, err
}
defer rows.Close()
return kp.processResult(rows)
}
func (kp *KeyPairs) GetMigratedKeyPairByKeyUID(keyUID string) ([]*KeyPair, error) {
rows, err := kp.db.Query(`
SELECT
keycard_uid,
keycard_name,
keycard_locked,
account_address,
key_uid
FROM
keypairs
WHERE
key_uid = ?
ORDER BY
keycard_uid
`, keyUID)
if err != nil {
return nil, err
}
defer rows.Close()
return kp.processResult(rows)
}
func (kp *KeyPairs) AddMigratedKeyPair(kcUID string, kpName string, KeyUID string, accountAddresses []types.Address) (err error) {
var (
tx *sql.Tx
insert *sql.Stmt
)
tx, err = kp.db.Begin()
if err != nil {
return
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
_ = tx.Rollback()
}()
insert, err = tx.Prepare(`
INSERT INTO
keypairs
(
keycard_uid,
keycard_name,
keycard_locked,
account_address,
key_uid
)
VALUES
(?, ?, ?, ?, ?);
`)
if err != nil {
return err
}
defer insert.Close()
for i := range accountAddresses {
addr := accountAddresses[i]
_, err = insert.Exec(kcUID, kpName, false, addr, KeyUID)
if err != nil {
return err
}
}
return nil
}
func (kp *KeyPairs) SetKeycardName(kcUID string, kpName string) (err error) {
update, err := kp.db.Prepare(`
UPDATE
keypairs
SET
keycard_name = ?
WHERE
keycard_uid = ?
`)
if err != nil {
return err
}
defer update.Close()
_, err = update.Exec(kpName, kcUID)
return err
}
func (kp *KeyPairs) updateKeycardLocked(kcUID string, locked bool) (err error) {
update, err := kp.db.Prepare(`
UPDATE
keypairs
SET
keycard_locked = ?
WHERE
keycard_uid = ?
`)
if err != nil {
return err
}
defer update.Close()
_, err = update.Exec(locked, kcUID)
return err
}
func (kp *KeyPairs) KeycardLocked(kcUID string) (err error) {
return kp.updateKeycardLocked(kcUID, true)
}
func (kp *KeyPairs) KeycardUnlocked(kcUID string) (err error) {
return kp.updateKeycardLocked(kcUID, false)
}
func (kp *KeyPairs) DeleteKeycard(kcUID string) (err error) {
delete, err := kp.db.Prepare(`
DELETE
FROM
keypairs
WHERE
keycard_uid = ?
`)
if err != nil {
return err
}
defer delete.Close()
_, err = delete.Exec(kcUID)
return err
}

View File

@ -13,6 +13,7 @@ import (
"github.com/status-im/status-go/account"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/multiaccounts/keypairs"
"github.com/status-im/status-go/multiaccounts/settings"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/protocol"
@ -316,3 +317,36 @@ func (api *API) VerifyPassword(password string) bool {
}
return true
}
func (api *API) AddMigratedKeyPair(ctx context.Context, kcUID string, kpName string, keyUID string, accountAddresses []string) error {
var addresses []types.Address
for _, addr := range accountAddresses {
addresses = append(addresses, types.Address(common.HexToAddress(addr)))
}
return api.db.AddMigratedKeyPair(kcUID, kpName, keyUID, addresses)
}
func (api *API) GetAllMigratedKeyPairs(ctx context.Context) ([]*keypairs.KeyPair, error) {
return api.db.GetAllMigratedKeyPairs()
}
func (api *API) GetMigratedKeyPairByKeyUID(ctx context.Context, keyUID string) ([]*keypairs.KeyPair, error) {
return api.db.GetMigratedKeyPairByKeyUID(keyUID)
}
func (api *API) SetKeycardName(ctx context.Context, kcUID string, kpName string) error {
return api.db.SetKeycardName(kcUID, kpName)
}
func (api *API) KeycardLocked(ctx context.Context, kcUID string) error {
return api.db.KeycardLocked(kcUID)
}
func (api *API) KeycardUnlocked(ctx context.Context, kcUID string) error {
return api.db.KeycardUnlocked(kcUID)
}
func (api *API) DeleteKeycard(ctx context.Context, kcUID string) error {
return api.db.DeleteKeycard(kcUID)
}