Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add currency abstraction #2707

Merged
merged 15 commits into from
May 25, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/grid_client/scripts/tft.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ async function yearlyUSD(client, hourlyUSD) {
}
async function main() {
const grid = await getClient();

grid.currency.rate = await grid.tfclient.tftPrice.get();
const amount: CurrencyModel = {
amount: 1,
};
Expand Down
13 changes: 2 additions & 11 deletions packages/grid_client/src/modules/tft.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
import Decimal from "decimal.js";

import { GridClientConfig, TFClient } from "..";
import { expose, validateInput } from "../helpers";
import { CurrencyModel } from "./models";

class TFTUSDConversionService {
private tfclient: TFClient;
private rate: number;

constructor(public config: GridClientConfig, public decimals = 2) {
this.decimals = decimals;
this.tfclient = config.tfclient;
this.tfclient.tftPrice.get().then(res => {
this.rate = res;
});
}
// TFT rate: 1 tft = x USD
constructor(public rate: number, private decimals = 2) {}
zaelgohary marked this conversation as resolved.
Show resolved Hide resolved

@expose
@validateInput
Expand Down
162 changes: 92 additions & 70 deletions packages/grid_client/tests/modules/tft.test.ts
Original file line number Diff line number Diff line change
@@ -1,162 +1,184 @@
import { ValidationError } from "@threefold/types";
import Decimal from "decimal.js";

import { currency, type GridClient } from "../../src";
import { currency as TFTUSDConversionService, type GridClient } from "../../src";
import { getClient } from "../client_loader";

jest.setTimeout(300000);
let grid: GridClient;
let tftPrice: number;
let rate: number;
let decimals: number;
let currency: TFTUSDConversionService;

beforeAll(async () => {
grid = await getClient();
tftPrice = await grid.tfclient.tftPrice.get();
grid.currency.decimals = 5;
rate = await grid.tfclient.tftPrice.get();
decimals = 5;
currency = new TFTUSDConversionService(rate, decimals);
});

afterAll(async () => {
await grid.disconnect();
});

describe("Testing TFT module", () => {
test("tft module to be instance of TFTUSDConversionService", async () => {
expect(await grid.currency).toBeInstanceOf(currency);
test("tft module to be instance of TFTUSDConversionService", () => {
expect(currency).toBeInstanceOf(TFTUSDConversionService);
});

test("should return value with 2 decimals.", async () => {
const result = await grid.currency.normalizeCurrency({ amount: 1 });
test("should return value with 2 decimals.", () => {
const result = currency.normalizeCurrency({ amount: 1 });

expect(typeof result).toBe("string");
expect(result).toBe(new Decimal(1).toFixed(grid.currency.decimals));
expect(result).toBe(new Decimal(1).toFixed(decimals));
});

test("should convert to the correct value based on tftPrice.", async () => {
test("should convert to the correct value based on tftPrice.", () => {
const hourlyTFT = { amount: 1 };
const result = await grid.currency.convertTFTtoUSD(hourlyTFT);
const result = currency.convertTFTtoUSD(hourlyTFT);

expect(typeof result).toBe("string");
expect(result).toBe(new Decimal(1 * tftPrice).toFixed(grid.currency.decimals));
expect(result).toBe(new Decimal(1 * rate).toFixed(decimals));
});

test("convertTFTtoUSD function to throw if passed a negative value.", async () => {
const result = async () => await grid.currency.convertTFTtoUSD({ amount: -1 });

await expect(result).rejects.toThrow();
await expect(result).rejects.toBeInstanceOf(ValidationError);
test("convertTFTtoUSD function to throw if passed a negative value.", () => {
const result = () => currency.convertTFTtoUSD({ amount: -1 });
try {
expect(result).toThrow();
} catch (error) {
expect(result).toBeInstanceOf(ValidationError);
}
});

test("convertUSDtoTFT function returns a valid value.", async () => {
test("convertUSDtoTFT function returns a valid value.", () => {
const usd = 1;
const result = await grid.currency.convertUSDtoTFT({ amount: usd });
const result = currency.convertUSDtoTFT({ amount: usd });

expect(typeof result).toBe("string");
expect(result).toEqual(new Decimal(1 / tftPrice).toFixed(grid.currency.decimals));
expect(result).toEqual(new Decimal(1 / rate).toFixed(decimals));
});

test("convertUSDtoTFT function to throw if passed a negative value.", async () => {
const result = async () => await grid.currency.convertUSDtoTFT({ amount: -1 });
test("convertUSDtoTFT function to throw if passed a negative value.", () => {
const result = () => currency.convertUSDtoTFT({ amount: -1 });

await expect(result).rejects.toThrow();
await expect(result).rejects.toBeInstanceOf(ValidationError);
try {
expect(result).toThrow();
} catch (error) {
expect(result).toBeInstanceOf(ValidationError);
}
});

test("dailyTFT function returns a valid value.", async () => {
test("dailyTFT function returns a valid value.", () => {
const tfts = 1;
const result = await grid.currency.dailyTFT({ amount: tfts });
const expected_result = new Decimal(tfts * 24).toFixed(grid.currency.decimals);
const result = currency.dailyTFT({ amount: tfts });
const expected_result = new Decimal(tfts * 24).toFixed(decimals);

expect(typeof result).toBe("string");
expect(result).toBe(expected_result);
});

test("dailyTFT function throws if passed anything other than a positive value.", async () => {
const result = async () => await grid.currency.dailyTFT({ amount: -1 });
test("dailyTFT function throws if passed anything other than a positive value.", () => {
const result = () => currency.dailyTFT({ amount: -1 });

expect(result).rejects.toThrow();
expect(result).rejects.toBeInstanceOf(ValidationError);
try {
expect(result).toThrow();
} catch (error) {
expect(result).toBeInstanceOf(ValidationError);
}
});

test("monthlyTFT function returns a valid value.", async () => {
test("monthlyTFT function returns a valid value.", () => {
const tfts = 1;
const result = await grid.currency.monthlyTFT({ amount: tfts });
const expected_result = new Decimal(tfts * 24 * 30).toFixed(grid.currency.decimals);
const result = currency.monthlyTFT({ amount: tfts });
const expected_result = new Decimal(tfts * 24 * 30).toFixed(decimals);

expect(typeof result).toBe("string");
expect(result).toBe(expected_result);
});

test("monthlyTFT function throws if passed anything other than a positive value.", async () => {
const result = async () => await grid.currency.monthlyTFT({ amount: -1 });
test("monthlyTFT function throws if passed anything other than a positive value.", () => {
const result = () => currency.monthlyTFT({ amount: -1 });

await expect(result).rejects.toThrow();
await expect(result).rejects.toBeInstanceOf(ValidationError);
try {
expect(result).toThrow();
} catch (error) {
expect(result).toBeInstanceOf(ValidationError);
}
});

test("yearlyTFT function returns a valid value.", async () => {
test("yearlyTFT function returns a valid value.", () => {
const tfts = 1;
const result = await grid.currency.yearlyTFT({ amount: tfts });
const expected_result = new Decimal(+(await grid.currency.monthlyTFT({ amount: tfts })) * 12).toFixed(
grid.currency.decimals,
);
const result = currency.yearlyTFT({ amount: tfts });
const expected_result = new Decimal(+currency.monthlyTFT({ amount: tfts }) * 12).toFixed(decimals);

expect(typeof result).toBe("string");
expect(result).toBe(expected_result);
});

test("yearlyTFT function throws if passed anything other than a positive value.", async () => {
const result = async () => grid.currency.yearlyTFT({ amount: -1 });
test("yearlyTFT function throws if passed anything other than a positive value.", () => {
const result = () => currency.yearlyTFT({ amount: -1 });

await expect(result).rejects.toThrow();
await expect(result).rejects.toBeInstanceOf(ValidationError);
try {
expect(result).toThrow();
} catch (error) {
expect(result).toBeInstanceOf(ValidationError);
}
});

test("dailyUSD function returns a valid value.", async () => {
test("dailyUSD function returns a valid value.", () => {
const tfts = 1;
const result = await grid.currency.dailyUSD({ amount: tfts });
const expected_result = new Decimal(tfts * 24).toFixed(grid.currency.decimals);
const result = currency.dailyUSD({ amount: tfts });
const expected_result = new Decimal(tfts * 24).toFixed(decimals);

expect(typeof result).toBe("string");
expect(result).toBe(expected_result);
});

test("dailyUSD function throws if passed anything other than a positive value.", async () => {
const result = async () => await grid.currency.dailyUSD({ amount: -1 });
test("dailyUSD function throws if passed anything other than a positive value.", () => {
const result = () => currency.dailyUSD({ amount: -1 });

expect(result).rejects.toThrow();
expect(result).rejects.toBeInstanceOf(ValidationError);
try {
expect(result).toThrow();
} catch (error) {
expect(result).toBeInstanceOf(ValidationError);
}
});

test("monthlyUSD function returns a valid value.", async () => {
test("monthlyUSD function returns a valid value.", () => {
const tfts = 1;
const result = await grid.currency.monthlyUSD({ amount: tfts });
const expected_result = new Decimal(tfts * 24 * 30).toFixed(grid.currency.decimals);
const result = currency.monthlyUSD({ amount: tfts });
const expected_result = new Decimal(tfts * 24 * 30).toFixed(decimals);

expect(typeof result).toBe("string");
expect(result).toBe(expected_result);
});

test("monthlyUSD function throws if passed anything other than a positive value.", async () => {
const result = async () => await grid.currency.monthlyUSD({ amount: -1 });
test("monthlyUSD function throws if passed anything other than a positive value.", () => {
const result = () => currency.monthlyUSD({ amount: -1 });

await expect(result).rejects.toThrow();
await expect(result).rejects.toBeInstanceOf(ValidationError);
try {
expect(result).toThrow();
} catch (error) {
expect(result).toBeInstanceOf(ValidationError);
}
});

test("yearlyUSD function returns a valid value.", async () => {
test("yearlyUSD function returns a valid value.", () => {
const tfts = 1;
const result = await grid.currency.yearlyUSD({ amount: tfts });
const expected_result = new Decimal(+(await grid.currency.monthlyUSD({ amount: tfts })) * 12).toFixed(
grid.currency.decimals,
);
const result = currency.yearlyUSD({ amount: tfts });
const expected_result = new Decimal(+currency.monthlyUSD({ amount: tfts }) * 12).toFixed(decimals);

expect(typeof result).toBe("string");
expect(result).toBe(expected_result);
});

test("yearlyUSD function throws if passed anything other than a positive value.", async () => {
const result = async () => grid.currency.yearlyUSD({ amount: -1 });
test("yearlyUSD function throws if passed anything other than a positive value.", () => {
const result = () => currency.yearlyUSD({ amount: -1 });

await expect(result).rejects.toThrow();
await expect(result).rejects.toBeInstanceOf(ValidationError);
try {
expect(result).toThrow();
} catch (error) {
expect(result).toBeInstanceOf(ValidationError);
}
});
});
Loading