Skip to content

Commit

Permalink
Populate colorHash and colorId (#2630)
Browse files Browse the repository at this point in the history
* feat: add colorId utility

it returns color id for given pubkey

* feat: populate Account with colorHash and colorId

accounts displayed to users on login page should display colorHash and
avatar fallback color (aka colorId)
  • Loading branch information
osmaczko authored Apr 8, 2022
1 parent dd86a82 commit 89626d9
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 14 deletions.
17 changes: 17 additions & 0 deletions mobile/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/profiling"
protocol "github.com/status-im/status-go/protocol"
identityUtils "github.com/status-im/status-go/protocol/identity"
"github.com/status-im/status-go/protocol/identity/alias"
"github.com/status-im/status-go/protocol/identity/colorhash"
"github.com/status-im/status-go/protocol/identity/emojihash"
Expand Down Expand Up @@ -277,6 +278,18 @@ func SaveAccountAndLogin(accountData, password, settingsJSON, configJSON, subacc
if err != nil {
return makeJSONResponse(err)
}

for _, acc := range subaccs {
if acc.Chat {
colorHash, _ := colorhash.GenerateFor(string(acc.PublicKey.Bytes()))
colorID, _ := identityUtils.ToColorID(string(acc.PublicKey.Bytes()))
account.ColorHash = colorHash
account.ColorID = colorID

break
}
}

api.RunAsync(func() error {
log.Debug("starting a node, and saving account with configuration", "key-uid", account.KeyUID)
err := statusBackend.StartNodeWithAccountAndInitialConfig(account, password, settings, &conf, subaccs)
Expand Down Expand Up @@ -664,6 +677,10 @@ func ColorHash(pk string) string {
return prepareJSONResponse(colorhash.GenerateFor(pk))
}

func ColorID(pk string) string {
return prepareJSONResponse(identityUtils.ToColorID(pk))
}

func ValidateMnemonic(mnemonic string) string {
m := extkeys.NewMnemonic()
err := m.ValidateMnemonic(mnemonic, extkeys.Language(0))
Expand Down
26 changes: 23 additions & 3 deletions multiaccounts/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package multiaccounts
import (
"context"
"database/sql"
"encoding/json"

"github.com/ethereum/go-ethereum/log"
"github.com/status-im/status-go/images"
Expand All @@ -15,6 +16,8 @@ type Account struct {
Name string `json:"name"`
Timestamp int64 `json:"timestamp"`
Identicon string `json:"identicon"`
ColorHash [][]int `json:"colorHash"`
ColorID int64 `json:"colorId"`
KeycardPairing string `json:"keycard-pairing"`
KeyUID string `json:"key-uid"`
Images []images.IdentityImage `json:"images"`
Expand Down Expand Up @@ -47,7 +50,7 @@ func (db *Database) Close() error {
}

func (db *Database) GetAccounts() (rst []Account, err error) {
rows, err := db.db.Query("SELECT a.name, a.loginTimestamp, a.identicon, a.keycardPairing, a.keyUid, ii.name, ii.image_payload, ii.width, ii.height, ii.file_size, ii.resize_target FROM accounts AS a LEFT JOIN identity_images AS ii ON ii.key_uid = a.keyUid ORDER BY loginTimestamp DESC")
rows, err := db.db.Query("SELECT a.name, a.loginTimestamp, a.identicon, a.colorHash, a.colorId, a.keycardPairing, a.keyUid, ii.name, ii.image_payload, ii.width, ii.height, ii.file_size, ii.resize_target FROM accounts AS a LEFT JOIN identity_images AS ii ON ii.key_uid = a.keyUid ORDER BY loginTimestamp DESC")
if err != nil {
return nil, err
}
Expand All @@ -59,6 +62,8 @@ func (db *Database) GetAccounts() (rst []Account, err error) {
acc := Account{}
accLoginTimestamp := sql.NullInt64{}
accIdenticon := sql.NullString{}
accColorHash := sql.NullString{}
accColorID := sql.NullInt64{}
ii := &images.IdentityImage{}
iiName := sql.NullString{}
iiWidth := sql.NullInt64{}
Expand All @@ -70,6 +75,8 @@ func (db *Database) GetAccounts() (rst []Account, err error) {
&acc.Name,
&accLoginTimestamp,
&accIdenticon,
&accColorHash,
&accColorID,
&acc.KeycardPairing,
&acc.KeyUID,
&iiName,
Expand All @@ -85,6 +92,11 @@ func (db *Database) GetAccounts() (rst []Account, err error) {

acc.Timestamp = accLoginTimestamp.Int64
acc.Identicon = accIdenticon.String
acc.ColorID = accColorID.Int64
err = json.Unmarshal([]byte(accColorHash.String), &acc.ColorHash)
if err != nil {
return nil, err
}

ii.KeyUID = acc.KeyUID
ii.Name = iiName.String
Expand Down Expand Up @@ -121,12 +133,20 @@ func (db *Database) GetAccounts() (rst []Account, err error) {
}

func (db *Database) SaveAccount(account Account) error {
_, err := db.db.Exec("INSERT OR REPLACE INTO accounts (name, identicon, keycardPairing, keyUid) VALUES (?, ?, ?, ?)", account.Name, account.Identicon, account.KeycardPairing, account.KeyUID)
colorHash, err := json.Marshal(account.ColorHash)
if err != nil {
return err
}
_, err = db.db.Exec("INSERT OR REPLACE INTO accounts (name, identicon, colorHash, colorId, keycardPairing, keyUid) VALUES (?, ?, ?, ?, ?, ?)", account.Name, account.Identicon, colorHash, account.ColorID, account.KeycardPairing, account.KeyUID)
return err
}

func (db *Database) UpdateAccount(account Account) error {
_, err := db.db.Exec("UPDATE accounts SET name = ?, identicon = ?, keycardPairing = ? WHERE keyUid = ?", account.Name, account.Identicon, account.KeycardPairing, account.KeyUID)
colorHash, err := json.Marshal(account.ColorHash)
if err != nil {
return err
}
_, err = db.db.Exec("UPDATE accounts SET name = ?, identicon = ?, colorHash = ?, colorId = ?, keycardPairing = ? WHERE keyUid = ?", account.Name, account.Identicon, colorHash, account.ColorID, account.KeycardPairing, account.KeyUID)
return err
}

Expand Down
6 changes: 3 additions & 3 deletions multiaccounts/database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func setupTestDB(t *testing.T) (*Database, func()) {
func TestAccounts(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
expected := Account{Name: "string", KeyUID: "string"}
expected := Account{Name: "string", KeyUID: "string", ColorHash: [][]int{{4, 3}, {4, 0}, {4, 3}, {4, 0}}, ColorID: 10}
require.NoError(t, db.SaveAccount(expected))
accounts, err := db.GetAccounts()
require.NoError(t, err)
Expand All @@ -36,7 +36,7 @@ func TestAccounts(t *testing.T) {
func TestAccountsUpdate(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
expected := Account{KeyUID: "string"}
expected := Account{KeyUID: "string", ColorHash: [][]int{{4, 3}, {4, 0}, {4, 3}, {4, 0}}, ColorID: 10}
require.NoError(t, db.SaveAccount(expected))
expected.Name = "chars"
require.NoError(t, db.UpdateAccount(expected))
Expand Down Expand Up @@ -154,7 +154,7 @@ func TestDatabase_GetAccountsWithIdentityImages(t *testing.T) {
{Name: "string", KeyUID: keyUID2 + "2"},
{Name: "string", KeyUID: keyUID2 + "3"},
}
expected := `[{"name":"string","timestamp":100,"identicon":"data","keycard-pairing":"","key-uid":"0xdeadbeef","images":[{"keyUid":"0xdeadbeef","type":"large","uri":"data:image/png;base64,iVBORw0KGgoAAAANSUg=","width":240,"height":300,"fileSize":1024,"resizeTarget":240},{"keyUid":"0xdeadbeef","type":"thumbnail","uri":"data:image/jpeg;base64,/9j/2wCEAFA3PEY8MlA=","width":80,"height":80,"fileSize":256,"resizeTarget":80}]},{"name":"string","timestamp":10,"identicon":"","keycard-pairing":"","key-uid":"0x1337beef","images":null},{"name":"string","timestamp":0,"identicon":"","keycard-pairing":"","key-uid":"0x1337beef2","images":null},{"name":"string","timestamp":0,"identicon":"","keycard-pairing":"","key-uid":"0x1337beef3","images":[{"keyUid":"0x1337beef3","type":"large","uri":"data:image/png;base64,iVBORw0KGgoAAAANSUg=","width":240,"height":300,"fileSize":1024,"resizeTarget":240},{"keyUid":"0x1337beef3","type":"thumbnail","uri":"data:image/jpeg;base64,/9j/2wCEAFA3PEY8MlA=","width":80,"height":80,"fileSize":256,"resizeTarget":80}]}]`
expected := `[{"name":"string","timestamp":100,"identicon":"data","colorHash":null,"colorId":0,"keycard-pairing":"","key-uid":"0xdeadbeef","images":[{"keyUid":"0xdeadbeef","type":"large","uri":"data:image/png;base64,iVBORw0KGgoAAAANSUg=","width":240,"height":300,"fileSize":1024,"resizeTarget":240},{"keyUid":"0xdeadbeef","type":"thumbnail","uri":"data:image/jpeg;base64,/9j/2wCEAFA3PEY8MlA=","width":80,"height":80,"fileSize":256,"resizeTarget":80}]},{"name":"string","timestamp":10,"identicon":"","colorHash":null,"colorId":0,"keycard-pairing":"","key-uid":"0x1337beef","images":null},{"name":"string","timestamp":0,"identicon":"","colorHash":null,"colorId":0,"keycard-pairing":"","key-uid":"0x1337beef2","images":null},{"name":"string","timestamp":0,"identicon":"","colorHash":null,"colorId":0,"keycard-pairing":"","key-uid":"0x1337beef3","images":[{"keyUid":"0x1337beef3","type":"large","uri":"data:image/png;base64,iVBORw0KGgoAAAANSUg=","width":240,"height":300,"fileSize":1024,"resizeTarget":240},{"keyUid":"0x1337beef3","type":"thumbnail","uri":"data:image/jpeg;base64,/9j/2wCEAFA3PEY8MlA=","width":80,"height":80,"fileSize":256,"resizeTarget":80}]}]`

for _, a := range testAccs {
require.NoError(t, db.SaveAccount(a))
Expand Down
40 changes: 32 additions & 8 deletions multiaccounts/migrations/bindata.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions multiaccounts/migrations/sql/1649317600_add_color_hash.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ALTER TABLE accounts ADD COLUMN colorHash TEXT NOT NULL DEFAULT "";
ALTER TABLE accounts ADD COLUMN colorId INT NOT NULL DEFAULT 0;
UPDATE accounts SET colorHash = "";
UPDATE accounts SET colorId = 0;
13 changes: 13 additions & 0 deletions protocol/identity/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ import (
"github.com/ethereum/go-ethereum/crypto/secp256k1"
)

func ToColorID(pubkey string) (int64, error) {
const colorPalletLength = 12

pubkeyValue, ok := new(big.Int).SetString(pubkey, 0)
if !ok {
return 0, fmt.Errorf("invalid pubkey: %s", pubkey)
}

colorID := new(big.Int).Mod(pubkeyValue, new(big.Int).SetInt64(colorPalletLength-1)).Int64()

return colorID, nil
}

func ToBigBase(value *big.Int, base uint64) (res [](uint64)) {
toBigBaseImpl(value, base, &res)
return
Expand Down

0 comments on commit 89626d9

Please sign in to comment.