diff --git a/frontend/src/lib/contracts.test.ts b/frontend/src/lib/contracts.test.ts index 9f27589..9ed6083 100644 --- a/frontend/src/lib/contracts.test.ts +++ b/frontend/src/lib/contracts.test.ts @@ -1,7 +1,21 @@ -import { parseUserProfile, parseBotNFT, parseListing } from "./contracts"; +import { parseListing, parseUserProfile, parseBotNFT } from "./contracts"; describe("parse helpers in contracts.ts", () => { describe("parseUserProfile", () => { + it("should parse raw user profile data correctly with total_points or points", () => { + const rawData = { + username: "alice", + points: "150", + }; + + const result = parseUserProfile(rawData); + + expect(result).toEqual({ + username: "alice", + points: 150n, + }); + }); + it("parses correctly with bigint points", () => { const raw = { username: "alice", points: 100n }; const parsed = parseUserProfile(raw); @@ -25,6 +39,30 @@ describe("parse helpers in contracts.ts", () => { last_claim_timestamp: 123456789n, }; + it("should parse raw bot NFT data correctly with string tier", () => { + const rawData = { + id: 10, + name: "Bot #10", + owner: "GXYZ987654321", + tier: "Gold", + accrual_rate: "50", + minted_at: 1690000000, + last_claim_timestamp: "1690005000", + }; + + const result = parseBotNFT(rawData); + + expect(result).toEqual({ + id: 10n, + name: "Bot #10", + owner: "GXYZ987654321", + tier: "Gold", + accrual_rate: 50n, + minted_at: 1690000000, + last_claim_timestamp: 1690005000n, + }); + }); + it("parses tier as string", () => { const parsed = parseBotNFT({ ...baseRaw, tier: "Premium" }); expect(parsed.tier).toBe("Premium"); @@ -63,16 +101,24 @@ describe("parse helpers in contracts.ts", () => { }); describe("parseListing", () => { - it("parses listing correctly", () => { - const raw = { - id: 100n, - seller: "GBDUJF...", - bot_id: 5n, - price: 500n, - listed_at: 123456789n, + it("should parse a valid raw marketplace listing map into a MarketplaceListing object", () => { + const rawData = { + id: "1", + seller: "GABC1234567890", + bot_id: 42, + price: "1000000000", + listed_at: 1700000000n, }; - const parsed = parseListing(raw); - expect(parsed).toEqual(raw); + + const result = parseListing(rawData); + + expect(result).toEqual({ + id: 1n, + seller: "GABC1234567890", + bot_id: 42n, + price: 1000000000n, + listed_at: 1700000000n, + }); }); it("parses missing fields gracefully", () => { diff --git a/frontend/src/lib/contracts.ts b/frontend/src/lib/contracts.ts index 0072f6c..db3e968 100644 --- a/frontend/src/lib/contracts.ts +++ b/frontend/src/lib/contracts.ts @@ -108,6 +108,21 @@ export function parseBotNFT(rawData: Record): BotNFT { }; } +/** + * Parse a raw scVal map from the marketplace contract into a typed MarketplaceListing. + */ +export function parseListing( + rawData: Record +): MarketplaceListing { + return { + id: toBigInt(rawData.id), + seller: String(rawData.seller ?? ""), + bot_id: toBigInt(rawData.bot_id), + price: toBigInt(rawData.price), + listed_at: toBigInt(rawData.listed_at), + }; +} + /** * Get the AMT token balance for a user. * Calls token contract's balance() function. @@ -208,16 +223,6 @@ export async function cancelListing( ); } -export function parseListing(listing: Record): MarketplaceListing { - return { - id: toBigInt(listing.id), - seller: String(listing.seller ?? ""), - bot_id: toBigInt(listing.bot_id), - price: toBigInt(listing.price), - listed_at: toBigInt(listing.listed_at), - }; -} - /** * Get all active marketplace listings. * Returns array of listing objects. @@ -238,13 +243,7 @@ export async function getActiveListings( defaultSource(sourceAddress) ); if (!Array.isArray(listingsRaw)) return []; - return listingsRaw.map((listing: Record) => ({ - id: toBigInt(listing.id), - seller: String(listing.seller ?? ""), - bot_id: toBigInt(listing.bot_id), - price: toBigInt(listing.price), - listed_at: toBigInt(listing.listed_at), - })); + return listingsRaw.map((listing: Record) => parseListing(listing)); } catch { return []; } @@ -265,13 +264,7 @@ export async function getUserListings( userAddress ); if (!Array.isArray(listingsRaw)) return []; - return listingsRaw.map((listing: Record) => ({ - id: toBigInt(listing.id), - seller: String(listing.seller ?? ""), - bot_id: toBigInt(listing.bot_id), - price: toBigInt(listing.price), - listed_at: toBigInt(listing.listed_at), - })); + return listingsRaw.map((listing: Record) => parseListing(listing)); } catch { return []; } diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index 83d3027..ca0a43b 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -28,6 +28,8 @@ export interface MarketplaceListing { listed_at: bigint; } +export type Listing = MarketplaceListing; + export interface UserVault { user: string; balance: bigint;