Skip to content

Commit

Permalink
feat(cardano-graphql): add txSubmitHttpProvider
Browse files Browse the repository at this point in the history
- Uses got as the HTTP request library. It's pinned at the previous
major version as the latest is incompatible with CommonJS, so I've elected
stay on v11 until we look at our module strategy and targets.
sindresorhus/got#1789
- deserialize and throw domain errors
- Note: While this rehydrates errors, until
sindresorhus/serialize-error#48, the type precision is lost.
The error.name can be used to differentiate the type for now.
- Fixes JSDoc references
  • Loading branch information
rhyslbw committed Mar 25, 2022
1 parent cb03f69 commit 81dad15
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 1 deletion.
5 changes: 4 additions & 1 deletion packages/cardano-graphql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"test:debug": "DEBUG=true yarn test"
},
"devDependencies": {
"@cardano-sdk/cardano-graphql-services": "0.2.0",
"@graphql-codegen/cli": "~2.5.0",
"@graphql-codegen/typescript": "~2.4.3",
"@graphql-codegen/typescript-graphql-request": "~4.3.4",
Expand All @@ -39,10 +40,12 @@
"@cardano-ogmios/client": "~5.1.0",
"@cardano-sdk/core": "0.2.0",
"class-validator": "^0.13.1",
"got": "^11",
"graphql": "~15.6.1",
"graphql-request": "npm:graphql-request-configurable-serializer@4.0.0",
"graphql-tag": "2.12.5",
"json-bigint": "~1.0.0"
"json-bigint": "~1.0.0",
"serialize-error": "^8"
},
"files": [
"dist/*",
Expand Down
1 change: 1 addition & 0 deletions packages/cardano-graphql/src/TxSubmitProvider/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './txSubmitHttpProvider';
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
Cardano,
ProviderError,
ProviderFailure,
TxSubmitProvider
} from '@cardano-sdk/core';
import { deserializeError } from 'serialize-error';
import got from 'got';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import type ConnectionConfig from '@cardano-sdk/cardano-graphql-services';

/**
* Connect to a TxSubmitHttpServer instance
*
* @param {ConnectionConfig} connectionConfig Service connection configuration
* @returns {TxSubmitProvider} TxSubmitProvider
* @throws {Cardano.TxSubmissionErrors}
*/
export const txSubmitHttpProvider = (connectionConfig: { url: string }): TxSubmitProvider => ({
async healthCheck() {
try {
const response = await got.get(`${connectionConfig.url}/health`);
return JSON.parse(response.body);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
if (error.name === 'RequestError') {
return { ok: false };
}
throw new ProviderError(ProviderFailure.Unknown, error);
}
},
async submitTx(tx: Uint8Array) {
try {
await got.post(`${connectionConfig.url}/submit`, {
body: Buffer.from(tx),
headers: { 'Content-Type': 'application/cbor' }
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
const domainErrors = JSON.parse(error?.response?.body || null) as null | string | string[];
if (Array.isArray(domainErrors)) {
throw domainErrors.map((e: string) => deserializeError(e));
} else if (domainErrors !== null) {
throw deserializeError(domainErrors);
}
throw new ProviderError(ProviderFailure.Unknown, error);
}
}
});
1 change: 1 addition & 0 deletions packages/cardano-graphql/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export { WalletProvider, StakePoolSearchProvider } from '@cardano-sdk/core';
export * from './StakePoolSearchProvider';
export * from './WalletProvider';
export * from './AssetProvider';
export * from './TxSubmitProvider';
export * from './createSDK';
// Do not export this. Using core types elsewhere in the sdk.
// export * as Schema from './Schema';
1 change: 1 addition & 0 deletions packages/cardano-graphql/src/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"rootDir": "."
},
"references": [
{ "path": "../../cardano-graphql-services/src" },
{ "path": "../../core/src" }
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Cardano } from '@cardano-sdk/core';
import { serializeError } from 'serialize-error';
import { txSubmitHttpProvider } from '../../src';
import got from 'got';

const url = 'http://some-hostname:3000';

describe('txSubmitHttpProvider', () => {
describe('healthCheck', () => {
it('is not ok if cannot connect', async () => {
const provider = txSubmitHttpProvider({ url });
await expect(provider.healthCheck()).resolves.toEqual({ ok: false });
});
describe('mocked', () => {
beforeAll(() => {
jest.mock('got');
});

afterAll(() => {
jest.unmock('got');
});

it('is ok if 200 response body is { ok: true }', async () => {
got.get = jest.fn().mockResolvedValue({ body: JSON.stringify({ ok: true }) });
const provider = txSubmitHttpProvider({ url });
await expect(provider.healthCheck()).resolves.toEqual({ ok: true });
});

it('is not ok if 200 response body is { ok: false }', async () => {
got.get = jest.fn().mockResolvedValue({ body: JSON.stringify({ ok: false }) });
const provider = txSubmitHttpProvider({ url });
await expect(provider.healthCheck()).resolves.toEqual({ ok: false });
});
});
});
describe('submitTx', () => {
it('resolves if successful', async () => {
got.post = jest.fn().mockResolvedValue('');
const provider = txSubmitHttpProvider({ url });
await expect(provider.submitTx(new Uint8Array())).resolves;
});
it('rehydrates errors, although only as base Error class', async () => {
const errors = [new Cardano.TxSubmissionErrors.BadInputsError({ badInputs: [] })];
try {
got.post = jest.fn().mockRejectedValue({
response: {
body: JSON.stringify(errors.map((e) => serializeError(e)))
}
});
const provider = txSubmitHttpProvider({ url });
await provider.submitTx(new Uint8Array());
throw new Error('fail');
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
// https://github.com/sindresorhus/serialize-error/issues/48
// expect(error[0]).toBeInstanceOf(Cardano.TxSubmissionErrors.BadInputsError);
expect(error[0]).toBeInstanceOf(Error);
expect(error[0].name).toBe('BadInputsError');
}
});
});
});

0 comments on commit 81dad15

Please sign in to comment.