diff --git a/files/grest/rpc/account/account_addresses.sql b/files/grest/rpc/account/account_addresses.sql index 51f9a7b6..5cf301e4 100644 --- a/files/grest/rpc/account/account_addresses.sql +++ b/files/grest/rpc/account/account_addresses.sql @@ -27,13 +27,10 @@ BEGIN txo.address, txo.stake_address_id, txo.id - FROM - tx_out AS txo - LEFT JOIN tx_in ON txo.tx_id = tx_in.tx_out_id - AND txo.index::smallint = tx_in.tx_out_index::smallint + FROM tx_out AS txo WHERE txo.stake_address_id = ANY(sa_id_list) - AND tx_in.tx_out_id IS NULL + AND tx_out.consumed_by_tx_in_id IS NULL ) AS x ) @@ -57,8 +54,7 @@ BEGIN txo.address, txo.stake_address_id, txo.id - FROM - tx_out AS txo + FROM tx_out AS txo WHERE txo.stake_address_id = ANY(sa_id_list) LIMIT (CASE WHEN _first_only IS TRUE THEN 1 ELSE NULL END) diff --git a/files/grest/rpc/account/account_assets.sql b/files/grest/rpc/account/account_assets.sql index 06397515..2c8fd1ed 100644 --- a/files/grest/rpc/account/account_assets.sql +++ b/files/grest/rpc/account/account_assets.sql @@ -29,11 +29,9 @@ BEGIN INNER JOIN tx_out AS txo ON txo.id = mtx.tx_out_id INNER JOIN stake_address AS sa ON sa.id = txo.stake_address_id LEFT JOIN grest.asset_info_cache AS aic ON aic.asset_id = ma.id - LEFT JOIN tx_in ON txo.tx_id = tx_in.tx_out_id - AND txo.index::smallint = tx_in.tx_out_index::smallint WHERE sa.id = ANY(sa_id_list) - AND tx_in.tx_out_id IS NULL + AND tx_out.consumed_by_tx_in_id IS NULL GROUP BY sa.view, ma.policy, ma.name, ma.fingerprint, aic.decimals ) @@ -61,4 +59,4 @@ BEGIN END; $$; -COMMENT ON FUNCTION grest.account_assets IS 'Get the native asset balance of given accounts'; -- noqa: LT01 +COMMENT ON FUNCTION grest.account_assets IS 'Get the native asset balance of given accounts'; -- noqa: LT01 \ No newline at end of file diff --git a/files/grest/rpc/account/account_info.sql b/files/grest/rpc/account/account_info.sql index e2149b5b..213e3aaa 100644 --- a/files/grest/rpc/account/account_info.sql +++ b/files/grest/rpc/account/account_info.sql @@ -109,15 +109,10 @@ BEGIN SELECT tx_out.stake_address_id, COALESCE(SUM(VALUE), 0) AS utxo - FROM - tx_out - LEFT JOIN tx_in ON tx_out.tx_id = tx_in.tx_out_id - AND tx_out.index::smallint = tx_in.tx_out_index::smallint - WHERE - tx_out.stake_address_id = ANY(sa_id_list) - AND tx_in.tx_out_id IS NULL - GROUP BY - tx_out.stake_address_id + FROM tx_out + WHERE tx_out.stake_address_id = ANY(sa_id_list) + AND tx_out.consumed_by_tx_in_id IS NULL + GROUP BY tx_out.stake_address_id ) AS utxo_t ON utxo_t.stake_address_id = status_t.id LEFT JOIN ( SELECT diff --git a/files/grest/rpc/account/account_txs.sql b/files/grest/rpc/account/account_txs.sql new file mode 100644 index 00000000..bcf8c76b --- /dev/null +++ b/files/grest/rpc/account/account_txs.sql @@ -0,0 +1,53 @@ +CREATE OR REPLACE FUNCTION grest.account_txs(_stake_address text, _after_block_height integer DEFAULT 0) +RETURNS TABLE ( + tx_hash text, + epoch_no word31type, + block_height word31type, + block_time integer +) +LANGUAGE plpgsql +AS $$ +DECLARE + _tx_id_min bigint; + _tx_id_list bigint[]; +BEGIN + SELECT INTO _tx_id_min id + FROM tx + WHERE block_id >= (SELECT id FROM block WHERE block_no >= _after_block_height ORDER BY id limit 1) + ORDER BY id limit 1; + + -- all tx_out & tx_in tx ids + SELECT INTO _tx_id_list ARRAY_AGG(tx_id) + FROM ( + SELECT tx_id + FROM tx_out + WHERE stake_address_id = ANY(SELECT id FROM stake_address WHERE view = _stake_address) + AND tx_id >= _tx_id_min + -- + UNION + -- + SELECT tx_in_id AS tx_id + FROM tx_out + LEFT JOIN tx_in ON tx_out.tx_id = tx_in.tx_out_id + AND tx_out.index = tx_in.tx_out_index + WHERE + tx_in.tx_in_id IS NOT NULL + AND tx_out.stake_address_id = ANY(SELECT id FROM stake_address WHERE view = _stake_address) + AND tx_in.tx_in_id >= _tx_id_min + ) AS tmp; + + RETURN QUERY + SELECT + DISTINCT(ENCODE(tx.hash, 'hex')) AS tx_hash, + b.epoch_no, + b.block_no AS block_height, + EXTRACT(EPOCH FROM b.time)::integer AS block_time + FROM public.tx + INNER JOIN public.block AS b ON b.id = tx.block_id + WHERE tx.id = ANY(_tx_id_list) + AND block.block_no >= _after_block_height + ORDER BY block.block_no DESC; +END; +$$; + +COMMENT ON FUNCTION grest.account_txs IS 'Get transactions associated with a given stake address'; -- noqa: LT01 diff --git a/files/grest/rpc/account/account_utxos.sql b/files/grest/rpc/account/account_utxos.sql index 2692104d..2737a375 100644 --- a/files/grest/rpc/account/account_utxos.sql +++ b/files/grest/rpc/account/account_utxos.sql @@ -1,34 +1,82 @@ -CREATE OR REPLACE FUNCTION grest.account_utxos(_stake_address text) +CREATE OR REPLACE FUNCTION grest.account_utxos(_stake_addresses text [], _extended boolean DEFAULT false) RETURNS TABLE ( tx_hash text, tx_index smallint, - address varchar, + address text, value text, + stake_address text, + payment_cred text, + epoch_no word31type, block_height word31type, - block_time integer + block_time integer, + datum_hash text, + inline_datum jsonb, + reference_script jsonb, + asset_list jsonb, + is_spent boolean ) LANGUAGE plpgsql AS $$ +DECLARE + known_addresses varchar[]; BEGIN RETURN QUERY - SELECT - ENCODE(tx.hash,'hex') AS tx_hash, - tx_out.index::smallint AS tx_index, - tx_out.address, - tx_out.value::text AS value, - b.block_no AS block_height, - EXTRACT(EPOCH FROM b.time)::integer AS block_time - FROM - tx_out - LEFT JOIN tx_in ON tx_in.tx_out_id = tx_out.tx_id - AND tx_in.tx_out_index = tx_out.index - INNER JOIN tx ON tx.id = tx_out.tx_id + SELECT + ENCODE(tx.hash, 'hex')::text AS tx_hash, + tx_out.index::smallint, + tx_out.address::text, + tx_out.value::text, + sa.view::text as stake_address, + ENCODE(tx_out.payment_cred, 'hex') AS payment_cred, + b.epoch_no, + b.block_no, + EXTRACT(EPOCH FROM b.time)::integer AS block_time, + ENCODE(tx_out.data_hash, 'hex') AS datum_hash, + (CASE + WHEN _extended = false OR tx_out.inline_datum_id IS NULL THEN NULL + ELSE JSONB_BUILD_OBJECT( + 'bytes', ENCODE(datum.bytes, 'hex'), + 'value', datum.value + ) + END) AS inline_datum, + (CASE + WHEN _extended = false OR tx_out.reference_script_id IS NULL THEN NULL + ELSE JSONB_BUILD_OBJECT( + 'hash', ENCODE(script.hash, 'hex'), + 'bytes', ENCODE(script.bytes, 'hex'), + 'value', script.json, + 'type', script.type::text, + 'size', script.serialised_size + ) + END) AS reference_script, + (CASE + WHEN _extended = false OR ma.policy IS NULL THEN NULL + ELSE JSONB_BUILD_OBJECT( + 'policy_id', ENCODE(ma.policy, 'hex'), + 'asset_name', ENCODE(ma.name, 'hex'), + 'fingerprint', ma.fingerprint, + 'decimals', aic.decimals, + 'quantity', mto.quantity::text + ) + END + ) AS asset_list, + (CASE + WHEN tx_out.consumed_by_tx_in_id IS NULL THEN false + ELSE true + END) AS is_spent + FROM tx_out + INNER JOIN tx ON tx_out.tx_id = tx.id + LEFT JOIN stake_address AS sa ON tx_out.stake_address_id = sa.id LEFT JOIN block AS b ON b.id = tx.block_id - WHERE - tx_in.tx_out_id IS NULL - AND - tx_out.stake_address_id = (SELECT id FROM stake_address WHERE view = _stake_address); + LEFT JOIN ma_tx_out AS mto ON mto.tx_out_id = tx_out.id + LEFT JOIN multi_asset AS ma ON ma.id = mto.ident + LEFT JOIN grest.asset_info_cache AS aic ON aic.asset_id = ma.id + LEFT JOIN datum ON datum.id = tx_out.inline_datum_id + LEFT JOIN script ON script.id = tx_out.reference_script_id + WHERE + tx_out.stake_address_id IN (SELECT sa.id FROM stake_address AS sa WHERE sa.view = ANY(_stake_addresses)) + ; END; $$; -COMMENT ON FUNCTION grest.account_utxos IS 'Get non-empty UTxOs associated with a given stake address'; -- noqa: LT01 +COMMENT ON FUNCTION grest.address_utxos IS 'Get UTxO details for requested addresses'; -- noqa: LT01 \ No newline at end of file diff --git a/files/grest/rpc/address/address_assets.sql b/files/grest/rpc/address/address_assets.sql index 274d0c62..8f25abf7 100644 --- a/files/grest/rpc/address/address_assets.sql +++ b/files/grest/rpc/address/address_assets.sql @@ -16,16 +16,12 @@ BEGIN ma.fingerprint, COALESCE(aic.decimals, 0) AS decimals, SUM(mtx.quantity) AS quantity - FROM - ma_tx_out AS mtx - INNER JOIN multi_asset AS ma ON ma.id = mtx.ident - LEFT JOIN grest.asset_info_cache AS aic ON aic.asset_id = ma.id - INNER JOIN tx_out AS txo ON txo.id = mtx.tx_out_id - LEFT JOIN tx_in ON txo.tx_id = tx_in.tx_out_id - AND txo.index::smallint = tx_in.tx_out_index::smallint - WHERE - txo.address = ANY(_addresses) - AND tx_in.tx_out_id IS NULL + FROM ma_tx_out AS mtx + INNER JOIN multi_asset AS ma ON ma.id = mtx.ident + LEFT JOIN grest.asset_info_cache AS aic ON aic.asset_id = ma.id + INNER JOIN tx_out AS txo ON txo.id = mtx.tx_out_id + WHERE txo.address = ANY(_addresses) + AND tx_out.consumed_by_tx_in_id IS NULL GROUP BY txo.address, ma.policy, ma.name, ma.fingerprint, aic.decimals ) diff --git a/files/grest/rpc/address/address_info.sql b/files/grest/rpc/address/address_info.sql index 2ac829ca..3c4ee367 100644 --- a/files/grest/rpc/address/address_info.sql +++ b/files/grest/rpc/address/address_info.sql @@ -34,10 +34,8 @@ BEGIN tx_out.inline_datum_id, tx_out.reference_script_id FROM tx_out - LEFT JOIN tx_in ON tx_in.tx_out_id = tx_out.tx_id - AND tx_in.tx_out_index = tx_out.index INNER JOIN tx ON tx.id = tx_out.tx_id - WHERE tx_in.tx_out_id IS NULL + WHERE tx_out.consumed_by_tx_in_id IS NULL AND tx_out.address = ANY(_addresses) ) @@ -118,4 +116,4 @@ BEGIN END; $$; -COMMENT ON FUNCTION grest.address_info IS 'Get bulk address info - balance, associated stake address (if any) and UTXO set'; -- noqa: LT01 +COMMENT ON FUNCTION grest.address_info IS 'Get bulk address info - balance, associated stake address (if any) and UTXO set'; -- noqa: LT01 \ No newline at end of file diff --git a/files/grest/rpc/address/address_txs.sql b/files/grest/rpc/address/address_txs.sql index 840be398..743ea71f 100644 --- a/files/grest/rpc/address/address_txs.sql +++ b/files/grest/rpc/address/address_txs.sql @@ -19,24 +19,18 @@ BEGIN -- all tx_out & tx_in tx ids SELECT INTO _tx_id_list ARRAY_AGG(tx_id) FROM ( - SELECT - tx_id - FROM - tx_out - WHERE - address = ANY(_addresses) + SELECT tx_id + FROM tx_out + WHERE address = ANY(_addresses) AND tx_id >= _tx_id_min -- UNION -- - SELECT - tx_in_id AS tx_id - FROM - tx_out - LEFT JOIN tx_in ON tx_out.tx_id = tx_in.tx_out_id - AND tx_out.index = tx_in.tx_out_index - WHERE - tx_in.tx_in_id IS NOT NULL + SELECT tx_in_id AS tx_id + FROM tx_out + LEFT JOIN tx_in ON tx_out.tx_id = tx_in.tx_out_id + AND tx_out.index = tx_in.tx_out_index + WHERE tx_in.tx_in_id IS NOT NULL AND tx_out.address = ANY(_addresses) AND tx_in.tx_in_id >= _tx_id_min ) AS tmp; @@ -44,17 +38,14 @@ BEGIN RETURN QUERY SELECT DISTINCT(ENCODE(tx.hash, 'hex')) AS tx_hash, - block.epoch_no, - block.block_no, - EXTRACT(EPOCH FROM block.time)::integer - FROM - public.tx - INNER JOIN public.block ON block.id = tx.block_id - WHERE - tx.id = ANY(_tx_id_list) + b.epoch_no, + b.block_no AS block_height, + EXTRACT(EPOCH FROM b.time)::integer AS block_time + FROM public.tx + INNER JOIN public.block AS b ON b.id = tx.block_id + WHERE tx.id = ANY(_tx_id_list) AND block.block_no >= _after_block_height - ORDER BY - block.block_no DESC; + ORDER BY block.block_no DESC; END; $$; diff --git a/files/grest/rpc/address/address_utxos.sql b/files/grest/rpc/address/address_utxos.sql new file mode 100644 index 00000000..c5b14ade --- /dev/null +++ b/files/grest/rpc/address/address_utxos.sql @@ -0,0 +1,82 @@ +CREATE OR REPLACE FUNCTION grest.address_utxos(_addresses text [], _extended boolean DEFAULT false) +RETURNS TABLE ( + tx_hash text, + tx_index smallint, + address text, + value text, + stake_address text, + payment_cred text, + epoch_no word31type, + block_height word31type, + block_time integer, + datum_hash text, + inline_datum jsonb, + reference_script jsonb, + asset_list jsonb, + is_spent boolean +) +LANGUAGE plpgsql +AS $$ +DECLARE + known_addresses varchar[]; +BEGIN + RETURN QUERY + SELECT + ENCODE(tx.hash, 'hex')::text AS tx_hash, + tx_out.index::smallint, + tx_out.address::text, + tx_out.value::text, + sa.view::text as stake_address, + ENCODE(tx_out.payment_cred, 'hex') AS payment_cred, + b.epoch_no, + b.block_no, + EXTRACT(EPOCH FROM b.time)::integer AS block_time, + ENCODE(tx_out.data_hash, 'hex') AS datum_hash, + (CASE + WHEN _extended = false OR tx_out.inline_datum_id IS NULL THEN NULL + ELSE JSONB_BUILD_OBJECT( + 'bytes', ENCODE(datum.bytes, 'hex'), + 'value', datum.value + ) + END) AS inline_datum, + (CASE + WHEN _extended = false OR tx_out.reference_script_id IS NULL THEN NULL + ELSE JSONB_BUILD_OBJECT( + 'hash', ENCODE(script.hash, 'hex'), + 'bytes', ENCODE(script.bytes, 'hex'), + 'value', script.json, + 'type', script.type::text, + 'size', script.serialised_size + ) + END) AS reference_script, + (CASE + WHEN _extended = false OR ma.policy IS NULL THEN NULL + ELSE JSONB_BUILD_OBJECT( + 'policy_id', ENCODE(ma.policy, 'hex'), + 'asset_name', ENCODE(ma.name, 'hex'), + 'fingerprint', ma.fingerprint, + 'decimals', aic.decimals, + 'quantity', mto.quantity::text + ) + END + ) AS asset_list, + (CASE + WHEN tx_out.consumed_by_tx_in_id IS NULL THEN false + ELSE true + END) AS is_spent + FROM tx_out + INNER JOIN tx ON tx_out.tx_id = tx.id + LEFT JOIN stake_address AS sa ON tx_out.stake_address_id = sa.id + LEFT JOIN block AS b ON b.id = tx.block_id + LEFT JOIN ma_tx_out AS mto ON mto.tx_out_id = tx_out.id + LEFT JOIN multi_asset AS ma ON ma.id = mto.ident + LEFT JOIN grest.asset_info_cache AS aic ON aic.asset_id = ma.id + LEFT JOIN datum ON datum.id = tx_out.inline_datum_id + LEFT JOIN script ON script.id = tx_out.reference_script_id + WHERE + tx_out.address = ANY(_addresses) + ; +END; +$$; + +COMMENT ON FUNCTION grest.address_utxos IS 'Get UTxO details for requested addresses'; -- noqa: LT01 \ No newline at end of file diff --git a/files/grest/rpc/address/credential_txs.sql b/files/grest/rpc/address/credential_txs.sql index d581858a..e3ad6a4e 100644 --- a/files/grest/rpc/address/credential_txs.sql +++ b/files/grest/rpc/address/credential_txs.sql @@ -16,34 +16,29 @@ BEGIN SELECT INTO _payment_cred_bytea ARRAY_AGG(cred_bytea) FROM ( SELECT DECODE(cred_hex, 'hex') AS cred_bytea - FROM - UNNEST(_payment_credentials) AS cred_hex + FROM UNNEST(_payment_credentials) AS cred_hex ) AS tmp; SELECT INTO _tx_id_min id - FROM tx - WHERE block_id >= (SELECT id FROM block WHERE block_no = _after_block_height) - ORDER BY id limit 1; + FROM tx + WHERE block_id >= (SELECT id FROM block WHERE block_no >= _after_block_height ORDER BY id limit 1) + ORDER BY id limit 1; -- all tx_out & tx_in tx ids SELECT INTO _tx_id_list ARRAY_AGG(tx_id) FROM ( SELECT tx_id - FROM - tx_out - WHERE - payment_cred = ANY(_payment_cred_bytea) + FROM tx_out + WHERE payment_cred = ANY(_payment_cred_bytea) AND tx_id >= _tx_id_min -- UNION -- SELECT tx_in_id AS tx_id - FROM - tx_out - LEFT JOIN tx_in ON tx_out.tx_id = tx_in.tx_out_id - AND tx_out.index = tx_in.tx_out_index - WHERE - tx_in.tx_in_id IS NOT NULL + FROM tx_out + LEFT JOIN tx_in ON tx_out.tx_id = tx_in.tx_out_id + AND tx_out.index = tx_in.tx_out_index + WHERE tx_in.tx_in_id IS NOT NULL AND tx_out.payment_cred = ANY(_payment_cred_bytea) AND tx_in.tx_in_id >= _tx_id_min ) AS tmp; @@ -51,18 +46,15 @@ BEGIN RETURN QUERY SELECT DISTINCT(ENCODE(tx.hash, 'hex')) AS tx_hash, - block.epoch_no, - block.block_no, - EXTRACT(EPOCH FROM block.time)::integer - FROM - public.tx - INNER JOIN public.block ON block.id = tx.block_id - WHERE - tx.id = ANY(_tx_id_list) + b.epoch_no, + b.block_no AS block_height, + EXTRACT(EPOCH FROM b.time)::integer AS block_time + FROM public.tx + INNER JOIN public.block AS b ON b.id = tx.block_id + WHERE tx.id = ANY(_tx_id_list) AND block.block_no >= _after_block_height - ORDER BY - block.block_no DESC; + ORDER BY block.block_no DESC; END; $$; -COMMENT ON FUNCTION grest.address_txs IS 'Get the transaction hash list of a payment credentials array, optionally filtering after specified block height (inclusive).'; --noqa: LT01 +COMMENT ON FUNCTION grest.credential_txs IS 'Get the transaction hash list of a payment credentials array, optionally filtering after specified block height (inclusive).'; --noqa: LT01 diff --git a/files/grest/rpc/address/credential_utxos.sql b/files/grest/rpc/address/credential_utxos.sql index 6d9d4677..76f71d86 100644 --- a/files/grest/rpc/address/credential_utxos.sql +++ b/files/grest/rpc/address/credential_utxos.sql @@ -1,34 +1,88 @@ -CREATE OR REPLACE FUNCTION grest.credential_utxos(_payment_credentials text []) +CREATE OR REPLACE FUNCTION grest.credential_utxos(_payment_credentials text [], _extended boolean DEFAULT false) RETURNS TABLE ( tx_hash text, tx_index smallint, - value text + address text, + value text, + stake_address text, + payment_cred text, + epoch_no word31type, + block_height word31type, + block_time integer, + datum_hash text, + inline_datum jsonb, + reference_script jsonb, + asset_list jsonb, + is_spent boolean ) LANGUAGE plpgsql AS $$ DECLARE _payment_cred_bytea bytea[]; - BEGIN SELECT INTO _payment_cred_bytea ARRAY_AGG(cred_bytea) FROM ( - SELECT - DECODE(cred_hex, 'hex') AS cred_bytea - FROM - UNNEST(_payment_credentials) AS cred_hex + SELECT DECODE(cred_hex, 'hex') AS cred_bytea + FROM UNNEST(_payment_credentials) AS cred_hex ) AS tmp; RETURN QUERY SELECT ENCODE(tx.hash, 'hex')::text AS tx_hash, tx_out.index::smallint, - tx_out.value::text AS balance + tx_out.address::text, + tx_out.value::text, + sa.view::text as stake_address, + ENCODE(tx_out.payment_cred, 'hex') AS payment_cred, + b.epoch_no, + b.block_no, + EXTRACT(EPOCH FROM b.time)::integer AS block_time, + ENCODE(tx_out.data_hash, 'hex') AS datum_hash, + (CASE + WHEN _extended = false OR tx_out.inline_datum_id IS NULL THEN NULL + ELSE JSONB_BUILD_OBJECT( + 'bytes', ENCODE(datum.bytes, 'hex'), + 'value', datum.value + ) + END) AS inline_datum, + (CASE + WHEN _extended = false OR tx_out.reference_script_id IS NULL THEN NULL + ELSE JSONB_BUILD_OBJECT( + 'hash', ENCODE(script.hash, 'hex'), + 'bytes', ENCODE(script.bytes, 'hex'), + 'value', script.json, + 'type', script.type::text, + 'size', script.serialised_size + ) + END) AS reference_script, + (CASE + WHEN _extended = false OR ma.policy IS NULL THEN NULL + ELSE JSONB_BUILD_OBJECT( + 'policy_id', ENCODE(ma.policy, 'hex'), + 'asset_name', ENCODE(ma.name, 'hex'), + 'fingerprint', ma.fingerprint, + 'decimals', aic.decimals, + 'quantity', mto.quantity::text + ) + END + ) AS asset_list, + (CASE + WHEN tx_out.consumed_by_tx_in_id IS NULL THEN false + ELSE true + END) AS is_spent FROM tx_out - INNER JOIN tx ON tx_out.tx_id = tx.id - LEFT JOIN tx_in ON tx_out.tx_id = tx_in.tx_out_id - AND tx_out.index = tx_in.tx_out_index + INNER JOIN tx ON tx_out.tx_id = tx.id + LEFT JOIN stake_address AS sa ON tx_out.stake_address_id = sa.id + LEFT JOIN block AS b ON b.id = tx.block_id + LEFT JOIN ma_tx_out AS mto ON mto.tx_out_id = tx_out.id + LEFT JOIN multi_asset AS ma ON ma.id = mto.ident + LEFT JOIN grest.asset_info_cache AS aic ON aic.asset_id = ma.id + LEFT JOIN datum ON datum.id = tx_out.inline_datum_id + LEFT JOIN script ON script.id = tx_out.reference_script_id WHERE - payment_cred = ANY(_payment_cred_bytea) - AND tx_in.tx_out_id IS NULL; + tx_out.payment_cred = ANY(_payment_cred_bytea) + ; END; $$; + +COMMENT ON FUNCTION grest.credential_utxos IS 'Get UTxO details for requested payment credentials'; -- noqa: LT01 \ No newline at end of file diff --git a/files/grest/rpc/assets/asset_addresses.sql b/files/grest/rpc/assets/asset_addresses.sql index 3344d395..8216671c 100644 --- a/files/grest/rpc/assets/asset_addresses.sql +++ b/files/grest/rpc/assets/asset_addresses.sql @@ -24,15 +24,15 @@ DECLARE _asset_id int; BEGIN SELECT DECODE(_asset_policy, 'hex') INTO _asset_policy_decoded; - SELECT DECODE( - CASE WHEN _asset_name IS NULL - THEN '' - ELSE - _asset_name - END, - 'hex' - ) INTO _asset_name_decoded; - SELECT id INTO _asset_id FROM multi_asset AS ma WHERE ma.policy = _asset_policy_decoded AND ma.name = _asset_name_decoded; + SELECT DECODE(CASE + WHEN _asset_name IS NULL THEN '' + ELSE _asset_name + END, 'hex') INTO _asset_name_decoded; + SELECT id INTO _asset_id + FROM multi_asset AS ma + WHERE ma.policy = _asset_policy_decoded + AND ma.name = _asset_name_decoded; + RETURN QUERY SELECT x.address, @@ -42,17 +42,12 @@ BEGIN SELECT txo.address, mto.quantity - FROM - ma_tx_out AS mto - INNER JOIN tx_out AS txo ON txo.id = mto.tx_out_id - LEFT JOIN tx_in ON txo.tx_id = tx_in.tx_out_id - AND txo.index::smallint = tx_in.tx_out_index::smallint - WHERE - mto.ident = _asset_id - AND tx_in.tx_out_id IS NULL + FROM ma_tx_out AS mto + INNER JOIN tx_out AS txo ON txo.id = mto.tx_out_id + WHERE mto.ident = _asset_id + AND tx_out.consumed_by_tx_in_id IS NULL ) AS x - GROUP BY - x.address; + GROUP BY x.address; END; $$; diff --git a/files/grest/rpc/assets/asset_txs.sql b/files/grest/rpc/assets/asset_txs.sql index e34fc924..01d950f2 100644 --- a/files/grest/rpc/assets/asset_txs.sql +++ b/files/grest/rpc/assets/asset_txs.sql @@ -19,14 +19,15 @@ DECLARE BEGIN SELECT DECODE(_asset_policy, 'hex') INTO _asset_policy_decoded; SELECT DECODE( - CASE WHEN _asset_name IS NULL - THEN '' - ELSE - _asset_name + CASE + WHEN _asset_name IS NULL THEN '' + ELSE _asset_name END, 'hex' ) INTO _asset_name_decoded; - SELECT id INTO _asset_id FROM multi_asset AS ma WHERE ma.policy = _asset_policy_decoded AND ma.name = _asset_name_decoded; + SELECT id INTO _asset_id + FROM multi_asset AS ma + WHERE ma.policy = _asset_policy_decoded AND ma.name = _asset_name_decoded; RETURN QUERY SELECT @@ -35,18 +36,17 @@ BEGIN tx_hashes.block_no, EXTRACT(EPOCH FROM tx_hashes.time)::integer FROM ( - SELECT DISTINCT ON (tx.hash) + SELECT DISTINCT ON (tx.hash,txo.index::smallint) tx.hash, block.epoch_no, block.block_no, block.time - FROM - ma_tx_out AS mto - INNER JOIN tx_out AS txo ON txo.id = mto.tx_out_id - INNER JOIN tx ON tx.id = txo.tx_id - INNER JOIN block ON block.id = tx.block_id - LEFT JOIN tx_in AS txi ON txo.tx_id = txi.tx_out_id - AND txo.index::smallint = txi.tx_out_index::smallint + FROM ma_tx_out AS mto + INNER JOIN tx_out AS txo ON txo.id = mto.tx_out_id + INNER JOIN tx ON tx.id = txo.tx_id + INNER JOIN block ON block.id = tx.block_id + LEFT JOIN tx_in AS txi ON txo.tx_id = txi.tx_out_id + AND txo.index::smallint = txi.tx_out_index::smallint WHERE mto.ident = _asset_id AND block.block_no >= _after_block_height diff --git a/files/grest/rpc/assets/asset_utxos.sql b/files/grest/rpc/assets/asset_utxos.sql new file mode 100644 index 00000000..e26c8327 --- /dev/null +++ b/files/grest/rpc/assets/asset_utxos.sql @@ -0,0 +1,95 @@ +CREATE OR REPLACE FUNCTION grest.asset_utxos(_asset_list text [] [], _extended boolean DEFAULT false) +RETURNS TABLE ( + tx_hash text, + tx_index smallint, + address text, + value text, + stake_address text, + payment_cred text, + epoch_no word31type, + block_height word31type, + block_time integer, + datum_hash text, + inline_datum jsonb, + reference_script jsonb, + asset_list jsonb, + is_spent boolean +) +LANGUAGE plpgsql +AS $$ +DECLARE + _asset_id_list bigint[]; +BEGIN + -- find all asset id's based ON nested array input + SELECT INTO _asset_id_list ARRAY_AGG(id) + FROM ( + SELECT DISTINCT mu.id + FROM ( + SELECT + DECODE(al->>0, 'hex') AS policy, + DECODE(al->>1, 'hex') AS name + FROM JSONB_ARRAY_ELEMENTS(TO_JSONB(_asset_list)) AS al + ) AS ald + INNER JOIN multi_asset AS mu ON mu.policy = ald.policy AND mu.name = ald.name + ) AS tmp; + + RETURN QUERY + SELECT + ENCODE(tx.hash, 'hex')::text AS tx_hash, + tx_out.index::smallint, + tx_out.address::text, + tx_out.value::text, + sa.view::text as stake_address, + ENCODE(tx_out.payment_cred, 'hex') AS payment_cred, + b.epoch_no, + b.block_no, + EXTRACT(EPOCH FROM b.time)::integer AS block_time, + ENCODE(tx_out.data_hash, 'hex') AS datum_hash, + (CASE + WHEN _extended = false OR tx_out.inline_datum_id IS NULL THEN NULL + ELSE JSONB_BUILD_OBJECT( + 'bytes', ENCODE(datum.bytes, 'hex'), + 'value', datum.value + ) + END) AS inline_datum, + (CASE + WHEN _extended = false OR tx_out.reference_script_id IS NULL THEN NULL + ELSE JSONB_BUILD_OBJECT( + 'hash', ENCODE(script.hash, 'hex'), + 'bytes', ENCODE(script.bytes, 'hex'), + 'value', script.json, + 'type', script.type::text, + 'size', script.serialised_size + ) + END) AS reference_script, + (CASE + WHEN ma.policy IS NULL THEN NULL + ELSE JSONB_BUILD_OBJECT( + 'policy_id', ENCODE(ma.policy, 'hex'), + 'asset_name', ENCODE(ma.name, 'hex'), + 'fingerprint', ma.fingerprint, + 'decimals', aic.decimals, + 'quantity', mto.quantity::text + ) + END + ) AS asset_list, + (CASE + WHEN tx_out.consumed_by_tx_in_id IS NULL THEN false + ELSE true + END) AS is_spent + FROM tx_out + INNER JOIN tx ON tx_out.tx_id = tx.id + LEFT JOIN stake_address AS sa ON tx_out.stake_address_id = sa.id + LEFT JOIN block AS b ON b.id = tx.block_id + LEFT JOIN ma_tx_out AS mto ON mto.tx_out_id = tx_out.id + LEFT JOIN multi_asset AS ma ON ma.id = mto.ident + LEFT JOIN grest.asset_info_cache AS aic ON aic.asset_id = ma.id + LEFT JOIN datum ON datum.id = tx_out.inline_datum_id + LEFT JOIN script ON script.id = tx_out.reference_script_id + WHERE + mto.ident = ANY(_asset_id_list) + ; +END; +$$; + +COMMENT ON FUNCTION grest.asset_utxos IS 'Get UTxO details for requested assets'; -- noqa: LT01 diff --git a/files/grest/rpc/assets/policy_asset_addresses.sql b/files/grest/rpc/assets/policy_asset_addresses.sql index 478b1527..5287b4a1 100644 --- a/files/grest/rpc/assets/policy_asset_addresses.sql +++ b/files/grest/rpc/assets/policy_asset_addresses.sql @@ -16,8 +16,7 @@ BEGIN SELECT id, ENCODE(name, 'hex') AS asset_name - FROM - multi_asset AS ma + FROM multi_asset AS ma WHERE ma.policy = _asset_policy_decoded ) @@ -31,17 +30,14 @@ BEGIN aa.asset_name, txo.address, mto.quantity - FROM - _all_assets AS aa - INNER JOIN ma_tx_out AS mto ON mto.ident = aa.id - INNER JOIN tx_out AS txo ON txo.id = mto.tx_out_id - LEFT JOIN tx_in ON txo.tx_id = tx_in.tx_out_id - AND txo.index::smallint = tx_in.tx_out_index::smallint - WHERE - tx_in.tx_out_id IS NULL + FROM _all_assets AS aa + INNER JOIN ma_tx_out AS mto ON mto.ident = aa.id + INNER JOIN tx_out AS txo ON txo.id = mto.tx_out_id + WHERE tx_out.consumed_by_tx_in_id IS NULL ) AS x GROUP BY - x.asset_name, x.address; + x.asset_name, + x.address; END; $$; diff --git a/files/grest/rpc/blocks/block_txs.sql b/files/grest/rpc/blocks/block_txs.sql index 8bdeeaf6..daf45adf 100644 --- a/files/grest/rpc/blocks/block_txs.sql +++ b/files/grest/rpc/blocks/block_txs.sql @@ -1,7 +1,10 @@ CREATE OR REPLACE FUNCTION grest.block_txs(_block_hashes text []) RETURNS TABLE ( block_hash text, - tx_hashes text [] + tx_hash text, + epoch_no word31type, + block_height word31type, + block_time integer ) LANGUAGE plpgsql AS $$ @@ -21,13 +24,15 @@ BEGIN RETURN QUERY SELECT - encode(b.hash, 'hex'), - ARRAY_AGG(ENCODE(tx.hash::bytea, 'hex')) - FROM - public.block AS b - INNER JOIN public.tx ON tx.block_id = b.id + ENCODE(b.hash, 'hex'), + ENCODE(tx.hash, 'hex') AS tx_hash, + b.epoch_no, + b.block_no AS block_height, + EXTRACT(EPOCH FROM b.time)::integer AS block_time + FROM public.block AS b + INNER JOIN public.tx ON tx.block_id = b.id WHERE b.id = ANY(_block_ids) - GROUP BY b.hash; + ; END; $$;