@@ -80,21 +80,6 @@ async function fetchIpfsJson(cidOrUrl: string): Promise<any | null> {
8080 return null ;
8181}
8282
83- const denormalizeMetadata = ( json : any ) : any => {
84- return {
85- metadata : json ,
86- title : typeof json ?. title === "string" ? json . title : null ,
87- description : typeof json ?. description === "string" ? json . description : null ,
88- category : typeof json ?. category === "string" ? json . category : null ,
89- image : typeof json ?. image === "string" ? json . image : null ,
90- contact : typeof json ?. contact === "object" ? json . contact : ( typeof json ?. contact === "string" ? json . contact : null ) ,
91- tags : Array . isArray ( json ?. tags ) ? json . tags : ( typeof json ?. tags === "string" ? json . tags : null ) ,
92- price : typeof json ?. price === "string" || typeof json ?. price === "number" ? String ( json . price ) : null ,
93- currency : typeof json ?. currency === "string" ? json . currency : null ,
94- locationId : typeof json ?. locationId === "string" ? json . locationId : null ,
95- } ;
96- }
97-
9883// Minimal ABI to read listing pointer + data from Marketplace
9984const marketplaceGetListingAbi = [
10085 {
@@ -112,12 +97,6 @@ const marketplaceGetListingAbi = [
11297 } ,
11398] as const ;
11499
115- const erc20MetaAbi = [
116- { name : "name" , type : "function" , stateMutability : "view" , inputs : [ ] , outputs : [ { type : "string" } ] } ,
117- { name : "symbol" , type : "function" , stateMutability : "view" , inputs : [ ] , outputs : [ { type : "string" } ] } ,
118- { name : "decimals" , type : "function" , stateMutability : "view" , inputs : [ ] , outputs : [ { type : "uint8" } ] } ,
119- ] ;
120-
121100function signatureToSelector ( signature : string ) : `0x${string } ` {
122101 const hash = keccak256 ( stringToHex ( signature ) ) ;
123102 return ( `0x${ hash . slice ( 2 , 10 ) } ` ) as `0x${string } `;
@@ -174,6 +153,11 @@ ponder.on("Marketplace:ListingCreated" as any, async ({ event, context }) => {
174153 . set ( { tokenName : "Ether" , tokenSymbol : "ETH" , tokenDecimals : 18 } )
175154 . where ( eq ( listings . id , id ) ) ;
176155 } else {
156+ const erc20MetaAbi = [
157+ { name : "name" , type : "function" , stateMutability : "view" , inputs : [ ] , outputs : [ { type : "string" } ] } ,
158+ { name : "symbol" , type : "function" , stateMutability : "view" , inputs : [ ] , outputs : [ { type : "string" } ] } ,
159+ { name : "decimals" , type : "function" , stateMutability : "view" , inputs : [ ] , outputs : [ { type : "uint8" } ] } ,
160+ ] as const ;
177161 const [ name , symbol , decimals ] = await Promise . all ( [
178162 publicClient . readContract ( { address : pt as `0x${string } `, abi : erc20MetaAbi , functionName : "name" } ) . catch ( ( ) => null ) ,
179163 publicClient . readContract ( { address : pt as `0x${string } `, abi : erc20MetaAbi , functionName : "symbol" } ) . catch ( ( ) => null ) ,
@@ -197,7 +181,19 @@ ponder.on("Marketplace:ListingCreated" as any, async ({ event, context }) => {
197181 try {
198182 const json : any | null = await fetchIpfsJson ( cid ) ;
199183 if ( json ) {
200- const denorm = denormalizeMetadata ( json ) ;
184+ const denorm : any = {
185+ metadata : json ,
186+ // Top-level denormalized fields for convenient querying & UI
187+ title : typeof json ?. title === "string" ? json . title : null ,
188+ description : typeof json ?. description === "string" ? json . description : null ,
189+ category : typeof json ?. category === "string" ? json . category : null ,
190+ image : typeof json ?. image === "string" ? json . image : null ,
191+ contact : typeof json ?. contact === "object" ? json . contact : ( typeof json ?. contact === "string" ? json . contact : null ) ,
192+ tags : Array . isArray ( json ?. tags ) ? json . tags : ( typeof json ?. tags === "string" ? json . tags : null ) ,
193+ price : typeof json ?. price === "string" || typeof json ?. price === "number" ? String ( json . price ) : null ,
194+ currency : typeof json ?. currency === "string" ? json . currency : null ,
195+ locationId : typeof json ?. locationId === "string" ? json . locationId : null ,
196+ } ;
201197 await db . sql . update ( listings ) . set ( denorm ) . where ( eq ( listings . id , id ) ) ;
202198 }
203199 } catch { }
@@ -241,88 +237,7 @@ ponder.on("Marketplace:ListingActivationChanged" as any, async ({ event, context
241237 . where ( eq ( listings . id , args . listingId . toString ( ) ) ) ;
242238} ) ;
243239
244- < < < << << Updated upstream
245- < << << << Updated upstream
246- ponder . on ( "Marketplace:ListingDeleted" as any , async ( { event, context } ) => {
247- const { db } = context ;
248- const args = ( event as any ) . args ;
249- const listingId = args . id . toString ( ) ;
250- await db . sql . delete ( listings ) . where ( eq ( listings . id , listingId ) ) ;
251- } ) ;
252-
253- ponder . on ( "Marketplace:ListingContenthashUpdated" as any , async ( { event, context } ) => {
254- const { db } = context ;
255- const listingId = ( event as any ) . args . id . toString ( ) ;
256- const cid = ( event as any ) . args . contenthash as string ;
257-
258- try {
259- await db . sql . update ( listings ) . set ( { cid } ) . where ( eq ( listings . id , listingId ) ) ;
260- const json : any | null = await fetchIpfsJson ( cid ) ;
261- if ( json ) {
262- const denorm = denormalizeMetadata ( json ) ;
263- await db . sql . update ( listings ) . set ( denorm ) . where ( eq ( listings . id , listingId ) ) ;
264- }
265-
266- try {
267- const mpAddress = ( ( event as any ) . log ?. address as string ) || ( ( event as any ) . transaction ?. to as string ) ;
268- if ( mpAddress ) {
269- const [ , , , , listingData ] = ( await publicClient . readContract ( {
270- address : mpAddress as `0x${string } `,
271- abi : marketplaceGetListingAbi ,
272- functionName : "getListing" ,
273- args : [ BigInt ( listingId ) ] ,
274- } ) ) as unknown as [ string , string , string , boolean , Hex ] ;
275-
276- if ( listingData && ( listingData ) . length > 0 ) {
277- try {
278- const [ paymentToken , price ] = decodeAbiParameters (
279- [ { type : "address" } , { type : "uint256" } ] ,
280- listingData ,
281- ) ;
282- await db . sql
283- . update ( listings )
284- . set ( {
285- paymentToken : paymentToken ?. toLowerCase ?.( ) ?? null ,
286- priceWei : price ?. toString ?.( ) ?? null ,
287- } )
288- . where ( eq ( listings . id , listingId ) ) ;
289-
290- const isEth = ! paymentToken || paymentToken === zeroAddress ;
291- if ( isEth ) {
292- await db . sql
293- . update ( listings )
294- . set ( { tokenName : "Ether" , tokenSymbol : "ETH" , tokenDecimals : 18 } )
295- . where ( eq ( listings . id , listingId ) ) ;
296- } else {
297- const [ name , symbol , decimals ] = await Promise . all ( [
298- publicClient . readContract ( { address : paymentToken as `0x${string } `, abi : erc20MetaAbi , functionName : "name" } ) ,
299- publicClient . readContract ( { address : paymentToken as `0x${string } `, abi : erc20MetaAbi , functionName : "symbol" } ) ,
300- publicClient . readContract ( { address : paymentToken as `0x${string } `, abi : erc20MetaAbi , functionName : "decimals" } ) ,
301- ] ) ;
302- await db . sql
303- . update ( listings )
304- . set ( {
305- tokenName : typeof name === "string" ? name : null ,
306- tokenSymbol : typeof symbol === "string" ? symbol : null ,
307- tokenDecimals : typeof decimals === "number" ? decimals : ( typeof decimals === "bigint" ? Number ( decimals ) : null ) ,
308- } )
309- . where ( eq ( listings . id , listingId ) ) ;
310- }
311- } catch { }
312- }
313- }
314- } catch ( chainErr ) {
315- console . error ( `[Ponder] Error refreshing on-chain listing data for ${ listingId } :` , chainErr ) ;
316- }
317- } catch ( e ) {
318- console . error ( `[Ponder] Error handling ListingContenthashUpdated for ${ listingId } :` , e ) ;
319- }
320- } ) ;
321- === = ===
322- = === = ==
323- > >>> > >> Stashed changes
324240// (No SimpleListings event handlers required)
325- >>> > >>> Stashed changes
326241
327242// --- EAS Reviews indexing ---
328243// Read new per-chain keyed shape only
0 commit comments