feat(wallet) WalletConnect: track pairings in DB

Add new APIs to track if valid pairings are available to be used
by application not to run WalletConnect SDK if not needed.

Closes status-desktop: #12794
This commit is contained in:
Stefan 2023-11-19 19:29:17 +02:00 committed by Stefan Dunca
parent b7acde0910
commit a855f9e3e8
11 changed files with 358 additions and 64 deletions

View File

@ -1 +1 @@
0.171.16
0.171.17

View File

@ -634,6 +634,26 @@ func (api *API) WCPairSessionProposal(ctx context.Context, sessionProposalJSON s
return api.s.walletConnect.PairSessionProposal(data)
}
// WCPairEstablished confirms that a pairing has been established
func (api *API) WCRecordSuccessfulPairing(ctx context.Context, sessionProposalJSON string) error {
log.Debug("wallet.api.wc.RecordSuccessfulPairing", "proposal.len", len(sessionProposalJSON))
var data wc.SessionProposal
err := json.Unmarshal([]byte(sessionProposalJSON), &data)
if err != nil {
return err
}
return api.s.walletConnect.RecordSuccessfulPairing(data)
}
// WCSessionRequest responds to "session_request" event
func (api *API) WCHasActivePairings(ctx context.Context) (bool, error) {
log.Debug("wallet.api.wc.HasActivePairings")
return api.s.walletConnect.HasActivePairings()
}
// WCSessionRequest responds to "session_request" event
func (api *API) WCSessionRequest(ctx context.Context, sessionRequestJSON string) (response *wc.SessionRequestResponse, err error) {
log.Debug("wallet.api.wc.SessionRequest", "request.len", len(sessionRequestJSON))

View File

@ -137,7 +137,7 @@ func NewService(
activity := activity.NewService(db, tokenManager, collectiblesManager, feed)
walletconnect := walletconnect.NewService(rpcClient.NetworkManager, accountsDB, transactor, gethManager, feed, config)
walletconnect := walletconnect.NewService(db, rpcClient.NetworkManager, accountsDB, transactor, gethManager, feed, config)
return &Service{
db: db,

View File

@ -0,0 +1,80 @@
package walletconnect
import (
"database/sql"
)
type Pairing struct {
Topic Topic `json:"topic"`
Expiry int64 `json:"expiry"`
Active bool `json:"active"`
AppName string `json:"appName"`
URL string `json:"url"`
Description string `json:"description"`
Icon string `json:"icon"`
Verified Verified `json:"verified"`
}
func InsertPairing(db *sql.DB, pairing Pairing) error {
insertSQL := `INSERT INTO wallet_connect_pairings (topic, expiry_timestamp, active, app_name, url, description, icon, verified_is_scam, verified_origin, verified_verify_url, verified_validation) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
_, err := db.Exec(insertSQL, pairing.Topic, pairing.Expiry, pairing.Active, pairing.AppName, pairing.URL, pairing.Description, pairing.Icon, pairing.Verified.IsScam, pairing.Verified.Origin, pairing.Verified.VerifyURL, pairing.Verified.Validation)
return err
}
func GetPairingByTopic(db *sql.DB, topic Topic) (*Pairing, error) {
querySQL := `SELECT topic, expiry_timestamp, active, app_name, url, description, icon, verified_is_scam, verified_origin, verified_verify_url, verified_validation FROM wallet_connect_pairings WHERE topic = ?`
row := db.QueryRow(querySQL, topic)
var pairing Pairing
err := row.Scan(&pairing.Topic, &pairing.Expiry, &pairing.Active, &pairing.AppName, &pairing.URL, &pairing.Description, &pairing.Icon, &pairing.Verified.IsScam, &pairing.Verified.Origin, &pairing.Verified.VerifyURL, &pairing.Verified.Validation)
if err != nil {
return nil, err
}
return &pairing, nil
}
// GetActivePairings returns all active pairings (active and not expired) that have an expiry timestamp newer or equal to the given timestamp.
func GetActivePairings(db *sql.DB, expiryNotOlderThanTimestamp int64) ([]Pairing, error) {
querySQL := `SELECT topic, expiry_timestamp, active, app_name, url, description, icon, verified_is_scam, verified_origin, verified_verify_url, verified_validation FROM wallet_connect_pairings WHERE active != 0 AND expiry_timestamp >= ? ORDER BY expiry_timestamp DESC`
rows, err := db.Query(querySQL, expiryNotOlderThanTimestamp)
if err != nil {
return nil, err
}
defer rows.Close()
pairings := make([]Pairing, 0, 2)
for rows.Next() {
var pairing Pairing
err := rows.Scan(&pairing.Topic, &pairing.Expiry, &pairing.Active, &pairing.AppName, &pairing.URL, &pairing.Description, &pairing.Icon, &pairing.Verified.IsScam, &pairing.Verified.Origin, &pairing.Verified.VerifyURL, &pairing.Verified.Validation)
if err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
pairings = append(pairings, pairing)
}
if err := rows.Err(); err != nil {
return nil, err
}
return pairings, nil
}
func HasActivePairings(db *sql.DB, expiryNotOlderThanTimestamp int64) (bool, error) {
querySQL := `SELECT EXISTS(SELECT 1 FROM wallet_connect_pairings WHERE active != 0 AND expiry_timestamp >= ?)`
row := db.QueryRow(querySQL, expiryNotOlderThanTimestamp)
var exists bool
err := row.Scan(&exists)
if err != nil {
return false, err
}
return exists, nil
}

View File

@ -0,0 +1,114 @@
package walletconnect
import (
"strconv"
"testing"
"database/sql"
"github.com/status-im/status-go/t/helpers"
"github.com/status-im/status-go/walletdatabase"
"github.com/stretchr/testify/require"
)
func setupTestDB(t *testing.T) (db *sql.DB, close func()) {
db, err := helpers.SetupTestMemorySQLDB(walletdatabase.DbInitializer{})
require.NoError(t, err)
return db, func() {
require.NoError(t, db.Close())
}
}
// generateTestData generates alternative disconnected and active pairings starting with the active one
// timestamps start with 1234567890
func generateTestData(count int) []Pairing {
res := make([]Pairing, count)
for i := 0; i < count; i++ {
strI := strconv.Itoa(i)
res[i] = Pairing{
Topic: Topic(strI + "abcdef1234567890"),
Expiry: 1234567890 + int64(i),
Active: (i % 2) == 0,
AppName: "TestApp" + strI,
URL: "https://test.url/" + strI,
Description: "Test Description" + strI,
Icon: "https://test.icon" + strI,
Verified: Verified{
IsScam: false,
Origin: "https://test.origin/" + strI,
VerifyURL: "https://test.verify.url/" + strI,
Validation: "https://test.validation/" + strI,
},
}
}
return res
}
func insertTestData(t *testing.T, db *sql.DB, entries []Pairing) {
for _, entry := range entries {
err := InsertPairing(db, entry)
require.NoError(t, err)
}
}
func TestInsertAndGetPairing(t *testing.T) {
db, close := setupTestDB(t)
defer close()
entry := generateTestData(1)[0]
err := InsertPairing(db, entry)
require.NoError(t, err)
retrievedPairing, err := GetPairingByTopic(db, entry.Topic)
require.NoError(t, err)
require.Equal(t, entry, *retrievedPairing)
}
func TestGet(t *testing.T) {
db, close := setupTestDB(t)
defer close()
entries := generateTestData(3)
insertTestData(t, db, entries)
retrievedPairing, err := GetPairingByTopic(db, entries[1].Topic)
require.NoError(t, err)
require.Equal(t, entries[1], *retrievedPairing)
}
func TestGetActivePairings(t *testing.T) {
db, close := setupTestDB(t)
defer close()
// insert two disconnected and three active pairing
entries := generateTestData(5)
insertTestData(t, db, entries)
activePairings, err := GetActivePairings(db, 1234567892)
require.NoError(t, err)
require.Equal(t, 2, len(activePairings))
// Expect newest on top
require.Equal(t, entries[4], activePairings[0])
require.Equal(t, entries[2], activePairings[1])
}
func TestHasActivePairings(t *testing.T) {
db, close := setupTestDB(t)
defer close()
// insert one disconnected and two active pairing
entries := generateTestData(2)
insertTestData(t, db, entries)
hasActivePairings, err := HasActivePairings(db, 1234567890)
require.NoError(t, err)
require.True(t, hasActivePairings)
hasActivePairings, err = HasActivePairings(db, 1234567891)
require.NoError(t, err)
require.False(t, hasActivePairings)
}

View File

@ -8,7 +8,6 @@ import (
"strings"
)
// TODO #12434: respond async
// func sendResponseEvent(eventFeed *event.Feed, eventType walletevent.EventType, payloadObj interface{}, resErr error) {
// payload, err := json.Marshal(payloadObj)
// if err != nil {
@ -17,14 +16,14 @@ import (
// err = resErr
// }
// log.Debug("wallet.api.wc RESPONSE", "eventType", eventType, "error", err, "payload.len", len(payload))
// event := walletevent.Event{
// Type: eventType,
// Message: string(payload),
// }
// eventFeed.Send(event)
// sentCount := eventFeed.Send(event)
// log.Debug("wallet.api.wc RESPONSE", "eventType", eventType, "error", err, "payload.len", len(payload), "sentCount", sentCount)
// }
func parseCaip2ChainID(str string) (uint64, error) {

View File

@ -10,6 +10,7 @@ import (
"github.com/ethereum/go-ethereum/common"
ethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/transactions"

View File

@ -1,12 +1,15 @@
package walletconnect
import (
"database/sql"
"fmt"
"time"
"github.com/ethereum/go-ethereum/common"
ethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
"github.com/status-im/status-go/account"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types"
@ -23,6 +26,7 @@ type txSigningDetails struct {
}
type Service struct {
db *sql.DB
networkManager *network.Manager
accountsDB *accounts.Database
eventFeed *event.Feed
@ -34,9 +38,9 @@ type Service struct {
txSignDetails *txSigningDetails
}
func NewService(networkManager *network.Manager, accountsDB *accounts.Database, transactor *transactions.Transactor,
gethManager *account.GethManager, eventFeed *event.Feed, config *params.NodeConfig) *Service {
func NewService(db *sql.DB, networkManager *network.Manager, accountsDB *accounts.Database, transactor *transactions.Transactor, gethManager *account.GethManager, eventFeed *event.Feed, config *params.NodeConfig) *Service {
return &Service{
db: db,
networkManager: networkManager,
accountsDB: accountsDB,
eventFeed: eventFeed,
@ -103,6 +107,27 @@ func (s *Service) PairSessionProposal(proposal SessionProposal) (*PairSessionRes
}, nil
}
func (s *Service) RecordSuccessfulPairing(proposal SessionProposal) error {
var icon string
if len(proposal.Params.Proposer.Metadata.Icons) > 0 {
icon = proposal.Params.Proposer.Metadata.Icons[0]
}
return InsertPairing(s.db, Pairing{
Topic: proposal.Params.PairingTopic,
Expiry: proposal.Params.Expiry,
Active: true,
AppName: proposal.Params.Proposer.Metadata.Name,
URL: proposal.Params.Proposer.Metadata.URL,
Description: proposal.Params.Proposer.Metadata.Description,
Icon: icon,
Verified: proposal.Params.Verify.Verified,
})
}
func (s *Service) HasActivePairings() (bool, error) {
return HasActivePairings(s.db, time.Now().Unix())
}
func (s *Service) SessionRequest(request SessionRequest) (response *SessionRequestResponse, err error) {
// TODO #12434: should we check topic for validity? It might make sense if we
// want to cache the paired sessions

View File

@ -18,6 +18,8 @@ var ErrorChainsNotSupported = errors.New("chains not supported")
var ErrorInvalidParamsCount = errors.New("invalid params count")
var ErrorMethodNotSupported = errors.New("method not supported")
type Topic string
type Namespace struct {
Methods []string `json:"methods"`
Chains []string `json:"chains"` // CAIP-2 format e.g. ["eip155:1"]
@ -43,18 +45,20 @@ type Namespaces struct {
// We ignore non ethereum namespaces
}
type Verified struct {
VerifyURL string `json:"verifyUrl"`
Validation string `json:"validation"`
Origin string `json:"origin"`
IsScam bool `json:"isScam,omitempty"`
}
type VerifyContext struct {
Verified struct {
VerifyURL string `json:"verifyUrl"`
Validation string `json:"validation"`
Origin string `json:"origin"`
IsScam bool `json:"isScam,omitempty"`
} `json:"verified"`
Verified Verified `json:"verified"`
}
type Params struct {
ID int64 `json:"id"`
PairingTopic string `json:"pairingTopic"`
PairingTopic Topic `json:"pairingTopic"`
Expiry int64 `json:"expiry"`
RequiredNamespaces Namespaces `json:"requiredNamespaces"`
OptionalNamespaces Namespaces `json:"optionalNamespaces"`
@ -63,7 +67,7 @@ type Params struct {
}
type SessionProposal struct {
ID uint64 `json:"id"`
ID int64 `json:"id"`
Params Params `json:"params"`
}
@ -82,11 +86,16 @@ type RequestParams struct {
type SessionRequest struct {
ID int64 `json:"id"`
Topic string `json:"topic"`
Topic Topic `json:"topic"`
Params RequestParams `json:"params"`
Verify VerifyContext `json:"verifyContext"`
}
type SessionDelete struct {
ID int64 `json:"id"`
Topic Topic `json:"topic"`
}
type SessionRequestResponse struct {
KeyUID string `json:"keyUid,omitempty"`
Address types.Address `json:"address,omitempty"`

View File

@ -11,6 +11,7 @@
// 1698117918_add_community_id_to_tokens.up.sql (61B)
// 1698257443_add_community_metadata_to_wallet_db.up.sql (323B)
// 1699987075_add_timestamp_and_state_to_community_data_cache.up.sql (865B)
// 1700414564_add_wallet_connect_pairings_table.up.sql (439B)
// doc.go (74B)
package migrations
@ -21,6 +22,7 @@ import (
"crypto/sha256"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
@ -30,7 +32,7 @@ import (
func bindataRead(data []byte, name string) ([]byte, error) {
gz, err := gzip.NewReader(bytes.NewBuffer(data))
if err != nil {
return nil, fmt.Errorf("read %q: %w", name, err)
return nil, fmt.Errorf("read %q: %v", name, err)
}
var buf bytes.Buffer
@ -38,7 +40,7 @@ func bindataRead(data []byte, name string) ([]byte, error) {
clErr := gz.Close()
if err != nil {
return nil, fmt.Errorf("read %q: %w", name, err)
return nil, fmt.Errorf("read %q: %v", name, err)
}
if clErr != nil {
return nil, err
@ -94,7 +96,7 @@ func _1691753758_initialUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1691753758_initial.up.sql", size: 5738, mode: os.FileMode(0644), modTime: time.Unix(1698840720, 0)}
info := bindataFileInfo{name: "1691753758_initial.up.sql", size: 5738, mode: os.FileMode(0644), modTime: time.Unix(1700316153, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x6b, 0x25, 0x31, 0xc8, 0x27, 0x3, 0x6b, 0x9f, 0x15, 0x42, 0x2f, 0x85, 0xfb, 0xe3, 0x6, 0xea, 0xf7, 0x97, 0x12, 0x56, 0x3c, 0x9a, 0x5b, 0x1a, 0xca, 0xb1, 0x23, 0xfa, 0xcd, 0x57, 0x25, 0x5c}}
return a, nil
}
@ -114,7 +116,7 @@ func _1692701329_add_collectibles_and_collections_data_cacheUpSql() (*asset, err
return nil, err
}
info := bindataFileInfo{name: "1692701329_add_collectibles_and_collections_data_cache.up.sql", size: 1808, mode: os.FileMode(0644), modTime: time.Unix(1698840720, 0)}
info := bindataFileInfo{name: "1692701329_add_collectibles_and_collections_data_cache.up.sql", size: 1808, mode: os.FileMode(0644), modTime: time.Unix(1700316153, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1, 0x51, 0xf4, 0x2b, 0x92, 0xde, 0x59, 0x65, 0xd8, 0x9b, 0x57, 0xe0, 0xfd, 0x7b, 0x12, 0xb, 0x29, 0x6e, 0x9d, 0xb5, 0x90, 0xe, 0xfa, 0x12, 0x97, 0xd, 0x61, 0x60, 0x7f, 0x32, 0x1d, 0xc3}}
return a, nil
}
@ -134,7 +136,7 @@ func _1692701339_add_scope_to_pendingUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1692701339_add_scope_to_pending.up.sql", size: 576, mode: os.FileMode(0644), modTime: time.Unix(1698840720, 0)}
info := bindataFileInfo{name: "1692701339_add_scope_to_pending.up.sql", size: 576, mode: os.FileMode(0644), modTime: time.Unix(1700316153, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x36, 0x8a, 0x5e, 0xe2, 0x63, 0x15, 0x37, 0xba, 0x55, 0x18, 0xf3, 0xcc, 0xe0, 0x5, 0x84, 0xe1, 0x5b, 0xe8, 0x1, 0x32, 0x6b, 0x9f, 0x7d, 0x9f, 0xd9, 0x23, 0x6c, 0xa9, 0xb5, 0xdc, 0xf4, 0x93}}
return a, nil
}
@ -154,7 +156,7 @@ func _1694540071_add_collectibles_ownership_update_timestampUpSql() (*asset, err
return nil, err
}
info := bindataFileInfo{name: "1694540071_add_collectibles_ownership_update_timestamp.up.sql", size: 349, mode: os.FileMode(0644), modTime: time.Unix(1698840720, 0)}
info := bindataFileInfo{name: "1694540071_add_collectibles_ownership_update_timestamp.up.sql", size: 349, mode: os.FileMode(0644), modTime: time.Unix(1700316153, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x7f, 0x45, 0xc7, 0xce, 0x79, 0x63, 0xbc, 0x6f, 0x83, 0x5f, 0xe2, 0x3, 0x56, 0xcc, 0x5, 0x2f, 0x85, 0xda, 0x7e, 0xea, 0xf5, 0xd2, 0xac, 0x19, 0xd4, 0xd8, 0x5e, 0xdd, 0xed, 0xe2, 0xa9, 0x97}}
return a, nil
}
@ -174,7 +176,7 @@ func _1694692748_add_raw_balance_to_token_balancesUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1694692748_add_raw_balance_to_token_balances.up.sql", size: 165, mode: os.FileMode(0644), modTime: time.Unix(1698840720, 0)}
info := bindataFileInfo{name: "1694692748_add_raw_balance_to_token_balances.up.sql", size: 165, mode: os.FileMode(0644), modTime: time.Unix(1700316153, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd4, 0xe0, 0x5b, 0x42, 0xf0, 0x96, 0xa5, 0xf5, 0xed, 0xc0, 0x97, 0x88, 0xb0, 0x6d, 0xfe, 0x7d, 0x97, 0x2e, 0x17, 0xd2, 0x16, 0xbc, 0x2a, 0xf2, 0xcc, 0x67, 0x9e, 0xc5, 0x47, 0xf6, 0x69, 0x1}}
return a, nil
}
@ -194,7 +196,7 @@ func _1695133989_add_community_id_to_collectibles_and_collections_data_cacheUpSq
return nil, err
}
info := bindataFileInfo{name: "1695133989_add_community_id_to_collectibles_and_collections_data_cache.up.sql", size: 275, mode: os.FileMode(0644), modTime: time.Unix(1698840720, 0)}
info := bindataFileInfo{name: "1695133989_add_community_id_to_collectibles_and_collections_data_cache.up.sql", size: 275, mode: os.FileMode(0644), modTime: time.Unix(1700316153, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xfa, 0x2, 0xa, 0x7f, 0x4b, 0xd1, 0x3, 0xd0, 0x3, 0x29, 0x84, 0x31, 0xed, 0x49, 0x4f, 0xb1, 0x2d, 0xd7, 0x80, 0x41, 0x5b, 0xfa, 0x6, 0xae, 0xb4, 0xf6, 0x6b, 0x49, 0xee, 0x57, 0x33, 0x76}}
return a, nil
}
@ -214,7 +216,7 @@ func _1695932536_balance_history_v2UpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1695932536_balance_history_v2.up.sql", size: 653, mode: os.FileMode(0644), modTime: time.Unix(1698840720, 0)}
info := bindataFileInfo{name: "1695932536_balance_history_v2.up.sql", size: 653, mode: os.FileMode(0644), modTime: time.Unix(1700316153, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x37, 0xf4, 0x14, 0x91, 0xf6, 0x5f, 0xc4, 0x9b, 0xb7, 0x83, 0x32, 0x72, 0xbe, 0x82, 0x42, 0x39, 0xa4, 0x3b, 0xc9, 0x78, 0x3d, 0xca, 0xd4, 0xbf, 0xfc, 0x7a, 0x33, 0x1e, 0xcd, 0x9e, 0xe4, 0x85}}
return a, nil
}
@ -234,7 +236,7 @@ func _1696853635_input_dataUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1696853635_input_data.up.sql", size: 23140, mode: os.FileMode(0644), modTime: time.Unix(1698840720, 0)}
info := bindataFileInfo{name: "1696853635_input_data.up.sql", size: 23140, mode: os.FileMode(0644), modTime: time.Unix(1700316153, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x89, 0x30, 0x33, 0x33, 0x55, 0xc5, 0x57, 0x2b, 0xaf, 0xef, 0x3d, 0x8d, 0x2a, 0xaa, 0x5c, 0x32, 0xd1, 0xf4, 0xd, 0x4a, 0xd0, 0x33, 0x4a, 0xe8, 0xf6, 0x8, 0x6b, 0x65, 0xcc, 0xba, 0xed, 0x42}}
return a, nil
}
@ -254,7 +256,7 @@ func _1698117918_add_community_id_to_tokensUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1698117918_add_community_id_to_tokens.up.sql", size: 61, mode: os.FileMode(0644), modTime: time.Unix(1698840720, 0)}
info := bindataFileInfo{name: "1698117918_add_community_id_to_tokens.up.sql", size: 61, mode: os.FileMode(0644), modTime: time.Unix(1700316153, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb3, 0x82, 0xdb, 0xde, 0x3, 0x3, 0xc, 0x67, 0xf3, 0x54, 0xc4, 0xad, 0xd6, 0xce, 0x56, 0xfb, 0xc1, 0x87, 0xd7, 0xda, 0xab, 0xec, 0x1, 0xe1, 0x7d, 0xb3, 0x63, 0xd6, 0xe5, 0x5d, 0x1c, 0x15}}
return a, nil
}
@ -274,7 +276,7 @@ func _1698257443_add_community_metadata_to_wallet_dbUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1698257443_add_community_metadata_to_wallet_db.up.sql", size: 323, mode: os.FileMode(0644), modTime: time.Unix(1698840720, 0)}
info := bindataFileInfo{name: "1698257443_add_community_metadata_to_wallet_db.up.sql", size: 323, mode: os.FileMode(0644), modTime: time.Unix(1700316153, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x22, 0xd3, 0x4, 0x25, 0xfa, 0x23, 0x1, 0x48, 0x83, 0x26, 0x20, 0xf2, 0x3d, 0xbc, 0xc1, 0xa7, 0x7c, 0x27, 0x7c, 0x1d, 0x63, 0x3, 0xa, 0xd0, 0xce, 0x47, 0x86, 0xdc, 0xa1, 0x3c, 0x2, 0x1c}}
return a, nil
}
@ -294,11 +296,31 @@ func _1699987075_add_timestamp_and_state_to_community_data_cacheUpSql() (*asset,
return nil, err
}
info := bindataFileInfo{name: "1699987075_add_timestamp_and_state_to_community_data_cache.up.sql", size: 865, mode: os.FileMode(0644), modTime: time.Unix(1700084408, 0)}
info := bindataFileInfo{name: "1699987075_add_timestamp_and_state_to_community_data_cache.up.sql", size: 865, mode: os.FileMode(0644), modTime: time.Unix(1700316153, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc3, 0xee, 0x37, 0xf9, 0x7f, 0x9e, 0xfe, 0x93, 0x66, 0x2b, 0xd, 0x57, 0xf4, 0x89, 0x6c, 0x51, 0xfd, 0x14, 0xe9, 0xcd, 0xab, 0x65, 0xe7, 0xa7, 0x83, 0x7e, 0xe0, 0x5c, 0x14, 0x49, 0xf3, 0xe5}}
return a, nil
}
var __1700414564_add_wallet_connect_pairings_tableUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\x90\x4b\x6a\xc3\x30\x10\x86\xf7\x3a\xc5\x2c\x1b\xc8\x0d\xb2\x72\xda\x69\x11\x75\xe5\xe2\xa8\xe0\xac\x84\x90\xa7\x61\xc0\x96\x85\xa4\xa6\xc9\xed\x0b\x76\x1f\x89\x68\x76\x9a\xff\xc1\x2f\xbe\xfb\x16\x2b\x8d\xa0\xab\x6d\x8d\x20\x1f\x41\x35\x1a\xb0\x93\x3b\xbd\x83\x4f\x3b\x0c\x94\x8d\x9b\xbc\x27\x97\x4d\xb0\x1c\xd9\x1f\x12\xdc\x09\x00\x80\x3c\x05\x76\xa0\xb1\xd3\xf0\xda\xca\x97\xaa\xdd\xc3\x33\xee\xe7\xbe\x7a\xab\xeb\xf5\x1c\xa2\x53\xe0\x78\x36\x99\x47\x4a\xd9\x8e\x01\xa4\xd2\xf8\x84\x6d\x11\xb3\x2e\xf3\x91\x60\xdb\x34\x35\x56\xaa\x34\x43\x30\xde\x8e\x34\x6f\x2d\xd2\x47\x1c\x2e\xae\x9e\x92\x8b\x1c\x32\x4f\xfe\x42\x65\x77\x75\x1e\x29\xf2\x3b\x53\x6f\x38\x99\xe4\xec\xf8\x33\x56\xb8\x53\xe4\x03\xff\xdb\x9b\x1f\x67\x73\x3d\xfd\xe7\xda\x81\x7b\xfb\xfb\x05\xb1\xda\x08\xf1\x8d\x56\xaa\x07\xec\x0a\xb4\xdc\x9f\xcc\xc2\x06\x1a\x75\x1b\x74\x89\x6f\xbd\x80\x5a\x6d\xc4\x57\x00\x00\x00\xff\xff\x66\xec\xe7\x64\xb7\x01\x00\x00")
func _1700414564_add_wallet_connect_pairings_tableUpSqlBytes() ([]byte, error) {
return bindataRead(
__1700414564_add_wallet_connect_pairings_tableUpSql,
"1700414564_add_wallet_connect_pairings_table.up.sql",
)
}
func _1700414564_add_wallet_connect_pairings_tableUpSql() (*asset, error) {
bytes, err := _1700414564_add_wallet_connect_pairings_tableUpSqlBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "1700414564_add_wallet_connect_pairings_table.up.sql", size: 439, mode: os.FileMode(0644), modTime: time.Unix(1700503490, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa9, 0x77, 0x5e, 0x19, 0x62, 0x3c, 0x3a, 0x81, 0x16, 0xa0, 0x95, 0x35, 0x62, 0xab, 0x5e, 0x2b, 0xea, 0x11, 0x71, 0x11, 0xd0, 0x9, 0xab, 0x9c, 0xab, 0xf2, 0xdd, 0x5f, 0x88, 0x83, 0x9a, 0x93}}
return a, nil
}
var _docGo = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2c\xc9\xb1\x0d\xc4\x20\x0c\x05\xd0\x9e\x29\xfe\x02\xd8\xfd\x6d\xe3\x4b\xac\x2f\x44\x82\x09\x78\x7f\xa5\x49\xfd\xa6\x1d\xdd\xe8\xd8\xcf\x55\x8a\x2a\xe3\x47\x1f\xbe\x2c\x1d\x8c\xfa\x6f\xe3\xb4\x34\xd4\xd9\x89\xbb\x71\x59\xb6\x18\x1b\x35\x20\xa2\x9f\x0a\x03\xa2\xe5\x0d\x00\x00\xff\xff\x60\xcd\x06\xbe\x4a\x00\x00\x00")
func docGoBytes() ([]byte, error) {
@ -314,7 +336,7 @@ func docGo() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1698840720, 0)}
info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1700316153, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xde, 0x7c, 0x28, 0xcd, 0x47, 0xf2, 0xfa, 0x7c, 0x51, 0x2d, 0xd8, 0x38, 0xb, 0xb0, 0x34, 0x9d, 0x4c, 0x62, 0xa, 0x9e, 0x28, 0xc3, 0x31, 0x23, 0xd9, 0xbb, 0x89, 0x9f, 0xa0, 0x89, 0x1f, 0xe8}}
return a, nil
}
@ -410,34 +432,42 @@ func AssetNames() []string {
// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() (*asset, error){
"1691753758_initial.up.sql": _1691753758_initialUpSql,
"1692701329_add_collectibles_and_collections_data_cache.up.sql": _1692701329_add_collectibles_and_collections_data_cacheUpSql,
"1692701339_add_scope_to_pending.up.sql": _1692701339_add_scope_to_pendingUpSql,
"1694540071_add_collectibles_ownership_update_timestamp.up.sql": _1694540071_add_collectibles_ownership_update_timestampUpSql,
"1694692748_add_raw_balance_to_token_balances.up.sql": _1694692748_add_raw_balance_to_token_balancesUpSql,
"1691753758_initial.up.sql": _1691753758_initialUpSql,
"1692701329_add_collectibles_and_collections_data_cache.up.sql": _1692701329_add_collectibles_and_collections_data_cacheUpSql,
"1692701339_add_scope_to_pending.up.sql": _1692701339_add_scope_to_pendingUpSql,
"1694540071_add_collectibles_ownership_update_timestamp.up.sql": _1694540071_add_collectibles_ownership_update_timestampUpSql,
"1694692748_add_raw_balance_to_token_balances.up.sql": _1694692748_add_raw_balance_to_token_balancesUpSql,
"1695133989_add_community_id_to_collectibles_and_collections_data_cache.up.sql": _1695133989_add_community_id_to_collectibles_and_collections_data_cacheUpSql,
"1695932536_balance_history_v2.up.sql": _1695932536_balance_history_v2UpSql,
"1696853635_input_data.up.sql": _1696853635_input_dataUpSql,
"1698117918_add_community_id_to_tokens.up.sql": _1698117918_add_community_id_to_tokensUpSql,
"1698257443_add_community_metadata_to_wallet_db.up.sql": _1698257443_add_community_metadata_to_wallet_dbUpSql,
"1699987075_add_timestamp_and_state_to_community_data_cache.up.sql": _1699987075_add_timestamp_and_state_to_community_data_cacheUpSql,
"1695932536_balance_history_v2.up.sql": _1695932536_balance_history_v2UpSql,
"1696853635_input_data.up.sql": _1696853635_input_dataUpSql,
"1698117918_add_community_id_to_tokens.up.sql": _1698117918_add_community_id_to_tokensUpSql,
"1698257443_add_community_metadata_to_wallet_db.up.sql": _1698257443_add_community_metadata_to_wallet_dbUpSql,
"1699987075_add_timestamp_and_state_to_community_data_cache.up.sql": _1699987075_add_timestamp_and_state_to_community_data_cacheUpSql,
"1700414564_add_wallet_connect_pairings_table.up.sql": _1700414564_add_wallet_connect_pairings_tableUpSql,
"doc.go": docGo,
}
// AssetDebug is true if the assets were built with the debug flag enabled.
const AssetDebug = false
// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
// following hierarchy:
//
// data/
// foo.txt
// img/
// a.png
// b.png
//
// data/
// foo.txt
// img/
// a.png
// b.png
// then AssetDir("data") would return []string{"foo.txt", "img"},
// AssetDir("data/img") would return []string{"a.png", "b.png"},
// AssetDir("foo.txt") and AssetDir("notexist") would return an error, and
@ -470,18 +500,19 @@ type bintree struct {
}
var _bintree = &bintree{nil, map[string]*bintree{
"1691753758_initial.up.sql": {_1691753758_initialUpSql, map[string]*bintree{}},
"1692701329_add_collectibles_and_collections_data_cache.up.sql": {_1692701329_add_collectibles_and_collections_data_cacheUpSql, map[string]*bintree{}},
"1692701339_add_scope_to_pending.up.sql": {_1692701339_add_scope_to_pendingUpSql, map[string]*bintree{}},
"1694540071_add_collectibles_ownership_update_timestamp.up.sql": {_1694540071_add_collectibles_ownership_update_timestampUpSql, map[string]*bintree{}},
"1694692748_add_raw_balance_to_token_balances.up.sql": {_1694692748_add_raw_balance_to_token_balancesUpSql, map[string]*bintree{}},
"1695133989_add_community_id_to_collectibles_and_collections_data_cache.up.sql": {_1695133989_add_community_id_to_collectibles_and_collections_data_cacheUpSql, map[string]*bintree{}},
"1695932536_balance_history_v2.up.sql": {_1695932536_balance_history_v2UpSql, map[string]*bintree{}},
"1696853635_input_data.up.sql": {_1696853635_input_dataUpSql, map[string]*bintree{}},
"1698117918_add_community_id_to_tokens.up.sql": {_1698117918_add_community_id_to_tokensUpSql, map[string]*bintree{}},
"1698257443_add_community_metadata_to_wallet_db.up.sql": {_1698257443_add_community_metadata_to_wallet_dbUpSql, map[string]*bintree{}},
"1699987075_add_timestamp_and_state_to_community_data_cache.up.sql": {_1699987075_add_timestamp_and_state_to_community_data_cacheUpSql, map[string]*bintree{}},
"doc.go": {docGo, map[string]*bintree{}},
"1691753758_initial.up.sql": &bintree{_1691753758_initialUpSql, map[string]*bintree{}},
"1692701329_add_collectibles_and_collections_data_cache.up.sql": &bintree{_1692701329_add_collectibles_and_collections_data_cacheUpSql, map[string]*bintree{}},
"1692701339_add_scope_to_pending.up.sql": &bintree{_1692701339_add_scope_to_pendingUpSql, map[string]*bintree{}},
"1694540071_add_collectibles_ownership_update_timestamp.up.sql": &bintree{_1694540071_add_collectibles_ownership_update_timestampUpSql, map[string]*bintree{}},
"1694692748_add_raw_balance_to_token_balances.up.sql": &bintree{_1694692748_add_raw_balance_to_token_balancesUpSql, map[string]*bintree{}},
"1695133989_add_community_id_to_collectibles_and_collections_data_cache.up.sql": &bintree{_1695133989_add_community_id_to_collectibles_and_collections_data_cacheUpSql, map[string]*bintree{}},
"1695932536_balance_history_v2.up.sql": &bintree{_1695932536_balance_history_v2UpSql, map[string]*bintree{}},
"1696853635_input_data.up.sql": &bintree{_1696853635_input_dataUpSql, map[string]*bintree{}},
"1698117918_add_community_id_to_tokens.up.sql": &bintree{_1698117918_add_community_id_to_tokensUpSql, map[string]*bintree{}},
"1698257443_add_community_metadata_to_wallet_db.up.sql": &bintree{_1698257443_add_community_metadata_to_wallet_dbUpSql, map[string]*bintree{}},
"1699987075_add_timestamp_and_state_to_community_data_cache.up.sql": &bintree{_1699987075_add_timestamp_and_state_to_community_data_cacheUpSql, map[string]*bintree{}},
"1700414564_add_wallet_connect_pairings_table.up.sql": &bintree{_1700414564_add_wallet_connect_pairings_tableUpSql, map[string]*bintree{}},
"doc.go": &bintree{docGo, map[string]*bintree{}},
}}
// RestoreAsset restores an asset under the given directory.
@ -498,7 +529,7 @@ func RestoreAsset(dir, name string) error {
if err != nil {
return err
}
err = os.WriteFile(_filePath(dir, name), data, info.Mode())
err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
if err != nil {
return err
}

View File

@ -0,0 +1,15 @@
CREATE TABLE IF NOT EXISTS wallet_connect_pairings (
topic TEXT PRIMARY KEY NOT NULL,
expiry_timestamp INTEGER NOT NULL,
active BOOLEAN NOT NULL,
app_name TEXT,
url TEXT,
description TEXT,
icon TEXT,
verified_is_scam BOOLEAN,
verified_origin TEXT,
verified_verify_url TEXT,
verified_validation TEXT
);
CREATE INDEX IF NOT EXISTS idx_expiry ON wallet_connect_pairings (expiry_timestamp,active);