chore!: remove deprecated /nft_events endpoint (#1329)

* fix: remove deprecated /nft_events endpoint

* chore: remove endpoint from openapi
This commit is contained in:
Rafael Cárdenas
2022-09-28 12:34:59 -05:00
committed by GitHub
parent 465aa0b42c
commit 65bb4e55fa
6 changed files with 0 additions and 429 deletions

View File

@@ -1,13 +0,0 @@
{
"limit": 20,
"offset": 0,
"total": 1,
"nft_events": [
{
"sender": "none",
"recipient": "ST1HB64MAJ1MBV4CQ80GF01DZS4T1DSMX20ADCRA4",
"asset_identifier": "some-asset",
"value": { "hex": "0x00", "repr": "0" }
}
]
}

View File

@@ -1,28 +0,0 @@
{
"type": "object",
"title": "AddressNftListResponse",
"additionalProperties": false,
"required": [
"limit",
"offset",
"total",
"nft_events"
],
"properties": {
"limit": {
"type": "integer"
},
"offset": {
"type": "integer"
},
"total": {
"type": "integer"
},
"nft_events": {
"type": "array",
"items": {
"$ref": "../../entities/nft-events/nft-event.schema.json"
}
}
}
}

View File

@@ -1643,63 +1643,6 @@ paths:
example:
$ref: ./api/address/get-address-stx-inbound.example.json
/extended/v1/address/{principal}/nft_events:
get:
summary: Get nft events
deprecated: true
description: |
**NOTE:** This endpoint is deprecated in favor of [Non-Fungible Token holdings](#operation/get_nft_holdings).
Retrieves a list of all nfts owned by an address, contains the clarity value of the identifier of the nft.
tags:
- Accounts
operationId: get_account_nft
parameters:
- name: principal
in: path
description: Stacks address or a Contract identifier
required: true
schema:
type: string
example: "SP31DA6FTSJX2WGTZ69SFY11BH51NZMB0ZW97B5P0"
- name: limit
in: query
description: number of items to return
required: false
schema:
type: integer
- name: offset
in: query
description: number of items to skip
required: false
schema:
type: integer
example: 42000
- name: unanchored
in: query
description: Include transaction data from unanchored (i.e. unconfirmed) microblocks
required: false
schema:
type: boolean
example: true
default: false
- name: until_block
in: query
description: returned data representing the state up until that point in time, rather than the current block. Note - Use either of the query parameters but not both at a time.
required: false
schema:
type: string
example: 60000
responses:
200:
description: Success
content:
application/json:
schema:
$ref: ./api/address/get-address-nft-events.schema.json
example:
$ref: ./api/address/get-address-nft-events.example.json
/v2/accounts/{principal}:
get:
summary: Get account info

View File

@@ -476,59 +476,6 @@ export function createAddressRouter(db: PgStore, chainId: ChainID): express.Rout
})
);
/**
* @deprecated Use `/extended/v1/tokens/nft/holdings` instead.
*/
router.get(
'/:stx_address/nft_events',
cacheHandler,
asyncHandler(async (req, res, next) => {
// get recent asset event associated with address
const stxAddress = req.params['stx_address'];
validatePrincipal(stxAddress);
const untilBlock = parseUntilBlockQuery(req, res, next);
const blockHeight = await getBlockHeight(untilBlock, req, res, next, db);
const limit = parseAssetsQueryLimit(req.query.limit ?? 20);
const offset = parsePagingQueryInput(req.query.offset ?? 0);
const includeUnanchored = isUnanchoredRequest(req, res, next);
const response = await db.getAddressNFTEvent({
stxAddress,
limit,
offset,
blockHeight,
includeUnanchored,
});
const nft_events = response.results.map(row => {
const parsedClarityValue = decodeClarityValueToRepr(row.value);
const r: NftEvent = {
sender: row.sender,
recipient: row.recipient,
asset_identifier: row.asset_identifier,
value: {
hex: row.value,
repr: parsedClarityValue,
},
tx_id: row.tx_id,
block_height: row.block_height,
event_index: row.event_index,
asset_event_type: getAssetEventTypeString(row.asset_event_type_id),
tx_index: row.tx_index,
};
return r;
});
const nftListResponse: AddressNftListResponse = {
nft_events: nft_events,
total: response.total,
limit: limit,
offset: offset,
};
setETagCacheHeaders(res);
res.json(nftListResponse);
})
);
router.get(
'/:address/mempool',
mempoolCacheHandler,

View File

@@ -3066,56 +3066,6 @@ export class PgStore {
return { found: true, result: result[0] } as const;
}
/**
* @deprecated Use `getNftHoldings` instead.
*/
async getAddressNFTEvent(args: {
stxAddress: string;
limit: number;
offset: number;
blockHeight: number;
includeUnanchored: boolean;
}): Promise<{ results: AddressNftEventIdentifier[]; total: number }> {
// Join against `nft_custody` materialized view only if we're looking for canonical results.
const result = await this.sql<(AddressNftEventIdentifier & { count: number })[]>`
WITH address_transfers AS (
SELECT asset_identifier, value, sender, recipient, block_height, microblock_sequence, tx_index, event_index, tx_id, asset_event_type_id
FROM nft_events
WHERE canonical = true AND microblock_canonical = true
AND recipient = ${args.stxAddress} AND block_height <= ${args.blockHeight}
),
last_nft_transfers AS (
SELECT DISTINCT ON(asset_identifier, value) asset_identifier, value, recipient
FROM nft_events
WHERE canonical = true AND microblock_canonical = true
AND block_height <= ${args.blockHeight}
ORDER BY asset_identifier, value, block_height DESC, microblock_sequence DESC, tx_index DESC, event_index DESC
)
SELECT sender, recipient, asset_identifier, value, event_index, asset_event_type_id, address_transfers.block_height, address_transfers.tx_id, (COUNT(*) OVER())::INTEGER AS count
FROM address_transfers
INNER JOIN ${args.includeUnanchored ? this.sql`last_nft_transfers` : this.sql`nft_custody`}
USING (asset_identifier, value, recipient)
ORDER BY block_height DESC, microblock_sequence DESC, tx_index DESC, event_index DESC
LIMIT ${args.limit} OFFSET ${args.offset}
`;
const count = result.length > 0 ? result[0].count : 0;
const nftEvents = result.map(row => ({
sender: row.sender,
recipient: row.recipient,
asset_identifier: row.asset_identifier,
value: row.value,
block_height: row.block_height,
tx_id: row.tx_id,
event_index: row.event_index,
asset_event_type_id: row.asset_event_type_id,
tx_index: row.tx_index,
}));
return { results: nftEvents, total: count };
}
async getTxListDetails({
txIds,
includeUnanchored,

View File

@@ -2235,7 +2235,6 @@ describe('address tests', () => {
'/transactions_with_transfers',
'/assets',
'/stx_inbound',
'/nft_events',
];
//check for mutually exclusive unachored and and until_block
@@ -2257,233 +2256,6 @@ describe('address tests', () => {
}
});
test('Success: nft events for address', async () => {
const addr1 = 'ST3J8EVYHVKH6XXPD61EE8XEHW4Y2K83861225AB1';
const addr2 = 'ST1HB64MAJ1MBV4CQ80GF01DZS4T1DSMX20ADCRA4';
const dbBlock: DbBlock = {
block_hash: '0xff',
index_block_hash: '0x1234',
parent_index_block_hash: '0x5678',
parent_block_hash: '0x5678',
parent_microblock_hash: '',
parent_microblock_sequence: 0,
block_height: 1,
burn_block_time: 1594647995,
burn_block_hash: '0x1234',
burn_block_height: 123,
miner_txid: '0x4321',
canonical: true,
execution_cost_read_count: 0,
execution_cost_read_length: 0,
execution_cost_runtime: 0,
execution_cost_write_count: 0,
execution_cost_write_length: 0,
};
const stxTx: DbTx = {
tx_id: '0x1111000000000000000000000000000000000000000000000000000000000000',
tx_index: 0,
anchor_mode: 3,
nonce: 0,
raw_tx: '0x',
index_block_hash: dbBlock.index_block_hash,
block_hash: dbBlock.block_hash,
block_height: dbBlock.block_height,
burn_block_time: dbBlock.burn_block_time,
parent_burn_block_time: 1626122935,
type_id: DbTxTypeId.TokenTransfer,
token_transfer_amount: 1n,
token_transfer_memo: bufferToHexPrefixString(Buffer.from('hi')),
token_transfer_recipient_address: 'none',
status: 1,
raw_result: '0x0100000000000000000000000000000001', // u1
canonical: true,
microblock_canonical: true,
microblock_sequence: I32_MAX,
microblock_hash: '',
parent_index_block_hash: dbBlock.parent_index_block_hash,
parent_block_hash: dbBlock.parent_block_hash,
post_conditions: '0x01f5',
fee_rate: 1234n,
sponsored: false,
sponsor_address: undefined,
sender_address: addr1,
origin_hash_mode: 1,
event_count: 10,
execution_cost_read_count: 0,
execution_cost_read_length: 0,
execution_cost_runtime: 0,
execution_cost_write_count: 0,
execution_cost_write_length: 0,
};
const nftEvents: DbNftEvent[] = [];
for (let i = 0; i < 10; i++) {
nftEvents.push({
canonical: true,
event_type: DbEventTypeId.NonFungibleTokenAsset,
asset_event_type_id: DbAssetEventTypeId.Transfer,
event_index: 0,
tx_id: stxTx.tx_id,
tx_index: 1,
block_height: dbBlock.block_height,
asset_identifier: 'some-asset',
value: '0x0000000000000000000000000000000000',
recipient: addr1,
sender: 'none',
});
}
await db.update({
block: dbBlock,
microblocks: [],
minerRewards: [],
txs: [
{
tx: stxTx,
stxLockEvents: [],
stxEvents: [],
ftEvents: [],
nftEvents: nftEvents,
contractLogEvents: [],
smartContracts: [],
names: [],
namespaces: [],
},
],
});
const limit = 2;
const offset = 0;
// test nft for given addresses
const result = await supertest(api.server).get(
`/extended/v1/address/${addr1}/nft_events?limit=${limit}&offset=${offset}`
);
expect(result.status).toBe(200);
expect(result.type).toBe('application/json');
expect(result.body.total).toEqual(10);
expect(result.body.nft_events.length).toEqual(2);
expect(result.body.nft_events[0].recipient).toBe(addr1);
expect(result.body.nft_events[0].tx_id).toBe(
'0x1111000000000000000000000000000000000000000000000000000000000000'
);
expect(result.body.nft_events[0].block_height).toBe(1);
expect(result.body.nft_events[0].value.repr).toBe('0');
const dbBlock2: DbBlock = {
block_hash: '0xffff',
index_block_hash: '0x123466',
parent_index_block_hash: '0x1234',
parent_block_hash: '0xff',
parent_microblock_hash: '',
parent_microblock_sequence: 0,
block_height: 2,
burn_block_time: 1594649995,
burn_block_hash: '0x123456',
burn_block_height: 124,
miner_txid: '0x4321',
canonical: true,
execution_cost_read_count: 0,
execution_cost_read_length: 0,
execution_cost_runtime: 0,
execution_cost_write_count: 0,
execution_cost_write_length: 0,
};
const stxTx1: DbTx = {
tx_id: '0x1111100000000000000000000000000000000000000000000000000000000001',
tx_index: 0,
anchor_mode: 3,
nonce: 0,
raw_tx: '0x',
index_block_hash: dbBlock2.index_block_hash,
block_hash: dbBlock2.block_hash,
block_height: dbBlock2.block_height,
burn_block_time: dbBlock2.burn_block_time,
parent_burn_block_time: 1626124935,
type_id: DbTxTypeId.TokenTransfer,
token_transfer_amount: 1n,
token_transfer_memo: bufferToHexPrefixString(Buffer.from('hi')),
token_transfer_recipient_address: 'none',
status: 1,
raw_result: '0x0100000000000000000000000000000001', // u1
canonical: true,
microblock_canonical: true,
microblock_sequence: I32_MAX,
microblock_hash: '',
parent_index_block_hash: dbBlock2.parent_index_block_hash,
parent_block_hash: dbBlock2.parent_block_hash,
post_conditions: '0x01f5',
fee_rate: 1234n,
sponsored: false,
sponsor_address: undefined,
sender_address: addr2,
origin_hash_mode: 1,
event_count: 1,
execution_cost_read_count: 0,
execution_cost_read_length: 0,
execution_cost_runtime: 0,
execution_cost_write_count: 0,
execution_cost_write_length: 0,
};
const nftEvent2: DbNftEvent = {
canonical: true,
event_type: DbEventTypeId.NonFungibleTokenAsset,
asset_event_type_id: DbAssetEventTypeId.Transfer,
event_index: 1,
tx_id: stxTx1.tx_id,
tx_index: 2,
block_height: dbBlock2.block_height,
asset_identifier: 'some-asset',
value: '0x0000000000000000000000000000000000',
recipient: addr2,
sender: 'none',
};
await db.update({
block: dbBlock2,
microblocks: [],
minerRewards: [],
txs: [
{
tx: stxTx1,
stxLockEvents: [],
stxEvents: [],
ftEvents: [],
nftEvents: [nftEvent2],
contractLogEvents: [],
smartContracts: [],
names: [],
namespaces: [],
},
],
});
const result1 = await supertest(api.server).get(`/extended/v1/address/${addr2}/nft_events`);
expect(result1.status).toBe(200);
expect(result1.type).toBe('application/json');
expect(result1.body.total).toEqual(1);
expect(result1.body.nft_events.length).toEqual(1);
expect(result1.body.nft_events[0].recipient).toBe(addr2);
expect(result1.body.nft_events[0].tx_id).toBe(
'0x1111100000000000000000000000000000000000000000000000000000000001'
);
expect(result1.body.nft_events[0].block_height).toBe(2);
expect(result.body.nft_events[0].value.repr).toBe('0');
//check ownership for addr
const result2 = await supertest(api.server).get(`/extended/v1/address/${addr1}/nft_events`);
expect(result2.status).toBe(200);
expect(result2.type).toBe('application/json');
expect(result2.body.nft_events.length).toEqual(0);
expect(result2.body.total).toEqual(0);
});
test('nft invalid address', async () => {
const result = await supertest(api.server).get(
`/extended/v1/address/invalid-address/nft_events`
);
expect(result.status).toBe(400);
expect(result.type).toBe('application/json');
});
test('/transactions materialized view separates anchored and unanchored counts correctly', async () => {
const contractId = 'SP3D6PV2ACBPEKYJTCMH7HEN02KP87QSP8KTEH335.megapont-ape-club-nft';