proof-measure is a separate, public, unauthenticated Dragonchain service. Adds: - UnauthHttpClient: HMAC-free transport mirroring DragonchainClient (timeout, agent, redirect refusal). - ProofMeasureClient: getSecurity / report / health; default base URL https://proof-measure.dragonchain.com. Standalone (new ProofMeasureClient()) and via DragonchainSDK.proofMeasure. - Proof-measure types (decimals as strings, timestamps as numbers). - jest tests.
80 lines
3.2 KiB
TypeScript
80 lines
3.2 KiB
TypeScript
import { ProofMeasureClient, PROOF_MEASURE_DEFAULT_BASE_URL } from '../src/proofMeasure';
|
|
import { UnauthHttpClient } from '../src/unauthHttpClient';
|
|
import { ProofMeasureSecurityResult, ProofMeasureTransactionReport } from '../src/types';
|
|
|
|
// Build a fake transport that is an instanceof UnauthHttpClient (so the
|
|
// ProofMeasureClient constructor uses it directly) with mocked get/post.
|
|
function fakeClient(get?: jest.Mock, post?: jest.Mock): UnauthHttpClient {
|
|
const c = Object.create(UnauthHttpClient.prototype) as UnauthHttpClient;
|
|
(c as unknown as { get: jest.Mock }).get = get ?? jest.fn(async () => ({}));
|
|
(c as unknown as { post: jest.Mock }).post = post ?? jest.fn(async () => ({}));
|
|
return c;
|
|
}
|
|
|
|
describe('ProofMeasureClient', () => {
|
|
it('getSecurity builds the path with since and returns the parsed result', async () => {
|
|
const sec: ProofMeasureSecurityResult = {
|
|
network: 'BTC',
|
|
consensus: 'pow',
|
|
raw: { value: '71.63', unit: 'Yottahashes', base: '7.16e25' },
|
|
valueUsd: '13928170.26',
|
|
valueUsdFormatted: '$13,928,170.26',
|
|
label: '$13,928,170.26 energy consumed',
|
|
normalizedScore: '0.9234',
|
|
since: 1780504894,
|
|
asOf: 1780591253,
|
|
};
|
|
const get = jest.fn(async () => sec);
|
|
const client = fakeClient(get);
|
|
const res = await new ProofMeasureClient(client).getSecurity('BTC', 1780504894);
|
|
expect(get).toHaveBeenCalledWith('/api/v1/security/BTC?since=1780504894');
|
|
expect(res.network).toBe('BTC');
|
|
expect(res.raw.unit).toBe('Yottahashes');
|
|
expect(res.valueUsdFormatted).toBe('$13,928,170.26');
|
|
});
|
|
|
|
it('getSecurity omits the since param when not provided', async () => {
|
|
const get = jest.fn(async () => ({}));
|
|
await new ProofMeasureClient(fakeClient(get)).getSecurity('ETH');
|
|
expect(get).toHaveBeenCalledWith('/api/v1/security/ETH');
|
|
});
|
|
|
|
it('report POSTs the request to /api/v1/report and parses the report', async () => {
|
|
const report: ProofMeasureTransactionReport = {
|
|
transactionId: 't',
|
|
primeId: 'p',
|
|
blockId: '42',
|
|
anchors: [],
|
|
totalValueUsd: '100.00',
|
|
totalValueUsdFormatted: '$100.00',
|
|
hashPower: { value: '40.06', units: 'Yottahashes' },
|
|
totalNormalizedScore: '0.9',
|
|
};
|
|
const post = jest.fn(async () => report);
|
|
const client = fakeClient(undefined, post);
|
|
const req = {
|
|
transactionId: 't',
|
|
primeId: 'p',
|
|
blockId: '42',
|
|
anchors: [{ network: 'BTC', txHash: '0xabc', timestamp: 1712345678 }],
|
|
};
|
|
const rep = await new ProofMeasureClient(client).report(req);
|
|
expect(post).toHaveBeenCalledWith('/api/v1/report', 'application/json', req);
|
|
expect(rep.totalValueUsdFormatted).toBe('$100.00');
|
|
expect(rep.hashPower?.units).toBe('Yottahashes');
|
|
});
|
|
|
|
it('health calls /api/v1/health', async () => {
|
|
const get = jest.fn(async () => ({ status: 'ok' }));
|
|
const res = await new ProofMeasureClient(fakeClient(get)).health();
|
|
expect(get).toHaveBeenCalledWith('/api/v1/health');
|
|
expect(res.status).toBe('ok');
|
|
});
|
|
|
|
it('defaults to the public endpoint with no config', () => {
|
|
const pm = new ProofMeasureClient();
|
|
expect(pm).toBeInstanceOf(ProofMeasureClient);
|
|
expect(PROOF_MEASURE_DEFAULT_BASE_URL).toBe('https://proof-measure.dragonchain.com');
|
|
});
|
|
});
|