Skip to content

Repository files navigation

pg_cryptocurrency

pg_cryptocurrency provides PostgreSQL-native types for blockchain networks, asset identities, exact decimal amounts, raw token units, validated addresses, and EVM-sized unsigned integers. An asset is identified by its network and by whether it is native or contract-backed; its ticker is metadata, not identity.

Build and install

The extension supports PostgreSQL 14–18, Rust 1.96+, and cargo-pgrx 0.19.2.

cargo install cargo-pgrx --version 0.19.2 --locked
cargo pgrx init --pg18=/path/to/pg_config
./install.sh --pg-config /path/to/pg_config
CREATE EXTENSION pg_cryptocurrency;

Core types

SELECT '1.25 BTC'::crypto_amount;
SELECT '0.500000000000000000 ETH'::crypto_amount;
SELECT '1500 USDC@ethereum'::crypto_amount;

SELECT 'ethereum:0x742d35cc6634c0532925a3b844bc9e7595f0beb0'
       ::crypto_address;

SELECT '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
       ::uint256;

The extension ships native metadata for Bitcoin, Ethereum, Solana, TRON, Cardano, Polkadot, Arbitrum, Optimism, Base, Polygon, and Avalanche. Its PostgreSQL token registry is seeded with Ethereum USDC, USDT, and DAI.

SELECT crypto_register_asset(
    symbol   => 'TEST',
    name     => 'Test Token',
    network  => 'ethereum',
    contract => '0x0000000000000000000000000000000000000042',
    decimals => 8
);

Exact units and arithmetic

SELECT crypto_to_units('10 ETH');
-- 10000000000000000000

SELECT crypto_from_units(1000000000000000001::bigint, 'ETH');
-- 1.000000000000000001 ETH

SELECT crypto_normalize_units(123456789, 'USDC@ethereum');
-- 123.456789 v1|token|USDC|ethereum|0xa0b8...|6|erc20|55534420436f696e

SELECT '1 BTC'::crypto_amount + '0.25 BTC';
-- 1.25 BTC

Adding distinct identities fails, including equal tickers on different networks. crypto_amount, crypto_asset, crypto_units, crypto_address, and uint256 all have default B-tree and hash operator classes. sum() and avg() are available for crypto_amount and reject mixed assets.

Use the unambiguous amount accessor names when passing string literals:

SELECT crypto_amount_value('12.5 USDC@ethereum');    -- 12.5
SELECT crypto_amount_asset('12.5 USDC@ethereum');    -- v1|token|USDC|ethereum|...
SELECT crypto_amount_network('12.5 USDC@ethereum');  -- ethereum

The original crypto_amount(value), crypto_asset(value), and crypto_network(value) accessors remain available for already-typed values.

Optional pg_money interoperability

If pg_money is already installed when pg_cryptocurrency is created, the extension adds crypto_to_money(crypto_amount, text, numeric). If it is installed later, run SELECT crypto_enable_pg_money();. Conversion always requires an explicit price and never performs network or HTTP access.

See the SQL API, security model, and binary format.

Development

cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings -W clippy::pedantic
./ci/test-extension.sh "$(cargo pgrx info pg-config 18)"
cargo clippy --manifest-path fuzz/Cargo.toml --all-targets -- \
  -D warnings -W clippy::pedantic

About

An extension for PostgreSQL to work with cryptocurrencies

Topics

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors

Languages