From 58f6c48e5786ab97027c1c4ba2ae8a5554035408 Mon Sep 17 00:00:00 2001 From: Rhys Bartels-Waller Date: Tue, 12 Jul 2022 16:11:25 +1000 Subject: [PATCH] feat: support Plutus data - adds `Datum` and `RedeemerDatum` views and GraphQL types --- .../hasura/project/metadata/tables.yaml | 156 +++++++++++++----- .../migrations/1589369664961_init/down.sql | 2 + .../migrations/1589369664961_init/up.sql | 30 +++- packages/api-cardano-db-hasura/schema.graphql | 19 +++ .../redeemers/redeemers.graphql | 8 + .../utxos/utxoSetForAddress.graphql | 8 + .../getAnyUtxoAddress.graphql | 8 +- .../getFirstUtxoWithPlutus.graphql | 32 ++++ .../test/redeemers.query.test.ts | 5 + .../test/utxos.query.test.ts | 18 ++ 10 files changed, 244 insertions(+), 42 deletions(-) create mode 100644 packages/api-cardano-db-hasura/test/graphql_operations/getFirstUtxoWithPlutus.graphql diff --git a/packages/api-cardano-db-hasura/hasura/project/metadata/tables.yaml b/packages/api-cardano-db-hasura/hasura/project/metadata/tables.yaml index 8a54a483..4805cfb0 100644 --- a/packages/api-cardano-db-hasura/hasura/project/metadata/tables.yaml +++ b/packages/api-cardano-db-hasura/hasura/project/metadata/tables.yaml @@ -290,6 +290,26 @@ filter: {} limit: 2500 allow_aggregations: true +- table: + schema: public + name: Datum + object_relationships: + - name: firstIncludedIn + using: + manual_configuration: + remote_table: + schema: public + name: Transaction + column_mapping: + tx_id: id + select_permissions: + - role: cardano-graphql + permission: + columns: + - bytes + - hash + - value + filter: {} - table: schema: public name: Delegation @@ -388,6 +408,44 @@ filter: {} limit: 2500 allow_aggregations: true +- table: + schema: public + name: ProtocolParams + select_permissions: + - role: cardano-graphql + permission: + columns: + - a0 + - coinsPerUtxoByte + - collateralPercent + - costModels + - decentralisationParam + - eMax + - epoch_no + - extraEntropy + - keyDeposit + - maxBlockBodySize + - maxBlockExMem + - maxBlockExSteps + - maxBlockHeaderSize + - maxCollateralInputs + - maxTxExMem + - maxTxExSteps + - maxTxSize + - maxValSize + - minFeeA + - minFeeB + - minPoolCost + - minUTxOValue + - nOpt + - poolDeposit + - priceMem + - priceStep + - protocolVersion + - rho + - tau + filter: {} + limit: 2500 - table: schema: public name: Redeemer @@ -397,6 +455,14 @@ select: redeemers custom_column_names: {} object_relationships: + - name: datum + using: + manual_configuration: + remote_table: + schema: public + name: RedeemerDatum + column_mapping: + redeemer_datum_id: id - name: transaction using: manual_configuration: @@ -418,6 +484,26 @@ filter: {} limit: 2500 allow_aggregations: true +- table: + schema: public + name: RedeemerDatum + object_relationships: + - name: firstIncludedIn + using: + manual_configuration: + remote_table: + schema: public + name: Transaction + column_mapping: + tx_id: id + select_permissions: + - role: cardano-graphql + permission: + columns: + - bytes + - hash + - value + filter: {} - table: schema: public name: Reward @@ -488,44 +574,6 @@ filter: {} limit: 2500 allow_aggregations: true -- table: - schema: public - name: ProtocolParams - select_permissions: - - role: cardano-graphql - permission: - columns: - - a0 - - coinsPerUtxoByte - - collateralPercent - - costModels - - decentralisationParam - - eMax - - epoch_no - - extraEntropy - - keyDeposit - - maxBlockBodySize - - maxBlockExMem - - maxBlockExSteps - - maxBlockHeaderSize - - maxCollateralInputs - - maxTxExMem - - maxTxExSteps - - maxTxSize - - maxValSize - - minFeeA - - minFeeB - - minPoolCost - - minUTxOValue - - nOpt - - poolDeposit - - priceMem - - priceStep - - protocolVersion - - rho - - tau - filter: {} - limit: 2500 - table: schema: public name: SlotLeader @@ -971,6 +1019,22 @@ schema: public name: TransactionOutput object_relationships: + - name: datum + using: + manual_configuration: + remote_table: + schema: public + name: Datum + column_mapping: + inline_datum_id: id + - name: script + using: + manual_configuration: + remote_table: + schema: public + name: Script + column_mapping: + reference_script_id: id - name: transaction using: manual_configuration: @@ -1009,6 +1073,22 @@ select: utxos custom_column_names: {} object_relationships: + - name: datum + using: + manual_configuration: + remote_table: + schema: public + name: Datum + column_mapping: + inline_datum_id: id + - name: script + using: + manual_configuration: + remote_table: + schema: public + name: Script + column_mapping: + reference_script_id: id - name: transaction using: manual_configuration: diff --git a/packages/api-cardano-db-hasura/hasura/project/migrations/1589369664961_init/down.sql b/packages/api-cardano-db-hasura/hasura/project/migrations/1589369664961_init/down.sql index c0d9ee99..e84139e7 100644 --- a/packages/api-cardano-db-hasura/hasura/project/migrations/1589369664961_init/down.sql +++ b/packages/api-cardano-db-hasura/hasura/project/migrations/1589369664961_init/down.sql @@ -4,10 +4,12 @@ DROP VIEW IF EXISTS "Block", "Cardano", "Collateral", + "Datum", "Delegation", "Epoch", "ProtocolParams", "Redeemer", + "RedeemerDatum", "Reward", "Script", "SlotLeader", diff --git a/packages/api-cardano-db-hasura/hasura/project/migrations/1589369664961_init/up.sql b/packages/api-cardano-db-hasura/hasura/project/migrations/1589369664961_init/up.sql index b3ef6f81..e756493b 100644 --- a/packages/api-cardano-db-hasura/hasura/project/migrations/1589369664961_init/up.sql +++ b/packages/api-cardano-db-hasura/hasura/project/migrations/1589369664961_init/up.sql @@ -99,6 +99,24 @@ SELECT FROM epoch LEFT JOIN epoch_param on epoch.no = epoch_param.epoch_no; +CREATE OR REPLACE VIEW "Datum" AS +SELECT + bytes, + hash, + id, + tx_id, + value +FROM datum; + +CREATE OR REPLACE VIEW "RedeemerDatum" AS +SELECT + bytes, + hash, + id, + tx_id, + value +FROM redeemer_data; + CREATE OR REPLACE VIEW "ProtocolParams" AS SELECT epoch_param.influence AS "a0", @@ -143,7 +161,8 @@ SELECT redeemer.script_hash AS "scriptHash", redeemer.tx_id AS "txId", redeemer.unit_mem AS "unitMem", - redeemer.unit_steps AS "unitSteps" + redeemer.unit_steps AS "unitSteps", + redeemer.redeemer_data_id AS "redeemer_datum_id" FROM redeemer; CREATE OR REPLACE VIEW "Reward" AS @@ -160,6 +179,7 @@ JOIN stake_address on reward.addr_id = stake_address.id; CREATE OR REPLACE VIEW "Script" AS SELECT script.hash AS "hash", + script.id AS "id", script.serialised_size AS "serialisedSize", script.type AS "type", script.tx_id AS "txId" @@ -317,7 +337,9 @@ SELECT value, tx.hash AS "txHash", tx_out.id, - index + index, + tx_out.inline_datum_id AS "inline_datum_id", + tx_out.reference_script_id AS "reference_script_id" FROM tx JOIN tx_out ON tx.id = tx_out.tx_id; @@ -328,7 +350,9 @@ CREATE OR REPLACE VIEW "Utxo" AS SELECT value, tx.hash AS "txHash", tx_out.id, - index + index, + tx_out.inline_datum_id AS "inline_datum_id", + tx_out.reference_script_id AS "reference_script_id" FROM tx JOIN tx_out ON tx.id = tx_out.tx_id diff --git a/packages/api-cardano-db-hasura/schema.graphql b/packages/api-cardano-db-hasura/schema.graphql index 33b319c8..69188c3d 100644 --- a/packages/api-cardano-db-hasura/schema.graphql +++ b/packages/api-cardano-db-hasura/schema.graphql @@ -467,6 +467,18 @@ type CardanoDbMeta { syncPercentage: Percentage! } +type Datum { + bytes: Hex! + hash: Hash32Hex! + firstIncludedIn: Transaction! + value: JSONObject! +} + +input Datum_bool_exp { + firstIncludedIn: Transaction_bool_exp + hash: Hex_comparison_exp +} + type Delegation { address: StakeAddress! redeemer: Redeemer @@ -522,6 +534,7 @@ type PaymentAddressSummary { } type Redeemer { + datum: Datum fee: BigInt index: Int! purpose: String! # Todo: Make scalar @@ -571,6 +584,7 @@ input Redeemer_bool_exp { _and: [Redeemer_bool_exp] _not: Redeemer_bool_exp _or: [Redeemer_bool_exp] + datum: Datum_bool_exp fee: BigInt_comparison_exp index: Int_comparison_exp purpose: text_comparison_exp @@ -1364,7 +1378,9 @@ input TransactionMetadata_bool_exp { type TransactionOutput { address: String! addressHasScript: Boolean! + datum: Datum index: Int! + script: Script transaction: Transaction! txHash: Hash32Hex! tokens: [Token!]! @@ -1379,6 +1395,7 @@ enum TransactionOutput_distinct_on { input TransactionOutput_order_by { address: order_by addressHasScript: order_by + datum: Transaction_order_by index: order_by txHash: order_by value: order_by @@ -1390,7 +1407,9 @@ input TransactionOutput_bool_exp { _or: [TransactionOutput_bool_exp] address: text_comparison_exp addressHasScript: Boolean_comparison_exp + datum: Datum_bool_exp index: Int_comparison_exp + script: Script_bool_exp tokens: Token_bool_exp transaction: Transaction_bool_exp value: text_comparison_exp diff --git a/packages/api-cardano-db-hasura/src/example_queries/redeemers/redeemers.graphql b/packages/api-cardano-db-hasura/src/example_queries/redeemers/redeemers.graphql index ea336f64..50612ca1 100644 --- a/packages/api-cardano-db-hasura/src/example_queries/redeemers/redeemers.graphql +++ b/packages/api-cardano-db-hasura/src/example_queries/redeemers/redeemers.graphql @@ -4,6 +4,14 @@ query redeemers ( redeemers( limit: $limit ) { + datum { + bytes + hash + firstIncludedIn { + hash + } + value + } fee index purpose diff --git a/packages/api-cardano-db-hasura/src/example_queries/utxos/utxoSetForAddress.graphql b/packages/api-cardano-db-hasura/src/example_queries/utxos/utxoSetForAddress.graphql index 3b00026c..e251a30a 100644 --- a/packages/api-cardano-db-hasura/src/example_queries/utxos/utxoSetForAddress.graphql +++ b/packages/api-cardano-db-hasura/src/example_queries/utxos/utxoSetForAddress.graphql @@ -6,6 +6,14 @@ query utxoSetForAddress ( where: { address: { _eq: $address }} ) { address + datum { + bytes + hash + firstIncludedIn { + hash + } + value + } transaction { block { number diff --git a/packages/api-cardano-db-hasura/test/graphql_operations/getAnyUtxoAddress.graphql b/packages/api-cardano-db-hasura/test/graphql_operations/getAnyUtxoAddress.graphql index c6cfc322..4836f7a1 100644 --- a/packages/api-cardano-db-hasura/test/graphql_operations/getAnyUtxoAddress.graphql +++ b/packages/api-cardano-db-hasura/test/graphql_operations/getAnyUtxoAddress.graphql @@ -1,7 +1,13 @@ query getAnyUtxoAddress ( $qty: Int! ){ - utxos (limit: $qty, where: { transaction: { block: { number: { _is_null: false }}}}) { + utxos ( + limit: $qty, + where: { + _and: { + transaction: { block: { number: { _is_null: false }}}, + datum: { firstIncludedIn: { block: { number: { _is_null: false }}}} + }}) { address transaction { block { diff --git a/packages/api-cardano-db-hasura/test/graphql_operations/getFirstUtxoWithPlutus.graphql b/packages/api-cardano-db-hasura/test/graphql_operations/getFirstUtxoWithPlutus.graphql new file mode 100644 index 00000000..eafc4610 --- /dev/null +++ b/packages/api-cardano-db-hasura/test/graphql_operations/getFirstUtxoWithPlutus.graphql @@ -0,0 +1,32 @@ +query getFirstUtxoWithPlutus { + utxos ( + limit: 1, + where: { + _and: { + script: { transaction: { block: { number: { _is_null: false }}}}, + datum: { firstIncludedIn: { block: { number: { _is_null: false }}}} + } + }) { + address + datum { + bytes + firstIncludedIn { + hash + } + hash + } + script { + hash + serialisedSize + transaction { + hash + } + type + } + transaction { + block { + number + } + } + } +} \ No newline at end of file diff --git a/packages/api-cardano-db-hasura/test/redeemers.query.test.ts b/packages/api-cardano-db-hasura/test/redeemers.query.test.ts index 1046fcb3..87c314a7 100644 --- a/packages/api-cardano-db-hasura/test/redeemers.query.test.ts +++ b/packages/api-cardano-db-hasura/test/redeemers.query.test.ts @@ -22,6 +22,11 @@ describe('redeemers', () => { limit: 1 } }) + expect(result.data.redeemers[0].datum).not.toBeNull() + expect(result.data.redeemers[0].datum.bytes).not.toBeNull() + expect(result.data.redeemers[0].datum.hash).not.toBeNull() + expect(result.data.redeemers[0].datum.firstIncludedIn.hash).not.toBeNull() + expect(result.data.redeemers[0].datum.value).not.toBeNull() expect(result.data.redeemers[0].fee).not.toBeNull() expect(result.data.redeemers[0].index).not.toBeNull() expect(result.data.redeemers[0].purpose).not.toBeNull() diff --git a/packages/api-cardano-db-hasura/test/utxos.query.test.ts b/packages/api-cardano-db-hasura/test/utxos.query.test.ts index fe761dcb..607434bb 100644 --- a/packages/api-cardano-db-hasura/test/utxos.query.test.ts +++ b/packages/api-cardano-db-hasura/test/utxos.query.test.ts @@ -54,4 +54,22 @@ describe('utxos', () => { }) expect(result.data.utxos_aggregate.aggregate.count).toBeDefined() }) + + it('Includes Plutus script and datum if present', async () => { + const result = await client.query({ + query: await loadTestOperationDocument('getFirstUtxoWithPlutus') + }) + const datum = result.data.utxos[0].datum + const script = result.data.utxos[0].script + expect(datum.hash).toBeDefined() + expect(datum).not.toBeNull() + expect(datum.bytes).not.toBeNull() + expect(datum.hash).not.toBeNull() + expect(datum.firstIncludedIn.hash).not.toBeNull() + expect(datum.value).not.toBeNull() + expect(script.hash).toBeDefined() + expect(script.serialisedSize).toBeDefined() + expect(script.transaction.hash).toBeDefined() + expect(script.type).toBeDefined() + }) })