Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 5 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,23 +82,15 @@ a 32-byte hex string (`0x` followed by 64 hexadecimal digits) that denotes the b

- [`/accounts/ADDRESS/staking-payouts` fetch staking payouts for `ADDRESS`.](/src/controllers/accounts/AccountsStakingPayoutsController.ts)

- [`/blocks` fetch a block.](/src/controllers/blocks/BlocksController.ts) (Replaces `/block`.)
- [`/accounts/ADDRESS/balance-info` fetch balances info for `ADDRESS`.](src/controllers/accounts/AccountsBalanceInfoController.ts) (Replaces `/balance/ADDRESS`.)

- [`/balance/ADDRESS` fetch balances for `ADDRESS` at latest finalized block.](src/controllers/accounts/AccountsBalanceInfoController.ts)
- [`/accounts/ADDRESS/vesting-info` vesting info for `ADDRESS`.](src/controllers/accounts/AccountsVestingInfoController.ts) (Replaces `/vesting/ADDRESS`.)

- [`/balance/ADDRESS/NUMBER` fetch balances for `ADDRESS` at the block identified by 'NUMBER`.](src/controllers/accounts/AccountsBalanceInfoController.ts)
- [`/accounts/ADDRESS/staking-info` fetch the staking info for `ADDRESS`.](src/controllers/accounts/AccountsStakingInfoController.ts) (Replaces `/staking/ADDRESS`.)

- [`/staking/ADDRESS` fetch the staking info for `ADDRESS` at latest finalized block.](src/controllers/accounts/AccountsStakingInfoController.ts)
- [`/blocks/{head, BlockId}` fetch the finalized head or block identified by BlockId.](/src/controllers/blocks/BlocksController.ts) (Replaces `/block`.)

- [`/staking/ADDRESS/NUMBER` fetch the staking info for `ADDRESS` at the block identified by 'NUMBER`.](src/controllers/accounts/AccountsStakingInfoController.ts)

- [`/staking-info` fetch information on general staking progress at the latest finalized block.](src/controllers/pallets/PalletsStakingProgressController.ts)

- [`/staking-info/NUMBER` fetch information on general staking progress at the block identified by 'NUMBER`.](src/controllers/pallets/PalletsStakingProgressController.ts)

- [`/vesting/ADDRESS` fetch the vesting info for `ADDRESS` at latest finalized block.](src/controllers/accounts/AccountsVestingInfoController.ts)

- [`/vesting/ADDRESS/NUMBER` fetch the vesting info for `ADDRESS` at the block identified by 'NUMBER`.](src/controllers/accounts/AccountsVestingInfoController.ts)
- [`/pallets/staking/progress` fetch information on general staking progress.](src/controllers/pallets/PalletsStakingProgressController.ts) (Replaces `/staking-info`.)

- [`/node/network` fetch information about the Substrate node's activity in the peer-to-peer network.](src/controllers/node/NodeNetworkController.ts)

Expand Down
4 changes: 2 additions & 2 deletions openapi/openapi-proposal.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ paths:
summary: Get balance information for an account.
description: Returns information about an account's balance.
Replaces `/balance/{address}` from versions < v1.0.0.
operationId: getBalanceSummaryByAccountId
operationId: getAccountBalanceInfo
parameters:
- name: accountId
in: path
Expand Down Expand Up @@ -433,7 +433,7 @@ paths:
get:
tags:
- staking
summary: Get a progress report on the chain's staking system.
summary: Get progress on the general Staking pallet system.
description: Returns information on the progress of key components of the
staking system and estimates of future points of interest. Replaces
`/staking-info` from versions < v1.0.0.
Expand Down
77 changes: 77 additions & 0 deletions src/controllers/accounts/AccountsBalanceInfoController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { ApiPromise } from '@polkadot/api';
import { RequestHandler } from 'express';
import { IAddressParam } from 'src/types/requests';

import { validateAddress } from '../../middleware';
import { AccountsBalanceInfoService } from '../../services';
import AbstractController from '../AbstractController';

/**
* GET balance information for an address.
*
* Paths:
* - `address`: The address to query.
*
* Query:
* - (Optional)`at`: Block at which to retrieve runtime version information at. Block
* identifier, as the block height or block hash. Defaults to most recent block.
*
* Returns:
* - `at`: Block number and hash at which the call was made.
* - `nonce`: Account nonce.
* - `free`: Free balance of the account. Not equivalent to _spendable_ balance. This is the only
* balance that matters in terms of most operations on tokens.
* - `reserved`: Reserved balance of the account.
* - `miscFrozen`: The amount that `free` may not drop below when withdrawing for anything except
* transaction fee payment.
* - `feeFrozen`: The amount that `free` may not drop below when withdrawing specifically for
* transaction fee payment.
* - `locks`: Array of locks on a balance. There can be many of these on an account and they
* "overlap", so the same balance is frozen by multiple locks. Contains:
* - `id`: An identifier for this lock. Only one lock may be in existence for each identifier.
* - `amount`: The amount below which the free balance may not drop with this lock in effect.
* - `reasons`: If true, then the lock remains in effect even for payment of transaction fees.
*
* Substrate Reference:
* - FRAME System: https://crates.parity.io/frame_system/index.html
* - Balances Pallet: https://crates.parity.io/pallet_balances/index.html
* - `AccountInfo`: https://crates.parity.io/frame_system/struct.AccountInfo.html
* - `AccountData`: https://crates.parity.io/pallet_balances/struct.AccountData.html
* - `BalanceLock`: https://crates.parity.io/pallet_balances/struct.BalanceLock.html
*/
export default class AccountsBalanceController extends AbstractController<
AccountsBalanceInfoService
> {
constructor(api: ApiPromise) {
super(
api,
'/accounts/:address/balance-info',
new AccountsBalanceInfoService(api)
);
this.initRoutes();
}

protected initRoutes(): void {
this.router.use(this.path, validateAddress);

this.safeMountAsyncGetHandlers([['', this.getAccountBalanceInfo]]);
}

/**
* Get the latest account balance summary of `address`.
*
* @param req Express Request
* @param res Express Response
*/
private getAccountBalanceInfo: RequestHandler<IAddressParam> = async (
{ params: { address }, query: { at } },
res
): Promise<void> => {
const hash = await this.getHashFromAt(at);

AccountsBalanceController.sanitizedSend(
res,
await this.service.fetchAccountBalanceInfo(hash, address)
);
};
}
85 changes: 85 additions & 0 deletions src/controllers/accounts/AccountsStakingInfoController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { ApiPromise } from '@polkadot/api';
import { RequestHandler } from 'express';
import { IAddressParam } from 'src/types/requests';

import { validateAddress } from '../../middleware';
import { AccountsStakingInfoService } from '../../services';
import AbstractController from '../AbstractController';

/**
* GET staking information for an address.
*
* Paths:
* - `address`: The _Stash_ address for staking.
*
* Query:
* - (Optional)`at`: Block at which to retrieve runtime version information at. Block
* identifier, as the block height or block hash. Defaults to most recent block.
*
* Returns:
* - `at`: Block number and hash at which the call was made.
* - `rewardDestination`: The account to which rewards will be paid. Can be 'Staked' (Stash
* account, adding to the amount at stake), 'Stash' (Stash address, not adding to the amount at
* stake), or 'Controller' (Controller address).
* - `controller`: Controller address for the given Stash.
* - `numSlashingSpans`: Number of slashing spans on Stash account; `null` if provided address is
* not a Controller.
* - `staking`: The staking ledger. Empty object if provided address is not a Controller.
* - `stash`: The stash account whose balance is actually locked and at stake.
* - `total`: The total amount of the stash's balance that we are currently accounting for.
* Simply `active + unlocking`.
* - `active`: The total amount of the stash's balance that will be at stake in any forthcoming
* eras.
* - `unlocking`: Any balance that is becoming free, which may eventually be transferred out of
* the stash (assuming it doesn't get slashed first). Represented as an array of objects, each
* with an `era` at which `value` will be unlocked.
* - `claimedRewards`: Array of eras for which the stakers behind a validator have claimed
* rewards. Only updated for _validators._
*
* Note: Runtime versions of Kusama less than 1062 will either have `lastReward` in place of
* `claimedRewards`, or no field at all. This is related to changes in reward distribution. See:
* - Lazy Payouts: https://github.com/paritytech/substrate/pull/4474
* - Simple Payouts: https://github.com/paritytech/substrate/pull/5406
*
* Substrate Reference:
* - Staking Pallet: https://crates.parity.io/pallet_staking/index.html
* - `RewardDestination`: https://crates.parity.io/pallet_staking/enum.RewardDestination.html
* - `Bonded`: https://crates.parity.io/pallet_staking/struct.Bonded.html
* - `StakingLedger`: https://crates.parity.io/pallet_staking/struct.StakingLedger.html
*/
export default class AccountsStakingInfoController extends AbstractController<
AccountsStakingInfoService
> {
constructor(api: ApiPromise) {
super(
api,
'/accounts/:address/staking-info',
new AccountsStakingInfoService(api)
);
this.initRoutes();
}

protected initRoutes(): void {
this.router.use(this.path, validateAddress);

this.safeMountAsyncGetHandlers([['', this.getAccountStakingInfo]]);
}

/**
* Get the latest account staking summary of `address`.
*
* @param req Express Request
* @param res Express Response
*/
private getAccountStakingInfo: RequestHandler<IAddressParam> = async (
{ params: { address }, query: { at } },
res
): Promise<void> => {
const hash = await this.getHashFromAt(at);

AccountsStakingInfoController.sanitizedSend(
res,
await this.service.fetchAccountStakingInfo(hash, address)
);
};
}
65 changes: 65 additions & 0 deletions src/controllers/accounts/AccountsVestingInfoController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { ApiPromise } from '@polkadot/api';
import { RequestHandler } from 'express';
import { IAddressParam } from 'src/types/requests';

import { validateAddress } from '../../middleware';
import { AccountsVestingInfoService } from '../../services';
import AbstractController from '../AbstractController';

/**
* GET vesting information for an address.
*
* Paths:
* - `address`: Address to query.
*
* Query params:
* - (Optional)`at`: Block at which to retrieve runtime version information at. Block
* identifier, as the block height or block hash. Defaults to most recent block.
*
* Returns:
* - `at`: Block number and hash at which the call was made.
* - `vesting`: Vesting schedule for an account.
* - `locked`: Number of tokens locked at start.
* - `perBlock`: Number of tokens that gets unlocked every block after `startingBlock`.
* - `startingBlock`: Starting block for unlocking(vesting).
*
* Substrate Reference:
* - Vesting Pallet: https://crates.parity.io/pallet_vesting/index.html
* - `VestingInfo`: https://crates.parity.io/pallet_vesting/struct.VestingInfo.html
*/
export default class AccountsVestingInfoController extends AbstractController<
AccountsVestingInfoService
> {
constructor(api: ApiPromise) {
super(
api,
'/accounts/:address/vesting-info',
new AccountsVestingInfoService(api)
);
this.initRoutes();
}

protected initRoutes(): void {
this.router.use(this.path, validateAddress);

this.safeMountAsyncGetHandlers([['', this.getAccountVestingInfo]]);
}

/**
* Get vesting information for an account.
*
* @param req Express Request
* @param res Express Response
*/
private getAccountVestingInfo: RequestHandler<IAddressParam> = async (
{ params: { address }, query: { at } },
res
): Promise<void> => {
const hash = await this.getHashFromAt(at);

AccountsVestingInfoController.sanitizedSend(
res,
await this.service.fetchAccountVestingInfo(hash, address)
);
};
}
3 changes: 3 additions & 0 deletions src/controllers/accounts/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
export { default as AccountsStakingPayouts } from './AccountsStakingPayoutsController';
export { default as AccountsBalanceInfo } from './AccountsBalanceInfoController';
export { default as AccountsStakingInfo } from './AccountsStakingInfoController';
export { default as AccountsVestingInfo } from './AccountsVestingInfoController';
2 changes: 1 addition & 1 deletion src/controllers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export * from './transaction';
export * from './accounts';
export * from './blocks';
export * from './runtime';
// export * from './pallets';
export * from './pallets';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

export * from './node';

export * as v0 from './v0';
104 changes: 104 additions & 0 deletions src/controllers/pallets/PalletsStakingProgressController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { ApiPromise } from '@polkadot/api';
import { RequestHandler } from 'express';

import { PalletsStakingProgressService } from '../../services';
import AbstractController from '../AbstractController';

/**
* GET progress on the general Staking pallet system.
*
* Paths:
* - (Optional) `number`: Block hash or height at which to query. If not provided, queries
* finalized head.
*
* Query params:
* - (Optional)`at`: Block at which to retrieve runtime version information at. Block
* identifier, as the block height or block hash. Defaults to most recent block.
*
* Returns:
* - `at`: Block number and hash at which the call was made.
* - `activeEra`: `EraIndex` of the era being rewarded.
* - `forceEra`: Current status of era forcing.
* - `nextActiveEraEstimate`: **Upper bound estimate** of the block height at which the next
* active era will start. Not included in response when `forceEra.isForceNone`.
* - `nextSessionEstimate`: **Upper bound estimate** of the block height at which the next
* session will start.
* - `unappliedSlashes`: Array of upcoming `UnappliedSlash` indexed by era. Each `UnappliedSlash`
* contains:
* - `validator`: Stash account ID of the offending validator.
* - `own`: The amount the validator will be slashed.
* - `others`: Array of tuples of (accountId, amount) representing all the stashes of other
* slashed stakers and the amount they will be slashed.
* - `reporters`: Array of account IDs of the reporters of the offense.
* - `payout`: Amount of bounty payout to reporters.
* - `electionStatus`: Information about the off-chain election. Not included in response when
* `forceEra.isForceNone`. Response includes:
* - `status`: Era election status; either `Close: null` or `Open: <BlockNumber>`. A status of
* `Close` indicates that the submission window for solutions from off-chain Phragmen is not
* open. A status of `Open` indicates the submission window for off-chain Phragmen solutions
* has been open since BlockNumber. N.B. when the submission window is open, certain
* extrinsics are not allowed because they would mutate the state that the off-chain Phragmen
* calculation relies on for calculating results.
* - `toggleEstimate`: **Upper bound estimate** of the block height at which the `status` will
* switch.
* - `idealValidatorCount`: Upper bound of validator set size; considered the ideal size. Not
* included in response when `forceEra.isForceNone`.
* - `validatorSet`: Stash account IDs of the validators for the current session. Not included in
* response when `forceEra.isForceNone`.
*
* Note about 'active' vs. 'current' era: The _active_ era is the era currently being rewarded.
* That is, an elected validator set will be in place for an entire active era, as long as none
* are kicked out due to slashing. Elections take place at the end of each _current_ era, which
* is the latest planned era, and may not equal the active era. Normally, the current era index
* increments one session before the active era, in order to perform the election and queue the
* validator set for the next active era. For example:
*
* ```
* Time: --------->
* CurrentEra: 1 | 2 |
* ActiveEra: | 1 | 2 |
* SessionIdx: | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
* Elections: ^ ^
* Set Changes: ^ ^
* ```
*
* Substrate Reference:
* - Staking Pallet: https://crates.parity.io/pallet_staking/index.html
* - Session Pallet: https://crates.parity.io/pallet_session/index.html
* - `Forcing`: https://crates.parity.io/pallet_staking/enum.Forcing.html
* - `ElectionStatus`: https://crates.parity.io/pallet_staking/enum.ElectionStatus.html
*/
export default class PalletsStakingProgressController extends AbstractController<
PalletsStakingProgressService
> {
constructor(api: ApiPromise) {
super(
api,
'/pallets/staking/progress',
new PalletsStakingProgressService(api)
);
this.initRoutes();
}

protected initRoutes(): void {
this.safeMountAsyncGetHandlers([['', this.getPalletStakingProgress]]);
}

/**
* Get the progress of the staking pallet system.
*
* @param _req Express Request
* @param res Express Response
*/
private getPalletStakingProgress: RequestHandler = async (
{ query: { at } },
res
): Promise<void> => {
const hash = await this.getHashFromAt(at);

PalletsStakingProgressController.sanitizedSend(
res,
await this.service.derivePalletStakingProgress(hash)
);
};
}
1 change: 1 addition & 0 deletions src/controllers/pallets/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as palletsStakingProgress } from './PalletsStakingProgressController';
Loading