mirror of
https://github.com/cf-sonr/motr.git
synced 2026-01-12 02:59:13 +00:00
Implement Database Migrations (#12)
* feat: enhance modularity by relocating core packages * refactor: move chart components to dashboard package * refactor: restructure database access layer * refactor: rename credential descriptor to credentials for clarity * feat: enhance development environment configuration for database interactions * feat: integrate go-task for database migrations * feat: introduce middleware for market data and WebAuthn
This commit is contained in:
2
.github/setup_env.sh
vendored
2
.github/setup_env.sh
vendored
@@ -9,6 +9,8 @@ export PATH=$GOBIN:$PATH
|
||||
export ROOT_DIR=$(git rev-parse --show-toplevel)
|
||||
export RADAR_ROOT=$ROOT_DIR/cmd/radar
|
||||
export WORKER_ROOT=$ROOT_DIR/cmd/worker
|
||||
export SQLC_ROOT=$ROOT_DIR/internal/db
|
||||
export MIGRATE_ROOT=$ROOT_DIR/internal/migrate
|
||||
|
||||
# Setup Build Outputs
|
||||
export RADAR_OUT=$RADAR_ROOT/build/app.wasm
|
||||
|
||||
3
Makefile
3
Makefile
@@ -33,3 +33,6 @@ release:
|
||||
|
||||
templ-watch:
|
||||
@devbox run watch:templ
|
||||
|
||||
migrate:
|
||||
@devbox run db:migrate
|
||||
|
||||
@@ -4,19 +4,63 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/sonr-io/motr/pkg/database"
|
||||
"github.com/sonr-io/motr/pkg/session"
|
||||
"github.com/sonr-io/motr/middleware/database"
|
||||
"github.com/sonr-io/motr/middleware/marketapi"
|
||||
"github.com/sonr-io/motr/middleware/session"
|
||||
"github.com/sonr-io/motr/routes"
|
||||
"github.com/syumai/workers"
|
||||
"github.com/syumai/workers/cloudflare/cron"
|
||||
|
||||
_ "github.com/syumai/workers/cloudflare/d1"
|
||||
)
|
||||
|
||||
func main() {
|
||||
e := echo.New()
|
||||
e.Use(session.Middleware(), database.Middleware())
|
||||
// ╭──────────────────────────────────────────────────╮
|
||||
// │ Initialization │
|
||||
// ╰──────────────────────────────────────────────────╯
|
||||
|
||||
// Setup the HTTP handler
|
||||
func loadHandler() http.Handler {
|
||||
e := echo.New()
|
||||
e.Use(session.Middleware(), database.Middleware(), marketapi.Middleware())
|
||||
routes.SetupViews(e)
|
||||
routes.SetupPartials(e)
|
||||
workers.Serve(e)
|
||||
return e
|
||||
}
|
||||
|
||||
// Setup the cron task
|
||||
func loadTask() cron.Task {
|
||||
return func(ctx context.Context) error {
|
||||
e, err := cron.NewEvent(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(e.ScheduledTime.Unix())
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ╭─────────────────────────────────────────────────╮
|
||||
// │ Main Function │
|
||||
// ╰─────────────────────────────────────────────────╯
|
||||
|
||||
func main() {
|
||||
// Setup CRON jobs
|
||||
e := loadHandler()
|
||||
t := loadTask()
|
||||
|
||||
// Configure Worker
|
||||
workers.ServeNonBlock(e)
|
||||
cron.ScheduleTaskNonBlock(t)
|
||||
workers.Ready()
|
||||
|
||||
// Block until handler/task is done
|
||||
select {
|
||||
case <-workers.Done():
|
||||
case <-cron.Done():
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,17 +16,31 @@ port = 4242
|
||||
[observability]
|
||||
enabled = true
|
||||
|
||||
[triggers]
|
||||
crons = ["0 */1 * * *"]
|
||||
|
||||
|
||||
[[d1_databases]]
|
||||
binding = "DB" # available in your Worker on env.DB
|
||||
database_name = "motr-controller-db"
|
||||
database_id = "872a4b08-7e07-4978-b227-5b60940238ed"
|
||||
binding = "ACTIVITY_DB"
|
||||
database_name = "motr-activity"
|
||||
database_id = "a7ccb4bb-c529-4f42-8029-92564a3aecb8"
|
||||
|
||||
[[d1_databases]]
|
||||
binding = "NETWORK_DB"
|
||||
database_name = "motr-network"
|
||||
database_id = "acb75499-3502-4052-9604-263a913e077a"
|
||||
|
||||
[[d1_databases]]
|
||||
binding = "USERS_DB"
|
||||
database_name = "motr-users"
|
||||
database_id = "8ed4d399-5932-419c-b92f-9c20d7a36ad2"
|
||||
|
||||
[[kv_namespaces]]
|
||||
binding = "SESSIONS" # available in your Worker on env.KV
|
||||
binding = "SESSIONS_KV"
|
||||
id = "ea5de66fcfc14b5eba170395e29432ee"
|
||||
|
||||
[[kv_namespaces]]
|
||||
binding = "HANDLES" # available in your Worker on env.KV
|
||||
binding = "HANDLES_KV"
|
||||
id = "271d47087a8842b2aac5ee79cf7bb203"
|
||||
|
||||
[[r2_buckets]]
|
||||
|
||||
@@ -4,20 +4,64 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/sonr-io/motr/pkg/database"
|
||||
"github.com/sonr-io/motr/pkg/session"
|
||||
"github.com/sonr-io/motr/middleware/database"
|
||||
"github.com/sonr-io/motr/middleware/session"
|
||||
"github.com/sonr-io/motr/middleware/sonrapi"
|
||||
"github.com/sonr-io/motr/middleware/webauthn"
|
||||
"github.com/sonr-io/motr/routes"
|
||||
"github.com/syumai/workers"
|
||||
"github.com/syumai/workers/cloudflare/cron"
|
||||
|
||||
_ "github.com/syumai/workers/cloudflare/d1"
|
||||
)
|
||||
|
||||
func main() {
|
||||
e := echo.New()
|
||||
e.Use(session.Middleware(), database.Middleware())
|
||||
// ╭──────────────────────────────────────────────────╮
|
||||
// │ Initialization │
|
||||
// ╰──────────────────────────────────────────────────╯
|
||||
|
||||
// Setup the HTTP handler
|
||||
func loadHandler() http.Handler {
|
||||
e := echo.New()
|
||||
e.Use(session.Middleware(), database.Middleware(), sonrapi.Middleware(), webauthn.Middleware())
|
||||
routes.SetupViews(e)
|
||||
routes.SetupPartials(e)
|
||||
|
||||
workers.Serve(e)
|
||||
return e
|
||||
}
|
||||
|
||||
// Setup the cron task
|
||||
func loadTask() cron.Task {
|
||||
return func(ctx context.Context) error {
|
||||
e, err := cron.NewEvent(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(e.ScheduledTime.Unix())
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ╭─────────────────────────────────────────────────╮
|
||||
// │ Main Function │
|
||||
// ╰─────────────────────────────────────────────────╯
|
||||
|
||||
func main() {
|
||||
// Setup CRON jobs
|
||||
e := loadHandler()
|
||||
t := loadTask()
|
||||
|
||||
// Configure Worker
|
||||
workers.ServeNonBlock(e)
|
||||
cron.ScheduleTaskNonBlock(t)
|
||||
workers.Ready()
|
||||
|
||||
// Block until handler/task is done
|
||||
select {
|
||||
case <-workers.Done():
|
||||
case <-cron.Done():
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,17 +16,30 @@ port = 6969
|
||||
[observability]
|
||||
enabled = true
|
||||
|
||||
[triggers]
|
||||
crons = ["0 */1 * * *"]
|
||||
|
||||
[[d1_databases]]
|
||||
binding = "DB" # available in your Worker on env.DB
|
||||
database_name = "motr-controller-db"
|
||||
database_id = "872a4b08-7e07-4978-b227-5b60940238ed"
|
||||
binding = "ACTIVITY_DB"
|
||||
database_name = "motr-activity"
|
||||
database_id = "a7ccb4bb-c529-4f42-8029-92564a3aecb8"
|
||||
|
||||
[[d1_databases]]
|
||||
binding = "NETWORK_DB"
|
||||
database_name = "motr-network"
|
||||
database_id = "acb75499-3502-4052-9604-263a913e077a"
|
||||
|
||||
[[d1_databases]]
|
||||
binding = "USERS_DB"
|
||||
database_name = "motr-users"
|
||||
database_id = "8ed4d399-5932-419c-b92f-9c20d7a36ad2"
|
||||
|
||||
[[kv_namespaces]]
|
||||
binding = "SESSIONS" # available in your Worker on env.KV
|
||||
binding = "SESSIONS_KV"
|
||||
id = "ea5de66fcfc14b5eba170395e29432ee"
|
||||
|
||||
[[kv_namespaces]]
|
||||
binding = "HANDLES" # available in your Worker on env.KV
|
||||
binding = "HANDLES_KV"
|
||||
id = "271d47087a8842b2aac5ee79cf7bb203"
|
||||
|
||||
[[r2_buckets]]
|
||||
|
||||
13
devbox.json
13
devbox.json
@@ -5,9 +5,8 @@
|
||||
"sqlc@latest",
|
||||
"nodejs@latest",
|
||||
"goreleaser@latest",
|
||||
"doppler@latest",
|
||||
"commitizen@latest",
|
||||
"process-compose@latest"
|
||||
"go-task@latest",
|
||||
"doppler@latest"
|
||||
],
|
||||
"shell": {
|
||||
"init_hook": [
|
||||
@@ -17,9 +16,6 @@
|
||||
"npm_install $WORKER_ROOT"
|
||||
],
|
||||
"scripts": {
|
||||
"dev": [
|
||||
"process-compose up"
|
||||
],
|
||||
"deploy": [
|
||||
"wrangler_deploy $RADAR_ROOT",
|
||||
"wrangler_deploy $WORKER_ROOT"
|
||||
@@ -48,7 +44,10 @@
|
||||
"npm run start"
|
||||
],
|
||||
"gen:sqlc": [
|
||||
"cd ./internal/sink && sqlc generate"
|
||||
"cd $SQLC_ROOT && sqlc generate"
|
||||
],
|
||||
"db:migrate": [
|
||||
"cd $MIGRATE_ROOT && task"
|
||||
],
|
||||
"gen:templ": [
|
||||
"templ generate"
|
||||
|
||||
160
devbox.lock
160
devbox.lock
@@ -1,70 +1,6 @@
|
||||
{
|
||||
"lockfile_version": "1",
|
||||
"packages": {
|
||||
"commitizen@latest": {
|
||||
"last_modified": "2025-05-21T01:27:34Z",
|
||||
"resolved": "github:NixOS/nixpkgs/f0d925b947cca0bbe7f2d25115cbaf021844aba7#commitizen",
|
||||
"source": "devbox-search",
|
||||
"version": "4.7.1",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/m3307fx56ifajpg0qgqjj9dg71xjcfn4-python3.12-commitizen-4.7.1",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/1081mrd0v09sx6g2c12h2bsyyim0s204-python3.12-commitizen-4.7.1-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/m3307fx56ifajpg0qgqjj9dg71xjcfn4-python3.12-commitizen-4.7.1"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/kiaab8hfkacad3nh3ygc9p6m02sskb0l-python3.12-commitizen-4.7.1",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/y7yqhxmmfnb5i012xvkzg8g5qkq8vrkj-python3.12-commitizen-4.7.1-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/kiaab8hfkacad3nh3ygc9p6m02sskb0l-python3.12-commitizen-4.7.1"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/06s8d1qwgd1mw0jmp35fhfdznwpppb0l-python3.12-commitizen-4.7.1",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/nlvvhrsg465n918474zh3jirlifvqbww-python3.12-commitizen-4.7.1-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/06s8d1qwgd1mw0jmp35fhfdznwpppb0l-python3.12-commitizen-4.7.1"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/gaqvcwn0dya1crk789s0xsf7s4knraxz-python3.12-commitizen-4.7.1",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/iagih5hd0nq8a5fh3naads5xc3gpg9jn-python3.12-commitizen-4.7.1-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/gaqvcwn0dya1crk789s0xsf7s4knraxz-python3.12-commitizen-4.7.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"doppler@latest": {
|
||||
"last_modified": "2025-05-16T20:19:48Z",
|
||||
"resolved": "github:NixOS/nixpkgs/12a55407652e04dcf2309436eb06fef0d3713ef3#doppler",
|
||||
@@ -117,6 +53,54 @@
|
||||
"last_modified": "2025-05-26T00:03:27Z",
|
||||
"resolved": "github:NixOS/nixpkgs/3108eaa516ae22c2360928589731a4f1581526ef?lastModified=1748217807&narHash=sha256-P3u2PXxMlo49PutQLnk2PhI%2FimC69hFl1yY4aT5Nax8%3D"
|
||||
},
|
||||
"go-task@latest": {
|
||||
"last_modified": "2025-05-16T20:19:48Z",
|
||||
"resolved": "github:NixOS/nixpkgs/12a55407652e04dcf2309436eb06fef0d3713ef3#go-task",
|
||||
"source": "devbox-search",
|
||||
"version": "3.43.3",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/5h0ykqayf8kfxwqlawzxvm05hlq7n22c-go-task-3.43.3",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/5h0ykqayf8kfxwqlawzxvm05hlq7n22c-go-task-3.43.3"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/xxl2rg7k3c95gk5s0kwj8p8055r4yldf-go-task-3.43.3",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/xxl2rg7k3c95gk5s0kwj8p8055r4yldf-go-task-3.43.3"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/4az7i4f6lm4ss77wnf8kklkr21hrfhns-go-task-3.43.3",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/4az7i4f6lm4ss77wnf8kklkr21hrfhns-go-task-3.43.3"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/gjdgw1zhvl9hl7mmiw6ncpnpmpxlk2yb-go-task-3.43.3",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/gjdgw1zhvl9hl7mmiw6ncpnpmpxlk2yb-go-task-3.43.3"
|
||||
}
|
||||
}
|
||||
},
|
||||
"goreleaser@latest": {
|
||||
"last_modified": "2025-05-16T20:19:48Z",
|
||||
"resolved": "github:NixOS/nixpkgs/12a55407652e04dcf2309436eb06fef0d3713ef3#goreleaser",
|
||||
@@ -246,54 +230,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"process-compose@latest": {
|
||||
"last_modified": "2025-05-16T20:19:48Z",
|
||||
"resolved": "github:NixOS/nixpkgs/12a55407652e04dcf2309436eb06fef0d3713ef3#process-compose",
|
||||
"source": "devbox-search",
|
||||
"version": "1.64.1",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/yffykcwzkaqy490wzkiyw0ff6lss5fcx-process-compose-1.64.1",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/yffykcwzkaqy490wzkiyw0ff6lss5fcx-process-compose-1.64.1"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/2n23nlnm52pi84vn3g8mg14xxsg5ww00-process-compose-1.64.1",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/2n23nlnm52pi84vn3g8mg14xxsg5ww00-process-compose-1.64.1"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/g3r6rxrfk09vfv19rzpd6fmc9s75d21p-process-compose-1.64.1",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/g3r6rxrfk09vfv19rzpd6fmc9s75d21p-process-compose-1.64.1"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/4hymfhkv9ldhbjqz6wjln05bhyxfd9xl-process-compose-1.64.1",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/4hymfhkv9ldhbjqz6wjln05bhyxfd9xl-process-compose-1.64.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sqlc@latest": {
|
||||
"last_modified": "2025-05-16T20:19:48Z",
|
||||
"resolved": "github:NixOS/nixpkgs/12a55407652e04dcf2309436eb06fef0d3713ef3#sqlc",
|
||||
|
||||
@@ -3,7 +3,7 @@ package handlers
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/sonr-io/motr/internal/ui/home"
|
||||
"github.com/sonr-io/motr/pkg/render"
|
||||
"github.com/sonr-io/motr/middleware/render"
|
||||
)
|
||||
|
||||
func HandleItemNotFound(c echo.Context) error {
|
||||
|
||||
@@ -3,7 +3,7 @@ package handlers
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/sonr-io/motr/internal/ui/home"
|
||||
"github.com/sonr-io/motr/pkg/render"
|
||||
"github.com/sonr-io/motr/middleware/render"
|
||||
)
|
||||
|
||||
func HandleDefaultIndex(c echo.Context) error {
|
||||
|
||||
@@ -3,18 +3,10 @@ package handlers
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/sonr-io/motr/internal/ui/login"
|
||||
"github.com/sonr-io/motr/pkg/render"
|
||||
"github.com/sonr-io/motr/pkg/webauth"
|
||||
"github.com/sonr-io/motr/middleware/render"
|
||||
)
|
||||
|
||||
type LoginOptions struct {
|
||||
Account string
|
||||
Handle string
|
||||
HelpText string
|
||||
Label string
|
||||
Challenge string
|
||||
AllowedCredentials []*webauth.CredentialDescriptor
|
||||
}
|
||||
|
||||
|
||||
func HandleLoginCheck(c echo.Context) error {
|
||||
return render.View(c, login.LoginView())
|
||||
|
||||
@@ -3,7 +3,7 @@ package handlers
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/sonr-io/motr/internal/ui/register"
|
||||
"github.com/sonr-io/motr/pkg/render"
|
||||
"github.com/sonr-io/motr/middleware/render"
|
||||
)
|
||||
|
||||
type RegisterOptions struct {
|
||||
|
||||
@@ -29,6 +29,42 @@ type Activity struct {
|
||||
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"`
|
||||
@@ -12,28 +12,50 @@ import (
|
||||
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)
|
||||
}
|
||||
@@ -189,3 +189,150 @@ RETURNING *;
|
||||
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 = ?;
|
||||
@@ -73,6 +73,141 @@ func (q *Queries) GetActivityByTxHash(ctx context.Context, txHash sql.NullString
|
||||
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
|
||||
@@ -132,6 +267,55 @@ func (q *Queries) GetHealthByID(ctx context.Context, id string) (Health, error)
|
||||
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
|
||||
@@ -290,6 +474,134 @@ func (q *Queries) InsertActivity(ctx context.Context, arg InsertActivityParams)
|
||||
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,
|
||||
@@ -573,6 +885,141 @@ func (q *Queries) ListActivitiesByType(ctx context.Context, arg ListActivitiesBy
|
||||
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
|
||||
@@ -832,6 +1279,39 @@ func (q *Queries) SoftDeleteActivity(ctx context.Context, id string) error {
|
||||
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
|
||||
@@ -912,6 +1392,144 @@ func (q *Queries) UpdateActivityStatus(ctx context.Context, arg UpdateActivitySt
|
||||
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
|
||||
@@ -59,6 +59,47 @@ CREATE TABLE health (
|
||||
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);
|
||||
@@ -82,3 +123,14 @@ 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);
|
||||
@@ -62,42 +62,6 @@ type Blockchain struct {
|
||||
Forum sql.NullString `json:"forum"`
|
||||
}
|
||||
|
||||
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 Price struct {
|
||||
ID string `json:"id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
@@ -22,14 +22,6 @@ type Querier interface {
|
||||
GetBlockchainEndpoints(ctx context.Context, id string) (GetBlockchainEndpointsRow, error)
|
||||
GetBlockchainExplorer(ctx context.Context, id string) (GetBlockchainExplorerRow, error)
|
||||
GetBlockchainWithAssetInfo(ctx context.Context, id string) (GetBlockchainWithAssetInfoRow, 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)
|
||||
GetLatestFearGreedIndex(ctx context.Context) (FearGreedIndex, error)
|
||||
GetLatestGlobalMarket(ctx context.Context) (GlobalMarket, 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)
|
||||
@@ -39,12 +31,6 @@ type Querier interface {
|
||||
InsertAsset(ctx context.Context, arg InsertAssetParams) (Asset, error)
|
||||
// BLOCKCHAIN QUERIES
|
||||
InsertBlockchain(ctx context.Context, arg InsertBlockchainParams) (Blockchain, 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)
|
||||
// GLOBAL MARKET QUERIES (NEW)
|
||||
InsertGlobalMarket(ctx context.Context, arg InsertGlobalMarketParams) (GlobalMarket, error)
|
||||
// PRICE QUERIES (UPDATED)
|
||||
InsertPrice(ctx context.Context, arg InsertPriceParams) (Price, error)
|
||||
// PRICE CONVERSION QUERIES (NEW)
|
||||
@@ -58,16 +44,10 @@ type Querier interface {
|
||||
ListBlockchainsWithExtensionSupport(ctx context.Context) ([]Blockchain, error)
|
||||
ListBlockchainsWithMobileSupport(ctx context.Context) ([]Blockchain, error)
|
||||
ListBlockchainsWithStaking(ctx context.Context) ([]Blockchain, 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)
|
||||
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
|
||||
SoftDeleteCryptoListing(ctx context.Context, id string) error
|
||||
SoftDeleteFearGreedIndex(ctx context.Context, id string) error
|
||||
SoftDeleteGlobalMarket(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)
|
||||
@@ -77,9 +57,6 @@ type Querier interface {
|
||||
UpdateBlockchainFeeInfo(ctx context.Context, arg UpdateBlockchainFeeInfoParams) (Blockchain, error)
|
||||
UpdateBlockchainImages(ctx context.Context, arg UpdateBlockchainImagesParams) (Blockchain, error)
|
||||
UpdateBlockchainSocialLinks(ctx context.Context, arg UpdateBlockchainSocialLinksParams) (Blockchain, 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)
|
||||
UpdatePrice(ctx context.Context, arg UpdatePriceParams) (Price, error)
|
||||
UpdatePriceConversion(ctx context.Context, arg UpdatePriceConversionParams) (PriceConversion, error)
|
||||
}
|
||||
@@ -190,152 +190,6 @@ UPDATE price_conversions
|
||||
SET deleted_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?;
|
||||
|
||||
-- GLOBAL MARKET QUERIES (NEW)
|
||||
-- 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: 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: 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 = ?;
|
||||
|
||||
-- BLOCKCHAIN QUERIES
|
||||
-- name: InsertBlockchain :one
|
||||
INSERT INTO blockchains (
|
||||
@@ -541,190 +541,6 @@ func (q *Queries) GetBlockchainWithAssetInfo(ctx context.Context, id string) (Ge
|
||||
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 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 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
|
||||
@@ -1088,135 +904,6 @@ func (q *Queries) InsertBlockchain(ctx context.Context, arg InsertBlockchainPara
|
||||
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"`
|
||||
}
|
||||
|
||||
// GLOBAL MARKET QUERIES (NEW)
|
||||
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 insertPrice = `-- name: InsertPrice :one
|
||||
INSERT INTO prices (
|
||||
asset_id,
|
||||
@@ -2010,141 +1697,6 @@ func (q *Queries) ListBlockchainsWithStaking(ctx context.Context) ([]Blockchain,
|
||||
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 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
|
||||
@@ -2309,39 +1861,6 @@ func (q *Queries) SoftDeleteBlockchain(ctx context.Context, id string) error {
|
||||
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 softDeletePriceConversion = `-- name: SoftDeletePriceConversion :exec
|
||||
UPDATE price_conversions
|
||||
SET deleted_at = CURRENT_TIMESTAMP
|
||||
@@ -2942,144 +2461,6 @@ func (q *Queries) UpdateBlockchainSocialLinks(ctx context.Context, arg UpdateBlo
|
||||
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 updatePrice = `-- name: UpdatePrice :one
|
||||
UPDATE prices
|
||||
SET
|
||||
@@ -52,46 +52,6 @@ CREATE TABLE price_conversions (
|
||||
UNIQUE(price_id, currency_code)
|
||||
);
|
||||
|
||||
-- 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)
|
||||
);
|
||||
|
||||
-- Blockchains table to store chain configuration parameters
|
||||
CREATE TABLE blockchains (
|
||||
id TEXT PRIMARY KEY,
|
||||
@@ -172,18 +132,6 @@ 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_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);
|
||||
|
||||
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);
|
||||
1
internal/jobs/cron.go
Normal file
1
internal/jobs/cron.go
Normal file
@@ -0,0 +1 @@
|
||||
package jobs
|
||||
12
internal/jobs/events.go
Normal file
12
internal/jobs/events.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package jobs
|
||||
|
||||
type EventTrigger string
|
||||
|
||||
var (
|
||||
EventTriggerMinute = EventTrigger("0 * * * * *") // Every minute (with seconds)
|
||||
EventTriggerHourly = EventTrigger("0 0 * * * *") // Every hour at minute 0
|
||||
EventTriggerDaily = EventTrigger("0 0 0 * * *") // Every day at 00:00:00
|
||||
EventTriggerWeekly = EventTrigger("0 0 0 * * 0") // Every Sunday at 00:00:00
|
||||
EventTriggerMonthly = EventTrigger("0 0 0 1 * *") // First day of every month at 00:00:00
|
||||
EventTriggerYearly = EventTrigger("0 0 0 1 1 *") // January 1st every year at 00:00:00
|
||||
)
|
||||
1
internal/jobs/tasks.go
Normal file
1
internal/jobs/tasks.go
Normal file
@@ -0,0 +1 @@
|
||||
package jobs
|
||||
1
internal/migrate/001_accounts_table.down.sql
Normal file
1
internal/migrate/001_accounts_table.down.sql
Normal file
@@ -0,0 +1 @@
|
||||
DROP TABLE accounts;
|
||||
30
internal/migrate/001_accounts_table.up.sql
Normal file
30
internal/migrate/001_accounts_table.up.sql
Normal file
@@ -0,0 +1,30 @@
|
||||
-- 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))
|
||||
);
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
||||
1
internal/migrate/002_credentials_table.down.sql
Normal file
1
internal/migrate/002_credentials_table.down.sql
Normal file
@@ -0,0 +1 @@
|
||||
DROP TABLE credential;
|
||||
19
internal/migrate/002_credentials_table.up.sql
Normal file
19
internal/migrate/002_credentials_table.up.sql
Normal file
@@ -0,0 +1,19 @@
|
||||
-- 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
|
||||
);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
1
internal/migrate/003_profiles_table.down.sql
Normal file
1
internal/migrate/003_profiles_table.down.sql
Normal file
@@ -0,0 +1 @@
|
||||
DROP TABLE profiles;
|
||||
18
internal/migrate/003_profiles_table.up.sql
Normal file
18
internal/migrate/003_profiles_table.up.sql
Normal file
@@ -0,0 +1,18 @@
|
||||
-- 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)
|
||||
);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
1
internal/migrate/004_vaults_table.down.sql
Normal file
1
internal/migrate/004_vaults_table.down.sql
Normal file
@@ -0,0 +1 @@
|
||||
DROP TABLE vaults;
|
||||
19
internal/migrate/004_vaults_table.up.sql
Normal file
19
internal/migrate/004_vaults_table.up.sql
Normal file
@@ -0,0 +1,19 @@
|
||||
-- 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_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)
|
||||
1
internal/migrate/005_assets_table.down.sql
Normal file
1
internal/migrate/005_assets_table.down.sql
Normal file
@@ -0,0 +1 @@
|
||||
DROP TABLE assets;
|
||||
21
internal/migrate/005_assets_table.up.sql
Normal file
21
internal/migrate/005_assets_table.up.sql
Normal file
@@ -0,0 +1,21 @@
|
||||
-- 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)
|
||||
);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
0
internal/migrate/006_prices_table.down.sql
Normal file
0
internal/migrate/006_prices_table.down.sql
Normal file
28
internal/migrate/006_prices_table.up.sql
Normal file
28
internal/migrate/006_prices_table.up.sql
Normal file
@@ -0,0 +1,28 @@
|
||||
-- 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)
|
||||
);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
1
internal/migrate/007_price_conversions_table.down.sql
Normal file
1
internal/migrate/007_price_conversions_table.down.sql
Normal file
@@ -0,0 +1 @@
|
||||
DROP TABLE price_conversions;
|
||||
21
internal/migrate/007_price_conversions_table.up.sql
Normal file
21
internal/migrate/007_price_conversions_table.up.sql
Normal file
@@ -0,0 +1,21 @@
|
||||
-- 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)
|
||||
);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
1
internal/migrate/008_blockchains_table.down.sql
Normal file
1
internal/migrate/008_blockchains_table.down.sql
Normal file
@@ -0,0 +1 @@
|
||||
DROP TABLE blockchains;
|
||||
71
internal/migrate/008_blockchains_table.up.sql
Normal file
71
internal/migrate/008_blockchains_table.up.sql
Normal file
@@ -0,0 +1,71 @@
|
||||
-- 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))
|
||||
);
|
||||
|
||||
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);
|
||||
1
internal/migrate/009_services_table.down.sql
Normal file
1
internal/migrate/009_services_table.down.sql
Normal file
@@ -0,0 +1 @@
|
||||
DROP TABLE services;
|
||||
24
internal/migrate/009_services_table.up.sql
Normal file
24
internal/migrate/009_services_table.up.sql
Normal file
@@ -0,0 +1,24 @@
|
||||
-- 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)
|
||||
);
|
||||
|
||||
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);
|
||||
1
internal/migrate/010_activities_table.down.sql
Normal file
1
internal/migrate/010_activities_table.down.sql
Normal file
@@ -0,0 +1 @@
|
||||
DROP TABLE activities;
|
||||
32
internal/migrate/010_activities_table.up.sql
Normal file
32
internal/migrate/010_activities_table.up.sql
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
-- 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)
|
||||
);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
32
internal/migrate/011_health_table.down.sql
Normal file
32
internal/migrate/011_health_table.down.sql
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
-- 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)
|
||||
);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
28
internal/migrate/011_health_table.up.sql
Normal file
28
internal/migrate/011_health_table.up.sql
Normal file
@@ -0,0 +1,28 @@
|
||||
-- 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)
|
||||
);
|
||||
|
||||
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);
|
||||
|
||||
1
internal/migrate/012_global_market_table.down.sql
Normal file
1
internal/migrate/012_global_market_table.down.sql
Normal file
@@ -0,0 +1 @@
|
||||
DROP TABLE global_market;
|
||||
19
internal/migrate/012_global_market_table.up.sql
Normal file
19
internal/migrate/012_global_market_table.up.sql
Normal file
@@ -0,0 +1,19 @@
|
||||
-- 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
|
||||
);
|
||||
|
||||
CREATE INDEX idx_global_market_last_updated ON global_market(last_updated);
|
||||
CREATE INDEX idx_global_market_deleted_at ON global_market(deleted_at);
|
||||
|
||||
|
||||
1
internal/migrate/013_fear_greed_index_table.down.sql
Normal file
1
internal/migrate/013_fear_greed_index_table.down.sql
Normal file
@@ -0,0 +1 @@
|
||||
DROP TABLE fear_greed_index;
|
||||
15
internal/migrate/013_fear_greed_index_table.up.sql
Normal file
15
internal/migrate/013_fear_greed_index_table.up.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
-- 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
|
||||
);
|
||||
|
||||
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);
|
||||
1
internal/migrate/014_crypto_listings_table.down.sql
Normal file
1
internal/migrate/014_crypto_listings_table.down.sql
Normal file
@@ -0,0 +1 @@
|
||||
DROP TABLE crypto_listings;
|
||||
18
internal/migrate/014_crypto_listings_table.up.sql
Normal file
18
internal/migrate/014_crypto_listings_table.up.sql
Normal file
@@ -0,0 +1,18 @@
|
||||
-- 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_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);
|
||||
199
internal/migrate/Taskfile.yml
Normal file
199
internal/migrate/Taskfile.yml
Normal file
@@ -0,0 +1,199 @@
|
||||
# yaml-language-server: $schema=https://taskfile.dev/schema.json
|
||||
version: "3"
|
||||
silent: true
|
||||
|
||||
tasks:
|
||||
default:
|
||||
cmd: task -l --json | jq -r '.tasks[].name' | fzf | xargs task
|
||||
|
||||
initialize:
|
||||
cmds:
|
||||
- task: migrate:accounts:up
|
||||
- task: migrate:credentials:up
|
||||
- task: migrate:profiles:up
|
||||
- task: migrate:vaults:up
|
||||
- task: migrate:assets:up
|
||||
- task: migrate:prices:up
|
||||
- task: migrate:price_conversions:up
|
||||
- task: migrate:blockchains:up
|
||||
- task: migrate:services:up
|
||||
- task: migrate:activities:up
|
||||
- task: migrate:health:up
|
||||
- task: migrate:global_market:up
|
||||
- task: migrate:fear_greed_index:up
|
||||
- task: migrate:crypto_listings:up
|
||||
|
||||
migrate:
|
||||
cmds:
|
||||
- task: migrate:accounts
|
||||
- task: migrate:credentials
|
||||
- task: migrate:profiles
|
||||
- task: migrate:vaults
|
||||
- task: migrate:assets
|
||||
- task: migrate:prices
|
||||
- task: migrate:price_conversions
|
||||
- task: migrate:blockchains
|
||||
- task: migrate:services
|
||||
- task: migrate:activities
|
||||
- task: migrate:health
|
||||
- task: migrate:global_market
|
||||
- task: migrate:fear_greed_index
|
||||
- task: migrate:crypto_listings
|
||||
|
||||
# ---------------
|
||||
# Main Tasks
|
||||
# ---------------
|
||||
migrate:accounts:
|
||||
cmds:
|
||||
- task: migrate:accounts:down
|
||||
- task: migrate:accounts:up
|
||||
|
||||
migrate:accounts:up:
|
||||
cmd: wrangler d1 execute USERS_DB --file 001_accounts_table.up.sql --remote
|
||||
|
||||
migrate:accounts:down:
|
||||
cmd: wrangler d1 execute USERS_DB --file 001_accounts_table.down.sql --remote
|
||||
|
||||
migrate:credentials:
|
||||
cmds:
|
||||
- task: migrate:credentials:down
|
||||
- task: migrate:credentials:up
|
||||
|
||||
migrate:credentials:up:
|
||||
cmd: wrangler d1 execute USERS_DB --file 002_credentials_table.up.sql --remote
|
||||
|
||||
migrate:credentials:down:
|
||||
cmd: wrangler d1 execute USERS_DB --file 002_credentials_table.down.sql --remote
|
||||
|
||||
migrate:profiles:
|
||||
cmds:
|
||||
- task: migrate:profiles:down
|
||||
- task: migrate:profiles:up
|
||||
|
||||
migrate:profiles:up:
|
||||
cmd: wrangler d1 execute USERS_DB --file 003_profiles_table.up.sql --remote
|
||||
|
||||
migrate:profiles:down:
|
||||
cmd: wrangler d1 execute USERS_DB --file 003_profiles_table.down.sql --remote
|
||||
|
||||
migrate:vaults:
|
||||
cmds:
|
||||
- task: migrate:vaults:down
|
||||
- task: migrate:vaults:up
|
||||
|
||||
migrate:vaults:down:
|
||||
cmd: wrangler d1 execute USERS_DB --file 004_vaults_table.down.sql --remote
|
||||
|
||||
migrate:vaults:up:
|
||||
cmd: wrangler d1 execute USERS_DB --file 004_vaults_table.up.sql --remote
|
||||
|
||||
migrate:assets:
|
||||
cmds:
|
||||
- task: migrate:assets:down
|
||||
- task: migrate:assets:up
|
||||
|
||||
migrate:assets:up:
|
||||
cmd: wrangler d1 execute NETWORK_DB --file 005_assets_table.up.sql --remote
|
||||
|
||||
migrate:assets:down:
|
||||
cmd: wrangler d1 execute NETWORK_DB --file 005_assets_table.down.sql --remote
|
||||
|
||||
migrate:prices:
|
||||
cmds:
|
||||
- task: migrate:prices:down
|
||||
- task: migrate:prices:up
|
||||
|
||||
migrate:prices:up:
|
||||
cmd: wrangler d1 execute NETWORK_DB --file 006_prices_table.up.sql --remote
|
||||
|
||||
migrate:prices:down:
|
||||
cmd: wrangler d1 execute NETWORK_DB --file 006_prices_table.down.sql --remote
|
||||
|
||||
migrate:price_conversions:
|
||||
cmds:
|
||||
- task: migrate:price_conversions:down
|
||||
- task: migrate:price_conversions:up
|
||||
|
||||
migrate:price_conversions:up:
|
||||
cmd: wrangler d1 execute NETWORK_DB --file 007_price_conversions_table.up.sql --remote
|
||||
|
||||
migrate:price_conversions:down:
|
||||
cmd: wrangler d1 execute NETWORK_DB --file 007_price_conversions_table.down.sql --remote
|
||||
|
||||
migrate:blockchains:
|
||||
cmds:
|
||||
- task: migrate:blockchains:down
|
||||
- task: migrate:blockchains:up
|
||||
|
||||
migrate:blockchains:up:
|
||||
cmd: wrangler d1 execute NETWORK_DB --file 008_blockchains_table.up.sql --remote
|
||||
|
||||
migrate:blockchains:down:
|
||||
cmd: wrangler d1 execute NETWORK_DB --file 008_blockchains_table.down.sql --remote
|
||||
|
||||
migrate:services:
|
||||
cmds:
|
||||
- task: migrate:services:down
|
||||
- task: migrate:services:up
|
||||
|
||||
migrate:services:up:
|
||||
cmd: wrangler d1 execute ACTIVITY_DB --file 009_services_table.up.sql --remote
|
||||
|
||||
migrate:services:down:
|
||||
cmd: wrangler d1 execute ACTIVITY_DB --file 009_services_table.down.sql --remote
|
||||
|
||||
migrate:activities:
|
||||
cmds:
|
||||
- task: migrate:activities:down
|
||||
- task: migrate:activities:up
|
||||
|
||||
migrate:activities:up:
|
||||
cmd: wrangler d1 execute ACTIVITY_DB --file 010_activities_table.up.sql --remote
|
||||
|
||||
migrate:activities:down:
|
||||
cmd: wrangler d1 execute ACTIVITY_DB --file 010_activities_table.down.sql --remote
|
||||
|
||||
migrate:health:
|
||||
cmds:
|
||||
- task: migrate:health:down
|
||||
- task: migrate:health:up
|
||||
|
||||
migrate:health:up:
|
||||
cmd: wrangler d1 execute ACTIVITY_DB --file 011_health_table.up.sql --remote
|
||||
|
||||
migrate:health:down:
|
||||
cmd: wrangler d1 execute ACTIVITY_DB --file 011_health_table.down.sql --remote
|
||||
|
||||
migrate:global_market:
|
||||
cmds:
|
||||
- task: global_market:down
|
||||
- task: global_market:up
|
||||
|
||||
migrate:global_market:up:
|
||||
cmd: wrangler d1 execute ACTIVITY_DB --file 012_global_market_table.up.sql --remote
|
||||
|
||||
migrate:global_market:down:
|
||||
cmd: wrangler d1 execute ACTIVITY_DB --file 012_global_market_table.down.sql --remote
|
||||
|
||||
migrate:fear_greed_index:
|
||||
cmds:
|
||||
- task: migrate:fear_greed_index:down
|
||||
- task: migrate:fear_greed_index:up
|
||||
|
||||
migrate:fear_greed_index:up:
|
||||
cmd: wrangler d1 execute ACTIVITY_DB --file 013_fear_greed_index_table.up.sql --remote
|
||||
|
||||
migrate:fear_greed_index:down:
|
||||
cmd: wrangler d1 execute ACTIVITY_DB --file 013_fear_greed_index_table.down.sql --remote
|
||||
|
||||
migrate:crypto_listings:
|
||||
cmds:
|
||||
- task: migrate:crypto_listings:down
|
||||
- task: migrate:crypto_listings:up
|
||||
|
||||
migrate:crypto_listings:up:
|
||||
cmd: wrangler d1 execute ACTIVITY_DB --file 014_crypto_listings_table.up.sql --remote
|
||||
|
||||
migrate:crypto_listings:down:
|
||||
cmd: wrangler d1 execute ACTIVITY_DB --file 014_crypto_listings_table.down.sql --remote
|
||||
|
||||
64
internal/migrate/wrangler.toml
Normal file
64
internal/migrate/wrangler.toml
Normal file
@@ -0,0 +1,64 @@
|
||||
# Top-level configuration
|
||||
name = "motr-worker"
|
||||
main = "worker.mjs"
|
||||
compatibility_date = "2025-04-14"
|
||||
|
||||
routes = [
|
||||
{ pattern = "sonr.id", custom_domain = true },
|
||||
]
|
||||
|
||||
[build]
|
||||
command = "devbox run build:worker"
|
||||
|
||||
[dev]
|
||||
port = 6969
|
||||
|
||||
[observability]
|
||||
enabled = true
|
||||
|
||||
[triggers]
|
||||
crons = ["0 */1 * * *"]
|
||||
|
||||
[[d1_databases]]
|
||||
binding = "ACTIVITY_DB"
|
||||
database_name = "motr-activity"
|
||||
database_id = "a7ccb4bb-c529-4f42-8029-92564a3aecb8"
|
||||
|
||||
[[d1_databases]]
|
||||
binding = "NETWORK_DB"
|
||||
database_name = "motr-network"
|
||||
database_id = "acb75499-3502-4052-9604-263a913e077a"
|
||||
|
||||
[[d1_databases]]
|
||||
binding = "USERS_DB"
|
||||
database_name = "motr-users"
|
||||
database_id = "8ed4d399-5932-419c-b92f-9c20d7a36ad2"
|
||||
|
||||
[[kv_namespaces]]
|
||||
binding = "SESSIONS_KV"
|
||||
id = "ea5de66fcfc14b5eba170395e29432ee"
|
||||
|
||||
[[kv_namespaces]]
|
||||
binding = "HANDLES_KV"
|
||||
id = "271d47087a8842b2aac5ee79cf7bb203"
|
||||
|
||||
[[r2_buckets]]
|
||||
binding = 'PROFILES'
|
||||
bucket_name = 'profiles'
|
||||
|
||||
[vars]
|
||||
SONR_CHAIN_ID = 'sonr-testnet-1'
|
||||
IPFS_GATEWAY = 'https://ipfs.sonr.land'
|
||||
SONR_API_URL = 'https://api.sonr.land'
|
||||
SONR_RPC_URL = 'https://rpc.sonr.land'
|
||||
SONR_GRPC_URL = 'https://grpc.sonr.land'
|
||||
MATRIX_SERVER = 'https://bm.chat'
|
||||
MOTR_GATEWAY = 'https://sonr.id'
|
||||
MOTR_VAULT = 'https://did.run'
|
||||
|
||||
[durable_objects]
|
||||
bindings = [{name = "VAULT", class_name = "Vault"}]
|
||||
|
||||
[[migrations]]
|
||||
tag = "v1" # Should be unique for each entry
|
||||
new_classes = ["Vault"] # List the classes that should be created
|
||||
@@ -2,7 +2,7 @@ package dash
|
||||
|
||||
import (
|
||||
"github.com/sonr-io/motr/internal/ui"
|
||||
"github.com/sonr-io/motr/pkg/session"
|
||||
"github.com/sonr-io/motr/middleware/session"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package home
|
||||
|
||||
import "github.com/sonr-io/motr/internal/ui"
|
||||
import "github.com/sonr-io/motr/pkg/session"
|
||||
import "github.com/sonr-io/motr/middleware/session"
|
||||
|
||||
func HomeView() templ.Component {
|
||||
return homeComponent()
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package login
|
||||
|
||||
import "github.com/sonr-io/motr/internal/ui"
|
||||
import "github.com/sonr-io/motr/pkg/session"
|
||||
import "github.com/sonr-io/motr/middleware/session"
|
||||
|
||||
templ LoginView() {
|
||||
@ui.HTML() {
|
||||
@ui.Head() {
|
||||
@session.DefaultMetaComponent()
|
||||
@ui.DefaultMetaComponent()
|
||||
}
|
||||
@ui.Nav() {
|
||||
@ui.NavLeft() {
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package register
|
||||
|
||||
import "github.com/sonr-io/motr/internal/ui"
|
||||
import "github.com/sonr-io/motr/pkg/session"
|
||||
import "github.com/sonr-io/motr/middleware/session"
|
||||
|
||||
templ RegisterView() {
|
||||
@ui.HTML() {
|
||||
@ui.Head() {
|
||||
@session.DefaultMetaComponent()
|
||||
@ui.DefaultMetaComponent()
|
||||
}
|
||||
@ui.Nav() {
|
||||
@ui.NavLeft() {
|
||||
|
||||
@@ -6,9 +6,9 @@ package database
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/sonr-io/motr/internal/sink/activity"
|
||||
"github.com/sonr-io/motr/internal/sink/network"
|
||||
"github.com/sonr-io/motr/internal/sink/users"
|
||||
"github.com/sonr-io/motr/internal/db/activity"
|
||||
"github.com/sonr-io/motr/internal/db/network"
|
||||
"github.com/sonr-io/motr/internal/db/users"
|
||||
|
||||
_ "github.com/syumai/workers/cloudflare/d1"
|
||||
)
|
||||
@@ -4,9 +4,9 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"github.com/sonr-io/motr/internal/sink/activity"
|
||||
"github.com/sonr-io/motr/internal/sink/network"
|
||||
"github.com/sonr-io/motr/internal/sink/users"
|
||||
"github.com/sonr-io/motr/internal/db/activity"
|
||||
"github.com/sonr-io/motr/internal/db/network"
|
||||
"github.com/sonr-io/motr/internal/db/users"
|
||||
)
|
||||
|
||||
// connection is a database context
|
||||
77
middleware/marketapi/middleware.go
Normal file
77
middleware/marketapi/middleware.go
Normal file
@@ -0,0 +1,77 @@
|
||||
//go:build js && wasm
|
||||
// +build js,wasm
|
||||
|
||||
package marketapi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/syumai/workers/cloudflare/fetch"
|
||||
)
|
||||
|
||||
const (
|
||||
kCryptoAPIURL = "https://api.alternative.me"
|
||||
kCryptoAPIListings = "/v2/listings"
|
||||
kCryptoAPITickers = "/v2/ticker"
|
||||
kCryptoAPIGlobal = "/v2/global"
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
echo.Context
|
||||
client *fetch.Client
|
||||
}
|
||||
|
||||
func (c *Context) Listings(symbol string) (*ListingsResponse, error) {
|
||||
r := c.buildRequest(fmt.Sprintf("%s/%s", kCryptoAPIListings, symbol))
|
||||
v := &ListingsResponse{}
|
||||
err := c.fetch(r, v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (c *Context) Ticker(symbol string) (*TickersResponse, error) {
|
||||
r := c.buildRequest(fmt.Sprintf("%s/%s", kCryptoAPITickers, symbol))
|
||||
v := &TickersResponse{}
|
||||
err := c.fetch(r, v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (c *Context) GlobalMarket() (*GlobalMarketResponse, error) {
|
||||
r := c.buildRequest(kCryptoAPIGlobal)
|
||||
v := &GlobalMarketResponse{}
|
||||
err := c.fetch(r, v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// Middleware is a middleware that adds a new key to the context
|
||||
func Middleware() echo.MiddlewareFunc {
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
f := fetch.NewClient()
|
||||
return func(c echo.Context) error {
|
||||
ctx := &Context{
|
||||
Context: c,
|
||||
client: f,
|
||||
}
|
||||
return next(ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unwrap unwraps the session context
|
||||
func Unwrap(c echo.Context) (*Context, error) {
|
||||
cc := c.(*Context)
|
||||
if cc == nil {
|
||||
return nil, errors.New("failed to unwrap session context")
|
||||
}
|
||||
return cc, nil
|
||||
}
|
||||
98
middleware/marketapi/types.go
Normal file
98
middleware/marketapi/types.go
Normal file
@@ -0,0 +1,98 @@
|
||||
//go:build js && wasm
|
||||
// +build js,wasm
|
||||
|
||||
package marketapi
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/syumai/workers/cloudflare/fetch"
|
||||
)
|
||||
|
||||
type Response interface {
|
||||
UnmarshalJSON(data []byte) error
|
||||
}
|
||||
|
||||
type ListingsResponse struct {
|
||||
Data []struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Symbol string `json:"symbol"`
|
||||
WebsiteSlug string `json:"website_slug"`
|
||||
} `json:"data"`
|
||||
Metadata struct {
|
||||
Timestamp int `json:"timestamp"`
|
||||
NumCryptocurrencies int `json:"num_cryptocurrencies"`
|
||||
Error any `json:"error"`
|
||||
} `json:"metadata"`
|
||||
}
|
||||
|
||||
func (r *ListingsResponse) UnmarshalJSON(data []byte) error {
|
||||
return json.Unmarshal(data, r)
|
||||
}
|
||||
|
||||
type TickersResponse struct {
|
||||
Data []struct {
|
||||
Symbol string `json:"symbol"`
|
||||
Price struct {
|
||||
USD float64 `json:"USD"`
|
||||
} `json:"price"`
|
||||
} `json:"data"`
|
||||
Metadata struct {
|
||||
Timestamp int `json:"timestamp"`
|
||||
Error any `json:"error"`
|
||||
} `json:"metadata"`
|
||||
}
|
||||
|
||||
func (r *TickersResponse) UnmarshalJSON(data []byte) error {
|
||||
return json.Unmarshal(data, r)
|
||||
}
|
||||
|
||||
type GlobalMarketResponse struct {
|
||||
Data []struct {
|
||||
Symbol string `json:"symbol"`
|
||||
Price struct {
|
||||
USD float64 `json:"USD"`
|
||||
} `json:"price"`
|
||||
} `json:"data"`
|
||||
Metadata struct {
|
||||
Timestamp int `json:"timestamp"`
|
||||
Error any `json:"error"`
|
||||
} `json:"metadata"`
|
||||
}
|
||||
|
||||
func (r *GlobalMarketResponse) UnmarshalJSON(data []byte) error {
|
||||
return json.Unmarshal(data, r)
|
||||
}
|
||||
|
||||
func (c *Context) buildRequest(url string) *fetch.Request {
|
||||
r, err := fetch.NewRequest(c.Request().Context(), http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return nil
|
||||
}
|
||||
r.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/111.0")
|
||||
return r
|
||||
}
|
||||
|
||||
func (c *Context) fetch(r *fetch.Request, v Response) error {
|
||||
resp, err := c.client.Do(r, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("request failed: %w", err)
|
||||
}
|
||||
defer resp.Body.Close() // Ensure body is always closed
|
||||
|
||||
// Check for non-200 status codes
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
// Directly decode JSON into the response struct
|
||||
if err := json.NewDecoder(resp.Body).Decode(v); err != nil {
|
||||
return fmt.Errorf("failed to decode response: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -6,7 +6,7 @@ package session
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/segmentio/ksuid"
|
||||
"github.com/sonr-io/motr/pkg/cookies"
|
||||
"github.com/sonr-io/motr/middleware/cookies"
|
||||
)
|
||||
|
||||
// Context is a session context
|
||||
42
middleware/sonrapi/middleware.go
Normal file
42
middleware/sonrapi/middleware.go
Normal file
@@ -0,0 +1,42 @@
|
||||
//go:build js && wasm
|
||||
// +build js,wasm
|
||||
|
||||
package sonrapi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
const (
|
||||
kCryptoAPIURL = "https://api.alternative.me"
|
||||
kCryptoAPIListings = "/v2/listings"
|
||||
kCryptoAPITickers = "/v2/ticker"
|
||||
kCryptoAPIGlobal = "/v2/global"
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
echo.Context
|
||||
}
|
||||
|
||||
// Middleware is a middleware that adds a new key to the context
|
||||
func Middleware() echo.MiddlewareFunc {
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
ctx := &Context{
|
||||
Context: c,
|
||||
}
|
||||
return next(ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unwrap unwraps the session context
|
||||
func Unwrap(c echo.Context) (*Context, error) {
|
||||
cc := c.(*Context)
|
||||
if cc == nil {
|
||||
return nil, errors.New("failed to unwrap session context")
|
||||
}
|
||||
return cc, nil
|
||||
}
|
||||
1
middleware/webauthn/assertion.go
Normal file
1
middleware/webauthn/assertion.go
Normal file
@@ -0,0 +1 @@
|
||||
package webauthn
|
||||
9
middleware/webauthn/attestation.go
Normal file
9
middleware/webauthn/attestation.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package webauthn
|
||||
|
||||
type LoginOptions struct {
|
||||
Account string
|
||||
Handle string
|
||||
HelpText string
|
||||
Label string
|
||||
Challenge string
|
||||
}
|
||||
35
middleware/webauthn/middleware.go
Normal file
35
middleware/webauthn/middleware.go
Normal file
@@ -0,0 +1,35 @@
|
||||
//go:build js && wasm
|
||||
// +build js,wasm
|
||||
|
||||
package webauthn
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
echo.Context
|
||||
}
|
||||
|
||||
// Middleware is a middleware that adds a new key to the context
|
||||
func Middleware() echo.MiddlewareFunc {
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
ctx := &Context{
|
||||
Context: c,
|
||||
}
|
||||
return next(ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unwrap unwraps the session context
|
||||
func Unwrap(c echo.Context) (*Context, error) {
|
||||
cc := c.(*Context)
|
||||
if cc == nil {
|
||||
return nil, errors.New("failed to unwrap session context")
|
||||
}
|
||||
return cc, nil
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package webauth
|
||||
package webauthn
|
||||
|
||||
import models "github.com/sonr-io/motr/internal/sink/users"
|
||||
import models "github.com/sonr-io/motr/internal/db/users"
|
||||
|
||||
// Define the credential structure matching our frontend data
|
||||
type CredentialDescriptor struct {
|
||||
Reference in New Issue
Block a user