Initial version of js sdk for express relay (#1281)
This commit is contained in:
parent
ca852ea989
commit
5c8e372ef6
|
@ -0,0 +1,6 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
parser: "@typescript-eslint/parser",
|
||||
plugins: ["@typescript-eslint"],
|
||||
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
lib/
|
|
@ -0,0 +1,74 @@
|
|||
# Pyth Express Relay JS SDK
|
||||
|
||||
Utility library for interacting with the Pyth Express Relay API.
|
||||
|
||||
## Installation
|
||||
|
||||
### npm
|
||||
|
||||
```
|
||||
$ npm install --save @pythnetwork/express-relay-evm-js
|
||||
```
|
||||
|
||||
### Yarn
|
||||
|
||||
```
|
||||
$ yarn add @pythnetwork/express-relay-evm-js
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
To generate the latest type declarations from the server openapi schema, run:
|
||||
|
||||
```bash
|
||||
npm run generate-api-types
|
||||
```
|
||||
|
||||
## Quickstart
|
||||
|
||||
```typescript
|
||||
import {
|
||||
Client,
|
||||
OpportunityParams,
|
||||
BidInfo,
|
||||
} from "@pythnetwork/express-relay-evm-js";
|
||||
|
||||
const client = new Client({ baseUrl: "https://per-staging.dourolabs.app/" });
|
||||
|
||||
function calculateOpportunityBid(
|
||||
opportunity: OpportunityParams
|
||||
): BidInfo | null {
|
||||
// searcher implementation here
|
||||
// if the opportunity is not suitable for the searcher, return null
|
||||
}
|
||||
const opportunities = await client.getOpportunities();
|
||||
|
||||
for (const opportunity of opportunities) {
|
||||
const bidInfo = calculateOpportunityBid(order);
|
||||
if (bidInfo === null) continue;
|
||||
const opportunityBid = await client.signOpportunityBid(
|
||||
opportunity,
|
||||
bidInfo,
|
||||
privateKey // searcher private key with appropriate permissions and assets
|
||||
);
|
||||
await client.submitOpportunityBid(opportunityBid);
|
||||
}
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
There is an example searcher in [examples](./src/examples/) directory.
|
||||
|
||||
#### SimpleSearcher
|
||||
|
||||
[This example](./src/examples/SimpleSearcher.ts) fetches `OpportunityParams` from the specified endpoint,
|
||||
creates a fixed bid on each opportunity and signs them with the provided private key, and finally submits them back to the server. You can run it with
|
||||
`npm run simple-searcher`. A full command looks like this:
|
||||
|
||||
```bash
|
||||
npm run simple-searcher -- \
|
||||
--endpoint https://per-staging.dourolabs.app/ \
|
||||
--bid 100000 \
|
||||
--chain-id op_sepolia \
|
||||
--private-key <YOUR-PRIVATE-KEY>
|
||||
```
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"name": "@pythnetwork/express-relay-evm-js",
|
||||
"version": "0.1.0",
|
||||
"description": "Utilities for interacting with the express relay protocol",
|
||||
"homepage": "https://pyth.network",
|
||||
"author": {
|
||||
"name": "Pyth Data Association"
|
||||
},
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"files": [
|
||||
"lib/**/*"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"simple-searcher": "npm run build && node lib/examples/SimpleSearcher.js",
|
||||
"generate-api-types": "openapi-typescript http://127.0.0.1:9000/docs/openapi.json --output src/types.d.ts",
|
||||
"format": "prettier --write \"src/**/*.ts\"",
|
||||
"lint": "eslint src",
|
||||
"prepublishOnly": "npm run build && npm test && npm run lint",
|
||||
"preversion": "npm run lint",
|
||||
"version": "npm run format && git add -A src"
|
||||
},
|
||||
"keywords": [
|
||||
"pyth",
|
||||
"oracle",
|
||||
"relay"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pyth-network/pyth-crosschain",
|
||||
"directory": "express_relay/sdk/js"
|
||||
},
|
||||
"dependencies": {
|
||||
"openapi-client-axios": "^7.5.4",
|
||||
"openapi-fetch": "^0.8.2",
|
||||
"viem": "^2.7.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/yargs": "^17.0.10",
|
||||
"@typescript-eslint/eslint-plugin": "^5.21.0",
|
||||
"@typescript-eslint/parser": "^5.21.0",
|
||||
"eslint": "^8.56.0",
|
||||
"openapi-typescript": "^6.5.5",
|
||||
"prettier": "^2.6.2",
|
||||
"typescript": "5.1",
|
||||
"yargs": "^17.4.1"
|
||||
},
|
||||
"license": "Apache-2.0"
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
import yargs from "yargs";
|
||||
import { hideBin } from "yargs/helpers";
|
||||
import { Client } from "../index";
|
||||
import { privateKeyToAccount } from "viem/accounts";
|
||||
import { isHex } from "viem";
|
||||
|
||||
function sleep(ms: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
const argv = yargs(hideBin(process.argv))
|
||||
.option("endpoint", {
|
||||
description:
|
||||
"Express relay endpoint. e.g: https://per-staging.dourolabs.app/",
|
||||
type: "string",
|
||||
demandOption: true,
|
||||
})
|
||||
.option("chain-id", {
|
||||
description: "Chain id to fetch opportunities for. e.g: sepolia",
|
||||
type: "string",
|
||||
})
|
||||
.option("bid", {
|
||||
description: "Bid amount in wei",
|
||||
type: "string",
|
||||
default: "100",
|
||||
})
|
||||
.option("private-key", {
|
||||
description:
|
||||
"Private key to sign the bid with in hex format with 0x prefix. e.g: 0xdeadbeef...",
|
||||
type: "string",
|
||||
demandOption: true,
|
||||
})
|
||||
.help()
|
||||
.alias("help", "h")
|
||||
.parseSync();
|
||||
|
||||
async function run() {
|
||||
const client = new Client({ baseUrl: argv.endpoint });
|
||||
if (isHex(argv.privateKey)) {
|
||||
const account = privateKeyToAccount(argv.privateKey);
|
||||
console.log(`Using account: ${account.address}`);
|
||||
} else {
|
||||
throw new Error(`Invalid private key: ${argv.privateKey}`);
|
||||
}
|
||||
const DAY_IN_SECONDS = 60 * 60 * 24;
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
const opportunities = await client.getOpportunities(argv.chainId);
|
||||
console.log(`Fetched ${opportunities.length} opportunities`);
|
||||
for (const opportunity of opportunities) {
|
||||
const bid = BigInt(argv.bid);
|
||||
// Bid info should be generated by evaluating the opportunity
|
||||
// here for simplicity we are using a constant bid and 24 hours of validity
|
||||
const bidInfo = {
|
||||
amount: bid,
|
||||
validUntil: BigInt(Math.round(Date.now() / 1000 + DAY_IN_SECONDS)),
|
||||
};
|
||||
const opportunityBid = await client.signOpportunityBid(
|
||||
opportunity,
|
||||
bidInfo,
|
||||
argv.privateKey
|
||||
);
|
||||
try {
|
||||
await client.submitOpportunityBid(opportunityBid);
|
||||
console.log(
|
||||
`Successful bid ${bid} on opportunity ${opportunity.opportunityId}`
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`Failed to bid on opportunity ${opportunity.opportunityId}: ${error}`
|
||||
);
|
||||
}
|
||||
}
|
||||
await sleep(5000);
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
|
@ -0,0 +1,283 @@
|
|||
import type { paths } from "./types";
|
||||
import createClient, { ClientOptions } from "openapi-fetch";
|
||||
import {
|
||||
Address,
|
||||
encodeAbiParameters,
|
||||
encodePacked,
|
||||
Hex,
|
||||
isAddress,
|
||||
isHex,
|
||||
keccak256,
|
||||
} from "viem";
|
||||
import { privateKeyToAccount, sign, signatureToHex } from "viem/accounts";
|
||||
|
||||
/**
|
||||
* ERC20 token with contract address and amount
|
||||
*/
|
||||
export type TokenQty = {
|
||||
contract: Address;
|
||||
amount: bigint;
|
||||
};
|
||||
|
||||
/**
|
||||
* Bid information
|
||||
*/
|
||||
export type BidInfo = {
|
||||
/**
|
||||
* Bid amount in wei
|
||||
*/
|
||||
amount: bigint;
|
||||
/**
|
||||
* Unix timestamp for when the bid is no longer valid in seconds
|
||||
*/
|
||||
validUntil: bigint;
|
||||
};
|
||||
|
||||
/**
|
||||
* All the parameters necessary to represent a liquidation opportunity
|
||||
*/
|
||||
export type Opportunity = {
|
||||
/**
|
||||
* The chain id where the liquidation will be executed.
|
||||
*/
|
||||
chainId: string;
|
||||
|
||||
/**
|
||||
* Unique identifier for the opportunity
|
||||
*/
|
||||
opportunityId: string;
|
||||
/**
|
||||
* Permission key required for succesful execution of the liquidation.
|
||||
*/
|
||||
permissionKey: Hex;
|
||||
/**
|
||||
* Contract address to call for execution of the liquidation.
|
||||
*/
|
||||
contract: Address;
|
||||
/**
|
||||
* Calldata for the contract call.
|
||||
*/
|
||||
calldata: Hex;
|
||||
/**
|
||||
* Value to send with the contract call.
|
||||
*/
|
||||
value: bigint;
|
||||
|
||||
/**
|
||||
* Tokens required to repay the debt
|
||||
*/
|
||||
repayTokens: TokenQty[];
|
||||
/**
|
||||
* Tokens to receive after the liquidation
|
||||
*/
|
||||
receiptTokens: TokenQty[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a bid for a liquidation opportunity
|
||||
*/
|
||||
export type OpportunityBid = {
|
||||
/**
|
||||
* Opportunity unique identifier in uuid format
|
||||
*/
|
||||
opportunityId: string;
|
||||
/**
|
||||
* The permission key required for succesful execution of the liquidation.
|
||||
*/
|
||||
permissionKey: Hex;
|
||||
/**
|
||||
* Liquidator address
|
||||
*/
|
||||
liquidator: Address;
|
||||
/**
|
||||
* Signature of the liquidator
|
||||
*/
|
||||
signature: Hex;
|
||||
|
||||
bid: BidInfo;
|
||||
};
|
||||
|
||||
export function checkHex(hex: string): Hex {
|
||||
if (isHex(hex)) {
|
||||
return hex;
|
||||
}
|
||||
throw new Error(`Invalid hex: ${hex}`);
|
||||
}
|
||||
|
||||
export function checkAddress(address: string): Address {
|
||||
if (isAddress(address)) {
|
||||
return address;
|
||||
}
|
||||
throw new Error(`Invalid address: ${address}`);
|
||||
}
|
||||
|
||||
function checkTokenQty(token: { contract: string; amount: string }): TokenQty {
|
||||
return {
|
||||
contract: checkAddress(token.contract),
|
||||
amount: BigInt(token.amount),
|
||||
};
|
||||
}
|
||||
|
||||
export class Client {
|
||||
private clientOptions?: ClientOptions;
|
||||
|
||||
constructor(clientOptions?: ClientOptions) {
|
||||
this.clientOptions = clientOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches liquidation opportunities
|
||||
* @param chainId Chain id to fetch opportunities for. e.g: sepolia
|
||||
*/
|
||||
async getOpportunities(chainId?: string): Promise<Opportunity[]> {
|
||||
const client = createClient<paths>(this.clientOptions);
|
||||
const opportunities = await client.GET("/v1/liquidation/opportunities", {
|
||||
params: { query: { chain_id: chainId } },
|
||||
});
|
||||
if (opportunities.data === undefined) {
|
||||
throw new Error("No opportunities found");
|
||||
}
|
||||
return opportunities.data.flatMap((opportunity) => {
|
||||
if (opportunity.version != "v1") {
|
||||
console.warn(
|
||||
`Can not handle opportunity version: ${opportunity.version}. Please upgrade your client.`
|
||||
);
|
||||
return [];
|
||||
}
|
||||
return {
|
||||
chainId: opportunity.chain_id,
|
||||
opportunityId: opportunity.opportunity_id,
|
||||
permissionKey: checkHex(opportunity.permission_key),
|
||||
contract: checkAddress(opportunity.contract),
|
||||
calldata: checkHex(opportunity.calldata),
|
||||
value: BigInt(opportunity.value),
|
||||
repayTokens: opportunity.repay_tokens.map(checkTokenQty),
|
||||
receiptTokens: opportunity.receipt_tokens.map(checkTokenQty),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Submits a liquidation opportunity to be exposed to searchers
|
||||
* @param opportunity Opportunity to submit
|
||||
*/
|
||||
async submitOpportunity(opportunity: Omit<Opportunity, "opportunityId">) {
|
||||
const client = createClient<paths>(this.clientOptions);
|
||||
const response = await client.POST("/v1/liquidation/opportunities", {
|
||||
body: {
|
||||
chain_id: opportunity.chainId,
|
||||
version: "v1",
|
||||
permission_key: opportunity.permissionKey,
|
||||
contract: opportunity.contract,
|
||||
calldata: opportunity.calldata,
|
||||
value: opportunity.value.toString(),
|
||||
repay_tokens: opportunity.repayTokens.map((token) => ({
|
||||
contract: token.contract,
|
||||
amount: token.amount.toString(),
|
||||
})),
|
||||
receipt_tokens: opportunity.receiptTokens.map((token) => ({
|
||||
contract: token.contract,
|
||||
amount: token.amount.toString(),
|
||||
})),
|
||||
},
|
||||
});
|
||||
if (response.error) {
|
||||
throw new Error(response.error.error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a signed bid for a liquidation opportunity
|
||||
* @param opportunity Opportunity to bid on
|
||||
* @param bidInfo Bid amount and valid until timestamp
|
||||
* @param privateKey Private key to sign the bid with
|
||||
*/
|
||||
async signOpportunityBid(
|
||||
opportunity: Opportunity,
|
||||
bidInfo: BidInfo,
|
||||
privateKey: Hex
|
||||
): Promise<OpportunityBid> {
|
||||
const account = privateKeyToAccount(privateKey);
|
||||
const convertTokenQty = (token: TokenQty): [Hex, bigint] => [
|
||||
token.contract,
|
||||
token.amount,
|
||||
];
|
||||
const payload = encodeAbiParameters(
|
||||
[
|
||||
{
|
||||
name: "repayTokens",
|
||||
type: "tuple[]",
|
||||
components: [
|
||||
{
|
||||
type: "address",
|
||||
},
|
||||
{
|
||||
type: "uint256",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "receiptTokens",
|
||||
type: "tuple[]",
|
||||
components: [
|
||||
{
|
||||
type: "address",
|
||||
},
|
||||
{
|
||||
type: "uint256",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ name: "contract", type: "address" },
|
||||
{ name: "calldata", type: "bytes" },
|
||||
{ name: "value", type: "uint256" },
|
||||
{ name: "bid", type: "uint256" },
|
||||
],
|
||||
[
|
||||
opportunity.repayTokens.map(convertTokenQty),
|
||||
opportunity.receiptTokens.map(convertTokenQty),
|
||||
opportunity.contract,
|
||||
opportunity.calldata,
|
||||
opportunity.value,
|
||||
bidInfo.amount,
|
||||
]
|
||||
);
|
||||
|
||||
const msgHash = keccak256(
|
||||
encodePacked(["bytes", "uint256"], [payload, bidInfo.validUntil])
|
||||
);
|
||||
|
||||
const hash = signatureToHex(await sign({ hash: msgHash, privateKey }));
|
||||
return {
|
||||
permissionKey: opportunity.permissionKey,
|
||||
bid: bidInfo,
|
||||
liquidator: account.address,
|
||||
signature: hash,
|
||||
opportunityId: opportunity.opportunityId,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Submits a bid for a liquidation opportunity
|
||||
* @param bid
|
||||
*/
|
||||
async submitOpportunityBid(bid: OpportunityBid) {
|
||||
const client = createClient<paths>(this.clientOptions);
|
||||
const response = await client.POST(
|
||||
"/v1/liquidation/opportunities/{opportunity_id}/bids",
|
||||
{
|
||||
body: {
|
||||
amount: bid.bid.amount.toString(),
|
||||
liquidator: bid.liquidator,
|
||||
permission_key: bid.permissionKey,
|
||||
signature: bid.signature,
|
||||
valid_until: bid.bid.validUntil.toString(),
|
||||
},
|
||||
params: { path: { opportunity_id: bid.opportunityId } },
|
||||
}
|
||||
);
|
||||
if (response.error) {
|
||||
throw new Error(response.error.error);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,319 @@
|
|||
/**
|
||||
* This file was auto-generated by openapi-typescript.
|
||||
* Do not make direct changes to the file.
|
||||
*/
|
||||
|
||||
export interface paths {
|
||||
"/v1/bids": {
|
||||
/**
|
||||
* Bid on a specific permission key for a specific chain.
|
||||
* @description Bid on a specific permission key for a specific chain.
|
||||
*
|
||||
* Your bid will be simulated and verified by the server. Depending on the outcome of the auction, a transaction
|
||||
* containing the contract call will be sent to the blockchain expecting the bid amount to be paid after the call.
|
||||
*/
|
||||
post: operations["bid"];
|
||||
};
|
||||
"/v1/liquidation/opportunities": {
|
||||
/**
|
||||
* Fetch all liquidation opportunities ready to be exectued.
|
||||
* @description Fetch all liquidation opportunities ready to be exectued.
|
||||
*/
|
||||
get: operations["get_opportunities"];
|
||||
/**
|
||||
* Submit a liquidation opportunity ready to be executed.
|
||||
* @description Submit a liquidation opportunity ready to be executed.
|
||||
*
|
||||
* The opportunity will be verified by the server. If the opportunity is valid, it will be stored in the database
|
||||
* and will be available for bidding.
|
||||
*/
|
||||
post: operations["post_opportunity"];
|
||||
};
|
||||
"/v1/liquidation/opportunities/{opportunity_id}/bids": {
|
||||
/**
|
||||
* Bid on liquidation opportunity
|
||||
* @description Bid on liquidation opportunity
|
||||
*/
|
||||
post: operations["post_bid"];
|
||||
};
|
||||
}
|
||||
|
||||
export type webhooks = Record<string, never>;
|
||||
|
||||
export interface components {
|
||||
schemas: {
|
||||
Bid: {
|
||||
/**
|
||||
* @description Amount of bid in wei.
|
||||
* @example 10
|
||||
*/
|
||||
amount: string;
|
||||
/**
|
||||
* @description Calldata for the contract call.
|
||||
* @example 0xdeadbeef
|
||||
*/
|
||||
calldata: string;
|
||||
/**
|
||||
* @description The chain id to bid on.
|
||||
* @example sepolia
|
||||
*/
|
||||
chain_id: string;
|
||||
/**
|
||||
* @description The contract address to call.
|
||||
* @example 0xcA11bde05977b3631167028862bE2a173976CA11
|
||||
*/
|
||||
contract: string;
|
||||
/**
|
||||
* @description The permission key to bid on.
|
||||
* @example 0xdeadbeef
|
||||
*/
|
||||
permission_key: string;
|
||||
};
|
||||
BidResult: {
|
||||
status: string;
|
||||
};
|
||||
ErrorBodyResponse: {
|
||||
error: string;
|
||||
};
|
||||
OpportunityBid: {
|
||||
/**
|
||||
* @description The bid amount in wei.
|
||||
* @example 1000000000000000000
|
||||
*/
|
||||
amount: string;
|
||||
/**
|
||||
* @description Liquidator address
|
||||
* @example 0x5FbDB2315678afecb367f032d93F642f64180aa2
|
||||
*/
|
||||
liquidator: string;
|
||||
/**
|
||||
* @description The opportunity permission key
|
||||
* @example 0xdeadbeefcafe
|
||||
*/
|
||||
permission_key: string;
|
||||
/** @example 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef12 */
|
||||
signature: string;
|
||||
/**
|
||||
* @description How long the bid will be valid for.
|
||||
* @example 1000000000000000000
|
||||
*/
|
||||
valid_until: string;
|
||||
};
|
||||
OpportunityParams: components["schemas"]["OpportunityParamsV1"] & {
|
||||
/** @enum {string} */
|
||||
version: "v1";
|
||||
};
|
||||
/**
|
||||
* @description Opportunity parameters needed for on-chain execution
|
||||
* If a searcher signs the opportunity and have approved enough tokens to liquidation adapter,
|
||||
* by calling this contract with the given calldata and structures, they will receive the tokens specified
|
||||
* in the receipt_tokens field, and will send the tokens specified in the repay_tokens field.
|
||||
*/
|
||||
OpportunityParamsV1: {
|
||||
/**
|
||||
* @description Calldata for the contract call.
|
||||
* @example 0xdeadbeef
|
||||
*/
|
||||
calldata: string;
|
||||
/**
|
||||
* @description The chain id where the liquidation will be executed.
|
||||
* @example sepolia
|
||||
*/
|
||||
chain_id: string;
|
||||
/**
|
||||
* @description The contract address to call for execution of the liquidation.
|
||||
* @example 0xcA11bde05977b3631167028862bE2a173976CA11
|
||||
*/
|
||||
contract: string;
|
||||
/**
|
||||
* @description The permission key required for succesful execution of the liquidation.
|
||||
* @example 0xdeadbeefcafe
|
||||
*/
|
||||
permission_key: string;
|
||||
receipt_tokens: components["schemas"]["TokenQty"][];
|
||||
repay_tokens: components["schemas"]["TokenQty"][];
|
||||
/**
|
||||
* @description The value to send with the contract call.
|
||||
* @example 1
|
||||
*/
|
||||
value: string;
|
||||
};
|
||||
/** @description Similar to OpportunityParams, but with the opportunity id included. */
|
||||
OpportunityParamsWithId: components["schemas"]["OpportunityParams"] & {
|
||||
/**
|
||||
* @description The opportunity unique id
|
||||
* @example f47ac10b-58cc-4372-a567-0e02b2c3d479
|
||||
*/
|
||||
opportunity_id: string;
|
||||
};
|
||||
TokenQty: {
|
||||
/**
|
||||
* @description Token amount
|
||||
* @example 1000
|
||||
*/
|
||||
amount: string;
|
||||
/**
|
||||
* @description Token contract address
|
||||
* @example 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
|
||||
*/
|
||||
contract: string;
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
BidResult: {
|
||||
content: {
|
||||
"application/json": {
|
||||
status: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
/** @description An error occurred processing the request */
|
||||
ErrorBodyResponse: {
|
||||
content: {
|
||||
"application/json": {
|
||||
error: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
/** @description Similar to OpportunityParams, but with the opportunity id included. */
|
||||
OpportunityParamsWithId: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["OpportunityParams"] & {
|
||||
/**
|
||||
* @description The opportunity unique id
|
||||
* @example f47ac10b-58cc-4372-a567-0e02b2c3d479
|
||||
*/
|
||||
opportunity_id: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
parameters: never;
|
||||
requestBodies: never;
|
||||
headers: never;
|
||||
pathItems: never;
|
||||
}
|
||||
|
||||
export type $defs = Record<string, never>;
|
||||
|
||||
export type external = Record<string, never>;
|
||||
|
||||
export interface operations {
|
||||
/**
|
||||
* Bid on a specific permission key for a specific chain.
|
||||
* @description Bid on a specific permission key for a specific chain.
|
||||
*
|
||||
* Your bid will be simulated and verified by the server. Depending on the outcome of the auction, a transaction
|
||||
* containing the contract call will be sent to the blockchain expecting the bid amount to be paid after the call.
|
||||
*/
|
||||
bid: {
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["Bid"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Bid was placed succesfully */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["BidResult"];
|
||||
};
|
||||
};
|
||||
400: components["responses"]["ErrorBodyResponse"];
|
||||
/** @description Chain id was not found */
|
||||
404: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["ErrorBodyResponse"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Fetch all liquidation opportunities ready to be exectued.
|
||||
* @description Fetch all liquidation opportunities ready to be exectued.
|
||||
*/
|
||||
get_opportunities: {
|
||||
parameters: {
|
||||
query?: {
|
||||
/** @example sepolia */
|
||||
chain_id?: string | null;
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Array of liquidation opportunities ready for bidding */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["OpportunityParamsWithId"][];
|
||||
};
|
||||
};
|
||||
400: components["responses"]["ErrorBodyResponse"];
|
||||
/** @description Chain id was not found */
|
||||
404: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["ErrorBodyResponse"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Submit a liquidation opportunity ready to be executed.
|
||||
* @description Submit a liquidation opportunity ready to be executed.
|
||||
*
|
||||
* The opportunity will be verified by the server. If the opportunity is valid, it will be stored in the database
|
||||
* and will be available for bidding.
|
||||
*/
|
||||
post_opportunity: {
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["OpportunityParams"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description The created opportunity */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["OpportunityParamsWithId"];
|
||||
};
|
||||
};
|
||||
400: components["responses"]["ErrorBodyResponse"];
|
||||
/** @description Chain id was not found */
|
||||
404: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["ErrorBodyResponse"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Bid on liquidation opportunity
|
||||
* @description Bid on liquidation opportunity
|
||||
*/
|
||||
post_bid: {
|
||||
parameters: {
|
||||
path: {
|
||||
/** @description Opportunity id to bid on */
|
||||
opportunity_id: string;
|
||||
};
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["OpportunityBid"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Bid Result */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["BidResult"];
|
||||
};
|
||||
};
|
||||
400: components["responses"]["ErrorBodyResponse"];
|
||||
/** @description Opportunity or chain id was not found */
|
||||
404: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["ErrorBodyResponse"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "commonjs",
|
||||
"declaration": true,
|
||||
"rootDir": "src/",
|
||||
"outDir": "./lib",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "**/__tests__/*"]
|
||||
}
|
Loading…
Reference in New Issue