commit 9e281897ba3714fa69fa2d34e4d26b30e28a6751 Author: Prad N Date: Sun Jun 8 14:42:09 2025 +0800 feat: implement activity tracking with database models and queries diff --git a/README.md b/README.md new file mode 100644 index 0000000..edf1b21 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# dbx + +## Usage + +```sh +go run . +``` + +## Development + +### Generate + +```sh +task gen:sqlc +``` + +### Run + +```sh +task +``` diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 0000000..c2030a3 --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,25 @@ +# yaml-language-server: $schema=https://taskfile.dev/schema.json +version: "3" +silent: true +vars: + GIT_ROOT: + sh: git rev-parse --show-toplevel + +tasks: + default: + cmds: + - go mod tidy + - task -l --json | jq -r '.tasks[].name' | fzf --tmux | xargs task + + gen:templ: + aliases: [templ] + desc: Templ Generate + cmds: + - templ generate + + gen:sqlc: + aliases: [sqlc] + desc: Sqlc Generate + cmds: + - sqlc generate + diff --git a/activity/db.go b/activity/db.go new file mode 100644 index 0000000..3562a94 --- /dev/null +++ b/activity/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 + +package activity + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/activity/models.go b/activity/models.go new file mode 100644 index 0000000..7e6f06d --- /dev/null +++ b/activity/models.go @@ -0,0 +1,99 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 + +package activity + +import ( + "database/sql" + "time" +) + +type Activity struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt sql.NullTime `json:"deleted_at"` + AccountID string `json:"account_id"` + TxHash sql.NullString `json:"tx_hash"` + TxType string `json:"tx_type"` + Status string `json:"status"` + Amount sql.NullString `json:"amount"` + Fee sql.NullString `json:"fee"` + GasUsed sql.NullInt64 `json:"gas_used"` + GasWanted sql.NullInt64 `json:"gas_wanted"` + Memo sql.NullString `json:"memo"` + BlockHeight sql.NullInt64 `json:"block_height"` + Timestamp time.Time `json:"timestamp"` + RawLog sql.NullString `json:"raw_log"` + Error sql.NullString `json:"error"` +} + +type CryptoListing struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt sql.NullTime `json:"deleted_at"` + ApiID string `json:"api_id"` + Name string `json:"name"` + Symbol string `json:"symbol"` + WebsiteSlug string `json:"website_slug"` +} + +type FearGreedIndex struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt sql.NullTime `json:"deleted_at"` + Value int64 `json:"value"` + ValueClassification string `json:"value_classification"` + Timestamp time.Time `json:"timestamp"` + TimeUntilUpdate sql.NullString `json:"time_until_update"` +} + +type GlobalMarket struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt sql.NullTime `json:"deleted_at"` + TotalMarketCapUsd sql.NullFloat64 `json:"total_market_cap_usd"` + Total24hVolumeUsd sql.NullFloat64 `json:"total_24h_volume_usd"` + BitcoinPercentageOfMarketCap sql.NullFloat64 `json:"bitcoin_percentage_of_market_cap"` + ActiveCurrencies sql.NullInt64 `json:"active_currencies"` + ActiveAssets sql.NullInt64 `json:"active_assets"` + ActiveMarkets sql.NullInt64 `json:"active_markets"` + LastUpdated time.Time `json:"last_updated"` +} + +type Health struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt sql.NullTime `json:"deleted_at"` + EndpointUrl string `json:"endpoint_url"` + EndpointType string `json:"endpoint_type"` + ChainID sql.NullString `json:"chain_id"` + Status string `json:"status"` + ResponseTimeMs sql.NullInt64 `json:"response_time_ms"` + LastChecked time.Time `json:"last_checked"` + NextCheck sql.NullTime `json:"next_check"` + FailureCount int64 `json:"failure_count"` + SuccessCount int64 `json:"success_count"` + ResponseData sql.NullString `json:"response_data"` + ErrorMessage sql.NullString `json:"error_message"` +} + +type Service struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt sql.NullTime `json:"deleted_at"` + Name string `json:"name"` + Description sql.NullString `json:"description"` + ChainID string `json:"chain_id"` + Address string `json:"address"` + OwnerAddress string `json:"owner_address"` + Metadata sql.NullString `json:"metadata"` + Status string `json:"status"` + BlockHeight int64 `json:"block_height"` +} diff --git a/activity/querier.go b/activity/querier.go new file mode 100644 index 0000000..c281773 --- /dev/null +++ b/activity/querier.go @@ -0,0 +1,63 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 + +package activity + +import ( + "context" + "database/sql" +) + +type Querier interface { + GetActivityByID(ctx context.Context, id string) (Activity, error) + GetActivityByTxHash(ctx context.Context, txHash sql.NullString) (Activity, error) + GetCryptoListingByApiID(ctx context.Context, apiID string) (CryptoListing, error) + GetCryptoListingByID(ctx context.Context, id string) (CryptoListing, error) + GetCryptoListingBySymbol(ctx context.Context, symbol string) (CryptoListing, error) + GetCryptoListingByWebsiteSlug(ctx context.Context, websiteSlug string) (CryptoListing, error) + GetFearGreedIndexByID(ctx context.Context, id string) (FearGreedIndex, error) + GetGlobalMarketByID(ctx context.Context, id string) (GlobalMarket, error) + GetHealthByEndpoint(ctx context.Context, endpointUrl string) (Health, error) + GetHealthByID(ctx context.Context, id string) (Health, error) + GetLatestFearGreedIndex(ctx context.Context) (FearGreedIndex, error) + GetLatestGlobalMarket(ctx context.Context) (GlobalMarket, error) + GetServiceByAddress(ctx context.Context, address string) (Service, error) + GetServiceByChainAndAddress(ctx context.Context, arg GetServiceByChainAndAddressParams) (Service, error) + GetServiceByID(ctx context.Context, id string) (Service, error) + // ACTIVITY QUERIES + InsertActivity(ctx context.Context, arg InsertActivityParams) (Activity, error) + // CRYPTO LISTINGS QUERIES (NEW) + InsertCryptoListing(ctx context.Context, arg InsertCryptoListingParams) (CryptoListing, error) + // FEAR AND GREED INDEX QUERIES (NEW) + InsertFearGreedIndex(ctx context.Context, arg InsertFearGreedIndexParams) (FearGreedIndex, error) + InsertGlobalMarket(ctx context.Context, arg InsertGlobalMarketParams) (GlobalMarket, error) + // HEALTH QUERIES + InsertHealth(ctx context.Context, arg InsertHealthParams) (Health, error) + InsertService(ctx context.Context, arg InsertServiceParams) (Service, error) + ListActivitiesByAccount(ctx context.Context, arg ListActivitiesByAccountParams) ([]Activity, error) + ListActivitiesByStatus(ctx context.Context, arg ListActivitiesByStatusParams) ([]Activity, error) + ListActivitiesByType(ctx context.Context, arg ListActivitiesByTypeParams) ([]Activity, error) + ListCryptoListings(ctx context.Context, arg ListCryptoListingsParams) ([]CryptoListing, error) + ListFearGreedIndexHistory(ctx context.Context, arg ListFearGreedIndexHistoryParams) ([]FearGreedIndex, error) + ListGlobalMarketHistory(ctx context.Context, arg ListGlobalMarketHistoryParams) ([]GlobalMarket, error) + ListHealthByChain(ctx context.Context, arg ListHealthByChainParams) ([]Health, error) + ListHealthByStatus(ctx context.Context, arg ListHealthByStatusParams) ([]Health, error) + ListHealthChecksNeedingUpdate(ctx context.Context, limit int64) ([]Health, error) + ListServicesByChain(ctx context.Context, arg ListServicesByChainParams) ([]Service, error) + ListServicesByOwner(ctx context.Context, arg ListServicesByOwnerParams) ([]Service, error) + SoftDeleteActivity(ctx context.Context, id string) error + SoftDeleteCryptoListing(ctx context.Context, id string) error + SoftDeleteFearGreedIndex(ctx context.Context, id string) error + SoftDeleteGlobalMarket(ctx context.Context, id string) error + SoftDeleteHealth(ctx context.Context, id string) error + SoftDeleteService(ctx context.Context, id string) error + UpdateActivityStatus(ctx context.Context, arg UpdateActivityStatusParams) (Activity, error) + UpdateCryptoListing(ctx context.Context, arg UpdateCryptoListingParams) (CryptoListing, error) + UpdateFearGreedIndex(ctx context.Context, arg UpdateFearGreedIndexParams) (FearGreedIndex, error) + UpdateGlobalMarket(ctx context.Context, arg UpdateGlobalMarketParams) (GlobalMarket, error) + UpdateHealthCheck(ctx context.Context, arg UpdateHealthCheckParams) (Health, error) + UpdateService(ctx context.Context, arg UpdateServiceParams) (Service, error) +} + +var _ Querier = (*Queries)(nil) diff --git a/activity/query.sql.go b/activity/query.sql.go new file mode 100644 index 0000000..dd11bc3 --- /dev/null +++ b/activity/query.sql.go @@ -0,0 +1,1640 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 +// source: query.sql + +package activity + +import ( + "context" + "database/sql" + "time" +) + +const getActivityByID = `-- name: GetActivityByID :one +SELECT id, created_at, updated_at, deleted_at, account_id, tx_hash, tx_type, status, amount, fee, gas_used, gas_wanted, memo, block_height, timestamp, raw_log, error FROM activities +WHERE id = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetActivityByID(ctx context.Context, id string) (Activity, error) { + row := q.db.QueryRowContext(ctx, getActivityByID, id) + var i Activity + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.AccountID, + &i.TxHash, + &i.TxType, + &i.Status, + &i.Amount, + &i.Fee, + &i.GasUsed, + &i.GasWanted, + &i.Memo, + &i.BlockHeight, + &i.Timestamp, + &i.RawLog, + &i.Error, + ) + return i, err +} + +const getActivityByTxHash = `-- name: GetActivityByTxHash :one +SELECT id, created_at, updated_at, deleted_at, account_id, tx_hash, tx_type, status, amount, fee, gas_used, gas_wanted, memo, block_height, timestamp, raw_log, error FROM activities +WHERE tx_hash = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetActivityByTxHash(ctx context.Context, txHash sql.NullString) (Activity, error) { + row := q.db.QueryRowContext(ctx, getActivityByTxHash, txHash) + var i Activity + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.AccountID, + &i.TxHash, + &i.TxType, + &i.Status, + &i.Amount, + &i.Fee, + &i.GasUsed, + &i.GasWanted, + &i.Memo, + &i.BlockHeight, + &i.Timestamp, + &i.RawLog, + &i.Error, + ) + return i, err +} + +const getCryptoListingByApiID = `-- name: GetCryptoListingByApiID :one +SELECT id, created_at, updated_at, deleted_at, api_id, name, symbol, website_slug FROM crypto_listings +WHERE api_id = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetCryptoListingByApiID(ctx context.Context, apiID string) (CryptoListing, error) { + row := q.db.QueryRowContext(ctx, getCryptoListingByApiID, apiID) + var i CryptoListing + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ApiID, + &i.Name, + &i.Symbol, + &i.WebsiteSlug, + ) + return i, err +} + +const getCryptoListingByID = `-- name: GetCryptoListingByID :one +SELECT id, created_at, updated_at, deleted_at, api_id, name, symbol, website_slug FROM crypto_listings +WHERE id = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetCryptoListingByID(ctx context.Context, id string) (CryptoListing, error) { + row := q.db.QueryRowContext(ctx, getCryptoListingByID, id) + var i CryptoListing + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ApiID, + &i.Name, + &i.Symbol, + &i.WebsiteSlug, + ) + return i, err +} + +const getCryptoListingBySymbol = `-- name: GetCryptoListingBySymbol :one +SELECT id, created_at, updated_at, deleted_at, api_id, name, symbol, website_slug FROM crypto_listings +WHERE symbol = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetCryptoListingBySymbol(ctx context.Context, symbol string) (CryptoListing, error) { + row := q.db.QueryRowContext(ctx, getCryptoListingBySymbol, symbol) + var i CryptoListing + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ApiID, + &i.Name, + &i.Symbol, + &i.WebsiteSlug, + ) + return i, err +} + +const getCryptoListingByWebsiteSlug = `-- name: GetCryptoListingByWebsiteSlug :one +SELECT id, created_at, updated_at, deleted_at, api_id, name, symbol, website_slug FROM crypto_listings +WHERE website_slug = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetCryptoListingByWebsiteSlug(ctx context.Context, websiteSlug string) (CryptoListing, error) { + row := q.db.QueryRowContext(ctx, getCryptoListingByWebsiteSlug, websiteSlug) + var i CryptoListing + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ApiID, + &i.Name, + &i.Symbol, + &i.WebsiteSlug, + ) + return i, err +} + +const getFearGreedIndexByID = `-- name: GetFearGreedIndexByID :one +SELECT id, created_at, updated_at, deleted_at, value, value_classification, timestamp, time_until_update FROM fear_greed_index +WHERE id = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetFearGreedIndexByID(ctx context.Context, id string) (FearGreedIndex, error) { + row := q.db.QueryRowContext(ctx, getFearGreedIndexByID, id) + var i FearGreedIndex + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Value, + &i.ValueClassification, + &i.Timestamp, + &i.TimeUntilUpdate, + ) + return i, err +} + +const getGlobalMarketByID = `-- name: GetGlobalMarketByID :one +SELECT id, created_at, updated_at, deleted_at, total_market_cap_usd, total_24h_volume_usd, bitcoin_percentage_of_market_cap, active_currencies, active_assets, active_markets, last_updated FROM global_market +WHERE id = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetGlobalMarketByID(ctx context.Context, id string) (GlobalMarket, error) { + row := q.db.QueryRowContext(ctx, getGlobalMarketByID, id) + var i GlobalMarket + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.TotalMarketCapUsd, + &i.Total24hVolumeUsd, + &i.BitcoinPercentageOfMarketCap, + &i.ActiveCurrencies, + &i.ActiveAssets, + &i.ActiveMarkets, + &i.LastUpdated, + ) + return i, err +} + +const getHealthByEndpoint = `-- name: GetHealthByEndpoint :one +SELECT id, created_at, updated_at, deleted_at, endpoint_url, endpoint_type, chain_id, status, response_time_ms, last_checked, next_check, failure_count, success_count, response_data, error_message FROM health +WHERE endpoint_url = ? AND deleted_at IS NULL +ORDER BY last_checked DESC +LIMIT 1 +` + +func (q *Queries) GetHealthByEndpoint(ctx context.Context, endpointUrl string) (Health, error) { + row := q.db.QueryRowContext(ctx, getHealthByEndpoint, endpointUrl) + var i Health + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.EndpointUrl, + &i.EndpointType, + &i.ChainID, + &i.Status, + &i.ResponseTimeMs, + &i.LastChecked, + &i.NextCheck, + &i.FailureCount, + &i.SuccessCount, + &i.ResponseData, + &i.ErrorMessage, + ) + return i, err +} + +const getHealthByID = `-- name: GetHealthByID :one +SELECT id, created_at, updated_at, deleted_at, endpoint_url, endpoint_type, chain_id, status, response_time_ms, last_checked, next_check, failure_count, success_count, response_data, error_message FROM health +WHERE id = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetHealthByID(ctx context.Context, id string) (Health, error) { + row := q.db.QueryRowContext(ctx, getHealthByID, id) + var i Health + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.EndpointUrl, + &i.EndpointType, + &i.ChainID, + &i.Status, + &i.ResponseTimeMs, + &i.LastChecked, + &i.NextCheck, + &i.FailureCount, + &i.SuccessCount, + &i.ResponseData, + &i.ErrorMessage, + ) + return i, err +} + +const getLatestFearGreedIndex = `-- name: GetLatestFearGreedIndex :one +SELECT id, created_at, updated_at, deleted_at, value, value_classification, timestamp, time_until_update FROM fear_greed_index +WHERE deleted_at IS NULL +ORDER BY timestamp DESC +LIMIT 1 +` + +func (q *Queries) GetLatestFearGreedIndex(ctx context.Context) (FearGreedIndex, error) { + row := q.db.QueryRowContext(ctx, getLatestFearGreedIndex) + var i FearGreedIndex + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Value, + &i.ValueClassification, + &i.Timestamp, + &i.TimeUntilUpdate, + ) + return i, err +} + +const getLatestGlobalMarket = `-- name: GetLatestGlobalMarket :one +SELECT id, created_at, updated_at, deleted_at, total_market_cap_usd, total_24h_volume_usd, bitcoin_percentage_of_market_cap, active_currencies, active_assets, active_markets, last_updated FROM global_market +WHERE deleted_at IS NULL +ORDER BY last_updated DESC +LIMIT 1 +` + +func (q *Queries) GetLatestGlobalMarket(ctx context.Context) (GlobalMarket, error) { + row := q.db.QueryRowContext(ctx, getLatestGlobalMarket) + var i GlobalMarket + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.TotalMarketCapUsd, + &i.Total24hVolumeUsd, + &i.BitcoinPercentageOfMarketCap, + &i.ActiveCurrencies, + &i.ActiveAssets, + &i.ActiveMarkets, + &i.LastUpdated, + ) + return i, err +} + +const getServiceByAddress = `-- name: GetServiceByAddress :one +SELECT id, created_at, updated_at, deleted_at, name, description, chain_id, address, owner_address, metadata, status, block_height FROM services +WHERE address = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetServiceByAddress(ctx context.Context, address string) (Service, error) { + row := q.db.QueryRowContext(ctx, getServiceByAddress, address) + var i Service + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Name, + &i.Description, + &i.ChainID, + &i.Address, + &i.OwnerAddress, + &i.Metadata, + &i.Status, + &i.BlockHeight, + ) + return i, err +} + +const getServiceByChainAndAddress = `-- name: GetServiceByChainAndAddress :one +SELECT id, created_at, updated_at, deleted_at, name, description, chain_id, address, owner_address, metadata, status, block_height FROM services +WHERE chain_id = ? AND address = ? AND deleted_at IS NULL +LIMIT 1 +` + +type GetServiceByChainAndAddressParams struct { + ChainID string `json:"chain_id"` + Address string `json:"address"` +} + +func (q *Queries) GetServiceByChainAndAddress(ctx context.Context, arg GetServiceByChainAndAddressParams) (Service, error) { + row := q.db.QueryRowContext(ctx, getServiceByChainAndAddress, arg.ChainID, arg.Address) + var i Service + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Name, + &i.Description, + &i.ChainID, + &i.Address, + &i.OwnerAddress, + &i.Metadata, + &i.Status, + &i.BlockHeight, + ) + return i, err +} + +const getServiceByID = `-- name: GetServiceByID :one +SELECT id, created_at, updated_at, deleted_at, name, description, chain_id, address, owner_address, metadata, status, block_height FROM services +WHERE id = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetServiceByID(ctx context.Context, id string) (Service, error) { + row := q.db.QueryRowContext(ctx, getServiceByID, id) + var i Service + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Name, + &i.Description, + &i.ChainID, + &i.Address, + &i.OwnerAddress, + &i.Metadata, + &i.Status, + &i.BlockHeight, + ) + return i, err +} + +const insertActivity = `-- name: InsertActivity :one +INSERT INTO activities ( + account_id, + tx_hash, + tx_type, + status, + amount, + fee, + gas_used, + gas_wanted, + memo, + block_height, + timestamp, + raw_log, + error +) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) +RETURNING id, created_at, updated_at, deleted_at, account_id, tx_hash, tx_type, status, amount, fee, gas_used, gas_wanted, memo, block_height, timestamp, raw_log, error +` + +type InsertActivityParams struct { + AccountID string `json:"account_id"` + TxHash sql.NullString `json:"tx_hash"` + TxType string `json:"tx_type"` + Status string `json:"status"` + Amount sql.NullString `json:"amount"` + Fee sql.NullString `json:"fee"` + GasUsed sql.NullInt64 `json:"gas_used"` + GasWanted sql.NullInt64 `json:"gas_wanted"` + Memo sql.NullString `json:"memo"` + BlockHeight sql.NullInt64 `json:"block_height"` + Timestamp time.Time `json:"timestamp"` + RawLog sql.NullString `json:"raw_log"` + Error sql.NullString `json:"error"` +} + +// ACTIVITY QUERIES +func (q *Queries) InsertActivity(ctx context.Context, arg InsertActivityParams) (Activity, error) { + row := q.db.QueryRowContext(ctx, insertActivity, + arg.AccountID, + arg.TxHash, + arg.TxType, + arg.Status, + arg.Amount, + arg.Fee, + arg.GasUsed, + arg.GasWanted, + arg.Memo, + arg.BlockHeight, + arg.Timestamp, + arg.RawLog, + arg.Error, + ) + var i Activity + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.AccountID, + &i.TxHash, + &i.TxType, + &i.Status, + &i.Amount, + &i.Fee, + &i.GasUsed, + &i.GasWanted, + &i.Memo, + &i.BlockHeight, + &i.Timestamp, + &i.RawLog, + &i.Error, + ) + return i, err +} + +const insertCryptoListing = `-- name: InsertCryptoListing :one +INSERT INTO crypto_listings ( + api_id, + name, + symbol, + website_slug +) VALUES (?, ?, ?, ?) +RETURNING id, created_at, updated_at, deleted_at, api_id, name, symbol, website_slug +` + +type InsertCryptoListingParams struct { + ApiID string `json:"api_id"` + Name string `json:"name"` + Symbol string `json:"symbol"` + WebsiteSlug string `json:"website_slug"` +} + +// CRYPTO LISTINGS QUERIES (NEW) +func (q *Queries) InsertCryptoListing(ctx context.Context, arg InsertCryptoListingParams) (CryptoListing, error) { + row := q.db.QueryRowContext(ctx, insertCryptoListing, + arg.ApiID, + arg.Name, + arg.Symbol, + arg.WebsiteSlug, + ) + var i CryptoListing + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ApiID, + &i.Name, + &i.Symbol, + &i.WebsiteSlug, + ) + return i, err +} + +const insertFearGreedIndex = `-- name: InsertFearGreedIndex :one +INSERT INTO fear_greed_index ( + value, + value_classification, + timestamp, + time_until_update +) VALUES (?, ?, ?, ?) +RETURNING id, created_at, updated_at, deleted_at, value, value_classification, timestamp, time_until_update +` + +type InsertFearGreedIndexParams struct { + Value int64 `json:"value"` + ValueClassification string `json:"value_classification"` + Timestamp time.Time `json:"timestamp"` + TimeUntilUpdate sql.NullString `json:"time_until_update"` +} + +// FEAR AND GREED INDEX QUERIES (NEW) +func (q *Queries) InsertFearGreedIndex(ctx context.Context, arg InsertFearGreedIndexParams) (FearGreedIndex, error) { + row := q.db.QueryRowContext(ctx, insertFearGreedIndex, + arg.Value, + arg.ValueClassification, + arg.Timestamp, + arg.TimeUntilUpdate, + ) + var i FearGreedIndex + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Value, + &i.ValueClassification, + &i.Timestamp, + &i.TimeUntilUpdate, + ) + return i, err +} + +const insertGlobalMarket = `-- name: InsertGlobalMarket :one +INSERT INTO global_market ( + total_market_cap_usd, + total_24h_volume_usd, + bitcoin_percentage_of_market_cap, + active_currencies, + active_assets, + active_markets, + last_updated +) VALUES (?, ?, ?, ?, ?, ?, ?) +RETURNING id, created_at, updated_at, deleted_at, total_market_cap_usd, total_24h_volume_usd, bitcoin_percentage_of_market_cap, active_currencies, active_assets, active_markets, last_updated +` + +type InsertGlobalMarketParams struct { + TotalMarketCapUsd sql.NullFloat64 `json:"total_market_cap_usd"` + Total24hVolumeUsd sql.NullFloat64 `json:"total_24h_volume_usd"` + BitcoinPercentageOfMarketCap sql.NullFloat64 `json:"bitcoin_percentage_of_market_cap"` + ActiveCurrencies sql.NullInt64 `json:"active_currencies"` + ActiveAssets sql.NullInt64 `json:"active_assets"` + ActiveMarkets sql.NullInt64 `json:"active_markets"` + LastUpdated time.Time `json:"last_updated"` +} + +func (q *Queries) InsertGlobalMarket(ctx context.Context, arg InsertGlobalMarketParams) (GlobalMarket, error) { + row := q.db.QueryRowContext(ctx, insertGlobalMarket, + arg.TotalMarketCapUsd, + arg.Total24hVolumeUsd, + arg.BitcoinPercentageOfMarketCap, + arg.ActiveCurrencies, + arg.ActiveAssets, + arg.ActiveMarkets, + arg.LastUpdated, + ) + var i GlobalMarket + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.TotalMarketCapUsd, + &i.Total24hVolumeUsd, + &i.BitcoinPercentageOfMarketCap, + &i.ActiveCurrencies, + &i.ActiveAssets, + &i.ActiveMarkets, + &i.LastUpdated, + ) + return i, err +} + +const insertHealth = `-- name: InsertHealth :one +INSERT INTO health ( + endpoint_url, + endpoint_type, + chain_id, + status, + response_time_ms, + last_checked, + next_check, + failure_count, + success_count, + response_data, + error_message +) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) +RETURNING id, created_at, updated_at, deleted_at, endpoint_url, endpoint_type, chain_id, status, response_time_ms, last_checked, next_check, failure_count, success_count, response_data, error_message +` + +type InsertHealthParams struct { + EndpointUrl string `json:"endpoint_url"` + EndpointType string `json:"endpoint_type"` + ChainID sql.NullString `json:"chain_id"` + Status string `json:"status"` + ResponseTimeMs sql.NullInt64 `json:"response_time_ms"` + LastChecked time.Time `json:"last_checked"` + NextCheck sql.NullTime `json:"next_check"` + FailureCount int64 `json:"failure_count"` + SuccessCount int64 `json:"success_count"` + ResponseData sql.NullString `json:"response_data"` + ErrorMessage sql.NullString `json:"error_message"` +} + +// HEALTH QUERIES +func (q *Queries) InsertHealth(ctx context.Context, arg InsertHealthParams) (Health, error) { + row := q.db.QueryRowContext(ctx, insertHealth, + arg.EndpointUrl, + arg.EndpointType, + arg.ChainID, + arg.Status, + arg.ResponseTimeMs, + arg.LastChecked, + arg.NextCheck, + arg.FailureCount, + arg.SuccessCount, + arg.ResponseData, + arg.ErrorMessage, + ) + var i Health + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.EndpointUrl, + &i.EndpointType, + &i.ChainID, + &i.Status, + &i.ResponseTimeMs, + &i.LastChecked, + &i.NextCheck, + &i.FailureCount, + &i.SuccessCount, + &i.ResponseData, + &i.ErrorMessage, + ) + return i, err +} + +const insertService = `-- name: InsertService :one +INSERT INTO services ( + name, + description, + chain_id, + address, + owner_address, + metadata, + status, + block_height +) VALUES (?, ?, ?, ?, ?, ?, ?, ?) +RETURNING id, created_at, updated_at, deleted_at, name, description, chain_id, address, owner_address, metadata, status, block_height +` + +type InsertServiceParams struct { + Name string `json:"name"` + Description sql.NullString `json:"description"` + ChainID string `json:"chain_id"` + Address string `json:"address"` + OwnerAddress string `json:"owner_address"` + Metadata sql.NullString `json:"metadata"` + Status string `json:"status"` + BlockHeight int64 `json:"block_height"` +} + +func (q *Queries) InsertService(ctx context.Context, arg InsertServiceParams) (Service, error) { + row := q.db.QueryRowContext(ctx, insertService, + arg.Name, + arg.Description, + arg.ChainID, + arg.Address, + arg.OwnerAddress, + arg.Metadata, + arg.Status, + arg.BlockHeight, + ) + var i Service + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Name, + &i.Description, + &i.ChainID, + &i.Address, + &i.OwnerAddress, + &i.Metadata, + &i.Status, + &i.BlockHeight, + ) + return i, err +} + +const listActivitiesByAccount = `-- name: ListActivitiesByAccount :many +SELECT id, created_at, updated_at, deleted_at, account_id, tx_hash, tx_type, status, amount, fee, gas_used, gas_wanted, memo, block_height, timestamp, raw_log, error FROM activities +WHERE account_id = ? AND deleted_at IS NULL +ORDER BY timestamp DESC +LIMIT ? OFFSET ? +` + +type ListActivitiesByAccountParams struct { + AccountID string `json:"account_id"` + Limit int64 `json:"limit"` + Offset int64 `json:"offset"` +} + +func (q *Queries) ListActivitiesByAccount(ctx context.Context, arg ListActivitiesByAccountParams) ([]Activity, error) { + rows, err := q.db.QueryContext(ctx, listActivitiesByAccount, arg.AccountID, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Activity + for rows.Next() { + var i Activity + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.AccountID, + &i.TxHash, + &i.TxType, + &i.Status, + &i.Amount, + &i.Fee, + &i.GasUsed, + &i.GasWanted, + &i.Memo, + &i.BlockHeight, + &i.Timestamp, + &i.RawLog, + &i.Error, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listActivitiesByStatus = `-- name: ListActivitiesByStatus :many +SELECT id, created_at, updated_at, deleted_at, account_id, tx_hash, tx_type, status, amount, fee, gas_used, gas_wanted, memo, block_height, timestamp, raw_log, error FROM activities +WHERE status = ? AND deleted_at IS NULL +ORDER BY timestamp DESC +LIMIT ? OFFSET ? +` + +type ListActivitiesByStatusParams struct { + Status string `json:"status"` + Limit int64 `json:"limit"` + Offset int64 `json:"offset"` +} + +func (q *Queries) ListActivitiesByStatus(ctx context.Context, arg ListActivitiesByStatusParams) ([]Activity, error) { + rows, err := q.db.QueryContext(ctx, listActivitiesByStatus, arg.Status, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Activity + for rows.Next() { + var i Activity + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.AccountID, + &i.TxHash, + &i.TxType, + &i.Status, + &i.Amount, + &i.Fee, + &i.GasUsed, + &i.GasWanted, + &i.Memo, + &i.BlockHeight, + &i.Timestamp, + &i.RawLog, + &i.Error, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listActivitiesByType = `-- name: ListActivitiesByType :many +SELECT id, created_at, updated_at, deleted_at, account_id, tx_hash, tx_type, status, amount, fee, gas_used, gas_wanted, memo, block_height, timestamp, raw_log, error FROM activities +WHERE tx_type = ? AND deleted_at IS NULL +ORDER BY timestamp DESC +LIMIT ? OFFSET ? +` + +type ListActivitiesByTypeParams struct { + TxType string `json:"tx_type"` + Limit int64 `json:"limit"` + Offset int64 `json:"offset"` +} + +func (q *Queries) ListActivitiesByType(ctx context.Context, arg ListActivitiesByTypeParams) ([]Activity, error) { + rows, err := q.db.QueryContext(ctx, listActivitiesByType, arg.TxType, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Activity + for rows.Next() { + var i Activity + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.AccountID, + &i.TxHash, + &i.TxType, + &i.Status, + &i.Amount, + &i.Fee, + &i.GasUsed, + &i.GasWanted, + &i.Memo, + &i.BlockHeight, + &i.Timestamp, + &i.RawLog, + &i.Error, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listCryptoListings = `-- name: ListCryptoListings :many +SELECT id, created_at, updated_at, deleted_at, api_id, name, symbol, website_slug FROM crypto_listings +WHERE deleted_at IS NULL +ORDER BY name ASC +LIMIT ? OFFSET ? +` + +type ListCryptoListingsParams struct { + Limit int64 `json:"limit"` + Offset int64 `json:"offset"` +} + +func (q *Queries) ListCryptoListings(ctx context.Context, arg ListCryptoListingsParams) ([]CryptoListing, error) { + rows, err := q.db.QueryContext(ctx, listCryptoListings, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + var items []CryptoListing + for rows.Next() { + var i CryptoListing + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ApiID, + &i.Name, + &i.Symbol, + &i.WebsiteSlug, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listFearGreedIndexHistory = `-- name: ListFearGreedIndexHistory :many +SELECT id, created_at, updated_at, deleted_at, value, value_classification, timestamp, time_until_update FROM fear_greed_index +WHERE deleted_at IS NULL +ORDER BY timestamp DESC +LIMIT ? OFFSET ? +` + +type ListFearGreedIndexHistoryParams struct { + Limit int64 `json:"limit"` + Offset int64 `json:"offset"` +} + +func (q *Queries) ListFearGreedIndexHistory(ctx context.Context, arg ListFearGreedIndexHistoryParams) ([]FearGreedIndex, error) { + rows, err := q.db.QueryContext(ctx, listFearGreedIndexHistory, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + var items []FearGreedIndex + for rows.Next() { + var i FearGreedIndex + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Value, + &i.ValueClassification, + &i.Timestamp, + &i.TimeUntilUpdate, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listGlobalMarketHistory = `-- name: ListGlobalMarketHistory :many +SELECT id, created_at, updated_at, deleted_at, total_market_cap_usd, total_24h_volume_usd, bitcoin_percentage_of_market_cap, active_currencies, active_assets, active_markets, last_updated FROM global_market +WHERE deleted_at IS NULL +ORDER BY last_updated DESC +LIMIT ? OFFSET ? +` + +type ListGlobalMarketHistoryParams struct { + Limit int64 `json:"limit"` + Offset int64 `json:"offset"` +} + +func (q *Queries) ListGlobalMarketHistory(ctx context.Context, arg ListGlobalMarketHistoryParams) ([]GlobalMarket, error) { + rows, err := q.db.QueryContext(ctx, listGlobalMarketHistory, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GlobalMarket + for rows.Next() { + var i GlobalMarket + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.TotalMarketCapUsd, + &i.Total24hVolumeUsd, + &i.BitcoinPercentageOfMarketCap, + &i.ActiveCurrencies, + &i.ActiveAssets, + &i.ActiveMarkets, + &i.LastUpdated, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listHealthByChain = `-- name: ListHealthByChain :many +SELECT id, created_at, updated_at, deleted_at, endpoint_url, endpoint_type, chain_id, status, response_time_ms, last_checked, next_check, failure_count, success_count, response_data, error_message FROM health +WHERE chain_id = ? AND deleted_at IS NULL +ORDER BY last_checked DESC +LIMIT ? OFFSET ? +` + +type ListHealthByChainParams struct { + ChainID sql.NullString `json:"chain_id"` + Limit int64 `json:"limit"` + Offset int64 `json:"offset"` +} + +func (q *Queries) ListHealthByChain(ctx context.Context, arg ListHealthByChainParams) ([]Health, error) { + rows, err := q.db.QueryContext(ctx, listHealthByChain, arg.ChainID, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Health + for rows.Next() { + var i Health + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.EndpointUrl, + &i.EndpointType, + &i.ChainID, + &i.Status, + &i.ResponseTimeMs, + &i.LastChecked, + &i.NextCheck, + &i.FailureCount, + &i.SuccessCount, + &i.ResponseData, + &i.ErrorMessage, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listHealthByStatus = `-- name: ListHealthByStatus :many +SELECT id, created_at, updated_at, deleted_at, endpoint_url, endpoint_type, chain_id, status, response_time_ms, last_checked, next_check, failure_count, success_count, response_data, error_message FROM health +WHERE status = ? AND deleted_at IS NULL +ORDER BY last_checked DESC +LIMIT ? OFFSET ? +` + +type ListHealthByStatusParams struct { + Status string `json:"status"` + Limit int64 `json:"limit"` + Offset int64 `json:"offset"` +} + +func (q *Queries) ListHealthByStatus(ctx context.Context, arg ListHealthByStatusParams) ([]Health, error) { + rows, err := q.db.QueryContext(ctx, listHealthByStatus, arg.Status, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Health + for rows.Next() { + var i Health + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.EndpointUrl, + &i.EndpointType, + &i.ChainID, + &i.Status, + &i.ResponseTimeMs, + &i.LastChecked, + &i.NextCheck, + &i.FailureCount, + &i.SuccessCount, + &i.ResponseData, + &i.ErrorMessage, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listHealthChecksNeedingUpdate = `-- name: ListHealthChecksNeedingUpdate :many +SELECT id, created_at, updated_at, deleted_at, endpoint_url, endpoint_type, chain_id, status, response_time_ms, last_checked, next_check, failure_count, success_count, response_data, error_message FROM health +WHERE next_check <= CURRENT_TIMESTAMP AND deleted_at IS NULL +ORDER BY next_check ASC +LIMIT ? +` + +func (q *Queries) ListHealthChecksNeedingUpdate(ctx context.Context, limit int64) ([]Health, error) { + rows, err := q.db.QueryContext(ctx, listHealthChecksNeedingUpdate, limit) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Health + for rows.Next() { + var i Health + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.EndpointUrl, + &i.EndpointType, + &i.ChainID, + &i.Status, + &i.ResponseTimeMs, + &i.LastChecked, + &i.NextCheck, + &i.FailureCount, + &i.SuccessCount, + &i.ResponseData, + &i.ErrorMessage, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listServicesByChain = `-- name: ListServicesByChain :many +SELECT id, created_at, updated_at, deleted_at, name, description, chain_id, address, owner_address, metadata, status, block_height FROM services +WHERE chain_id = ? AND deleted_at IS NULL +ORDER BY name ASC +LIMIT ? OFFSET ? +` + +type ListServicesByChainParams struct { + ChainID string `json:"chain_id"` + Limit int64 `json:"limit"` + Offset int64 `json:"offset"` +} + +func (q *Queries) ListServicesByChain(ctx context.Context, arg ListServicesByChainParams) ([]Service, error) { + rows, err := q.db.QueryContext(ctx, listServicesByChain, arg.ChainID, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Service + for rows.Next() { + var i Service + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Name, + &i.Description, + &i.ChainID, + &i.Address, + &i.OwnerAddress, + &i.Metadata, + &i.Status, + &i.BlockHeight, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listServicesByOwner = `-- name: ListServicesByOwner :many +SELECT id, created_at, updated_at, deleted_at, name, description, chain_id, address, owner_address, metadata, status, block_height FROM services +WHERE owner_address = ? AND deleted_at IS NULL +ORDER BY created_at DESC +LIMIT ? OFFSET ? +` + +type ListServicesByOwnerParams struct { + OwnerAddress string `json:"owner_address"` + Limit int64 `json:"limit"` + Offset int64 `json:"offset"` +} + +func (q *Queries) ListServicesByOwner(ctx context.Context, arg ListServicesByOwnerParams) ([]Service, error) { + rows, err := q.db.QueryContext(ctx, listServicesByOwner, arg.OwnerAddress, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Service + for rows.Next() { + var i Service + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Name, + &i.Description, + &i.ChainID, + &i.Address, + &i.OwnerAddress, + &i.Metadata, + &i.Status, + &i.BlockHeight, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const softDeleteActivity = `-- name: SoftDeleteActivity :exec +UPDATE activities +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ? +` + +func (q *Queries) SoftDeleteActivity(ctx context.Context, id string) error { + _, err := q.db.ExecContext(ctx, softDeleteActivity, id) + return err +} + +const softDeleteCryptoListing = `-- name: SoftDeleteCryptoListing :exec +UPDATE crypto_listings +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ? +` + +func (q *Queries) SoftDeleteCryptoListing(ctx context.Context, id string) error { + _, err := q.db.ExecContext(ctx, softDeleteCryptoListing, id) + return err +} + +const softDeleteFearGreedIndex = `-- name: SoftDeleteFearGreedIndex :exec +UPDATE fear_greed_index +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ? +` + +func (q *Queries) SoftDeleteFearGreedIndex(ctx context.Context, id string) error { + _, err := q.db.ExecContext(ctx, softDeleteFearGreedIndex, id) + return err +} + +const softDeleteGlobalMarket = `-- name: SoftDeleteGlobalMarket :exec +UPDATE global_market +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ? +` + +func (q *Queries) SoftDeleteGlobalMarket(ctx context.Context, id string) error { + _, err := q.db.ExecContext(ctx, softDeleteGlobalMarket, id) + return err +} + +const softDeleteHealth = `-- name: SoftDeleteHealth :exec +UPDATE health +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ? +` + +func (q *Queries) SoftDeleteHealth(ctx context.Context, id string) error { + _, err := q.db.ExecContext(ctx, softDeleteHealth, id) + return err +} + +const softDeleteService = `-- name: SoftDeleteService :exec +UPDATE services +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ? +` + +func (q *Queries) SoftDeleteService(ctx context.Context, id string) error { + _, err := q.db.ExecContext(ctx, softDeleteService, id) + return err +} + +const updateActivityStatus = `-- name: UpdateActivityStatus :one +UPDATE activities +SET + status = ?, + tx_hash = ?, + block_height = ?, + gas_used = ?, + raw_log = ?, + error = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, account_id, tx_hash, tx_type, status, amount, fee, gas_used, gas_wanted, memo, block_height, timestamp, raw_log, error +` + +type UpdateActivityStatusParams struct { + Status string `json:"status"` + TxHash sql.NullString `json:"tx_hash"` + BlockHeight sql.NullInt64 `json:"block_height"` + GasUsed sql.NullInt64 `json:"gas_used"` + RawLog sql.NullString `json:"raw_log"` + Error sql.NullString `json:"error"` + ID string `json:"id"` +} + +func (q *Queries) UpdateActivityStatus(ctx context.Context, arg UpdateActivityStatusParams) (Activity, error) { + row := q.db.QueryRowContext(ctx, updateActivityStatus, + arg.Status, + arg.TxHash, + arg.BlockHeight, + arg.GasUsed, + arg.RawLog, + arg.Error, + arg.ID, + ) + var i Activity + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.AccountID, + &i.TxHash, + &i.TxType, + &i.Status, + &i.Amount, + &i.Fee, + &i.GasUsed, + &i.GasWanted, + &i.Memo, + &i.BlockHeight, + &i.Timestamp, + &i.RawLog, + &i.Error, + ) + return i, err +} + +const updateCryptoListing = `-- name: UpdateCryptoListing :one +UPDATE crypto_listings +SET + name = ?, + symbol = ?, + website_slug = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, api_id, name, symbol, website_slug +` + +type UpdateCryptoListingParams struct { + Name string `json:"name"` + Symbol string `json:"symbol"` + WebsiteSlug string `json:"website_slug"` + ID string `json:"id"` +} + +func (q *Queries) UpdateCryptoListing(ctx context.Context, arg UpdateCryptoListingParams) (CryptoListing, error) { + row := q.db.QueryRowContext(ctx, updateCryptoListing, + arg.Name, + arg.Symbol, + arg.WebsiteSlug, + arg.ID, + ) + var i CryptoListing + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ApiID, + &i.Name, + &i.Symbol, + &i.WebsiteSlug, + ) + return i, err +} + +const updateFearGreedIndex = `-- name: UpdateFearGreedIndex :one +UPDATE fear_greed_index +SET + value = ?, + value_classification = ?, + timestamp = ?, + time_until_update = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, value, value_classification, timestamp, time_until_update +` + +type UpdateFearGreedIndexParams struct { + Value int64 `json:"value"` + ValueClassification string `json:"value_classification"` + Timestamp time.Time `json:"timestamp"` + TimeUntilUpdate sql.NullString `json:"time_until_update"` + ID string `json:"id"` +} + +func (q *Queries) UpdateFearGreedIndex(ctx context.Context, arg UpdateFearGreedIndexParams) (FearGreedIndex, error) { + row := q.db.QueryRowContext(ctx, updateFearGreedIndex, + arg.Value, + arg.ValueClassification, + arg.Timestamp, + arg.TimeUntilUpdate, + arg.ID, + ) + var i FearGreedIndex + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Value, + &i.ValueClassification, + &i.Timestamp, + &i.TimeUntilUpdate, + ) + return i, err +} + +const updateGlobalMarket = `-- name: UpdateGlobalMarket :one +UPDATE global_market +SET + total_market_cap_usd = ?, + total_24h_volume_usd = ?, + bitcoin_percentage_of_market_cap = ?, + active_currencies = ?, + active_assets = ?, + active_markets = ?, + last_updated = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, total_market_cap_usd, total_24h_volume_usd, bitcoin_percentage_of_market_cap, active_currencies, active_assets, active_markets, last_updated +` + +type UpdateGlobalMarketParams struct { + TotalMarketCapUsd sql.NullFloat64 `json:"total_market_cap_usd"` + Total24hVolumeUsd sql.NullFloat64 `json:"total_24h_volume_usd"` + BitcoinPercentageOfMarketCap sql.NullFloat64 `json:"bitcoin_percentage_of_market_cap"` + ActiveCurrencies sql.NullInt64 `json:"active_currencies"` + ActiveAssets sql.NullInt64 `json:"active_assets"` + ActiveMarkets sql.NullInt64 `json:"active_markets"` + LastUpdated time.Time `json:"last_updated"` + ID string `json:"id"` +} + +func (q *Queries) UpdateGlobalMarket(ctx context.Context, arg UpdateGlobalMarketParams) (GlobalMarket, error) { + row := q.db.QueryRowContext(ctx, updateGlobalMarket, + arg.TotalMarketCapUsd, + arg.Total24hVolumeUsd, + arg.BitcoinPercentageOfMarketCap, + arg.ActiveCurrencies, + arg.ActiveAssets, + arg.ActiveMarkets, + arg.LastUpdated, + arg.ID, + ) + var i GlobalMarket + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.TotalMarketCapUsd, + &i.Total24hVolumeUsd, + &i.BitcoinPercentageOfMarketCap, + &i.ActiveCurrencies, + &i.ActiveAssets, + &i.ActiveMarkets, + &i.LastUpdated, + ) + return i, err +} + +const updateHealthCheck = `-- name: UpdateHealthCheck :one +UPDATE health +SET + status = ?, + response_time_ms = ?, + last_checked = CURRENT_TIMESTAMP, + next_check = ?, + failure_count = CASE WHEN status = 'failed' THEN failure_count + 1 ELSE failure_count END, + success_count = CASE WHEN status = 'success' THEN success_count + 1 ELSE success_count END, + response_data = ?, + error_message = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, endpoint_url, endpoint_type, chain_id, status, response_time_ms, last_checked, next_check, failure_count, success_count, response_data, error_message +` + +type UpdateHealthCheckParams struct { + Status string `json:"status"` + ResponseTimeMs sql.NullInt64 `json:"response_time_ms"` + NextCheck sql.NullTime `json:"next_check"` + ResponseData sql.NullString `json:"response_data"` + ErrorMessage sql.NullString `json:"error_message"` + ID string `json:"id"` +} + +func (q *Queries) UpdateHealthCheck(ctx context.Context, arg UpdateHealthCheckParams) (Health, error) { + row := q.db.QueryRowContext(ctx, updateHealthCheck, + arg.Status, + arg.ResponseTimeMs, + arg.NextCheck, + arg.ResponseData, + arg.ErrorMessage, + arg.ID, + ) + var i Health + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.EndpointUrl, + &i.EndpointType, + &i.ChainID, + &i.Status, + &i.ResponseTimeMs, + &i.LastChecked, + &i.NextCheck, + &i.FailureCount, + &i.SuccessCount, + &i.ResponseData, + &i.ErrorMessage, + ) + return i, err +} + +const updateService = `-- name: UpdateService :one +UPDATE services +SET + name = ?, + description = ?, + owner_address = ?, + metadata = ?, + status = ?, + block_height = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, name, description, chain_id, address, owner_address, metadata, status, block_height +` + +type UpdateServiceParams struct { + Name string `json:"name"` + Description sql.NullString `json:"description"` + OwnerAddress string `json:"owner_address"` + Metadata sql.NullString `json:"metadata"` + Status string `json:"status"` + BlockHeight int64 `json:"block_height"` + ID string `json:"id"` +} + +func (q *Queries) UpdateService(ctx context.Context, arg UpdateServiceParams) (Service, error) { + row := q.db.QueryRowContext(ctx, updateService, + arg.Name, + arg.Description, + arg.OwnerAddress, + arg.Metadata, + arg.Status, + arg.BlockHeight, + arg.ID, + ) + var i Service + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Name, + &i.Description, + &i.ChainID, + &i.Address, + &i.OwnerAddress, + &i.Metadata, + &i.Status, + &i.BlockHeight, + ) + return i, err +} diff --git a/activity/sink/query.sql b/activity/sink/query.sql new file mode 100644 index 0000000..cff4428 --- /dev/null +++ b/activity/sink/query.sql @@ -0,0 +1,338 @@ +-- name: InsertService :one +INSERT INTO services ( + name, + description, + chain_id, + address, + owner_address, + metadata, + status, + block_height +) VALUES (?, ?, ?, ?, ?, ?, ?, ?) +RETURNING *; + +-- name: GetServiceByID :one +SELECT * FROM services +WHERE id = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetServiceByAddress :one +SELECT * FROM services +WHERE address = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetServiceByChainAndAddress :one +SELECT * FROM services +WHERE chain_id = ? AND address = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: ListServicesByChain :many +SELECT * FROM services +WHERE chain_id = ? AND deleted_at IS NULL +ORDER BY name ASC +LIMIT ? OFFSET ?; + +-- name: ListServicesByOwner :many +SELECT * FROM services +WHERE owner_address = ? AND deleted_at IS NULL +ORDER BY created_at DESC +LIMIT ? OFFSET ?; + +-- name: UpdateService :one +UPDATE services +SET + name = ?, + description = ?, + owner_address = ?, + metadata = ?, + status = ?, + block_height = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: SoftDeleteService :exec +UPDATE services +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ?; + +-- ACTIVITY QUERIES +-- name: InsertActivity :one +INSERT INTO activities ( + account_id, + tx_hash, + tx_type, + status, + amount, + fee, + gas_used, + gas_wanted, + memo, + block_height, + timestamp, + raw_log, + error +) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) +RETURNING *; + +-- name: GetActivityByID :one +SELECT * FROM activities +WHERE id = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetActivityByTxHash :one +SELECT * FROM activities +WHERE tx_hash = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: ListActivitiesByAccount :many +SELECT * FROM activities +WHERE account_id = ? AND deleted_at IS NULL +ORDER BY timestamp DESC +LIMIT ? OFFSET ?; + +-- name: ListActivitiesByType :many +SELECT * FROM activities +WHERE tx_type = ? AND deleted_at IS NULL +ORDER BY timestamp DESC +LIMIT ? OFFSET ?; + +-- name: ListActivitiesByStatus :many +SELECT * FROM activities +WHERE status = ? AND deleted_at IS NULL +ORDER BY timestamp DESC +LIMIT ? OFFSET ?; + +-- name: UpdateActivityStatus :one +UPDATE activities +SET + status = ?, + tx_hash = ?, + block_height = ?, + gas_used = ?, + raw_log = ?, + error = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: SoftDeleteActivity :exec +UPDATE activities +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ?; + +-- HEALTH QUERIES +-- name: InsertHealth :one +INSERT INTO health ( + endpoint_url, + endpoint_type, + chain_id, + status, + response_time_ms, + last_checked, + next_check, + failure_count, + success_count, + response_data, + error_message +) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) +RETURNING *; + +-- name: GetHealthByID :one +SELECT * FROM health +WHERE id = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetHealthByEndpoint :one +SELECT * FROM health +WHERE endpoint_url = ? AND deleted_at IS NULL +ORDER BY last_checked DESC +LIMIT 1; + +-- name: ListHealthByChain :many +SELECT * FROM health +WHERE chain_id = ? AND deleted_at IS NULL +ORDER BY last_checked DESC +LIMIT ? OFFSET ?; + +-- name: ListHealthByStatus :many +SELECT * FROM health +WHERE status = ? AND deleted_at IS NULL +ORDER BY last_checked DESC +LIMIT ? OFFSET ?; + +-- name: ListHealthChecksNeedingUpdate :many +SELECT * FROM health +WHERE next_check <= CURRENT_TIMESTAMP AND deleted_at IS NULL +ORDER BY next_check ASC +LIMIT ?; + +-- name: UpdateHealthCheck :one +UPDATE health +SET + status = ?, + response_time_ms = ?, + last_checked = CURRENT_TIMESTAMP, + next_check = ?, + failure_count = CASE WHEN status = 'failed' THEN failure_count + 1 ELSE failure_count END, + success_count = CASE WHEN status = 'success' THEN success_count + 1 ELSE success_count END, + response_data = ?, + error_message = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: SoftDeleteHealth :exec +UPDATE health +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ?; + + +-- name: GetGlobalMarketByID :one +SELECT * FROM global_market +WHERE id = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetLatestGlobalMarket :one +SELECT * FROM global_market +WHERE deleted_at IS NULL +ORDER BY last_updated DESC +LIMIT 1; + +-- name: ListGlobalMarketHistory :many +SELECT * FROM global_market +WHERE deleted_at IS NULL +ORDER BY last_updated DESC +LIMIT ? OFFSET ?; + +-- name: UpdateGlobalMarket :one +UPDATE global_market +SET + total_market_cap_usd = ?, + total_24h_volume_usd = ?, + bitcoin_percentage_of_market_cap = ?, + active_currencies = ?, + active_assets = ?, + active_markets = ?, + last_updated = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: SoftDeleteGlobalMarket :exec +UPDATE global_market +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ?; + +-- FEAR AND GREED INDEX QUERIES (NEW) +-- name: InsertFearGreedIndex :one +INSERT INTO fear_greed_index ( + value, + value_classification, + timestamp, + time_until_update +) VALUES (?, ?, ?, ?) +RETURNING *; + +-- name: GetFearGreedIndexByID :one +SELECT * FROM fear_greed_index +WHERE id = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetLatestFearGreedIndex :one +SELECT * FROM fear_greed_index +WHERE deleted_at IS NULL +ORDER BY timestamp DESC +LIMIT 1; + +-- name: ListFearGreedIndexHistory :many +SELECT * FROM fear_greed_index +WHERE deleted_at IS NULL +ORDER BY timestamp DESC +LIMIT ? OFFSET ?; + +-- name: UpdateFearGreedIndex :one +UPDATE fear_greed_index +SET + value = ?, + value_classification = ?, + timestamp = ?, + time_until_update = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: InsertGlobalMarket :one +INSERT INTO global_market ( + total_market_cap_usd, + total_24h_volume_usd, + bitcoin_percentage_of_market_cap, + active_currencies, + active_assets, + active_markets, + last_updated +) VALUES (?, ?, ?, ?, ?, ?, ?) +RETURNING *; + + +-- name: SoftDeleteFearGreedIndex :exec +UPDATE fear_greed_index +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ?; + +-- CRYPTO LISTINGS QUERIES (NEW) +-- name: InsertCryptoListing :one +INSERT INTO crypto_listings ( + api_id, + name, + symbol, + website_slug +) VALUES (?, ?, ?, ?) +RETURNING *; + +-- name: GetCryptoListingByID :one +SELECT * FROM crypto_listings +WHERE id = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetCryptoListingByApiID :one +SELECT * FROM crypto_listings +WHERE api_id = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetCryptoListingBySymbol :one +SELECT * FROM crypto_listings +WHERE symbol = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetCryptoListingByWebsiteSlug :one +SELECT * FROM crypto_listings +WHERE website_slug = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: ListCryptoListings :many +SELECT * FROM crypto_listings +WHERE deleted_at IS NULL +ORDER BY name ASC +LIMIT ? OFFSET ?; + +-- name: UpdateCryptoListing :one +UPDATE crypto_listings +SET + name = ?, + symbol = ?, + website_slug = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: SoftDeleteCryptoListing :exec +UPDATE crypto_listings +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ?; diff --git a/activity/sink/schema.sql b/activity/sink/schema.sql new file mode 100644 index 0000000..1c64724 --- /dev/null +++ b/activity/sink/schema.sql @@ -0,0 +1,136 @@ + +-- Service for Service Records sourced on chain +CREATE TABLE services ( + id TEXT PRIMARY KEY, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP, + name TEXT NOT NULL, + description TEXT, + chain_id TEXT NOT NULL, + address TEXT NOT NULL, + owner_address TEXT NOT NULL, + metadata TEXT CHECK(json_valid(metadata)), + status TEXT NOT NULL, + block_height INTEGER NOT NULL, + FOREIGN KEY (chain_id) REFERENCES assets(chain_id), + UNIQUE(chain_id, address) +); + +-- Activity table for basic transaction broadcast activity +CREATE TABLE activities ( + id TEXT PRIMARY KEY, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP, + account_id TEXT NOT NULL, + tx_hash TEXT, + tx_type TEXT NOT NULL, + status TEXT NOT NULL, + amount TEXT, + fee TEXT, + gas_used INTEGER, + gas_wanted INTEGER, + memo TEXT, + block_height INTEGER, + timestamp TIMESTAMP NOT NULL, + raw_log TEXT, + error TEXT, + FOREIGN KEY (account_id) REFERENCES accounts(id) +); + +-- Health table for scheduled checks for API endpoints +CREATE TABLE health ( + id TEXT PRIMARY KEY, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP, + endpoint_url TEXT NOT NULL, + endpoint_type TEXT NOT NULL, + chain_id TEXT, + status TEXT NOT NULL, + response_time_ms INTEGER, + last_checked TIMESTAMP NOT NULL, + next_check TIMESTAMP, + failure_count INTEGER NOT NULL DEFAULT 0, + success_count INTEGER NOT NULL DEFAULT 0, + response_data TEXT, + error_message TEXT, + FOREIGN KEY (chain_id) REFERENCES assets(chain_id) +); + +-- Global market data from Alternative.me API +CREATE TABLE global_market ( + id TEXT PRIMARY KEY, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP, + total_market_cap_usd REAL, + total_24h_volume_usd REAL, + bitcoin_percentage_of_market_cap REAL, + active_currencies INTEGER, + active_assets INTEGER, + active_markets INTEGER, + last_updated TIMESTAMP NOT NULL +); + +-- Fear and Greed Index data from Alternative.me +CREATE TABLE fear_greed_index ( + id TEXT PRIMARY KEY, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP, + value INTEGER NOT NULL, + value_classification TEXT NOT NULL, + timestamp TIMESTAMP NOT NULL, + time_until_update TEXT +); + +-- Listings data from Alternative.me API +CREATE TABLE crypto_listings ( + id TEXT PRIMARY KEY, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP, + api_id TEXT NOT NULL, + name TEXT NOT NULL, + symbol TEXT NOT NULL, + website_slug TEXT NOT NULL, + UNIQUE(api_id) +); + + +CREATE INDEX idx_services_name ON services(name); +CREATE INDEX idx_services_chain_id ON services(chain_id); +CREATE INDEX idx_services_address ON services(address); +CREATE INDEX idx_services_owner_address ON services(owner_address); +CREATE INDEX idx_services_status ON services(status); +CREATE INDEX idx_services_deleted_at ON services(deleted_at); + +CREATE INDEX idx_activities_account_id ON activities(account_id); +CREATE INDEX idx_activities_tx_hash ON activities(tx_hash); +CREATE INDEX idx_activities_tx_type ON activities(tx_type); +CREATE INDEX idx_activities_status ON activities(status); +CREATE INDEX idx_activities_timestamp ON activities(timestamp); +CREATE INDEX idx_activities_block_height ON activities(block_height); +CREATE INDEX idx_activities_deleted_at ON activities(deleted_at); + +CREATE INDEX idx_health_endpoint_url ON health(endpoint_url); +CREATE INDEX idx_health_endpoint_type ON health(endpoint_type); +CREATE INDEX idx_health_chain_id ON health(chain_id); +CREATE INDEX idx_health_status ON health(status); +CREATE INDEX idx_health_last_checked ON health(last_checked); +CREATE INDEX idx_health_next_check ON health(next_check); +CREATE INDEX idx_health_deleted_at ON health(deleted_at); + +CREATE INDEX idx_global_market_last_updated ON global_market(last_updated); +CREATE INDEX idx_global_market_deleted_at ON global_market(deleted_at); + +CREATE INDEX idx_fear_greed_index_timestamp ON fear_greed_index(timestamp); +CREATE INDEX idx_fear_greed_index_value ON fear_greed_index(value); +CREATE INDEX idx_fear_greed_index_deleted_at ON fear_greed_index(deleted_at); + +CREATE INDEX idx_crypto_listings_api_id ON crypto_listings(api_id); +CREATE INDEX idx_crypto_listings_symbol ON crypto_listings(symbol); +CREATE INDEX idx_crypto_listings_website_slug ON crypto_listings(website_slug); +CREATE INDEX idx_crypto_listings_deleted_at ON crypto_listings(deleted_at); diff --git a/connection.go b/connection.go new file mode 100644 index 0000000..995fb17 --- /dev/null +++ b/connection.go @@ -0,0 +1 @@ +package dbx diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..f321705 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/cf-sonr/dbx + +go 1.24.2 diff --git a/network/db.go b/network/db.go new file mode 100644 index 0000000..d69bdcb --- /dev/null +++ b/network/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 + +package network + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/network/models.go b/network/models.go new file mode 100644 index 0000000..b61d9fc --- /dev/null +++ b/network/models.go @@ -0,0 +1,96 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 + +package network + +import ( + "database/sql" + "time" +) + +type Asset struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt sql.NullTime `json:"deleted_at"` + Name string `json:"name"` + Symbol string `json:"symbol"` + Decimals int64 `json:"decimals"` + ChainID string `json:"chain_id"` + Channel string `json:"channel"` + AssetType string `json:"asset_type"` + CoingeckoID sql.NullString `json:"coingecko_id"` +} + +type Blockchain struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt sql.NullTime `json:"deleted_at"` + ChainName string `json:"chain_name"` + ChainIDCosmos sql.NullString `json:"chain_id_cosmos"` + ChainIDEvm sql.NullString `json:"chain_id_evm"` + ApiName sql.NullString `json:"api_name"` + BechAccountPrefix sql.NullString `json:"bech_account_prefix"` + BechValidatorPrefix sql.NullString `json:"bech_validator_prefix"` + MainAssetSymbol sql.NullString `json:"main_asset_symbol"` + MainAssetDenom sql.NullString `json:"main_asset_denom"` + StakingAssetSymbol sql.NullString `json:"staking_asset_symbol"` + StakingAssetDenom sql.NullString `json:"staking_asset_denom"` + IsStakeEnabled bool `json:"is_stake_enabled"` + ChainImage sql.NullString `json:"chain_image"` + MainAssetImage sql.NullString `json:"main_asset_image"` + StakingAssetImage sql.NullString `json:"staking_asset_image"` + ChainType string `json:"chain_type"` + IsSupportMobileWallet bool `json:"is_support_mobile_wallet"` + IsSupportExtensionWallet bool `json:"is_support_extension_wallet"` + IsSupportErc20 bool `json:"is_support_erc20"` + DescriptionEn sql.NullString `json:"description_en"` + DescriptionKo sql.NullString `json:"description_ko"` + DescriptionJa sql.NullString `json:"description_ja"` + OriginGenesisTime sql.NullTime `json:"origin_genesis_time"` + AccountType string `json:"account_type"` + BtcStaking sql.NullString `json:"btc_staking"` + CosmosFeeInfo sql.NullString `json:"cosmos_fee_info"` + EvmFeeInfo sql.NullString `json:"evm_fee_info"` + LcdEndpoint sql.NullString `json:"lcd_endpoint"` + GrpcEndpoint sql.NullString `json:"grpc_endpoint"` + EvmRpcEndpoint sql.NullString `json:"evm_rpc_endpoint"` + Explorer sql.NullString `json:"explorer"` + About sql.NullString `json:"about"` + Forum sql.NullString `json:"forum"` +} + +type Price struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt sql.NullTime `json:"deleted_at"` + AssetID string `json:"asset_id"` + PriceUsd sql.NullFloat64 `json:"price_usd"` + PriceBtc sql.NullFloat64 `json:"price_btc"` + Volume24hUsd sql.NullFloat64 `json:"volume_24h_usd"` + MarketCapUsd sql.NullFloat64 `json:"market_cap_usd"` + AvailableSupply sql.NullFloat64 `json:"available_supply"` + TotalSupply sql.NullFloat64 `json:"total_supply"` + MaxSupply sql.NullFloat64 `json:"max_supply"` + PercentChange1h sql.NullFloat64 `json:"percent_change_1h"` + PercentChange24h sql.NullFloat64 `json:"percent_change_24h"` + PercentChange7d sql.NullFloat64 `json:"percent_change_7d"` + Rank sql.NullInt64 `json:"rank"` + LastUpdated time.Time `json:"last_updated"` +} + +type PriceConversion struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt sql.NullTime `json:"deleted_at"` + PriceID string `json:"price_id"` + CurrencyCode string `json:"currency_code"` + Price sql.NullFloat64 `json:"price"` + Volume24h sql.NullFloat64 `json:"volume_24h"` + MarketCap sql.NullFloat64 `json:"market_cap"` + LastUpdated time.Time `json:"last_updated"` +} diff --git a/network/querier.go b/network/querier.go new file mode 100644 index 0000000..61a3a06 --- /dev/null +++ b/network/querier.go @@ -0,0 +1,64 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 + +package network + +import ( + "context" + "database/sql" +) + +type Querier interface { + CountBlockchainsByChainType(ctx context.Context, dollar_1 sql.NullString) (int64, error) + GetAssetByChainAndSymbol(ctx context.Context, arg GetAssetByChainAndSymbolParams) (Asset, error) + GetAssetByID(ctx context.Context, id string) (Asset, error) + GetAssetBySymbol(ctx context.Context, symbol string) (Asset, error) + GetAssetWithLatestPrice(ctx context.Context, id string) (GetAssetWithLatestPriceRow, error) + GetBlockchainByChainName(ctx context.Context, chainName string) (Blockchain, error) + GetBlockchainByCosmosChainID(ctx context.Context, chainIDCosmos sql.NullString) (Blockchain, error) + GetBlockchainByEvmChainID(ctx context.Context, chainIDEvm sql.NullString) (Blockchain, error) + GetBlockchainByID(ctx context.Context, id string) (Blockchain, error) + GetBlockchainEndpoints(ctx context.Context, id string) (GetBlockchainEndpointsRow, error) + GetBlockchainExplorer(ctx context.Context, id string) (GetBlockchainExplorerRow, error) + GetBlockchainWithAssetInfo(ctx context.Context, id string) (GetBlockchainWithAssetInfoRow, error) + GetPriceByAssetID(ctx context.Context, assetID string) (Price, error) + GetPriceByID(ctx context.Context, id string) (Price, error) + GetPriceConversionByCurrency(ctx context.Context, arg GetPriceConversionByCurrencyParams) (PriceConversion, error) + GetPriceConversionByID(ctx context.Context, id string) (PriceConversion, error) + GetPriceConversionsByPriceID(ctx context.Context, priceID string) ([]PriceConversion, error) + // ASSET QUERIES + InsertAsset(ctx context.Context, arg InsertAssetParams) (Asset, error) + // BLOCKCHAIN QUERIES + InsertBlockchain(ctx context.Context, arg InsertBlockchainParams) (Blockchain, error) + // PRICE QUERIES (UPDATED) + InsertPrice(ctx context.Context, arg InsertPriceParams) (Price, error) + // PRICE CONVERSION QUERIES (NEW) + InsertPriceConversion(ctx context.Context, arg InsertPriceConversionParams) (PriceConversion, error) + ListAllBlockchains(ctx context.Context) ([]Blockchain, error) + ListAssetsByChain(ctx context.Context, chainID string) ([]Asset, error) + ListAssetsWithLatestPrices(ctx context.Context, arg ListAssetsWithLatestPricesParams) ([]ListAssetsWithLatestPricesRow, error) + ListBlockchainsByChainType(ctx context.Context, dollar_1 sql.NullString) ([]Blockchain, error) + ListBlockchainsWithAssetInfo(ctx context.Context, arg ListBlockchainsWithAssetInfoParams) ([]ListBlockchainsWithAssetInfoRow, error) + ListBlockchainsWithERC20Support(ctx context.Context) ([]Blockchain, error) + ListBlockchainsWithExtensionSupport(ctx context.Context) ([]Blockchain, error) + ListBlockchainsWithMobileSupport(ctx context.Context) ([]Blockchain, error) + ListBlockchainsWithStaking(ctx context.Context) ([]Blockchain, error) + ListPriceHistoryByAssetID(ctx context.Context, arg ListPriceHistoryByAssetIDParams) ([]Price, error) + SearchBlockchains(ctx context.Context, arg SearchBlockchainsParams) ([]Blockchain, error) + SoftDeleteAsset(ctx context.Context, id string) error + SoftDeleteBlockchain(ctx context.Context, id string) error + SoftDeletePriceConversion(ctx context.Context, id string) error + UpdateAsset(ctx context.Context, arg UpdateAssetParams) (Asset, error) + UpdateBlockchain(ctx context.Context, arg UpdateBlockchainParams) (Blockchain, error) + UpdateBlockchainDescriptions(ctx context.Context, arg UpdateBlockchainDescriptionsParams) (Blockchain, error) + UpdateBlockchainEndpoints(ctx context.Context, arg UpdateBlockchainEndpointsParams) (Blockchain, error) + UpdateBlockchainExplorer(ctx context.Context, arg UpdateBlockchainExplorerParams) (Blockchain, error) + UpdateBlockchainFeeInfo(ctx context.Context, arg UpdateBlockchainFeeInfoParams) (Blockchain, error) + UpdateBlockchainImages(ctx context.Context, arg UpdateBlockchainImagesParams) (Blockchain, error) + UpdateBlockchainSocialLinks(ctx context.Context, arg UpdateBlockchainSocialLinksParams) (Blockchain, error) + UpdatePrice(ctx context.Context, arg UpdatePriceParams) (Price, error) + UpdatePriceConversion(ctx context.Context, arg UpdatePriceConversionParams) (PriceConversion, error) +} + +var _ Querier = (*Queries)(nil) diff --git a/network/query.sql.go b/network/query.sql.go new file mode 100644 index 0000000..ae29548 --- /dev/null +++ b/network/query.sql.go @@ -0,0 +1,2583 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 +// source: query.sql + +package network + +import ( + "context" + "database/sql" + "time" +) + +const countBlockchainsByChainType = `-- name: CountBlockchainsByChainType :one +SELECT COUNT(*) as count FROM blockchains +WHERE chain_type LIKE '%' || ? || '%' AND deleted_at IS NULL +` + +func (q *Queries) CountBlockchainsByChainType(ctx context.Context, dollar_1 sql.NullString) (int64, error) { + row := q.db.QueryRowContext(ctx, countBlockchainsByChainType, dollar_1) + var count int64 + err := row.Scan(&count) + return count, err +} + +const getAssetByChainAndSymbol = `-- name: GetAssetByChainAndSymbol :one +SELECT id, created_at, updated_at, deleted_at, name, symbol, decimals, chain_id, channel, asset_type, coingecko_id FROM assets +WHERE chain_id = ? AND symbol = ? AND deleted_at IS NULL +LIMIT 1 +` + +type GetAssetByChainAndSymbolParams struct { + ChainID string `json:"chain_id"` + Symbol string `json:"symbol"` +} + +func (q *Queries) GetAssetByChainAndSymbol(ctx context.Context, arg GetAssetByChainAndSymbolParams) (Asset, error) { + row := q.db.QueryRowContext(ctx, getAssetByChainAndSymbol, arg.ChainID, arg.Symbol) + var i Asset + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Name, + &i.Symbol, + &i.Decimals, + &i.ChainID, + &i.Channel, + &i.AssetType, + &i.CoingeckoID, + ) + return i, err +} + +const getAssetByID = `-- name: GetAssetByID :one +SELECT id, created_at, updated_at, deleted_at, name, symbol, decimals, chain_id, channel, asset_type, coingecko_id FROM assets +WHERE id = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetAssetByID(ctx context.Context, id string) (Asset, error) { + row := q.db.QueryRowContext(ctx, getAssetByID, id) + var i Asset + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Name, + &i.Symbol, + &i.Decimals, + &i.ChainID, + &i.Channel, + &i.AssetType, + &i.CoingeckoID, + ) + return i, err +} + +const getAssetBySymbol = `-- name: GetAssetBySymbol :one +SELECT id, created_at, updated_at, deleted_at, name, symbol, decimals, chain_id, channel, asset_type, coingecko_id FROM assets +WHERE symbol = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetAssetBySymbol(ctx context.Context, symbol string) (Asset, error) { + row := q.db.QueryRowContext(ctx, getAssetBySymbol, symbol) + var i Asset + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Name, + &i.Symbol, + &i.Decimals, + &i.ChainID, + &i.Channel, + &i.AssetType, + &i.CoingeckoID, + ) + return i, err +} + +const getAssetWithLatestPrice = `-- name: GetAssetWithLatestPrice :one +SELECT a.id, a.created_at, a.updated_at, a.deleted_at, a.name, a.symbol, a.decimals, a.chain_id, a.channel, a.asset_type, a.coingecko_id, p.price_usd, p.price_btc, p.volume_24h_usd, p.market_cap_usd, + p.available_supply, p.total_supply, p.max_supply, + p.percent_change_1h, p.percent_change_24h, p.percent_change_7d, + p.rank, p.last_updated +FROM assets a +LEFT JOIN ( + SELECT p1.id, p1.created_at, p1.updated_at, p1.deleted_at, p1.asset_id, p1.price_usd, p1.price_btc, p1.volume_24h_usd, p1.market_cap_usd, p1.available_supply, p1.total_supply, p1.max_supply, p1.percent_change_1h, p1.percent_change_24h, p1.percent_change_7d, p1.rank, p1.last_updated + FROM prices p1 + INNER JOIN ( + SELECT asset_id, MAX(last_updated) as max_date + FROM prices + WHERE deleted_at IS NULL + GROUP BY asset_id + ) p2 ON p1.asset_id = p2.asset_id AND p1.last_updated = p2.max_date + WHERE p1.deleted_at IS NULL +) p ON a.id = p.asset_id +WHERE a.id = ? AND a.deleted_at IS NULL +LIMIT 1 +` + +type GetAssetWithLatestPriceRow struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt sql.NullTime `json:"deleted_at"` + Name string `json:"name"` + Symbol string `json:"symbol"` + Decimals int64 `json:"decimals"` + ChainID string `json:"chain_id"` + Channel string `json:"channel"` + AssetType string `json:"asset_type"` + CoingeckoID sql.NullString `json:"coingecko_id"` + PriceUsd sql.NullFloat64 `json:"price_usd"` + PriceBtc sql.NullFloat64 `json:"price_btc"` + Volume24hUsd sql.NullFloat64 `json:"volume_24h_usd"` + MarketCapUsd sql.NullFloat64 `json:"market_cap_usd"` + AvailableSupply sql.NullFloat64 `json:"available_supply"` + TotalSupply sql.NullFloat64 `json:"total_supply"` + MaxSupply sql.NullFloat64 `json:"max_supply"` + PercentChange1h sql.NullFloat64 `json:"percent_change_1h"` + PercentChange24h sql.NullFloat64 `json:"percent_change_24h"` + PercentChange7d sql.NullFloat64 `json:"percent_change_7d"` + Rank sql.NullInt64 `json:"rank"` + LastUpdated time.Time `json:"last_updated"` +} + +func (q *Queries) GetAssetWithLatestPrice(ctx context.Context, id string) (GetAssetWithLatestPriceRow, error) { + row := q.db.QueryRowContext(ctx, getAssetWithLatestPrice, id) + var i GetAssetWithLatestPriceRow + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Name, + &i.Symbol, + &i.Decimals, + &i.ChainID, + &i.Channel, + &i.AssetType, + &i.CoingeckoID, + &i.PriceUsd, + &i.PriceBtc, + &i.Volume24hUsd, + &i.MarketCapUsd, + &i.AvailableSupply, + &i.TotalSupply, + &i.MaxSupply, + &i.PercentChange1h, + &i.PercentChange24h, + &i.PercentChange7d, + &i.Rank, + &i.LastUpdated, + ) + return i, err +} + +const getBlockchainByChainName = `-- name: GetBlockchainByChainName :one +SELECT id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum FROM blockchains +WHERE chain_name = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetBlockchainByChainName(ctx context.Context, chainName string) (Blockchain, error) { + row := q.db.QueryRowContext(ctx, getBlockchainByChainName, chainName) + var i Blockchain + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ) + return i, err +} + +const getBlockchainByCosmosChainID = `-- name: GetBlockchainByCosmosChainID :one +SELECT id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum FROM blockchains +WHERE chain_id_cosmos = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetBlockchainByCosmosChainID(ctx context.Context, chainIDCosmos sql.NullString) (Blockchain, error) { + row := q.db.QueryRowContext(ctx, getBlockchainByCosmosChainID, chainIDCosmos) + var i Blockchain + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ) + return i, err +} + +const getBlockchainByEvmChainID = `-- name: GetBlockchainByEvmChainID :one +SELECT id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum FROM blockchains +WHERE chain_id_evm = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetBlockchainByEvmChainID(ctx context.Context, chainIDEvm sql.NullString) (Blockchain, error) { + row := q.db.QueryRowContext(ctx, getBlockchainByEvmChainID, chainIDEvm) + var i Blockchain + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ) + return i, err +} + +const getBlockchainByID = `-- name: GetBlockchainByID :one +SELECT id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum FROM blockchains +WHERE id = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetBlockchainByID(ctx context.Context, id string) (Blockchain, error) { + row := q.db.QueryRowContext(ctx, getBlockchainByID, id) + var i Blockchain + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ) + return i, err +} + +const getBlockchainEndpoints = `-- name: GetBlockchainEndpoints :one +SELECT id, chain_name, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint +FROM blockchains +WHERE id = ? AND deleted_at IS NULL +LIMIT 1 +` + +type GetBlockchainEndpointsRow struct { + ID string `json:"id"` + ChainName string `json:"chain_name"` + LcdEndpoint sql.NullString `json:"lcd_endpoint"` + GrpcEndpoint sql.NullString `json:"grpc_endpoint"` + EvmRpcEndpoint sql.NullString `json:"evm_rpc_endpoint"` +} + +func (q *Queries) GetBlockchainEndpoints(ctx context.Context, id string) (GetBlockchainEndpointsRow, error) { + row := q.db.QueryRowContext(ctx, getBlockchainEndpoints, id) + var i GetBlockchainEndpointsRow + err := row.Scan( + &i.ID, + &i.ChainName, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + ) + return i, err +} + +const getBlockchainExplorer = `-- name: GetBlockchainExplorer :one +SELECT id, chain_name, explorer +FROM blockchains +WHERE id = ? AND deleted_at IS NULL +LIMIT 1 +` + +type GetBlockchainExplorerRow struct { + ID string `json:"id"` + ChainName string `json:"chain_name"` + Explorer sql.NullString `json:"explorer"` +} + +func (q *Queries) GetBlockchainExplorer(ctx context.Context, id string) (GetBlockchainExplorerRow, error) { + row := q.db.QueryRowContext(ctx, getBlockchainExplorer, id) + var i GetBlockchainExplorerRow + err := row.Scan(&i.ID, &i.ChainName, &i.Explorer) + return i, err +} + +const getBlockchainWithAssetInfo = `-- name: GetBlockchainWithAssetInfo :one +SELECT b.id, b.created_at, b.updated_at, b.deleted_at, b.chain_name, b.chain_id_cosmos, b.chain_id_evm, b.api_name, b.bech_account_prefix, b.bech_validator_prefix, b.main_asset_symbol, b.main_asset_denom, b.staking_asset_symbol, b.staking_asset_denom, b.is_stake_enabled, b.chain_image, b.main_asset_image, b.staking_asset_image, b.chain_type, b.is_support_mobile_wallet, b.is_support_extension_wallet, b.is_support_erc20, b.description_en, b.description_ko, b.description_ja, b.origin_genesis_time, b.account_type, b.btc_staking, b.cosmos_fee_info, b.evm_fee_info, b.lcd_endpoint, b.grpc_endpoint, b.evm_rpc_endpoint, b.explorer, b.about, b.forum, a.id as asset_id, a.symbol, a.decimals, p.price_usd, p.price_btc +FROM blockchains b +LEFT JOIN assets a ON b.main_asset_symbol = a.symbol +LEFT JOIN ( + SELECT p1.id, p1.created_at, p1.updated_at, p1.deleted_at, p1.asset_id, p1.price_usd, p1.price_btc, p1.volume_24h_usd, p1.market_cap_usd, p1.available_supply, p1.total_supply, p1.max_supply, p1.percent_change_1h, p1.percent_change_24h, p1.percent_change_7d, p1.rank, p1.last_updated + FROM prices p1 + INNER JOIN ( + SELECT asset_id, MAX(last_updated) as max_date + FROM prices + WHERE deleted_at IS NULL + GROUP BY asset_id + ) p2 ON p1.asset_id = p2.asset_id AND p1.last_updated = p2.max_date + WHERE p1.deleted_at IS NULL +) p ON a.id = p.asset_id +WHERE b.id = ? AND b.deleted_at IS NULL +LIMIT 1 +` + +type GetBlockchainWithAssetInfoRow struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt sql.NullTime `json:"deleted_at"` + ChainName string `json:"chain_name"` + ChainIDCosmos sql.NullString `json:"chain_id_cosmos"` + ChainIDEvm sql.NullString `json:"chain_id_evm"` + ApiName sql.NullString `json:"api_name"` + BechAccountPrefix sql.NullString `json:"bech_account_prefix"` + BechValidatorPrefix sql.NullString `json:"bech_validator_prefix"` + MainAssetSymbol sql.NullString `json:"main_asset_symbol"` + MainAssetDenom sql.NullString `json:"main_asset_denom"` + StakingAssetSymbol sql.NullString `json:"staking_asset_symbol"` + StakingAssetDenom sql.NullString `json:"staking_asset_denom"` + IsStakeEnabled bool `json:"is_stake_enabled"` + ChainImage sql.NullString `json:"chain_image"` + MainAssetImage sql.NullString `json:"main_asset_image"` + StakingAssetImage sql.NullString `json:"staking_asset_image"` + ChainType string `json:"chain_type"` + IsSupportMobileWallet bool `json:"is_support_mobile_wallet"` + IsSupportExtensionWallet bool `json:"is_support_extension_wallet"` + IsSupportErc20 bool `json:"is_support_erc20"` + DescriptionEn sql.NullString `json:"description_en"` + DescriptionKo sql.NullString `json:"description_ko"` + DescriptionJa sql.NullString `json:"description_ja"` + OriginGenesisTime sql.NullTime `json:"origin_genesis_time"` + AccountType string `json:"account_type"` + BtcStaking sql.NullString `json:"btc_staking"` + CosmosFeeInfo sql.NullString `json:"cosmos_fee_info"` + EvmFeeInfo sql.NullString `json:"evm_fee_info"` + LcdEndpoint sql.NullString `json:"lcd_endpoint"` + GrpcEndpoint sql.NullString `json:"grpc_endpoint"` + EvmRpcEndpoint sql.NullString `json:"evm_rpc_endpoint"` + Explorer sql.NullString `json:"explorer"` + About sql.NullString `json:"about"` + Forum sql.NullString `json:"forum"` + AssetID sql.NullString `json:"asset_id"` + Symbol sql.NullString `json:"symbol"` + Decimals sql.NullInt64 `json:"decimals"` + PriceUsd sql.NullFloat64 `json:"price_usd"` + PriceBtc sql.NullFloat64 `json:"price_btc"` +} + +func (q *Queries) GetBlockchainWithAssetInfo(ctx context.Context, id string) (GetBlockchainWithAssetInfoRow, error) { + row := q.db.QueryRowContext(ctx, getBlockchainWithAssetInfo, id) + var i GetBlockchainWithAssetInfoRow + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + &i.AssetID, + &i.Symbol, + &i.Decimals, + &i.PriceUsd, + &i.PriceBtc, + ) + return i, err +} + +const getPriceByAssetID = `-- name: GetPriceByAssetID :one +SELECT id, created_at, updated_at, deleted_at, asset_id, price_usd, price_btc, volume_24h_usd, market_cap_usd, available_supply, total_supply, max_supply, percent_change_1h, percent_change_24h, percent_change_7d, rank, last_updated FROM prices +WHERE asset_id = ? AND deleted_at IS NULL +ORDER BY last_updated DESC +LIMIT 1 +` + +func (q *Queries) GetPriceByAssetID(ctx context.Context, assetID string) (Price, error) { + row := q.db.QueryRowContext(ctx, getPriceByAssetID, assetID) + var i Price + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.AssetID, + &i.PriceUsd, + &i.PriceBtc, + &i.Volume24hUsd, + &i.MarketCapUsd, + &i.AvailableSupply, + &i.TotalSupply, + &i.MaxSupply, + &i.PercentChange1h, + &i.PercentChange24h, + &i.PercentChange7d, + &i.Rank, + &i.LastUpdated, + ) + return i, err +} + +const getPriceByID = `-- name: GetPriceByID :one +SELECT id, created_at, updated_at, deleted_at, asset_id, price_usd, price_btc, volume_24h_usd, market_cap_usd, available_supply, total_supply, max_supply, percent_change_1h, percent_change_24h, percent_change_7d, rank, last_updated FROM prices +WHERE id = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetPriceByID(ctx context.Context, id string) (Price, error) { + row := q.db.QueryRowContext(ctx, getPriceByID, id) + var i Price + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.AssetID, + &i.PriceUsd, + &i.PriceBtc, + &i.Volume24hUsd, + &i.MarketCapUsd, + &i.AvailableSupply, + &i.TotalSupply, + &i.MaxSupply, + &i.PercentChange1h, + &i.PercentChange24h, + &i.PercentChange7d, + &i.Rank, + &i.LastUpdated, + ) + return i, err +} + +const getPriceConversionByCurrency = `-- name: GetPriceConversionByCurrency :one +SELECT id, created_at, updated_at, deleted_at, price_id, currency_code, price, volume_24h, market_cap, last_updated FROM price_conversions +WHERE price_id = ? AND currency_code = ? AND deleted_at IS NULL +LIMIT 1 +` + +type GetPriceConversionByCurrencyParams struct { + PriceID string `json:"price_id"` + CurrencyCode string `json:"currency_code"` +} + +func (q *Queries) GetPriceConversionByCurrency(ctx context.Context, arg GetPriceConversionByCurrencyParams) (PriceConversion, error) { + row := q.db.QueryRowContext(ctx, getPriceConversionByCurrency, arg.PriceID, arg.CurrencyCode) + var i PriceConversion + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.PriceID, + &i.CurrencyCode, + &i.Price, + &i.Volume24h, + &i.MarketCap, + &i.LastUpdated, + ) + return i, err +} + +const getPriceConversionByID = `-- name: GetPriceConversionByID :one +SELECT id, created_at, updated_at, deleted_at, price_id, currency_code, price, volume_24h, market_cap, last_updated FROM price_conversions +WHERE id = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetPriceConversionByID(ctx context.Context, id string) (PriceConversion, error) { + row := q.db.QueryRowContext(ctx, getPriceConversionByID, id) + var i PriceConversion + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.PriceID, + &i.CurrencyCode, + &i.Price, + &i.Volume24h, + &i.MarketCap, + &i.LastUpdated, + ) + return i, err +} + +const getPriceConversionsByPriceID = `-- name: GetPriceConversionsByPriceID :many +SELECT id, created_at, updated_at, deleted_at, price_id, currency_code, price, volume_24h, market_cap, last_updated FROM price_conversions +WHERE price_id = ? AND deleted_at IS NULL +ORDER BY currency_code ASC +` + +func (q *Queries) GetPriceConversionsByPriceID(ctx context.Context, priceID string) ([]PriceConversion, error) { + rows, err := q.db.QueryContext(ctx, getPriceConversionsByPriceID, priceID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []PriceConversion + for rows.Next() { + var i PriceConversion + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.PriceID, + &i.CurrencyCode, + &i.Price, + &i.Volume24h, + &i.MarketCap, + &i.LastUpdated, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const insertAsset = `-- name: InsertAsset :one +INSERT INTO assets ( + name, + symbol, + decimals, + chain_id, + channel, + asset_type, + coingecko_id +) VALUES (?, ?, ?, ?, ?, ?, ?) +RETURNING id, created_at, updated_at, deleted_at, name, symbol, decimals, chain_id, channel, asset_type, coingecko_id +` + +type InsertAssetParams struct { + Name string `json:"name"` + Symbol string `json:"symbol"` + Decimals int64 `json:"decimals"` + ChainID string `json:"chain_id"` + Channel string `json:"channel"` + AssetType string `json:"asset_type"` + CoingeckoID sql.NullString `json:"coingecko_id"` +} + +// ASSET QUERIES +func (q *Queries) InsertAsset(ctx context.Context, arg InsertAssetParams) (Asset, error) { + row := q.db.QueryRowContext(ctx, insertAsset, + arg.Name, + arg.Symbol, + arg.Decimals, + arg.ChainID, + arg.Channel, + arg.AssetType, + arg.CoingeckoID, + ) + var i Asset + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Name, + &i.Symbol, + &i.Decimals, + &i.ChainID, + &i.Channel, + &i.AssetType, + &i.CoingeckoID, + ) + return i, err +} + +const insertBlockchain = `-- name: InsertBlockchain :one +INSERT INTO blockchains ( + id, + chain_name, + chain_id_cosmos, + chain_id_evm, + api_name, + bech_account_prefix, + bech_validator_prefix, + main_asset_symbol, + main_asset_denom, + staking_asset_symbol, + staking_asset_denom, + is_stake_enabled, + chain_image, + main_asset_image, + staking_asset_image, + chain_type, + is_support_mobile_wallet, + is_support_extension_wallet, + is_support_erc20, + description_en, + description_ko, + description_ja, + origin_genesis_time, + account_type, + btc_staking, + cosmos_fee_info, + evm_fee_info, + lcd_endpoint, + grpc_endpoint, + evm_rpc_endpoint, + explorer, + about, + forum +) VALUES ( + ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? +) +RETURNING id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum +` + +type InsertBlockchainParams struct { + ID string `json:"id"` + ChainName string `json:"chain_name"` + ChainIDCosmos sql.NullString `json:"chain_id_cosmos"` + ChainIDEvm sql.NullString `json:"chain_id_evm"` + ApiName sql.NullString `json:"api_name"` + BechAccountPrefix sql.NullString `json:"bech_account_prefix"` + BechValidatorPrefix sql.NullString `json:"bech_validator_prefix"` + MainAssetSymbol sql.NullString `json:"main_asset_symbol"` + MainAssetDenom sql.NullString `json:"main_asset_denom"` + StakingAssetSymbol sql.NullString `json:"staking_asset_symbol"` + StakingAssetDenom sql.NullString `json:"staking_asset_denom"` + IsStakeEnabled bool `json:"is_stake_enabled"` + ChainImage sql.NullString `json:"chain_image"` + MainAssetImage sql.NullString `json:"main_asset_image"` + StakingAssetImage sql.NullString `json:"staking_asset_image"` + ChainType string `json:"chain_type"` + IsSupportMobileWallet bool `json:"is_support_mobile_wallet"` + IsSupportExtensionWallet bool `json:"is_support_extension_wallet"` + IsSupportErc20 bool `json:"is_support_erc20"` + DescriptionEn sql.NullString `json:"description_en"` + DescriptionKo sql.NullString `json:"description_ko"` + DescriptionJa sql.NullString `json:"description_ja"` + OriginGenesisTime sql.NullTime `json:"origin_genesis_time"` + AccountType string `json:"account_type"` + BtcStaking sql.NullString `json:"btc_staking"` + CosmosFeeInfo sql.NullString `json:"cosmos_fee_info"` + EvmFeeInfo sql.NullString `json:"evm_fee_info"` + LcdEndpoint sql.NullString `json:"lcd_endpoint"` + GrpcEndpoint sql.NullString `json:"grpc_endpoint"` + EvmRpcEndpoint sql.NullString `json:"evm_rpc_endpoint"` + Explorer sql.NullString `json:"explorer"` + About sql.NullString `json:"about"` + Forum sql.NullString `json:"forum"` +} + +// BLOCKCHAIN QUERIES +func (q *Queries) InsertBlockchain(ctx context.Context, arg InsertBlockchainParams) (Blockchain, error) { + row := q.db.QueryRowContext(ctx, insertBlockchain, + arg.ID, + arg.ChainName, + arg.ChainIDCosmos, + arg.ChainIDEvm, + arg.ApiName, + arg.BechAccountPrefix, + arg.BechValidatorPrefix, + arg.MainAssetSymbol, + arg.MainAssetDenom, + arg.StakingAssetSymbol, + arg.StakingAssetDenom, + arg.IsStakeEnabled, + arg.ChainImage, + arg.MainAssetImage, + arg.StakingAssetImage, + arg.ChainType, + arg.IsSupportMobileWallet, + arg.IsSupportExtensionWallet, + arg.IsSupportErc20, + arg.DescriptionEn, + arg.DescriptionKo, + arg.DescriptionJa, + arg.OriginGenesisTime, + arg.AccountType, + arg.BtcStaking, + arg.CosmosFeeInfo, + arg.EvmFeeInfo, + arg.LcdEndpoint, + arg.GrpcEndpoint, + arg.EvmRpcEndpoint, + arg.Explorer, + arg.About, + arg.Forum, + ) + var i Blockchain + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ) + return i, err +} + +const insertPrice = `-- name: InsertPrice :one +INSERT INTO prices ( + asset_id, + price_usd, + price_btc, + volume_24h_usd, + market_cap_usd, + available_supply, + total_supply, + max_supply, + percent_change_1h, + percent_change_24h, + percent_change_7d, + rank, + last_updated +) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) +RETURNING id, created_at, updated_at, deleted_at, asset_id, price_usd, price_btc, volume_24h_usd, market_cap_usd, available_supply, total_supply, max_supply, percent_change_1h, percent_change_24h, percent_change_7d, rank, last_updated +` + +type InsertPriceParams struct { + AssetID string `json:"asset_id"` + PriceUsd sql.NullFloat64 `json:"price_usd"` + PriceBtc sql.NullFloat64 `json:"price_btc"` + Volume24hUsd sql.NullFloat64 `json:"volume_24h_usd"` + MarketCapUsd sql.NullFloat64 `json:"market_cap_usd"` + AvailableSupply sql.NullFloat64 `json:"available_supply"` + TotalSupply sql.NullFloat64 `json:"total_supply"` + MaxSupply sql.NullFloat64 `json:"max_supply"` + PercentChange1h sql.NullFloat64 `json:"percent_change_1h"` + PercentChange24h sql.NullFloat64 `json:"percent_change_24h"` + PercentChange7d sql.NullFloat64 `json:"percent_change_7d"` + Rank sql.NullInt64 `json:"rank"` + LastUpdated time.Time `json:"last_updated"` +} + +// PRICE QUERIES (UPDATED) +func (q *Queries) InsertPrice(ctx context.Context, arg InsertPriceParams) (Price, error) { + row := q.db.QueryRowContext(ctx, insertPrice, + arg.AssetID, + arg.PriceUsd, + arg.PriceBtc, + arg.Volume24hUsd, + arg.MarketCapUsd, + arg.AvailableSupply, + arg.TotalSupply, + arg.MaxSupply, + arg.PercentChange1h, + arg.PercentChange24h, + arg.PercentChange7d, + arg.Rank, + arg.LastUpdated, + ) + var i Price + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.AssetID, + &i.PriceUsd, + &i.PriceBtc, + &i.Volume24hUsd, + &i.MarketCapUsd, + &i.AvailableSupply, + &i.TotalSupply, + &i.MaxSupply, + &i.PercentChange1h, + &i.PercentChange24h, + &i.PercentChange7d, + &i.Rank, + &i.LastUpdated, + ) + return i, err +} + +const insertPriceConversion = `-- name: InsertPriceConversion :one +INSERT INTO price_conversions ( + price_id, + currency_code, + price, + volume_24h, + market_cap, + last_updated +) VALUES (?, ?, ?, ?, ?, ?) +RETURNING id, created_at, updated_at, deleted_at, price_id, currency_code, price, volume_24h, market_cap, last_updated +` + +type InsertPriceConversionParams struct { + PriceID string `json:"price_id"` + CurrencyCode string `json:"currency_code"` + Price sql.NullFloat64 `json:"price"` + Volume24h sql.NullFloat64 `json:"volume_24h"` + MarketCap sql.NullFloat64 `json:"market_cap"` + LastUpdated time.Time `json:"last_updated"` +} + +// PRICE CONVERSION QUERIES (NEW) +func (q *Queries) InsertPriceConversion(ctx context.Context, arg InsertPriceConversionParams) (PriceConversion, error) { + row := q.db.QueryRowContext(ctx, insertPriceConversion, + arg.PriceID, + arg.CurrencyCode, + arg.Price, + arg.Volume24h, + arg.MarketCap, + arg.LastUpdated, + ) + var i PriceConversion + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.PriceID, + &i.CurrencyCode, + &i.Price, + &i.Volume24h, + &i.MarketCap, + &i.LastUpdated, + ) + return i, err +} + +const listAllBlockchains = `-- name: ListAllBlockchains :many +SELECT id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum FROM blockchains +WHERE deleted_at IS NULL +ORDER BY chain_name ASC +` + +func (q *Queries) ListAllBlockchains(ctx context.Context) ([]Blockchain, error) { + rows, err := q.db.QueryContext(ctx, listAllBlockchains) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Blockchain + for rows.Next() { + var i Blockchain + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listAssetsByChain = `-- name: ListAssetsByChain :many +SELECT id, created_at, updated_at, deleted_at, name, symbol, decimals, chain_id, channel, asset_type, coingecko_id FROM assets +WHERE chain_id = ? AND deleted_at IS NULL +ORDER BY symbol ASC +` + +func (q *Queries) ListAssetsByChain(ctx context.Context, chainID string) ([]Asset, error) { + rows, err := q.db.QueryContext(ctx, listAssetsByChain, chainID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Asset + for rows.Next() { + var i Asset + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Name, + &i.Symbol, + &i.Decimals, + &i.ChainID, + &i.Channel, + &i.AssetType, + &i.CoingeckoID, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listAssetsWithLatestPrices = `-- name: ListAssetsWithLatestPrices :many +SELECT a.id, a.created_at, a.updated_at, a.deleted_at, a.name, a.symbol, a.decimals, a.chain_id, a.channel, a.asset_type, a.coingecko_id, p.price_usd, p.price_btc, p.volume_24h_usd, p.market_cap_usd, + p.available_supply, p.total_supply, p.max_supply, + p.percent_change_1h, p.percent_change_24h, p.percent_change_7d, + p.rank, p.last_updated +FROM assets a +LEFT JOIN ( + SELECT p1.id, p1.created_at, p1.updated_at, p1.deleted_at, p1.asset_id, p1.price_usd, p1.price_btc, p1.volume_24h_usd, p1.market_cap_usd, p1.available_supply, p1.total_supply, p1.max_supply, p1.percent_change_1h, p1.percent_change_24h, p1.percent_change_7d, p1.rank, p1.last_updated + FROM prices p1 + INNER JOIN ( + SELECT asset_id, MAX(last_updated) as max_date + FROM prices + WHERE deleted_at IS NULL + GROUP BY asset_id + ) p2 ON p1.asset_id = p2.asset_id AND p1.last_updated = p2.max_date + WHERE p1.deleted_at IS NULL +) p ON a.id = p.asset_id +WHERE a.deleted_at IS NULL +ORDER BY p.rank ASC, a.symbol ASC +LIMIT ? OFFSET ? +` + +type ListAssetsWithLatestPricesParams struct { + Limit int64 `json:"limit"` + Offset int64 `json:"offset"` +} + +type ListAssetsWithLatestPricesRow struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt sql.NullTime `json:"deleted_at"` + Name string `json:"name"` + Symbol string `json:"symbol"` + Decimals int64 `json:"decimals"` + ChainID string `json:"chain_id"` + Channel string `json:"channel"` + AssetType string `json:"asset_type"` + CoingeckoID sql.NullString `json:"coingecko_id"` + PriceUsd sql.NullFloat64 `json:"price_usd"` + PriceBtc sql.NullFloat64 `json:"price_btc"` + Volume24hUsd sql.NullFloat64 `json:"volume_24h_usd"` + MarketCapUsd sql.NullFloat64 `json:"market_cap_usd"` + AvailableSupply sql.NullFloat64 `json:"available_supply"` + TotalSupply sql.NullFloat64 `json:"total_supply"` + MaxSupply sql.NullFloat64 `json:"max_supply"` + PercentChange1h sql.NullFloat64 `json:"percent_change_1h"` + PercentChange24h sql.NullFloat64 `json:"percent_change_24h"` + PercentChange7d sql.NullFloat64 `json:"percent_change_7d"` + Rank sql.NullInt64 `json:"rank"` + LastUpdated time.Time `json:"last_updated"` +} + +func (q *Queries) ListAssetsWithLatestPrices(ctx context.Context, arg ListAssetsWithLatestPricesParams) ([]ListAssetsWithLatestPricesRow, error) { + rows, err := q.db.QueryContext(ctx, listAssetsWithLatestPrices, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + var items []ListAssetsWithLatestPricesRow + for rows.Next() { + var i ListAssetsWithLatestPricesRow + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Name, + &i.Symbol, + &i.Decimals, + &i.ChainID, + &i.Channel, + &i.AssetType, + &i.CoingeckoID, + &i.PriceUsd, + &i.PriceBtc, + &i.Volume24hUsd, + &i.MarketCapUsd, + &i.AvailableSupply, + &i.TotalSupply, + &i.MaxSupply, + &i.PercentChange1h, + &i.PercentChange24h, + &i.PercentChange7d, + &i.Rank, + &i.LastUpdated, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listBlockchainsByChainType = `-- name: ListBlockchainsByChainType :many +SELECT id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum FROM blockchains +WHERE chain_type LIKE '%' || ? || '%' AND deleted_at IS NULL +ORDER BY chain_name ASC +` + +func (q *Queries) ListBlockchainsByChainType(ctx context.Context, dollar_1 sql.NullString) ([]Blockchain, error) { + rows, err := q.db.QueryContext(ctx, listBlockchainsByChainType, dollar_1) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Blockchain + for rows.Next() { + var i Blockchain + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listBlockchainsWithAssetInfo = `-- name: ListBlockchainsWithAssetInfo :many +SELECT b.id, b.created_at, b.updated_at, b.deleted_at, b.chain_name, b.chain_id_cosmos, b.chain_id_evm, b.api_name, b.bech_account_prefix, b.bech_validator_prefix, b.main_asset_symbol, b.main_asset_denom, b.staking_asset_symbol, b.staking_asset_denom, b.is_stake_enabled, b.chain_image, b.main_asset_image, b.staking_asset_image, b.chain_type, b.is_support_mobile_wallet, b.is_support_extension_wallet, b.is_support_erc20, b.description_en, b.description_ko, b.description_ja, b.origin_genesis_time, b.account_type, b.btc_staking, b.cosmos_fee_info, b.evm_fee_info, b.lcd_endpoint, b.grpc_endpoint, b.evm_rpc_endpoint, b.explorer, b.about, b.forum, a.id as asset_id, a.symbol, a.decimals, p.price_usd, p.price_btc +FROM blockchains b +LEFT JOIN assets a ON b.main_asset_symbol = a.symbol +LEFT JOIN ( + SELECT p1.id, p1.created_at, p1.updated_at, p1.deleted_at, p1.asset_id, p1.price_usd, p1.price_btc, p1.volume_24h_usd, p1.market_cap_usd, p1.available_supply, p1.total_supply, p1.max_supply, p1.percent_change_1h, p1.percent_change_24h, p1.percent_change_7d, p1.rank, p1.last_updated + FROM prices p1 + INNER JOIN ( + SELECT asset_id, MAX(last_updated) as max_date + FROM prices + WHERE deleted_at IS NULL + GROUP BY asset_id + ) p2 ON p1.asset_id = p2.asset_id AND p1.last_updated = p2.max_date + WHERE p1.deleted_at IS NULL +) p ON a.id = p.asset_id +WHERE b.deleted_at IS NULL +ORDER BY b.chain_name ASC +LIMIT ? OFFSET ? +` + +type ListBlockchainsWithAssetInfoParams struct { + Limit int64 `json:"limit"` + Offset int64 `json:"offset"` +} + +type ListBlockchainsWithAssetInfoRow struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt sql.NullTime `json:"deleted_at"` + ChainName string `json:"chain_name"` + ChainIDCosmos sql.NullString `json:"chain_id_cosmos"` + ChainIDEvm sql.NullString `json:"chain_id_evm"` + ApiName sql.NullString `json:"api_name"` + BechAccountPrefix sql.NullString `json:"bech_account_prefix"` + BechValidatorPrefix sql.NullString `json:"bech_validator_prefix"` + MainAssetSymbol sql.NullString `json:"main_asset_symbol"` + MainAssetDenom sql.NullString `json:"main_asset_denom"` + StakingAssetSymbol sql.NullString `json:"staking_asset_symbol"` + StakingAssetDenom sql.NullString `json:"staking_asset_denom"` + IsStakeEnabled bool `json:"is_stake_enabled"` + ChainImage sql.NullString `json:"chain_image"` + MainAssetImage sql.NullString `json:"main_asset_image"` + StakingAssetImage sql.NullString `json:"staking_asset_image"` + ChainType string `json:"chain_type"` + IsSupportMobileWallet bool `json:"is_support_mobile_wallet"` + IsSupportExtensionWallet bool `json:"is_support_extension_wallet"` + IsSupportErc20 bool `json:"is_support_erc20"` + DescriptionEn sql.NullString `json:"description_en"` + DescriptionKo sql.NullString `json:"description_ko"` + DescriptionJa sql.NullString `json:"description_ja"` + OriginGenesisTime sql.NullTime `json:"origin_genesis_time"` + AccountType string `json:"account_type"` + BtcStaking sql.NullString `json:"btc_staking"` + CosmosFeeInfo sql.NullString `json:"cosmos_fee_info"` + EvmFeeInfo sql.NullString `json:"evm_fee_info"` + LcdEndpoint sql.NullString `json:"lcd_endpoint"` + GrpcEndpoint sql.NullString `json:"grpc_endpoint"` + EvmRpcEndpoint sql.NullString `json:"evm_rpc_endpoint"` + Explorer sql.NullString `json:"explorer"` + About sql.NullString `json:"about"` + Forum sql.NullString `json:"forum"` + AssetID sql.NullString `json:"asset_id"` + Symbol sql.NullString `json:"symbol"` + Decimals sql.NullInt64 `json:"decimals"` + PriceUsd sql.NullFloat64 `json:"price_usd"` + PriceBtc sql.NullFloat64 `json:"price_btc"` +} + +func (q *Queries) ListBlockchainsWithAssetInfo(ctx context.Context, arg ListBlockchainsWithAssetInfoParams) ([]ListBlockchainsWithAssetInfoRow, error) { + rows, err := q.db.QueryContext(ctx, listBlockchainsWithAssetInfo, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + var items []ListBlockchainsWithAssetInfoRow + for rows.Next() { + var i ListBlockchainsWithAssetInfoRow + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + &i.AssetID, + &i.Symbol, + &i.Decimals, + &i.PriceUsd, + &i.PriceBtc, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listBlockchainsWithERC20Support = `-- name: ListBlockchainsWithERC20Support :many +SELECT id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum FROM blockchains +WHERE is_support_erc20 = 1 AND deleted_at IS NULL +ORDER BY chain_name ASC +` + +func (q *Queries) ListBlockchainsWithERC20Support(ctx context.Context) ([]Blockchain, error) { + rows, err := q.db.QueryContext(ctx, listBlockchainsWithERC20Support) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Blockchain + for rows.Next() { + var i Blockchain + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listBlockchainsWithExtensionSupport = `-- name: ListBlockchainsWithExtensionSupport :many +SELECT id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum FROM blockchains +WHERE is_support_extension_wallet = 1 AND deleted_at IS NULL +ORDER BY chain_name ASC +` + +func (q *Queries) ListBlockchainsWithExtensionSupport(ctx context.Context) ([]Blockchain, error) { + rows, err := q.db.QueryContext(ctx, listBlockchainsWithExtensionSupport) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Blockchain + for rows.Next() { + var i Blockchain + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listBlockchainsWithMobileSupport = `-- name: ListBlockchainsWithMobileSupport :many +SELECT id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum FROM blockchains +WHERE is_support_mobile_wallet = 1 AND deleted_at IS NULL +ORDER BY chain_name ASC +` + +func (q *Queries) ListBlockchainsWithMobileSupport(ctx context.Context) ([]Blockchain, error) { + rows, err := q.db.QueryContext(ctx, listBlockchainsWithMobileSupport) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Blockchain + for rows.Next() { + var i Blockchain + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listBlockchainsWithStaking = `-- name: ListBlockchainsWithStaking :many +SELECT id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum FROM blockchains +WHERE is_stake_enabled = 1 AND deleted_at IS NULL +ORDER BY chain_name ASC +` + +func (q *Queries) ListBlockchainsWithStaking(ctx context.Context) ([]Blockchain, error) { + rows, err := q.db.QueryContext(ctx, listBlockchainsWithStaking) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Blockchain + for rows.Next() { + var i Blockchain + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listPriceHistoryByAssetID = `-- name: ListPriceHistoryByAssetID :many +SELECT id, created_at, updated_at, deleted_at, asset_id, price_usd, price_btc, volume_24h_usd, market_cap_usd, available_supply, total_supply, max_supply, percent_change_1h, percent_change_24h, percent_change_7d, rank, last_updated FROM prices +WHERE asset_id = ? AND deleted_at IS NULL +ORDER BY last_updated DESC +LIMIT ? OFFSET ? +` + +type ListPriceHistoryByAssetIDParams struct { + AssetID string `json:"asset_id"` + Limit int64 `json:"limit"` + Offset int64 `json:"offset"` +} + +func (q *Queries) ListPriceHistoryByAssetID(ctx context.Context, arg ListPriceHistoryByAssetIDParams) ([]Price, error) { + rows, err := q.db.QueryContext(ctx, listPriceHistoryByAssetID, arg.AssetID, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Price + for rows.Next() { + var i Price + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.AssetID, + &i.PriceUsd, + &i.PriceBtc, + &i.Volume24hUsd, + &i.MarketCapUsd, + &i.AvailableSupply, + &i.TotalSupply, + &i.MaxSupply, + &i.PercentChange1h, + &i.PercentChange24h, + &i.PercentChange7d, + &i.Rank, + &i.LastUpdated, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const searchBlockchains = `-- name: SearchBlockchains :many +SELECT id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum FROM blockchains +WHERE ( + chain_name LIKE '%' || ? || '%' OR + main_asset_symbol LIKE '%' || ? || '%' OR + staking_asset_symbol LIKE '%' || ? || '%' OR + description_en LIKE '%' || ? || '%' +) AND deleted_at IS NULL +ORDER BY chain_name ASC +LIMIT ? OFFSET ? +` + +type SearchBlockchainsParams struct { + Column1 sql.NullString `json:"column_1"` + Column2 sql.NullString `json:"column_2"` + Column3 sql.NullString `json:"column_3"` + Column4 sql.NullString `json:"column_4"` + Limit int64 `json:"limit"` + Offset int64 `json:"offset"` +} + +func (q *Queries) SearchBlockchains(ctx context.Context, arg SearchBlockchainsParams) ([]Blockchain, error) { + rows, err := q.db.QueryContext(ctx, searchBlockchains, + arg.Column1, + arg.Column2, + arg.Column3, + arg.Column4, + arg.Limit, + arg.Offset, + ) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Blockchain + for rows.Next() { + var i Blockchain + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const softDeleteAsset = `-- name: SoftDeleteAsset :exec +UPDATE assets +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ? +` + +func (q *Queries) SoftDeleteAsset(ctx context.Context, id string) error { + _, err := q.db.ExecContext(ctx, softDeleteAsset, id) + return err +} + +const softDeleteBlockchain = `-- name: SoftDeleteBlockchain :exec +UPDATE blockchains +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ? +` + +func (q *Queries) SoftDeleteBlockchain(ctx context.Context, id string) error { + _, err := q.db.ExecContext(ctx, softDeleteBlockchain, id) + return err +} + +const softDeletePriceConversion = `-- name: SoftDeletePriceConversion :exec +UPDATE price_conversions +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ? +` + +func (q *Queries) SoftDeletePriceConversion(ctx context.Context, id string) error { + _, err := q.db.ExecContext(ctx, softDeletePriceConversion, id) + return err +} + +const updateAsset = `-- name: UpdateAsset :one +UPDATE assets +SET + name = ?, + decimals = ?, + channel = ?, + asset_type = ?, + coingecko_id = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, name, symbol, decimals, chain_id, channel, asset_type, coingecko_id +` + +type UpdateAssetParams struct { + Name string `json:"name"` + Decimals int64 `json:"decimals"` + Channel string `json:"channel"` + AssetType string `json:"asset_type"` + CoingeckoID sql.NullString `json:"coingecko_id"` + ID string `json:"id"` +} + +func (q *Queries) UpdateAsset(ctx context.Context, arg UpdateAssetParams) (Asset, error) { + row := q.db.QueryRowContext(ctx, updateAsset, + arg.Name, + arg.Decimals, + arg.Channel, + arg.AssetType, + arg.CoingeckoID, + arg.ID, + ) + var i Asset + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Name, + &i.Symbol, + &i.Decimals, + &i.ChainID, + &i.Channel, + &i.AssetType, + &i.CoingeckoID, + ) + return i, err +} + +const updateBlockchain = `-- name: UpdateBlockchain :one +UPDATE blockchains +SET + chain_name = ?, + chain_id_cosmos = ?, + chain_id_evm = ?, + api_name = ?, + bech_account_prefix = ?, + bech_validator_prefix = ?, + main_asset_symbol = ?, + main_asset_denom = ?, + staking_asset_symbol = ?, + staking_asset_denom = ?, + is_stake_enabled = ?, + chain_image = ?, + main_asset_image = ?, + staking_asset_image = ?, + chain_type = ?, + is_support_mobile_wallet = ?, + is_support_extension_wallet = ?, + is_support_erc20 = ?, + description_en = ?, + description_ko = ?, + description_ja = ?, + origin_genesis_time = ?, + account_type = ?, + btc_staking = ?, + cosmos_fee_info = ?, + evm_fee_info = ?, + lcd_endpoint = ?, + grpc_endpoint = ?, + evm_rpc_endpoint = ?, + explorer = ?, + about = ?, + forum = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum +` + +type UpdateBlockchainParams struct { + ChainName string `json:"chain_name"` + ChainIDCosmos sql.NullString `json:"chain_id_cosmos"` + ChainIDEvm sql.NullString `json:"chain_id_evm"` + ApiName sql.NullString `json:"api_name"` + BechAccountPrefix sql.NullString `json:"bech_account_prefix"` + BechValidatorPrefix sql.NullString `json:"bech_validator_prefix"` + MainAssetSymbol sql.NullString `json:"main_asset_symbol"` + MainAssetDenom sql.NullString `json:"main_asset_denom"` + StakingAssetSymbol sql.NullString `json:"staking_asset_symbol"` + StakingAssetDenom sql.NullString `json:"staking_asset_denom"` + IsStakeEnabled bool `json:"is_stake_enabled"` + ChainImage sql.NullString `json:"chain_image"` + MainAssetImage sql.NullString `json:"main_asset_image"` + StakingAssetImage sql.NullString `json:"staking_asset_image"` + ChainType string `json:"chain_type"` + IsSupportMobileWallet bool `json:"is_support_mobile_wallet"` + IsSupportExtensionWallet bool `json:"is_support_extension_wallet"` + IsSupportErc20 bool `json:"is_support_erc20"` + DescriptionEn sql.NullString `json:"description_en"` + DescriptionKo sql.NullString `json:"description_ko"` + DescriptionJa sql.NullString `json:"description_ja"` + OriginGenesisTime sql.NullTime `json:"origin_genesis_time"` + AccountType string `json:"account_type"` + BtcStaking sql.NullString `json:"btc_staking"` + CosmosFeeInfo sql.NullString `json:"cosmos_fee_info"` + EvmFeeInfo sql.NullString `json:"evm_fee_info"` + LcdEndpoint sql.NullString `json:"lcd_endpoint"` + GrpcEndpoint sql.NullString `json:"grpc_endpoint"` + EvmRpcEndpoint sql.NullString `json:"evm_rpc_endpoint"` + Explorer sql.NullString `json:"explorer"` + About sql.NullString `json:"about"` + Forum sql.NullString `json:"forum"` + ID string `json:"id"` +} + +func (q *Queries) UpdateBlockchain(ctx context.Context, arg UpdateBlockchainParams) (Blockchain, error) { + row := q.db.QueryRowContext(ctx, updateBlockchain, + arg.ChainName, + arg.ChainIDCosmos, + arg.ChainIDEvm, + arg.ApiName, + arg.BechAccountPrefix, + arg.BechValidatorPrefix, + arg.MainAssetSymbol, + arg.MainAssetDenom, + arg.StakingAssetSymbol, + arg.StakingAssetDenom, + arg.IsStakeEnabled, + arg.ChainImage, + arg.MainAssetImage, + arg.StakingAssetImage, + arg.ChainType, + arg.IsSupportMobileWallet, + arg.IsSupportExtensionWallet, + arg.IsSupportErc20, + arg.DescriptionEn, + arg.DescriptionKo, + arg.DescriptionJa, + arg.OriginGenesisTime, + arg.AccountType, + arg.BtcStaking, + arg.CosmosFeeInfo, + arg.EvmFeeInfo, + arg.LcdEndpoint, + arg.GrpcEndpoint, + arg.EvmRpcEndpoint, + arg.Explorer, + arg.About, + arg.Forum, + arg.ID, + ) + var i Blockchain + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ) + return i, err +} + +const updateBlockchainDescriptions = `-- name: UpdateBlockchainDescriptions :one +UPDATE blockchains +SET + description_en = ?, + description_ko = ?, + description_ja = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum +` + +type UpdateBlockchainDescriptionsParams struct { + DescriptionEn sql.NullString `json:"description_en"` + DescriptionKo sql.NullString `json:"description_ko"` + DescriptionJa sql.NullString `json:"description_ja"` + ID string `json:"id"` +} + +func (q *Queries) UpdateBlockchainDescriptions(ctx context.Context, arg UpdateBlockchainDescriptionsParams) (Blockchain, error) { + row := q.db.QueryRowContext(ctx, updateBlockchainDescriptions, + arg.DescriptionEn, + arg.DescriptionKo, + arg.DescriptionJa, + arg.ID, + ) + var i Blockchain + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ) + return i, err +} + +const updateBlockchainEndpoints = `-- name: UpdateBlockchainEndpoints :one +UPDATE blockchains +SET + lcd_endpoint = ?, + grpc_endpoint = ?, + evm_rpc_endpoint = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum +` + +type UpdateBlockchainEndpointsParams struct { + LcdEndpoint sql.NullString `json:"lcd_endpoint"` + GrpcEndpoint sql.NullString `json:"grpc_endpoint"` + EvmRpcEndpoint sql.NullString `json:"evm_rpc_endpoint"` + ID string `json:"id"` +} + +func (q *Queries) UpdateBlockchainEndpoints(ctx context.Context, arg UpdateBlockchainEndpointsParams) (Blockchain, error) { + row := q.db.QueryRowContext(ctx, updateBlockchainEndpoints, + arg.LcdEndpoint, + arg.GrpcEndpoint, + arg.EvmRpcEndpoint, + arg.ID, + ) + var i Blockchain + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ) + return i, err +} + +const updateBlockchainExplorer = `-- name: UpdateBlockchainExplorer :one +UPDATE blockchains +SET + explorer = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum +` + +type UpdateBlockchainExplorerParams struct { + Explorer sql.NullString `json:"explorer"` + ID string `json:"id"` +} + +func (q *Queries) UpdateBlockchainExplorer(ctx context.Context, arg UpdateBlockchainExplorerParams) (Blockchain, error) { + row := q.db.QueryRowContext(ctx, updateBlockchainExplorer, arg.Explorer, arg.ID) + var i Blockchain + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ) + return i, err +} + +const updateBlockchainFeeInfo = `-- name: UpdateBlockchainFeeInfo :one +UPDATE blockchains +SET + cosmos_fee_info = ?, + evm_fee_info = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum +` + +type UpdateBlockchainFeeInfoParams struct { + CosmosFeeInfo sql.NullString `json:"cosmos_fee_info"` + EvmFeeInfo sql.NullString `json:"evm_fee_info"` + ID string `json:"id"` +} + +func (q *Queries) UpdateBlockchainFeeInfo(ctx context.Context, arg UpdateBlockchainFeeInfoParams) (Blockchain, error) { + row := q.db.QueryRowContext(ctx, updateBlockchainFeeInfo, arg.CosmosFeeInfo, arg.EvmFeeInfo, arg.ID) + var i Blockchain + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ) + return i, err +} + +const updateBlockchainImages = `-- name: UpdateBlockchainImages :one +UPDATE blockchains +SET + chain_image = ?, + main_asset_image = ?, + staking_asset_image = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum +` + +type UpdateBlockchainImagesParams struct { + ChainImage sql.NullString `json:"chain_image"` + MainAssetImage sql.NullString `json:"main_asset_image"` + StakingAssetImage sql.NullString `json:"staking_asset_image"` + ID string `json:"id"` +} + +func (q *Queries) UpdateBlockchainImages(ctx context.Context, arg UpdateBlockchainImagesParams) (Blockchain, error) { + row := q.db.QueryRowContext(ctx, updateBlockchainImages, + arg.ChainImage, + arg.MainAssetImage, + arg.StakingAssetImage, + arg.ID, + ) + var i Blockchain + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ) + return i, err +} + +const updateBlockchainSocialLinks = `-- name: UpdateBlockchainSocialLinks :one +UPDATE blockchains +SET + about = ?, + forum = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, chain_name, chain_id_cosmos, chain_id_evm, api_name, bech_account_prefix, bech_validator_prefix, main_asset_symbol, main_asset_denom, staking_asset_symbol, staking_asset_denom, is_stake_enabled, chain_image, main_asset_image, staking_asset_image, chain_type, is_support_mobile_wallet, is_support_extension_wallet, is_support_erc20, description_en, description_ko, description_ja, origin_genesis_time, account_type, btc_staking, cosmos_fee_info, evm_fee_info, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint, explorer, about, forum +` + +type UpdateBlockchainSocialLinksParams struct { + About sql.NullString `json:"about"` + Forum sql.NullString `json:"forum"` + ID string `json:"id"` +} + +func (q *Queries) UpdateBlockchainSocialLinks(ctx context.Context, arg UpdateBlockchainSocialLinksParams) (Blockchain, error) { + row := q.db.QueryRowContext(ctx, updateBlockchainSocialLinks, arg.About, arg.Forum, arg.ID) + var i Blockchain + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.ChainName, + &i.ChainIDCosmos, + &i.ChainIDEvm, + &i.ApiName, + &i.BechAccountPrefix, + &i.BechValidatorPrefix, + &i.MainAssetSymbol, + &i.MainAssetDenom, + &i.StakingAssetSymbol, + &i.StakingAssetDenom, + &i.IsStakeEnabled, + &i.ChainImage, + &i.MainAssetImage, + &i.StakingAssetImage, + &i.ChainType, + &i.IsSupportMobileWallet, + &i.IsSupportExtensionWallet, + &i.IsSupportErc20, + &i.DescriptionEn, + &i.DescriptionKo, + &i.DescriptionJa, + &i.OriginGenesisTime, + &i.AccountType, + &i.BtcStaking, + &i.CosmosFeeInfo, + &i.EvmFeeInfo, + &i.LcdEndpoint, + &i.GrpcEndpoint, + &i.EvmRpcEndpoint, + &i.Explorer, + &i.About, + &i.Forum, + ) + return i, err +} + +const updatePrice = `-- name: UpdatePrice :one +UPDATE prices +SET + price_usd = ?, + price_btc = ?, + volume_24h_usd = ?, + market_cap_usd = ?, + available_supply = ?, + total_supply = ?, + max_supply = ?, + percent_change_1h = ?, + percent_change_24h = ?, + percent_change_7d = ?, + rank = ?, + last_updated = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, asset_id, price_usd, price_btc, volume_24h_usd, market_cap_usd, available_supply, total_supply, max_supply, percent_change_1h, percent_change_24h, percent_change_7d, rank, last_updated +` + +type UpdatePriceParams struct { + PriceUsd sql.NullFloat64 `json:"price_usd"` + PriceBtc sql.NullFloat64 `json:"price_btc"` + Volume24hUsd sql.NullFloat64 `json:"volume_24h_usd"` + MarketCapUsd sql.NullFloat64 `json:"market_cap_usd"` + AvailableSupply sql.NullFloat64 `json:"available_supply"` + TotalSupply sql.NullFloat64 `json:"total_supply"` + MaxSupply sql.NullFloat64 `json:"max_supply"` + PercentChange1h sql.NullFloat64 `json:"percent_change_1h"` + PercentChange24h sql.NullFloat64 `json:"percent_change_24h"` + PercentChange7d sql.NullFloat64 `json:"percent_change_7d"` + Rank sql.NullInt64 `json:"rank"` + LastUpdated time.Time `json:"last_updated"` + ID string `json:"id"` +} + +func (q *Queries) UpdatePrice(ctx context.Context, arg UpdatePriceParams) (Price, error) { + row := q.db.QueryRowContext(ctx, updatePrice, + arg.PriceUsd, + arg.PriceBtc, + arg.Volume24hUsd, + arg.MarketCapUsd, + arg.AvailableSupply, + arg.TotalSupply, + arg.MaxSupply, + arg.PercentChange1h, + arg.PercentChange24h, + arg.PercentChange7d, + arg.Rank, + arg.LastUpdated, + arg.ID, + ) + var i Price + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.AssetID, + &i.PriceUsd, + &i.PriceBtc, + &i.Volume24hUsd, + &i.MarketCapUsd, + &i.AvailableSupply, + &i.TotalSupply, + &i.MaxSupply, + &i.PercentChange1h, + &i.PercentChange24h, + &i.PercentChange7d, + &i.Rank, + &i.LastUpdated, + ) + return i, err +} + +const updatePriceConversion = `-- name: UpdatePriceConversion :one +UPDATE price_conversions +SET + price = ?, + volume_24h = ?, + market_cap = ?, + last_updated = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, price_id, currency_code, price, volume_24h, market_cap, last_updated +` + +type UpdatePriceConversionParams struct { + Price sql.NullFloat64 `json:"price"` + Volume24h sql.NullFloat64 `json:"volume_24h"` + MarketCap sql.NullFloat64 `json:"market_cap"` + LastUpdated time.Time `json:"last_updated"` + ID string `json:"id"` +} + +func (q *Queries) UpdatePriceConversion(ctx context.Context, arg UpdatePriceConversionParams) (PriceConversion, error) { + row := q.db.QueryRowContext(ctx, updatePriceConversion, + arg.Price, + arg.Volume24h, + arg.MarketCap, + arg.LastUpdated, + arg.ID, + ) + var i PriceConversion + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.PriceID, + &i.CurrencyCode, + &i.Price, + &i.Volume24h, + &i.MarketCap, + &i.LastUpdated, + ) + return i, err +} diff --git a/network/sink/query.sql b/network/sink/query.sql new file mode 100644 index 0000000..b228615 --- /dev/null +++ b/network/sink/query.sql @@ -0,0 +1,453 @@ +-- ASSET QUERIES +-- name: InsertAsset :one +INSERT INTO assets ( + name, + symbol, + decimals, + chain_id, + channel, + asset_type, + coingecko_id +) VALUES (?, ?, ?, ?, ?, ?, ?) +RETURNING *; + +-- name: GetAssetByID :one +SELECT * FROM assets +WHERE id = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetAssetBySymbol :one +SELECT * FROM assets +WHERE symbol = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetAssetByChainAndSymbol :one +SELECT * FROM assets +WHERE chain_id = ? AND symbol = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: ListAssetsByChain :many +SELECT * FROM assets +WHERE chain_id = ? AND deleted_at IS NULL +ORDER BY symbol ASC; + +-- name: UpdateAsset :one +UPDATE assets +SET + name = ?, + decimals = ?, + channel = ?, + asset_type = ?, + coingecko_id = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: SoftDeleteAsset :exec +UPDATE assets +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ?; + +-- PRICE QUERIES (UPDATED) +-- name: InsertPrice :one +INSERT INTO prices ( + asset_id, + price_usd, + price_btc, + volume_24h_usd, + market_cap_usd, + available_supply, + total_supply, + max_supply, + percent_change_1h, + percent_change_24h, + percent_change_7d, + rank, + last_updated +) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) +RETURNING *; + +-- name: GetPriceByAssetID :one +SELECT * FROM prices +WHERE asset_id = ? AND deleted_at IS NULL +ORDER BY last_updated DESC +LIMIT 1; + +-- name: GetPriceByID :one +SELECT * FROM prices +WHERE id = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: ListPriceHistoryByAssetID :many +SELECT * FROM prices +WHERE asset_id = ? AND deleted_at IS NULL +ORDER BY last_updated DESC +LIMIT ? OFFSET ?; + +-- name: GetAssetWithLatestPrice :one +SELECT a.*, p.price_usd, p.price_btc, p.volume_24h_usd, p.market_cap_usd, + p.available_supply, p.total_supply, p.max_supply, + p.percent_change_1h, p.percent_change_24h, p.percent_change_7d, + p.rank, p.last_updated +FROM assets a +LEFT JOIN ( + SELECT p1.* + FROM prices p1 + INNER JOIN ( + SELECT asset_id, MAX(last_updated) as max_date + FROM prices + WHERE deleted_at IS NULL + GROUP BY asset_id + ) p2 ON p1.asset_id = p2.asset_id AND p1.last_updated = p2.max_date + WHERE p1.deleted_at IS NULL +) p ON a.id = p.asset_id +WHERE a.id = ? AND a.deleted_at IS NULL +LIMIT 1; + +-- name: ListAssetsWithLatestPrices :many +SELECT a.*, p.price_usd, p.price_btc, p.volume_24h_usd, p.market_cap_usd, + p.available_supply, p.total_supply, p.max_supply, + p.percent_change_1h, p.percent_change_24h, p.percent_change_7d, + p.rank, p.last_updated +FROM assets a +LEFT JOIN ( + SELECT p1.* + FROM prices p1 + INNER JOIN ( + SELECT asset_id, MAX(last_updated) as max_date + FROM prices + WHERE deleted_at IS NULL + GROUP BY asset_id + ) p2 ON p1.asset_id = p2.asset_id AND p1.last_updated = p2.max_date + WHERE p1.deleted_at IS NULL +) p ON a.id = p.asset_id +WHERE a.deleted_at IS NULL +ORDER BY p.rank ASC, a.symbol ASC +LIMIT ? OFFSET ?; + +-- name: UpdatePrice :one +UPDATE prices +SET + price_usd = ?, + price_btc = ?, + volume_24h_usd = ?, + market_cap_usd = ?, + available_supply = ?, + total_supply = ?, + max_supply = ?, + percent_change_1h = ?, + percent_change_24h = ?, + percent_change_7d = ?, + rank = ?, + last_updated = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING *; + +-- PRICE CONVERSION QUERIES (NEW) +-- name: InsertPriceConversion :one +INSERT INTO price_conversions ( + price_id, + currency_code, + price, + volume_24h, + market_cap, + last_updated +) VALUES (?, ?, ?, ?, ?, ?) +RETURNING *; + +-- name: GetPriceConversionByID :one +SELECT * FROM price_conversions +WHERE id = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetPriceConversionsByPriceID :many +SELECT * FROM price_conversions +WHERE price_id = ? AND deleted_at IS NULL +ORDER BY currency_code ASC; + +-- name: GetPriceConversionByCurrency :one +SELECT * FROM price_conversions +WHERE price_id = ? AND currency_code = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: UpdatePriceConversion :one +UPDATE price_conversions +SET + price = ?, + volume_24h = ?, + market_cap = ?, + last_updated = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: SoftDeletePriceConversion :exec +UPDATE price_conversions +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ?; + +-- BLOCKCHAIN QUERIES +-- name: InsertBlockchain :one +INSERT INTO blockchains ( + id, + chain_name, + chain_id_cosmos, + chain_id_evm, + api_name, + bech_account_prefix, + bech_validator_prefix, + main_asset_symbol, + main_asset_denom, + staking_asset_symbol, + staking_asset_denom, + is_stake_enabled, + chain_image, + main_asset_image, + staking_asset_image, + chain_type, + is_support_mobile_wallet, + is_support_extension_wallet, + is_support_erc20, + description_en, + description_ko, + description_ja, + origin_genesis_time, + account_type, + btc_staking, + cosmos_fee_info, + evm_fee_info, + lcd_endpoint, + grpc_endpoint, + evm_rpc_endpoint, + explorer, + about, + forum +) VALUES ( + ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? +) +RETURNING *; + +-- name: GetBlockchainByID :one +SELECT * FROM blockchains +WHERE id = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetBlockchainByChainName :one +SELECT * FROM blockchains +WHERE chain_name = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetBlockchainByCosmosChainID :one +SELECT * FROM blockchains +WHERE chain_id_cosmos = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetBlockchainByEvmChainID :one +SELECT * FROM blockchains +WHERE chain_id_evm = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: ListAllBlockchains :many +SELECT * FROM blockchains +WHERE deleted_at IS NULL +ORDER BY chain_name ASC; + +-- name: ListBlockchainsByChainType :many +SELECT * FROM blockchains +WHERE chain_type LIKE '%' || ? || '%' AND deleted_at IS NULL +ORDER BY chain_name ASC; + +-- name: ListBlockchainsWithStaking :many +SELECT * FROM blockchains +WHERE is_stake_enabled = 1 AND deleted_at IS NULL +ORDER BY chain_name ASC; + +-- name: ListBlockchainsWithMobileSupport :many +SELECT * FROM blockchains +WHERE is_support_mobile_wallet = 1 AND deleted_at IS NULL +ORDER BY chain_name ASC; + +-- name: ListBlockchainsWithExtensionSupport :many +SELECT * FROM blockchains +WHERE is_support_extension_wallet = 1 AND deleted_at IS NULL +ORDER BY chain_name ASC; + +-- name: ListBlockchainsWithERC20Support :many +SELECT * FROM blockchains +WHERE is_support_erc20 = 1 AND deleted_at IS NULL +ORDER BY chain_name ASC; + +-- name: UpdateBlockchain :one +UPDATE blockchains +SET + chain_name = ?, + chain_id_cosmos = ?, + chain_id_evm = ?, + api_name = ?, + bech_account_prefix = ?, + bech_validator_prefix = ?, + main_asset_symbol = ?, + main_asset_denom = ?, + staking_asset_symbol = ?, + staking_asset_denom = ?, + is_stake_enabled = ?, + chain_image = ?, + main_asset_image = ?, + staking_asset_image = ?, + chain_type = ?, + is_support_mobile_wallet = ?, + is_support_extension_wallet = ?, + is_support_erc20 = ?, + description_en = ?, + description_ko = ?, + description_ja = ?, + origin_genesis_time = ?, + account_type = ?, + btc_staking = ?, + cosmos_fee_info = ?, + evm_fee_info = ?, + lcd_endpoint = ?, + grpc_endpoint = ?, + evm_rpc_endpoint = ?, + explorer = ?, + about = ?, + forum = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: UpdateBlockchainEndpoints :one +UPDATE blockchains +SET + lcd_endpoint = ?, + grpc_endpoint = ?, + evm_rpc_endpoint = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: UpdateBlockchainExplorer :one +UPDATE blockchains +SET + explorer = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: UpdateBlockchainFeeInfo :one +UPDATE blockchains +SET + cosmos_fee_info = ?, + evm_fee_info = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: UpdateBlockchainImages :one +UPDATE blockchains +SET + chain_image = ?, + main_asset_image = ?, + staking_asset_image = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: UpdateBlockchainDescriptions :one +UPDATE blockchains +SET + description_en = ?, + description_ko = ?, + description_ja = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: UpdateBlockchainSocialLinks :one +UPDATE blockchains +SET + about = ?, + forum = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: SoftDeleteBlockchain :exec +UPDATE blockchains +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ?; + +-- name: GetBlockchainWithAssetInfo :one +SELECT b.*, a.id as asset_id, a.symbol, a.decimals, p.price_usd, p.price_btc +FROM blockchains b +LEFT JOIN assets a ON b.main_asset_symbol = a.symbol +LEFT JOIN ( + SELECT p1.* + FROM prices p1 + INNER JOIN ( + SELECT asset_id, MAX(last_updated) as max_date + FROM prices + WHERE deleted_at IS NULL + GROUP BY asset_id + ) p2 ON p1.asset_id = p2.asset_id AND p1.last_updated = p2.max_date + WHERE p1.deleted_at IS NULL +) p ON a.id = p.asset_id +WHERE b.id = ? AND b.deleted_at IS NULL +LIMIT 1; + +-- name: ListBlockchainsWithAssetInfo :many +SELECT b.*, a.id as asset_id, a.symbol, a.decimals, p.price_usd, p.price_btc +FROM blockchains b +LEFT JOIN assets a ON b.main_asset_symbol = a.symbol +LEFT JOIN ( + SELECT p1.* + FROM prices p1 + INNER JOIN ( + SELECT asset_id, MAX(last_updated) as max_date + FROM prices + WHERE deleted_at IS NULL + GROUP BY asset_id + ) p2 ON p1.asset_id = p2.asset_id AND p1.last_updated = p2.max_date + WHERE p1.deleted_at IS NULL +) p ON a.id = p.asset_id +WHERE b.deleted_at IS NULL +ORDER BY b.chain_name ASC +LIMIT ? OFFSET ?; + +-- name: SearchBlockchains :many +SELECT * FROM blockchains +WHERE ( + chain_name LIKE '%' || ? || '%' OR + main_asset_symbol LIKE '%' || ? || '%' OR + staking_asset_symbol LIKE '%' || ? || '%' OR + description_en LIKE '%' || ? || '%' +) AND deleted_at IS NULL +ORDER BY chain_name ASC +LIMIT ? OFFSET ?; + +-- name: CountBlockchainsByChainType :one +SELECT COUNT(*) as count FROM blockchains +WHERE chain_type LIKE '%' || ? || '%' AND deleted_at IS NULL; + +-- name: GetBlockchainEndpoints :one +SELECT id, chain_name, lcd_endpoint, grpc_endpoint, evm_rpc_endpoint +FROM blockchains +WHERE id = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetBlockchainExplorer :one +SELECT id, chain_name, explorer +FROM blockchains +WHERE id = ? AND deleted_at IS NULL +LIMIT 1; diff --git a/network/sink/schema.sql b/network/sink/schema.sql new file mode 100644 index 0000000..297f045 --- /dev/null +++ b/network/sink/schema.sql @@ -0,0 +1,139 @@ +-- Assets represent tokens and coins +CREATE TABLE assets ( + id TEXT PRIMARY KEY, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP, + name TEXT NOT NULL, + symbol TEXT NOT NULL, + decimals INTEGER NOT NULL CHECK(decimals >= 0), + chain_id TEXT NOT NULL, + channel TEXT NOT NULL, + asset_type TEXT NOT NULL, + coingecko_id TEXT, + UNIQUE(chain_id, symbol) +); + +-- Prices entity based on the Alternative.me API for crypto prices +CREATE TABLE prices ( + id TEXT PRIMARY KEY, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP, + asset_id TEXT NOT NULL, + price_usd REAL, + price_btc REAL, + volume_24h_usd REAL, + market_cap_usd REAL, + available_supply REAL, + total_supply REAL, + max_supply REAL, + percent_change_1h REAL, + percent_change_24h REAL, + percent_change_7d REAL, + rank INTEGER, + last_updated TIMESTAMP NOT NULL, + FOREIGN KEY (asset_id) REFERENCES assets(id) +); + +-- Currency conversion rates for crypto prices +CREATE TABLE price_conversions ( + id TEXT PRIMARY KEY, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP, + price_id TEXT NOT NULL, + currency_code TEXT NOT NULL, + price REAL, + volume_24h REAL, + market_cap REAL, + last_updated TIMESTAMP NOT NULL, + FOREIGN KEY (price_id) REFERENCES prices(id), + UNIQUE(price_id, currency_code) +); + +-- Blockchains table to store chain configuration parameters +CREATE TABLE blockchains ( + id TEXT PRIMARY KEY, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP, + + -- Basic chain information + chain_name TEXT NOT NULL, + chain_id_cosmos TEXT, + chain_id_evm TEXT, + api_name TEXT, + bech_account_prefix TEXT, + bech_validator_prefix TEXT, + + -- Chain assets + main_asset_symbol TEXT, + main_asset_denom TEXT, + staking_asset_symbol TEXT, + staking_asset_denom TEXT, + is_stake_enabled BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_stake_enabled IN (0,1)), + + -- Chain images + chain_image TEXT, + main_asset_image TEXT, + staking_asset_image TEXT, + + -- Chain types and features + chain_type TEXT NOT NULL CHECK(json_valid(chain_type)), + is_support_mobile_wallet BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_support_mobile_wallet IN (0,1)), + is_support_extension_wallet BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_support_extension_wallet IN (0,1)), + is_support_erc20 BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_support_erc20 IN (0,1)), + + -- Descriptions in multiple languages + description_en TEXT, + description_ko TEXT, + description_ja TEXT, + + -- Genesis information + origin_genesis_time TIMESTAMP, + + -- Account types configuration + account_type TEXT NOT NULL CHECK(json_valid(account_type)), + + -- BTC staking specific + btc_staking TEXT CHECK(json_valid(btc_staking)), + + -- Cosmos fee information + cosmos_fee_info TEXT CHECK(json_valid(cosmos_fee_info)), + + -- EVM fee information + evm_fee_info TEXT CHECK(json_valid(evm_fee_info)), + + -- Endpoints + lcd_endpoint TEXT CHECK(json_valid(lcd_endpoint)), + grpc_endpoint TEXT CHECK(json_valid(grpc_endpoint)), + evm_rpc_endpoint TEXT CHECK(json_valid(evm_rpc_endpoint)), + + -- Explorer information + explorer TEXT CHECK(json_valid(explorer)), + + -- Social and documentation links + about TEXT CHECK(json_valid(about)), + forum TEXT CHECK(json_valid(forum)) +); + +-- Add all necessary indexes +CREATE INDEX idx_assets_symbol ON assets(symbol); +CREATE INDEX idx_assets_chain_id ON assets(chain_id); +CREATE INDEX idx_assets_deleted_at ON assets(deleted_at); + +CREATE INDEX idx_prices_asset_id ON prices(asset_id); +CREATE INDEX idx_prices_rank ON prices(rank); +CREATE INDEX idx_prices_last_updated ON prices(last_updated); +CREATE INDEX idx_prices_deleted_at ON prices(deleted_at); + +CREATE INDEX idx_price_conversions_price_id ON price_conversions(price_id); +CREATE INDEX idx_price_conversions_currency_code ON price_conversions(currency_code); +CREATE INDEX idx_price_conversions_deleted_at ON price_conversions(deleted_at); + +CREATE INDEX idx_blockchains_chain_name ON blockchains(chain_name); +CREATE INDEX idx_blockchains_chain_id_cosmos ON blockchains(chain_id_cosmos); +CREATE INDEX idx_blockchains_chain_id_evm ON blockchains(chain_id_evm); +CREATE INDEX idx_blockchains_main_asset_symbol ON blockchains(main_asset_symbol); +CREATE INDEX idx_blockchains_deleted_at ON blockchains(deleted_at); diff --git a/sqlc.yaml b/sqlc.yaml new file mode 100644 index 0000000..9677173 --- /dev/null +++ b/sqlc.yaml @@ -0,0 +1,34 @@ +version: "2" +sql: + # Activity DB - User to User Interactions + - engine: "sqlite" + queries: "./activity/sink/query.sql" + schema: "./activity/sink/schema.sql" + gen: + go: + emit_interface: true + emit_json_tags: true + package: "activity" + out: "./activity" + + # Network DB - Blockchain Parameters and Asset Metadata + - engine: "sqlite" + queries: "./network/sink/query.sql" + schema: "./network/sink/schema.sql" + gen: + go: + emit_interface: true + emit_json_tags: true + package: "network" + out: "./network" + + # Users DB - Accounts, Profiles, and Vault Metadata + - engine: "sqlite" + queries: "./users/sink/query.sql" + schema: "./users/sink/schema.sql" + gen: + go: + emit_interface: true + emit_json_tags: true + package: "users" + out: "./users" diff --git a/users/db.go b/users/db.go new file mode 100644 index 0000000..9615903 --- /dev/null +++ b/users/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 + +package users + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/users/models.go b/users/models.go new file mode 100644 index 0000000..0468a2e --- /dev/null +++ b/users/models.go @@ -0,0 +1,68 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 + +package users + +import ( + "database/sql" + "time" +) + +type Account struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt sql.NullTime `json:"deleted_at"` + Number int64 `json:"number"` + Sequence int64 `json:"sequence"` + Address string `json:"address"` + PublicKey string `json:"public_key"` + ChainID string `json:"chain_id"` + BlockCreated int64 `json:"block_created"` + Controller string `json:"controller"` + Label string `json:"label"` + Handle string `json:"handle"` + IsSubsidiary bool `json:"is_subsidiary"` + IsValidator bool `json:"is_validator"` + IsDelegator bool `json:"is_delegator"` + IsAccountable bool `json:"is_accountable"` +} + +type Credential struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt sql.NullTime `json:"deleted_at"` + Handle string `json:"handle"` + CredentialID string `json:"credential_id"` + AuthenticatorAttachment string `json:"authenticator_attachment"` + Origin string `json:"origin"` + Type string `json:"type"` + Transports string `json:"transports"` +} + +type Profile struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt sql.NullTime `json:"deleted_at"` + Address string `json:"address"` + Handle string `json:"handle"` + Origin string `json:"origin"` + Name string `json:"name"` +} + +type Vault struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt sql.NullTime `json:"deleted_at"` + Handle string `json:"handle"` + Origin string `json:"origin"` + Address string `json:"address"` + Cid string `json:"cid"` + Config string `json:"config"` + SessionID string `json:"session_id"` + RedirectUri string `json:"redirect_uri"` +} diff --git a/users/querier.go b/users/querier.go new file mode 100644 index 0000000..49368b8 --- /dev/null +++ b/users/querier.go @@ -0,0 +1,53 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 + +package users + +import ( + "context" +) + +type Querier interface { + CheckHandleExists(ctx context.Context, handle string) (bool, error) + GetAccountByAddress(ctx context.Context, address string) (Account, error) + GetAccountByController(ctx context.Context, controller string) (Account, error) + GetAccountByID(ctx context.Context, id string) (Account, error) + GetAccountByNumber(ctx context.Context, number int64) (Account, error) + GetAccountByPublicKey(ctx context.Context, publicKey string) (Account, error) + GetAccountBySequence(ctx context.Context, sequence int64) (Account, error) + GetAccountsByChainID(ctx context.Context, chainID string) ([]Account, error) + GetAccountsByController(ctx context.Context, controller string) ([]Account, error) + GetAccountsByHandle(ctx context.Context, handle string) ([]Account, error) + GetAccountsByLabel(ctx context.Context, label string) ([]Account, error) + GetCredentialByID(ctx context.Context, credentialID string) (Credential, error) + GetCredentialsByHandle(ctx context.Context, handle string) ([]Credential, error) + GetProfileByAddress(ctx context.Context, address string) (Profile, error) + GetProfileByHandle(ctx context.Context, handle string) (Profile, error) + GetProfileByID(ctx context.Context, id string) (Profile, error) + GetVaultByID(ctx context.Context, id string) (Vault, error) + GetVaultConfigByCID(ctx context.Context, cid string) (Vault, error) + GetVaultRedirectURIBySessionID(ctx context.Context, sessionID string) (string, error) + GetVaultsByHandle(ctx context.Context, handle string) ([]Vault, error) + // ACCOUNT QUERIES + InsertAccount(ctx context.Context, arg InsertAccountParams) (Account, error) + // CREDENTIAL QUERIES + InsertCredential(ctx context.Context, arg InsertCredentialParams) (Credential, error) + // PROFILE QUERIES + InsertProfile(ctx context.Context, arg InsertProfileParams) (Profile, error) + // VAULT QUERIES + InsertVault(ctx context.Context, arg InsertVaultParams) (Vault, error) + ListDelegatorAccounts(ctx context.Context) ([]Account, error) + ListProfiles(ctx context.Context, arg ListProfilesParams) ([]Profile, error) + ListValidatorAccounts(ctx context.Context) ([]Account, error) + SoftDeleteAccount(ctx context.Context, id string) error + SoftDeleteCredential(ctx context.Context, credentialID string) error + SoftDeleteProfile(ctx context.Context, address string) error + SoftDeleteVault(ctx context.Context, id string) error + UpdateAccountLabel(ctx context.Context, arg UpdateAccountLabelParams) (Account, error) + UpdateAccountSequence(ctx context.Context, arg UpdateAccountSequenceParams) (Account, error) + UpdateProfile(ctx context.Context, arg UpdateProfileParams) (Profile, error) + UpdateVault(ctx context.Context, arg UpdateVaultParams) (Vault, error) +} + +var _ Querier = (*Queries)(nil) diff --git a/users/query.sql.go b/users/query.sql.go new file mode 100644 index 0000000..6a0879d --- /dev/null +++ b/users/query.sql.go @@ -0,0 +1,1177 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 +// source: query.sql + +package users + +import ( + "context" +) + +const checkHandleExists = `-- name: CheckHandleExists :one +SELECT COUNT(*) > 0 as handle_exists FROM profiles +WHERE handle = ? +AND deleted_at IS NULL +` + +func (q *Queries) CheckHandleExists(ctx context.Context, handle string) (bool, error) { + row := q.db.QueryRowContext(ctx, checkHandleExists, handle) + var handle_exists bool + err := row.Scan(&handle_exists) + return handle_exists, err +} + +const getAccountByAddress = `-- name: GetAccountByAddress :one +SELECT id, created_at, updated_at, deleted_at, number, sequence, address, public_key, chain_id, block_created, controller, label, handle, is_subsidiary, is_validator, is_delegator, is_accountable FROM accounts +WHERE address = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetAccountByAddress(ctx context.Context, address string) (Account, error) { + row := q.db.QueryRowContext(ctx, getAccountByAddress, address) + var i Account + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Number, + &i.Sequence, + &i.Address, + &i.PublicKey, + &i.ChainID, + &i.BlockCreated, + &i.Controller, + &i.Label, + &i.Handle, + &i.IsSubsidiary, + &i.IsValidator, + &i.IsDelegator, + &i.IsAccountable, + ) + return i, err +} + +const getAccountByController = `-- name: GetAccountByController :one +SELECT id, created_at, updated_at, deleted_at, number, sequence, address, public_key, chain_id, block_created, controller, label, handle, is_subsidiary, is_validator, is_delegator, is_accountable FROM accounts +WHERE controller = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetAccountByController(ctx context.Context, controller string) (Account, error) { + row := q.db.QueryRowContext(ctx, getAccountByController, controller) + var i Account + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Number, + &i.Sequence, + &i.Address, + &i.PublicKey, + &i.ChainID, + &i.BlockCreated, + &i.Controller, + &i.Label, + &i.Handle, + &i.IsSubsidiary, + &i.IsValidator, + &i.IsDelegator, + &i.IsAccountable, + ) + return i, err +} + +const getAccountByID = `-- name: GetAccountByID :one +SELECT id, created_at, updated_at, deleted_at, number, sequence, address, public_key, chain_id, block_created, controller, label, handle, is_subsidiary, is_validator, is_delegator, is_accountable FROM accounts +WHERE id = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetAccountByID(ctx context.Context, id string) (Account, error) { + row := q.db.QueryRowContext(ctx, getAccountByID, id) + var i Account + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Number, + &i.Sequence, + &i.Address, + &i.PublicKey, + &i.ChainID, + &i.BlockCreated, + &i.Controller, + &i.Label, + &i.Handle, + &i.IsSubsidiary, + &i.IsValidator, + &i.IsDelegator, + &i.IsAccountable, + ) + return i, err +} + +const getAccountByNumber = `-- name: GetAccountByNumber :one +SELECT id, created_at, updated_at, deleted_at, number, sequence, address, public_key, chain_id, block_created, controller, label, handle, is_subsidiary, is_validator, is_delegator, is_accountable FROM accounts +WHERE number = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetAccountByNumber(ctx context.Context, number int64) (Account, error) { + row := q.db.QueryRowContext(ctx, getAccountByNumber, number) + var i Account + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Number, + &i.Sequence, + &i.Address, + &i.PublicKey, + &i.ChainID, + &i.BlockCreated, + &i.Controller, + &i.Label, + &i.Handle, + &i.IsSubsidiary, + &i.IsValidator, + &i.IsDelegator, + &i.IsAccountable, + ) + return i, err +} + +const getAccountByPublicKey = `-- name: GetAccountByPublicKey :one +SELECT id, created_at, updated_at, deleted_at, number, sequence, address, public_key, chain_id, block_created, controller, label, handle, is_subsidiary, is_validator, is_delegator, is_accountable FROM accounts +WHERE public_key = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetAccountByPublicKey(ctx context.Context, publicKey string) (Account, error) { + row := q.db.QueryRowContext(ctx, getAccountByPublicKey, publicKey) + var i Account + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Number, + &i.Sequence, + &i.Address, + &i.PublicKey, + &i.ChainID, + &i.BlockCreated, + &i.Controller, + &i.Label, + &i.Handle, + &i.IsSubsidiary, + &i.IsValidator, + &i.IsDelegator, + &i.IsAccountable, + ) + return i, err +} + +const getAccountBySequence = `-- name: GetAccountBySequence :one +SELECT id, created_at, updated_at, deleted_at, number, sequence, address, public_key, chain_id, block_created, controller, label, handle, is_subsidiary, is_validator, is_delegator, is_accountable FROM accounts +WHERE sequence = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetAccountBySequence(ctx context.Context, sequence int64) (Account, error) { + row := q.db.QueryRowContext(ctx, getAccountBySequence, sequence) + var i Account + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Number, + &i.Sequence, + &i.Address, + &i.PublicKey, + &i.ChainID, + &i.BlockCreated, + &i.Controller, + &i.Label, + &i.Handle, + &i.IsSubsidiary, + &i.IsValidator, + &i.IsDelegator, + &i.IsAccountable, + ) + return i, err +} + +const getAccountsByChainID = `-- name: GetAccountsByChainID :many +SELECT id, created_at, updated_at, deleted_at, number, sequence, address, public_key, chain_id, block_created, controller, label, handle, is_subsidiary, is_validator, is_delegator, is_accountable FROM accounts +WHERE chain_id = ? AND deleted_at IS NULL +ORDER BY sequence DESC +` + +func (q *Queries) GetAccountsByChainID(ctx context.Context, chainID string) ([]Account, error) { + rows, err := q.db.QueryContext(ctx, getAccountsByChainID, chainID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Account + for rows.Next() { + var i Account + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Number, + &i.Sequence, + &i.Address, + &i.PublicKey, + &i.ChainID, + &i.BlockCreated, + &i.Controller, + &i.Label, + &i.Handle, + &i.IsSubsidiary, + &i.IsValidator, + &i.IsDelegator, + &i.IsAccountable, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getAccountsByController = `-- name: GetAccountsByController :many +SELECT id, created_at, updated_at, deleted_at, number, sequence, address, public_key, chain_id, block_created, controller, label, handle, is_subsidiary, is_validator, is_delegator, is_accountable FROM accounts +WHERE controller = ? AND deleted_at IS NULL +ORDER BY created_at DESC +` + +func (q *Queries) GetAccountsByController(ctx context.Context, controller string) ([]Account, error) { + rows, err := q.db.QueryContext(ctx, getAccountsByController, controller) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Account + for rows.Next() { + var i Account + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Number, + &i.Sequence, + &i.Address, + &i.PublicKey, + &i.ChainID, + &i.BlockCreated, + &i.Controller, + &i.Label, + &i.Handle, + &i.IsSubsidiary, + &i.IsValidator, + &i.IsDelegator, + &i.IsAccountable, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getAccountsByHandle = `-- name: GetAccountsByHandle :many +SELECT id, created_at, updated_at, deleted_at, number, sequence, address, public_key, chain_id, block_created, controller, label, handle, is_subsidiary, is_validator, is_delegator, is_accountable FROM accounts +WHERE handle = ? AND deleted_at IS NULL +ORDER BY created_at DESC +` + +func (q *Queries) GetAccountsByHandle(ctx context.Context, handle string) ([]Account, error) { + rows, err := q.db.QueryContext(ctx, getAccountsByHandle, handle) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Account + for rows.Next() { + var i Account + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Number, + &i.Sequence, + &i.Address, + &i.PublicKey, + &i.ChainID, + &i.BlockCreated, + &i.Controller, + &i.Label, + &i.Handle, + &i.IsSubsidiary, + &i.IsValidator, + &i.IsDelegator, + &i.IsAccountable, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getAccountsByLabel = `-- name: GetAccountsByLabel :many +SELECT id, created_at, updated_at, deleted_at, number, sequence, address, public_key, chain_id, block_created, controller, label, handle, is_subsidiary, is_validator, is_delegator, is_accountable FROM accounts +WHERE label = ? AND deleted_at IS NULL +ORDER BY created_at DESC +` + +func (q *Queries) GetAccountsByLabel(ctx context.Context, label string) ([]Account, error) { + rows, err := q.db.QueryContext(ctx, getAccountsByLabel, label) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Account + for rows.Next() { + var i Account + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Number, + &i.Sequence, + &i.Address, + &i.PublicKey, + &i.ChainID, + &i.BlockCreated, + &i.Controller, + &i.Label, + &i.Handle, + &i.IsSubsidiary, + &i.IsValidator, + &i.IsDelegator, + &i.IsAccountable, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getCredentialByID = `-- name: GetCredentialByID :one +SELECT id, created_at, updated_at, deleted_at, handle, credential_id, authenticator_attachment, origin, type, transports FROM credentials +WHERE credential_id = ? +AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetCredentialByID(ctx context.Context, credentialID string) (Credential, error) { + row := q.db.QueryRowContext(ctx, getCredentialByID, credentialID) + var i Credential + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Handle, + &i.CredentialID, + &i.AuthenticatorAttachment, + &i.Origin, + &i.Type, + &i.Transports, + ) + return i, err +} + +const getCredentialsByHandle = `-- name: GetCredentialsByHandle :many +SELECT id, created_at, updated_at, deleted_at, handle, credential_id, authenticator_attachment, origin, type, transports FROM credentials +WHERE handle = ? +AND deleted_at IS NULL +` + +func (q *Queries) GetCredentialsByHandle(ctx context.Context, handle string) ([]Credential, error) { + rows, err := q.db.QueryContext(ctx, getCredentialsByHandle, handle) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Credential + for rows.Next() { + var i Credential + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Handle, + &i.CredentialID, + &i.AuthenticatorAttachment, + &i.Origin, + &i.Type, + &i.Transports, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getProfileByAddress = `-- name: GetProfileByAddress :one +SELECT id, created_at, updated_at, deleted_at, address, handle, origin, name FROM profiles +WHERE address = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetProfileByAddress(ctx context.Context, address string) (Profile, error) { + row := q.db.QueryRowContext(ctx, getProfileByAddress, address) + var i Profile + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Address, + &i.Handle, + &i.Origin, + &i.Name, + ) + return i, err +} + +const getProfileByHandle = `-- name: GetProfileByHandle :one +SELECT id, created_at, updated_at, deleted_at, address, handle, origin, name FROM profiles +WHERE handle = ? +AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetProfileByHandle(ctx context.Context, handle string) (Profile, error) { + row := q.db.QueryRowContext(ctx, getProfileByHandle, handle) + var i Profile + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Address, + &i.Handle, + &i.Origin, + &i.Name, + ) + return i, err +} + +const getProfileByID = `-- name: GetProfileByID :one +SELECT id, created_at, updated_at, deleted_at, address, handle, origin, name FROM profiles +WHERE id = ? AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetProfileByID(ctx context.Context, id string) (Profile, error) { + row := q.db.QueryRowContext(ctx, getProfileByID, id) + var i Profile + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Address, + &i.Handle, + &i.Origin, + &i.Name, + ) + return i, err +} + +const getVaultByID = `-- name: GetVaultByID :one +SELECT id, created_at, updated_at, deleted_at, handle, origin, address, cid, config, session_id, redirect_uri FROM vaults +WHERE id = ? +AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetVaultByID(ctx context.Context, id string) (Vault, error) { + row := q.db.QueryRowContext(ctx, getVaultByID, id) + var i Vault + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Handle, + &i.Origin, + &i.Address, + &i.Cid, + &i.Config, + &i.SessionID, + &i.RedirectUri, + ) + return i, err +} + +const getVaultConfigByCID = `-- name: GetVaultConfigByCID :one +SELECT id, created_at, updated_at, deleted_at, handle, origin, address, cid, config, session_id, redirect_uri FROM vaults +WHERE cid = ? +AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetVaultConfigByCID(ctx context.Context, cid string) (Vault, error) { + row := q.db.QueryRowContext(ctx, getVaultConfigByCID, cid) + var i Vault + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Handle, + &i.Origin, + &i.Address, + &i.Cid, + &i.Config, + &i.SessionID, + &i.RedirectUri, + ) + return i, err +} + +const getVaultRedirectURIBySessionID = `-- name: GetVaultRedirectURIBySessionID :one +SELECT redirect_uri FROM vaults +WHERE session_id = ? +AND deleted_at IS NULL +LIMIT 1 +` + +func (q *Queries) GetVaultRedirectURIBySessionID(ctx context.Context, sessionID string) (string, error) { + row := q.db.QueryRowContext(ctx, getVaultRedirectURIBySessionID, sessionID) + var redirect_uri string + err := row.Scan(&redirect_uri) + return redirect_uri, err +} + +const getVaultsByHandle = `-- name: GetVaultsByHandle :many +SELECT id, created_at, updated_at, deleted_at, handle, origin, address, cid, config, session_id, redirect_uri FROM vaults +WHERE handle = ? +AND deleted_at IS NULL +ORDER BY created_at DESC +` + +func (q *Queries) GetVaultsByHandle(ctx context.Context, handle string) ([]Vault, error) { + rows, err := q.db.QueryContext(ctx, getVaultsByHandle, handle) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Vault + for rows.Next() { + var i Vault + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Handle, + &i.Origin, + &i.Address, + &i.Cid, + &i.Config, + &i.SessionID, + &i.RedirectUri, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const insertAccount = `-- name: InsertAccount :one +INSERT INTO accounts ( + number, + sequence, + address, + public_key, + chain_id, + block_created, + controller, + label, + is_subsidiary, + is_validator, + is_delegator, + is_accountable +) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) +RETURNING id, created_at, updated_at, deleted_at, number, sequence, address, public_key, chain_id, block_created, controller, label, handle, is_subsidiary, is_validator, is_delegator, is_accountable +` + +type InsertAccountParams struct { + Number int64 `json:"number"` + Sequence int64 `json:"sequence"` + Address string `json:"address"` + PublicKey string `json:"public_key"` + ChainID string `json:"chain_id"` + BlockCreated int64 `json:"block_created"` + Controller string `json:"controller"` + Label string `json:"label"` + IsSubsidiary bool `json:"is_subsidiary"` + IsValidator bool `json:"is_validator"` + IsDelegator bool `json:"is_delegator"` + IsAccountable bool `json:"is_accountable"` +} + +// ACCOUNT QUERIES +func (q *Queries) InsertAccount(ctx context.Context, arg InsertAccountParams) (Account, error) { + row := q.db.QueryRowContext(ctx, insertAccount, + arg.Number, + arg.Sequence, + arg.Address, + arg.PublicKey, + arg.ChainID, + arg.BlockCreated, + arg.Controller, + arg.Label, + arg.IsSubsidiary, + arg.IsValidator, + arg.IsDelegator, + arg.IsAccountable, + ) + var i Account + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Number, + &i.Sequence, + &i.Address, + &i.PublicKey, + &i.ChainID, + &i.BlockCreated, + &i.Controller, + &i.Label, + &i.Handle, + &i.IsSubsidiary, + &i.IsValidator, + &i.IsDelegator, + &i.IsAccountable, + ) + return i, err +} + +const insertCredential = `-- name: InsertCredential :one +INSERT INTO credentials ( + handle, + credential_id, + authenticator_attachment, + origin, + type, + transports +) VALUES (?, ?, ?, ?, ?, ?) +RETURNING id, created_at, updated_at, deleted_at, handle, credential_id, authenticator_attachment, origin, type, transports +` + +type InsertCredentialParams struct { + Handle string `json:"handle"` + CredentialID string `json:"credential_id"` + AuthenticatorAttachment string `json:"authenticator_attachment"` + Origin string `json:"origin"` + Type string `json:"type"` + Transports string `json:"transports"` +} + +// CREDENTIAL QUERIES +func (q *Queries) InsertCredential(ctx context.Context, arg InsertCredentialParams) (Credential, error) { + row := q.db.QueryRowContext(ctx, insertCredential, + arg.Handle, + arg.CredentialID, + arg.AuthenticatorAttachment, + arg.Origin, + arg.Type, + arg.Transports, + ) + var i Credential + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Handle, + &i.CredentialID, + &i.AuthenticatorAttachment, + &i.Origin, + &i.Type, + &i.Transports, + ) + return i, err +} + +const insertProfile = `-- name: InsertProfile :one +INSERT INTO profiles ( + address, + handle, + origin, + name +) VALUES (?, ?, ?, ?) +RETURNING id, created_at, updated_at, deleted_at, address, handle, origin, name +` + +type InsertProfileParams struct { + Address string `json:"address"` + Handle string `json:"handle"` + Origin string `json:"origin"` + Name string `json:"name"` +} + +// PROFILE QUERIES +func (q *Queries) InsertProfile(ctx context.Context, arg InsertProfileParams) (Profile, error) { + row := q.db.QueryRowContext(ctx, insertProfile, + arg.Address, + arg.Handle, + arg.Origin, + arg.Name, + ) + var i Profile + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Address, + &i.Handle, + &i.Origin, + &i.Name, + ) + return i, err +} + +const insertVault = `-- name: InsertVault :one +INSERT INTO vaults ( + handle, + origin, + address, + cid, + config, + session_id, + redirect_uri +) VALUES (?, ?, ?, ?, ?, ?, ?) +RETURNING id, created_at, updated_at, deleted_at, handle, origin, address, cid, config, session_id, redirect_uri +` + +type InsertVaultParams struct { + Handle string `json:"handle"` + Origin string `json:"origin"` + Address string `json:"address"` + Cid string `json:"cid"` + Config string `json:"config"` + SessionID string `json:"session_id"` + RedirectUri string `json:"redirect_uri"` +} + +// VAULT QUERIES +func (q *Queries) InsertVault(ctx context.Context, arg InsertVaultParams) (Vault, error) { + row := q.db.QueryRowContext(ctx, insertVault, + arg.Handle, + arg.Origin, + arg.Address, + arg.Cid, + arg.Config, + arg.SessionID, + arg.RedirectUri, + ) + var i Vault + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Handle, + &i.Origin, + &i.Address, + &i.Cid, + &i.Config, + &i.SessionID, + &i.RedirectUri, + ) + return i, err +} + +const listDelegatorAccounts = `-- name: ListDelegatorAccounts :many +SELECT id, created_at, updated_at, deleted_at, number, sequence, address, public_key, chain_id, block_created, controller, label, handle, is_subsidiary, is_validator, is_delegator, is_accountable FROM accounts +WHERE is_delegator = 1 +AND deleted_at IS NULL +ORDER BY created_at DESC +` + +func (q *Queries) ListDelegatorAccounts(ctx context.Context) ([]Account, error) { + rows, err := q.db.QueryContext(ctx, listDelegatorAccounts) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Account + for rows.Next() { + var i Account + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Number, + &i.Sequence, + &i.Address, + &i.PublicKey, + &i.ChainID, + &i.BlockCreated, + &i.Controller, + &i.Label, + &i.Handle, + &i.IsSubsidiary, + &i.IsValidator, + &i.IsDelegator, + &i.IsAccountable, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listProfiles = `-- name: ListProfiles :many +SELECT id, created_at, updated_at, deleted_at, address, handle, origin, name FROM profiles +WHERE deleted_at IS NULL +ORDER BY created_at DESC +LIMIT ? OFFSET ? +` + +type ListProfilesParams struct { + Limit int64 `json:"limit"` + Offset int64 `json:"offset"` +} + +func (q *Queries) ListProfiles(ctx context.Context, arg ListProfilesParams) ([]Profile, error) { + rows, err := q.db.QueryContext(ctx, listProfiles, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Profile + for rows.Next() { + var i Profile + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Address, + &i.Handle, + &i.Origin, + &i.Name, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listValidatorAccounts = `-- name: ListValidatorAccounts :many +SELECT id, created_at, updated_at, deleted_at, number, sequence, address, public_key, chain_id, block_created, controller, label, handle, is_subsidiary, is_validator, is_delegator, is_accountable FROM accounts +WHERE is_validator = 1 +AND deleted_at IS NULL +ORDER BY created_at DESC +` + +func (q *Queries) ListValidatorAccounts(ctx context.Context) ([]Account, error) { + rows, err := q.db.QueryContext(ctx, listValidatorAccounts) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Account + for rows.Next() { + var i Account + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Number, + &i.Sequence, + &i.Address, + &i.PublicKey, + &i.ChainID, + &i.BlockCreated, + &i.Controller, + &i.Label, + &i.Handle, + &i.IsSubsidiary, + &i.IsValidator, + &i.IsDelegator, + &i.IsAccountable, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const softDeleteAccount = `-- name: SoftDeleteAccount :exec +UPDATE accounts +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ? +` + +func (q *Queries) SoftDeleteAccount(ctx context.Context, id string) error { + _, err := q.db.ExecContext(ctx, softDeleteAccount, id) + return err +} + +const softDeleteCredential = `-- name: SoftDeleteCredential :exec +UPDATE credentials +SET deleted_at = CURRENT_TIMESTAMP +WHERE credential_id = ? +` + +func (q *Queries) SoftDeleteCredential(ctx context.Context, credentialID string) error { + _, err := q.db.ExecContext(ctx, softDeleteCredential, credentialID) + return err +} + +const softDeleteProfile = `-- name: SoftDeleteProfile :exec +UPDATE profiles +SET deleted_at = CURRENT_TIMESTAMP +WHERE address = ? +` + +func (q *Queries) SoftDeleteProfile(ctx context.Context, address string) error { + _, err := q.db.ExecContext(ctx, softDeleteProfile, address) + return err +} + +const softDeleteVault = `-- name: SoftDeleteVault :exec +UPDATE vaults +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ? +` + +func (q *Queries) SoftDeleteVault(ctx context.Context, id string) error { + _, err := q.db.ExecContext(ctx, softDeleteVault, id) + return err +} + +const updateAccountLabel = `-- name: UpdateAccountLabel :one +UPDATE accounts +SET + label = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, number, sequence, address, public_key, chain_id, block_created, controller, label, handle, is_subsidiary, is_validator, is_delegator, is_accountable +` + +type UpdateAccountLabelParams struct { + Label string `json:"label"` + ID string `json:"id"` +} + +func (q *Queries) UpdateAccountLabel(ctx context.Context, arg UpdateAccountLabelParams) (Account, error) { + row := q.db.QueryRowContext(ctx, updateAccountLabel, arg.Label, arg.ID) + var i Account + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Number, + &i.Sequence, + &i.Address, + &i.PublicKey, + &i.ChainID, + &i.BlockCreated, + &i.Controller, + &i.Label, + &i.Handle, + &i.IsSubsidiary, + &i.IsValidator, + &i.IsDelegator, + &i.IsAccountable, + ) + return i, err +} + +const updateAccountSequence = `-- name: UpdateAccountSequence :one +UPDATE accounts +SET + sequence = ?, + updated_at = CURRENT_TIMESTAMP +WHERE address = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, number, sequence, address, public_key, chain_id, block_created, controller, label, handle, is_subsidiary, is_validator, is_delegator, is_accountable +` + +type UpdateAccountSequenceParams struct { + Sequence int64 `json:"sequence"` + Address string `json:"address"` +} + +func (q *Queries) UpdateAccountSequence(ctx context.Context, arg UpdateAccountSequenceParams) (Account, error) { + row := q.db.QueryRowContext(ctx, updateAccountSequence, arg.Sequence, arg.Address) + var i Account + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Number, + &i.Sequence, + &i.Address, + &i.PublicKey, + &i.ChainID, + &i.BlockCreated, + &i.Controller, + &i.Label, + &i.Handle, + &i.IsSubsidiary, + &i.IsValidator, + &i.IsDelegator, + &i.IsAccountable, + ) + return i, err +} + +const updateProfile = `-- name: UpdateProfile :one +UPDATE profiles +SET + name = ?, + handle = ?, + updated_at = CURRENT_TIMESTAMP +WHERE address = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, address, handle, origin, name +` + +type UpdateProfileParams struct { + Name string `json:"name"` + Handle string `json:"handle"` + Address string `json:"address"` +} + +func (q *Queries) UpdateProfile(ctx context.Context, arg UpdateProfileParams) (Profile, error) { + row := q.db.QueryRowContext(ctx, updateProfile, arg.Name, arg.Handle, arg.Address) + var i Profile + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Address, + &i.Handle, + &i.Origin, + &i.Name, + ) + return i, err +} + +const updateVault = `-- name: UpdateVault :one +UPDATE vaults +SET + config = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING id, created_at, updated_at, deleted_at, handle, origin, address, cid, config, session_id, redirect_uri +` + +type UpdateVaultParams struct { + Config string `json:"config"` + ID string `json:"id"` +} + +func (q *Queries) UpdateVault(ctx context.Context, arg UpdateVaultParams) (Vault, error) { + row := q.db.QueryRowContext(ctx, updateVault, arg.Config, arg.ID) + var i Vault + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.DeletedAt, + &i.Handle, + &i.Origin, + &i.Address, + &i.Cid, + &i.Config, + &i.SessionID, + &i.RedirectUri, + ) + return i, err +} diff --git a/users/sink/query.sql b/users/sink/query.sql new file mode 100644 index 0000000..73b50d1 --- /dev/null +++ b/users/sink/query.sql @@ -0,0 +1,234 @@ +-- PROFILE QUERIES +-- name: InsertProfile :one +INSERT INTO profiles ( + address, + handle, + origin, + name +) VALUES (?, ?, ?, ?) +RETURNING *; + +-- name: GetProfileByID :one +SELECT * FROM profiles +WHERE id = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetProfileByAddress :one +SELECT * FROM profiles +WHERE address = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetProfileByHandle :one +SELECT * FROM profiles +WHERE handle = ? +AND deleted_at IS NULL +LIMIT 1; + +-- name: CheckHandleExists :one +SELECT COUNT(*) > 0 as handle_exists FROM profiles +WHERE handle = ? +AND deleted_at IS NULL; + +-- name: UpdateProfile :one +UPDATE profiles +SET + name = ?, + handle = ?, + updated_at = CURRENT_TIMESTAMP +WHERE address = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: SoftDeleteProfile :exec +UPDATE profiles +SET deleted_at = CURRENT_TIMESTAMP +WHERE address = ?; + +-- name: ListProfiles :many +SELECT * FROM profiles +WHERE deleted_at IS NULL +ORDER BY created_at DESC +LIMIT ? OFFSET ?; + +-- VAULT QUERIES +-- name: InsertVault :one +INSERT INTO vaults ( + handle, + origin, + address, + cid, + config, + session_id, + redirect_uri +) VALUES (?, ?, ?, ?, ?, ?, ?) +RETURNING *; + +-- name: GetVaultByID :one +SELECT * FROM vaults +WHERE id = ? +AND deleted_at IS NULL +LIMIT 1; + +-- name: GetVaultsByHandle :many +SELECT * FROM vaults +WHERE handle = ? +AND deleted_at IS NULL +ORDER BY created_at DESC; + +-- name: GetVaultConfigByCID :one +SELECT * FROM vaults +WHERE cid = ? +AND deleted_at IS NULL +LIMIT 1; + +-- name: GetVaultRedirectURIBySessionID :one +SELECT redirect_uri FROM vaults +WHERE session_id = ? +AND deleted_at IS NULL +LIMIT 1; + +-- name: UpdateVault :one +UPDATE vaults +SET + config = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: SoftDeleteVault :exec +UPDATE vaults +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ?; + +-- ACCOUNT QUERIES +-- name: InsertAccount :one +INSERT INTO accounts ( + number, + sequence, + address, + public_key, + chain_id, + block_created, + controller, + label, + is_subsidiary, + is_validator, + is_delegator, + is_accountable +) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) +RETURNING *; + +-- name: GetAccountByID :one +SELECT * FROM accounts +WHERE id = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetAccountByAddress :one +SELECT * FROM accounts +WHERE address = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetAccountsByHandle :many +SELECT * FROM accounts +WHERE handle = ? AND deleted_at IS NULL +ORDER BY created_at DESC; + +-- name: GetAccountByController :one +SELECT * FROM accounts +WHERE controller = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetAccountByPublicKey :one +SELECT * FROM accounts +WHERE public_key = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetAccountByNumber :one +SELECT * FROM accounts +WHERE number = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetAccountBySequence :one +SELECT * FROM accounts +WHERE sequence = ? AND deleted_at IS NULL +LIMIT 1; + +-- name: GetAccountsByChainID :many +SELECT * FROM accounts +WHERE chain_id = ? AND deleted_at IS NULL +ORDER BY sequence DESC; + +-- name: GetAccountsByController :many +SELECT * FROM accounts +WHERE controller = ? AND deleted_at IS NULL +ORDER BY created_at DESC; + +-- name: GetAccountsByLabel :many +SELECT * FROM accounts +WHERE label = ? AND deleted_at IS NULL +ORDER BY created_at DESC; + +-- name: UpdateAccountSequence :one +UPDATE accounts +SET + sequence = ?, + updated_at = CURRENT_TIMESTAMP +WHERE address = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: UpdateAccountLabel :one +UPDATE accounts +SET + label = ?, + updated_at = CURRENT_TIMESTAMP +WHERE id = ? +AND deleted_at IS NULL +RETURNING *; + +-- name: SoftDeleteAccount :exec +UPDATE accounts +SET deleted_at = CURRENT_TIMESTAMP +WHERE id = ?; + +-- name: ListValidatorAccounts :many +SELECT * FROM accounts +WHERE is_validator = 1 +AND deleted_at IS NULL +ORDER BY created_at DESC; + +-- name: ListDelegatorAccounts :many +SELECT * FROM accounts +WHERE is_delegator = 1 +AND deleted_at IS NULL +ORDER BY created_at DESC; + +-- CREDENTIAL QUERIES +-- name: InsertCredential :one +INSERT INTO credentials ( + handle, + credential_id, + authenticator_attachment, + origin, + type, + transports +) VALUES (?, ?, ?, ?, ?, ?) +RETURNING *; + +-- name: GetCredentialsByHandle :many +SELECT * FROM credentials +WHERE handle = ? +AND deleted_at IS NULL; + +-- name: GetCredentialByID :one +SELECT * FROM credentials +WHERE credential_id = ? +AND deleted_at IS NULL +LIMIT 1; + +-- name: SoftDeleteCredential :exec +UPDATE credentials +SET deleted_at = CURRENT_TIMESTAMP +WHERE credential_id = ?; + diff --git a/users/sink/schema.sql b/users/sink/schema.sql new file mode 100644 index 0000000..b5ba399 --- /dev/null +++ b/users/sink/schema.sql @@ -0,0 +1,81 @@ +-- Credentials store WebAuthn credentials +CREATE TABLE credentials ( + id TEXT PRIMARY KEY, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP, + handle TEXT NOT NULL, + credential_id TEXT NOT NULL UNIQUE, + authenticator_attachment TEXT NOT NULL, + origin TEXT NOT NULL, + type TEXT NOT NULL, + transports TEXT NOT NULL +); + +-- Accounts represent blockchain accounts +CREATE TABLE accounts ( + id TEXT PRIMARY KEY, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP, + number INTEGER NOT NULL, + sequence INTEGER NOT NULL DEFAULT 0, + address TEXT NOT NULL UNIQUE, + public_key TEXT NOT NULL CHECK(json_valid(public_key)), + chain_id TEXT NOT NULL, + block_created INTEGER NOT NULL, + controller TEXT NOT NULL, + label TEXT NOT NULL, + handle TEXT NOT NULL, + is_subsidiary BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_subsidiary IN (0,1)), + is_validator BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_validator IN (0,1)), + is_delegator BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_delegator IN (0,1)), + is_accountable BOOLEAN NOT NULL DEFAULT TRUE CHECK(is_accountable IN (0,1)) +); + +-- Profiles represent user identities +CREATE TABLE profiles ( + id TEXT PRIMARY KEY, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP, + address TEXT NOT NULL, + handle TEXT NOT NULL UNIQUE, + origin TEXT NOT NULL, + name TEXT NOT NULL, + UNIQUE(address, origin) +); + +-- Vaults store encrypted data +CREATE TABLE vaults ( + id TEXT PRIMARY KEY, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP, + handle TEXT NOT NULL, + origin TEXT NOT NULL, + address TEXT NOT NULL, + cid TEXT NOT NULL UNIQUE, + config TEXT NOT NULL CHECK(json_valid(config)), + session_id TEXT NOT NULL, + redirect_uri TEXT NOT NULL +); + +CREATE INDEX idx_credentials_handle ON credentials(handle); +CREATE INDEX idx_credentials_origin ON credentials(origin); +CREATE INDEX idx_credentials_deleted_at ON credentials(deleted_at); + +CREATE INDEX idx_accounts_address ON accounts(address); +CREATE INDEX idx_accounts_chain_id ON accounts(chain_id); +CREATE INDEX idx_accounts_block_created ON accounts(block_created); +CREATE INDEX idx_accounts_label ON accounts(label); +CREATE INDEX idx_accounts_controller ON accounts(controller); +CREATE INDEX idx_accounts_deleted_at ON accounts(deleted_at); + +CREATE INDEX idx_profiles_handle ON profiles(handle); +CREATE INDEX idx_profiles_address ON profiles(address); +CREATE INDEX idx_profiles_deleted_at ON profiles(deleted_at); + +CREATE INDEX idx_vaults_handle ON vaults(handle); +CREATE INDEX idx_vaults_session_id ON vaults(session_id); +CREATE INDEX idx_vaults_deleted_at ON vaults(deleted_at);