feat: add feature RPC (#2719)

* add feature RPC

* export, add tests

* update history

* fix test

* update models

* update feature models to correctly handle both cases

* fix models/tests

* fix test, improve type

* undo type change

* fix test
This commit is contained in:
Mayukha Vadari
2024-07-10 13:18:16 -04:00
committed by GitHub
parent 3858a09e1f
commit 00f1a6bcdd
4 changed files with 153 additions and 0 deletions

View File

@@ -11,6 +11,7 @@ Subscribe to [the **xrpl-announce** mailing list](https://groups.google.com/g/xr
### Added
* Add `nfts_by_issuer` clio-only API definition
* Support for the `fixPreviousTxnID` amendment.
* Support for the user version of the `feature` RPC.
## 3.1.0 (2024-06-03)

View File

@@ -0,0 +1,68 @@
import { BaseRequest, BaseResponse } from './baseMethod'
export interface FeatureAllRequest extends BaseRequest {
command: 'feature'
feature?: never
}
export interface FeatureOneRequest extends BaseRequest {
command: 'feature'
feature: string
}
/**
* The `feature` command returns information about amendments this server knows about, including whether they are enabled.
* Returns an {@link FeatureResponse}.
*
* @category Requests
*/
export type FeatureRequest = FeatureAllRequest | FeatureOneRequest
export interface FeatureAllResponse extends BaseResponse {
result: {
features: Record<
string,
{
/*
* Whether this amendment is currently enabled in the latest ledger.
*/
enabled: boolean
/*
* The human-readable name for this amendment, if known.
*/
name: string
supported: boolean
}
>
}
}
export interface FeatureOneResponse extends BaseResponse {
result: Record<
string,
{
/*
* Whether this amendment is currently enabled in the latest ledger.
*/
enabled: boolean
/*
* The human-readable name for this amendment, if known.
*/
name: string
supported: boolean
}
>
}
/**
* Response expected from an {@link FeatureRequest}.
*
* @category Responses
*/
export type FeatureResponse = FeatureAllResponse | FeatureOneResponse

View File

@@ -66,6 +66,14 @@ import {
DepositAuthorizedRequest,
DepositAuthorizedResponse,
} from './depositAuthorized'
import {
FeatureAllRequest,
FeatureAllResponse,
FeatureOneRequest,
FeatureOneResponse,
FeatureRequest,
FeatureResponse,
} from './feature'
import { FeeRequest, FeeResponse } from './fee'
import {
GatewayBalance,
@@ -214,6 +222,7 @@ type Request =
| ServerDefinitionsRequest
| ServerInfoRequest
| ServerStateRequest
| FeatureRequest
// utility methods
| PingRequest
| RandomRequest
@@ -271,6 +280,7 @@ type Response<Version extends APIVersion = typeof DEFAULT_API_VERSION> =
| ServerDefinitionsResponse
| ServerInfoResponse
| ServerStateResponse
| FeatureResponse
// utility methods
| PingResponse
| RandomResponse
@@ -419,6 +429,10 @@ export type RequestResponseMap<
? ServerStateResponse
: T extends ServerDefinitionsRequest
? ServerDefinitionsResponse
: T extends FeatureAllRequest
? FeatureAllResponse
: T extends FeatureOneRequest
? FeatureOneResponse
: T extends PingRequest
? PingResponse
: T extends RandomRequest
@@ -591,6 +605,8 @@ export {
ServerState,
StateAccountingFinal,
StateAccounting,
FeatureRequest,
FeatureResponse,
// utility methods
PingRequest,
PingResponse,

View File

@@ -0,0 +1,68 @@
import { assert } from 'chai'
import { FeatureRequest } from '../../../src'
import serverUrl from '../serverUrl'
import {
setupClient,
teardownClient,
type XrplIntegrationTestContext,
} from '../setup'
// how long before each test case times out
const TIMEOUT = 20000
const AMENDMENT =
'8CC0774A3BF66D1D22E76BBDA8E8A232E6B6313834301B3B23E8601196AE6455'
describe('feature', function () {
let testContext: XrplIntegrationTestContext
beforeEach(async () => {
testContext = await setupClient(serverUrl)
})
afterEach(async () => teardownClient(testContext))
it(
'all',
async () => {
const featureRequest: FeatureRequest = {
command: 'feature',
}
const featureResponse = await testContext.client.request(featureRequest)
assert.equal(featureResponse.type, 'response')
assert.typeOf(featureResponse.result.features, 'object')
assert.isTrue(AMENDMENT in featureResponse.result.features)
const amendmentData = featureResponse.result.features[AMENDMENT]
assert.equal(amendmentData.name, 'AMM')
// TODO: rippled says "false" for standalone nodes for some reason
assert.typeOf(amendmentData.enabled, 'boolean')
assert.equal(amendmentData.supported, true)
},
TIMEOUT,
)
it(
'one',
async () => {
const featureRequest: FeatureRequest = {
command: 'feature',
feature: AMENDMENT,
}
const featureResponse = await testContext.client.request(featureRequest)
assert.equal(featureResponse.type, 'response')
assert.typeOf(featureResponse.result, 'object')
assert.isTrue(AMENDMENT in featureResponse.result)
assert.lengthOf(Object.keys(featureResponse.result), 1)
const amendmentData = featureResponse.result[AMENDMENT]
assert.equal(amendmentData.name, 'AMM')
// TODO: rippled says "false" for standalone nodes for some reason
assert.typeOf(amendmentData.enabled, 'boolean')
assert.equal(amendmentData.supported, true)
},
TIMEOUT,
)
})