-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cardano-graphql): add txSubmitHttpProvider
- 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
Showing
6 changed files
with
121 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './txSubmitHttpProvider'; |
52 changes: 52 additions & 0 deletions
52
packages/cardano-graphql/src/TxSubmitProvider/txSubmitHttpProvider.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
packages/cardano-graphql/test/TxSubmitProvider/txSubmitHttpProvider.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'); | ||
} | ||
}); | ||
}); | ||
}); |