Update availability endpoints

This commit is contained in:
Arnaud 2024-09-20 10:50:35 +02:00
parent 68dec65501
commit d75ef63b42
No known key found for this signature in database
GPG Key ID: 69D6CE281FCAE663
3 changed files with 100 additions and 28 deletions

View File

@ -108,10 +108,6 @@ function minNumberValidationError(field: string, min: number) {
function createAvailability() { function createAvailability() {
return { return {
id: randomEthereumAddress(), id: randomEthereumAddress(),
availabilityId: randomEthereumAddress(),
size: randomInt(3000, 300000),
requestId: randomEthereumAddress(),
slotIndex: randomInt(0, 9),
totalSize: randomInt(0, 9).toString(), totalSize: randomInt(0, 9).toString(),
duration: randomInt(0, 9).toString(), duration: randomInt(0, 9).toString(),
minPrice: randomInt(0, 9).toString(), minPrice: randomInt(0, 9).toString(),
@ -230,7 +226,9 @@ describe("marketplace", () => {
duration: 100, 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 () => { it("returns a response when the create availability succeed", async () => {
@ -246,11 +244,18 @@ describe("marketplace", () => {
duration: 100, 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 () => { 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")); assert.deepStrictEqual(response, missingStringValidationError("id"));
}); });
@ -259,6 +264,9 @@ describe("marketplace", () => {
const response = await marketplace.updateAvailability({ const response = await marketplace.updateAvailability({
id: randomString(64), id: randomString(64),
totalSize: 0, totalSize: 0,
minPrice: 100,
duration: 100,
maxCollateral: 100,
}); });
assert.deepStrictEqual(response, minNumberValidationError("totalSize", 1)); 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 () => { it("returns an error when trying to update an availability with zero duration", async () => {
const response = await marketplace.updateAvailability({ const response = await marketplace.updateAvailability({
id: randomString(64), id: randomString(64),
totalSize: 100,
duration: 0, duration: 0,
minPrice: 100,
maxCollateral: 100,
}); });
assert.deepStrictEqual(response, minNumberValidationError("duration", 1)); assert.deepStrictEqual(response, minNumberValidationError("duration", 1));
}); });
it("returns a response when the update availability succeed", async () => { it("returns a response when the update availability succeed", async () => {
const data = createAvailability(); const mockResponse = {
ok: true,
const spy = vi.spyOn(Fetch, "safeJson"); status: 200,
spy.mockImplementationOnce(() => Promise.resolve({ error: false, data })); } as any;
globalThis.fetch = vi.fn().mockResolvedValue(mockResponse);
const response = await marketplace.updateAvailability({ const response = await marketplace.updateAvailability({
id: randomString(64), id: randomString(64),
totalSize: 3000, 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 () => { it("returns an error when trying to create a storage request without cid", async () => {

View File

@ -6,6 +6,7 @@ import type { SafeValue } from "../values/values";
import { import {
type CodexAvailability, type CodexAvailability,
type CodexAvailabilityCreateResponse, type CodexAvailabilityCreateResponse,
type CodexAvailabilityDto,
CodexCreateAvailabilityInput, CodexCreateAvailabilityInput,
CodexCreateStorageRequestInput, CodexCreateStorageRequestInput,
type CodexPurchase, type CodexPurchase,
@ -50,9 +51,24 @@ export class CodexMarketplace {
async availabilities(): Promise<SafeValue<CodexAvailability[]>> { async availabilities(): Promise<SafeValue<CodexAvailability[]>> {
const url = this.url + Api.config.prefix + "/sales/availability"; const url = this.url + Api.config.prefix + "/sales/availability";
return Fetch.safeJson<CodexAvailability[]>(url, { const res = await Fetch.safeJson<CodexAvailabilityDto[]>(url, {
method: "GET", 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 url = this.url + Api.config.prefix + "/sales/availability";
const body = result.output;
return Fetch.safeJson<CodexAvailabilityCreateResponse>(url, { return Fetch.safeJson<CodexAvailabilityCreateResponse>(url, {
method: "POST", method: "POST",
headers: { body: JSON.stringify({
"content-type": "application/json", totalSize: body.totalSize.toString(),
}, duration: body.duration.toString(),
body: JSON.stringify(result.output), minPrice: body.minPrice.toString(),
maxCollateral: body.maxCollateral.toString(),
}),
}); });
} }
@ -90,7 +110,7 @@ export class CodexMarketplace {
*/ */
async updateAvailability( async updateAvailability(
input: CodexUpdateAvailabilityInput input: CodexUpdateAvailabilityInput
): Promise<SafeValue<CodexAvailability>> { ): Promise<SafeValue<"">> {
const result = v.safeParse(CodexUpdateAvailabilityInput, input); const result = v.safeParse(CodexUpdateAvailabilityInput, input);
if (!result.success) { if (!result.success) {
@ -106,13 +126,23 @@ export class CodexMarketplace {
const url = const url =
this.url + Api.config.prefix + "/sales/availability/" + result.output.id; this.url + Api.config.prefix + "/sales/availability/" + result.output.id;
return Fetch.safeJson<CodexAvailability>(url, { const body = result.output;
method: "POST",
headers: { const res = await Fetch.safe(url, {
"content-type": "application/json", method: "PATCH",
}, body: JSON.stringify({
body: JSON.stringify(result.output), 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: "" };
} }
/** /**

View File

@ -100,6 +100,33 @@ export type CodexSlot = {
export type CodexAvailability = { export type CodexAvailability = {
id: string; 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 * Size of available storage in bytes
*/ */
@ -143,10 +170,10 @@ export type CodexCreateAvailabilityInput = v.InferOutput<
export const CodexUpdateAvailabilityInput = v.strictObject({ export const CodexUpdateAvailabilityInput = v.strictObject({
id: v.string(), id: v.string(),
totalSize: v.optional(v.pipe(v.number(), v.minValue(1))), totalSize: v.pipe(v.number(), v.minValue(1)),
duration: v.optional(v.pipe(v.number(), v.minValue(1))), duration: v.pipe(v.number(), v.minValue(1)),
minPrice: v.optional(v.number()), minPrice: v.number(),
maxCollateral: v.optional(v.number()), maxCollateral: v.number(),
}); });
export type CodexUpdateAvailabilityInput = v.InferOutput< export type CodexUpdateAvailabilityInput = v.InferOutput<