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
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ order; the entry is the editorial text of the version's GitHub Release. The 1.7
maintenance line continues in `CHANGELOG.md` on the `release/1.7` branch. This
project follows semantic versioning.

## [2.6.1]

Refuses an integer request parameter above the safe integer range with a 400 response.

### Upgrading

- Image `ghcr.io/atomicassets/atomicassets-api:2.6.1`. The `2.6` and `latest` tags move to it.
- The release has no migration and needs no operator action.

### Bug fixes

- An integer request parameter with a value above `Number.MAX_SAFE_INTEGER` now returns 400. Before, such a value passed the validation of the template mint filters of the asset and market endpoints, the asset count filters of the market endpoints, the supply filters of `/v1/templates`, the `before` and `after` filters, the integer forms of `lower_bound` and `upper_bound`, `page`, and the `limit` of the asset sales history. The database then refused the value, and the request ended with a 500 response and a warn log line.

## [2.6.0]

Adds an effective mint filter and sort to the market listing endpoints, so a client can range over the mint of a bridged asset and of a plain asset with one parameter.
Expand Down
2 changes: 1 addition & 1 deletion src/api/namespaces/atomicassets/handlers/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export async function getAccountsAction(
): Promise<any> { // TODO: Use a proper type here - can't be at the moment different return types
const maxLimit = ctx.coreArgs.limits?.accounts || 5000;
const args = await filterQueryArgs(params, {
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},

match_owner: {type: 'name'},
Expand Down
31 changes: 31 additions & 0 deletions src/api/namespaces/atomicassets/handlers/assets-mint-bound.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'mocha';
import { expect } from 'chai';

import { buildAssetQueryCondition } from './assets';
import QueryBuilder from '../../../builder';

describe('buildAssetQueryCondition - template mint bounds', () => {
const tooLarge = String(Number.MAX_SAFE_INTEGER) + '0';

for (const key of ['template_mint', 'min_template_mint', 'max_template_mint']) {
it(`${key} above the safe integer range is refused as a 400`, async () => {
let error: any = null;

try {
await buildAssetQueryCondition({[key]: tooLarge}, new QueryBuilder('SELECT 1'), {assetTable: 'asset'});
} catch (e) {
error = e;
}

expect(error).to.not.equal(null);
expect(error.code).to.equal(400);
expect(error.message).to.contain(`Invalid value for parameter ${key}`);
});
}

it('template_mint at the safe integer limit is accepted', async () => {
await buildAssetQueryCondition(
{template_mint: String(Number.MAX_SAFE_INTEGER)}, new QueryBuilder('SELECT 1'), {assetTable: 'asset'}
);
});
});
10 changes: 5 additions & 5 deletions src/api/namespaces/atomicassets/handlers/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ export async function buildAssetQueryCondition(
has_backed_tokens: {type: 'bool'},
has_template_buyoffer: {type: 'bool'},

template_mint: {type: 'int', min: 1},
template_mint: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER},

min_template_mint: {type: 'int', min: 1},
max_template_mint: {type: 'int', min: 1},
min_template_mint: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER},
max_template_mint: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER},

template_blacklist: {type: 'list[id]'},
template_whitelist: {type: 'list[id]'}
Expand Down Expand Up @@ -286,7 +286,7 @@ export async function getRawAssetsAction(
const {search, match, ...params} = values;
const maxLimit = ctx.coreArgs.limits?.assets || 1000;
const args = await filterQueryArgs(params, {
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},
sort: {type: 'string', min: 1},
order: {type: 'string', allowedValues: ['asc', 'desc'], default: 'desc'},
Expand Down Expand Up @@ -592,7 +592,7 @@ export async function getAssetLogsAction(params: RequestValues, ctx: AtomicAsset
const maxLimit = ctx.coreArgs.limits?.logs || 100;
const args = await filterQueryArgs({...ctx.pathParams, ...params}, {
asset_id: {type: 'id'},
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},
order: {type: 'string', allowedValues: ['asc', 'desc'], default: 'asc'},
action_whitelist: {type: 'string[]', min: 1},
Expand Down
2 changes: 1 addition & 1 deletion src/api/namespaces/atomicassets/handlers/burns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function burnsQueryNeedsTemplateJoin(params: RequestValues): boolean {
export async function getBurnsAction(params: RequestValues, ctx: AtomicAssetsContext): Promise<any> {
const maxLimit = ctx.coreArgs.limits?.burns || 5000;
const args = await filterQueryArgs(params, {
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},

match_owner: {type: 'name'},
Expand Down
4 changes: 2 additions & 2 deletions src/api/namespaces/atomicassets/handlers/collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { filterQueryArgs } from '../../validation';
export async function getCollectionsAction(params: RequestValues, ctx: AtomicAssetsContext): Promise<any> {
const maxLimit = ctx.coreArgs.limits?.collections || 1000;
const args = await filterQueryArgs(params, {
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},
sort: {type: 'string', allowedValues: ['created', 'collection_name'], default: 'created'},
order: {type: 'string', allowedValues: ['asc', 'desc'], default: 'desc'},
Expand Down Expand Up @@ -146,7 +146,7 @@ export async function getCollectionSchemasAction(params: RequestValues, ctx: Ato
export async function getCollectionLogsAction(params: RequestValues, ctx: AtomicAssetsContext): Promise<any> {
const maxLimit = ctx.coreArgs.limits?.logs || 100;
const args = await filterQueryArgs(params, {
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},
order: {type: 'string', allowedValues: ['asc', 'desc'], default: 'asc'},
action_whitelist: {type: 'string[]', min: 1},
Expand Down
4 changes: 2 additions & 2 deletions src/api/namespaces/atomicassets/handlers/offers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { filterQueryArgs } from '../../validation';
export async function getRawOffersAction(params: RequestValues, ctx: AtomicAssetsContext): Promise<any> {
const maxLimit = ctx.coreArgs.limits?.offers || 100;
const args = await filterQueryArgs(params, {
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},
sort: {type: 'string', allowedValues: ['created', 'updated'], default: 'created'},
order: {type: 'string', allowedValues: ['asc', 'desc'], default: 'desc'},
Expand Down Expand Up @@ -224,7 +224,7 @@ export async function getOfferLogsCountAction(params: RequestValues, ctx: Atomic
const maxLimit = ctx.coreArgs.limits?.logs || 100;
const args = await filterQueryArgs({...ctx.pathParams, ...params}, {
offer_id: {type: 'id'},
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},
order: {type: 'string', allowedValues: ['asc', 'desc'], default: 'asc'},
action_whitelist: {type: 'string[]', min: 1},
Expand Down
4 changes: 2 additions & 2 deletions src/api/namespaces/atomicassets/handlers/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { filterQueryArgs } from '../../validation';
export async function getSchemasAction(params: RequestValues, ctx: AtomicAssetsContext): Promise<any> {
const maxLimit = ctx.coreArgs.limits?.schemas || 1000;
const args = await filterQueryArgs(params, {
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},
sort: {type: 'string', allowedValues: ['created', 'schema_name', 'assets'], default: 'created'},
order: {type: 'string', allowedValues: ['asc', 'desc'], default: 'desc'},
Expand Down Expand Up @@ -121,7 +121,7 @@ export async function getSchemaStatsAction(params: RequestValues, ctx: AtomicAss
export async function getSchemaLogsAction(params: RequestValues, ctx: AtomicAssetsContext): Promise<any> {
const maxLimit = ctx.coreArgs.limits?.logs || 100;
const args = await filterQueryArgs(params, {
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},
order: {type: 'string', allowedValues: ['asc', 'desc'], default: 'asc'},
action_whitelist: {type: 'string[]', min: 1},
Expand Down
12 changes: 6 additions & 6 deletions src/api/namespaces/atomicassets/handlers/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { filterQueryArgs } from '../../validation';
export async function getTemplatesAction(params: RequestValues, ctx: AtomicAssetsContext): Promise<any> {
const maxLimit = ctx.coreArgs.limits?.templates || 1000;
const args = await filterQueryArgs(params, {
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},
sort: {type: 'string', allowedValues: ['created', 'name'], default: 'created'},
order: {type: 'string', allowedValues: ['asc', 'desc'], default: 'desc'},
Expand All @@ -19,13 +19,13 @@ export async function getTemplatesAction(params: RequestValues, ctx: AtomicAsset
schema_name: {type: 'list[name]'},
authorized_account: {type: 'name'},

issued_supply: {type: 'int', min: 0},
min_issued_supply: {type: 'int', min: 0},
max_issued_supply: {type: 'int', min: 0},
issued_supply: {type: 'int', min: 0, max: Number.MAX_SAFE_INTEGER},
min_issued_supply: {type: 'int', min: 0, max: Number.MAX_SAFE_INTEGER},
max_issued_supply: {type: 'int', min: 0, max: Number.MAX_SAFE_INTEGER},
has_assets: {type: 'bool'},
include_deleted: {type: 'bool'},

max_supply: {type: 'int', min: 0},
max_supply: {type: 'int', min: 0, max: Number.MAX_SAFE_INTEGER},
is_transferable: {type: 'bool'},
is_burnable: {type: 'bool'},

Expand Down Expand Up @@ -186,7 +186,7 @@ export async function getTemplateLogsAction(params: RequestValues, ctx: AtomicAs
const maxLimit = ctx.coreArgs.limits?.logs || 100;
const args = await filterQueryArgs({...ctx.pathParams, ...params}, {
template_id: {type: 'id'},
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},
order: {type: 'string', allowedValues: ['asc', 'desc'], default: 'asc'},
action_whitelist: {type: 'string[]', min: 1},
Expand Down
2 changes: 1 addition & 1 deletion src/api/namespaces/atomicassets/handlers/transfers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ApiError } from '../../../error';
export async function getRawTransfersAction(params: RequestValues, ctx: AtomicAssetsContext): Promise<any> {
const maxLimit = ctx.coreArgs.limits?.transfers || 100;
const args = await filterQueryArgs(params, {
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},
sort: {type: 'string', allowedValues: ['created'], default: 'created'},
order: {type: 'string', allowedValues: ['asc', 'desc'], default: 'desc'},
Expand Down
4 changes: 2 additions & 2 deletions src/api/namespaces/atomicmarket/handlers/auctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {filterQueryArgs} from '../../validation';
export async function getAuctionsAction(params: RequestValues, ctx: AtomicMarketContext): Promise<any> {
const maxLimit = ctx.coreArgs.limits?.auctions || 100;
const args = await filterQueryArgs(params, {
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},
sort: {
type: 'string',
Expand Down Expand Up @@ -139,7 +139,7 @@ export async function getAuctionLogsAction(params: RequestValues, ctx: AtomicMar
const maxLimit = ctx.coreArgs.limits?.logs || 100;
const args = await filterQueryArgs({...ctx.pathParams, ...params}, {
auction_id: {type: 'id'},
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},
order: {type: 'string', allowedValues: ['asc', 'desc'], default: 'asc'},
action_whitelist: {type: 'string[]', min: 1},
Expand Down
4 changes: 2 additions & 2 deletions src/api/namespaces/atomicmarket/handlers/buyoffers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { filterQueryArgs } from '../../validation';
export async function getBuyOffersAction(params: RequestValues, ctx: AtomicMarketContext): Promise<any> {
const maxLimit = ctx.coreArgs.limits?.buyoffers || 100;
const args = await filterQueryArgs(params, {
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},
sort: {
type: 'string',
Expand Down Expand Up @@ -143,7 +143,7 @@ export async function getBuyOfferLogsAction(params: RequestValues, ctx: AtomicMa
const maxLimit = ctx.coreArgs.limits?.logs || 100;
const args = await filterQueryArgs({...ctx.pathParams, ...params}, {
buyoffer_id: {type: 'id'},
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},
order: {type: 'string', allowedValues: ['asc', 'desc'], default: 'asc'},
action_whitelist: {type: 'string[]', min: 1},
Expand Down
8 changes: 4 additions & 4 deletions src/api/namespaces/atomicmarket/handlers/prices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export async function getAssetSalesAction(params: RequestValues, ctx: AtomicMark
seller: {type: 'list[name]'},
buyer: {type: 'list[name]'},
symbol: {type: 'string', min: 1},
limit: {type: 'int', min: 1, default: 100},
limit: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 100},
order: {type: 'string', allowedValues: ['asc', 'desc'], default: 'desc'},
bundles: {type: 'bool'}
});
Expand Down Expand Up @@ -145,8 +145,8 @@ export async function getPricesSalesDaysAction(params: RequestValues, ctx: Atomi
schema_name: {type: 'list[name]'},
asset_id: {type: 'list[id]'},
symbol: {type: 'string', min: 1},
after: {type: 'int', min: 1},
before: {type: 'int', min: 1}
after: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER},
before: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER}
});

const query = new QueryBuilder(`
Expand Down Expand Up @@ -219,7 +219,7 @@ export async function getPricesTemplatesAction(params: RequestValues, ctx: Atomi
schema_name: {type: 'list[name]'},
symbol: {type: 'string', min: 1},

page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},
});

Expand Down
12 changes: 6 additions & 6 deletions src/api/namespaces/atomicmarket/handlers/royalties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export async function getRoyaltyTemplateRulesAction(params: RequestValues, ctx:
const args = await filterQueryArgs(params, {
template_id: { type: 'list[id]' },

page: { type: 'int', min: 1, default: 1 },
page: { type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1 },
limit: { type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100) },
});

Expand All @@ -97,10 +97,10 @@ export async function getRoyaltyTemplateRulesAction(params: RequestValues, ctx:
export async function getRoyaltyAttributeRulesAction(params: RequestValues, ctx: AtomicMarketContext): Promise<any> {
const maxLimit = ctx.coreArgs.limits?.royalties || 100;
const args = await filterQueryArgs(params, {
source: { type: 'int', min: 0 },
source: { type: 'int', min: 0, max: Number.MAX_SAFE_INTEGER },
field: { type: 'string', min: 1 },

page: { type: 'int', min: 1, default: 1 },
page: { type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1 },
limit: { type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100) },
});

Expand Down Expand Up @@ -142,7 +142,7 @@ export async function getRoyaltyPayoutsAction(params: RequestValues, ctx: Atomic
listing_id: { type: 'id' },
category: { type: 'list[string]', allowedValues: Object.keys(PAYOUT_CATEGORY_BY_NAME) },

page: { type: 'int', min: 1, default: 1 },
page: { type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1 },
limit: { type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100) },
sort: { type: 'string', allowedValues: ['created', 'amount'], default: 'created' },
order: { type: 'string', allowedValues: ['asc', 'desc'], default: 'desc' },
Expand Down Expand Up @@ -229,8 +229,8 @@ export async function getRoyaltyAccountAction(params: RequestValues, ctx: Atomic
const args = await filterQueryArgs(params, {
collection_name: { type: 'list[name]' },
symbol: { type: 'string', min: 1 },
before: { type: 'int', min: 1 },
after: { type: 'int', min: 1 },
before: { type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER },
after: { type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER },
});

const query = new QueryBuilder(`
Expand Down
4 changes: 2 additions & 2 deletions src/api/namespaces/atomicmarket/handlers/sales.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export async function getSaleLogsAction(params: RequestValues, ctx: AtomicMarket
const maxLimit = ctx.coreArgs.limits?.logs || 100;
const args = await filterQueryArgs({...ctx.pathParams, ...params}, {
sale_id: {type: 'id'},
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},
order: {type: 'string', allowedValues: ['asc', 'desc'], default: 'asc'},
action_whitelist: {type: 'string[]', min: 1},
Expand All @@ -55,7 +55,7 @@ export async function getSaleLogsAction(params: RequestValues, ctx: AtomicMarket
export async function getSalesAction(params: RequestValues, ctx: AtomicMarketContext): Promise<any> {
const maxLimit = ctx.coreArgs.limits?.sales || 100;
const args = await filterQueryArgs(params, {
page: {type: 'int', min: 1, default: 1},
page: {type: 'int', min: 1, max: Number.MAX_SAFE_INTEGER, default: 1},
limit: {type: 'int', min: 1, max: maxLimit, default: Math.min(maxLimit, 100)},
collection_name: {type: 'list[name]'},
state: {type: 'string', min: 1},
Expand Down
Loading
Loading