diff --git a/README.md b/README.md index 555d4258..7acc31a4 100644 --- a/README.md +++ b/README.md @@ -347,6 +347,56 @@ const records = arIO.getArNSRecords(); // } ``` +### `getPrescribedObservers({ evaluationOptions })` + +Retrieves the prescribed observers of the ArIO contract. To fetch prescribed observers for a previous epoch set the `evaluationOptions` to the desired epoch. + +```typescript +const arIO = new ArIO(); +const observers = arIO.getPrescribedObservers(); + +// outputs: + +// [ +// { +// "gatewayAddress": "BpQlyhREz4lNGS-y3rSS1WxADfxPpAuing9Lgfdrj2U", +// "observerAddress": "2Fk8lCmDegPg6jjprl57-UCpKmNgYiKwyhkU4vMNDnE", +// "stake": 10000, +// "start": 1296976, +// "stakeWeight": 1, +// "tenureWeight": 0.41453703703703704, +// "gatewayRewardRatioWeight": 1, +// "observerRewardRatioWeight": 1, +// "compositeWeight": 0.41453703703703704, +// "normalizedCompositeWeight": 0.0018972019546783507 +// }, +// ... +// ] + +// observers from a previous epoch +const previousEpochObservers = arIO.getPrescribedObservers({ + evaluationOptions: { + evalTo: { blockHeight: 1296975 }, // some block height from a previous epoch + }, +}); + +// [ +// { +// "gatewayAddress": "2Ic0ZIpt85tjiVRaD_qoTSo9jgT7w0rbf4puSTRidcU", +// "observerAddress": "2Ic0ZIpt85tjiVRaD_qoTSo9jgT7w0rbf4puSTRidcU", +// "stake": 10000, +// "start": 1292450, +// "stakeWeight": 1, +// "tenureWeight": 0.4494598765432099, +// "gatewayRewardRatioWeight": 1, +// "observerRewardRatioWeight": 1, +// "compositeWeight": 0.4494598765432099, +// "normalizedCompositeWeight": 0.002057032496835938 +// }, +// ... +// ] +``` + ## Developers ### Requirements diff --git a/src/common.ts b/src/common.ts index 1a74be6c..ee3102c3 100644 --- a/src/common.ts +++ b/src/common.ts @@ -19,6 +19,7 @@ import { ArNSNameData, EpochDistributionData, Gateway, + WeightedObserver, } from './contract-state.js'; export type BlockHeight = number; @@ -87,6 +88,9 @@ export interface ArIOContract { getCurrentEpoch({ evaluationOptions, }: EvaluationParameters): Promise; + getPrescribedObservers({ + evaluationOptions, + }: EvaluationParameters): Promise; } /* eslint-disable @typescript-eslint/no-explicit-any */ diff --git a/src/common/ar-io.ts b/src/common/ar-io.ts index 29031b65..53f20001 100644 --- a/src/common/ar-io.ts +++ b/src/common/ar-io.ts @@ -23,6 +23,7 @@ import { EvaluationParameters, Gateway, SmartWeaveContract, + WeightedObserver, } from '../types.js'; import { RemoteContract } from './contracts/remote-contract.js'; @@ -183,4 +184,16 @@ export class ArIO implements ArIOContract { evaluationOptions, }); } + + /** + * Returns the prescribed observers for the current epoch. If you are looking for prescribed observers for a past epoch, use `evaluationOptions: { blockHeight: }`. + */ + async getPrescribedObservers({ + evaluationOptions, + }: EvaluationParameters = {}): Promise { + return this.contract.readInteraction({ + functionName: 'prescribedObservers', + evaluationOptions, + }); + } } diff --git a/tests/ar-io.test.ts b/tests/ar-io.test.ts index 5539d193..949a544d 100644 --- a/tests/ar-io.test.ts +++ b/tests/ar-io.test.ts @@ -149,4 +149,46 @@ describe('ArIO Client', () => { expect(epoch.epochPeriod).toBeDefined(); expect(epoch.epochZeroStartHeight).toBeDefined(); }); + + it('should return the prescribed observers for the current epoch', async () => { + const observers = await arIO.getPrescribedObservers(); + expect(observers).toBeDefined(); + for (const observer of observers) { + expect(observer.gatewayAddress).toBeDefined(); + expect(observer.observerAddress).toBeDefined(); + expect(observer.stake).toBeDefined(); + expect(observer.start).toBeDefined(); + expect(observer.stakeWeight).toBeDefined(); + expect(observer.tenureWeight).toBeDefined(); + expect(observer.gatewayRewardRatioWeight).toBeDefined(); + expect(observer.observerRewardRatioWeight).toBeDefined(); + expect(observer.compositeWeight).toBeDefined(); + expect(observer.normalizedCompositeWeight).toBeDefined(); + } + }); + + it.each([ + [{ sortKey: evaluateToSortKey.toString() }], + [{ blockHeight: evaluateToBlockHeight }], + ])( + `should return the prescribed observers for provided evaluation options: ${JSON.stringify('%s')}`, + async (evalTo) => { + const observers = await arIO.getPrescribedObservers({ + evaluationOptions: { evalTo }, + }); + expect(observers).toBeDefined(); + for (const observer of observers) { + expect(observer.gatewayAddress).toBeDefined(); + expect(observer.observerAddress).toBeDefined(); + expect(observer.stake).toBeDefined(); + expect(observer.start).toBeDefined(); + expect(observer.stakeWeight).toBeDefined(); + expect(observer.tenureWeight).toBeDefined(); + expect(observer.gatewayRewardRatioWeight).toBeDefined(); + expect(observer.observerRewardRatioWeight).toBeDefined(); + expect(observer.compositeWeight).toBeDefined(); + expect(observer.normalizedCompositeWeight).toBeDefined(); + } + }, + ); });