mirror of
https://github.com/sonr-io/sonr.git
synced 2026-08-02 17:31:39 +00:00
@@ -0,0 +1,368 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
-- Create the http extension required for making HTTP requests
|
||||
CREATE EXTENSION IF NOT EXISTS http;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS chains (
|
||||
chain_id VARCHAR(100) PRIMARY KEY,
|
||||
name VARCHAR(100),
|
||||
path VARCHAR(100),
|
||||
chain_name VARCHAR(100),
|
||||
network_type VARCHAR(50),
|
||||
pretty_name VARCHAR(200),
|
||||
status VARCHAR(50),
|
||||
bech32_prefix VARCHAR(20),
|
||||
slip44 INTEGER,
|
||||
symbol VARCHAR(20),
|
||||
display VARCHAR(20),
|
||||
denom VARCHAR(50),
|
||||
decimals INTEGER,
|
||||
image VARCHAR(500),
|
||||
website VARCHAR(500),
|
||||
height BIGINT,
|
||||
proxy_status JSONB,
|
||||
keywords TEXT[],
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS chain_apis (
|
||||
id SERIAL PRIMARY KEY,
|
||||
chain_id VARCHAR(100) REFERENCES chains(chain_id) ON DELETE CASCADE,
|
||||
api_type VARCHAR(20), -- 'rest', 'rpc', 'grpc'
|
||||
address VARCHAR(500),
|
||||
provider VARCHAR(200),
|
||||
archive BOOLEAN DEFAULT FALSE,
|
||||
is_best_api BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS chain_explorers (
|
||||
id SERIAL PRIMARY KEY,
|
||||
chain_id VARCHAR(100) REFERENCES chains(chain_id) ON DELETE CASCADE,
|
||||
kind VARCHAR(50),
|
||||
url VARCHAR(500),
|
||||
tx_page VARCHAR(500),
|
||||
account_page VARCHAR(500),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- 4. Create versions table
|
||||
CREATE TABLE IF NOT EXISTS chain_versions (
|
||||
id SERIAL PRIMARY KEY,
|
||||
chain_id VARCHAR(100) REFERENCES chains(chain_id) ON DELETE CASCADE,
|
||||
application_name VARCHAR(100),
|
||||
application_version VARCHAR(50),
|
||||
consensus_name VARCHAR(100),
|
||||
consensus_version VARCHAR(50),
|
||||
cosmos_sdk_version VARCHAR(50),
|
||||
tendermint_version VARCHAR(50),
|
||||
ibc_go_version VARCHAR(50),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- 5. Create assets table
|
||||
CREATE TABLE IF NOT EXISTS chain_assets (
|
||||
id SERIAL PRIMARY KEY,
|
||||
chain_id VARCHAR(100) REFERENCES chains(chain_id) ON DELETE CASCADE,
|
||||
asset_name VARCHAR(100),
|
||||
description VARCHAR(1000),
|
||||
denom_units JSONB,
|
||||
base VARCHAR(100),
|
||||
display VARCHAR(100),
|
||||
symbol VARCHAR(20),
|
||||
logo_uri VARCHAR(500),
|
||||
keywords TEXT[],
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- 6. Create parameters table
|
||||
CREATE TABLE IF NOT EXISTS chain_params (
|
||||
id SERIAL PRIMARY KEY,
|
||||
chain_id VARCHAR(100) REFERENCES chains(chain_id) ON DELETE CASCADE,
|
||||
actual_block_time NUMERIC,
|
||||
actual_blocks_per_year NUMERIC,
|
||||
bonded_ratio NUMERIC,
|
||||
inflation JSONB,
|
||||
staking_apr NUMERIC,
|
||||
unbonding_time INTEGER,
|
||||
max_validators INTEGER,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- 7. Create indexes for better performance
|
||||
CREATE INDEX IF NOT EXISTS idx_chains_status ON chains(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_chains_network_type ON chains(network_type);
|
||||
CREATE INDEX IF NOT EXISTS idx_chain_apis_type ON chain_apis(api_type);
|
||||
CREATE INDEX IF NOT EXISTS idx_chain_apis_chain_id ON chain_apis(chain_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_chain_explorers_chain_id ON chain_explorers(chain_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_chain_versions_chain_id ON chain_versions(chain_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_chain_assets_chain_id ON chain_assets(chain_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_chain_params_chain_id ON chain_params(chain_id);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose StatementBegin
|
||||
-- 8. Main function to fetch and parse Cosmos chain data
|
||||
CREATE OR REPLACE FUNCTION fetch_and_parse_cosmos_chains()
|
||||
RETURNS TABLE(
|
||||
operation VARCHAR,
|
||||
chains_inserted INTEGER,
|
||||
apis_inserted INTEGER,
|
||||
explorers_inserted INTEGER,
|
||||
versions_inserted INTEGER,
|
||||
assets_inserted INTEGER,
|
||||
params_inserted INTEGER,
|
||||
total_processing_time INTERVAL
|
||||
) AS $$
|
||||
DECLARE
|
||||
start_time TIMESTAMP;
|
||||
cosmos_data JSONB;
|
||||
chains_count INTEGER := 0;
|
||||
apis_count INTEGER := 0;
|
||||
explorers_count INTEGER := 0;
|
||||
versions_count INTEGER := 0;
|
||||
assets_count INTEGER := 0;
|
||||
params_count INTEGER := 0;
|
||||
BEGIN
|
||||
start_time := clock_timestamp();
|
||||
|
||||
-- Fetch data from the Cosmos chain directory
|
||||
SELECT content::JSONB INTO cosmos_data
|
||||
FROM http_get('https://chains.cosmos.directory');
|
||||
|
||||
-- Clear existing data (optional - comment out if you want to preserve data)
|
||||
DELETE FROM chain_params;
|
||||
DELETE FROM chain_assets;
|
||||
DELETE FROM chain_versions;
|
||||
DELETE FROM chain_explorers;
|
||||
DELETE FROM chain_apis;
|
||||
DELETE FROM chains;
|
||||
|
||||
-- Insert chains data
|
||||
INSERT INTO chains (
|
||||
chain_id, name, path, chain_name, network_type, pretty_name,
|
||||
status, bech32_prefix, slip44, symbol, display, denom,
|
||||
decimals, image, website, height, proxy_status, keywords
|
||||
)
|
||||
SELECT
|
||||
(chain->>'chain_id')::VARCHAR(100),
|
||||
(chain->>'name')::VARCHAR(100),
|
||||
(chain->>'path')::VARCHAR(100),
|
||||
(chain->>'chain_name')::VARCHAR(100),
|
||||
(chain->>'network_type')::VARCHAR(50),
|
||||
(chain->>'pretty_name')::VARCHAR(200),
|
||||
(chain->>'status')::VARCHAR(50),
|
||||
(chain->>'bech32_prefix')::VARCHAR(20),
|
||||
(chain->>'slip44')::INTEGER,
|
||||
(chain->>'symbol')::VARCHAR(20),
|
||||
(chain->>'display')::VARCHAR(20),
|
||||
(chain->>'denom')::VARCHAR(50),
|
||||
(chain->>'decimals')::INTEGER,
|
||||
(chain->>'image')::VARCHAR(500),
|
||||
(chain->>'website')::VARCHAR(500),
|
||||
(chain->>'height')::BIGINT,
|
||||
chain->'proxy_status',
|
||||
CASE
|
||||
WHEN chain->'keywords' IS NOT NULL
|
||||
THEN ARRAY(SELECT jsonb_array_elements_text(chain->'keywords'))
|
||||
ELSE NULL
|
||||
END
|
||||
FROM JSONB_ARRAY_ELEMENTS(cosmos_data->'chains') AS chain;
|
||||
|
||||
GET DIAGNOSTICS chains_count = ROW_COUNT;
|
||||
|
||||
-- Insert REST API endpoints
|
||||
INSERT INTO chain_apis (chain_id, api_type, address, provider, archive, is_best_api)
|
||||
SELECT
|
||||
(chain->>'chain_id')::VARCHAR(100),
|
||||
'rest'::VARCHAR(20),
|
||||
(api->>'address')::VARCHAR(500),
|
||||
(api->>'provider')::VARCHAR(200),
|
||||
COALESCE((api->>'archive')::BOOLEAN, false),
|
||||
true
|
||||
FROM JSONB_ARRAY_ELEMENTS(cosmos_data->'chains') AS chain,
|
||||
JSONB_ARRAY_ELEMENTS(chain->'best_apis'->'rest') AS api
|
||||
WHERE chain->'best_apis'->'rest' IS NOT NULL;
|
||||
|
||||
-- Insert RPC API endpoints
|
||||
INSERT INTO chain_apis (chain_id, api_type, address, provider, archive, is_best_api)
|
||||
SELECT
|
||||
(chain->>'chain_id')::VARCHAR(100),
|
||||
'rpc'::VARCHAR(20),
|
||||
(api->>'address')::VARCHAR(500),
|
||||
(api->>'provider')::VARCHAR(200),
|
||||
COALESCE((api->>'archive')::BOOLEAN, false),
|
||||
true
|
||||
FROM JSONB_ARRAY_ELEMENTS(cosmos_data->'chains') AS chain,
|
||||
JSONB_ARRAY_ELEMENTS(chain->'best_apis'->'rpc') AS api
|
||||
WHERE chain->'best_apis'->'rpc' IS NOT NULL;
|
||||
|
||||
-- Insert GRPC API endpoints
|
||||
INSERT INTO chain_apis (chain_id, api_type, address, provider, archive, is_best_api)
|
||||
SELECT
|
||||
(chain->>'chain_id')::VARCHAR(100),
|
||||
'grpc'::VARCHAR(20),
|
||||
(api->>'address')::VARCHAR(500),
|
||||
(api->>'provider')::VARCHAR(200),
|
||||
COALESCE((api->>'archive')::BOOLEAN, false),
|
||||
true
|
||||
FROM JSONB_ARRAY_ELEMENTS(cosmos_data->'chains') AS chain,
|
||||
JSONB_ARRAY_ELEMENTS(chain->'best_apis'->'grpc') AS api
|
||||
WHERE chain->'best_apis'->'grpc' IS NOT NULL;
|
||||
|
||||
GET DIAGNOSTICS apis_count = ROW_COUNT;
|
||||
|
||||
-- Insert explorers
|
||||
INSERT INTO chain_explorers (chain_id, kind, url, tx_page, account_page)
|
||||
SELECT
|
||||
(chain->>'chain_id')::VARCHAR(100),
|
||||
(explorer->>'kind')::VARCHAR(50),
|
||||
(explorer->>'url')::VARCHAR(500),
|
||||
(explorer->>'tx_page')::VARCHAR(500),
|
||||
(explorer->>'account_page')::VARCHAR(500)
|
||||
FROM JSONB_ARRAY_ELEMENTS(cosmos_data->'chains') AS chain,
|
||||
JSONB_ARRAY_ELEMENTS(chain->'explorers') AS explorer
|
||||
WHERE chain->'explorers' IS NOT NULL;
|
||||
|
||||
GET DIAGNOSTICS explorers_count = ROW_COUNT;
|
||||
|
||||
-- Insert version information
|
||||
INSERT INTO chain_versions (
|
||||
chain_id, application_name, application_version,
|
||||
consensus_name, consensus_version, cosmos_sdk_version,
|
||||
tendermint_version, ibc_go_version
|
||||
)
|
||||
SELECT
|
||||
(chain->>'chain_id')::VARCHAR(100),
|
||||
(chain->'versions'->>'name')::VARCHAR(100),
|
||||
(chain->'versions'->>'version')::VARCHAR(50),
|
||||
(chain->'versions'->'consensus'->>'name')::VARCHAR(100),
|
||||
(chain->'versions'->'consensus'->>'version')::VARCHAR(50),
|
||||
(chain->'versions'->>'cosmos_sdk_version')::VARCHAR(50),
|
||||
(chain->'versions'->>'tendermint_version')::VARCHAR(50),
|
||||
(chain->'versions'->>'ibc_go_version')::VARCHAR(50)
|
||||
FROM JSONB_ARRAY_ELEMENTS(cosmos_data->'chains') AS chain
|
||||
WHERE chain->'versions' IS NOT NULL;
|
||||
|
||||
GET DIAGNOSTICS versions_count = ROW_COUNT;
|
||||
|
||||
-- Insert assets
|
||||
INSERT INTO chain_assets (
|
||||
chain_id, asset_name, description, denom_units,
|
||||
base, display, symbol, logo_uri, keywords
|
||||
)
|
||||
SELECT
|
||||
(chain->>'chain_id')::VARCHAR(100),
|
||||
(asset->>'name')::VARCHAR(100),
|
||||
(asset->>'description')::VARCHAR(1000),
|
||||
asset->'denom_units',
|
||||
(asset->>'base')::VARCHAR(100),
|
||||
(asset->>'display')::VARCHAR(100),
|
||||
(asset->>'symbol')::VARCHAR(20),
|
||||
(asset->'logo_URIs'->>'png')::VARCHAR(500),
|
||||
CASE
|
||||
WHEN asset->'keywords' IS NOT NULL
|
||||
THEN ARRAY(SELECT jsonb_array_elements_text(asset->'keywords'))
|
||||
ELSE NULL
|
||||
END
|
||||
FROM JSONB_ARRAY_ELEMENTS(cosmos_data->'chains') AS chain,
|
||||
JSONB_ARRAY_ELEMENTS(chain->'assets') AS asset
|
||||
WHERE chain->'assets' IS NOT NULL;
|
||||
|
||||
GET DIAGNOSTICS assets_count = ROW_COUNT;
|
||||
|
||||
-- Insert parameters
|
||||
INSERT INTO chain_params (
|
||||
chain_id, actual_block_time, actual_blocks_per_year,
|
||||
bonded_ratio, inflation, staking_apr, unbonding_time, max_validators
|
||||
)
|
||||
SELECT
|
||||
(chain->>'chain_id')::VARCHAR(100),
|
||||
(chain->'params'->>'actual_block_time')::NUMERIC,
|
||||
(chain->'params'->>'actual_blocks_per_year')::NUMERIC,
|
||||
(chain->'params'->>'bonded_ratio')::NUMERIC,
|
||||
chain->'params'->'inflation',
|
||||
(chain->'params'->>'staking_apr')::NUMERIC,
|
||||
(chain->'params'->>'unbonding_time')::INTEGER,
|
||||
(chain->'params'->>'max_validators')::INTEGER
|
||||
FROM JSONB_ARRAY_ELEMENTS(cosmos_data->'chains') AS chain
|
||||
WHERE chain->'params' IS NOT NULL;
|
||||
|
||||
GET DIAGNOSTICS params_count = ROW_COUNT;
|
||||
|
||||
-- Return summary
|
||||
RETURN QUERY SELECT
|
||||
'SUCCESS'::VARCHAR as operation,
|
||||
chains_count,
|
||||
apis_count,
|
||||
explorers_count,
|
||||
versions_count,
|
||||
assets_count,
|
||||
params_count,
|
||||
clock_timestamp() - start_time as total_processing_time;
|
||||
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
-- Return error information
|
||||
RETURN QUERY SELECT
|
||||
'ERROR'::VARCHAR as operation,
|
||||
0::INTEGER,
|
||||
0::INTEGER,
|
||||
0::INTEGER,
|
||||
0::INTEGER,
|
||||
0::INTEGER,
|
||||
0::INTEGER,
|
||||
clock_timestamp() - start_time as total_processing_time;
|
||||
RAISE;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose StatementBegin
|
||||
-- 9. Convenience function to refresh data
|
||||
CREATE OR REPLACE FUNCTION refresh_cosmos_data()
|
||||
RETURNS VOID AS $$
|
||||
BEGIN
|
||||
PERFORM fetch_and_parse_cosmos_chains();
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose StatementBegin
|
||||
-- 10. Function to get chain summary statistics
|
||||
CREATE OR REPLACE FUNCTION get_cosmos_chain_stats()
|
||||
RETURNS TABLE(
|
||||
total_chains INTEGER,
|
||||
live_chains INTEGER,
|
||||
testnet_chains INTEGER,
|
||||
total_apis INTEGER,
|
||||
total_explorers INTEGER,
|
||||
chains_with_staking_info INTEGER,
|
||||
avg_staking_apr NUMERIC
|
||||
) AS $$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT
|
||||
(SELECT COUNT(*)::INTEGER FROM chains) as total_chains,
|
||||
(SELECT COUNT(*)::INTEGER FROM chains WHERE status = 'live') as live_chains,
|
||||
(SELECT COUNT(*)::INTEGER FROM chains WHERE network_type = 'testnet') as testnet_chains,
|
||||
(SELECT COUNT(*)::INTEGER FROM chain_apis) as total_apis,
|
||||
(SELECT COUNT(*)::INTEGER FROM chain_explorers) as total_explorers,
|
||||
(SELECT COUNT(*)::INTEGER FROM chain_params WHERE staking_apr IS NOT NULL) as chains_with_staking_info,
|
||||
(SELECT AVG(staking_apr) FROM chain_params WHERE staking_apr IS NOT NULL) as avg_staking_apr;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP FUNCTION IF EXISTS get_cosmos_chain_stats();
|
||||
DROP FUNCTION IF EXISTS refresh_cosmos_data();
|
||||
DROP FUNCTION IF EXISTS fetch_and_parse_cosmos_chains();
|
||||
DROP TABLE IF EXISTS chain_params CASCADE;
|
||||
DROP TABLE IF EXISTS chain_assets CASCADE;
|
||||
DROP TABLE IF EXISTS chain_versions CASCADE;
|
||||
DROP TABLE IF EXISTS chain_explorers CASCADE;
|
||||
DROP TABLE IF EXISTS chain_apis CASCADE;
|
||||
DROP TABLE IF EXISTS chains CASCADE;
|
||||
-- +goose StatementEnd
|
||||
Reference in New Issue
Block a user