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:
parent
b7acde0910
commit
a855f9e3e8
|
@ -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))
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 VerifyContext struct {
|
||||
Verified struct {
|
||||
type Verified struct {
|
||||
VerifyURL string `json:"verifyUrl"`
|
||||
Validation string `json:"validation"`
|
||||
Origin string `json:"origin"`
|
||||
IsScam bool `json:"isScam,omitempty"`
|
||||
} `json:"verified"`
|
||||
}
|
||||
|
||||
type VerifyContext struct {
|
||||
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"`
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
@ -411,33 +433,41 @@ 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,
|
||||
|
||||
"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,
|
||||
|
||||
"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
|
||||
//
|
||||
// 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
|
||||
}
|
||||
|
|
|
@ -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);
|
Loading…
Reference in New Issue