diff --git a/src/marketplace/marketplace.test.ts b/src/marketplace/marketplace.test.ts index 77b9949..3e08896 100644 --- a/src/marketplace/marketplace.test.ts +++ b/src/marketplace/marketplace.test.ts @@ -108,10 +108,6 @@ function minNumberValidationError(field: string, min: number) { function createAvailability() { return { id: randomEthereumAddress(), - availabilityId: randomEthereumAddress(), - size: randomInt(3000, 300000), - requestId: randomEthereumAddress(), - slotIndex: randomInt(0, 9), totalSize: randomInt(0, 9).toString(), duration: randomInt(0, 9).toString(), minPrice: randomInt(0, 9).toString(), @@ -230,7 +226,9 @@ describe("marketplace", () => { duration: 100, }); - assert.deepStrictEqual(response, { error: false, data }); + assert.ok(!response.error); + // @ts-ignore + assert.deepEqual(response.data, data); }); it("returns a response when the create availability succeed", async () => { @@ -246,11 +244,18 @@ describe("marketplace", () => { duration: 100, }); - assert.deepStrictEqual(response, { error: false, data }); + assert.ok(!response.error); + // @ts-ignore + assert.deepEqual(response.data, data); }); it("returns an error when trying to update an availability without id", async () => { - const response = await marketplace.updateAvailability({} as any); + const response = await marketplace.updateAvailability({ + maxCollateral: 1, + totalSize: 3000, + minPrice: 100, + duration: 100, + } as any); assert.deepStrictEqual(response, missingStringValidationError("id")); }); @@ -259,6 +264,9 @@ describe("marketplace", () => { const response = await marketplace.updateAvailability({ id: randomString(64), totalSize: 0, + minPrice: 100, + duration: 100, + maxCollateral: 100, }); assert.deepStrictEqual(response, minNumberValidationError("totalSize", 1)); @@ -267,24 +275,31 @@ describe("marketplace", () => { it("returns an error when trying to update an availability with zero duration", async () => { const response = await marketplace.updateAvailability({ id: randomString(64), + totalSize: 100, duration: 0, + minPrice: 100, + maxCollateral: 100, }); assert.deepStrictEqual(response, minNumberValidationError("duration", 1)); }); it("returns a response when the update availability succeed", async () => { - const data = createAvailability(); - - const spy = vi.spyOn(Fetch, "safeJson"); - spy.mockImplementationOnce(() => Promise.resolve({ error: false, data })); + const mockResponse = { + ok: true, + status: 200, + } as any; + globalThis.fetch = vi.fn().mockResolvedValue(mockResponse); const response = await marketplace.updateAvailability({ id: randomString(64), totalSize: 3000, + duration: 10, + minPrice: 100, + maxCollateral: 100, }); - assert.deepStrictEqual(response, { error: false, data }); + assert.ok(!response.error); }); it("returns an error when trying to create a storage request without cid", async () => { diff --git a/src/marketplace/marketplace.ts b/src/marketplace/marketplace.ts index 8097a72..496ae0f 100644 --- a/src/marketplace/marketplace.ts +++ b/src/marketplace/marketplace.ts @@ -6,6 +6,7 @@ import type { SafeValue } from "../values/values"; import { type CodexAvailability, type CodexAvailabilityCreateResponse, + type CodexAvailabilityDto, CodexCreateAvailabilityInput, CodexCreateStorageRequestInput, type CodexPurchase, @@ -50,9 +51,24 @@ export class CodexMarketplace { async availabilities(): Promise> { const url = this.url + Api.config.prefix + "/sales/availability"; - return Fetch.safeJson(url, { + const res = await Fetch.safeJson(url, { method: "GET", }); + + if (res.error) { + return res; + } + + return { + error: false, + data: res.data.map((a) => ({ + id: a.id, + totalSize: parseInt(a.totalSize, 10), + duration: parseInt(a.duration, 10), + minPrice: parseInt(a.minPrice, 10), + maxCollateral: parseInt(a.maxCollateral, 10), + })), + }; } /** @@ -75,12 +91,16 @@ export class CodexMarketplace { const url = this.url + Api.config.prefix + "/sales/availability"; + const body = result.output; + return Fetch.safeJson(url, { method: "POST", - headers: { - "content-type": "application/json", - }, - body: JSON.stringify(result.output), + body: JSON.stringify({ + totalSize: body.totalSize.toString(), + duration: body.duration.toString(), + minPrice: body.minPrice.toString(), + maxCollateral: body.maxCollateral.toString(), + }), }); } @@ -90,7 +110,7 @@ export class CodexMarketplace { */ async updateAvailability( input: CodexUpdateAvailabilityInput - ): Promise> { + ): Promise> { const result = v.safeParse(CodexUpdateAvailabilityInput, input); if (!result.success) { @@ -106,13 +126,23 @@ export class CodexMarketplace { const url = this.url + Api.config.prefix + "/sales/availability/" + result.output.id; - return Fetch.safeJson(url, { - method: "POST", - headers: { - "content-type": "application/json", - }, - body: JSON.stringify(result.output), + const body = result.output; + + const res = await Fetch.safe(url, { + method: "PATCH", + body: JSON.stringify({ + totalSize: body.totalSize.toString(), + duration: body.duration.toString(), + minPrice: body.minPrice.toString(), + maxCollateral: body.maxCollateral.toString(), + }), }); + + if (res.error) { + return res; + } + + return { error: false, data: "" }; } /** diff --git a/src/marketplace/types.ts b/src/marketplace/types.ts index 1e20e33..a8f2adb 100644 --- a/src/marketplace/types.ts +++ b/src/marketplace/types.ts @@ -100,6 +100,33 @@ export type CodexSlot = { export type CodexAvailability = { id: string; + /** + * Size of available storage in bytes + */ + totalSize: number; + + /** + * Maximum time the storage should be sold for (in seconds) + */ + duration: number; + + /** + * Minimum price to be paid (in amount of tokens) + */ + minPrice: number; + + /** + * Maximum collateral user is willing to pay per filled Slot (in amount of tokens) + */ + maxCollateral: number; +}; + +/** + * Storage availability received from the api. + */ +export type CodexAvailabilityDto = { + id: string; + /** * Size of available storage in bytes */ @@ -143,10 +170,10 @@ export type CodexCreateAvailabilityInput = v.InferOutput< export const CodexUpdateAvailabilityInput = v.strictObject({ id: v.string(), - totalSize: v.optional(v.pipe(v.number(), v.minValue(1))), - duration: v.optional(v.pipe(v.number(), v.minValue(1))), - minPrice: v.optional(v.number()), - maxCollateral: v.optional(v.number()), + totalSize: v.pipe(v.number(), v.minValue(1)), + duration: v.pipe(v.number(), v.minValue(1)), + minPrice: v.number(), + maxCollateral: v.number(), }); export type CodexUpdateAvailabilityInput = v.InferOutput<