Skip to content

Commit

Permalink
feat: queryPriceListing and getTokenList features
Browse files Browse the repository at this point in the history
  • Loading branch information
kaliman93 committed Jan 20, 2023
1 parent 8048a56 commit 5b127a5
Show file tree
Hide file tree
Showing 14 changed files with 479 additions and 14 deletions.
14 changes: 13 additions & 1 deletion src/init/thea.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import { Signer } from "@ethersproject/abstract-signer";
import { Provider, Web3Provider } from "@ethersproject/providers";
import { Wallet } from "@ethersproject/wallet";
import { Convert, GetCharacteristicsBytes, Recover, Tokenization, Unwrap } from "../modules";
import {
Convert,
GetCharacteristicsBytes,
GetTokenList,
QueryPriceListing,
Recover,
Tokenization,
Unwrap
} from "../modules";
import { TheaNetwork, ProviderOrSigner } from "../types";
import { TheaError } from "../utils";

Expand All @@ -19,12 +27,16 @@ export class TheaSDK {
readonly tokenization: Tokenization;
readonly convert: Convert;
readonly recover: Recover;
readonly nftTokenList: GetTokenList;
readonly nftQueryPriceListing: QueryPriceListing;

private constructor(readonly providerOrSigner: ProviderOrSigner, readonly network: TheaNetwork) {
this.unwrap = new Unwrap(this.providerOrSigner, network);
this.convert = new Convert(this.providerOrSigner, network);
const registry = new GetCharacteristicsBytes(this.providerOrSigner, network);
this.recover = new Recover(this.providerOrSigner, network, registry);
this.nftTokenList = new GetTokenList(network);
this.nftQueryPriceListing = new QueryPriceListing(network);
}

/**
Expand Down
27 changes: 27 additions & 0 deletions src/modules/NFTtrading/getTokenList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { TheaNetwork, TokenListResponsePayload } from "src/types";
import { consts } from "src/utils/consts";
import { HttpClient } from "../shared";

export class GetTokenList {
readonly httpClient: HttpClient;
readonly network: TheaNetwork;

constructor(network: TheaNetwork) {
this.network = network;
this.httpClient = new HttpClient("https://api.rarible.org/v0.1");
}
async getTokenList() {
const response = await this.httpClient.get<TokenListResponsePayload>("/items/byCollection", {
collection: consts[`${this.network}`].networkName + ":" + consts[`${this.network}`].theaERC1155Contract
});
// eslint-disable-next-line no-var
var tokenIdsList: string[] = [];
if (response.items.length > 0) {
response.items.forEach((item) => {
tokenIdsList.push(item.tokenId);
});
}

return tokenIdsList;
}
}
74 changes: 74 additions & 0 deletions src/modules/NFTtrading/queryPriceListing copy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import {
OrderSide,
SearchOrdersParams,
// PostOrderRequestPayload,
// PostOrderResponsePayload,
SearchOrdersResponsePayload,
// SignedERC1155OrderStruct,
// SignedERC1155OrderStructSerialized,
TheaNetwork
} from "src/types";
import { consts } from "src/utils/consts";
import { HttpClient } from "../shared/httpClient";

export class QueryPriceListing {
readonly orderBook: HttpClient;
readonly network: TheaNetwork;

constructor(network: TheaNetwork) {
this.network = network;
this.orderBook = new HttpClient("https://api.trader.xyz/orderbook");
}
// private async postOrderToOrderbook(
// signedOrder: SignedERC1155OrderStruct,
// chainId: string | number,
// metadata: Record<string, string> = {}
// ) {
// const payload: PostOrderRequestPayload = {
// order: this.serializeNftOrder(signedOrder),
// chainId: chainId.toString(10),
// metadata
// };
// try {
// const response = await this.orderBook.post<string, PostOrderResponsePayload>("/orders", JSON.stringify(payload));
// return response;
// } catch (error) {
// throw new TheaError(error.message);
// }
// }
async queryPriceListing(tokenId: string, side: OrderSide) {
const response = await this.orderBook.get<SearchOrdersResponsePayload>("/orders", {
nftToken: consts[`${this.network}`].theaERC1155Contract,
nftTokenId: tokenId,
sellOrBuyNft: side,
status: "open",
erc20Token: consts[`${this.network}`].stableCoinContract
} as Partial<SearchOrdersParams>);
const priceList: number[] = [];
response.orders.forEach((element) => {
priceList.push(parseInt(element.nftTokenAmount) / (parseInt(element.erc20TokenAmount) / 10 ** 18));
});
return priceList;
}
// private serializeNftOrder = (signedOrder: SignedERC1155OrderStruct): SignedERC1155OrderStructSerialized => {
// if ("erc1155Token" in signedOrder) {
// return {
// ...signedOrder,
// direction: parseInt(signedOrder.direction.toString()),
// expiry: signedOrder.expiry.toString(),
// nonce: signedOrder.nonce.toString(),
// erc20TokenAmount: signedOrder.erc20TokenAmount.toString(),
// fees: signedOrder.fees.map((fee) => ({
// ...fee,
// amount: fee.amount.toString(),
// feeData: fee.feeData.toString()
// })),
// erc1155TokenAmount: signedOrder.erc1155TokenAmount.toString(),
// erc1155TokenId: signedOrder.erc1155TokenId.toString()
// };
// } else {
// console.log("unknown order format type erc1155", signedOrder);
// throw new TheaError({ message: "Unknown asset type", type: "NFT_ORDER_SERILIZATION_ERROR" });
// }
// };
}
28 changes: 28 additions & 0 deletions src/modules/NFTtrading/queryPriceListing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { OrderSide, SearchOrdersParams, SearchOrdersResponsePayload, TheaNetwork } from "src/types";
import { consts } from "src/utils/consts";
import { HttpClient } from "../shared/httpClient";

export class QueryPriceListing {
readonly orderBook: HttpClient;
readonly network: TheaNetwork;

constructor(network: TheaNetwork) {
this.network = network;
this.orderBook = new HttpClient("https://api.trader.xyz/orderbook");
}

async queryPriceListing(tokenId: string, side: OrderSide) {
const response = await this.orderBook.get<SearchOrdersResponsePayload>("/orders", {
nftToken: consts[`${this.network}`].theaERC1155Contract,
nftTokenId: tokenId,
sellOrBuyNft: side,
status: "open",
erc20Token: consts[`${this.network}`].stableCoinContract
} as Partial<SearchOrdersParams>);
const priceList: number[] = [];
response.orders.forEach((element) => {
priceList.push(parseInt(element.nftTokenAmount) / (parseInt(element.erc20TokenAmount) / 10 ** 18));
});
return priceList;
}
}
2 changes: 2 additions & 0 deletions src/modules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export * from "./recover";
export * from "./shared";
export * from "./tokenization";
export * from "./getCharacteristicsBytes";
export * from "./NFTtrading/getTokenList";
export * from "./NFTtrading/queryPriceListing";
10 changes: 5 additions & 5 deletions src/modules/shared/httpClient.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import axios, { AxiosInstance } from "axios";
import { TheaNetwork } from "../../types";
import { consts, TheaAPICallError } from "../../utils";
import { TheaAPICallError } from "../../utils";

export class HttpClient {
readonly client: AxiosInstance;
constructor(network: TheaNetwork) {
constructor(url: string) {
this.client = axios.create({
baseURL: consts[`${network}`].theaApiBaseUrl,
baseURL: url,
headers: {
"Content-Type": "application/json"
}
Expand All @@ -26,7 +25,8 @@ export class HttpClient {
}
}

async get<TResponse>(path: string, params?: Record<string, string>): Promise<TResponse> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async get<TResponse>(path: string, params?: Record<string, any>): Promise<TResponse> {
try {
const response = await this.client.get<TResponse>(path, { params });
return response.data;
Expand Down
4 changes: 2 additions & 2 deletions src/modules/tokenization.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { ClientDetails, TheaNetwork, TokenizationRequest, TokenizationSource, TokenizationState } from "../types";
import { TheaError, validateAddress } from "../utils";
import { consts, TheaError, validateAddress } from "../utils";
import { HttpClient } from "./shared";

export class Tokenization {
readonly httpClient: HttpClient;
constructor(network: TheaNetwork) {
this.httpClient = new HttpClient(network);
this.httpClient = new HttpClient(consts[`${network}`].theaApiBaseUrl);
}

/**
Expand Down
163 changes: 162 additions & 1 deletion src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Signer } from "@ethersproject/abstract-signer";
import { BigNumber } from "@ethersproject/bignumber";
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
import { Overrides } from "@ethersproject/contracts";
import { Provider } from "@ethersproject/providers";

Expand Down Expand Up @@ -131,6 +131,167 @@ export type BaseTokenAmounts = {
rating: BigNumber;
};

export interface PostOrderRequestPayload {
order: SignedERC1155OrderStructSerialized;
chainId: string;
metadata?: Record<string, string>;
}

export type PropertyStructSerialized = {
propertyValidator: string;
propertyData: string | Array<number>;
};

export type FeeStructSerialized = {
recipient: string;
amount: string;
feeData: string;
};
export type TokenListResponsePayload = {
continuation: string;
items: TokenResponseFromRaribleAPI[];
};
type TokenResponseFromRaribleAPI = {
id: string;
blockchain: string;
collection: string;
contract: string;
tokenId: string;
creators: [{ account: string; value: number }];
lazySupply: string;
pending: [];
mintedAt: string;
lastUpdatedAt: string;
supply: string;
meta: {
name: string;
description: string;
tags: [];
genres: [];
attributes: [{ key: string; value: string }];
content: [
{
"@type": "IMAGE";
url: string;
representation: string;
mimeType: string;
size: number;
width: number;
height: number;
}
];
restrictions: [];
};
deleted: true;
originOrders: [];
ammOrders: { ids: [] };
auctions: [];
totalStock: string;
sellers: number;
suspicious: boolean;
};
export interface PostOrderResponsePayload {
erc20Token: string;
erc20TokenAmount: string;
nftToken: string;
nftTokenId: string;
nftTokenAmount: string;
nftType: string;
sellOrBuyNft: "buy" | "sell";
chainId: string;
order: SignedERC1155OrderStructSerialized;
orderStatus: OrderStatus;
metadata: Record<string, string> | null;
}
export type OrderStatus = {
status: null | string;
transactionHash: null | string;
blockNumber: null | string;
};
export type OrderSide = "buy" | "sell";
export type ERC1155OrderStruct = {
direction: BigNumberish;
maker: string;
taker: string;
expiry: BigNumberish;
nonce: BigNumberish;
erc20Token: string;
erc20TokenAmount: BigNumberish;
fees: FeeStruct[];
erc1155Token: string;
erc1155TokenId: BigNumberish;
erc1155TokenProperties: PropertyStruct[];
erc1155TokenAmount: BigNumberish;
};
export type FeeStruct = {
recipient: string;
amount: BigNumberish;
feeData: string | Array<number>;
};
export type PropertyStruct = {
propertyValidator: string;
propertyData: string | Array<number>;
};
export interface SignedERC1155OrderStructSerialized extends ERC1155OrderStructSerialized {
signature: SignatureStructSerialized;
}

export interface SignedERC1155OrderStruct extends ERC1155OrderStruct {
signature: SignatureStruct;
}

export type SignatureStruct = {
signatureType: number; // 2 for EIP-712
v: number;
r: string;
s: string;
};
export type SignatureStructSerialized = {
signatureType: number; // 2 for EIP-712
v: number;
r: string;
s: string;
};

export type ERC1155OrderStructSerialized = {
direction: number;
maker: string;
taker: string;
expiry: string;
nonce: string;
erc20Token: string;
erc20TokenAmount: string;
fees: FeeStructSerialized[];
erc1155Token: string;
erc1155TokenId: string;
erc1155TokenProperties: PropertyStructSerialized[];
erc1155TokenAmount: string;
};
export interface SearchOrdersResponsePayload {
orders: Array<PostOrderResponsePayload>;
}

/**
* Available query parameters for searching the orderbook
*/
export interface SearchOrdersParams {
nftTokenId: string | string[];
erc20Token: string | string[];
nftToken: string | string[];
nftType: "ERC721" | "ERC1155";
chainId: string | number | string[] | number[];
maker: string;
taker: string;
nonce: string | string[];
offset: string | number;
limit: string | number;
sellOrBuyNft: "sell" | "buy";
direction: "0" | "1";
// Defaults to only 'open' orders
status: "open" | "filled" | "expired" | "cancelled" | "all";
visibility: "public" | "private";
valid: "valid" | "all";
}
export * from "./IRegistryContract";
export * from "./IBaseTokenManagerContract";
export * from "./IERC1155Contract";
Expand Down
Loading

0 comments on commit 5b127a5

Please sign in to comment.