import { describe, it, expect } from 'vitest'; import { jsonToGraphQLQuery, EnumType, VariableType, } from 'json-to-graphql-query'; describe('should convert json formated queries to GraphQL Schema Definition Language(SDL)', () => { it('subscription query', () => { const expectedQuery = `subscription MonitorSyncTips ( $chainFilter: String = "bchn-mainnet" ) { node ( where: { name: { _like: $chainFilter } } ) { name user_agent latest_tip: accepted_blocks( limit: 1, order_by: { block_internal_id: desc } ) { accepted_at block { hash height } } } }`; const monitorSyncTipsSubscriptionQuery = { subscription: { __name: 'MonitorSyncTips', __variables: { chainFilter: 'String = "bchn-mainnet"', // Default to 'bchn-mainnet' }, node: { __args: { where: { name: { _like: new VariableType('chainFilter'), }, }, }, name: true, user_agent: true, latest_tip: { __aliasFor: 'accepted_blocks', __args: { limit: 1, order_by: { block_internal_id: new EnumType('desc') }, }, accepted_at: true, block: { hash: true, height: true, }, }, }, }, }; expect( normalizeString(jsonToGraphQLQuery(monitorSyncTipsSubscriptionQuery)), ).toEqual(normalizeString(expectedQuery)); }); it('request query', () => { const expectedQuery = `query GetJonathan100CashAccount { search_output_prefix( args: { locking_bytecode_prefix_hex: "6a0401010101084a6f6e617468616e" }, where: { transaction: { block_inclusions: { block: { height: { _eq: 563720 } } } } } ) { transaction { hash data_carrier_outputs { locking_bytecode output_index } block_inclusions { block { hash height } } } } }`; const getJonathan100CashAccountRequestQuery = { query: { __name: 'GetJonathan100CashAccount', search_output_prefix: { __args: { args: { locking_bytecode_prefix_hex: '6a0401010101084a6f6e617468616e', }, where: { transaction: { block_inclusions: { block: { height: { _eq: 563720, }, }, }, }, }, }, transaction: { hash: true, data_carrier_outputs: { locking_bytecode: true, output_index: true, }, block_inclusions: { block: { hash: true, height: true, }, }, }, }, }, }; expect( normalizeString( jsonToGraphQLQuery(getJonathan100CashAccountRequestQuery), ), ).toEqual(normalizeString(expectedQuery)); }); it('fetch unspent transaction outputs for locking bytecode hex query', () => { const expectedQuery = `query SearchOutputsByLockingBytecode( $chainFilter: String = "bchn-mainnet", $lockingBytecodeHexObject: String ) { search_output( args: { locking_bytecode_hex: $lockingBytecodeHexObject }, where: { _not: { spent_by: {} }, transaction: { block_inclusions: { block: { accepted_by: { node: { name: { _like: $chainFilter } } } } } } } ) { locking_bytecode output_index transaction_hash value_satoshis token_category fungible_token_amount nonfungible_token_capability nonfungible_token_commitment transaction { block_inclusions { block { height } } } spent_by { input_index } } }`; const searchOutputsByLockingBytecodeQuery = { query: { __name: 'SearchOutputsByLockingBytecode', __variables: { chainFilter: 'String = "bchn-mainnet"', lockingBytecodeHexObject: 'String', }, search_output: { __args: { args: { locking_bytecode_hex: new VariableType( 'lockingBytecodeHexObject', ), }, where: { _not: { spent_by: {} }, transaction: { block_inclusions: { block: { accepted_by: { node: { name: { _like: new VariableType('chainFilter'), }, }, }, }, }, }, }, }, locking_bytecode: true, output_index: true, transaction_hash: true, value_satoshis: true, token_category: true, fungible_token_amount: true, nonfungible_token_capability: true, nonfungible_token_commitment: true, transaction: { block_inclusions: { block: { height: true, }, }, }, spent_by: { input_index: true, }, }, }, }; expect( normalizeString(jsonToGraphQLQuery(searchOutputsByLockingBytecodeQuery)), ).toEqual(normalizeString(expectedQuery)); }); it('Get Transaction Encoded Hex query', () => { const expectedQuery = `query GetTransactionHex($chainFilter: String = "bchn-mainnet", $txHash: String) { transaction(where: { hash: { _eq: $txHash }, block_inclusions: { block:{ accepted_by:{ node: { name: { _like: $chainFilter } } } } } }) { encoded_hex } }`; const getTransactionHex = { query: { __name: 'GetTransactionHex', __variables: { chainFilter: 'String = "bchn-mainnet"', txHash: 'String', }, transaction: { __args: { where: { hash: { _eq: new VariableType('txHash') }, block_inclusions: { block: { accepted_by: { node: { name: { _like: new VariableType('chainFilter'), }, }, }, }, }, }, }, encoded_hex: true, }, }, }; expect(normalizeString(jsonToGraphQLQuery(getTransactionHex))).toEqual( normalizeString(expectedQuery), ); }); it('Get Block Header Hex query', () => { const expectedQuery = `query GetBlockHeaderHex($chainFilter: String = "bchn-mainnet", $blockHeight: bigint) { block(where: { height: { _eq: $blockHeight }, accepted_by: { block:{ accepted_by:{ node: { name: { _like: $chainFilter } } } } } }) { header } }`; const getBlockHeaderHex = { query: { __name: 'GetBlockHeaderHex', __variables: { chainFilter: 'String = "bchn-mainnet"', blockHeight: 'bigint', }, block: { __args: { where: { height: { _eq: new VariableType('blockHeight') }, accepted_by: { block: { accepted_by: { node: { name: { _like: new VariableType('chainFilter'), }, }, }, }, }, }, }, header: true, }, }, }; expect(normalizeString(jsonToGraphQLQuery(getBlockHeaderHex))).toEqual( normalizeString(expectedQuery), ); }); it('Monitor For Payments subscription query', () => { const expectedQuery = `subscription MonitorForPayments( $lockscriptHexObject: _text ) { search_output( args: { locking_bytecode_hex: $lockscriptHexObject }, where:{ transaction: { _not: {block_inclusions: {}} } } ) { locking_bytecode transaction_hash value_satoshis transaction { node_validations { validated_at } } } }`; const monitorForPayments = { subscription: { __name: 'MonitorForPayments', __variables: { lockscriptHexObject: '_text', }, search_output: { __args: { args: { locking_bytecode_hex: new VariableType('lockscriptHexObject'), }, where: { transaction: { _not: { block_inclusions: {} }, }, }, }, locking_bytecode: true, transaction_hash: true, value_satoshis: true, transaction: { node_validations: { validated_at: true, }, }, }, }, }; expect(normalizeString(jsonToGraphQLQuery(monitorForPayments))).toEqual( normalizeString(expectedQuery), ); }); it('Monitor Transaction Hash subscription query', () => { const expectedQuery = `subscription MonitorTransactionHash( $transactionHash: bytea ) { transaction(where:{node_validations:{ transaction:{_not:{block_inclusions:{}}, hash:{_eq: $transactionHash}}}}) { hash node_validations { validated_at } } }`; const monitorTransactionHash = { subscription: { __name: 'MonitorTransactionHash', __variables: { transactionHash: 'bytea', }, transaction: { __args: { where: { node_validations: { transaction: { _not: { block_inclusions: {} }, hash: { _eq: new VariableType('transactionHash') }, }, }, }, }, hash: true, node_validations: { validated_at: true, }, }, }, }; expect(normalizeString(jsonToGraphQLQuery(monitorTransactionHash))).toEqual( normalizeString(expectedQuery), ); }); it('Get Transaction Details query', () => { const expectedQuery = `query GetLockscriptHistory( $lockscriptHex: bytea ) { transaction(where: { outputs: { locking_bytecode: { _eq: $lockscriptHex } }, inputs:{ outpoint:{ locking_bytecode: { _eq: $lockscriptHex } } } } ) { hash is_coinbase block_inclusions { block { height } } } }`; const getLockscriptHistory = { query: { __name: 'GetLockscriptHistory', __variables: { lockscriptHex: 'bytea', }, transaction: { __args: { where: { outputs: { locking_bytecode: { _eq: new VariableType('lockscriptHex') }, }, inputs: { outpoint: { locking_bytecode: { _eq: new VariableType('lockscriptHex') }, }, }, }, }, hash: true, is_coinbase: true, block_inclusions: { block: { height: true, }, }, }, }, }; expect(normalizeString(jsonToGraphQLQuery(getLockscriptHistory))).toEqual( normalizeString(expectedQuery), ); }); it('Send Raw Transaction Mutation query', () => { const expectedQuery = `mutation SendRawTransaction( $rawTransactionHex: String!, $nodeInternalId: bigint! ) { send_transaction( request: { node_internal_id: $nodeInternalId, encoded_hex: $rawTransactionHex } ) { transaction_hash validation_error_message validation_success transmission_error_message transmission_success } }`; const sendRawTransactionMutation = { mutation: { __name: 'SendRawTransaction', __variables: { rawTransactionHex: 'String!', nodeInternalId: 'bigint!', }, send_transaction: { __args: { request: { node_internal_id: new VariableType('nodeInternalId'), encoded_hex: new VariableType('rawTransactionHex'), }, }, transaction_hash: true, validation_error_message: true, validation_success: true, transmission_error_message: true, transmission_success: true, }, }, }; expect( normalizeString(jsonToGraphQLQuery(sendRawTransactionMutation)), ).toEqual(normalizeString(expectedQuery)); }); }); function normalizeString(str: string): string { // Removes all whitespace (spaces, line breaks, tabs) return str.replace(/\s+/g, ''); }