Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add pool-assets endpoints #1338

Merged
merged 3 commits into from
Oct 20, 2023
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
2 changes: 1 addition & 1 deletion docs/dist/app.bundle.js

Large diffs are not rendered by default.

163 changes: 159 additions & 4 deletions docs/src/openapi-v1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,112 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/Error'
/accounts/{accountId}/pool-asset-balances:
get:
tags:
- accounts
summary: Get an array of pool-asset-balances for an account.
description: Returns information about an account's pool-asset-balances. This is
specific to the pool assets pallet for parachains. If no `assets` query parameter
is provided, all pool-asset-balances for the given account will be returned.
operationId: getPoolAssetBalances
parameters:
- name: accountId
in: path
description: SS58 address of the account.
required: true
schema:
type: string
format: SS58
- name: at
in: query
description: Block at which to query pool-asset-balance info for the
specified account.
required: false
schema:
type: string
description: Block height (as a positive integer) or hash
(as a hex string).
format: unsignedInteger or $hex
- name: assets
in: query
description: An array of AssetId's to be queried. If not supplied, defaults to providing
all asset balances associated with the `accountId` will be returned. The array query param
format follows Express 4.x API. ex:`?assets[]=1&assets[]=2&assets[]=3`.
required: false
schema:
type: array
items:
type: string
description: A list of assetId numbers represented as strings
format: Array of unsignedInteger's
responses:
"200":
description: successfull operation
content:
application/json:
schema:
$ref: '#/components/schemas/AccountPoolAssetsBalances'
"400":
description: Invalid Address
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/accounts/{accountId}/pool-asset-approvals:
get:
tags:
- accounts
summary: Get an asset approval for an account.
description: Returns information about an account's asset approval transaction.
It is required to pass in a delegate and an assetId as query parameters.
operationId: getPoolAssetApprovals
parameters:
- name: accountId
in: path
description: SS58 address of the account.
required: true
schema:
type: string
format: SS58
- name: at
in: query
description: Block at which to query asset approval info for the
specified account.
required: false
schema:
type: string
description: Block height (as a non-negative integer) or hash
(as a hex string).
format: unsignedInteger or $hex
- name: assetId
in: query
description: The `assetId` associated with the asset-approval.
required: true
schema:
type: string
description: An assetId represented as an unsignedInteger.
format: unsignedInteger
- name: delegate
in: query
description: The delegate's `accountId` associated with an asset-approval.
required: true
schema:
type: string
format: SS58
responses:
"200":
description: successfull operation
content:
application/json:
schema:
$ref: '#/components/schemas/AccountAssetsApproval'
"400":
description: Invalid Address
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/accounts/{accountId}/staking-info:
get:
tags:
Expand Down Expand Up @@ -1701,6 +1807,37 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/Error'
/pallets/pool-assets/{assetId}/asset-info:
get:
tags:
- pallets
summary: Get information and metadata associated with a pool asset.
description: Returns information associated with a pool asset which includes
the assets `AssetDetails` and `AssetMetadata`.
operationId: getPoolAssetById
parameters:
- name: assetId
in: path
description: The unsignedInteger Id of a pool asset.
required: true
schema:
type: string
format: unsignedInteger
- name: at
in: query
description: Block at which to retrieve the assetInfo.
required: false
schema:
type: string
description: Block identifier, as the block height or block hash.
format: unsignedInteger or $hex
responses:
"200":
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/PalletsPoolAssetsInfo'
/pallets/staking/progress:
get:
tags:
Expand Down Expand Up @@ -2163,6 +2300,16 @@ components:
description: An array of queried assets.
items:
$ref: '#/components/schemas/AssetsBalance'
AccountPoolAssetsBalances:
type: object
properties:
at:
$ref: '#/components/schemas/BlockIdentifiers'
poolAssets:
type: array
description: An array of queried assets.
items:
$ref: '#/components/schemas/AssetsBalance'
LiquidityPools:
type: object
properties:
Expand Down Expand Up @@ -2413,10 +2560,9 @@ components:
type: string
description: The total number of approvals.
format: unsignedInteger
isFrozen:
type: boolean
description: Whether the asset is frozen for non-admin transfers. Note, that some runtimes may not have
support for isFrozen and if so the following will be returned `isFrozen does not exist for this runtime`
status:
type: string
description: The status of the asset.
AssetMetadata:
type: object
properties:
Expand Down Expand Up @@ -3291,6 +3437,15 @@ components:
type: number
minJoinBond:
type: number
PalletsPoolAssetsInfo:
type: object
properties:
at:
$ref: '#/components/schemas/BlockIdentifiers'
poolAssetInfo:
$ref: '#/components/schemas/AssetInfo'
poolAssetMetadata:
$ref: '#/components/schemas/AssetMetadata'
PalletStorage:
type: object
properties:
Expand Down
6 changes: 4 additions & 2 deletions src/chains-config/assetHubWestendControllers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2017-2022 Parity Technologies (UK) Ltd.
// Copyright 2017-2023 Parity Technologies (UK) Ltd.
// This file is part of Substrate API Sidecar.
//
// Substrate API Sidecar is free software: you can redistribute it and/or modify
Expand All @@ -18,12 +18,13 @@ import { ControllerConfig } from '../types/chains-config';
import { initLRUCache, QueryFeeDetailsCache } from './cache';

/**
* Asset Hub Polkadot configuration for Sidecar.
* Asset Hub Westend configuration for Sidecar.
*/
export const assetHubWestendControllers: ControllerConfig = {
controllers: [
'AccountsAssets',
'AccountsBalanceInfo',
'AccountsPoolAssets',
'AccountsValidate',
'Blocks',
'BlocksExtrinsics',
Expand All @@ -37,6 +38,7 @@ export const assetHubWestendControllers: ControllerConfig = {
'PalletsConsts',
'PalletsEvents',
'PalletsErrors',
'PalletsPoolAssets',
'RuntimeCode',
'RuntimeMetadata',
'RuntimeSpec',
Expand Down
4 changes: 2 additions & 2 deletions src/controllers/accounts/AccountsAssetsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export default class AccountsAssetsController extends AbstractController<Account

this.safeMountAsyncGetHandlers([
['/asset-balances', this.getAssetBalances],
['/asset-approvals', this.getAssetApproval],
['/asset-approvals', this.getAssetApprovals],
]);
}

Expand All @@ -96,7 +96,7 @@ export default class AccountsAssetsController extends AbstractController<Account
);
};

private getAssetApproval: RequestHandler = async (
private getAssetApprovals: RequestHandler = async (
{ params: { address }, query: { at, delegate, assetId } },
res
): Promise<void> => {
Expand Down
121 changes: 121 additions & 0 deletions src/controllers/accounts/AccountsPoolAssetsController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// Copyright 2017-2023 Parity Technologies (UK) Ltd.
// This file is part of Substrate API Sidecar.
//
// Substrate API Sidecar is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import { ApiPromise } from '@polkadot/api';
import { RequestHandler } from 'express';
import { BadRequest } from 'http-errors';

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

/**
* Get pool asset 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.
* - (Optional for `/accounts/:address/pool-asset-balances`)`assets`
* - (Required for `/accounts/:address/pool-asset-approvals)`assetId` The assetId associated
* with the `AssetApproval`.
* - (Required for `/accounts/:address/pool-asset-approvals)`delegate` The delegate associated
* with the `ApprovalKey` which is tied to a `Approval`. The `ApprovalKey` consists
* of an `owner` which is the `address` path parameter, and a `delegate`.
*
* `/accounts/:address/pool-asset-balances`
* Returns:
* - `at`: Block number and hash at which the call was made.
* - `poolAssets`: An array of `AssetBalance` objects which have a AssetId attached to them
* - `assetId`: The identifier of the asset.
* - `balance`: The balance of the asset.
* - `isFrozen`: Whether the pool asset is frozen for non-admin transfers.
* - `isSufficient`: Whether a non-zero balance of this pool asset is a deposit of sufficient
* value to account for the state bloat associated with its balance storage. If set to
* `true`, then non-zero balances may be stored without a `consumer` reference (and thus
* an ED in the Balances pallet or whatever else is used to control user-account state
* growth).
*
* `/accounts/:address/pool-asset-approvals`
* Returns:
* - `at`: Block number and hash at which the call was made.
* - `amount`: The amount of funds approved for the balance transfer from the owner
* to some delegated target.
* - `deposit`: The amount reserved on the owner's account to hold this item in storage.
*
* Substrate Reference:
* - PoolAssets Pallet: instance of Assets Pallet https://crates.parity.io/pallet_assets/index.html
* - `AssetBalance`: https://crates.parity.io/pallet_assets/struct.AssetBalance.html
* - `ApprovalKey`: https://crates.parity.io/pallet_assets/struct.ApprovalKey.html
* - `Approval`: https://crates.parity.io/pallet_assets/struct.Approval.html
*
*/
export default class AccountsPoolAssetsController extends AbstractController<AccountsPoolAssetsService> {
constructor(api: ApiPromise) {
super(api, '/accounts/:address', new AccountsPoolAssetsService(api));
this.initRoutes();
}

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

this.safeMountAsyncGetHandlers([
['/pool-asset-balances', this.getPoolAssetBalances],
['/pool-asset-approvals', this.getPoolAssetApprovals],
]);
}

private getPoolAssetBalances: RequestHandler = async (
{ params: { address }, query: { at, assets } },
res
): Promise<void> => {
const hash = await this.getHashFromAt(at);

const assetsArray = Array.isArray(assets)
? this.parseQueryParamArrayOrThrow(assets as string[])
: [];

AccountsPoolAssetsController.sanitizedSend(
res,
await this.service.fetchPoolAssetBalances(hash, address, assetsArray)
);
};

private getPoolAssetApprovals: RequestHandler = async (
{ params: { address }, query: { at, delegate, assetId } },
res
): Promise<void> => {
const hash = await this.getHashFromAt(at);

if (typeof delegate !== 'string' || typeof assetId !== 'string') {
throw new BadRequest(
'Must include a `delegate` and `assetId` query param'
);
}

const id = this.parseNumberOrThrow(
assetId,
'`assetId` provided is not a number.'
);

AccountsPoolAssetsController.sanitizedSend(
res,
await this.service.fetchPoolAssetApprovals(hash, address, id, delegate)
);
};
}
3 changes: 2 additions & 1 deletion src/controllers/accounts/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2017-2022 Parity Technologies (UK) Ltd.
// Copyright 2017-2023 Parity Technologies (UK) Ltd.
// This file is part of Substrate API Sidecar.
//
// Substrate API Sidecar is free software: you can redistribute it and/or modify
Expand All @@ -17,6 +17,7 @@
export { default as AccountsAssets } from './AccountsAssetsController';
export { default as AccountsBalanceInfo } from './AccountsBalanceInfoController';
export { default as AccountsConvert } from './AccountsConvertController';
export { default as AccountsPoolAssets } from './AccountsPoolAssetsController';
export { default as AccountsStakingInfo } from './AccountsStakingInfoController';
export { default as AccountsStakingPayouts } from './AccountsStakingPayoutsController';
export { default as AccountsValidate } from './AccountsValidateController';
Expand Down
Loading
Loading