From c75d88dad35266231d6e9872c3679e8ca4768bcc Mon Sep 17 00:00:00 2001 From: Enzo Cioppettini Date: Fri, 15 Mar 2024 17:48:59 -0300 Subject: [PATCH] erc721 cde: keep track of the address that burnt the asset --- .../paima-sm/src/cde-erc721-transfer.ts | 20 +++++- packages/node-sdk/paima-db/migrations/up.sql | 7 +++ .../node-sdk/paima-db/src/paima-tables.ts | 22 +++++++ .../paima-db/src/sql/cde-erc721.queries.ts | 63 +++++++++++++++++++ .../node-sdk/paima-db/src/sql/cde-erc721.sql | 17 +++++ 5 files changed, 127 insertions(+), 2 deletions(-) diff --git a/packages/engine/paima-sm/src/cde-erc721-transfer.ts b/packages/engine/paima-sm/src/cde-erc721-transfer.ts index 6426033fd..e93780fb0 100644 --- a/packages/engine/paima-sm/src/cde-erc721-transfer.ts +++ b/packages/engine/paima-sm/src/cde-erc721-transfer.ts @@ -2,7 +2,13 @@ import type { PoolClient } from 'pg'; import { doLog } from '@paima/utils'; import type { CdeErc721TransferDatum } from './types.js'; -import { cdeErc721GetOwner, cdeErc721InsertOwner, cdeErc721UpdateOwner } from '@paima/db'; +import { + cdeErc721BurnInsert, + cdeErc721Delete, + cdeErc721GetOwner, + cdeErc721InsertOwner, + cdeErc721UpdateOwner, +} from '@paima/db'; import type { SQLUpdate } from '@paima/db'; export default async function processErc721Datum( @@ -13,6 +19,8 @@ export default async function processErc721Datum( const { to, tokenId } = cdeDatum.payload; const toAddr = to.toLowerCase(); + const isBurn = Boolean(toAddr.match(/^0x0+$/g)); + const updateList: SQLUpdate[] = []; try { const ownerRow = await cdeErc721GetOwner.run( @@ -21,7 +29,15 @@ export default async function processErc721Datum( ); const newOwnerData = { cde_id: cdeId, token_id: tokenId, nft_owner: toAddr }; if (ownerRow.length > 0) { - updateList.push([cdeErc721UpdateOwner, newOwnerData]); + if (isBurn) { + updateList.push([ + cdeErc721BurnInsert, + { cde_id: cdeId, token_id: tokenId, nft_owner: ownerRow[0].nft_owner }, + ]); + updateList.push([cdeErc721Delete, { cde_id: cdeId, token_id: tokenId }]); + } else { + updateList.push([cdeErc721UpdateOwner, newOwnerData]); + } } else { updateList.push([cdeErc721InsertOwner, newOwnerData]); } diff --git a/packages/node-sdk/paima-db/migrations/up.sql b/packages/node-sdk/paima-db/migrations/up.sql index a8e56d7db..c0626e05a 100644 --- a/packages/node-sdk/paima-db/migrations/up.sql +++ b/packages/node-sdk/paima-db/migrations/up.sql @@ -56,6 +56,13 @@ CREATE TABLE cde_erc721_data ( PRIMARY KEY (cde_id, token_id) ); +CREATE TABLE cde_erc721_burn ( + cde_id INTEGER NOT NULL, + token_id TEXT NOT NULL, + nft_owner TEXT NOT NULL, + PRIMARY KEY(cde_id, token_id) +); + CREATE TABLE cde_erc20_deposit_data ( cde_id INTEGER NOT NULL, wallet_address TEXT NOT NULL, diff --git a/packages/node-sdk/paima-db/src/paima-tables.ts b/packages/node-sdk/paima-db/src/paima-tables.ts index 9de21e073..b8f18afd5 100644 --- a/packages/node-sdk/paima-db/src/paima-tables.ts +++ b/packages/node-sdk/paima-db/src/paima-tables.ts @@ -186,6 +186,27 @@ const TABLE_DATA_CDE_ERC721: TableData = { creationQuery: QUERY_CREATE_TABLE_CDE_ERC721, }; +const QUERY_CREATE_TABLE_CDE_ERC721_BURN = ` +CREATE TABLE cde_erc721_burn ( + cde_id INTEGER NOT NULL, + token_id TEXT NOT NULL, + nft_owner TEXT NOT NULL, + PRIMARY KEY (cde_id, token_id) +); +`; + +const TABLE_DATA_CDE_ERC721_BURN: TableData = { + tableName: 'cde_erc721_data_burn', + primaryKeyColumns: ['cde_id', 'token_id'], + columnData: packTuples([ + ['cde_id', 'integer', 'NO', ''], + ['token_id', 'text', 'NO', ''], + ['nft_owner', 'text', 'NO', ''], + ]), + serialColumns: [], + creationQuery: QUERY_CREATE_TABLE_CDE_ERC721_BURN, +}; + const QUERY_CREATE_TABLE_CDE_ERC20_DEPOSIT = ` CREATE TABLE cde_erc20_deposit_data ( cde_id INTEGER NOT NULL, @@ -510,6 +531,7 @@ export const TABLES: TableData[] = [ TABLE_DATA_CDE, TABLE_DATA_CDE_ERC20, TABLE_DATA_CDE_ERC721, + TABLE_DATA_CDE_ERC721_BURN, TABLE_DATA_CDE_ERC20_DEPOSIT, TABLE_DATA_CDE_GENERIC_DATA, TABLE_DATA_CDE_ERC6551_REGISTRY, diff --git a/packages/node-sdk/paima-db/src/sql/cde-erc721.queries.ts b/packages/node-sdk/paima-db/src/sql/cde-erc721.queries.ts index ee6b5c24b..7ac457148 100644 --- a/packages/node-sdk/paima-db/src/sql/cde-erc721.queries.ts +++ b/packages/node-sdk/paima-db/src/sql/cde-erc721.queries.ts @@ -161,3 +161,66 @@ const cdeErc721GetAllOwnedNftsIR: any = {"usedParamSet":{"nft_owner":true},"para export const cdeErc721GetAllOwnedNfts = new PreparedQuery(cdeErc721GetAllOwnedNftsIR); +/** 'CdeErc721Delete' parameters type */ +export interface ICdeErc721DeleteParams { + cde_id: number; + token_id: string; +} + +/** 'CdeErc721Delete' return type */ +export type ICdeErc721DeleteResult = void; + +/** 'CdeErc721Delete' query type */ +export interface ICdeErc721DeleteQuery { + params: ICdeErc721DeleteParams; + result: ICdeErc721DeleteResult; +} + +const cdeErc721DeleteIR: any = {"usedParamSet":{"cde_id":true,"token_id":true},"params":[{"name":"cde_id","required":true,"transform":{"type":"scalar"},"locs":[{"a":43,"b":50}]},{"name":"token_id","required":true,"transform":{"type":"scalar"},"locs":[{"a":67,"b":76}]}],"statement":"DELETE FROM cde_erc721_data\nWHERE cde_id = :cde_id!\nAND token_id = :token_id!"}; + +/** + * Query generated from SQL: + * ``` + * DELETE FROM cde_erc721_data + * WHERE cde_id = :cde_id! + * AND token_id = :token_id! + * ``` + */ +export const cdeErc721Delete = new PreparedQuery(cdeErc721DeleteIR); + + +/** 'CdeErc721BurnInsert' parameters type */ +export interface ICdeErc721BurnInsertParams { + cde_id: number; + nft_owner: string; + token_id: string; +} + +/** 'CdeErc721BurnInsert' return type */ +export type ICdeErc721BurnInsertResult = void; + +/** 'CdeErc721BurnInsert' query type */ +export interface ICdeErc721BurnInsertQuery { + params: ICdeErc721BurnInsertParams; + result: ICdeErc721BurnInsertResult; +} + +const cdeErc721BurnInsertIR: any = {"usedParamSet":{"cde_id":true,"token_id":true,"nft_owner":true},"params":[{"name":"cde_id","required":true,"transform":{"type":"scalar"},"locs":[{"a":84,"b":91}]},{"name":"token_id","required":true,"transform":{"type":"scalar"},"locs":[{"a":98,"b":107}]},{"name":"nft_owner","required":true,"transform":{"type":"scalar"},"locs":[{"a":114,"b":124}]}],"statement":"INSERT INTO cde_erc721_burn(\n cde_id,\n token_id,\n nft_owner\n) VALUES (\n :cde_id!,\n :token_id!,\n :nft_owner!\n)"}; + +/** + * Query generated from SQL: + * ``` + * INSERT INTO cde_erc721_burn( + * cde_id, + * token_id, + * nft_owner + * ) VALUES ( + * :cde_id!, + * :token_id!, + * :nft_owner! + * ) + * ``` + */ +export const cdeErc721BurnInsert = new PreparedQuery(cdeErc721BurnInsertIR); + + diff --git a/packages/node-sdk/paima-db/src/sql/cde-erc721.sql b/packages/node-sdk/paima-db/src/sql/cde-erc721.sql index b6e499cf7..1ef646f3a 100644 --- a/packages/node-sdk/paima-db/src/sql/cde-erc721.sql +++ b/packages/node-sdk/paima-db/src/sql/cde-erc721.sql @@ -30,3 +30,20 @@ AND token_id = :token_id!; SELECT cde_name, token_id FROM cde_erc721_data JOIN chain_data_extensions ON chain_data_extensions.cde_id = cde_erc721_data.cde_id WHERE nft_owner = :nft_owner!; + + +/* @name cdeErc721Delete */ +DELETE FROM cde_erc721_data +WHERE cde_id = :cde_id! +AND token_id = :token_id!; + +/* @name cdeErc721BurnInsert */ +INSERT INTO cde_erc721_burn( + cde_id, + token_id, + nft_owner +) VALUES ( + :cde_id!, + :token_id!, + :nft_owner! +); \ No newline at end of file