Skip to content

Commit

Permalink
Merge pull request #118 from input-output-hk/feat/query-stakepools
Browse files Browse the repository at this point in the history
feat: stake pool search
  • Loading branch information
rhyslbw authored Oct 25, 2021
2 parents ba44a6b + 2e0906b commit 1d86393
Show file tree
Hide file tree
Showing 76 changed files with 6,154 additions and 156 deletions.
3 changes: 3 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module.exports = {
2,
"unix"
],
"new-cap": 0,
"no-unused-expressions": 0,
"no-useless-constructor": 0,
"quotes": ["error", "single", { "avoidEscape": true }],
Expand All @@ -31,6 +32,8 @@ module.exports = {
"unicorn/no-null": 0,
"unicorn/no-array-reduce": 0,
"unicorn/prefer-node-protocol": 0,
"unicorn/prefer-module": 0,
"unicorn/no-array-callback-reference": 0, // needed for inference from type guards
"@typescript-eslint/no-floating-promises": ["error"],
'@typescript-eslint/no-var-requires': 0, // covered by unicorn/prefer-module
'@typescript-eslint/explicit-module-boundary-types': 0,
Expand Down
2 changes: 2 additions & 0 deletions .graphqlrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: 'packages/cardano-graphql/dist/dgraph.graphql'
documents: 'packages/cardano-graphql/src/operations/**/*.graphql'
44 changes: 24 additions & 20 deletions .versionrc.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,43 @@
const packageMap = [
{
filename: "package.json",
type: "json"
filename: 'package.json',
type: 'json'
},
{
filename: "packages/blockfrost/package.json",
type: "json"
filename: 'packages/blockfrost/package.json',
type: 'json'
},
{
filename: "packages/cardano-graphql-db-sync/package.json",
type: "json"
filename: 'packages/cardano-graphql/package.json',
type: 'json'
},
{
filename: "packages/cip2/package.json",
type: "json"
filename: 'packages/cardano-graphql-db-sync/package.json',
type: 'json'
},
{
filename: "packages/cip30/package.json",
type: "json"
filename: 'packages/cip2/package.json',
type: 'json'
},
{
filename: "packages/core/package.json",
type: "json"
filename: 'packages/cip30/package.json',
type: 'json'
},
{
filename: "packages/golden-test-generator/package.json",
type: "json"
filename: 'packages/core/package.json',
type: 'json'
},
{
filename: "packages/util-dev/package.json",
type: "json"
filename: 'packages/golden-test-generator/package.json',
type: 'json'
},
{
filename: "packages/wallet/package.json",
type: "json"
filename: 'packages/util-dev/package.json',
type: 'json'
},
{
filename: 'packages/wallet/package.json',
type: 'json'
}
];

Expand All @@ -44,5 +48,5 @@ module.exports = {
commit: true,
tag: true
},
"tag-prefix": ""
}
'tag-prefix': ''
};
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ A suite of TypeScript packages suitable for both Node.js and browser-based devel
### Cardano Provider Implementations

- [@cardano-sdk/cardano-graphql-db-sync](packages/cardano-graphql-db-sync)
- [@cardano-sdk/cardano-graphql](packages/cardano-graphql)
- [@cardano-sdk/blockfrost](packages/blockfrost)

:information_source: Looking to use a Cardano service not listed here? [Let us know!]
Expand All @@ -35,11 +36,13 @@ You may use the following config when bundling this SDK with Webpack:
const { IgnorePlugin, ProvidePlugin } = require('webpack');
{
plugins: [
// see https://www.npmjs.com/package/isomorphic-bip39 README
// see https://www.npmjs.com/package/bip39 README
new IgnorePlugin(/^\.\/wordlists\/(?!english)/, /bip39\/src$/),
],
experiments: {
asyncWebAssembly: true
// Requires code splitting to work.
// Must dynamically `import()` a chunk that imports '@cardano-sdk/*'.
syncWebAssembly: true
}
}
```
Expand All @@ -51,8 +54,9 @@ const { NormalModuleReplacementPlugin } = require('webpack');
{
resolve: {
fallback: {
// May want to install readable-stream as an explicit dependency
// Node.js polyfills. May want to install as explicit dependencies.
stream: require.resolve('readable-stream'),
buffer: require.resolve('buffer'),
}
},
plugins: [
Expand Down
43 changes: 21 additions & 22 deletions packages/blockfrost/src/blockfrostProvider.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { CardanoProvider, ProviderError, ProviderFailure } from '@cardano-sdk/core';
import { WalletProvider, ProviderError, ProviderFailure } from '@cardano-sdk/core';
import { BlockFrostAPI, Error as BlockfrostError } from '@blockfrost/blockfrost-js';
import { Options } from '@blockfrost/blockfrost-js/lib/types';
import { BlockfrostToOgmios } from './BlockfrostToOgmios';
Expand Down Expand Up @@ -51,17 +51,17 @@ const toProviderError = (error: unknown) => {
* Connect to the [Blockfrost service](https://docs.blockfrost.io/)
*
* @param {Options} options BlockFrostAPI options
* @returns {CardanoProvider} CardanoProvider
* @returns {WalletProvider} WalletProvider
*/
export const blockfrostProvider = (options: Options): CardanoProvider => {
export const blockfrostProvider = (options: Options): WalletProvider => {
const blockfrost = new BlockFrostAPI(options);

const ledgerTip: CardanoProvider['ledgerTip'] = async () => {
const ledgerTip: WalletProvider['ledgerTip'] = async () => {
const block = await blockfrost.blocksLatest();
return BlockfrostToOgmios.blockToTip(block);
};

const networkInfo: CardanoProvider['networkInfo'] = async () => {
const networkInfo: WalletProvider['networkInfo'] = async () => {
const currentEpoch = await blockfrost.epochsLatest();
const { stake, supply } = await blockfrost.network();
return {
Expand All @@ -86,7 +86,7 @@ export const blockfrostProvider = (options: Options): CardanoProvider => {
};
};

const stakePoolStats: CardanoProvider['stakePoolStats'] = async () => {
const stakePoolStats: WalletProvider['stakePoolStats'] = async () => {
const tallyPools = async (query: 'pools' | 'poolsRetired' | 'poolsRetiring', count = 0, page = 1) => {
const result = await blockfrost[query]({ page });
const newCount = count + result.length;
Expand All @@ -104,11 +104,11 @@ export const blockfrostProvider = (options: Options): CardanoProvider => {
};
};

const submitTx: CardanoProvider['submitTx'] = async (signedTransaction) => {
const submitTx: WalletProvider['submitTx'] = async (signedTransaction) => {
await blockfrost.txSubmit(signedTransaction.to_bytes());
};

const utxoDelegationAndRewards: CardanoProvider['utxoDelegationAndRewards'] = async (addresses, stakeKeyHash) => {
const utxoDelegationAndRewards: WalletProvider['utxoDelegationAndRewards'] = async (addresses, stakeKeyHash) => {
const utxoResults = await Promise.all(
addresses.map(async (address) =>
blockfrost.addressesUtxosAll(address).then((result) => BlockfrostToOgmios.addressUtxoContent(address, result))
Expand All @@ -125,35 +125,34 @@ export const blockfrostProvider = (options: Options): CardanoProvider => {
return { utxo, delegationAndRewards };
};

const queryTransactionsByAddresses: CardanoProvider['queryTransactionsByAddresses'] = async (addresses) => {
const queryTransactionsByHashes: WalletProvider['queryTransactionsByHashes'] = async (hashes) => {
const transactions = await Promise.all(hashes.map(async (hash) => blockfrost.txsUtxos(hash)));
return transactions.map((tx) => BlockfrostToOgmios.txContentUtxo(tx));
};

const queryTransactionsByAddresses: WalletProvider['queryTransactionsByAddresses'] = async (addresses) => {
const addressTransactions = await Promise.all(
addresses.map(async (address) => blockfrost.addressesTransactionsAll(address))
);

const transactionsArray = await Promise.all(
addressTransactions.map((transactionArray) =>
Promise.all(transactionArray.map(async ({ tx_hash }) => blockfrost.txsUtxos(tx_hash)))
queryTransactionsByHashes(transactionArray.map(({ tx_hash }) => tx_hash))
)
);

return transactionsArray.flat(1).map((tx) => BlockfrostToOgmios.txContentUtxo(tx));
};

const queryTransactionsByHashes: CardanoProvider['queryTransactionsByHashes'] = async (hashes) => {
const transactions = await Promise.all(hashes.map(async (hash) => blockfrost.txsUtxos(hash)));

return transactions.map((tx) => BlockfrostToOgmios.txContentUtxo(tx));
return transactionsArray.flat(1);
};

const currentWalletProtocolParameters: CardanoProvider['currentWalletProtocolParameters'] = async () => {
const currentWalletProtocolParameters: WalletProvider['currentWalletProtocolParameters'] = async () => {
const response = await blockfrost.axiosInstance({
url: `${blockfrost.apiUrl}/epochs/latest/parameters`
});

return BlockfrostToOgmios.currentWalletProtocolParameters(response.data);
};

const providerFunctions = {
const providerFunctions: WalletProvider = {
ledgerTip,
networkInfo,
stakePoolStats,
Expand All @@ -162,10 +161,10 @@ export const blockfrostProvider = (options: Options): CardanoProvider => {
queryTransactionsByAddresses,
queryTransactionsByHashes,
currentWalletProtocolParameters
} as any;
};

return Object.keys(providerFunctions).reduce((provider, key) => {
provider[key] = (...args: any[]) => providerFunctions[key](...args).catch(toProviderError);
provider[key] = (...args: any[]) => (providerFunctions as any)[key](...args).catch(toProviderError);
return provider;
}, {} as any) as CardanoProvider;
}, {} as any) as WalletProvider;
};
2 changes: 1 addition & 1 deletion packages/blockfrost/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { CardanoProvider } from '@cardano-sdk/core';
export { WalletProvider } from '@cardano-sdk/core';
export * from './blockfrostProvider';
export { Options } from '@blockfrost/blockfrost-js/lib/types';
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CardanoProvider, ProviderError, ProviderFailure } from '@cardano-sdk/core';
import { WalletProvider, ProviderError, ProviderFailure } from '@cardano-sdk/core';
import { gql, GraphQLClient } from 'graphql-request';
import { TransactionSubmitResponse } from '@cardano-graphql/client-ts';
import { Schema as Cardano } from '@cardano-ogmios/client';
Expand All @@ -16,10 +16,10 @@ import {
* ```
*/

export const cardanoGraphqlDbSyncProvider = (uri: string): CardanoProvider => {
export const cardanoGraphqlDbSyncProvider = (uri: string): WalletProvider => {
const client = new GraphQLClient(uri);

const ledgerTip: CardanoProvider['ledgerTip'] = async () => {
const ledgerTip: WalletProvider['ledgerTip'] = async () => {
const query = gql`
query {
cardano {
Expand All @@ -43,7 +43,7 @@ export const cardanoGraphqlDbSyncProvider = (uri: string): CardanoProvider => {
return CardanoGraphqlToOgmios.tip(response.cardano.tip);
};

const networkInfo: CardanoProvider['networkInfo'] = async () => {
const networkInfo: WalletProvider['networkInfo'] = async () => {
const query = gql`
query {
activeStake_aggregate {
Expand Down Expand Up @@ -118,7 +118,7 @@ export const cardanoGraphqlDbSyncProvider = (uri: string): CardanoProvider => {
};
};

const stakePoolStats: CardanoProvider['stakePoolStats'] = async () => {
const stakePoolStats: WalletProvider['stakePoolStats'] = async () => {
const currentEpochResponse = await client.request<{
cardano: {
currentEpoch: {
Expand Down Expand Up @@ -207,7 +207,7 @@ export const cardanoGraphqlDbSyncProvider = (uri: string): CardanoProvider => {
};
};

const submitTx: CardanoProvider['submitTx'] = async (signedTransaction) => {
const submitTx: WalletProvider['submitTx'] = async (signedTransaction) => {
try {
const mutation = gql`
mutation ($transaction: String!) {
Expand All @@ -233,11 +233,11 @@ export const cardanoGraphqlDbSyncProvider = (uri: string): CardanoProvider => {
};

// eslint-disable-next-line unicorn/consistent-function-scoping
const utxoDelegationAndRewards: CardanoProvider['utxoDelegationAndRewards'] = async () => {
const utxoDelegationAndRewards: WalletProvider['utxoDelegationAndRewards'] = async () => {
throw new Error('Not implemented yet.');
};

const queryTransactionsByAddresses: CardanoProvider['queryTransactionsByAddresses'] = async (addresses) => {
const queryTransactionsByAddresses: WalletProvider['queryTransactionsByAddresses'] = async (addresses) => {
const query = gql`
query ($addresses: [String]!) {
transactions(
Expand Down Expand Up @@ -280,7 +280,7 @@ export const cardanoGraphqlDbSyncProvider = (uri: string): CardanoProvider => {
return CardanoGraphqlToOgmios.graphqlTransactionsToCardanoTxs(response.transactions);
};

const queryTransactionsByHashes: CardanoProvider['queryTransactionsByHashes'] = async (hashes) => {
const queryTransactionsByHashes: WalletProvider['queryTransactionsByHashes'] = async (hashes) => {
const query = gql`
query ($hashes: [Hash32Hex]!) {
transactions(where: { hash: { _in: $hashes } }) {
Expand Down Expand Up @@ -321,7 +321,7 @@ export const cardanoGraphqlDbSyncProvider = (uri: string): CardanoProvider => {
return CardanoGraphqlToOgmios.graphqlTransactionsToCardanoTxs(response.transactions);
};

const currentWalletProtocolParameters: CardanoProvider['currentWalletProtocolParameters'] = async () => {
const currentWalletProtocolParameters: WalletProvider['currentWalletProtocolParameters'] = async () => {
const query = gql`
query {
cardano {
Expand Down
2 changes: 1 addition & 1 deletion packages/cardano-graphql-db-sync/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { CardanoProvider } from '@cardano-sdk/core';
export { WalletProvider } from '@cardano-sdk/core';
export * from './cardanoGraphqlDbSyncProvider';
4 changes: 4 additions & 0 deletions packages/cardano-graphql/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
dist
secrets
coverage
2 changes: 2 additions & 0 deletions packages/cardano-graphql/.graphqlrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: 'dist/schema.graphql'
documents: 'src/operations/*.graphql'
17 changes: 17 additions & 0 deletions packages/cardano-graphql/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Cardano JS SDK | Cardano GraphQL

This package implements StakePoolSearchProvider using GraphQL

## Server-side usage

This package:

1. Generates GraphQL SDL schema from TypeScript types (`yarn build:schema`, also part of `yarn build`) `=> dist/schema.graphql`
2. Generates Dgraph schema (`yarn build:schema:dgraph`; requires local dgraph server running at port 8080, see [docker-compose.yml](./docker-compose.yml)) `=> dist/dgraph.graphql`
3. Generates [dgraph client](./src/sdk.ts) from Dgraph schema and [operations](./src/operations), which can then be used to implement `*Provider` interfaces (`yarn generate`)

## Tests

See [code coverage report]

[code coverage report]: https://input-output-hk.github.io/cardano-js-sdk/coverage/cardano-graphql
13 changes: 13 additions & 0 deletions packages/cardano-graphql/codegen.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
schema: ./dist/dgraph.graphql
documents: ./src/operations/*.graphql
generates:
./src/sdk.ts:
plugins:
- typescript
- typescript-operations
- typescript-graphql-request
config:
strictScalars: true
scalars:
DateTime: string
Int64: number
10 changes: 10 additions & 0 deletions packages/cardano-graphql/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: "3.5"
services:
dgraph:
image: dgraph/standalone:v21.03.0
ports:
- 8080:8080
volumes:
- dgraph:/dgraph
volumes:
dgraph:
1 change: 1 addition & 0 deletions packages/cardano-graphql/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('../../test/jest.config');
Loading

0 comments on commit 1d86393

Please sign in to comment.