feat(wallet) filter activity by erc20
Main changes: - Refactor activity API to propagate token identities. - Extend service to convert token identities to symbols for filtering multi-transaction - Filter transfers, pending_transactions and multi-transactions based on the provided token identities - Return involved token identities in activity API - Test token filtering Also: - Fixed calling cancel on a filer activity completed task to release resources Notes: - Found limitations with the token identity which complicates things by not allowing to filter by token groups (like token-code does) Updates status-desktop #11025
This commit is contained in:
parent
bf64f97d5a
commit
8e63f44735
|
@ -317,22 +317,14 @@ func migrateWalletJSONBlobs(sqlTx *sql.Tx) error {
|
|||
}
|
||||
|
||||
if nullableTx.Valid {
|
||||
var tokenAddress *common.Address
|
||||
var correctType w_common.Type
|
||||
var tokenID, value *big.Int
|
||||
if nullableL.Valid {
|
||||
correctType, tokenAddress, tokenID, value = w_common.ExtractTokenIdentity(w_common.Type(entryType), l, tx)
|
||||
} else {
|
||||
correctType = w_common.Type(entryType)
|
||||
value = new(big.Int).Set(tx.Value())
|
||||
}
|
||||
correctType, tokenID, value, dbAddress := extractToken(entryType, tx, l, nullableL.Valid)
|
||||
|
||||
gasPrice := sqlite.BigIntToClampedInt64(tx.GasPrice())
|
||||
gasTipCap := sqlite.BigIntToClampedInt64(tx.GasTipCap())
|
||||
gasFeeCap := sqlite.BigIntToClampedInt64(tx.GasFeeCap())
|
||||
valueStr := sqlite.BigIntToPadded128BitsStr(value)
|
||||
|
||||
currentRow = append(currentRow, tx.Type(), tx.Protected(), tx.Gas(), gasPrice, gasTipCap, gasFeeCap, valueStr, tx.Nonce(), int64(tx.Size()), &sqlite.JSONBlob{Data: tokenAddress}, (*bigint.SQLBigIntBytes)(tokenID), correctType)
|
||||
currentRow = append(currentRow, tx.Type(), tx.Protected(), tx.Gas(), gasPrice, gasTipCap, gasFeeCap, valueStr, tx.Nonce(), int64(tx.Size()), dbAddress, (*bigint.SQLBigIntBytes)(tokenID), correctType)
|
||||
} else {
|
||||
for i := 0; i < 11; i++ {
|
||||
currentRow = append(currentRow, nil)
|
||||
|
@ -377,3 +369,18 @@ func migrateWalletJSONBlobs(sqlTx *sql.Tx) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func extractToken(entryType string, tx *types.Transaction, l *types.Log, logValid bool) (correctType w_common.Type, tokenID *big.Int, value *big.Int, dbAddress *string) {
|
||||
if logValid {
|
||||
var tokenAddress *common.Address
|
||||
correctType, tokenAddress, tokenID, value = w_common.ExtractTokenIdentity(w_common.Type(entryType), l, tx)
|
||||
if tokenAddress != nil {
|
||||
dbAddress = new(string)
|
||||
*dbAddress = tokenAddress.Hex()
|
||||
}
|
||||
} else {
|
||||
correctType = w_common.Type(entryType)
|
||||
value = new(big.Int).Set(tx.Value())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -219,7 +219,7 @@ func TestMigrateWalletJsonBlobs(t *testing.T) {
|
|||
entryType string
|
||||
isTokenIDNull bool
|
||||
)
|
||||
dbTokenAddress := sqlite.JSONBlob{Data: &tokenAddress}
|
||||
var dbTokenAddress sql.NullString
|
||||
tokenID := new(big.Int)
|
||||
rows, err := db.Query(`SELECT status, receipt_type, tx_hash, log_index, block_hash, cumulative_gas_used, contract_address, gas_used, tx_index,
|
||||
tx_type, protected, gas_limit, gas_price_clamped64, gas_tip_cap_clamped64, gas_fee_cap_clamped64, amount_padded128hex, account_nonce, size, token_address, token_id, type,
|
||||
|
@ -242,6 +242,9 @@ func TestMigrateWalletJsonBlobs(t *testing.T) {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if dbTokenAddress.Valid {
|
||||
tokenAddress = common.HexToAddress(dbTokenAddress.String)
|
||||
}
|
||||
if dbContractAddress.Valid {
|
||||
contractAddress = common.HexToAddress(dbContractAddress.String)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Code generated by go-bindata. DO NOT EDIT.
|
||||
// sources:
|
||||
// .DS_Store (6.148kB)
|
||||
// 1640111208_dummy.up.sql (258B)
|
||||
// 1642666031_add_removed_clock_to_bookmarks.up.sql (117B)
|
||||
// 1643644541_gif_api_key_setting.up.sql (108B)
|
||||
|
@ -70,6 +69,7 @@
|
|||
// 1686041510_add_idx_transfers_blkno_loaded.up.sql (71B)
|
||||
// 1686048341_transfers_receipt_json_blob_out.up.sql.down.sql (104B)
|
||||
// 1686048341_transfers_receipt_json_blob_out.up.sql.up.sql (1.5kB)
|
||||
// 1686825075_cleanup_token_address.up.sql (273B)
|
||||
// doc.go (74B)
|
||||
|
||||
package migrations
|
||||
|
@ -139,26 +139,6 @@ func (fi bindataFileInfo) Sys() interface{} {
|
|||
return nil
|
||||
}
|
||||
|
||||
var _Ds_store = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xd8\x31\x0a\x02\x31\x10\x85\xe1\x37\x31\x45\xc0\x26\xa5\x65\x1a\x0f\xe0\x0d\xc2\xb2\x9e\xc0\x0b\x58\x78\x05\xfb\x1c\x5d\x96\x79\x60\x60\xd5\x4e\x8c\xcb\xfb\x40\xfe\x05\x37\x2a\x16\x31\x23\x00\x9b\xee\xb7\x13\x90\x01\x24\x78\x71\xc4\x4b\x89\x8f\x95\xd0\x5d\x1b\x5f\x43\x44\x44\x44\xc6\x66\x9e\xb4\xff\xf5\x07\x11\x91\xe1\x2c\xfb\x43\x61\x2b\xdb\xbc\xc6\xe7\x03\x1b\xbb\x35\x99\x2d\x6c\x65\x9b\xd7\x78\x5f\x60\x23\x9b\xd8\xcc\x16\xb6\xb2\xcd\xcb\x4d\xcb\x38\x7c\x18\xdf\xd9\x38\xa1\x18\xa7\x10\x2b\x6c\xfd\xce\x77\x23\xf2\xef\x76\x9e\xbc\xfc\xfe\x9f\xdf\xcf\xff\x22\xb2\x61\x16\xe7\xcb\x3c\x3d\x07\x82\xf5\x0d\x00\xae\xdd\xf5\xa7\x43\x40\xf0\x3f\x0b\x0f\xdd\x5a\x1d\x04\x44\x06\xf3\x08\x00\x00\xff\xff\x6a\x00\x88\x6d\x04\x18\x00\x00")
|
||||
|
||||
func Ds_storeBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
_Ds_store,
|
||||
".DS_Store",
|
||||
)
|
||||
}
|
||||
|
||||
func Ds_store() (*asset, error) {
|
||||
bytes, err := Ds_storeBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: ".DS_Store", size: 6148, mode: os.FileMode(0644), modTime: time.Unix(1685384027, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd6, 0x51, 0x65, 0x27, 0x91, 0x5, 0xca, 0x67, 0x73, 0x18, 0x5, 0x0, 0x68, 0x8d, 0xf4, 0xbd, 0xc6, 0x9a, 0x2c, 0x7b, 0x77, 0x17, 0x52, 0xf0, 0xa4, 0x6e, 0xf1, 0x20, 0xb7, 0xfd, 0x8e, 0xc3}}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var __1640111208_dummyUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\x8e\xb1\x4e\x04\x31\x0c\x44\x7b\xbe\x62\x3a\x40\x22\x7f\x71\x57\x50\xc0\x4a\xe8\x44\x9f\x4b\x26\x1b\x8b\x5d\x1b\x62\xa3\xe5\xf3\x51\x44\x45\x73\x6e\x3d\xef\xcd\xa4\x84\xd3\x82\xd7\xe5\x82\xb7\xf3\xcb\xf2\x7e\xbe\x4b\x09\xe9\xd6\xcd\xc0\xa5\x8b\xa3\xc9\x46\x54\xa3\x43\x2d\xba\xe8\x3a\x3f\xcf\x71\xef\x28\x83\x39\x58\xe1\x86\xe8\xc4\x2e\xeb\xc8\x21\xa6\xf8\x50\x3b\x1c\x6d\xd8\x8e\xa3\x4b\xe9\xf0\xaf\xed\xcf\x13\x86\x62\x1a\xa2\xdf\x84\x8b\x16\x62\xda\xfe\xd3\x3d\x3b\xae\xa4\xc2\x3f\x37\x89\x59\x20\x8a\x38\x0c\x0f\x57\x36\x1b\x7c\x42\xd6\x8a\xdc\x82\x03\x6a\x95\xa5\xad\xe0\x4f\x8c\x5c\x26\xfe\x38\x85\x27\x9b\x63\x91\x6b\x45\xb1\x4a\x74\x0e\xfe\x06\x00\x00\xff\xff\x9b\xc1\xf3\x13\x02\x01\x00\x00")
|
||||
|
||||
func _1640111208_dummyUpSqlBytes() ([]byte, error) {
|
||||
|
@ -174,7 +154,7 @@ func _1640111208_dummyUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1640111208_dummy.up.sql", size: 258, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1640111208_dummy.up.sql", size: 258, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3e, 0xf0, 0xae, 0x20, 0x6e, 0x75, 0xd1, 0x36, 0x14, 0xf2, 0x40, 0xe5, 0xd6, 0x7a, 0xc4, 0xa5, 0x72, 0xaa, 0xb5, 0x4d, 0x71, 0x97, 0xb8, 0xe8, 0x95, 0x22, 0x95, 0xa2, 0xac, 0xaf, 0x48, 0x58}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -194,7 +174,7 @@ func _1642666031_add_removed_clock_to_bookmarksUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1642666031_add_removed_clock_to_bookmarks.up.sql", size: 117, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1642666031_add_removed_clock_to_bookmarks.up.sql", size: 117, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x84, 0x4e, 0x38, 0x99, 0x7a, 0xc, 0x90, 0x13, 0xec, 0xfe, 0x2f, 0x55, 0xff, 0xb7, 0xb6, 0xaa, 0x96, 0xc6, 0x92, 0x79, 0xcc, 0xee, 0x4e, 0x99, 0x53, 0xfe, 0x1c, 0xbb, 0x32, 0x2, 0xa4, 0x27}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -214,7 +194,7 @@ func _1643644541_gif_api_key_settingUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1643644541_gif_api_key_setting.up.sql", size: 108, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1643644541_gif_api_key_setting.up.sql", size: 108, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1b, 0x94, 0x28, 0xfb, 0x66, 0xd1, 0x7c, 0xb8, 0x89, 0xe2, 0xb4, 0x71, 0x65, 0x24, 0x57, 0x22, 0x95, 0x38, 0x97, 0x3, 0x9b, 0xc6, 0xa4, 0x41, 0x7b, 0xba, 0xf7, 0xdb, 0x70, 0xf7, 0x20, 0x3a}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -234,7 +214,7 @@ func _1644188994_recent_stickersUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1644188994_recent_stickers.up.sql", size: 79, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1644188994_recent_stickers.up.sql", size: 79, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1e, 0xad, 0xaa, 0x30, 0xbf, 0x4, 0x7, 0xf8, 0xc3, 0x3, 0xb8, 0x97, 0x23, 0x2b, 0xbd, 0x1c, 0x60, 0x69, 0xb0, 0x42, 0x5e, 0x6b, 0xd, 0xa7, 0xa3, 0x6b, 0x2e, 0xdc, 0x70, 0x13, 0x72, 0x7}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -254,7 +234,7 @@ func _1646659233_add_address_to_dapp_permisssionUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1646659233_add_address_to_dapp_permisssion.up.sql", size: 700, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1646659233_add_address_to_dapp_permisssion.up.sql", size: 700, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xed, 0xb0, 0x35, 0xcc, 0x2e, 0x16, 0xe6, 0x15, 0x86, 0x2c, 0x37, 0x80, 0xae, 0xa3, 0xc5, 0x31, 0x78, 0x5, 0x9d, 0xcd, 0x7b, 0xeb, 0x5f, 0xf2, 0xb3, 0x74, 0x72, 0xdf, 0xcf, 0x88, 0xb, 0x40}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -274,7 +254,7 @@ func _1646841105_add_emoji_accountUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1646841105_add_emoji_account.up.sql", size: 96, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1646841105_add_emoji_account.up.sql", size: 96, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe6, 0x77, 0x29, 0x95, 0x18, 0x64, 0x82, 0x63, 0xe7, 0xaf, 0x6c, 0xa9, 0x15, 0x7d, 0x46, 0xa6, 0xbc, 0xdf, 0xa7, 0xd, 0x2b, 0xd2, 0x2d, 0x97, 0x4d, 0xa, 0x6b, 0xd, 0x6e, 0x90, 0x42, 0x5c}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -294,7 +274,7 @@ func _1647278782_display_nameUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1647278782_display_name.up.sql", size: 110, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1647278782_display_name.up.sql", size: 110, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf4, 0xa1, 0x1f, 0x3e, 0x61, 0x65, 0x8d, 0xff, 0xee, 0xde, 0xc5, 0x91, 0xd9, 0x5c, 0xb5, 0xe2, 0xf0, 0xb7, 0xe7, 0x5c, 0x5c, 0x16, 0x25, 0x89, 0xee, 0x78, 0x12, 0xea, 0x3e, 0x48, 0x41, 0xa6}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -314,7 +294,7 @@ func _1647862838_reset_last_backupUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1647862838_reset_last_backup.up.sql", size: 37, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1647862838_reset_last_backup.up.sql", size: 37, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x21, 0xe3, 0xd5, 0xf6, 0x5f, 0xfe, 0x65, 0xfa, 0x1d, 0x88, 0xf8, 0x5f, 0x24, 0x71, 0x34, 0x68, 0x96, 0x2a, 0x60, 0x87, 0x15, 0x82, 0x4d, 0x8a, 0x59, 0x3d, 0x1f, 0xd8, 0x56, 0xd4, 0xfb, 0xda}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -334,7 +314,7 @@ func _1647871652_add_settings_sync_clock_tableUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1647871652_add_settings_sync_clock_table.up.sql", size: 1044, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1647871652_add_settings_sync_clock_table.up.sql", size: 1044, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd8, 0x58, 0xec, 0x85, 0x90, 0xfa, 0x30, 0x98, 0x98, 0x9a, 0xa6, 0xa8, 0x96, 0x2b, 0x38, 0x93, 0xf3, 0xae, 0x46, 0x74, 0xa4, 0x41, 0x62, 0x9b, 0x2, 0x86, 0xbf, 0xe5, 0x2a, 0xce, 0xe2, 0xc0}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -354,7 +334,7 @@ func _1647880168_add_torrent_configUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1647880168_add_torrent_config.up.sql", size: 211, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1647880168_add_torrent_config.up.sql", size: 211, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1, 0x92, 0x22, 0x37, 0x96, 0xf3, 0xb5, 0x5b, 0x27, 0xd0, 0x7d, 0x43, 0x5, 0x4e, 0x9d, 0xe2, 0x49, 0xbe, 0x86, 0x31, 0xa1, 0x89, 0xff, 0xd6, 0x51, 0xe0, 0x9c, 0xb, 0xda, 0xfc, 0xf2, 0x93}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -374,7 +354,7 @@ func _1647882837_add_communities_settings_tableUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1647882837_add_communities_settings_table.up.sql", size: 206, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1647882837_add_communities_settings_table.up.sql", size: 206, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xbd, 0x87, 0x78, 0x99, 0xd9, 0x5d, 0xbd, 0xf7, 0x57, 0x9c, 0xca, 0x97, 0xbd, 0xb3, 0xe9, 0xb5, 0x89, 0x31, 0x3f, 0xf6, 0x5c, 0x13, 0xb, 0xc3, 0x54, 0x93, 0x18, 0x40, 0x7, 0x82, 0xfe, 0x7e}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -394,7 +374,7 @@ func _1647956635_add_waku_messages_tableUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1647956635_add_waku_messages_table.up.sql", size: 266, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1647956635_add_waku_messages_table.up.sql", size: 266, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd1, 0xe, 0xe1, 0xdc, 0xda, 0x2e, 0x89, 0x8d, 0xdc, 0x2a, 0x1c, 0x13, 0xa1, 0xfc, 0xfe, 0xf, 0xb2, 0xb9, 0x85, 0xc8, 0x45, 0xd6, 0xd1, 0x7, 0x5c, 0xa3, 0x8, 0x47, 0x44, 0x6d, 0x96, 0xe0}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -414,7 +394,7 @@ func _1648554928_network_testUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1648554928_network_test.up.sql", size: 132, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1648554928_network_test.up.sql", size: 132, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x9a, 0xc5, 0x7f, 0x87, 0xf3, 0x2c, 0xf7, 0xbb, 0xd3, 0x3a, 0x4e, 0x76, 0x88, 0xca, 0xaf, 0x73, 0xce, 0x8f, 0xa1, 0xf6, 0x3d, 0x4d, 0xed, 0x6f, 0x49, 0xf2, 0xfe, 0x56, 0x2a, 0x60, 0x68, 0xca}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -434,7 +414,7 @@ func _1649174829_add_visitble_tokenUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1649174829_add_visitble_token.up.sql", size: 84, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1649174829_add_visitble_token.up.sql", size: 84, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa3, 0x22, 0xc0, 0x2b, 0x3f, 0x4f, 0x3d, 0x5e, 0x4c, 0x68, 0x7c, 0xd0, 0x15, 0x36, 0x9f, 0xec, 0xa1, 0x2a, 0x7b, 0xb4, 0xe3, 0xc6, 0xc9, 0xb4, 0x81, 0x50, 0x4a, 0x11, 0x3b, 0x35, 0x7, 0xcf}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -454,7 +434,7 @@ func _1649882262_add_derived_from_accountsUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1649882262_add_derived_from_accounts.up.sql", size: 110, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1649882262_add_derived_from_accounts.up.sql", size: 110, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x11, 0xb9, 0x44, 0x4d, 0x85, 0x8d, 0x7f, 0xb4, 0xae, 0x4f, 0x5c, 0x66, 0x64, 0xb6, 0xe2, 0xe, 0x3d, 0xad, 0x9d, 0x8, 0x4f, 0xab, 0x6e, 0xa8, 0x7d, 0x76, 0x3, 0xad, 0x96, 0x1, 0xee, 0x5c}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -474,7 +454,7 @@ func _1650612625_add_community_message_archive_hashes_tableUpSql() (*asset, erro
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1650612625_add_community_message_archive_hashes_table.up.sql", size: 130, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1650612625_add_community_message_archive_hashes_table.up.sql", size: 130, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x48, 0x31, 0xb3, 0x75, 0x23, 0xe2, 0x45, 0xe, 0x47, 0x1b, 0x35, 0xa5, 0x6e, 0x83, 0x4e, 0x64, 0x7d, 0xd7, 0xa2, 0xda, 0xe9, 0x53, 0xf1, 0x16, 0x86, 0x2c, 0x57, 0xad, 0xfa, 0xca, 0x39, 0xde}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -494,7 +474,7 @@ func _1650616788_add_communities_archives_info_tableUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1650616788_add_communities_archives_info_table.up.sql", size: 208, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1650616788_add_communities_archives_info_table.up.sql", size: 208, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd1, 0x4f, 0x80, 0x45, 0xb9, 0xd9, 0x15, 0xe2, 0x78, 0xd0, 0xcb, 0x71, 0xc1, 0x1b, 0xb7, 0x1b, 0x1b, 0x97, 0xfe, 0x47, 0x53, 0x3c, 0x62, 0xbc, 0xdd, 0x3a, 0x94, 0x1a, 0xc, 0x48, 0x76, 0xe}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -514,7 +494,7 @@ func _1652715604_add_clock_accountsUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1652715604_add_clock_accounts.up.sql", size: 62, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1652715604_add_clock_accounts.up.sql", size: 62, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb6, 0xd9, 0x8d, 0x73, 0xc9, 0xef, 0xfa, 0xb1, 0x4b, 0xa5, 0xf3, 0x5, 0x19, 0x26, 0x46, 0xf8, 0x47, 0x93, 0xdb, 0xac, 0x2, 0xef, 0xf9, 0x71, 0x56, 0x83, 0xe6, 0x2d, 0xb0, 0xd7, 0x83, 0x5c}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -534,7 +514,7 @@ func _1653037334_add_notifications_settings_tableUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1653037334_add_notifications_settings_table.up.sql", size: 1276, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1653037334_add_notifications_settings_table.up.sql", size: 1276, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x4b, 0xc4, 0x65, 0xac, 0xa, 0xf2, 0xef, 0xb6, 0x39, 0x3c, 0xc5, 0xb1, 0xb2, 0x9c, 0x86, 0x58, 0xe0, 0x38, 0xcb, 0x57, 0x3c, 0x76, 0x73, 0x87, 0x79, 0x4e, 0xf6, 0xed, 0xb0, 0x8e, 0x9e, 0xa}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -554,7 +534,7 @@ func _1654702119_add_mutual_contact_settingsUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1654702119_add_mutual_contact_settings.up.sql", size: 78, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1654702119_add_mutual_contact_settings.up.sql", size: 78, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x26, 0x66, 0x67, 0x50, 0xfe, 0xd7, 0xe3, 0x29, 0x8b, 0xff, 0x9d, 0x5a, 0x87, 0xa7, 0x99, 0x6e, 0xd6, 0xcd, 0x2e, 0xbb, 0x17, 0xdf, 0x7f, 0xf7, 0xa3, 0xfa, 0x32, 0x7c, 0x2d, 0x92, 0xc8, 0x74}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -574,7 +554,7 @@ func _1655375270_add_clock_field_to_communities_settings_tableUpSql() (*asset, e
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1655375270_add_clock_field_to_communities_settings_table.up.sql", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1655375270_add_clock_field_to_communities_settings_table.up.sql", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x19, 0xc5, 0xc0, 0xf9, 0x84, 0x53, 0xdf, 0x83, 0xcf, 0xb6, 0x40, 0x6d, 0xf5, 0xdc, 0x77, 0x37, 0xb7, 0xe3, 0xa, 0x75, 0xe7, 0x6, 0x11, 0xca, 0x2b, 0x51, 0x92, 0xdd, 0x7d, 0xdb, 0xc3, 0xf5}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -594,7 +574,7 @@ func _1655385721_drop_networks_configUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1655385721_drop_networks_config.up.sql", size: 27, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1655385721_drop_networks_config.up.sql", size: 27, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xfc, 0xa7, 0x20, 0xbb, 0x67, 0x21, 0xe, 0xc6, 0xc8, 0x21, 0x74, 0xe0, 0xce, 0xc8, 0xe2, 0x2, 0xb4, 0xea, 0xf0, 0xe5, 0xc4, 0x4d, 0xdd, 0xd4, 0x52, 0x31, 0xa9, 0x3d, 0xcd, 0xd8, 0x9b, 0xab}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -614,7 +594,7 @@ func _1655385724_networks_chaincolor_shortnameUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1655385724_networks_chainColor_shortName.up.sql", size: 220, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1655385724_networks_chainColor_shortName.up.sql", size: 220, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd9, 0xe7, 0x84, 0xbb, 0x5f, 0xd2, 0x2c, 0x42, 0x88, 0x62, 0x52, 0xb6, 0x58, 0x31, 0xac, 0xc, 0x96, 0x2b, 0x1b, 0xe5, 0x4e, 0x9a, 0x3a, 0xf6, 0xf6, 0xfc, 0xa9, 0x1a, 0x35, 0x62, 0x28, 0x88}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -634,7 +614,7 @@ func _1655456688_add_deleted_at_field_to_bookmarks_tableUpSql() (*asset, error)
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1655456688_add_deleted_at_field_to_bookmarks_table.up.sql", size: 69, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1655456688_add_deleted_at_field_to_bookmarks_table.up.sql", size: 69, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe7, 0x9a, 0xbd, 0x9a, 0xc9, 0xf, 0xdf, 0x90, 0x0, 0x5d, 0xea, 0x6e, 0x7d, 0x51, 0x95, 0xcd, 0x90, 0xd3, 0x1a, 0x36, 0x6c, 0xf4, 0xbd, 0xa7, 0x6b, 0xbf, 0xe5, 0xdb, 0xa3, 0x88, 0xe3, 0x50}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -654,7 +634,7 @@ func _1655462032_create_bookmarks_deleted_at_indexUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1655462032_create_bookmarks_deleted_at_index.up.sql", size: 81, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1655462032_create_bookmarks_deleted_at_index.up.sql", size: 81, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf, 0x8e, 0x20, 0x6b, 0x14, 0x9e, 0xcd, 0x97, 0xd3, 0xfe, 0x62, 0x3, 0x26, 0x59, 0x1, 0x6c, 0x99, 0xef, 0x6d, 0x21, 0xd4, 0xb5, 0xa3, 0xf4, 0x39, 0x40, 0x54, 0x6, 0xd, 0x60, 0x13, 0x38}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -674,7 +654,7 @@ func _1657617291_add_multi_transactions_tableUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1657617291_add_multi_transactions_table.up.sql", size: 412, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1657617291_add_multi_transactions_table.up.sql", size: 412, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x86, 0xb0, 0x4e, 0x8c, 0x4, 0x82, 0xb4, 0x43, 0xaa, 0xd0, 0x16, 0xdd, 0xcb, 0x88, 0x81, 0xac, 0x4, 0x34, 0x1a, 0x8f, 0x2e, 0xc5, 0x69, 0xb, 0xf0, 0x17, 0xf7, 0xe3, 0x9, 0xe, 0x54, 0xe0}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -694,7 +674,7 @@ func _1660134042_add_social_links_settings_tableUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1660134042_add_social_links_settings_table.up.sql", size: 334, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1660134042_add_social_links_settings_table.up.sql", size: 334, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x84, 0x73, 0xb6, 0xe7, 0x3f, 0xaa, 0x39, 0x9a, 0x56, 0x56, 0x31, 0xf1, 0x8e, 0x26, 0x23, 0x1, 0xe4, 0xfa, 0x98, 0xfe, 0x78, 0x87, 0x20, 0xcb, 0x52, 0xf4, 0x38, 0x7f, 0xc4, 0x1c, 0x4, 0x22}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -714,7 +694,7 @@ func _1660134060_settings_bioUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1660134060_settings_bio.up.sql", size: 91, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1660134060_settings_bio.up.sql", size: 91, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x46, 0x25, 0xa0, 0xa6, 0x47, 0xff, 0xbc, 0x2a, 0x0, 0xff, 0x59, 0x4b, 0xb0, 0xc9, 0x4e, 0x15, 0xe4, 0xd9, 0xda, 0xeb, 0xfe, 0x55, 0x98, 0xc3, 0x9d, 0x96, 0xe7, 0xf, 0xd1, 0x5c, 0x93, 0x73}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -734,7 +714,7 @@ func _1660134070_add_wakuv2_storeUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1660134070_add_wakuv2_store.up.sql", size: 269, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1660134070_add_wakuv2_store.up.sql", size: 269, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1d, 0xe6, 0xc3, 0x9, 0xef, 0xdc, 0xae, 0x49, 0x30, 0x78, 0x54, 0xd6, 0xdb, 0xbf, 0xc0, 0x8e, 0x25, 0x8f, 0xfc, 0x67, 0x80, 0x39, 0x37, 0xd4, 0x86, 0xc1, 0x85, 0xc8, 0x99, 0xc4, 0x59, 0xd4}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -754,7 +734,7 @@ func _1660134072_waku2_store_messagesUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1660134072_waku2_store_messages.up.sql", size: 497, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1660134072_waku2_store_messages.up.sql", size: 497, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3e, 0xeb, 0xb4, 0xa0, 0xa1, 0x2b, 0xcb, 0x4c, 0x3c, 0xc6, 0xd0, 0xe8, 0x96, 0xe3, 0x96, 0xf1, 0x4f, 0x1f, 0xe0, 0xe7, 0x1f, 0x85, 0xa3, 0xe, 0xf7, 0x52, 0x56, 0x63, 0x2b, 0xb0, 0x87, 0x7b}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -774,7 +754,7 @@ func _1662365868_add_key_uid_accountsUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1662365868_add_key_uid_accounts.up.sql", size: 68, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1662365868_add_key_uid_accounts.up.sql", size: 68, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc6, 0xd8, 0x2f, 0x2f, 0x3b, 0xa8, 0xbd, 0x6d, 0xf6, 0x87, 0x7e, 0xd2, 0xf1, 0xa2, 0xf7, 0x81, 0x6a, 0x23, 0x10, 0xbc, 0xbf, 0x5b, 0xe7, 0x2b, 0x9c, 0xa9, 0x8a, 0x18, 0xbb, 0xd0, 0x86, 0x91}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -794,7 +774,7 @@ func _1662447680_add_keypairs_tableUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1662447680_add_keypairs_table.up.sql", size: 218, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1662447680_add_keypairs_table.up.sql", size: 218, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 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
|
||||
}
|
||||
|
@ -814,7 +794,7 @@ func _1662460056_move_favourites_to_saved_addressesUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1662460056_move_favourites_to_saved_addresses.up.sql", size: 233, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1662460056_move_favourites_to_saved_addresses.up.sql", size: 233, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x10, 0xa2, 0x8c, 0xa3, 0xec, 0xad, 0xdf, 0xc3, 0x48, 0x5, 0x9b, 0x50, 0x25, 0x59, 0xae, 0x7d, 0xee, 0x58, 0xd2, 0x41, 0x27, 0xf2, 0x22, 0x2e, 0x9a, 0xb9, 0x4a, 0xcc, 0x38, 0x6e, 0x3a, 0xb2}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -834,7 +814,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(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1662738097_add_base_fee_transaction.up.sql", size: 112, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 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
|
||||
}
|
||||
|
@ -854,7 +834,7 @@ func _1662972194_add_keypairs_tableUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1662972194_add_keypairs_table.up.sql", size: 345, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1662972194_add_keypairs_table.up.sql", size: 345, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xab, 0x76, 0xf2, 0x86, 0xe1, 0x7e, 0xe9, 0x47, 0x32, 0x48, 0xd5, 0x6b, 0xe5, 0xd, 0xab, 0xb7, 0xf1, 0xd4, 0xf1, 0xad, 0x38, 0xa6, 0x11, 0xe7, 0xce, 0x5c, 0x11, 0x11, 0xf, 0x47, 0xb2, 0x4}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -874,7 +854,7 @@ func _1664392661_add_third_party_id_to_waku_messagesUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1664392661_add_third_party_id_to_waku_messages.up.sql", size: 70, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1664392661_add_third_party_id_to_waku_messages.up.sql", size: 70, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xfd, 0x67, 0x66, 0x9e, 0x66, 0x74, 0xce, 0x1c, 0xb, 0x1b, 0x9d, 0xd5, 0xfc, 0x65, 0xe, 0x83, 0x90, 0x4c, 0x61, 0x4e, 0x6b, 0xe7, 0x86, 0xbe, 0x36, 0x4f, 0x91, 0x36, 0x4, 0x47, 0x7b, 0x82}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -894,7 +874,7 @@ func _1664783660_add_sync_info_to_saved_addressesUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1664783660_add_sync_info_to_saved_addresses.up.sql", size: 388, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1664783660_add_sync_info_to_saved_addresses.up.sql", size: 388, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x67, 0x7c, 0x3a, 0x95, 0x4e, 0x55, 0xb2, 0xbd, 0xb4, 0x18, 0x93, 0xc1, 0xcf, 0x9f, 0x12, 0xbb, 0x49, 0x8a, 0x2a, 0x6a, 0x2a, 0x7f, 0xad, 0x44, 0xc3, 0xf, 0x3a, 0x79, 0x18, 0xb9, 0x4c, 0x64}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -914,7 +894,7 @@ func _1668109917_wakunodesUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1668109917_wakunodes.up.sql", size: 99, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1668109917_wakunodes.up.sql", size: 99, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x29, 0xaa, 0x9e, 0x2, 0x66, 0x85, 0x69, 0xa8, 0xd9, 0xe2, 0x4b, 0x8d, 0x2a, 0x9c, 0xdf, 0xd2, 0xef, 0x64, 0x58, 0xe3, 0xa6, 0xe7, 0xc1, 0xd1, 0xc8, 0x9c, 0xc0, 0x2c, 0x1, 0xa8, 0x7b, 0x81}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -934,7 +914,7 @@ func _1670249678_display_name_to_settings_sync_clock_tableUpSql() (*asset, error
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1670249678_display_name_to_settings_sync_clock_table.up.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1670249678_display_name_to_settings_sync_clock_table.up.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x39, 0x18, 0xdc, 0xc4, 0x1f, 0x79, 0x22, 0x16, 0x4d, 0xdf, 0x6c, 0x66, 0xd5, 0xa4, 0x88, 0x5d, 0x5, 0x37, 0xa7, 0x41, 0x5, 0x50, 0xae, 0x12, 0xfa, 0x7e, 0x89, 0x24, 0x5c, 0xae, 0x30, 0xfc}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -954,7 +934,7 @@ func _1670836810_add_imported_flag_to_community_archive_hashesUpSql() (*asset, e
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1670836810_add_imported_flag_to_community_archive_hashes.up.sql", size: 144, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1670836810_add_imported_flag_to_community_archive_hashes.up.sql", size: 144, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x6f, 0xf, 0xf0, 0xbd, 0xfe, 0x63, 0x25, 0x8f, 0x5e, 0x46, 0x4b, 0x45, 0x31, 0x8b, 0x3e, 0xd8, 0x6b, 0x5d, 0x9d, 0x6d, 0x10, 0x9a, 0x87, 0x4b, 0x18, 0xc6, 0x39, 0x81, 0x6e, 0xe4, 0x75, 0xfb}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -974,7 +954,7 @@ func _1671438731_add_magnetlink_uri_to_communities_archive_infoUpSql() (*asset,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1671438731_add_magnetlink_uri_to_communities_archive_info.up.sql", size: 86, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1671438731_add_magnetlink_uri_to_communities_archive_info.up.sql", size: 86, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xda, 0x8b, 0x4b, 0xd6, 0xd8, 0xe2, 0x3d, 0xf7, 0x6b, 0xcd, 0x1e, 0x70, 0x9, 0x2e, 0x35, 0x4, 0x61, 0xc3, 0xb5, 0x9d, 0xc5, 0x27, 0x21, 0xa, 0x5a, 0xd6, 0x3e, 0xa6, 0x24, 0xa2, 0x12, 0xdf}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -994,7 +974,7 @@ func _1672933930_switcher_cardUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1672933930_switcher_card.up.sql", size: 162, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1672933930_switcher_card.up.sql", size: 162, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x39, 0xba, 0xdc, 0xbb, 0x40, 0x4, 0xf2, 0x10, 0xdf, 0xb4, 0xd2, 0x80, 0x8a, 0x74, 0x4d, 0xf6, 0xbc, 0x50, 0x7, 0xd, 0x22, 0x7f, 0xc4, 0xaf, 0xaa, 0xde, 0xdc, 0x71, 0xe9, 0x42, 0x98, 0x36}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1014,7 +994,7 @@ func _1674056187_add_price_cacheUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1674056187_add_price_cache.up.sql", size: 255, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1674056187_add_price_cache.up.sql", size: 255, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb7, 0x79, 0x6a, 0x9b, 0x28, 0xd1, 0x22, 0xf0, 0x84, 0x76, 0x40, 0x39, 0x49, 0x15, 0x5d, 0xaa, 0xfd, 0x11, 0xff, 0x13, 0x27, 0x42, 0x12, 0xfa, 0x82, 0xe6, 0x7a, 0xf0, 0x5e, 0x1f, 0xe3, 0xba}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1034,7 +1014,7 @@ func _1674136690_ens_usernamesUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1674136690_ens_usernames.up.sql", size: 98, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1674136690_ens_usernames.up.sql", size: 98, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x81, 0x7a, 0xf3, 0xa8, 0x88, 0x99, 0xd6, 0x9c, 0x69, 0x48, 0x3c, 0x10, 0xda, 0x72, 0xdc, 0x14, 0xd, 0x6e, 0x8c, 0x82, 0x92, 0x2d, 0x2c, 0xee, 0x4c, 0x70, 0xa4, 0xdc, 0x5c, 0x5, 0x2, 0xc3}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1054,7 +1034,7 @@ func _1674232431_add_balance_historyUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1674232431_add_balance_history.up.sql", size: 698, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1674232431_add_balance_history.up.sql", size: 698, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf7, 0xb5, 0x18, 0xca, 0x4a, 0x93, 0xbb, 0x6f, 0xa4, 0xee, 0xe4, 0x3e, 0xff, 0x6a, 0x4b, 0xe2, 0xe1, 0x61, 0x28, 0xee, 0xc5, 0x26, 0x57, 0x61, 0x5e, 0x6d, 0x44, 0x1e, 0x85, 0x43, 0x70, 0xa2}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1074,7 +1054,7 @@ func _1676368933_keypairs_to_keycardsUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1676368933_keypairs_to_keycards.up.sql", size: 639, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1676368933_keypairs_to_keycards.up.sql", size: 639, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x81, 0x93, 0x27, 0x2, 0xf0, 0x37, 0x81, 0x65, 0xa4, 0xb3, 0x5b, 0x60, 0x36, 0x95, 0xfc, 0x81, 0xf0, 0x3b, 0x7c, 0xc3, 0x2c, 0x85, 0xbd, 0x38, 0x46, 0xa4, 0x95, 0x4a, 0x6, 0x3e, 0x74, 0xd5}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1094,7 +1074,7 @@ func _1676951398_add_currency_format_cacheUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1676951398_add_currency_format_cache.up.sql", size: 291, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1676951398_add_currency_format_cache.up.sql", size: 291, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf9, 0xa3, 0x76, 0x35, 0xca, 0xf, 0xe8, 0xdf, 0xd9, 0x61, 0xf9, 0xed, 0xfc, 0x6d, 0xf5, 0xe, 0x11, 0x88, 0xbd, 0x14, 0x92, 0xc6, 0x57, 0x53, 0xe, 0xcd, 0x52, 0xf4, 0xa9, 0xb1, 0xdd, 0xfd}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1114,7 +1094,7 @@ func _1676968196_keycards_add_clock_columnUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1676968196_keycards_add_clock_column.up.sql", size: 73, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1676968196_keycards_add_clock_column.up.sql", size: 73, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x4c, 0xf, 0x1c, 0x28, 0x41, 0x57, 0x57, 0x6c, 0xe, 0x75, 0x6b, 0x75, 0x12, 0x0, 0x18, 0x1e, 0x88, 0x1e, 0x45, 0xe0, 0x32, 0xb9, 0xd4, 0xd9, 0x2e, 0xc8, 0xb, 0x80, 0x6, 0x51, 0x3d, 0x28}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1134,7 +1114,7 @@ func _1676968197_add_fallback_rpc_to_networksUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1676968197_add_fallback_rpc_to_networks.up.sql", size: 112, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1676968197_add_fallback_rpc_to_networks.up.sql", size: 112, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x77, 0x6a, 0xc6, 0x45, 0xfa, 0x62, 0x84, 0x74, 0x6d, 0x7c, 0xd7, 0x1d, 0x79, 0xb6, 0x38, 0x43, 0xa8, 0x8, 0x6b, 0x75, 0x3d, 0x9, 0x2, 0xc5, 0x9f, 0xbb, 0x45, 0x56, 0x4c, 0x4e, 0x17, 0x89}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1154,7 +1134,7 @@ func _1677674090_add_chains_ens_istest_to_saved_addressesUpSql() (*asset, error)
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1677674090_add_chains_ens_istest_to_saved_addresses.up.sql", size: 638, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1677674090_add_chains_ens_istest_to_saved_addresses.up.sql", size: 638, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa8, 0x2d, 0xa4, 0x1b, 0xf6, 0x6a, 0x13, 0x7b, 0xe, 0x59, 0xcd, 0xe2, 0x4e, 0x81, 0x99, 0xc4, 0x33, 0x84, 0xde, 0x66, 0xca, 0xac, 0x2f, 0x5, 0x90, 0xac, 0xfd, 0x4e, 0xfc, 0x55, 0x44, 0xe5}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1174,7 +1154,7 @@ func _1677681143_accounts_table_type_column_updateUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1677681143_accounts_table_type_column_update.up.sql", size: 135, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1677681143_accounts_table_type_column_update.up.sql", size: 135, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd2, 0xc4, 0x6, 0x42, 0x50, 0x1d, 0xf4, 0x48, 0x55, 0xbc, 0xa2, 0x19, 0xdd, 0xad, 0xc8, 0xc, 0xa7, 0x30, 0xb6, 0xaf, 0xe, 0x2b, 0xaa, 0x2a, 0xa4, 0xe1, 0xb9, 0x41, 0x23, 0x66, 0xd3, 0x3}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1194,7 +1174,7 @@ func _1678264207_accounts_table_new_columns_addedUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1678264207_accounts_table_new_columns_added.up.sql", size: 130, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1678264207_accounts_table_new_columns_added.up.sql", size: 130, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf4, 0xd4, 0xf3, 0x35, 0xef, 0x5c, 0x19, 0x3c, 0x15, 0x90, 0x60, 0xbd, 0x1f, 0x81, 0xf0, 0x86, 0x73, 0x89, 0xa0, 0x70, 0xf2, 0x46, 0xae, 0xea, 0xd0, 0xc6, 0x9e, 0x55, 0x4a, 0x54, 0x62, 0xbb}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1214,7 +1194,7 @@ func _1680770368_add_bio_to_settings_sync_clock_tableUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1680770368_add_bio_to_settings_sync_clock_table.up.sql", size: 75, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1680770368_add_bio_to_settings_sync_clock_table.up.sql", size: 75, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x4a, 0x52, 0xf6, 0x3f, 0xaa, 0xd, 0xa0, 0xee, 0xe8, 0xe6, 0x16, 0x21, 0x80, 0x61, 0xe4, 0x7a, 0x4e, 0x37, 0x8d, 0x30, 0x51, 0x20, 0x4d, 0x15, 0x47, 0xfb, 0x6, 0xa1, 0xce, 0xc8, 0x27, 0x5a}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1234,7 +1214,7 @@ func _1681110436_add_mnemonic_to_settings_sync_clock_tableUpSql() (*asset, error
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1681110436_add_mnemonic_to_settings_sync_clock_table.up.sql", size: 311, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1681110436_add_mnemonic_to_settings_sync_clock_table.up.sql", size: 311, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3d, 0x74, 0x81, 0x7d, 0x9e, 0x77, 0xb6, 0xfe, 0xe3, 0xcb, 0x48, 0xe5, 0x5f, 0x39, 0x23, 0xa1, 0x7d, 0x53, 0x22, 0xe8, 0x96, 0x15, 0x8a, 0x1e, 0x8e, 0xbc, 0xe2, 0x1d, 0xc4, 0xc2, 0x56, 0x34}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1254,7 +1234,7 @@ func _1681392602_9d_sync_periodUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1681392602_9d_sync_period.up.sql", size: 60, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1681392602_9d_sync_period.up.sql", size: 60, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc9, 0xa, 0x90, 0x29, 0x7f, 0x76, 0x98, 0xa7, 0x71, 0x80, 0x5a, 0x2f, 0xbe, 0x23, 0x9a, 0xd4, 0xf4, 0x39, 0x19, 0xd3, 0xa5, 0x34, 0x6e, 0x67, 0x6a, 0xbe, 0x8a, 0xad, 0x21, 0xc7, 0xba, 0x88}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1274,7 +1254,7 @@ func _1681762078_default_sync_period_9dUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1681762078_default_sync_period_9d.up.sql", size: 3002, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1681762078_default_sync_period_9d.up.sql", size: 3002, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3e, 0xd9, 0x26, 0xfc, 0xa9, 0x45, 0xc1, 0x81, 0xa8, 0xe2, 0x2c, 0xe9, 0x3c, 0xea, 0x1d, 0x37, 0x11, 0x45, 0x8c, 0x6c, 0xbc, 0xc2, 0x6, 0x69, 0x2, 0x75, 0x29, 0x40, 0x9f, 0xc5, 0xbb, 0x36}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1294,7 +1274,7 @@ func _1681780680_add_clock_to_social_links_settingsUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1681780680_add_clock_to_social_links_settings.up.sql", size: 137, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1681780680_add_clock_to_social_links_settings.up.sql", size: 137, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x63, 0x11, 0xf5, 0x41, 0xe5, 0x5a, 0xf4, 0xe3, 0xf3, 0x14, 0x87, 0x28, 0xd8, 0xf0, 0x52, 0x31, 0x8, 0xd5, 0xbb, 0xf4, 0xff, 0x55, 0x5f, 0x42, 0x90, 0xcb, 0xf7, 0x46, 0x2, 0x6, 0xbe, 0x42}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1314,7 +1294,7 @@ func _1682073779_settings_table_remove_latest_derived_path_columnUpSql() (*asset
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1682073779_settings_table_remove_latest_derived_path_column.up.sql", size: 4470, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1682073779_settings_table_remove_latest_derived_path_column.up.sql", size: 4470, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x7a, 0x36, 0x2, 0x41, 0xd, 0x5c, 0xd1, 0x92, 0x85, 0x6d, 0x84, 0xff, 0x67, 0xa7, 0x4c, 0x67, 0xa4, 0xef, 0x52, 0x69, 0x1f, 0x22, 0x25, 0x92, 0xc, 0xb3, 0x89, 0x50, 0x91, 0xc, 0x49, 0xf9}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1334,7 +1314,7 @@ func _1682146075_add_created_at_to_saved_addressesUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1682146075_add_created_at_to_saved_addresses.up.sql", size: 107, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1682146075_add_created_at_to_saved_addresses.up.sql", size: 107, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x88, 0xfe, 0x35, 0x9c, 0x6b, 0xdf, 0x67, 0x18, 0x16, 0xe4, 0xc9, 0xd4, 0x77, 0x7c, 0x4, 0xe2, 0x6c, 0x41, 0xd9, 0x53, 0x97, 0xfe, 0x5, 0xa3, 0x23, 0xce, 0x82, 0xad, 0x92, 0x5e, 0xd7, 0x7d}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1354,7 +1334,7 @@ func _1682393575_sync_ens_nameUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1682393575_sync_ens_name.up.sql", size: 713, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1682393575_sync_ens_name.up.sql", size: 713, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xfb, 0xea, 0xcb, 0x4d, 0x71, 0x5a, 0x49, 0x19, 0x8b, 0xef, 0x66, 0x27, 0x33, 0x89, 0xb0, 0xe, 0x37, 0x1b, 0x41, 0x8, 0x12, 0xcc, 0x56, 0xd8, 0x1b, 0xf, 0xf8, 0x50, 0x4b, 0x93, 0xf1, 0x29}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1374,7 +1354,7 @@ func _1683457503_add_blocks_ranges_sequential_tableUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1683457503_add_blocks_ranges_sequential_table.up.sql", size: 263, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1683457503_add_blocks_ranges_sequential_table.up.sql", size: 263, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xfe, 0x57, 0x2e, 0x0, 0x6a, 0x6e, 0xd7, 0xeb, 0xe6, 0x66, 0x79, 0x32, 0x22, 0x82, 0x92, 0xf4, 0xc9, 0xf1, 0x58, 0x1a, 0x45, 0x60, 0x77, 0x50, 0xe7, 0x54, 0x4a, 0xc0, 0x42, 0x3a, 0x4f, 0x35}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1394,7 +1374,7 @@ func _1683627613_accounts_and_keycards_improvementsUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1683627613_accounts_and_keycards_improvements.up.sql", size: 3640, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1683627613_accounts_and_keycards_improvements.up.sql", size: 3640, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x8e, 0xbe, 0x62, 0xf5, 0x9, 0x42, 0x8c, 0x8f, 0xa8, 0x45, 0xe7, 0x36, 0xc9, 0xde, 0xf4, 0xe2, 0xfd, 0xc4, 0x8, 0xd0, 0xa3, 0x8, 0x64, 0xe2, 0x56, 0xcc, 0xa7, 0x6d, 0xc5, 0xcc, 0x82, 0x2c}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1414,7 +1394,7 @@ func _1685041348_settings_table_add_latest_derived_path_columnUpSql() (*asset, e
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1685041348_settings_table_add_latest_derived_path_column.up.sql", size: 115, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1685041348_settings_table_add_latest_derived_path_column.up.sql", size: 115, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x21, 0xd4, 0x1b, 0xbf, 0x8, 0xf9, 0xd4, 0xb0, 0xa0, 0x6, 0x5b, 0xfb, 0x7e, 0xff, 0xfa, 0xbf, 0xcc, 0x64, 0x47, 0x81, 0x8b, 0x5e, 0x17, 0x6a, 0xa7, 0xa4, 0x35, 0x8f, 0x30, 0x4f, 0xd9, 0xd}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1434,7 +1414,7 @@ func _1685440989_update_color_id_accountsUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1685440989_update_color_id_accounts.up.sql", size: 918, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1685440989_update_color_id_accounts.up.sql", size: 918, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x10, 0x2e, 0x51, 0x1d, 0x2d, 0x16, 0x84, 0xd6, 0xe8, 0xbc, 0x20, 0x53, 0x47, 0xb8, 0x40, 0x21, 0x52, 0x5c, 0xd9, 0xbb, 0xea, 0xe2, 0xa5, 0x77, 0xc8, 0x35, 0x4c, 0xe0, 0x9d, 0x42, 0x44, 0x50}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1454,7 +1434,7 @@ func _1685463947_add_to_asset_to_multitransactionUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1685463947_add_to_asset_to_multitransaction.up.sql", size: 61, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1685463947_add_to_asset_to_multitransaction.up.sql", size: 61, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd3, 0x66, 0x15, 0x10, 0xfa, 0x66, 0x81, 0x68, 0xd9, 0xb4, 0x93, 0x9e, 0x11, 0xed, 0x1d, 0x16, 0x9d, 0x5a, 0xf8, 0xd7, 0x8, 0xea, 0x7a, 0xaf, 0xe4, 0xb3, 0x22, 0x19, 0xca, 0xff, 0x75, 0x7c}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1474,7 +1454,7 @@ func _1685880973_add_profile_links_settings_tableUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1685880973_add_profile_links_settings_table.up.sql", size: 1656, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1685880973_add_profile_links_settings_table.up.sql", size: 1656, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x13, 0x23, 0x7b, 0x1e, 0x82, 0x61, 0xcc, 0x76, 0xd6, 0xc7, 0x42, 0x6e, 0x69, 0x21, 0x1b, 0xfd, 0x7d, 0xda, 0xd7, 0xb7, 0xc7, 0xd3, 0x22, 0x63, 0xfe, 0xc6, 0xd3, 0xdf, 0xc8, 0x5f, 0x50, 0xcc}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1494,7 +1474,7 @@ func _1686041510_add_idx_transfers_blkno_loadedUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1686041510_add_idx_transfers_blkno_loaded.up.sql", size: 71, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1686041510_add_idx_transfers_blkno_loaded.up.sql", size: 71, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe2, 0x5d, 0x7e, 0x43, 0x14, 0x3c, 0x50, 0x44, 0x25, 0xd0, 0xe1, 0x75, 0xba, 0x61, 0x7b, 0x68, 0x2e, 0x43, 0x74, 0x1d, 0x10, 0x61, 0x8e, 0x45, 0xe6, 0x25, 0x78, 0x81, 0x68, 0x6, 0x24, 0x5b}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1514,7 +1494,7 @@ func _1686048341_transfers_receipt_json_blob_outUpSqlDownSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1686048341_transfers_receipt_json_blob_out.up.sql.down.sql", size: 104, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1686048341_transfers_receipt_json_blob_out.up.sql.down.sql", size: 104, mode: os.FileMode(0644), modTime: time.Unix(1686217919, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x9f, 0x6c, 0xd9, 0x76, 0x83, 0x64, 0xf0, 0xf2, 0x74, 0x97, 0xca, 0xd7, 0xaa, 0x4, 0x74, 0x7c, 0x34, 0x56, 0x88, 0x10, 0xa9, 0x4d, 0x1d, 0x8e, 0x85, 0xc3, 0x66, 0x1, 0x2b, 0x30, 0x90, 0xf4}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -1534,11 +1514,31 @@ func _1686048341_transfers_receipt_json_blob_outUpSqlUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1686048341_transfers_receipt_json_blob_out.up.sql.up.sql", size: 1500, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "1686048341_transfers_receipt_json_blob_out.up.sql.up.sql", size: 1500, mode: os.FileMode(0644), modTime: time.Unix(1686217919, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x49, 0xcd, 0xe3, 0xa6, 0x8c, 0x53, 0x51, 0xe6, 0x3c, 0x64, 0xcb, 0x3, 0x3, 0xb, 0x4d, 0x52, 0xa5, 0x1c, 0xcc, 0xe1, 0x23, 0x94, 0x14, 0x79, 0xd7, 0x56, 0x58, 0xef, 0xcc, 0x1a, 0x6, 0xa4}}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var __1686825075_cleanup_token_addressUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\x8e\xcd\x4a\xc4\x40\x10\x84\xef\x79\x8a\x62\x40\x46\x21\x59\xe2\xcf\x4d\x3c\x08\x8e\x28\x7a\x10\x5d\xf1\x28\x9d\x49\xc7\x0c\x66\x67\xa4\xbb\x85\xe4\xed\x45\x17\x41\x73\xea\x86\xaf\xf8\xaa\x9a\x06\xd7\x69\x86\x8d\x0c\x2b\xef\x9c\x5f\xa9\xef\x85\x55\x11\xcb\xf4\xb9\xcb\x48\x79\xcf\x84\xb2\x0e\x2c\x0a\xa3\x6e\x62\xd8\x48\x86\x91\x14\x1d\x73\xae\x9a\x06\x29\xc7\x22\xc2\xd1\xa6\x05\xca\x06\x2b\x20\xa8\x49\xca\x6f\x28\xc3\x8f\x63\x28\xb2\x83\x6b\xe7\xe3\x13\xea\x36\x9b\xd3\xb3\xd8\x3b\xa4\xac\xc6\xd4\x7f\x47\x08\xdd\x62\x0c\x12\xa1\xa5\x7a\x7e\xb8\xba\xdc\x86\x3f\xb5\x4f\x61\xbb\x1a\x78\x01\xe1\x8f\x89\x22\x1f\xfe\xde\x7f\xbc\x86\x6f\x67\x5f\xc3\xfb\xa3\x1a\xde\xed\x3f\xbc\xdc\x84\xc7\xb0\x12\xdd\xdf\xde\x05\x78\xd7\xce\x07\xce\x9f\x57\x5f\x01\x00\x00\xff\xff\xf9\xa8\x19\x33\x11\x01\x00\x00")
|
||||
|
||||
func _1686825075_cleanup_token_addressUpSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
__1686825075_cleanup_token_addressUpSql,
|
||||
"1686825075_cleanup_token_address.up.sql",
|
||||
)
|
||||
}
|
||||
|
||||
func _1686825075_cleanup_token_addressUpSql() (*asset, error) {
|
||||
bytes, err := _1686825075_cleanup_token_addressUpSqlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1686825075_cleanup_token_address.up.sql", size: 273, mode: os.FileMode(0644), modTime: time.Unix(1686994151, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x14, 0x72, 0x10, 0xec, 0x97, 0xc9, 0x3a, 0xdb, 0x39, 0x33, 0xc9, 0x6, 0x92, 0xbe, 0xe4, 0xc2, 0x5c, 0xb6, 0xaa, 0xe5, 0x25, 0x21, 0x4d, 0x74, 0x18, 0x94, 0xc, 0x33, 0x2f, 0xa4, 0x9, 0x99}}
|
||||
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) {
|
||||
|
@ -1554,7 +1554,7 @@ func docGo() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1686648985, 0)}
|
||||
info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1686145633, 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
|
||||
}
|
||||
|
@ -1650,8 +1650,6 @@ func AssetNames() []string {
|
|||
|
||||
// _bindata is a table, holding each asset generator, mapped to its name.
|
||||
var _bindata = map[string]func() (*asset, error){
|
||||
".DS_Store": Ds_store,
|
||||
|
||||
"1640111208_dummy.up.sql": _1640111208_dummyUpSql,
|
||||
|
||||
"1642666031_add_removed_clock_to_bookmarks.up.sql": _1642666031_add_removed_clock_to_bookmarksUpSql,
|
||||
|
@ -1790,6 +1788,8 @@ var _bindata = map[string]func() (*asset, error){
|
|||
|
||||
"1686048341_transfers_receipt_json_blob_out.up.sql.up.sql": _1686048341_transfers_receipt_json_blob_outUpSqlUpSql,
|
||||
|
||||
"1686825075_cleanup_token_address.up.sql": _1686825075_cleanup_token_addressUpSql,
|
||||
|
||||
"doc.go": docGo,
|
||||
}
|
||||
|
||||
|
@ -1834,8 +1834,7 @@ type bintree struct {
|
|||
}
|
||||
|
||||
var _bintree = &bintree{nil, map[string]*bintree{
|
||||
".DS_Store": &bintree{Ds_store, map[string]*bintree{}},
|
||||
"1640111208_dummy.up.sql": &bintree{_1640111208_dummyUpSql, map[string]*bintree{}},
|
||||
"1640111208_dummy.up.sql": &bintree{_1640111208_dummyUpSql, map[string]*bintree{}},
|
||||
"1642666031_add_removed_clock_to_bookmarks.up.sql": &bintree{_1642666031_add_removed_clock_to_bookmarksUpSql, map[string]*bintree{}},
|
||||
"1643644541_gif_api_key_setting.up.sql": &bintree{_1643644541_gif_api_key_settingUpSql, map[string]*bintree{}},
|
||||
"1644188994_recent_stickers.up.sql": &bintree{_1644188994_recent_stickersUpSql, map[string]*bintree{}},
|
||||
|
@ -1904,6 +1903,7 @@ var _bintree = &bintree{nil, map[string]*bintree{
|
|||
"1686041510_add_idx_transfers_blkno_loaded.up.sql": &bintree{_1686041510_add_idx_transfers_blkno_loadedUpSql, map[string]*bintree{}},
|
||||
"1686048341_transfers_receipt_json_blob_out.up.sql.down.sql": &bintree{_1686048341_transfers_receipt_json_blob_outUpSqlDownSql, map[string]*bintree{}},
|
||||
"1686048341_transfers_receipt_json_blob_out.up.sql.up.sql": &bintree{_1686048341_transfers_receipt_json_blob_outUpSqlUpSql, map[string]*bintree{}},
|
||||
"1686825075_cleanup_token_address.up.sql": &bintree{_1686825075_cleanup_token_addressUpSql, map[string]*bintree{}},
|
||||
"doc.go": &bintree{docGo, map[string]*bintree{}},
|
||||
}}
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
-- Fix the token_address column in the transfers table that has been
|
||||
-- incorrectly set to a string of the form "0x12ab..34cd" instead of a byte array
|
||||
UPDATE transfers SET token_address = replace(replace(token_address, '0x', ''), '"', '') WHERE token_address LIKE '"0x%"';
|
|
@ -40,7 +40,7 @@ Filter requirements
|
|||
- [x] `chainID`: aggregate data for activity entries `Bridge`, `Buy`, `Swap`
|
||||
- [x] `tokenCode` for activity entries `Send`, `Receive`
|
||||
- For `Bridge` its already there and `Buy`, `Swap` is coming soon
|
||||
- [ ] `collectibles`: require adding collectible attributes to activity data (probably `token_address` and `tokenId`)
|
||||
- [ ] `collectibles`: require adding collectible attributes to activity data (`token_address` and `tokenId`)
|
||||
|
||||
UX requirements
|
||||
|
||||
|
|
|
@ -37,9 +37,10 @@ type Entry struct {
|
|||
timestamp int64
|
||||
activityType Type
|
||||
activityStatus Status
|
||||
tokenType TokenType
|
||||
amountOut *hexutil.Big // Used for activityType SendAT, SwapAT, BridgeAT
|
||||
amountIn *hexutil.Big // Used for activityType ReceiveAT, BuyAT, SwapAT, BridgeAT
|
||||
tokenOut *Token // Used for activityType SendAT, SwapAT, BridgeAT
|
||||
tokenIn *Token // Used for activityType ReceiveAT, BuyAT, SwapAT, BridgeAT
|
||||
}
|
||||
|
||||
type jsonSerializationTemplate struct {
|
||||
|
@ -49,9 +50,10 @@ type jsonSerializationTemplate struct {
|
|||
Timestamp int64 `json:"timestamp"`
|
||||
ActivityType Type `json:"activityType"`
|
||||
ActivityStatus Status `json:"activityStatus"`
|
||||
TokenType TokenType `json:"tokenType"`
|
||||
AmountOut *hexutil.Big `json:"amountOut"`
|
||||
AmountIn *hexutil.Big `json:"amountIn"`
|
||||
TokenOut *Token `json:"tokenOut,omitempty"`
|
||||
TokenIn *Token `json:"tokenIn,omitempty"`
|
||||
}
|
||||
|
||||
func (e *Entry) MarshalJSON() ([]byte, error) {
|
||||
|
@ -62,9 +64,10 @@ func (e *Entry) MarshalJSON() ([]byte, error) {
|
|||
Timestamp: e.timestamp,
|
||||
ActivityType: e.activityType,
|
||||
ActivityStatus: e.activityStatus,
|
||||
TokenType: e.tokenType,
|
||||
AmountOut: e.amountOut,
|
||||
AmountIn: e.amountIn,
|
||||
TokenOut: e.tokenOut,
|
||||
TokenIn: e.tokenIn,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -85,15 +88,15 @@ func (e *Entry) UnmarshalJSON(data []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func newActivityEntryWithPendingTransaction(transaction *transfer.TransactionIdentity, timestamp int64, activityType Type, activityStatus Status, amountIn *hexutil.Big, amountOut *hexutil.Big) Entry {
|
||||
return newActivityEntryWithTransaction(true, transaction, timestamp, activityType, activityStatus, amountIn, amountOut)
|
||||
func newActivityEntryWithPendingTransaction(transaction *transfer.TransactionIdentity, timestamp int64, activityType Type, activityStatus Status, amountIn *hexutil.Big, amountOut *hexutil.Big, tokenOut *Token, tokenIn *Token) Entry {
|
||||
return newActivityEntryWithTransaction(true, transaction, timestamp, activityType, activityStatus, amountIn, amountOut, tokenOut, tokenIn)
|
||||
}
|
||||
|
||||
func newActivityEntryWithSimpleTransaction(transaction *transfer.TransactionIdentity, timestamp int64, activityType Type, activityStatus Status, amountIn *hexutil.Big, amountOut *hexutil.Big) Entry {
|
||||
return newActivityEntryWithTransaction(false, transaction, timestamp, activityType, activityStatus, amountIn, amountOut)
|
||||
func newActivityEntryWithSimpleTransaction(transaction *transfer.TransactionIdentity, timestamp int64, activityType Type, activityStatus Status, amountIn *hexutil.Big, amountOut *hexutil.Big, tokenOut *Token, tokenIn *Token) Entry {
|
||||
return newActivityEntryWithTransaction(false, transaction, timestamp, activityType, activityStatus, amountIn, amountOut, tokenOut, tokenIn)
|
||||
}
|
||||
|
||||
func newActivityEntryWithTransaction(pending bool, transaction *transfer.TransactionIdentity, timestamp int64, activityType Type, activityStatus Status, amountIn *hexutil.Big, amountOut *hexutil.Big) Entry {
|
||||
func newActivityEntryWithTransaction(pending bool, transaction *transfer.TransactionIdentity, timestamp int64, activityType Type, activityStatus Status, amountIn *hexutil.Big, amountOut *hexutil.Big, tokenOut *Token, tokenIn *Token) Entry {
|
||||
payloadType := SimpleTransactionPT
|
||||
if pending {
|
||||
payloadType = PendingTransactionPT
|
||||
|
@ -106,22 +109,24 @@ func newActivityEntryWithTransaction(pending bool, transaction *transfer.Transac
|
|||
timestamp: timestamp,
|
||||
activityType: activityType,
|
||||
activityStatus: activityStatus,
|
||||
tokenType: AssetTT,
|
||||
amountIn: amountIn,
|
||||
amountOut: amountOut,
|
||||
tokenOut: tokenOut,
|
||||
tokenIn: tokenIn,
|
||||
}
|
||||
}
|
||||
|
||||
func NewActivityEntryWithMultiTransaction(id transfer.MultiTransactionIDType, timestamp int64, activityType Type, activityStatus Status, amountIn *hexutil.Big, amountOut *hexutil.Big) Entry {
|
||||
func NewActivityEntryWithMultiTransaction(id transfer.MultiTransactionIDType, timestamp int64, activityType Type, activityStatus Status, amountIn *hexutil.Big, amountOut *hexutil.Big, tokenOut *Token, tokenIn *Token) Entry {
|
||||
return Entry{
|
||||
payloadType: MultiTransactionPT,
|
||||
id: id,
|
||||
timestamp: timestamp,
|
||||
activityType: activityType,
|
||||
activityStatus: activityStatus,
|
||||
tokenType: AssetTT,
|
||||
amountIn: amountIn,
|
||||
amountOut: amountOut,
|
||||
tokenOut: tokenOut,
|
||||
tokenIn: tokenIn,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,6 +154,15 @@ func sliceContains[T constraints.Ordered](slice []T, item T) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func sliceChecksCondition[T any](slice []T, condition func(*T) bool) bool {
|
||||
for i := range slice {
|
||||
if condition(&slice[i]) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func joinItems[T interface{}](items []T, itemConversion func(T) string) string {
|
||||
if len(items) == 0 {
|
||||
return ""
|
||||
|
@ -203,6 +217,7 @@ const (
|
|||
// TODO: Multi-transaction network information is missing in filtering
|
||||
// TODO: extract token code for non transfer type eth
|
||||
// TODO optimization: consider implementing nullable []byte instead of using strings for addresses
|
||||
// or insert binary (X'...' syntax) directly into the query
|
||||
//
|
||||
// Query includes duplicates, will return multiple rows for the same transaction if both to and from addresses
|
||||
// are in the address list.
|
||||
|
@ -217,236 +232,461 @@ const (
|
|||
//
|
||||
// Only status FailedAS, PendingAS and CompleteAS are returned. FinalizedAS requires correlation with blockchain
|
||||
// current state. As an optimization we can approximate it by using timestamp information or last known block number
|
||||
//
|
||||
// Token filtering has two parts
|
||||
// 1. Filtering by symbol (multi_transactions and pending_transactions tables) where the chain ID is ignored, basically the
|
||||
// filter_networks will account for that
|
||||
// 2. Filtering by token identity (chain and address for transfers table) where the symbol is ignored and all the
|
||||
// token identities must be provided
|
||||
queryFormatString = `
|
||||
WITH filter_conditions AS (
|
||||
SELECT
|
||||
? AS startFilterDisabled,
|
||||
? AS startTimestamp,
|
||||
? AS endFilterDisabled,
|
||||
? AS endTimestamp,
|
||||
WITH filter_conditions AS (
|
||||
SELECT
|
||||
? AS startFilterDisabled,
|
||||
? AS startTimestamp,
|
||||
? AS endFilterDisabled,
|
||||
? AS endTimestamp,
|
||||
|
||||
? AS filterActivityTypeAll,
|
||||
? AS filterActivityTypeSend,
|
||||
? AS filterActivityTypeReceive,
|
||||
? AS filterActivityTypeAll,
|
||||
? AS filterActivityTypeSend,
|
||||
? AS filterActivityTypeReceive,
|
||||
|
||||
? AS fromTrType,
|
||||
? AS toTrType,
|
||||
? AS fromTrType,
|
||||
? AS toTrType,
|
||||
|
||||
? AS filterAllAddresses,
|
||||
? AS filterAllToAddresses,
|
||||
? AS filterAllAddresses,
|
||||
? AS filterAllToAddresses,
|
||||
|
||||
? AS filterAllActivityStatus,
|
||||
? AS filterStatusCompleted,
|
||||
? AS filterStatusFailed,
|
||||
? AS filterStatusFinalized,
|
||||
? AS filterStatusPending,
|
||||
? AS filterAllActivityStatus,
|
||||
? AS filterStatusCompleted,
|
||||
? AS filterStatusFailed,
|
||||
? AS filterStatusFinalized,
|
||||
? AS filterStatusPending,
|
||||
|
||||
? AS statusFailed,
|
||||
? AS statusSuccess,
|
||||
? AS statusPending,
|
||||
? AS statusFailed,
|
||||
? AS statusSuccess,
|
||||
? AS statusPending,
|
||||
|
||||
? AS includeAllTokenTypeAssets,
|
||||
? AS includeAllTokenTypeAssets,
|
||||
|
||||
? AS includeAllNetworks
|
||||
),
|
||||
filter_addresses(address) AS (
|
||||
SELECT HEX(address) FROM keypairs_accounts WHERE (SELECT filterAllAddresses FROM filter_conditions) != 0
|
||||
UNION ALL
|
||||
SELECT * FROM (VALUES %s) WHERE (SELECT filterAllAddresses FROM filter_conditions) = 0
|
||||
),
|
||||
filter_to_addresses(address) AS (
|
||||
VALUES %s
|
||||
),
|
||||
filter_assets(token_code) AS (
|
||||
VALUES %s
|
||||
),
|
||||
filter_networks(network_id) AS (
|
||||
VALUES %s
|
||||
),
|
||||
tr_status AS (
|
||||
SELECT
|
||||
multi_transaction_id,
|
||||
MIN(status) AS min_status,
|
||||
COUNT(*) AS count
|
||||
FROM
|
||||
transfers
|
||||
WHERE transfers.multi_transaction_id != 0
|
||||
GROUP BY
|
||||
transfers.multi_transaction_id
|
||||
),
|
||||
pending_status AS (
|
||||
SELECT
|
||||
multi_transaction_id,
|
||||
COUNT(*) AS count
|
||||
FROM
|
||||
pending_transactions
|
||||
WHERE pending_transactions.multi_transaction_id != 0
|
||||
GROUP BY pending_transactions.multi_transaction_id
|
||||
)
|
||||
SELECT
|
||||
transfers.hash AS transfer_hash,
|
||||
NULL AS pending_hash,
|
||||
transfers.network_id AS network_id,
|
||||
0 AS multi_tx_id,
|
||||
transfers.timestamp AS timestamp,
|
||||
NULL AS mt_type,
|
||||
? AS includeAllNetworks
|
||||
),
|
||||
filter_addresses(address) AS (
|
||||
SELECT HEX(address) FROM keypairs_accounts WHERE (SELECT filterAllAddresses FROM filter_conditions) != 0
|
||||
UNION ALL
|
||||
SELECT * FROM (VALUES %s) WHERE (SELECT filterAllAddresses FROM filter_conditions) = 0
|
||||
),
|
||||
filter_to_addresses(address) AS (
|
||||
VALUES %s
|
||||
),
|
||||
assets_token_codes(token_code) AS (
|
||||
VALUES %s
|
||||
),
|
||||
assets_erc20(chain_id, token_address) AS (
|
||||
VALUES %s
|
||||
),
|
||||
filter_networks(network_id) AS (
|
||||
VALUES %s
|
||||
),
|
||||
tr_status AS (
|
||||
SELECT
|
||||
multi_transaction_id,
|
||||
MIN(status) AS min_status,
|
||||
COUNT(*) AS count
|
||||
FROM
|
||||
transfers
|
||||
WHERE transfers.multi_transaction_id != 0
|
||||
GROUP BY
|
||||
transfers.multi_transaction_id
|
||||
),
|
||||
pending_status AS (
|
||||
SELECT
|
||||
multi_transaction_id,
|
||||
COUNT(*) AS count
|
||||
FROM
|
||||
pending_transactions
|
||||
WHERE pending_transactions.multi_transaction_id != 0
|
||||
GROUP BY pending_transactions.multi_transaction_id
|
||||
)
|
||||
SELECT
|
||||
transfers.hash AS transfer_hash,
|
||||
NULL AS pending_hash,
|
||||
transfers.network_id AS network_id,
|
||||
0 AS multi_tx_id,
|
||||
transfers.timestamp AS timestamp,
|
||||
NULL AS mt_type,
|
||||
|
||||
CASE
|
||||
WHEN from_join.address IS NOT NULL AND to_join.address IS NULL THEN fromTrType
|
||||
WHEN to_join.address IS NOT NULL AND from_join.address IS NULL THEN toTrType
|
||||
WHEN from_join.address IS NOT NULL AND to_join.address IS NOT NULL THEN
|
||||
CASE
|
||||
WHEN from_join.address < to_join.address THEN 1
|
||||
ELSE 2
|
||||
END
|
||||
ELSE NULL
|
||||
END as tr_type,
|
||||
CASE
|
||||
WHEN from_join.address IS NOT NULL AND to_join.address IS NULL THEN fromTrType
|
||||
WHEN to_join.address IS NOT NULL AND from_join.address IS NULL THEN toTrType
|
||||
WHEN from_join.address IS NOT NULL AND to_join.address IS NOT NULL THEN
|
||||
CASE
|
||||
WHEN from_join.address < to_join.address THEN 1
|
||||
ELSE 2
|
||||
END
|
||||
ELSE NULL
|
||||
END as tr_type,
|
||||
|
||||
transfers.sender AS from_address,
|
||||
transfers.address AS to_address,
|
||||
transfers.amount_padded128hex AS tr_amount,
|
||||
NULL AS mt_from_amount,
|
||||
NULL AS mt_to_amount,
|
||||
transfers.sender AS from_address,
|
||||
transfers.address AS to_address,
|
||||
transfers.amount_padded128hex AS tr_amount,
|
||||
NULL AS mt_from_amount,
|
||||
NULL AS mt_to_amount,
|
||||
|
||||
CASE
|
||||
WHEN transfers.status IS 1 THEN statusSuccess
|
||||
ELSE statusFailed
|
||||
END AS agg_status,
|
||||
CASE
|
||||
WHEN transfers.status IS 1 THEN statusSuccess
|
||||
ELSE statusFailed
|
||||
END AS agg_status,
|
||||
|
||||
1 AS agg_count
|
||||
FROM transfers, filter_conditions
|
||||
LEFT JOIN
|
||||
filter_addresses from_join ON HEX(transfers.sender) = from_join.address
|
||||
LEFT JOIN
|
||||
filter_addresses to_join ON HEX(transfers.address) = to_join.address
|
||||
WHERE transfers.multi_transaction_id = 0
|
||||
AND ((startFilterDisabled OR timestamp >= startTimestamp)
|
||||
AND (endFilterDisabled OR timestamp <= endTimestamp)
|
||||
)
|
||||
AND (filterActivityTypeAll
|
||||
OR (filterActivityTypeSend
|
||||
AND (filterAllAddresses
|
||||
OR (HEX(transfers.sender) IN filter_addresses)
|
||||
)
|
||||
)
|
||||
OR (filterActivityTypeReceive
|
||||
AND (filterAllAddresses OR (HEX(transfers.address) IN filter_addresses))
|
||||
)
|
||||
)
|
||||
AND (filterAllAddresses
|
||||
OR (HEX(transfers.sender) IN filter_addresses)
|
||||
OR (HEX(transfers.address) IN filter_addresses)
|
||||
)
|
||||
AND (filterAllToAddresses
|
||||
OR (HEX(transfers.address) IN filter_to_addresses)
|
||||
)
|
||||
AND (includeAllTokenTypeAssets OR (transfers.type = "eth" AND ("ETH" IN filter_assets)))
|
||||
AND (includeAllNetworks OR (transfers.network_id IN filter_networks))
|
||||
AND (filterAllActivityStatus OR ((filterStatusCompleted OR filterStatusFinalized) AND transfers.status = 1)
|
||||
OR (filterStatusFailed AND transfers.status = 0)
|
||||
)
|
||||
1 AS agg_count,
|
||||
|
||||
UNION ALL
|
||||
transfers.token_address AS token_address,
|
||||
NULL AS token_code,
|
||||
NULL AS from_token_code,
|
||||
NULL AS to_token_code
|
||||
FROM transfers, filter_conditions
|
||||
LEFT JOIN
|
||||
filter_addresses from_join ON HEX(transfers.sender) = from_join.address
|
||||
LEFT JOIN
|
||||
filter_addresses to_join ON HEX(transfers.address) = to_join.address
|
||||
WHERE transfers.multi_transaction_id = 0
|
||||
AND ((startFilterDisabled OR timestamp >= startTimestamp)
|
||||
AND (endFilterDisabled OR timestamp <= endTimestamp)
|
||||
)
|
||||
AND (filterActivityTypeAll
|
||||
OR (filterActivityTypeSend
|
||||
AND (filterAllAddresses
|
||||
OR (HEX(transfers.sender) IN filter_addresses)
|
||||
)
|
||||
)
|
||||
OR (filterActivityTypeReceive
|
||||
AND (filterAllAddresses OR (HEX(transfers.address) IN filter_addresses))
|
||||
)
|
||||
)
|
||||
AND (filterAllAddresses
|
||||
OR (HEX(transfers.sender) IN filter_addresses)
|
||||
OR (HEX(transfers.address) IN filter_addresses)
|
||||
)
|
||||
AND (filterAllToAddresses
|
||||
OR (HEX(transfers.address) IN filter_to_addresses)
|
||||
)
|
||||
AND (includeAllTokenTypeAssets OR (transfers.type = "eth" AND ("ETH" IN assets_token_codes))
|
||||
OR (transfers.type = "erc20" AND ((transfers.network_id, transfers.token_address) IN assets_erc20)))
|
||||
AND (includeAllNetworks OR (transfers.network_id IN filter_networks))
|
||||
AND (filterAllActivityStatus OR ((filterStatusCompleted OR filterStatusFinalized) AND transfers.status = 1)
|
||||
OR (filterStatusFailed AND transfers.status = 0)
|
||||
)
|
||||
|
||||
SELECT
|
||||
NULL AS transfer_hash,
|
||||
pending_transactions.hash AS pending_hash,
|
||||
pending_transactions.network_id AS network_id,
|
||||
0 AS multi_tx_id,
|
||||
pending_transactions.timestamp AS timestamp,
|
||||
NULL AS mt_type,
|
||||
UNION ALL
|
||||
|
||||
CASE
|
||||
WHEN from_join.address IS NOT NULL AND to_join.address IS NULL THEN 1
|
||||
WHEN to_join.address IS NOT NULL AND from_join.address IS NULL THEN 2
|
||||
WHEN from_join.address IS NOT NULL AND to_join.address IS NOT NULL THEN
|
||||
CASE
|
||||
WHEN from_join.address < to_join.address THEN 1
|
||||
ELSE 2
|
||||
END
|
||||
ELSE NULL
|
||||
END as tr_type,
|
||||
SELECT
|
||||
NULL AS transfer_hash,
|
||||
pending_transactions.hash AS pending_hash,
|
||||
pending_transactions.network_id AS network_id,
|
||||
0 AS multi_tx_id,
|
||||
pending_transactions.timestamp AS timestamp,
|
||||
NULL AS mt_type,
|
||||
|
||||
pending_transactions.from_address AS from_address,
|
||||
pending_transactions.to_address AS to_address,
|
||||
pending_transactions.value AS tr_amount,
|
||||
NULL AS mt_from_amount,
|
||||
NULL AS mt_to_amount,
|
||||
CASE
|
||||
WHEN from_join.address IS NOT NULL AND to_join.address IS NULL THEN 1
|
||||
WHEN to_join.address IS NOT NULL AND from_join.address IS NULL THEN 2
|
||||
WHEN from_join.address IS NOT NULL AND to_join.address IS NOT NULL THEN
|
||||
CASE
|
||||
WHEN from_join.address < to_join.address THEN 1
|
||||
ELSE 2
|
||||
END
|
||||
ELSE NULL
|
||||
END as tr_type,
|
||||
|
||||
statusPending AS agg_status,
|
||||
1 AS agg_count
|
||||
FROM pending_transactions, filter_conditions
|
||||
LEFT JOIN
|
||||
filter_addresses from_join ON HEX(pending_transactions.from_address) = from_join.address
|
||||
LEFT JOIN
|
||||
filter_addresses to_join ON HEX(pending_transactions.to_address) = to_join.address
|
||||
WHERE pending_transactions.multi_transaction_id = 0
|
||||
AND (filterAllActivityStatus OR filterStatusPending)
|
||||
AND ((startFilterDisabled OR timestamp >= startTimestamp)
|
||||
AND (endFilterDisabled OR timestamp <= endTimestamp)
|
||||
)
|
||||
AND (filterActivityTypeAll OR filterActivityTypeSend)
|
||||
AND (filterAllAddresses
|
||||
OR (HEX(pending_transactions.from_address) IN filter_addresses)
|
||||
OR (HEX(pending_transactions.to_address) IN filter_addresses)
|
||||
)
|
||||
AND (filterAllToAddresses
|
||||
OR (HEX(pending_transactions.to_address) IN filter_to_addresses)
|
||||
)
|
||||
AND (includeAllTokenTypeAssets OR (UPPER(pending_transactions.symbol) IN filter_assets))
|
||||
AND (includeAllNetworks OR (pending_transactions.network_id IN filter_networks))
|
||||
pending_transactions.from_address AS from_address,
|
||||
pending_transactions.to_address AS to_address,
|
||||
pending_transactions.value AS tr_amount,
|
||||
NULL AS mt_from_amount,
|
||||
NULL AS mt_to_amount,
|
||||
|
||||
UNION ALL
|
||||
statusPending AS agg_status,
|
||||
1 AS agg_count,
|
||||
|
||||
SELECT
|
||||
NULL AS transfer_hash,
|
||||
NULL AS pending_hash,
|
||||
NULL AS network_id,
|
||||
multi_transactions.ROWID AS multi_tx_id,
|
||||
multi_transactions.timestamp AS timestamp,
|
||||
multi_transactions.type AS mt_type,
|
||||
NULL as tr_type,
|
||||
multi_transactions.from_address AS from_address,
|
||||
multi_transactions.to_address AS to_address,
|
||||
NULL AS tr_amount,
|
||||
multi_transactions.from_amount AS mt_from_amount,
|
||||
multi_transactions.to_amount AS mt_to_amount,
|
||||
NULL AS token_address,
|
||||
pending_transactions.symbol AS token_code,
|
||||
NULL AS from_token_code,
|
||||
NULL AS to_token_code
|
||||
FROM pending_transactions, filter_conditions
|
||||
LEFT JOIN
|
||||
filter_addresses from_join ON HEX(pending_transactions.from_address) = from_join.address
|
||||
LEFT JOIN
|
||||
filter_addresses to_join ON HEX(pending_transactions.to_address) = to_join.address
|
||||
WHERE pending_transactions.multi_transaction_id = 0
|
||||
AND (filterAllActivityStatus OR filterStatusPending)
|
||||
AND ((startFilterDisabled OR timestamp >= startTimestamp)
|
||||
AND (endFilterDisabled OR timestamp <= endTimestamp)
|
||||
)
|
||||
AND (filterActivityTypeAll OR filterActivityTypeSend)
|
||||
AND (filterAllAddresses
|
||||
OR (HEX(pending_transactions.from_address) IN filter_addresses)
|
||||
OR (HEX(pending_transactions.to_address) IN filter_addresses)
|
||||
)
|
||||
AND (filterAllToAddresses
|
||||
OR (HEX(pending_transactions.to_address) IN filter_to_addresses)
|
||||
)
|
||||
AND (includeAllTokenTypeAssets OR (UPPER(pending_transactions.symbol) IN assets_token_codes))
|
||||
AND (includeAllNetworks OR (pending_transactions.network_id IN filter_networks))
|
||||
|
||||
CASE
|
||||
WHEN tr_status.min_status = 1 AND pending_status.count IS NULL THEN statusSuccess
|
||||
WHEN tr_status.min_status = 0 THEN statusFailed
|
||||
ELSE statusPending
|
||||
END AS agg_status,
|
||||
UNION ALL
|
||||
|
||||
COALESCE(tr_status.count, 0) + COALESCE(pending_status.count, 0) AS agg_count
|
||||
SELECT
|
||||
NULL AS transfer_hash,
|
||||
NULL AS pending_hash,
|
||||
NULL AS network_id,
|
||||
multi_transactions.ROWID AS multi_tx_id,
|
||||
multi_transactions.timestamp AS timestamp,
|
||||
multi_transactions.type AS mt_type,
|
||||
NULL as tr_type,
|
||||
multi_transactions.from_address AS from_address,
|
||||
multi_transactions.to_address AS to_address,
|
||||
NULL AS tr_amount,
|
||||
multi_transactions.from_amount AS mt_from_amount,
|
||||
multi_transactions.to_amount AS mt_to_amount,
|
||||
|
||||
FROM multi_transactions, filter_conditions
|
||||
JOIN tr_status ON multi_transactions.ROWID = tr_status.multi_transaction_id
|
||||
LEFT JOIN pending_status ON multi_transactions.ROWID = pending_status.multi_transaction_id
|
||||
WHERE
|
||||
((startFilterDisabled OR multi_transactions.timestamp >= startTimestamp)
|
||||
AND (endFilterDisabled OR multi_transactions.timestamp <= endTimestamp)
|
||||
)
|
||||
AND (filterActivityTypeAll OR (multi_transactions.type IN (%s)))
|
||||
AND (filterAllAddresses
|
||||
OR (HEX(multi_transactions.from_address) IN filter_addresses)
|
||||
OR (HEX(multi_transactions.to_address) IN filter_addresses)
|
||||
)
|
||||
AND (filterAllToAddresses
|
||||
OR (HEX(multi_transactions.to_address) IN filter_to_addresses)
|
||||
)
|
||||
AND (includeAllTokenTypeAssets OR (UPPER(multi_transactions.from_asset) IN filter_assets)
|
||||
OR (UPPER(multi_transactions.to_asset) IN filter_assets)
|
||||
)
|
||||
AND (filterAllActivityStatus OR ((filterStatusCompleted OR filterStatusFinalized) AND agg_status = statusSuccess)
|
||||
OR (filterStatusFailed AND agg_status = statusFailed) OR (filterStatusPending AND agg_status = statusPending))
|
||||
CASE
|
||||
WHEN tr_status.min_status = 1 AND pending_status.count IS NULL THEN statusSuccess
|
||||
WHEN tr_status.min_status = 0 THEN statusFailed
|
||||
ELSE statusPending
|
||||
END AS agg_status,
|
||||
|
||||
ORDER BY timestamp DESC
|
||||
LIMIT ? OFFSET ?`
|
||||
COALESCE(tr_status.count, 0) + COALESCE(pending_status.count, 0) AS agg_count,
|
||||
|
||||
noEntriesInTmpTableSQLValues = "(NULL)"
|
||||
NULL AS token_address,
|
||||
NULL AS token_code,
|
||||
multi_transactions.from_asset AS from_token_code,
|
||||
multi_transactions.to_asset AS to_token_code
|
||||
FROM multi_transactions, filter_conditions
|
||||
JOIN tr_status ON multi_transactions.ROWID = tr_status.multi_transaction_id
|
||||
LEFT JOIN pending_status ON multi_transactions.ROWID = pending_status.multi_transaction_id
|
||||
WHERE
|
||||
((startFilterDisabled OR multi_transactions.timestamp >= startTimestamp)
|
||||
AND (endFilterDisabled OR multi_transactions.timestamp <= endTimestamp)
|
||||
)
|
||||
AND (filterActivityTypeAll OR (multi_transactions.type IN (%s)))
|
||||
AND (filterAllAddresses
|
||||
OR (HEX(multi_transactions.from_address) IN filter_addresses)
|
||||
OR (HEX(multi_transactions.to_address) IN filter_addresses)
|
||||
)
|
||||
AND (filterAllToAddresses
|
||||
OR (HEX(multi_transactions.to_address) IN filter_to_addresses)
|
||||
)
|
||||
AND (includeAllTokenTypeAssets
|
||||
OR (multi_transactions.from_asset != '' AND (UPPER(multi_transactions.from_asset) IN assets_token_codes))
|
||||
OR (multi_transactions.to_asset != '' AND (UPPER(multi_transactions.to_asset) IN assets_token_codes))
|
||||
)
|
||||
AND (filterAllActivityStatus OR ((filterStatusCompleted OR filterStatusFinalized) AND agg_status = statusSuccess)
|
||||
OR (filterStatusFailed AND agg_status = statusFailed) OR (filterStatusPending AND agg_status = statusPending))
|
||||
|
||||
ORDER BY timestamp DESC
|
||||
LIMIT ? OFFSET ?`
|
||||
|
||||
noEntriesInTmpTableSQLValues = "(NULL)"
|
||||
noEntriesInTwoColumnsTmpTableSQLValues = "(NULL, NULL)"
|
||||
)
|
||||
|
||||
type FilterDependencies struct {
|
||||
db *sql.DB
|
||||
tokenSymbol func(token Token) string
|
||||
tokenFromSymbol func(chainID *common.ChainID, symbol string) *Token
|
||||
}
|
||||
|
||||
// getActivityEntries queries the transfers, pending_transactions, and multi_transactions tables
|
||||
// based on filter parameters and arguments
|
||||
// it returns metadata for all entries ordered by timestamp column
|
||||
//
|
||||
// Adding a no-limit option was never considered or required.
|
||||
func getActivityEntries(ctx context.Context, deps FilterDependencies, addresses []eth.Address, chainIDs []common.ChainID, filter Filter, offset int, limit int) ([]Entry, error) {
|
||||
includeAllTokenTypeAssets := len(filter.Assets) == 0 && !filter.FilterOutAssets
|
||||
|
||||
// Used for symbol bearing tables multi_transactions and pending_transactions
|
||||
assetsTokenCodes := noEntriesInTmpTableSQLValues
|
||||
// Used for identity bearing tables transfers
|
||||
assetsERC20 := noEntriesInTwoColumnsTmpTableSQLValues
|
||||
if !includeAllTokenTypeAssets && !filter.FilterOutAssets {
|
||||
symbolsSet := make(map[string]struct{})
|
||||
var symbols []string
|
||||
for _, item := range filter.Assets {
|
||||
symbol := deps.tokenSymbol(item)
|
||||
if _, ok := symbolsSet[symbol]; !ok {
|
||||
symbols = append(symbols, symbol)
|
||||
symbolsSet[symbol] = struct{}{}
|
||||
}
|
||||
}
|
||||
assetsTokenCodes = joinItems(symbols, func(s string) string {
|
||||
return fmt.Sprintf("'%s'", s)
|
||||
})
|
||||
|
||||
if sliceChecksCondition(filter.Assets, func(item *Token) bool { return item.TokenType == Erc20 }) {
|
||||
assetsERC20 = joinItems(filter.Assets, func(item Token) string {
|
||||
if item.TokenType == Erc20 {
|
||||
return fmt.Sprintf("%d, '%s'", item.ChainID, item.Address.Hex())
|
||||
}
|
||||
return ""
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// construct chain IDs
|
||||
includeAllNetworks := len(chainIDs) == 0
|
||||
networks := noEntriesInTmpTableSQLValues
|
||||
if !includeAllNetworks {
|
||||
networks = joinItems(chainIDs, nil)
|
||||
}
|
||||
|
||||
startFilterDisabled := !(filter.Period.StartTimestamp > 0)
|
||||
endFilterDisabled := !(filter.Period.EndTimestamp > 0)
|
||||
filterActivityTypeAll := len(filter.Types) == 0
|
||||
filterAllAddresses := len(addresses) == 0
|
||||
filterAllToAddresses := len(filter.CounterpartyAddresses) == 0
|
||||
includeAllStatuses := len(filter.Statuses) == 0
|
||||
|
||||
filterStatusPending := false
|
||||
filterStatusCompleted := false
|
||||
filterStatusFailed := false
|
||||
filterStatusFinalized := false
|
||||
if !includeAllStatuses {
|
||||
filterStatusPending = sliceContains(filter.Statuses, PendingAS)
|
||||
filterStatusCompleted = sliceContains(filter.Statuses, CompleteAS)
|
||||
filterStatusFailed = sliceContains(filter.Statuses, FailedAS)
|
||||
filterStatusFinalized = sliceContains(filter.Statuses, FinalizedAS)
|
||||
}
|
||||
|
||||
involvedAddresses := noEntriesInTmpTableSQLValues
|
||||
if !filterAllAddresses {
|
||||
involvedAddresses = joinAddresses(addresses)
|
||||
}
|
||||
toAddresses := noEntriesInTmpTableSQLValues
|
||||
if !filterAllToAddresses {
|
||||
toAddresses = joinAddresses(filter.CounterpartyAddresses)
|
||||
}
|
||||
|
||||
mtTypes := activityTypesToMultiTransactionTypes(filter.Types)
|
||||
joinedMTTypes := joinItems(mtTypes, func(t transfer.MultiTransactionType) string {
|
||||
return strconv.Itoa(int(t))
|
||||
})
|
||||
|
||||
queryString := fmt.Sprintf(queryFormatString, involvedAddresses, toAddresses, assetsTokenCodes, assetsERC20, networks,
|
||||
joinedMTTypes)
|
||||
|
||||
rows, err := deps.db.QueryContext(ctx, queryString,
|
||||
startFilterDisabled, filter.Period.StartTimestamp, endFilterDisabled, filter.Period.EndTimestamp,
|
||||
filterActivityTypeAll, sliceContains(filter.Types, SendAT), sliceContains(filter.Types, ReceiveAT),
|
||||
fromTrType, toTrType,
|
||||
filterAllAddresses, filterAllToAddresses,
|
||||
includeAllStatuses, filterStatusCompleted, filterStatusFailed, filterStatusFinalized, filterStatusPending,
|
||||
FailedAS, CompleteAS, PendingAS,
|
||||
includeAllTokenTypeAssets,
|
||||
includeAllNetworks,
|
||||
limit, offset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var entries []Entry
|
||||
for rows.Next() {
|
||||
var transferHash, pendingHash []byte
|
||||
var chainID, multiTxID, aggregatedCount sql.NullInt64
|
||||
var timestamp int64
|
||||
var dbMtType, dbTrType sql.NullByte
|
||||
var toAddress, fromAddress eth.Address
|
||||
var aggregatedStatus int
|
||||
var dbTrAmount sql.NullString
|
||||
var dbMtFromAmount, dbMtToAmount sql.NullString
|
||||
var tokenAddress, tokenCode, fromTokenCode, toTokenCode sql.NullString
|
||||
err := rows.Scan(&transferHash, &pendingHash, &chainID, &multiTxID, ×tamp, &dbMtType, &dbTrType, &fromAddress,
|
||||
&toAddress, &dbTrAmount, &dbMtFromAmount, &dbMtToAmount, &aggregatedStatus, &aggregatedCount,
|
||||
&tokenAddress, &tokenCode, &fromTokenCode, &toTokenCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
getActivityType := func(trType sql.NullByte) (activityType Type, filteredAddress eth.Address) {
|
||||
if trType.Valid {
|
||||
if trType.Byte == fromTrType {
|
||||
return SendAT, fromAddress
|
||||
} else if trType.Byte == toTrType {
|
||||
return ReceiveAT, toAddress
|
||||
}
|
||||
}
|
||||
log.Warn(fmt.Sprintf("unexpected activity type. Missing [%s, %s] in the addresses table?", fromAddress, toAddress))
|
||||
return ReceiveAT, toAddress
|
||||
}
|
||||
|
||||
// Can be mapped directly because the values are injected into the query
|
||||
activityStatus := Status(aggregatedStatus)
|
||||
var tokenOut, tokenIn *Token
|
||||
|
||||
var entry Entry
|
||||
if transferHash != nil && chainID.Valid {
|
||||
// Extract activity type: SendAT/ReceiveAT
|
||||
activityType, filteredAddress := getActivityType(dbTrType)
|
||||
|
||||
inAmount, outAmount := getTrInAndOutAmounts(activityType, dbTrAmount)
|
||||
|
||||
// Extract tokens
|
||||
var involvedToken *Token
|
||||
if tokenAddress.Valid && eth.HexToAddress(tokenAddress.String) != eth.HexToAddress("0x") {
|
||||
involvedToken = &Token{TokenType: Erc20, ChainID: common.ChainID(chainID.Int64), Address: eth.HexToAddress(tokenAddress.String)}
|
||||
} else {
|
||||
involvedToken = &Token{TokenType: Native, ChainID: common.ChainID(chainID.Int64)}
|
||||
}
|
||||
if activityType == SendAT {
|
||||
tokenOut = involvedToken
|
||||
} else {
|
||||
tokenIn = involvedToken
|
||||
}
|
||||
|
||||
entry = newActivityEntryWithSimpleTransaction(
|
||||
&transfer.TransactionIdentity{ChainID: common.ChainID(chainID.Int64), Hash: eth.BytesToHash(transferHash), Address: filteredAddress},
|
||||
timestamp, activityType, activityStatus, inAmount, outAmount, tokenOut, tokenIn)
|
||||
} else if pendingHash != nil && chainID.Valid {
|
||||
// Extract activity type: PendingAT
|
||||
activityType, _ := getActivityType(dbTrType)
|
||||
|
||||
inAmount, outAmount := getTrInAndOutAmounts(activityType, dbTrAmount)
|
||||
|
||||
// Extract tokens
|
||||
if tokenCode.Valid {
|
||||
cID := common.ChainID(chainID.Int64)
|
||||
tokenOut = deps.tokenFromSymbol(&cID, tokenCode.String)
|
||||
}
|
||||
|
||||
entry = newActivityEntryWithPendingTransaction(&transfer.TransactionIdentity{ChainID: common.ChainID(chainID.Int64), Hash: eth.BytesToHash(pendingHash)},
|
||||
timestamp, activityType, activityStatus, inAmount, outAmount, tokenOut, tokenIn)
|
||||
} else if multiTxID.Valid {
|
||||
mtInAmount, mtOutAmount := getMtInAndOutAmounts(dbMtFromAmount, dbMtToAmount)
|
||||
|
||||
// Extract activity type: SendAT/SwapAT/BridgeAT
|
||||
activityType := multiTransactionTypeToActivityType(transfer.MultiTransactionType(dbMtType.Byte))
|
||||
|
||||
// Extract tokens
|
||||
if fromTokenCode.Valid {
|
||||
tokenOut = deps.tokenFromSymbol(nil, fromTokenCode.String)
|
||||
}
|
||||
if toTokenCode.Valid {
|
||||
tokenIn = deps.tokenFromSymbol(nil, toTokenCode.String)
|
||||
}
|
||||
|
||||
entry = NewActivityEntryWithMultiTransaction(transfer.MultiTransactionIDType(multiTxID.Int64),
|
||||
timestamp, activityType, activityStatus, mtInAmount, mtOutAmount, tokenOut, tokenIn)
|
||||
} else {
|
||||
return nil, errors.New("invalid row data")
|
||||
}
|
||||
entries = append(entries, entry)
|
||||
}
|
||||
|
||||
if err = rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
func getTrInAndOutAmounts(activityType Type, trAmount sql.NullString) (inAmount *hexutil.Big, outAmount *hexutil.Big) {
|
||||
if trAmount.Valid {
|
||||
amount, ok := new(big.Int).SetString(trAmount.String, 16)
|
||||
|
@ -495,140 +735,3 @@ func getMtInAndOutAmounts(dbFromAmount sql.NullString, dbToAmount sql.NullString
|
|||
outAmount = (*hexutil.Big)(big.NewInt(0))
|
||||
return
|
||||
}
|
||||
|
||||
// getActivityEntries queries the transfers, pending_transactions, and multi_transactions tables
|
||||
// based on filter parameters and arguments
|
||||
// it returns metadata for all entries ordered by timestamp column
|
||||
//
|
||||
// Adding a no-limit option was never considered or required.
|
||||
func getActivityEntries(ctx context.Context, db *sql.DB, addresses []eth.Address, chainIDs []common.ChainID, filter Filter, offset int, limit int) ([]Entry, error) {
|
||||
// TODO: filter collectibles after they are added to multi_transactions table
|
||||
if len(filter.Tokens.EnabledTypes) > 0 && !sliceContains(filter.Tokens.EnabledTypes, AssetTT) {
|
||||
// For now we deal only with assets so return empty result
|
||||
return []Entry{}, nil
|
||||
}
|
||||
|
||||
includeAllTokenTypeAssets := (len(filter.Tokens.EnabledTypes) == 0 ||
|
||||
sliceContains(filter.Tokens.EnabledTypes, AssetTT)) && len(filter.Tokens.Assets) == 0
|
||||
|
||||
assets := noEntriesInTmpTableSQLValues
|
||||
if !includeAllTokenTypeAssets {
|
||||
assets = joinItems(filter.Tokens.Assets, func(item TokenCode) string { return fmt.Sprintf("'%v'", item) })
|
||||
}
|
||||
|
||||
includeAllNetworks := len(chainIDs) == 0
|
||||
networks := noEntriesInTmpTableSQLValues
|
||||
if !includeAllNetworks {
|
||||
networks = joinItems(chainIDs, nil)
|
||||
}
|
||||
|
||||
startFilterDisabled := !(filter.Period.StartTimestamp > 0)
|
||||
endFilterDisabled := !(filter.Period.EndTimestamp > 0)
|
||||
filterActivityTypeAll := len(filter.Types) == 0
|
||||
filterAllAddresses := len(addresses) == 0
|
||||
filterAllToAddresses := len(filter.CounterpartyAddresses) == 0
|
||||
includeAllStatuses := len(filter.Statuses) == 0
|
||||
|
||||
filterStatusPending := false
|
||||
filterStatusCompleted := false
|
||||
filterStatusFailed := false
|
||||
filterStatusFinalized := false
|
||||
if !includeAllStatuses {
|
||||
filterStatusPending = sliceContains(filter.Statuses, PendingAS)
|
||||
filterStatusCompleted = sliceContains(filter.Statuses, CompleteAS)
|
||||
filterStatusFailed = sliceContains(filter.Statuses, FailedAS)
|
||||
filterStatusFinalized = sliceContains(filter.Statuses, FinalizedAS)
|
||||
}
|
||||
|
||||
involvedAddresses := noEntriesInTmpTableSQLValues
|
||||
if !filterAllAddresses {
|
||||
involvedAddresses = joinAddresses(addresses)
|
||||
}
|
||||
toAddresses := noEntriesInTmpTableSQLValues
|
||||
if !filterAllToAddresses {
|
||||
toAddresses = joinAddresses(filter.CounterpartyAddresses)
|
||||
}
|
||||
|
||||
mtTypes := activityTypesToMultiTransactionTypes(filter.Types)
|
||||
joinedMTTypes := joinItems(mtTypes, func(t transfer.MultiTransactionType) string {
|
||||
return strconv.Itoa(int(t))
|
||||
})
|
||||
|
||||
queryString := fmt.Sprintf(queryFormatString, involvedAddresses, toAddresses, assets, networks,
|
||||
joinedMTTypes)
|
||||
|
||||
rows, err := db.QueryContext(ctx, queryString,
|
||||
startFilterDisabled, filter.Period.StartTimestamp, endFilterDisabled, filter.Period.EndTimestamp,
|
||||
filterActivityTypeAll, sliceContains(filter.Types, SendAT), sliceContains(filter.Types, ReceiveAT),
|
||||
fromTrType, toTrType,
|
||||
filterAllAddresses, filterAllToAddresses,
|
||||
includeAllStatuses, filterStatusCompleted, filterStatusFailed, filterStatusFinalized, filterStatusPending,
|
||||
FailedAS, CompleteAS, PendingAS,
|
||||
includeAllTokenTypeAssets,
|
||||
includeAllNetworks,
|
||||
limit, offset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var entries []Entry
|
||||
for rows.Next() {
|
||||
var transferHash, pendingHash []byte
|
||||
var chainID, multiTxID, aggregatedCount sql.NullInt64
|
||||
var timestamp int64
|
||||
var dbMtType, dbTrType sql.NullByte
|
||||
var toAddress, fromAddress eth.Address
|
||||
var aggregatedStatus int
|
||||
var dbTrAmount sql.NullString
|
||||
var dbMtFromAmount, dbMtToAmount sql.NullString
|
||||
err := rows.Scan(&transferHash, &pendingHash, &chainID, &multiTxID, ×tamp, &dbMtType, &dbTrType, &fromAddress, &toAddress, &dbTrAmount, &dbMtFromAmount, &dbMtToAmount, &aggregatedStatus, &aggregatedCount)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
getActivityType := func(trType sql.NullByte) (activityType Type, filteredAddress eth.Address) {
|
||||
if trType.Valid {
|
||||
if trType.Byte == fromTrType {
|
||||
return SendAT, fromAddress
|
||||
} else if trType.Byte == toTrType {
|
||||
return ReceiveAT, toAddress
|
||||
}
|
||||
}
|
||||
log.Warn(fmt.Sprintf("unexpected activity type. Missing [%s, %s] in the addresses table?", fromAddress, toAddress))
|
||||
return ReceiveAT, toAddress
|
||||
}
|
||||
|
||||
// Can be mapped directly because the values are injected into the query
|
||||
activityStatus := Status(aggregatedStatus)
|
||||
|
||||
var entry Entry
|
||||
if transferHash != nil && chainID.Valid {
|
||||
activityType, filteredAddress := getActivityType(dbTrType)
|
||||
inAmount, outAmount := getTrInAndOutAmounts(activityType, dbTrAmount)
|
||||
entry = newActivityEntryWithSimpleTransaction(
|
||||
&transfer.TransactionIdentity{ChainID: common.ChainID(chainID.Int64), Hash: eth.BytesToHash(transferHash), Address: filteredAddress},
|
||||
timestamp, activityType, activityStatus, inAmount, outAmount)
|
||||
} else if pendingHash != nil && chainID.Valid {
|
||||
activityType, _ := getActivityType(dbTrType)
|
||||
inAmount, outAmount := getTrInAndOutAmounts(activityType, dbTrAmount)
|
||||
entry = newActivityEntryWithPendingTransaction(&transfer.TransactionIdentity{ChainID: common.ChainID(chainID.Int64), Hash: eth.BytesToHash(pendingHash)},
|
||||
timestamp, activityType, activityStatus, inAmount, outAmount)
|
||||
} else if multiTxID.Valid {
|
||||
mtInAmount, mtOutAmount := getMtInAndOutAmounts(dbMtFromAmount, dbMtToAmount)
|
||||
activityType := multiTransactionTypeToActivityType(transfer.MultiTransactionType(dbMtType.Byte))
|
||||
fmt.Println("getMtInAndOutAmounts", multiTxID.Int64, activityType, mtInAmount, mtOutAmount)
|
||||
entry = NewActivityEntryWithMultiTransaction(transfer.MultiTransactionIDType(multiTxID.Int64),
|
||||
timestamp, activityType, activityStatus, mtInAmount, mtOutAmount)
|
||||
} else {
|
||||
return nil, errors.New("invalid row data")
|
||||
}
|
||||
entries = append(entries, entry)
|
||||
}
|
||||
|
||||
if err = rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return entries, nil
|
||||
}
|
||||
|
|
|
@ -20,23 +20,63 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func setupTestActivityDB(t *testing.T) (db *sql.DB, close func()) {
|
||||
func tokenFromSymbol(chainID *common.ChainID, symbol string) *Token {
|
||||
for i, t := range transfer.TestTokens {
|
||||
if (chainID == nil || t.ChainID == uint64(*chainID)) && t.Symbol == symbol {
|
||||
tokenType := Erc20
|
||||
if testutils.SliceContains(transfer.NativeTokenIndices, i) {
|
||||
tokenType = Native
|
||||
}
|
||||
return &Token{
|
||||
TokenType: tokenType,
|
||||
ChainID: common.ChainID(t.ChainID),
|
||||
Address: t.Address,
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func setupTestActivityDB(t *testing.T) (deps FilterDependencies, close func()) {
|
||||
db, err := appdatabase.SetupTestMemorySQLDB("wallet-activity-tests")
|
||||
require.NoError(t, err)
|
||||
deps = FilterDependencies{
|
||||
db: db,
|
||||
tokenSymbol: func(token Token) string {
|
||||
switch token.TokenType {
|
||||
case Native:
|
||||
for i, t := range transfer.TestTokens {
|
||||
if t.ChainID == uint64(token.ChainID) && testutils.SliceContains(transfer.NativeTokenIndices, i) {
|
||||
return t.Symbol
|
||||
}
|
||||
}
|
||||
case Erc20:
|
||||
for _, t := range transfer.TestTokens {
|
||||
if t.ChainID == uint64(token.ChainID) && t.Address == token.Address {
|
||||
return t.Symbol
|
||||
}
|
||||
}
|
||||
}
|
||||
// In case of ERC721 and ERC1155 we don't have a symbol and they are not yet handled
|
||||
return ""
|
||||
},
|
||||
// tokenFromSymbol nil chainID accepts first symbol found
|
||||
tokenFromSymbol: tokenFromSymbol,
|
||||
}
|
||||
|
||||
return db, func() {
|
||||
return deps, func() {
|
||||
require.NoError(t, db.Close())
|
||||
}
|
||||
}
|
||||
|
||||
type testData struct {
|
||||
tr1 transfer.TestTransfer // index 1
|
||||
pendingTr transfer.TestTransfer // index 2
|
||||
multiTx1Tr1 transfer.TestTransfer // index 3
|
||||
multiTx2Tr1 transfer.TestTransfer // index 4
|
||||
multiTx1Tr2 transfer.TestTransfer // index 5
|
||||
multiTx2Tr2 transfer.TestTransfer // index 6
|
||||
multiTx2PendingTr transfer.TestTransfer // index 7
|
||||
tr1 transfer.TestTransfer // index 1, ETH/Goerli
|
||||
pendingTr transfer.TestTransfer // index 2, ETH/Optimism
|
||||
multiTx1Tr1 transfer.TestTransfer // index 3, USDC/Mainnet
|
||||
multiTx2Tr1 transfer.TestTransfer // index 4, USDC/Goerli
|
||||
multiTx1Tr2 transfer.TestTransfer // index 5, USDC/Optimism
|
||||
multiTx2Tr2 transfer.TestTransfer // index 6, SNT/Mainnet
|
||||
multiTx2PendingTr transfer.TestTransfer // index 7, DAI/Mainnet
|
||||
|
||||
multiTx1 transfer.TestMultiTransaction
|
||||
multiTx1ID transfer.MultiTransactionIDType
|
||||
|
@ -61,6 +101,7 @@ func mockTestAccountsWithAddresses(t *testing.T, db *sql.DB, addresses []eth_com
|
|||
// Generates and adds to the DB 7 transfers and 2 multitransactions.
|
||||
// There are only 4 extractable activity entries (transactions + multi-transactions) with timestamps 1-4. The others are associated with a multi-transaction
|
||||
func fillTestData(t *testing.T, db *sql.DB) (td testData, fromAddresses, toAddresses []eth_common.Address) {
|
||||
// Generates ETH/Goerli, ETH/Optimism, USDC/Mainnet, USDC/Goerli, USDC/Optimism, SNT/Mainnet, DAI/Mainnet
|
||||
trs, fromAddresses, toAddresses := transfer.GenerateTestTransfers(t, db, 1, 7)
|
||||
|
||||
// Plain transfer
|
||||
|
@ -75,7 +116,8 @@ func fillTestData(t *testing.T, db *sql.DB) (td testData, fromAddresses, toAddre
|
|||
td.multiTx1Tr1 = trs[2]
|
||||
td.multiTx1Tr2 = trs[4]
|
||||
|
||||
td.multiTx1Tr1.Token = testutils.SntSymbol
|
||||
// TODO: This got automatically set by GenerateTestTransfers to USDC/Mainnet
|
||||
//td.multiTx1Tr1.Token = &transfer.SntMainnet
|
||||
|
||||
td.multiTx1 = transfer.GenerateTestSendMultiTransaction(td.multiTx1Tr1)
|
||||
td.multiTx1.ToToken = testutils.DaiSymbol
|
||||
|
@ -93,7 +135,7 @@ func fillTestData(t *testing.T, db *sql.DB) (td testData, fromAddresses, toAddre
|
|||
td.multiTx2PendingTr = trs[6]
|
||||
|
||||
td.multiTx2 = transfer.GenerateTestSendMultiTransaction(td.multiTx2Tr1)
|
||||
td.multiTx1.ToToken = testutils.SntSymbol
|
||||
td.multiTx2.ToToken = testutils.SntSymbol
|
||||
td.multiTx2ID = transfer.InsertTestMultiTransaction(t, db, &td.multiTx2)
|
||||
|
||||
td.multiTx2Tr1.MultiTransactionID = td.multiTx2ID
|
||||
|
@ -109,14 +151,27 @@ func fillTestData(t *testing.T, db *sql.DB) (td testData, fromAddresses, toAddre
|
|||
return td, fromAddresses, toAddresses
|
||||
}
|
||||
|
||||
func TTrToToken(t *testing.T, tt *transfer.TestTransaction) *Token {
|
||||
token, isNative := transfer.TestTrToToken(t, tt)
|
||||
tokenType := Erc20
|
||||
if isNative {
|
||||
tokenType = Native
|
||||
}
|
||||
return &Token{
|
||||
TokenType: tokenType,
|
||||
ChainID: common.ChainID(token.ChainID),
|
||||
Address: token.Address,
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetActivityEntriesAll(t *testing.T) {
|
||||
db, close := setupTestActivityDB(t)
|
||||
deps, close := setupTestActivityDB(t)
|
||||
defer close()
|
||||
|
||||
td, fromAddresses, toAddresses := fillTestData(t, db)
|
||||
td, fromAddresses, toAddresses := fillTestData(t, deps.db)
|
||||
|
||||
var filter Filter
|
||||
entries, err := getActivityEntries(context.Background(), db, append(toAddresses, fromAddresses...), []common.ChainID{}, filter, 0, 10)
|
||||
entries, err := getActivityEntries(context.Background(), deps, append(toAddresses, fromAddresses...), []common.ChainID{}, filter, 0, 10)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 4, len(entries))
|
||||
|
||||
|
@ -127,119 +182,66 @@ func TestGetActivityEntriesAll(t *testing.T) {
|
|||
curTimestamp--
|
||||
}
|
||||
|
||||
require.True(t, testutils.StructExistsInSlice(Entry{
|
||||
require.Equal(t, Entry{
|
||||
payloadType: SimpleTransactionPT,
|
||||
transaction: &transfer.TransactionIdentity{ChainID: td.tr1.ChainID, Hash: td.tr1.Hash, Address: td.tr1.From},
|
||||
id: td.tr1.MultiTransactionID,
|
||||
timestamp: td.tr1.Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(td.tr1.Value)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(0)),
|
||||
}, entries))
|
||||
require.True(t, testutils.StructExistsInSlice(Entry{
|
||||
tokenOut: TTrToToken(t, &td.tr1.TestTransaction),
|
||||
tokenIn: nil,
|
||||
}, entries[3])
|
||||
require.Equal(t, Entry{
|
||||
payloadType: PendingTransactionPT,
|
||||
transaction: &transfer.TransactionIdentity{ChainID: td.pendingTr.ChainID, Hash: td.pendingTr.Hash},
|
||||
id: td.pendingTr.MultiTransactionID,
|
||||
timestamp: td.pendingTr.Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: PendingAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(td.pendingTr.Value)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(0)),
|
||||
}, entries))
|
||||
require.True(t, testutils.StructExistsInSlice(Entry{
|
||||
tokenOut: TTrToToken(t, &td.pendingTr.TestTransaction),
|
||||
tokenIn: nil,
|
||||
}, entries[2])
|
||||
require.Equal(t, Entry{
|
||||
payloadType: MultiTransactionPT,
|
||||
transaction: nil,
|
||||
id: td.multiTx1ID,
|
||||
timestamp: td.multiTx1.Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(td.multiTx1.FromAmount)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(td.multiTx1.ToAmount)),
|
||||
}, entries))
|
||||
require.True(t, testutils.StructExistsInSlice(Entry{
|
||||
tokenOut: tokenFromSymbol(nil, td.multiTx1.FromToken),
|
||||
tokenIn: tokenFromSymbol(nil, td.multiTx1.ToToken),
|
||||
}, entries[1])
|
||||
require.Equal(t, Entry{
|
||||
payloadType: MultiTransactionPT,
|
||||
transaction: nil,
|
||||
id: td.multiTx2ID,
|
||||
timestamp: td.multiTx2.Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: PendingAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(td.multiTx2.FromAmount)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(td.multiTx2.ToAmount)),
|
||||
}, entries))
|
||||
|
||||
// Ensure the sub-transactions of the multi-transactions are not returned
|
||||
require.False(t, testutils.StructExistsInSlice(Entry{
|
||||
payloadType: SimpleTransactionPT,
|
||||
transaction: &transfer.TransactionIdentity{ChainID: td.multiTx1Tr1.ChainID, Hash: td.multiTx1Tr1.Hash, Address: td.multiTx1Tr1.To},
|
||||
id: td.multiTx1Tr1.MultiTransactionID,
|
||||
timestamp: td.multiTx1Tr1.Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(td.multiTx1Tr1.Value)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(0)),
|
||||
}, entries))
|
||||
require.False(t, testutils.StructExistsInSlice(Entry{
|
||||
payloadType: SimpleTransactionPT,
|
||||
transaction: &transfer.TransactionIdentity{ChainID: td.multiTx1Tr2.ChainID, Hash: td.multiTx1Tr2.Hash, Address: td.multiTx1Tr2.To},
|
||||
id: td.multiTx1Tr2.MultiTransactionID,
|
||||
timestamp: td.multiTx1Tr2.Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(td.multiTx1Tr2.Value)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(0)),
|
||||
}, entries))
|
||||
require.False(t, testutils.StructExistsInSlice(Entry{
|
||||
payloadType: SimpleTransactionPT,
|
||||
transaction: &transfer.TransactionIdentity{ChainID: td.multiTx2Tr1.ChainID, Hash: td.multiTx2Tr1.Hash, Address: td.multiTx2Tr1.To},
|
||||
id: td.multiTx2Tr1.MultiTransactionID,
|
||||
timestamp: td.multiTx2Tr1.Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(td.multiTx2Tr1.Value)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(0)),
|
||||
}, entries))
|
||||
require.False(t, testutils.StructExistsInSlice(Entry{
|
||||
payloadType: SimpleTransactionPT,
|
||||
transaction: &transfer.TransactionIdentity{ChainID: td.multiTx2Tr2.ChainID, Hash: td.multiTx2Tr2.Hash, Address: td.multiTx2Tr2.To},
|
||||
id: td.multiTx2Tr2.MultiTransactionID,
|
||||
timestamp: td.multiTx2Tr2.Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(td.multiTx2Tr2.Value)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(0)),
|
||||
}, entries))
|
||||
require.False(t, testutils.StructExistsInSlice(Entry{
|
||||
payloadType: PendingTransactionPT,
|
||||
transaction: &transfer.TransactionIdentity{ChainID: td.multiTx2PendingTr.ChainID, Hash: td.multiTx2PendingTr.Hash},
|
||||
id: td.multiTx2PendingTr.MultiTransactionID,
|
||||
timestamp: td.multiTx2PendingTr.Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: PendingAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(td.multiTx2PendingTr.Value)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(0)),
|
||||
}, entries))
|
||||
tokenOut: tokenFromSymbol(nil, td.multiTx2.FromToken),
|
||||
tokenIn: tokenFromSymbol(nil, td.multiTx2.ToToken),
|
||||
}, entries[0])
|
||||
}
|
||||
|
||||
// TestGetActivityEntriesWithSenderFilter covers the issue with returning the same transaction
|
||||
// twice when the sender and receiver have entries in the transfers table
|
||||
func TestGetActivityEntriesWithSameTransactionForSenderAndReceiverInDB(t *testing.T) {
|
||||
db, close := setupTestActivityDB(t)
|
||||
deps, close := setupTestActivityDB(t)
|
||||
defer close()
|
||||
|
||||
// Add 4 extractable transactions with timestamps 1-4
|
||||
td, fromAddresses, toAddresses := fillTestData(t, db)
|
||||
td, fromAddresses, toAddresses := fillTestData(t, deps.db)
|
||||
|
||||
mockTestAccountsWithAddresses(t, db, append(fromAddresses, toAddresses...))
|
||||
mockTestAccountsWithAddresses(t, deps.db, append(fromAddresses, toAddresses...))
|
||||
|
||||
// Add another transaction with sender and receiver reversed
|
||||
receiverTr := td.tr1
|
||||
|
@ -251,10 +253,10 @@ func TestGetActivityEntriesWithSameTransactionForSenderAndReceiverInDB(t *testin
|
|||
|
||||
// Ensure they are the oldest transactions (last in the list) and we have a consistent order
|
||||
receiverTr.Timestamp--
|
||||
transfer.InsertTestTransfer(t, db, &receiverTr)
|
||||
transfer.InsertTestTransfer(t, deps.db, &receiverTr)
|
||||
|
||||
var filter Filter
|
||||
entries, err := getActivityEntries(context.Background(), db, []eth.Address{td.tr1.From, receiverTr.From}, []common.ChainID{}, filter, 0, 10)
|
||||
entries, err := getActivityEntries(context.Background(), deps, []eth.Address{td.tr1.From, receiverTr.From}, []common.ChainID{}, filter, 0, 10)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 2, len(entries))
|
||||
|
||||
|
@ -267,7 +269,7 @@ func TestGetActivityEntriesWithSameTransactionForSenderAndReceiverInDB(t *testin
|
|||
require.NotEqual(t, eth.Address{}, entries[0].transaction.Address)
|
||||
require.Equal(t, td.tr1.From, entries[0].transaction.Address)
|
||||
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth.Address{}, []common.ChainID{}, filter, 0, 10)
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth.Address{}, []common.ChainID{}, filter, 0, 10)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 5, len(entries))
|
||||
|
||||
|
@ -277,24 +279,24 @@ func TestGetActivityEntriesWithSameTransactionForSenderAndReceiverInDB(t *testin
|
|||
}
|
||||
|
||||
func TestGetActivityEntriesFilterByTime(t *testing.T) {
|
||||
db, close := setupTestActivityDB(t)
|
||||
deps, close := setupTestActivityDB(t)
|
||||
defer close()
|
||||
|
||||
td, fromTds, toTds := fillTestData(t, db)
|
||||
td, fromTds, toTds := fillTestData(t, deps.db)
|
||||
|
||||
// Add 6 extractable transactions with timestamps 6-12
|
||||
trs, fromTrs, toTrs := transfer.GenerateTestTransfers(t, db, td.nextIndex, 6)
|
||||
trs, fromTrs, toTrs := transfer.GenerateTestTransfers(t, deps.db, td.nextIndex, 6)
|
||||
for i := range trs {
|
||||
transfer.InsertTestTransfer(t, db, &trs[i])
|
||||
transfer.InsertTestTransfer(t, deps.db, &trs[i])
|
||||
}
|
||||
|
||||
mockTestAccountsWithAddresses(t, db, append(append(append(fromTds, toTds...), fromTrs...), toTrs...))
|
||||
mockTestAccountsWithAddresses(t, deps.db, append(append(append(fromTds, toTds...), fromTrs...), toTrs...))
|
||||
|
||||
// Test start only
|
||||
var filter Filter
|
||||
filter.Period.StartTimestamp = td.multiTx1.Timestamp
|
||||
filter.Period.EndTimestamp = NoLimitTimestampForPeriod
|
||||
entries, err := getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err := getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 8, len(entries))
|
||||
// Check start and end content
|
||||
|
@ -305,9 +307,10 @@ func TestGetActivityEntriesFilterByTime(t *testing.T) {
|
|||
timestamp: trs[5].Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(trs[5].Value)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(0)),
|
||||
tokenOut: TTrToToken(t, &trs[5].TestTransaction),
|
||||
tokenIn: nil,
|
||||
}, entries[0])
|
||||
require.Equal(t, Entry{
|
||||
payloadType: MultiTransactionPT,
|
||||
|
@ -316,14 +319,15 @@ func TestGetActivityEntriesFilterByTime(t *testing.T) {
|
|||
timestamp: td.multiTx1.Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(td.multiTx1.FromAmount)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(td.multiTx1.ToAmount)),
|
||||
tokenOut: tokenFromSymbol(nil, td.multiTx1.FromToken),
|
||||
tokenIn: tokenFromSymbol(nil, td.multiTx1.ToToken),
|
||||
}, entries[7])
|
||||
|
||||
// Test complete interval
|
||||
filter.Period.EndTimestamp = trs[2].Timestamp
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 5, len(entries))
|
||||
// Check start and end content
|
||||
|
@ -334,9 +338,10 @@ func TestGetActivityEntriesFilterByTime(t *testing.T) {
|
|||
timestamp: trs[2].Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(trs[2].Value)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(0)),
|
||||
tokenOut: TTrToToken(t, &trs[2].TestTransaction),
|
||||
tokenIn: nil,
|
||||
}, entries[0])
|
||||
require.Equal(t, Entry{
|
||||
payloadType: MultiTransactionPT,
|
||||
|
@ -345,14 +350,15 @@ func TestGetActivityEntriesFilterByTime(t *testing.T) {
|
|||
timestamp: td.multiTx1.Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(td.multiTx1.FromAmount)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(td.multiTx1.ToAmount)),
|
||||
tokenOut: tokenFromSymbol(nil, td.multiTx1.FromToken),
|
||||
tokenIn: tokenFromSymbol(nil, td.multiTx1.ToToken),
|
||||
}, entries[4])
|
||||
|
||||
// Test end only
|
||||
filter.Period.StartTimestamp = NoLimitTimestampForPeriod
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 7, len(entries))
|
||||
// Check start and end content
|
||||
|
@ -363,9 +369,10 @@ func TestGetActivityEntriesFilterByTime(t *testing.T) {
|
|||
timestamp: trs[2].Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(trs[2].Value)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(0)),
|
||||
tokenOut: TTrToToken(t, &trs[2].TestTransaction),
|
||||
tokenIn: nil,
|
||||
}, entries[0])
|
||||
require.Equal(t, Entry{
|
||||
payloadType: SimpleTransactionPT,
|
||||
|
@ -374,34 +381,35 @@ func TestGetActivityEntriesFilterByTime(t *testing.T) {
|
|||
timestamp: td.tr1.Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(td.tr1.Value)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(0)),
|
||||
tokenOut: TTrToToken(t, &td.tr1.TestTransaction),
|
||||
tokenIn: nil,
|
||||
}, entries[6])
|
||||
}
|
||||
|
||||
func TestGetActivityEntriesCheckOffsetAndLimit(t *testing.T) {
|
||||
db, close := setupTestActivityDB(t)
|
||||
deps, close := setupTestActivityDB(t)
|
||||
defer close()
|
||||
|
||||
// Add 10 extractable transactions with timestamps 1-10
|
||||
trs, fromTrs, toTrs := transfer.GenerateTestTransfers(t, db, 1, 10)
|
||||
trs, fromTrs, toTrs := transfer.GenerateTestTransfers(t, deps.db, 1, 10)
|
||||
for i := range trs {
|
||||
transfer.InsertTestTransfer(t, db, &trs[i])
|
||||
transfer.InsertTestTransfer(t, deps.db, &trs[i])
|
||||
}
|
||||
|
||||
mockTestAccountsWithAddresses(t, db, append(fromTrs, toTrs...))
|
||||
mockTestAccountsWithAddresses(t, deps.db, append(fromTrs, toTrs...))
|
||||
|
||||
var filter Filter
|
||||
// Get all
|
||||
entries, err := getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 5)
|
||||
entries, err := getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 5)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 5, len(entries))
|
||||
|
||||
// Get time based interval
|
||||
filter.Period.StartTimestamp = trs[2].Timestamp
|
||||
filter.Period.EndTimestamp = trs[8].Timestamp
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 3)
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 3)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 3, len(entries))
|
||||
// Check start and end content
|
||||
|
@ -412,9 +420,10 @@ func TestGetActivityEntriesCheckOffsetAndLimit(t *testing.T) {
|
|||
timestamp: trs[8].Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(trs[8].Value)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(0)),
|
||||
tokenOut: TTrToToken(t, &trs[8].TestTransaction),
|
||||
tokenIn: nil,
|
||||
}, entries[0])
|
||||
require.Equal(t, Entry{
|
||||
payloadType: SimpleTransactionPT,
|
||||
|
@ -423,13 +432,14 @@ func TestGetActivityEntriesCheckOffsetAndLimit(t *testing.T) {
|
|||
timestamp: trs[6].Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(trs[6].Value)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(0)),
|
||||
tokenOut: TTrToToken(t, &trs[6].TestTransaction),
|
||||
tokenIn: nil,
|
||||
}, entries[2])
|
||||
|
||||
// Move window 2 entries forward
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 2, 3)
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 2, 3)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 3, len(entries))
|
||||
// Check start and end content
|
||||
|
@ -440,9 +450,10 @@ func TestGetActivityEntriesCheckOffsetAndLimit(t *testing.T) {
|
|||
timestamp: trs[6].Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(trs[6].Value)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(0)),
|
||||
tokenOut: TTrToToken(t, &trs[6].TestTransaction),
|
||||
tokenIn: nil,
|
||||
}, entries[0])
|
||||
require.Equal(t, Entry{
|
||||
payloadType: SimpleTransactionPT,
|
||||
|
@ -451,13 +462,14 @@ func TestGetActivityEntriesCheckOffsetAndLimit(t *testing.T) {
|
|||
timestamp: trs[4].Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(trs[4].Value)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(0)),
|
||||
tokenOut: TTrToToken(t, &trs[4].TestTransaction),
|
||||
tokenIn: nil,
|
||||
}, entries[2])
|
||||
|
||||
// Move window 4 more entries to test filter cap
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 6, 3)
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 6, 3)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(entries))
|
||||
// Check start and end content
|
||||
|
@ -468,9 +480,10 @@ func TestGetActivityEntriesCheckOffsetAndLimit(t *testing.T) {
|
|||
timestamp: trs[2].Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(trs[2].Value)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(0)),
|
||||
tokenOut: TTrToToken(t, &trs[2].TestTransaction),
|
||||
tokenIn: nil,
|
||||
}, entries[0])
|
||||
}
|
||||
|
||||
|
@ -493,14 +506,14 @@ func countTypes(entries []Entry) (sendCount, receiveCount, swapCount, buyCount,
|
|||
}
|
||||
|
||||
func TestGetActivityEntriesFilterByType(t *testing.T) {
|
||||
db, close := setupTestActivityDB(t)
|
||||
deps, close := setupTestActivityDB(t)
|
||||
defer close()
|
||||
|
||||
// Adds 4 extractable transactions
|
||||
td, _, _ := fillTestData(t, db)
|
||||
td, _, _ := fillTestData(t, deps.db)
|
||||
// Add 5 extractable transactions: one MultiTransactionSwap, two MultiTransactionBridge and two MultiTransactionSend
|
||||
multiTxs := make([]transfer.TestMultiTransaction, 5)
|
||||
trs, _, _ := transfer.GenerateTestTransfers(t, db, td.nextIndex, len(multiTxs)*2)
|
||||
trs, _, _ := transfer.GenerateTestTransfers(t, deps.db, td.nextIndex, len(multiTxs)*2)
|
||||
multiTxs[0] = transfer.GenerateTestBridgeMultiTransaction(trs[0], trs[1])
|
||||
multiTxs[1] = transfer.GenerateTestSwapMultiTransaction(trs[2], testutils.SntSymbol, 100) // trs[3]
|
||||
multiTxs[2] = transfer.GenerateTestSendMultiTransaction(trs[4]) // trs[5]
|
||||
|
@ -510,10 +523,10 @@ func TestGetActivityEntriesFilterByType(t *testing.T) {
|
|||
var lastMT transfer.MultiTransactionIDType
|
||||
for i := range trs {
|
||||
if i%2 == 0 {
|
||||
lastMT = transfer.InsertTestMultiTransaction(t, db, &multiTxs[i/2])
|
||||
lastMT = transfer.InsertTestMultiTransaction(t, deps.db, &multiTxs[i/2])
|
||||
}
|
||||
trs[i].MultiTransactionID = lastMT
|
||||
transfer.InsertTestTransfer(t, db, &trs[i])
|
||||
transfer.InsertTestTransfer(t, deps.db, &trs[i])
|
||||
}
|
||||
|
||||
// Test filtering out without address involved
|
||||
|
@ -522,12 +535,12 @@ func TestGetActivityEntriesFilterByType(t *testing.T) {
|
|||
filter.Types = allActivityTypesFilter()
|
||||
// Set tr1 to Receive and pendingTr to Send; rest of two MT remain default Send
|
||||
addresses := []eth_common.Address{td.tr1.To, td.pendingTr.From, td.multiTx1.FromAddress, td.multiTx2.FromAddress, trs[0].From, trs[2].From, trs[4].From, trs[6].From, trs[8].From}
|
||||
entries, err := getActivityEntries(context.Background(), db, addresses, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err := getActivityEntries(context.Background(), deps, addresses, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 9, len(entries))
|
||||
|
||||
filter.Types = []Type{SendAT, SwapAT}
|
||||
entries, err = getActivityEntries(context.Background(), db, addresses, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err = getActivityEntries(context.Background(), deps, addresses, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
// 3 from td Send + 2 trs MT Send + 1 (swap)
|
||||
require.Equal(t, 6, len(entries))
|
||||
|
@ -540,7 +553,7 @@ func TestGetActivityEntriesFilterByType(t *testing.T) {
|
|||
require.Equal(t, 0, bridgeCount)
|
||||
|
||||
filter.Types = []Type{BridgeAT, ReceiveAT}
|
||||
entries, err = getActivityEntries(context.Background(), db, addresses, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err = getActivityEntries(context.Background(), deps, addresses, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 3, len(entries))
|
||||
|
||||
|
@ -552,27 +565,27 @@ func TestGetActivityEntriesFilterByType(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetActivityEntriesFilterByAddresses(t *testing.T) {
|
||||
db, close := setupTestActivityDB(t)
|
||||
deps, close := setupTestActivityDB(t)
|
||||
defer close()
|
||||
|
||||
// Adds 4 extractable transactions
|
||||
td, fromTds, toTds := fillTestData(t, db)
|
||||
trs, fromTrs, toTrs := transfer.GenerateTestTransfers(t, db, td.nextIndex, 6)
|
||||
td, fromTds, toTds := fillTestData(t, deps.db)
|
||||
trs, fromTrs, toTrs := transfer.GenerateTestTransfers(t, deps.db, td.nextIndex, 6)
|
||||
for i := range trs {
|
||||
transfer.InsertTestTransfer(t, db, &trs[i])
|
||||
transfer.InsertTestTransfer(t, deps.db, &trs[i])
|
||||
}
|
||||
|
||||
mockTestAccountsWithAddresses(t, db, append(append(append(fromTds, toTds...), fromTrs...), toTrs...))
|
||||
mockTestAccountsWithAddresses(t, deps.db, append(append(append(fromTds, toTds...), fromTrs...), toTrs...))
|
||||
|
||||
var filter Filter
|
||||
|
||||
addressesFilter := allAddressesFilter()
|
||||
entries, err := getActivityEntries(context.Background(), db, addressesFilter, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err := getActivityEntries(context.Background(), deps, addressesFilter, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 10, len(entries))
|
||||
|
||||
addressesFilter = []eth_common.Address{td.multiTx2.ToAddress, trs[1].From, trs[4].To}
|
||||
entries, err = getActivityEntries(context.Background(), db, addressesFilter, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err = getActivityEntries(context.Background(), deps, addressesFilter, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 3, len(entries))
|
||||
require.Equal(t, Entry{
|
||||
|
@ -582,9 +595,10 @@ func TestGetActivityEntriesFilterByAddresses(t *testing.T) {
|
|||
timestamp: trs[4].Timestamp,
|
||||
activityType: ReceiveAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(0)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(trs[4].Value)),
|
||||
tokenOut: nil,
|
||||
tokenIn: TTrToToken(t, &trs[4].TestTransaction),
|
||||
}, entries[0])
|
||||
require.Equal(t, Entry{
|
||||
payloadType: SimpleTransactionPT,
|
||||
|
@ -593,9 +607,10 @@ func TestGetActivityEntriesFilterByAddresses(t *testing.T) {
|
|||
timestamp: trs[1].Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: CompleteAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(trs[1].Value)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(0)),
|
||||
tokenOut: TTrToToken(t, &trs[1].TestTransaction),
|
||||
tokenIn: nil,
|
||||
}, entries[1])
|
||||
require.Equal(t, Entry{
|
||||
payloadType: MultiTransactionPT,
|
||||
|
@ -604,42 +619,43 @@ func TestGetActivityEntriesFilterByAddresses(t *testing.T) {
|
|||
timestamp: td.multiTx2.Timestamp,
|
||||
activityType: SendAT,
|
||||
activityStatus: PendingAS,
|
||||
tokenType: AssetTT,
|
||||
amountOut: (*hexutil.Big)(big.NewInt(td.multiTx2.FromAmount)),
|
||||
amountIn: (*hexutil.Big)(big.NewInt(td.multiTx2.ToAmount)),
|
||||
tokenOut: tokenFromSymbol(nil, td.multiTx2.FromToken),
|
||||
tokenIn: tokenFromSymbol(nil, td.multiTx2.ToToken),
|
||||
}, entries[2])
|
||||
}
|
||||
|
||||
func TestGetActivityEntriesFilterByStatus(t *testing.T) {
|
||||
db, close := setupTestActivityDB(t)
|
||||
deps, close := setupTestActivityDB(t)
|
||||
defer close()
|
||||
|
||||
// Adds 4 extractable transactions: 1 T, 1 T pending, 1 MT pending, 1 MT with 2xT success
|
||||
td, fromTds, toTds := fillTestData(t, db)
|
||||
td, fromTds, toTds := fillTestData(t, deps.db)
|
||||
// Add 7 extractable transactions: 1 pending, 1 Tr failed, 1 MT failed, 4 success
|
||||
trs, fromTrs, toTrs := transfer.GenerateTestTransfers(t, db, td.nextIndex, 7)
|
||||
trs, fromTrs, toTrs := transfer.GenerateTestTransfers(t, deps.db, td.nextIndex, 7)
|
||||
multiTx := transfer.GenerateTestSendMultiTransaction(trs[6])
|
||||
failedMTID := transfer.InsertTestMultiTransaction(t, db, &multiTx)
|
||||
failedMTID := transfer.InsertTestMultiTransaction(t, deps.db, &multiTx)
|
||||
trs[6].MultiTransactionID = failedMTID
|
||||
for i := range trs {
|
||||
if i == 1 {
|
||||
transfer.InsertTestPendingTransaction(t, db, &trs[i])
|
||||
transfer.InsertTestPendingTransaction(t, deps.db, &trs[i])
|
||||
} else {
|
||||
trs[i].Success = i != 3 && i != 6
|
||||
transfer.InsertTestTransfer(t, db, &trs[i])
|
||||
transfer.InsertTestTransfer(t, deps.db, &trs[i])
|
||||
}
|
||||
}
|
||||
|
||||
mockTestAccountsWithAddresses(t, db, append(append(append(fromTds, toTds...), fromTrs...), toTrs...))
|
||||
mockTestAccountsWithAddresses(t, deps.db, append(append(append(fromTds, toTds...), fromTrs...), toTrs...))
|
||||
|
||||
var filter Filter
|
||||
filter.Statuses = allActivityStatusesFilter()
|
||||
entries, err := getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err := getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 11, len(entries))
|
||||
|
||||
filter.Statuses = []Status{PendingAS}
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 3, len(entries))
|
||||
require.Equal(t, td.pendingTr.Hash, entries[2].transaction.Hash)
|
||||
|
@ -647,162 +663,192 @@ func TestGetActivityEntriesFilterByStatus(t *testing.T) {
|
|||
require.Equal(t, trs[1].Hash, entries[0].transaction.Hash)
|
||||
|
||||
filter.Statuses = []Status{FailedAS}
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 2, len(entries))
|
||||
|
||||
filter.Statuses = []Status{CompleteAS}
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 6, len(entries))
|
||||
|
||||
// Finalized is treated as Complete, would need dynamic blockchain status to track the Finalized level
|
||||
filter.Statuses = []Status{FinalizedAS}
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 6, len(entries))
|
||||
|
||||
// Combined filter
|
||||
filter.Statuses = []Status{FailedAS, PendingAS}
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 5, len(entries))
|
||||
}
|
||||
|
||||
func TestGetActivityEntriesFilterByTokenType(t *testing.T) {
|
||||
db, close := setupTestActivityDB(t)
|
||||
deps, close := setupTestActivityDB(t)
|
||||
defer close()
|
||||
|
||||
// Adds 4 extractable transactions 2 transactions ETH, one MT SNT to DAI and another MT ETH to SNT
|
||||
td, fromTds, toTds := fillTestData(t, db)
|
||||
// Add 6 extractable transactions with USDC (only erc20 as type in DB)
|
||||
trs, fromTrs, toTrs := transfer.GenerateTestTransfers(t, db, td.nextIndex, 6)
|
||||
// Adds 4 extractable transactions 2 transactions (ETH/Goerli, ETH/Optimism), one MT USDC to DAI and another MT USDC to SNT
|
||||
td, fromTds, toTds := fillTestData(t, deps.db)
|
||||
// Add 9 transactions DAI/Goerli, ETH/Mainnet, ETH/Goerli, ETH/Optimism, USDC/Mainnet, USDC/Goerli, USDC/Optimism, SNT/Mainnet, DAI/Mainnet
|
||||
trs, fromTrs, toTrs := transfer.GenerateTestTransfers(t, deps.db, td.nextIndex, 9)
|
||||
for i := range trs {
|
||||
trs[i].Token = "USDC"
|
||||
transfer.InsertTestTransfer(t, db, &trs[i])
|
||||
tokenAddr := transfer.TestTokens[i].Address
|
||||
trs[i].ChainID = common.ChainID(transfer.TestTokens[i].ChainID)
|
||||
transfer.InsertTestTransferWithToken(t, deps.db, &trs[i], tokenAddr)
|
||||
}
|
||||
|
||||
mockTestAccountsWithAddresses(t, db, append(append(append(fromTds, toTds...), fromTrs...), toTrs...))
|
||||
mockTestAccountsWithAddresses(t, deps.db, append(append(append(fromTds, toTds...), fromTrs...), toTrs...))
|
||||
|
||||
var filter Filter
|
||||
filter.Tokens = noAssetsFilter()
|
||||
entries, err := getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
filter.FilterOutAssets = true
|
||||
entries, err := getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(entries))
|
||||
|
||||
filter.Tokens = allTokensFilter()
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
filter.FilterOutAssets = false
|
||||
filter.Assets = allTokensFilter()
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 10, len(entries))
|
||||
require.Equal(t, 13, len(entries))
|
||||
|
||||
// Regression when collectibles is nil
|
||||
filter.Tokens = Tokens{[]TokenCode{}, nil, []TokenType{}}
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
// Native tokens are network agnostic, hence all are returned
|
||||
filter.Assets = []Token{{TokenType: Native, ChainID: common.ChainID(transfer.EthMainnet.ChainID)}}
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 10, len(entries))
|
||||
require.Equal(t, 5, len(entries))
|
||||
|
||||
filter.Tokens = Tokens{Assets: []TokenCode{"ETH"}, EnabledTypes: []TokenType{AssetTT}}
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
// Test that it doesn't break the filter
|
||||
filter.Assets = []Token{{TokenType: Erc1155}}
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(entries))
|
||||
|
||||
filter.Assets = []Token{{
|
||||
TokenType: Erc20,
|
||||
ChainID: common.ChainID(transfer.UsdcMainnet.ChainID),
|
||||
Address: transfer.UsdcMainnet.Address,
|
||||
}}
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
// Two MT for which ChainID is ignored and one transfer on the main net and the Goerli is ignored
|
||||
require.Equal(t, 3, len(entries))
|
||||
require.Equal(t, Erc20, entries[0].tokenOut.TokenType)
|
||||
require.Equal(t, transfer.UsdcMainnet.Address, entries[0].tokenOut.Address)
|
||||
require.Nil(t, entries[0].tokenIn)
|
||||
// MT has only symbol, the first token is lookup by symbol for both entries
|
||||
require.Equal(t, Erc20, entries[1].tokenOut.TokenType)
|
||||
require.Equal(t, transfer.UsdcMainnet.Address, entries[1].tokenOut.Address)
|
||||
require.Equal(t, Erc20, entries[1].tokenIn.TokenType)
|
||||
require.Equal(t, transfer.SntMainnet.Address, entries[1].tokenIn.Address)
|
||||
require.Equal(t, Erc20, entries[2].tokenOut.TokenType)
|
||||
require.Equal(t, transfer.UsdcMainnet.Address, entries[1].tokenOut.Address)
|
||||
require.Equal(t, Erc20, entries[2].tokenIn.TokenType)
|
||||
require.Equal(t, transfer.UsdcMainnet.Address, entries[1].tokenOut.Address)
|
||||
|
||||
// TODO: update tests after adding token type to transfers
|
||||
filter.Tokens = Tokens{Assets: []TokenCode{"USDC", "DAI"}, EnabledTypes: []TokenType{AssetTT}}
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
filter.Assets = []Token{{
|
||||
TokenType: Erc20,
|
||||
ChainID: common.ChainID(transfer.UsdcMainnet.ChainID),
|
||||
Address: transfer.UsdcMainnet.Address,
|
||||
}, {
|
||||
TokenType: Erc20,
|
||||
ChainID: common.ChainID(transfer.UsdcGoerli.ChainID),
|
||||
Address: transfer.UsdcGoerli.Address,
|
||||
}}
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(entries))
|
||||
|
||||
// Regression when EnabledTypes ar empty
|
||||
filter.Tokens = Tokens{Assets: []TokenCode{"USDC", "DAI"}, EnabledTypes: []TokenType{}}
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(entries))
|
||||
// Two MT for which ChainID is ignored and two transfers on the main net and Goerli
|
||||
require.Equal(t, 4, len(entries))
|
||||
require.Equal(t, Erc20, entries[0].tokenOut.TokenType)
|
||||
require.Equal(t, transfer.UsdcGoerli.Address, entries[0].tokenOut.Address)
|
||||
require.Nil(t, entries[0].tokenIn)
|
||||
}
|
||||
|
||||
func TestGetActivityEntriesFilterByToAddresses(t *testing.T) {
|
||||
db, close := setupTestActivityDB(t)
|
||||
deps, close := setupTestActivityDB(t)
|
||||
defer close()
|
||||
|
||||
// Adds 4 extractable transactions
|
||||
td, fromTds, toTds := fillTestData(t, db)
|
||||
td, fromTds, toTds := fillTestData(t, deps.db)
|
||||
// Add 6 extractable transactions
|
||||
trs, fromTrs, toTrs := transfer.GenerateTestTransfers(t, db, td.nextIndex, 6)
|
||||
trs, fromTrs, toTrs := transfer.GenerateTestTransfers(t, deps.db, td.nextIndex, 6)
|
||||
for i := range trs {
|
||||
transfer.InsertTestTransfer(t, db, &trs[i])
|
||||
transfer.InsertTestTransfer(t, deps.db, &trs[i])
|
||||
}
|
||||
|
||||
mockTestAccountsWithAddresses(t, db, append(append(append(fromTds, toTds...), fromTrs...), toTrs...))
|
||||
mockTestAccountsWithAddresses(t, deps.db, append(append(append(fromTds, toTds...), fromTrs...), toTrs...))
|
||||
|
||||
var filter Filter
|
||||
filter.CounterpartyAddresses = allAddressesFilter()
|
||||
entries, err := getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err := getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 10, len(entries))
|
||||
|
||||
filter.CounterpartyAddresses = []eth_common.Address{eth_common.HexToAddress("0x567890")}
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(entries))
|
||||
|
||||
filter.CounterpartyAddresses = []eth_common.Address{td.pendingTr.To, td.multiTx2.ToAddress, trs[3].To}
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 3, len(entries))
|
||||
|
||||
filter.CounterpartyAddresses = []eth_common.Address{td.tr1.To, td.pendingTr.From, trs[3].From, trs[5].To}
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 2, len(entries))
|
||||
}
|
||||
func TestGetActivityEntriesFilterByNetworks(t *testing.T) {
|
||||
db, close := setupTestActivityDB(t)
|
||||
deps, close := setupTestActivityDB(t)
|
||||
defer close()
|
||||
|
||||
// Adds 4 extractable transactions
|
||||
td, fromTds, toTds := fillTestData(t, db)
|
||||
td, fromTds, toTds := fillTestData(t, deps.db)
|
||||
// Add 6 extractable transactions
|
||||
trs, fromTrs, toTrs := transfer.GenerateTestTransfers(t, db, td.nextIndex, 6)
|
||||
trs, fromTrs, toTrs := transfer.GenerateTestTransfers(t, deps.db, td.nextIndex, 6)
|
||||
for i := range trs {
|
||||
transfer.InsertTestTransfer(t, db, &trs[i])
|
||||
transfer.InsertTestTransfer(t, deps.db, &trs[i])
|
||||
}
|
||||
mockTestAccountsWithAddresses(t, db, append(append(append(fromTds, toTds...), fromTrs...), toTrs...))
|
||||
mockTestAccountsWithAddresses(t, deps.db, append(append(append(fromTds, toTds...), fromTrs...), toTrs...))
|
||||
|
||||
var filter Filter
|
||||
chainIDs := allNetworksFilter()
|
||||
entries, err := getActivityEntries(context.Background(), db, []eth_common.Address{}, chainIDs, filter, 0, 15)
|
||||
entries, err := getActivityEntries(context.Background(), deps, []eth_common.Address{}, chainIDs, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 10, len(entries))
|
||||
|
||||
chainIDs = []common.ChainID{5674839210}
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, chainIDs, filter, 0, 15)
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, chainIDs, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
// TODO: update after multi-transactions are filterable by ChainID
|
||||
require.Equal(t, 2 /*0*/, len(entries))
|
||||
|
||||
chainIDs = []common.ChainID{td.pendingTr.ChainID, td.multiTx2Tr1.ChainID, trs[3].ChainID}
|
||||
entries, err = getActivityEntries(context.Background(), db, []eth_common.Address{}, chainIDs, filter, 0, 15)
|
||||
entries, err = getActivityEntries(context.Background(), deps, []eth_common.Address{}, chainIDs, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
// TODO: update after multi-transactions are filterable by ChainID
|
||||
require.Equal(t, 4 /*3*/, len(entries))
|
||||
require.Equal(t, 8 /*6*/, len(entries))
|
||||
}
|
||||
|
||||
func TestGetActivityEntriesCheckToAndFrom(t *testing.T) {
|
||||
db, close := setupTestActivityDB(t)
|
||||
deps, close := setupTestActivityDB(t)
|
||||
defer close()
|
||||
|
||||
// Adds 6 transactions from which 4 are filered out
|
||||
td, _, _ := fillTestData(t, db)
|
||||
td, _, _ := fillTestData(t, deps.db)
|
||||
|
||||
// Add extra transactions to test To address
|
||||
trs, _, _ := transfer.GenerateTestTransfers(t, db, td.nextIndex, 2)
|
||||
transfer.InsertTestTransfer(t, db, &trs[0])
|
||||
transfer.InsertTestPendingTransaction(t, db, &trs[1])
|
||||
trs, _, _ := transfer.GenerateTestTransfers(t, deps.db, td.nextIndex, 2)
|
||||
transfer.InsertTestTransfer(t, deps.db, &trs[0])
|
||||
transfer.InsertTestPendingTransaction(t, deps.db, &trs[1])
|
||||
|
||||
addresses := []eth_common.Address{td.tr1.From, td.pendingTr.From,
|
||||
td.multiTx1.FromAddress, td.multiTx2.ToAddress, trs[0].To, trs[1].To}
|
||||
|
||||
var filter Filter
|
||||
entries, err := getActivityEntries(context.Background(), db, addresses, []common.ChainID{}, filter, 0, 15)
|
||||
entries, err := getActivityEntries(context.Background(), deps, addresses, []common.ChainID{}, filter, 0, 15)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 6, len(entries))
|
||||
|
||||
|
@ -829,15 +875,15 @@ func TestGetActivityEntriesCheckToAndFrom(t *testing.T) {
|
|||
// TODO test sub-transaction count for multi-transactions
|
||||
|
||||
func TestGetActivityEntriesCheckContextCancellation(t *testing.T) {
|
||||
db, close := setupTestActivityDB(t)
|
||||
deps, close := setupTestActivityDB(t)
|
||||
defer close()
|
||||
|
||||
_, _, _ = fillTestData(t, db)
|
||||
_, _, _ = fillTestData(t, deps.db)
|
||||
|
||||
cancellableCtx, cancelFn := context.WithCancel(context.Background())
|
||||
cancelFn()
|
||||
|
||||
activities, err := getActivityEntries(cancellableCtx, db, []eth.Address{}, []common.ChainID{}, Filter{}, 0, 10)
|
||||
activities, err := getActivityEntries(cancellableCtx, deps, []eth.Address{}, []common.ChainID{}, Filter{}, 0, 10)
|
||||
require.ErrorIs(t, err, context.Canceled)
|
||||
require.Equal(t, 0, len(activities))
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"database/sql"
|
||||
|
||||
eth "github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/status-im/status-go/services/wallet/common"
|
||||
)
|
||||
|
||||
|
@ -45,28 +46,25 @@ func allActivityStatusesFilter() []Status {
|
|||
type TokenType int
|
||||
|
||||
const (
|
||||
AssetTT TokenType = iota
|
||||
CollectiblesTT
|
||||
Native TokenType = iota
|
||||
Erc20
|
||||
Erc721
|
||||
Erc1155
|
||||
)
|
||||
|
||||
type TokenCode string
|
||||
type TokenID *hexutil.Big
|
||||
|
||||
// Tokens the following rules apply for its members:
|
||||
// empty member: none is selected
|
||||
// nil means all
|
||||
// see allTokensFilter and noTokensFilter
|
||||
type Tokens struct {
|
||||
Assets []TokenCode `json:"assets"`
|
||||
Collectibles []eth.Address `json:"collectibles"`
|
||||
EnabledTypes []TokenType `json:"enabledTypes"`
|
||||
// Token supports all tokens. Some fields might be optional, depending on the TokenType
|
||||
type Token struct {
|
||||
TokenType TokenType `json:"tokenType"`
|
||||
// ChainID is used for TokenType.Native only to lookup the symbol, all chains will be included in the token filter
|
||||
ChainID common.ChainID `json:"chainId"`
|
||||
Address eth.Address `json:"address,omitempty"`
|
||||
TokenID TokenID `json:"tokenId,omitempty"`
|
||||
}
|
||||
|
||||
func noAssetsFilter() Tokens {
|
||||
return Tokens{[]TokenCode{}, []eth.Address{}, []TokenType{CollectiblesTT}}
|
||||
}
|
||||
|
||||
func allTokensFilter() Tokens {
|
||||
return Tokens{}
|
||||
func allTokensFilter() []Token {
|
||||
return []Token{}
|
||||
}
|
||||
|
||||
func allAddressesFilter() []eth.Address {
|
||||
|
@ -81,8 +79,13 @@ type Filter struct {
|
|||
Period Period `json:"period"`
|
||||
Types []Type `json:"types"`
|
||||
Statuses []Status `json:"statuses"`
|
||||
Tokens Tokens `json:"tokens"`
|
||||
CounterpartyAddresses []eth.Address `json:"counterpartyAddresses"`
|
||||
|
||||
// Tokens
|
||||
Assets []Token `json:"assets"`
|
||||
Collectibles []Token `json:"collectibles"`
|
||||
FilterOutAssets bool `json:"filterOutAssets"`
|
||||
FilterOutCollectibles bool `json:"filterOutCollectibles"`
|
||||
}
|
||||
|
||||
// TODO: consider sorting by saved address and contacts to offload the client from doing it at runtime
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/log"
|
||||
|
||||
w_common "github.com/status-im/status-go/services/wallet/common"
|
||||
"github.com/status-im/status-go/services/wallet/token"
|
||||
"github.com/status-im/status-go/services/wallet/walletevent"
|
||||
)
|
||||
|
||||
|
@ -22,19 +23,21 @@ const (
|
|||
)
|
||||
|
||||
type Service struct {
|
||||
db *sql.DB
|
||||
eventFeed *event.Feed
|
||||
db *sql.DB
|
||||
tokenManager *token.Manager
|
||||
eventFeed *event.Feed
|
||||
|
||||
context context.Context
|
||||
cancelFn context.CancelFunc
|
||||
wg sync.WaitGroup
|
||||
mu sync.Mutex
|
||||
context context.Context
|
||||
cancelFn context.CancelFunc
|
||||
wg sync.WaitGroup
|
||||
cancelMutex sync.Mutex
|
||||
}
|
||||
|
||||
func NewService(db *sql.DB, eventFeed *event.Feed) *Service {
|
||||
func NewService(db *sql.DB, tokenManager *token.Manager, eventFeed *event.Feed) *Service {
|
||||
return &Service{
|
||||
db: db,
|
||||
eventFeed: eventFeed,
|
||||
db: db,
|
||||
tokenManager: tokenManager,
|
||||
eventFeed: eventFeed,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,12 +62,13 @@ type FilterResponse struct {
|
|||
// and it cancels the current one if a new one is started
|
||||
// All calls will trigger an EventActivityFilteringDone event with the result of the filtering
|
||||
func (s *Service) FilterActivityAsync(ctx context.Context, addresses []common.Address, chainIDs []w_common.ChainID, filter Filter, offset int, limit int) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.cancelMutex.Lock()
|
||||
defer s.cancelMutex.Unlock()
|
||||
|
||||
// If a previous task is running, cancel it and wait to finish
|
||||
if s.cancelFn != nil {
|
||||
s.cancelFn()
|
||||
s.cancelFn = nil
|
||||
s.wg.Wait()
|
||||
}
|
||||
|
||||
|
@ -73,16 +77,17 @@ func (s *Service) FilterActivityAsync(ctx context.Context, addresses []common.Ad
|
|||
}
|
||||
|
||||
s.context, s.cancelFn = context.WithCancel(context.Background())
|
||||
thisCancelFn := s.cancelFn
|
||||
|
||||
s.wg.Add(1)
|
||||
|
||||
go func() {
|
||||
defer s.wg.Done()
|
||||
defer func() {
|
||||
s.cancelFn = nil
|
||||
}()
|
||||
activities, err := getActivityEntries(s.context, s.getDeps(), addresses, chainIDs, filter, offset, limit)
|
||||
// Don't lock s.cancelMutex, it might have been locked already
|
||||
s.wg.Done()
|
||||
|
||||
activities, err := getActivityEntries(s.context, s.db, addresses, chainIDs, filter, offset, limit)
|
||||
// Release context resources
|
||||
thisCancelFn()
|
||||
|
||||
res := FilterResponse{
|
||||
ErrorCode: ErrorCodeFilterFailed,
|
||||
|
@ -104,8 +109,8 @@ func (s *Service) FilterActivityAsync(ctx context.Context, addresses []common.Ad
|
|||
}
|
||||
|
||||
func (s *Service) Stop() {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.cancelMutex.Lock()
|
||||
defer s.cancelMutex.Unlock()
|
||||
|
||||
// If a previous task is running, cancel it and wait to finish
|
||||
if s.cancelFn != nil {
|
||||
|
@ -115,12 +120,47 @@ func (s *Service) Stop() {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *Service) getDeps() FilterDependencies {
|
||||
return FilterDependencies{
|
||||
db: s.db,
|
||||
tokenSymbol: func(t Token) string {
|
||||
info := s.tokenManager.LookupTokenIdentity(uint64(t.ChainID), t.Address, t.TokenType == Native)
|
||||
if info == nil {
|
||||
return ""
|
||||
}
|
||||
return info.Symbol
|
||||
},
|
||||
tokenFromSymbol: func(chainID *w_common.ChainID, symbol string) *Token {
|
||||
var cID *uint64
|
||||
if chainID != nil {
|
||||
cID = new(uint64)
|
||||
*cID = uint64(*chainID)
|
||||
}
|
||||
t, detectedNative := s.tokenManager.LookupToken(cID, symbol)
|
||||
if t == nil {
|
||||
return nil
|
||||
}
|
||||
tokenType := Native
|
||||
if !detectedNative {
|
||||
tokenType = Erc20
|
||||
}
|
||||
return &Token{
|
||||
TokenType: tokenType,
|
||||
ChainID: w_common.ChainID(t.ChainID),
|
||||
Address: t.Address,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) sendResponseEvent(response FilterResponse) {
|
||||
payload, err := json.Marshal(response)
|
||||
if err != nil {
|
||||
log.Error("Error marshaling response: %v", err)
|
||||
}
|
||||
|
||||
log.Debug("wallet.api.FilterActivityAsync RESPONSE", "activities.len", len(response.Activities), "offset", response.Offset, "hasMore", response.HasMore, "error", response.ErrorCode)
|
||||
|
||||
s.eventFeed.Send(walletevent.Event{
|
||||
Type: EventActivityFilteringDone,
|
||||
Message: string(payload),
|
||||
|
|
|
@ -107,7 +107,7 @@ func (api *API) GetTransfersByAddressAndChainID(ctx context.Context, chainID uin
|
|||
}
|
||||
|
||||
func (api *API) GetTransfersForIdentities(ctx context.Context, identities []transfer.TransactionIdentity) ([]transfer.View, error) {
|
||||
log.Debug("[Wallet: GetTransfersForIdentities] count", len(identities))
|
||||
log.Debug("wallet.api.GetTransfersForIdentities", "identities.len", len(identities))
|
||||
|
||||
return api.s.transferController.GetTransfersForIdentities(ctx, identities)
|
||||
}
|
||||
|
@ -520,7 +520,7 @@ func (api *API) CreateMultiTransaction(ctx context.Context, multiTransactionComm
|
|||
}
|
||||
|
||||
func (api *API) GetMultiTransactions(ctx context.Context, transactionIDs []transfer.MultiTransactionIDType) ([]*transfer.MultiTransaction, error) {
|
||||
log.Debug("[WalletAPI:: GetMultiTransactions] for IDs", transactionIDs)
|
||||
log.Debug("wallet.api.GetMultiTransactions", "IDs.len", len(transactionIDs))
|
||||
return api.s.transactionManager.GetMultiTransactions(ctx, transactionIDs)
|
||||
}
|
||||
|
||||
|
@ -535,7 +535,8 @@ func (api *API) FetchAllCurrencyFormats() (currency.FormatPerSymbol, error) {
|
|||
}
|
||||
|
||||
func (api *API) FilterActivityAsync(ctx context.Context, addresses []common.Address, chainIDs []wcommon.ChainID, filter activity.Filter, offset int, limit int) error {
|
||||
log.Debug("[WalletAPI:: FilterActivityAsync] addr.count", len(addresses), "chainIDs.count", len(chainIDs), "filter", filter, "offset", offset, "limit", limit)
|
||||
log.Debug("wallet.api.FilterActivityAsync", "addr.count", len(addresses), "chainIDs.count", len(chainIDs), "offset", offset, "limit", limit)
|
||||
|
||||
return api.s.activity.FilterActivityAsync(ctx, addresses, chainIDs, filter, offset, limit)
|
||||
}
|
||||
|
||||
|
@ -545,6 +546,7 @@ type GetAllRecipientsResponse struct {
|
|||
}
|
||||
|
||||
func (api *API) GetAllRecipients(ctx context.Context, offset int, limit int) (result *GetAllRecipientsResponse, err error) {
|
||||
log.Debug("wallet.api.GetAllRecipients", "offset", offset, "limit", limit)
|
||||
result = &GetAllRecipientsResponse{}
|
||||
result.Addresses, result.HasMore, err = activity.GetRecipients(ctx, api.s.db, offset, limit)
|
||||
return result, err
|
||||
|
|
|
@ -95,7 +95,7 @@ func NewService(
|
|||
reader := NewReader(rpcClient, tokenManager, marketManager, accountsDB, NewPersistence(db), walletFeed)
|
||||
history := history.NewService(db, walletFeed, rpcClient, tokenManager, marketManager)
|
||||
currency := currency.NewService(db, walletFeed, tokenManager, marketManager)
|
||||
activity := activity.NewService(db, walletFeed)
|
||||
activity := activity.NewService(db, tokenManager, walletFeed)
|
||||
|
||||
alchemyClient := alchemy.NewClient(config.WalletConfig.AlchemyAPIKeys)
|
||||
infuraClient := infura.NewClient(config.WalletConfig.InfuraAPIKey, config.WalletConfig.InfuraAPIKeySecret)
|
||||
|
|
|
@ -6,6 +6,14 @@ const EthSymbol = "ETH"
|
|||
const SntSymbol = "SNT"
|
||||
const DaiSymbol = "DAI"
|
||||
|
||||
func SliceContains[T comparable](slice []T, value T) bool {
|
||||
for _, v := range slice {
|
||||
if v == value {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
func StructExistsInSlice[T any](target T, slice []T) bool {
|
||||
for _, item := range slice {
|
||||
if reflect.DeepEqual(target, item) {
|
||||
|
|
|
@ -163,7 +163,38 @@ func (tm *Manager) FindToken(network *params.Network, tokenSymbol string) *Token
|
|||
return tm.ToToken(network)
|
||||
}
|
||||
|
||||
allTokens := tm.getFullTokenList(network.ChainID)
|
||||
return tm.GetToken(network.ChainID, tokenSymbol)
|
||||
}
|
||||
|
||||
func (tm *Manager) LookupToken(chainID *uint64, tokenSymbol string) (token *Token, isNative bool) {
|
||||
if chainID == nil {
|
||||
networks, err := tm.networkManager.Get(true)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
for _, network := range networks {
|
||||
if tokenSymbol == network.NativeCurrencySymbol {
|
||||
return tm.ToToken(network), true
|
||||
}
|
||||
token := tm.GetToken(network.ChainID, tokenSymbol)
|
||||
if token != nil {
|
||||
return token, false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
network := tm.networkManager.Find(*chainID)
|
||||
if tokenSymbol == network.NativeCurrencySymbol {
|
||||
return tm.ToToken(network), true
|
||||
}
|
||||
return tm.GetToken(*chainID, tokenSymbol), false
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// GetToken returns token by chainID and tokenSymbol. Use ToToken for native token
|
||||
func (tm *Manager) GetToken(chainID uint64, tokenSymbol string) *Token {
|
||||
allTokens := tm.getFullTokenList(chainID)
|
||||
for _, token := range allTokens {
|
||||
if token.Symbol == tokenSymbol {
|
||||
return token
|
||||
|
@ -172,6 +203,15 @@ func (tm *Manager) FindToken(network *params.Network, tokenSymbol string) *Token
|
|||
return nil
|
||||
}
|
||||
|
||||
func (tm *Manager) LookupTokenIdentity(chainID uint64, address common.Address, native bool) *Token {
|
||||
network := tm.networkManager.Find(chainID)
|
||||
if native {
|
||||
return tm.ToToken(network)
|
||||
}
|
||||
|
||||
return tm.FindTokenByAddress(chainID, address)
|
||||
}
|
||||
|
||||
func (tm *Manager) FindTokenByAddress(chainID uint64, address common.Address) *Token {
|
||||
allTokens := tm.getFullTokenList(chainID)
|
||||
for _, token := range allTokens {
|
||||
|
|
|
@ -280,7 +280,6 @@ func (db *Database) GetTransfersForIdentities(ctx context.Context, identities []
|
|||
query := newTransfersQuery()
|
||||
for _, identity := range identities {
|
||||
subQuery := newSubQuery()
|
||||
// TODO optimization: consider using tuples in sqlite and IN operator
|
||||
subQuery = subQuery.FilterNetwork(uint64(identity.ChainID)).FilterTransactionHash(identity.Hash).FilterAddress(identity.Address)
|
||||
query.addSubQuery(subQuery, OrSeparator)
|
||||
}
|
||||
|
@ -450,12 +449,17 @@ func updateOrInsertTransfers(chainID uint64, creator statementCreator, transfers
|
|||
var txGasPrice, txGasTipCap, txGasFeeCap *int64
|
||||
var txType *uint8
|
||||
var txValue *string
|
||||
var tokenAddress *common.Address
|
||||
var dbAddress *string
|
||||
var tokenID *big.Int
|
||||
if t.Transaction != nil {
|
||||
var value *big.Int
|
||||
if t.Log != nil {
|
||||
var tokenAddress *common.Address
|
||||
_, tokenAddress, tokenID, value = w_common.ExtractTokenIdentity(t.Type, t.Log, t.Transaction)
|
||||
if tokenAddress != nil {
|
||||
dbAddress = new(string)
|
||||
*dbAddress = tokenAddress.Hex()
|
||||
}
|
||||
} else {
|
||||
value = new(big.Int).Set(t.Transaction.Value())
|
||||
}
|
||||
|
@ -478,7 +482,7 @@ func updateOrInsertTransfers(chainID uint64, creator statementCreator, transfers
|
|||
|
||||
_, err = insert.Exec(chainID, t.ID, t.BlockHash, (*bigint.SQLBigInt)(t.BlockNumber), t.Timestamp, t.Address, &JSONBlob{t.Transaction}, t.From, &JSONBlob{t.Receipt}, &JSONBlob{t.Log}, t.Type, t.BaseGasFees, t.MultiTransactionID,
|
||||
receiptStatus, receiptType, txHash, logIndex, blockHash, cumulativeGasUsed, contractAddress, gasUsed, transactionIndex,
|
||||
txType, txProtected, txGas, txGasPrice, txGasTipCap, txGasFeeCap, txValue, txNonce, txSize, &sqlite.JSONBlob{Data: tokenAddress}, (*bigint.SQLBigIntBytes)(tokenID))
|
||||
txType, txProtected, txGas, txGasPrice, txGasTipCap, txGasFeeCap, txValue, txNonce, txSize, dbAddress, (*bigint.SQLBigIntBytes)(tokenID))
|
||||
if err != nil {
|
||||
log.Error("can't save transfer", "b-hash", t.BlockHash, "b-n", t.BlockNumber, "a", t.Address, "h", t.ID)
|
||||
return err
|
||||
|
|
|
@ -4,13 +4,13 @@ import (
|
|||
"database/sql"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
eth_common "github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/status-im/status-go/services/wallet/common"
|
||||
"github.com/status-im/status-go/services/wallet/testutils"
|
||||
"github.com/status-im/status-go/services/wallet/token"
|
||||
"github.com/status-im/status-go/sqlite"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -29,8 +29,8 @@ type TestTransaction struct {
|
|||
type TestTransfer struct {
|
||||
TestTransaction
|
||||
To eth_common.Address // [address]
|
||||
Token string // used to detect type in transfers table
|
||||
Value int64
|
||||
Token *token.Token
|
||||
}
|
||||
|
||||
type TestMultiTransaction struct {
|
||||
|
@ -45,10 +45,26 @@ type TestMultiTransaction struct {
|
|||
Timestamp int64
|
||||
}
|
||||
|
||||
func SeedToToken(seed int) *token.Token {
|
||||
tokenIndex := seed % len(TestTokens)
|
||||
return TestTokens[tokenIndex]
|
||||
}
|
||||
|
||||
func TestTrToToken(t *testing.T, tt *TestTransaction) (token *token.Token, isNative bool) {
|
||||
// Sanity check that none of the markers changed and they should be equal to seed
|
||||
require.Equal(t, tt.Timestamp, tt.BlkNumber)
|
||||
|
||||
tokenIndex := int(tt.Timestamp) % len(TestTokens)
|
||||
isNative = testutils.SliceContains(NativeTokenIndices, tokenIndex)
|
||||
|
||||
return TestTokens[tokenIndex], isNative
|
||||
}
|
||||
|
||||
func generateTestTransaction(seed int) TestTransaction {
|
||||
token := SeedToToken(seed)
|
||||
return TestTransaction{
|
||||
Hash: eth_common.HexToHash(fmt.Sprintf("0x1%d", seed)),
|
||||
ChainID: common.ChainID(seed),
|
||||
ChainID: common.ChainID(token.ChainID),
|
||||
From: eth_common.HexToAddress(fmt.Sprintf("0x2%d", seed)),
|
||||
Timestamp: int64(seed),
|
||||
BlkNumber: int64(seed),
|
||||
|
@ -58,11 +74,13 @@ func generateTestTransaction(seed int) TestTransaction {
|
|||
}
|
||||
|
||||
func generateTestTransfer(seed int) TestTransfer {
|
||||
tokenIndex := seed % len(TestTokens)
|
||||
token := TestTokens[tokenIndex]
|
||||
return TestTransfer{
|
||||
TestTransaction: generateTestTransaction(seed),
|
||||
Token: "",
|
||||
To: eth_common.HexToAddress(fmt.Sprintf("0x3%d", seed)),
|
||||
Value: int64(seed),
|
||||
Token: token,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,8 +89,8 @@ func GenerateTestSendMultiTransaction(tr TestTransfer) TestMultiTransaction {
|
|||
MultiTransactionType: MultiTransactionSend,
|
||||
FromAddress: tr.From,
|
||||
ToAddress: tr.To,
|
||||
FromToken: tr.Token,
|
||||
ToToken: tr.Token,
|
||||
FromToken: tr.Token.Symbol,
|
||||
ToToken: tr.Token.Symbol,
|
||||
FromAmount: tr.Value,
|
||||
ToAmount: 0,
|
||||
Timestamp: tr.Timestamp,
|
||||
|
@ -84,7 +102,7 @@ func GenerateTestSwapMultiTransaction(tr TestTransfer, toToken string, toAmount
|
|||
MultiTransactionType: MultiTransactionSwap,
|
||||
FromAddress: tr.From,
|
||||
ToAddress: tr.To,
|
||||
FromToken: tr.Token,
|
||||
FromToken: tr.Token.Symbol,
|
||||
ToToken: toToken,
|
||||
FromAmount: tr.Value,
|
||||
ToAmount: toAmount,
|
||||
|
@ -97,14 +115,16 @@ func GenerateTestBridgeMultiTransaction(fromTr, toTr TestTransfer) TestMultiTran
|
|||
MultiTransactionType: MultiTransactionBridge,
|
||||
FromAddress: fromTr.From,
|
||||
ToAddress: toTr.To,
|
||||
FromToken: fromTr.Token,
|
||||
ToToken: toTr.Token,
|
||||
FromToken: fromTr.Token.Symbol,
|
||||
ToToken: toTr.Token.Symbol,
|
||||
FromAmount: fromTr.Value,
|
||||
ToAmount: toTr.Value,
|
||||
Timestamp: fromTr.Timestamp,
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateTestTransfers will generate transaction based on the TestTokens index and roll over if there are more than
|
||||
// len(TestTokens) transactions
|
||||
func GenerateTestTransfers(t *testing.T, db *sql.DB, firstStartIndex int, count int) (result []TestTransfer, fromAddresses, toAddresses []eth_common.Address) {
|
||||
for i := firstStartIndex; i < (firstStartIndex + count); i++ {
|
||||
tr := generateTestTransfer(i)
|
||||
|
@ -115,12 +135,88 @@ func GenerateTestTransfers(t *testing.T, db *sql.DB, firstStartIndex int, count
|
|||
return
|
||||
}
|
||||
|
||||
var EthMainnet = token.Token{
|
||||
Address: eth_common.HexToAddress("0x"),
|
||||
Name: "Ether",
|
||||
Symbol: "ETH",
|
||||
ChainID: 1,
|
||||
}
|
||||
|
||||
var EthGoerli = token.Token{
|
||||
Address: eth_common.HexToAddress("0x"),
|
||||
Name: "Ether",
|
||||
Symbol: "ETH",
|
||||
ChainID: 5,
|
||||
}
|
||||
|
||||
var EthOptimism = token.Token{
|
||||
Address: eth_common.HexToAddress("0x"),
|
||||
Name: "Ether",
|
||||
Symbol: "ETH",
|
||||
ChainID: 10,
|
||||
}
|
||||
|
||||
var UsdcMainnet = token.Token{
|
||||
Address: eth_common.HexToAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"),
|
||||
Name: "USD Coin",
|
||||
Symbol: "USDC",
|
||||
ChainID: 1,
|
||||
}
|
||||
|
||||
var UsdcGoerli = token.Token{
|
||||
Address: eth_common.HexToAddress("0x98339d8c260052b7ad81c28c16c0b98420f2b46a"),
|
||||
Name: "USD Coin",
|
||||
Symbol: "USDC",
|
||||
ChainID: 5,
|
||||
}
|
||||
|
||||
var UsdcOptimism = token.Token{
|
||||
Address: eth_common.HexToAddress("0x7f5c764cbc14f9669b88837ca1490cca17c31607"),
|
||||
Name: "USD Coin",
|
||||
Symbol: "USDC",
|
||||
ChainID: 10,
|
||||
}
|
||||
|
||||
var SntMainnet = token.Token{
|
||||
Address: eth_common.HexToAddress("0x744d70fdbe2ba4cf95131626614a1763df805b9e"),
|
||||
Name: "Status Network Token",
|
||||
Symbol: "SNT",
|
||||
ChainID: 1,
|
||||
}
|
||||
|
||||
var DaiMainnet = token.Token{
|
||||
Address: eth_common.HexToAddress("0xf2edF1c091f683E3fb452497d9a98A49cBA84666"),
|
||||
Name: "DAI Stablecoin",
|
||||
Symbol: "DAI",
|
||||
ChainID: 5,
|
||||
}
|
||||
|
||||
var DaiGoerli = token.Token{
|
||||
Address: eth_common.HexToAddress("0xf2edF1c091f683E3fb452497d9a98A49cBA84666"),
|
||||
Name: "DAI Stablecoin",
|
||||
Symbol: "DAI",
|
||||
ChainID: 5,
|
||||
}
|
||||
|
||||
// TestTokens contains ETH/Mainnet, ETH/Goerli, ETH/Optimism, USDC/Mainnet, USDC/Goerli, USDC/Optimism, SNT/Mainnet, DAI/Mainnet, DAI/Goerli
|
||||
var TestTokens = []*token.Token{
|
||||
&EthMainnet, &EthGoerli, &EthOptimism, &UsdcMainnet, &UsdcGoerli, &UsdcOptimism, &SntMainnet, &DaiMainnet, &DaiGoerli,
|
||||
}
|
||||
|
||||
var NativeTokenIndices = []int{0, 1, 2}
|
||||
|
||||
func InsertTestTransfer(t *testing.T, db *sql.DB, tr *TestTransfer) {
|
||||
// Respect `FOREIGN KEY(network_id,address,blk_hash)` of `transfers` table
|
||||
token := TestTokens[int(tr.Timestamp)%len(TestTokens)]
|
||||
InsertTestTransferWithToken(t, db, tr, token.Address)
|
||||
}
|
||||
|
||||
func InsertTestTransferWithToken(t *testing.T, db *sql.DB, tr *TestTransfer, tokenAddress eth_common.Address) {
|
||||
tokenType := "eth"
|
||||
if tr.Token != "" && strings.ToUpper(tr.Token) != testutils.EthSymbol {
|
||||
if (tokenAddress != eth_common.Address{}) {
|
||||
tokenType = "erc20"
|
||||
}
|
||||
|
||||
// Respect `FOREIGN KEY(network_id,address,blk_hash)` of `transfers` table
|
||||
blkHash := eth_common.HexToHash("4")
|
||||
value := sqlite.Int64ToPadded128BitsStr(tr.Value)
|
||||
|
||||
|
@ -130,10 +226,10 @@ func InsertTestTransfer(t *testing.T, db *sql.DB, tr *TestTransfer) {
|
|||
) VALUES (?, ?, ?, ?);
|
||||
INSERT INTO transfers (network_id, hash, address, blk_hash, tx,
|
||||
sender, receipt, log, type, blk_number, timestamp, loaded,
|
||||
multi_transaction_id, base_gas_fee, status, amount_padded128hex
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?, 0, ?, ?)`,
|
||||
multi_transaction_id, base_gas_fee, status, amount_padded128hex, token_address
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?, 0, ?, ?, ?)`,
|
||||
tr.ChainID, tr.To, tr.BlkNumber, blkHash,
|
||||
tr.ChainID, tr.Hash, tr.To, blkHash, &JSONBlob{}, tr.From, &JSONBlob{}, &JSONBlob{}, tokenType, tr.BlkNumber, tr.Timestamp, tr.MultiTransactionID, tr.Success, value)
|
||||
tr.ChainID, tr.Hash, tr.To, blkHash, &JSONBlob{}, tr.From, &JSONBlob{}, &JSONBlob{}, tokenType, tr.BlkNumber, tr.Timestamp, tr.MultiTransactionID, tr.Success, value, tokenAddress.Hex())
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue