From 02bba108e78820dc4f13c71d7ffc82b422d68ad2 Mon Sep 17 00:00:00 2001 From: Danial Date: Mon, 19 Aug 2024 18:19:42 +0900 Subject: [PATCH] Add documentation of the API using tspec --- packages/relay/.gitignore | 1 + packages/relay/package.json | 1 + packages/relay/src/DefaultServer.ts | 22 +- packages/relay/src/routers/BridgeRouter.ts | 2 +- packages/relay/src/routers/DefaultRouter.ts | 5 +- packages/relay/src/routers/ETCRouter.ts | 2 +- packages/relay/src/routers/HistoryRouter.ts | 2 +- packages/relay/src/routers/LedgerRouter.ts | 2 +- packages/relay/src/routers/PaymentRouter.ts | 2 +- packages/relay/src/routers/PhoneLinkRouter.ts | 2 +- packages/relay/src/routers/ProviderRouter.ts | 2 +- packages/relay/src/routers/ShopRouter.ts | 2 +- .../relay/src/routers/StorePurchaseRouter.ts | 2 +- packages/relay/src/routers/TokenRouter.ts | 2 +- packages/relay/tspec.config.json | 13 + packages/relay/tspec/01_Ledger.ts | 310 +++++++ packages/relay/tspec/02_Shop.ts | 590 +++++++++++++ packages/relay/tspec/03_Payment.ts | 803 ++++++++++++++++++ packages/relay/tspec/05_Phone.ts | 48 ++ packages/relay/tspec/05_PhoneLink.ts | 128 +++ packages/relay/tspec/06_Currency.ts | 53 ++ packages/relay/tspec/07_Summary.ts | 424 +++++++++ packages/relay/tspec/08_Bridge.ts | 274 ++++++ packages/relay/tspec/09_Chain.ts | 520 ++++++++++++ packages/relay/tspec/10_Provider.ts | 360 ++++++++ packages/relay/tspec/15_History.ts | 404 +++++++++ packages/relay/tspec/20_CallBack.ts | 140 +++ packages/relay/tspec/types.ts | 229 +++++ yarn.lock | 200 ++++- 29 files changed, 4518 insertions(+), 27 deletions(-) create mode 100644 packages/relay/tspec.config.json create mode 100644 packages/relay/tspec/01_Ledger.ts create mode 100644 packages/relay/tspec/02_Shop.ts create mode 100644 packages/relay/tspec/03_Payment.ts create mode 100644 packages/relay/tspec/05_Phone.ts create mode 100644 packages/relay/tspec/05_PhoneLink.ts create mode 100644 packages/relay/tspec/06_Currency.ts create mode 100644 packages/relay/tspec/07_Summary.ts create mode 100644 packages/relay/tspec/08_Bridge.ts create mode 100644 packages/relay/tspec/09_Chain.ts create mode 100644 packages/relay/tspec/10_Provider.ts create mode 100644 packages/relay/tspec/15_History.ts create mode 100644 packages/relay/tspec/20_CallBack.ts create mode 100644 packages/relay/tspec/types.ts diff --git a/packages/relay/.gitignore b/packages/relay/.gitignore index be64f17c..42a41d33 100644 --- a/packages/relay/.gitignore +++ b/packages/relay/.gitignore @@ -141,3 +141,4 @@ typechain-types cache artifacts +generate/* diff --git a/packages/relay/package.json b/packages/relay/package.json index 7c7db8cb..9fbd6c97 100644 --- a/packages/relay/package.json +++ b/packages/relay/package.json @@ -103,6 +103,7 @@ "ts-node": "^10.5.0", "tslint": "^6.1.3", "tslint-config-prettier": "^1.18.0", + "tspec": "^0.1.116", "typechain": "^8.1.0", "typescript": "^4.5.5", "urijs": "^1.19.7", diff --git a/packages/relay/src/DefaultServer.ts b/packages/relay/src/DefaultServer.ts index 2c58d2d9..8c2ce080 100644 --- a/packages/relay/src/DefaultServer.ts +++ b/packages/relay/src/DefaultServer.ts @@ -221,17 +221,17 @@ export class DefaultServer extends WebService { }) ); - this.defaultRouter.registerRoutes(); - this.ledgerRouter.registerRoutes(); - this.shopRouter.registerRoutes(); - this.paymentRouter.registerRoutes(); - this.etcRouter.registerRoutes(); - this.purchaseRouter.registerRoutes(); - this.tokenRouter.registerRoutes(); - this.phoneLinkRouter.registerRoutes(); - this.providerRouter.registerRoutes(); - this.bridgeRouter.registerRoutes(); - this.historyRouter.registerRoutes(); + await this.defaultRouter.registerRoutes(); + await this.ledgerRouter.registerRoutes(); + await this.shopRouter.registerRoutes(); + await this.paymentRouter.registerRoutes(); + await this.etcRouter.registerRoutes(); + await this.purchaseRouter.registerRoutes(); + await this.tokenRouter.registerRoutes(); + await this.phoneLinkRouter.registerRoutes(); + await this.providerRouter.registerRoutes(); + await this.bridgeRouter.registerRoutes(); + await this.historyRouter.registerRoutes(); for (const m of this.schedules) await m.start(); diff --git a/packages/relay/src/routers/BridgeRouter.ts b/packages/relay/src/routers/BridgeRouter.ts index 384a6142..01cc461b 100644 --- a/packages/relay/src/routers/BridgeRouter.ts +++ b/packages/relay/src/routers/BridgeRouter.ts @@ -81,7 +81,7 @@ export class BridgeRouter { }; } - public registerRoutes() { + public async registerRoutes() { this.app.post( "/v1/bridge/withdraw", [ diff --git a/packages/relay/src/routers/DefaultRouter.ts b/packages/relay/src/routers/DefaultRouter.ts index 5a0aaadf..9abf2b85 100644 --- a/packages/relay/src/routers/DefaultRouter.ts +++ b/packages/relay/src/routers/DefaultRouter.ts @@ -3,6 +3,8 @@ import { ContractManager } from "../contract/ContractManager"; import { Metrics } from "../metrics/Metrics"; import { WebService } from "../service/WebService"; +import { Tspec, TspecDocsMiddleware } from "tspec"; + import { BigNumber, Wallet } from "ethers"; import express from "express"; @@ -23,11 +25,12 @@ export class DefaultRouter { return this.web_service.app; } - public registerRoutes() { + public async registerRoutes() { // Get Health Status this.app.get("/", [], this.getHealthStatus.bind(this)); this.app.post("/callback", [], this.callback.bind(this)); this.app.get("/metrics", [], this.getMetrics.bind(this)); + this.app.use("/docs", await TspecDocsMiddleware()); } private async getHealthStatus(req: express.Request, res: express.Response) { diff --git a/packages/relay/src/routers/ETCRouter.ts b/packages/relay/src/routers/ETCRouter.ts index 06a2af2e..f8743f80 100644 --- a/packages/relay/src/routers/ETCRouter.ts +++ b/packages/relay/src/routers/ETCRouter.ts @@ -61,7 +61,7 @@ export class ETCRouter { }; } - public registerRoutes() { + public async registerRoutes() { // 포인트의 종류를 선택하는 기능 this.app.post( "/v1/mobile/register", diff --git a/packages/relay/src/routers/HistoryRouter.ts b/packages/relay/src/routers/HistoryRouter.ts index f88e8ff7..ce222d5f 100644 --- a/packages/relay/src/routers/HistoryRouter.ts +++ b/packages/relay/src/routers/HistoryRouter.ts @@ -86,7 +86,7 @@ export class HistoryRouter { }; } - public registerRoutes() { + public async registerRoutes() { this.app.get( "/v1/token/main/history/:account", [ diff --git a/packages/relay/src/routers/LedgerRouter.ts b/packages/relay/src/routers/LedgerRouter.ts index 2d0ec67e..22ad6c27 100644 --- a/packages/relay/src/routers/LedgerRouter.ts +++ b/packages/relay/src/routers/LedgerRouter.ts @@ -86,7 +86,7 @@ export class LedgerRouter { }; } - public registerRoutes() { + public async registerRoutes() { this.app.get( "/v1/ledger/nonce/:account", [param("account").exists().trim().isEthereumAddress()], diff --git a/packages/relay/src/routers/PaymentRouter.ts b/packages/relay/src/routers/PaymentRouter.ts index 442475db..7ad710ed 100644 --- a/packages/relay/src/routers/PaymentRouter.ts +++ b/packages/relay/src/routers/PaymentRouter.ts @@ -68,7 +68,7 @@ export class PaymentRouter { return this.web_service.app; } - public registerRoutes() { + public async registerRoutes() { this.app.get( "/v1/payment/user/balance", [query("account").exists().trim().isEthereumAddress()], diff --git a/packages/relay/src/routers/PhoneLinkRouter.ts b/packages/relay/src/routers/PhoneLinkRouter.ts index ce238da2..be8ecbf8 100644 --- a/packages/relay/src/routers/PhoneLinkRouter.ts +++ b/packages/relay/src/routers/PhoneLinkRouter.ts @@ -80,7 +80,7 @@ export class PhoneLinkRouter { }; } - public registerRoutes() { + public async registerRoutes() { this.app.get( "/v1/link/nonce/:account", [param("account").exists().trim().isEthereumAddress()], diff --git a/packages/relay/src/routers/ProviderRouter.ts b/packages/relay/src/routers/ProviderRouter.ts index 48a68429..b286d5ed 100644 --- a/packages/relay/src/routers/ProviderRouter.ts +++ b/packages/relay/src/routers/ProviderRouter.ts @@ -84,7 +84,7 @@ export class ProviderRouter { }; } - public registerRoutes() { + public async registerRoutes() { this.app.post( "/v1/provider/register", [ diff --git a/packages/relay/src/routers/ShopRouter.ts b/packages/relay/src/routers/ShopRouter.ts index 1fda9286..e20f7d48 100644 --- a/packages/relay/src/routers/ShopRouter.ts +++ b/packages/relay/src/routers/ShopRouter.ts @@ -101,7 +101,7 @@ export class ShopRouter { }; } - public registerRoutes() { + public async registerRoutes() { this.app.get( "/v1/shop/nonce/:account", [param("account").exists().trim().isEthereumAddress()], diff --git a/packages/relay/src/routers/StorePurchaseRouter.ts b/packages/relay/src/routers/StorePurchaseRouter.ts index acdd7b74..6ad7e974 100644 --- a/packages/relay/src/routers/StorePurchaseRouter.ts +++ b/packages/relay/src/routers/StorePurchaseRouter.ts @@ -62,7 +62,7 @@ export class StorePurchaseRouter { }; } - public registerRoutes() { + public async registerRoutes() { this.app.post( "/v1/purchase/save", [ diff --git a/packages/relay/src/routers/TokenRouter.ts b/packages/relay/src/routers/TokenRouter.ts index 4104692b..8b179ca5 100644 --- a/packages/relay/src/routers/TokenRouter.ts +++ b/packages/relay/src/routers/TokenRouter.ts @@ -84,7 +84,7 @@ export class TokenRouter { }; } - public registerRoutes() { + public async registerRoutes() { this.app.get( "/v1/token/main/balance/:account", [param("account").exists().trim().isEthereumAddress()], diff --git a/packages/relay/tspec.config.json b/packages/relay/tspec.config.json new file mode 100644 index 00000000..9a96ccef --- /dev/null +++ b/packages/relay/tspec.config.json @@ -0,0 +1,13 @@ +{ + "specPathGlobs": ["tspec/**/*.ts"], + "tsconfigPath": "./tsconfig.json", + "outputPath": "./generate/openapi.json", + "specVersion": 3, + "openapi": { + "title": "Decentralized Loyalty System API", + "version": "1.0.0", + "description": "API of Decentralized Loyalty System

The amount of tokens and points
The amount of tokens and points is a string. The decimal place is 18. One point is expressed as \"100000000000000000000\".

Responses
Response data consists of three parts: `code`, `data`, `error`.
The value of code is 0 if normal. In this case, the value of data exists.
If an error occurs during the processing, the value of code is not zero. At this time, you can check the contents of error to find the cause." + }, + "debug": false, + "ignoreErrors": true +} diff --git a/packages/relay/tspec/01_Ledger.ts b/packages/relay/tspec/01_Ledger.ts new file mode 100644 index 00000000..f02fbae2 --- /dev/null +++ b/packages/relay/tspec/01_Ledger.ts @@ -0,0 +1,310 @@ +import { Tspec } from "tspec"; +import { ResultCode } from "./types"; + +export type LedgerApiSpec = Tspec.DefineApiSpec<{ + tags: ["Ledger"]; + paths: { + "/v1/ledger/balance/account/{account}": { + get: { + summary: "Provide the balance corresponding to the wallet address"; + description: "It provides both the balance of points and tokens.
It also provides the value converted into basic currency units along with the balance."; + path: { + /** + * Address of wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + + data?: { + /** + * Address of wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + + point: { + /** + * Balance of Point (info. decimals are 18) + * @example "10000000000000000000000000" + */ + balance: string; + /** + * Value of Point (info. decimals are 18) + * @example "10000000000000000000000000" + */ + value: string; + }; + + token: { + /** + * Balance of Token (info. decimals are 18) + * @example "100000000000000000000000" + */ + balance: string; + /** + * Value of Token (info. decimals are 18) + * @example "112108371800000000000000" + */ + value: string; + }; + }; + + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/ledger/balance/phone/{phone}": { + get: { + summary: "Provide the balance corresponding to the user`s phone number"; + description: "It provides both the balance of points and tokens.
It also provides the value converted into basic currency units along with the balance."; + path: { + /** + * Phone number + * @example "+82 10-1000-5000" + */ + phone: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + + data: { + /** + * Phone Number + * @example "+82 10-1000-5000" + */ + phone: string; + + /** + * Phone Number Hash + * @example "0xF48F4BF6C8B5B285F0D9EB5D52623EE14B6F2B5980E87FAC89E4B968995FAE2B" + */ + phoneHash: string; + + /** + * Address of wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + + point: { + /** + * Balance of Point (info. decimals are 18) + * @example "10000000000000000000000000" + */ + balance: string; + /** + * Value of Point (info. decimals are 18) + * @example "10000000000000000000000000" + */ + value: string; + }; + + token: { + /** + * Balance of Token (info. decimals are 18) + * @example "100000000000000000000000" + */ + balance: string; + /** + * Value of Token (info. decimals are 18) + * @example "112108371800000000000000" + */ + value: string; + }; + }; + + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/ledger/balance/phoneHash/{phoneHash}": { + get: { + summary: "Provide the balance corresponding to the user's phone number hash"; + description: "It provides both the balance of points and tokens.
It also provides the value converted into basic currency units along with the balance."; + path: { + /** + * Phone number hash + * @example "0xF48F4BF6C8B5B285F0D9EB5D52623EE14B6F2B5980E87FAC89E4B968995FAE2B" + */ + phoneHash: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + + data: { + /** + * Phone Number Hash + * @example "0xF48F4BF6C8B5B285F0D9EB5D52623EE14B6F2B5980E87FAC89E4B968995FAE2B" + */ + phoneHash: string; + + /** + * Address of wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + + point: { + /** + * Balance of Point (info. decimals are 18) + * @example "10000000000000000000000000" + */ + balance: string; + /** + * Value of Point (info. decimals are 18) + * @example "10000000000000000000000000" + */ + value: string; + }; + + token: { + /** + * Balance of Token (info. decimals are 18) + * @example "100000000000000000000000" + */ + balance: string; + /** + * Value of Token (info. decimals are 18) + * @example "112108371800000000000000" + */ + value: string; + }; + }; + + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/ledger/nonce/{account}": { + get: { + summary: "Provide the nonce corresponding to the user's wallet address"; + description: "The nonce is required for signing.
This is to produce a signature result that is not the same, including the ever-changing nonce in the original data to be signed.
The nonce is recorded in the contract, which increases the value of the nonce by 1 when the signature is used."; + path: { + /** + * Address of wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + + data: { + /** + * Address of wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + + /** + * Nonce for address of wallet in Ledger Contract + * @example "45" + */ + nonce: string; + }; + + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/ledger/exchangePointToToken": { + post: { + summary: "Exchange points to tokens"; + description: "Exchange your points for tokens.
Signatures are required to request this.
Your wallet address, amount of exchange, nonce, and chain ID will be used for your signature.
The exchange rate is based on the price of the token recorded by the validators by agreement."; + body: { + /** + * Wallet address of user + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + /** + * Amount to be exchanged (info. decimals are 18) + * @example "100000000000000000000000" + */ + amount: string; + /** + * Signature of user wallet + * @example "0x020d671b80fbd20466d8cb65cef79a24e3bca3fdf82e9dd89d78e7a4c4c045bd72944c20bb1d839e76ee6bb69fed61f64376c37799598b40b8c49148f3cdd88a1b" + */ + signature: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + + data: { + /** + * Hash of transaction + * @example "0x3798157a3f32c0ed7692f240eb83f3a3c2f6077c5ad7acf7a9a54d426d63632e" + */ + txHash: string; + }; + + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + }; +}>; diff --git a/packages/relay/tspec/02_Shop.ts b/packages/relay/tspec/02_Shop.ts new file mode 100644 index 00000000..3467e097 --- /dev/null +++ b/packages/relay/tspec/02_Shop.ts @@ -0,0 +1,590 @@ +import { Tspec } from "tspec"; +import { ResultCode, ShopTaskStatus } from "./types"; + +export type ShopApiSpec = Tspec.DefineApiSpec<{ + tags: ["Shop"]; + paths: { + "/v1/shop/info/{shopId}": { + get: { + summary: "Provide shop information"; + path: { + /** + * ID of Shop + * @example "0x0001be96d74202df38fd21462ffcef10dfe0fcbd7caa3947689a3903e8b6b874" + */ + shopId: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * ID of Shop + * @example "0x0001be96d74202df38fd21462ffcef10dfe0fcbd7caa3947689a3903e8b6b874" + */ + shopId: string; + /** + * Name of Shop + * @example "Coffee Nine" + */ + name: string; + /** + * Basic currency symbol of Shop + * @example "php" + */ + currency: string; + /** + * Active status of Shop ( 0: None, 1: ACTIVE, 2: INACTIVE ) + * @example 1 + */ + status: number; + /** + * Wallet address of the shop owner + * @example "0xafFe745418Ad24c272175e5B58610A8a35e2EcDa" + */ + account: string; + /** + * Wallet address that authorizes cancellation on behalf of the shop owner + * @example "0xD10ADf251463A260242c216c8c7D3e736eBdB398" + */ + delegator: string; + /** + * Amount of provided + * @example "1000000000000000000000" + */ + providedAmount: string; + /** + * Amount of used + * @example "2000000000000000000000" + */ + usedAmount: string; + /** + * Amount of refunded + * @example "0" + */ + refundedAmount: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/shop/list": { + get: { + summary: "Provide all shop information"; + query: { + /** + * Current Page Number + * @example 1 + */ + pageNumber: number; + /** + * Number of items per page + * @example 10 + */ + pageSize: number; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * ID of Shop + * @example "0x0001be96d74202df38fd21462ffcef10dfe0fcbd7caa3947689a3903e8b6b874" + */ + shopId: string; + /** + * Name of Shop + * @example "Coffee Nine" + */ + name: string; + /** + * Basic currency symbol of Shop + * @example "php" + */ + currency: string; + /** + * Active status of Shop ( 0: None, 1: ACTIVE, 2: INACTIVE ) + * @example 1 + */ + status: number; + /** + * Wallet address of the shop owner + * @example "0xafFe745418Ad24c272175e5B58610A8a35e2EcDa" + */ + account: string; + /** + * Amount of provided + * @example "1000000000000000000000" + */ + providedAmount: string; + /** + * Amount of used + * @example "2000000000000000000000" + */ + usedAmount: string; + /** + * Amount of refunded + * @example "0" + */ + refundedAmount: string; + }[]; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/shop/nonce/{account}": { + get: { + summary: "Provide the nonce corresponding to the wallet address of the shop owner"; + description: "The nonce is required for signing.
This is to produce a signature result that is not the same, including the ever-changing nonce in the original data to be signed.
The nonce is recorded in the contract, which increases the value of the nonce by 1 when the signature is used."; + path: { + /** + * Address of wallet + * @example "0xafFe745418Ad24c272175e5B58610A8a35e2EcDa" + */ + account: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Address of wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + + /** + * Nonce for address of wallet in Shop Contract + * @example "45" + */ + nonce: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/shop/refundable/{shopId}": { + get: { + summary: "Provide refundable amount"; + path: { + /** + * ID of Shop + * @example "0x0001be96d74202df38fd21462ffcef10dfe0fcbd7caa3947689a3903e8b6b874" + */ + shopId: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Basic currency amount equivalent to refundable amount + * @example "2000000000000000000000" + */ + refundableAmount: string; + /** + * Token amount equivalent to refundable amount + * @example "500000000000000000000" + */ + refundableToken: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/shop/update/create": { + post: { + summary: "Start changing the name and rate symbol of the shop. Completed after successful approval of the shop owner"; + body: { + /** + * ID of Shop + * @example "0x0001be96d74202df38fd21462ffcef10dfe0fcbd7caa3947689a3903e8b6b874" + */ + shopId: string; + /** + * Name of Shop + * @example "Coffee Nine" + */ + name: string; + /** + * Basic currency symbol of Shop + * @example "php" + */ + currency: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * ID of Task + * @example "0x6d335fe57648a92b6024be84fd4f265fb497366a916f5a28a5f2a04e523d9c7b" + */ + taskId: string; + /** + * ID of Shop + * @example "0x0001be96d74202df38fd21462ffcef10dfe0fcbd7caa3947689a3903e8b6b874" + */ + shopId: string; + /** + * Name of Shop + * @example "Coffee Nine" + */ + name: string; + /** + * Basic currency symbol of Shop + * @example "php" + */ + currency: string; + /** + * Task progress status ( 11: OPENED, 12: FAILED_TX, 13: REVERTED_TX, 14: SENT_TX, 15: DENIED, 16: COMPLETED ) + * @example 11 + */ + taskStatus: ShopTaskStatus; + /** + * Task start time + * @example 1722948039 + */ + timestamp: number; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/shop/update/approval": { + post: { + summary: "Approve changing the name and rate symbol of the shop."; + body: { + /** + * ID of Shop + * @example "0x0001be96d74202df38fd21462ffcef10dfe0fcbd7caa3947689a3903e8b6b874" + */ + shopId: string; + /** + * Name of Shop + * @example "Coffee Nine" + */ + name: string; + /** + * Basic currency symbol of Shop + * @example "php" + */ + currency: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * ID of Task + * @example "0x6d335fe57648a92b6024be84fd4f265fb497366a916f5a28a5f2a04e523d9c7b" + */ + taskId: string; + /** + * ID of Shop + * @example "0x0001be96d74202df38fd21462ffcef10dfe0fcbd7caa3947689a3903e8b6b874" + */ + shopId: string; + /** + * Name of Shop + * @example "Coffee Nine" + */ + name: string; + /** + * Basic currency symbol of Shop + * @example "php" + */ + currency: string; + /** + * Task progress status ( 11: OPENED, 12: FAILED_TX, 13: REVERTED_TX, 14: SENT_TX, 15: DENIED, 16: COMPLETED ) + * @example 11 + */ + taskStatus: ShopTaskStatus; + /** + * Task start time + * @example 1722948039 + */ + timestamp: number; + /** + * Hash of transaction + * @example "0xe5502185d39057bd82e6dde675821b87313570df77d3e23d8e5712bd5f3fa6b6" + */ + txHash?: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/shop/status/create": { + post: { + summary: "Start changing the activation of the shop. Completed after successful approval of the shop owner"; + body: { + /** + * ID of Shop + * @example "0x0001be96d74202df38fd21462ffcef10dfe0fcbd7caa3947689a3903e8b6b874" + */ + shopId: string; + /** + * Active status of Shop ( 0: None, 1: ACTIVE, 2: INACTIVE ) + * @example 1 + */ + status: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * ID of Task + * @example "0x6d335fe57648a92b6024be84fd4f265fb497366a916f5a28a5f2a04e523d9c7b" + */ + taskId: string; + /** + * ID of Shop + * @example "0x0001be96d74202df38fd21462ffcef10dfe0fcbd7caa3947689a3903e8b6b874" + */ + shopId: string; + /** + * Active status of Shop ( 0: None, 1: ACTIVE, 2: INACTIVE ) + * @example 1 + */ + status: number; + /** + * Task progress status ( 11: OPENED, 12: FAILED_TX, 13: REVERTED_TX, 14: SENT_TX, 15: DENIED, 16: COMPLETED ) + * @example 11 + */ + taskStatus: ShopTaskStatus; + /** + * Task start time + * @example 1722948039 + */ + timestamp: number; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/shop/status/approval": { + post: { + summary: "Approve changing the activation of the shop."; + body: { + /** + * ID of Task + * @example "0x0001be96d74202df38fd21462ffcef10dfe0fcbd7caa3947689a3903e8b6b874" + */ + taskId: string; + /** + * If this value is true, the change is accepted; if false, the change is rejected. + * @example true + */ + approval: boolean; + /** + * Signature of shop owner + * @example "0x020d671b80fbd20466d8cb65cef79a24e3bca3fdf82e9dd89d78e7a4c4c045bd72944c20bb1d839e76ee6bb69fed61f64376c37799598b40b8c49148f3cdd88a1b" + */ + signature: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * ID of Task + * @example "0x6d335fe57648a92b6024be84fd4f265fb497366a916f5a28a5f2a04e523d9c7b" + */ + taskId: string; + /** + * ID of Shop + * @example "0x0001be96d74202df38fd21462ffcef10dfe0fcbd7caa3947689a3903e8b6b874" + */ + shopId: string; + /** + * Active status of Shop ( 0: None, 1: ACTIVE, 2: INACTIVE ) + * @example 1 + */ + status: number; + /** + * Task progress status ( 11: OPENED, 12: FAILED_TX, 13: REVERTED_TX, 14: SENT_TX, 15: DENIED, 16: COMPLETED ) + * @example 11 + */ + taskStatus: ShopTaskStatus; + /** + * Task start time + * @example 1722948039 + */ + timestamp: number; + /** + * Hash of transaction + * @example "0xe5502185d39057bd82e6dde675821b87313570df77d3e23d8e5712bd5f3fa6b6" + */ + txHash?: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/shop/task": { + get: { + summary: "provide details of the task."; + body: { + /** + * ID of Task + * @example "0x6d335fe57648a92b6024be84fd4f265fb497366a916f5a28a5f2a04e523d9c7b" + */ + taskId: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * ID of Task + * @example "0x6d335fe57648a92b6024be84fd4f265fb497366a916f5a28a5f2a04e523d9c7b" + */ + taskId: string; + /** + * Type of Task ("shop_add", "shop_update", "shop_status" ) + * @example "shop_update" + */ + type: string; + /** + * ID of Shop + * @example "0x0001be96d74202df38fd21462ffcef10dfe0fcbd7caa3947689a3903e8b6b874" + */ + shopId: string; + /** + * Name of Shop + * @example "Coffee Nine" + */ + name: string; + /** + * Basic currency symbol of Shop + * @example "php" + */ + currency: string; + /** + * Active status of Shop ( 0: None, 1: ACTIVE, 2: INACTIVE ) + * @example 1 + */ + status: number; + /** + * Task progress status ( 11: OPENED, 12: FAILED_TX, 13: REVERTED_TX, 14: SENT_TX, 15: DENIED, 16: COMPLETED ) + * @example 11 + */ + taskStatus: ShopTaskStatus; + /** + * Wallet address of the shop owner + * @example "0xafFe745418Ad24c272175e5B58610A8a35e2EcDa" + */ + account: string; + /** + * Task start time + * @example 1722948039 + */ + timestamp: number; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + }; +}>; diff --git a/packages/relay/tspec/03_Payment.ts b/packages/relay/tspec/03_Payment.ts new file mode 100644 index 00000000..96cb68c7 --- /dev/null +++ b/packages/relay/tspec/03_Payment.ts @@ -0,0 +1,803 @@ +import { Tspec } from "tspec"; +import { LoyaltyPaymentTaskStatus, ResultCode } from "./types"; + +export type PaymentApiSpec = Tspec.DefineApiSpec<{ + tags: ["Payment"]; + paths: { + "/v1/payment/account/temporary": { + post: { + summary: "Provide a temporary address for payment"; + body: { + /** + * Wallet address of user + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + /** + * Signature of user wallet + * @example "0x020d671b80fbd20466d8cb65cef79a24e3bca3fdf82e9dd89d78e7a4c4c045bd72944c20bb1d839e76ee6bb69fed61f64376c37799598b40b8c49148f3cdd88a1b" + */ + signature: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Temporary wallet address for payment + * @example "0xfFFffffF603fe1D97658fFeF5b590B4000000000" + */ + temporaryAccount: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/payment/info": { + get: { + summary: "Check the user's balance for the amount required to start the payment"; + query: { + /** + * Wallet address of user or temporary wallet address of user + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + /** + * Amount to be used for payment (info. decimals are 18) + * @example "100000000000000000000000" + */ + amount: string; + /** + * Currency symbol for amount to be used for payment + * @example "php" + */ + currency: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Wallet address for payment + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + /** + * Amount to be used for payment (info. decimals are 18) + * @example "100000000000000000000" + */ + amount: string; + /** + * Currency symbol for amount to be used for payment + * @example "php" + */ + currency: string; + /** + * User's point balance (info. decimals are 18) + * @example "100000000000000000000000" + */ + balance: string; + /** + * User's point balance converted to payment currency (info. decimals are 18) + * @example "100000000000000000000000" + */ + balanceValue: string; + /** + * Amount of points to be paid (info. decimals are 18) + * @example "100000000000000000000" + */ + paidPoint: string; + /** + * Amount of points to be paid converted to payment currency (info. decimals are 18) + * @example "100000000000000000000" + */ + paidValue: string; + /** + * Fee (info. decimals are 18) + * @example "5000000000000000000" + */ + feePoint: string; + /** + * Fee converted to payment currency (info. decimals are 18) + * @example "5000000000000000000" + */ + feeValue: string; + /** + * Amount of points to be paid including fees (info. decimals are 18) + * @example "105000000000000000000" + */ + totalPoint: string; + /** + * Amount of points to be paid including fees converted to payment currency (info. decimals are 18) + * @example "105000000000000000000" + */ + totalValue: string; + /** + * Fee Rate + * @example "5" + */ + feeRate: number; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/payment/new/open": { + post: { + summary: "Open a new payment"; + body: { + /** + * ID of Purchase + * @example "P00000000000203" + */ + purchaseId: string; + /** + * Amount to be used for payment (info. decimals are 18) + * @example "100000000000000000000" + */ + amount: string; + /** + * Currency symbol for amount to be used for payment + * @example "php" + */ + currency: string; + /** + * ID of shop + * @example "0x00011936a68f7c26797fa2ab64d444ea82c2fb1af36cdea6d4ff845da635f287" + */ + shopId: string; + /** + * Wallet address of user + * @example "0x5A3Fc8990417b3e6ddCdAE0E8039E798A609Ef84" + */ + account: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * ID of Payment + * @example "0x2d9100c28be32e1a29e55b2ead66d472a6271627235778379657d08c9dc1d901" + */ + paymentId: string; + /** + * ID of Purchase + * @example "P00000000000203" + */ + purchaseId: string; + /** + * Amount to be used for payment (info. decimals are 18) + * @example "100000000000000000000" + */ + amount: string; + /** + * Currency symbol for amount to be used for payment + * @example "php" + */ + currency: string; + /** + * ID of Shop + * @example "0x00011936a68f7c26797fa2ab64d444ea82c2fb1af36cdea6d4ff845da635f287" + */ + shopId: string; + /** + * Wallet address for payment + * @example "0x5A3Fc8990417b3e6ddCdAE0E8039E798A609Ef84" + */ + account: string; + /** + * Amount of points to be paid (info. decimals are 18) + * @example "100000000000000000000" + */ + paidPoint: string; + /** + * Amount of points to be paid converted to payment currency (info. decimals are 18) + * @example "100000000000000000000" + */ + paidValue: string; + /** + * Fee (info. decimals are 18) + * @example "5000000000000000000" + */ + feePoint: string; + /** + * Fee converted to payment currency (info. decimals are 18) + * @example "5000000000000000000" + */ + feeValue: string; + /** + * Amount of points to be paid including fees (info. decimals are 18) + * @example "105000000000000000000" + */ + totalPoint: string; + /** + * Amount of points to be paid including fees converted to payment currency (info. decimals are 18) + * @example "105000000000000000000" + */ + totalValue: string; + /** + * Progress status of payment task + * @example 18 + */ + paymentStatus: LoyaltyPaymentTaskStatus; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/payment/new/close": { + post: { + summary: "Close a new payment"; + body: { + /** + * ID of Payment + * @example "0x2d9100c28be32e1a29e55b2ead66d472a6271627235778379657d08c9dc1d901" + */ + paymentId: string; + /** + * If this value is true, the payment will be processed normally, and if this value is false, all processes that have been processed so far will be canceled. + * @example true + */ + confirm: boolean; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * ID of Payment + * @example "0x2d9100c28be32e1a29e55b2ead66d472a6271627235778379657d08c9dc1d901" + */ + paymentId: string; + /** + * ID of Purchase + * @example "P00000000000203" + */ + purchaseId: string; + /** + * Amount to be used for payment (info. decimals are 18) + * @example "100000000000000000000" + */ + amount: string; + /** + * Currency symbol for amount to be used for payment + * @example "php" + */ + currency: string; + /** + * ID of Shop + * @example "0x00011936a68f7c26797fa2ab64d444ea82c2fb1af36cdea6d4ff845da635f287" + */ + shopId: string; + /** + * Wallet address for payment + * @example "0x5A3Fc8990417b3e6ddCdAE0E8039E798A609Ef84" + */ + account: string; + /** + * Amount of points to be paid (info. decimals are 18) + * @example "100000000000000000000" + */ + paidPoint: string; + /** + * Amount of points to be paid converted to payment currency (info. decimals are 18) + * @example "100000000000000000000" + */ + paidValue: string; + /** + * Fee (info. decimals are 18) + * @example "5000000000000000000" + */ + feePoint: string; + /** + * Fee converted to payment currency (info. decimals are 18) + * @example "5000000000000000000" + */ + feeValue: string; + /** + * Amount of points to be paid including fees (info. decimals are 18) + * @example "105000000000000000000" + */ + totalPoint: string; + /** + * Amount of points to be paid including fees converted to payment currency (info. decimals are 18) + * @example "105000000000000000000" + */ + totalValue: string; + /** + * Progress status of payment task + * @example 18 + */ + paymentStatus: LoyaltyPaymentTaskStatus; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/payment/new/approval": { + post: { + summary: "Approve a new payment"; + body: { + /** + * ID of Payment + * @example "0x2d9100c28be32e1a29e55b2ead66d472a6271627235778379657d08c9dc1d901" + */ + paymentId: string; + /** + * If this value is true, the payment is accepted; if false, the payment is rejected. + * @example true + */ + approval: boolean; + /** + * Signature of user wallet + * @example "0x020d671b80fbd20466d8cb65cef79a24e3bca3fdf82e9dd89d78e7a4c4c045bd72944c20bb1d839e76ee6bb69fed61f64376c37799598b40b8c49148f3cdd88a1b" + */ + signature: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * ID of Payment + * @example "0x2d9100c28be32e1a29e55b2ead66d472a6271627235778379657d08c9dc1d901" + */ + paymentId: string; + /** + * ID of Purchase + * @example "P00000000000203" + */ + purchaseId: string; + /** + * Amount to be used for payment (info. decimals are 18) + * @example "100000000000000000000" + */ + amount: string; + /** + * Currency symbol for amount to be used for payment + * @example "php" + */ + currency: string; + /** + * ID of Shop + * @example "0x00011936a68f7c26797fa2ab64d444ea82c2fb1af36cdea6d4ff845da635f287" + */ + shopId: string; + /** + * Wallet address for payment + * @example "0x5A3Fc8990417b3e6ddCdAE0E8039E798A609Ef84" + */ + account: string; + /** + * Progress status of payment task + * @example 18 + */ + paymentStatus: LoyaltyPaymentTaskStatus; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/payment/item": { + get: { + summary: "Provider a payment information"; + body: { + /** + * ID of Payment + * @example "0x2d9100c28be32e1a29e55b2ead66d472a6271627235778379657d08c9dc1d901" + */ + paymentId: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * ID of Payment + * @example "0x2d9100c28be32e1a29e55b2ead66d472a6271627235778379657d08c9dc1d901" + */ + paymentId: string; + /** + * ID of Purchase + * @example "P00000000000203" + */ + purchaseId: string; + /** + * Amount to be used for payment (info. decimals are 18) + * @example "100000000000000000000" + */ + amount: string; + /** + * Currency symbol for amount to be used for payment + * @example "php" + */ + currency: string; + /** + * ID of Shop + * @example "0x00011936a68f7c26797fa2ab64d444ea82c2fb1af36cdea6d4ff845da635f287" + */ + shopId: string; + /** + * Wallet address for payment + * @example "0x5A3Fc8990417b3e6ddCdAE0E8039E798A609Ef84" + */ + account: string; + /** + * Amount of points to be paid (info. decimals are 18) + * @example "100000000000000000000" + */ + paidPoint: string; + /** + * Amount of points to be paid converted to payment currency (info. decimals are 18) + * @example "100000000000000000000" + */ + paidValue: string; + /** + * Fee (info. decimals are 18) + * @example "5000000000000000000" + */ + feePoint: string; + /** + * Fee converted to payment currency (info. decimals are 18) + * @example "5000000000000000000" + */ + feeValue: string; + /** + * Amount of points to be paid including fees (info. decimals are 18) + * @example "105000000000000000000" + */ + totalPoint: string; + /** + * Amount of points to be paid including fees converted to payment currency (info. decimals are 18) + * @example "105000000000000000000" + */ + totalValue: string; + /** + * Progress status of payment task + * @example 18 + */ + paymentStatus: LoyaltyPaymentTaskStatus; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/payment/cancel/open": { + post: { + summary: "Open a cancel payment"; + body: { + /** + * ID of Payment + * @example "0x2d9100c28be32e1a29e55b2ead66d472a6271627235778379657d08c9dc1d901" + */ + paymentId: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * ID of Payment + * @example "0x2d9100c28be32e1a29e55b2ead66d472a6271627235778379657d08c9dc1d901" + */ + paymentId: string; + /** + * ID of Purchase + * @example "P00000000000203" + */ + purchaseId: string; + /** + * Amount to be used for payment (info. decimals are 18) + * @example "100000000000000000000" + */ + amount: string; + /** + * Currency symbol for amount to be used for payment + * @example "php" + */ + currency: string; + /** + * ID of Shop + * @example "0x00011936a68f7c26797fa2ab64d444ea82c2fb1af36cdea6d4ff845da635f287" + */ + shopId: string; + /** + * Wallet address for payment + * @example "0x5A3Fc8990417b3e6ddCdAE0E8039E798A609Ef84" + */ + account: string; + /** + * Amount of points to be paid (info. decimals are 18) + * @example "100000000000000000000" + */ + paidPoint: string; + /** + * Amount of points to be paid converted to payment currency (info. decimals are 18) + * @example "100000000000000000000" + */ + paidValue: string; + /** + * Fee (info. decimals are 18) + * @example "5000000000000000000" + */ + feePoint: string; + /** + * Fee converted to payment currency (info. decimals are 18) + * @example "5000000000000000000" + */ + feeValue: string; + /** + * Amount of points to be paid including fees (info. decimals are 18) + * @example "105000000000000000000" + */ + totalPoint: string; + /** + * Amount of points to be paid including fees converted to payment currency (info. decimals are 18) + * @example "105000000000000000000" + */ + totalValue: string; + /** + * Progress status of payment task + * @example 18 + */ + paymentStatus: LoyaltyPaymentTaskStatus; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/payment/cancel/close": { + post: { + summary: "Close a cancel payment"; + body: { + /** + * ID of Payment + * @example "0x2d9100c28be32e1a29e55b2ead66d472a6271627235778379657d08c9dc1d901" + */ + paymentId: string; + /** + * If this value is true, the cancel payment will be processed normally, and if this value is false, all processes that have been processed so far will be canceled. + * @example true + */ + confirm: boolean; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * ID of Payment + * @example "0x2d9100c28be32e1a29e55b2ead66d472a6271627235778379657d08c9dc1d901" + */ + paymentId: string; + /** + * ID of Purchase + * @example "P00000000000203" + */ + purchaseId: string; + /** + * Amount to be used for payment (info. decimals are 18) + * @example "100000000000000000000" + */ + amount: string; + /** + * Currency symbol for amount to be used for payment + * @example "php" + */ + currency: string; + /** + * ID of Shop + * @example "0x00011936a68f7c26797fa2ab64d444ea82c2fb1af36cdea6d4ff845da635f287" + */ + shopId: string; + /** + * Wallet address for payment + * @example "0x5A3Fc8990417b3e6ddCdAE0E8039E798A609Ef84" + */ + account: string; + /** + * Amount of points to be paid (info. decimals are 18) + * @example "100000000000000000000" + */ + paidPoint: string; + /** + * Amount of points to be paid converted to payment currency (info. decimals are 18) + * @example "100000000000000000000" + */ + paidValue: string; + /** + * Fee (info. decimals are 18) + * @example "5000000000000000000" + */ + feePoint: string; + /** + * Fee converted to payment currency (info. decimals are 18) + * @example "5000000000000000000" + */ + feeValue: string; + /** + * Amount of points to be paid including fees (info. decimals are 18) + * @example "105000000000000000000" + */ + totalPoint: string; + /** + * Amount of points to be paid including fees converted to payment currency (info. decimals are 18) + * @example "105000000000000000000" + */ + totalValue: string; + /** + * Progress status of payment task + * @example 18 + */ + paymentStatus: LoyaltyPaymentTaskStatus; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/payment/cancel/approval": { + post: { + summary: "Approve a cancel payment"; + body: { + /** + * ID of Payment + * @example "0x2d9100c28be32e1a29e55b2ead66d472a6271627235778379657d08c9dc1d901" + */ + paymentId: string; + /** + * If this value is true, the payment is accepted; if false, the payment is rejected. + * @example true + */ + approval: boolean; + /** + * Signature of user wallet + * @example "0x020d671b80fbd20466d8cb65cef79a24e3bca3fdf82e9dd89d78e7a4c4c045bd72944c20bb1d839e76ee6bb69fed61f64376c37799598b40b8c49148f3cdd88a1b" + */ + signature: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * ID of Payment + * @example "0x2d9100c28be32e1a29e55b2ead66d472a6271627235778379657d08c9dc1d901" + */ + paymentId: string; + /** + * ID of Purchase + * @example "P00000000000203" + */ + purchaseId: string; + /** + * Amount to be used for payment (info. decimals are 18) + * @example "100000000000000000000" + */ + amount: string; + /** + * Currency symbol for amount to be used for payment + * @example "php" + */ + currency: string; + /** + * ID of Shop + * @example "0x00011936a68f7c26797fa2ab64d444ea82c2fb1af36cdea6d4ff845da635f287" + */ + shopId: string; + /** + * Wallet address for payment + * @example "0x5A3Fc8990417b3e6ddCdAE0E8039E798A609Ef84" + */ + account: string; + /** + * Progress status of payment task + * @example 18 + */ + paymentStatus: LoyaltyPaymentTaskStatus; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + }; +}>; diff --git a/packages/relay/tspec/05_Phone.ts b/packages/relay/tspec/05_Phone.ts new file mode 100644 index 00000000..b90ffa7c --- /dev/null +++ b/packages/relay/tspec/05_Phone.ts @@ -0,0 +1,48 @@ +import { Tspec } from "tspec"; +import { ResultCode } from "./types"; + +export type PhoneApiSpec = Tspec.DefineApiSpec<{ + tags: ["Phone", "Ledger"]; + paths: { + "/v1/phone/hash/{phone}": { + get: { + summary: "Provide the hash of phone number"; + path: { + /** + * Phone Number + * @example "+82 10-1000-5000" + */ + phone: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Phone Number + * @example "+82 10-1000-5000" + */ + phone: string; + /** + * Phone Number Hash + * @example "0xF48F4BF6C8B5B285F0D9EB5D52623EE14B6F2B5980E87FAC89E4B968995FAE2B" + */ + phoneHash: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + }; +}>; diff --git a/packages/relay/tspec/05_PhoneLink.ts b/packages/relay/tspec/05_PhoneLink.ts new file mode 100644 index 00000000..f6d8faa9 --- /dev/null +++ b/packages/relay/tspec/05_PhoneLink.ts @@ -0,0 +1,128 @@ +import { Tspec } from "tspec"; +import { ResultCode } from "./types"; + +export type PhoneLinkApiSpec = Tspec.DefineApiSpec<{ + tags: ["Phone"]; + paths: { + "/v1/link/nonce/{account}": { + get: { + summary: "Provides nonce for account on PhoneLink"; + path: { + /** + * Address of wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Address of wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + /** + * Nonce for address of wallet in Ledger Contract + * @example "45" + */ + nonce: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/link/to_account/{phone}": { + get: { + summary: "Provide a wallet address corresponding to the user's phone number hash"; + path: { + /** + * Phone Number Hash + * @example "0xF48F4BF6C8B5B285F0D9EB5D52623EE14B6F2B5980E87FAC89E4B968995FAE2B" + */ + phone: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Phone Number Hash + * @example "0xF48F4BF6C8B5B285F0D9EB5D52623EE14B6F2B5980E87FAC89E4B968995FAE2B" + */ + phone: string; + /** + * Address of wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/link/to_phone/{account}": { + get: { + summary: "Provide a phone number hash corresponding to the user's wallet address"; + path: { + /** + * Address of wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Phone Number Hash + * @example "0xF48F4BF6C8B5B285F0D9EB5D52623EE14B6F2B5980E87FAC89E4B968995FAE2B" + */ + phone: string; + /** + * Address of wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + }; +}>; diff --git a/packages/relay/tspec/06_Currency.ts b/packages/relay/tspec/06_Currency.ts new file mode 100644 index 00000000..67dbbf31 --- /dev/null +++ b/packages/relay/tspec/06_Currency.ts @@ -0,0 +1,53 @@ +import { Tspec } from "tspec"; +import { ResultCode } from "./types"; + +export type CurrencyApiSpec = Tspec.DefineApiSpec<{ + tags: ["Currency"]; + paths: { + "/v1/currency/convert": { + get: { + summary: "Provide value converted from one currency to another"; + query: { + /** + * Amount (info. 1 UNIT = "1000000000000000000", decimals is 18 + * @example "10000000000000000000000000" + */ + amount: string; + /** + * Currency Symbol of source (ex. acc, point, usd, krw, php, ...) + * @example "php" + */ + from: string; + /** + * Currency Symbol of target (ex. acc, point, usd, krw, php, ...) + * @example "point" + */ + to: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Value converted to target currency (info. decimals are 18) + * @example "10000000000000000000000000" + */ + amount: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + }; +}>; diff --git a/packages/relay/tspec/07_Summary.ts b/packages/relay/tspec/07_Summary.ts new file mode 100644 index 00000000..0b414e42 --- /dev/null +++ b/packages/relay/tspec/07_Summary.ts @@ -0,0 +1,424 @@ +import { Tspec } from "tspec"; +import { ResultCode } from "./types"; + +export type Summary1ApiSpec = Tspec.DefineApiSpec<{ + tags: ["Summary", "Ledger"]; + paths: { + "/v1/summary/account/{account}": { + get: { + summary: "Provide general information corresponding to the user's wallet address"; + path: { + /** + * Address of wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Address of wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + tokenInfo: { + /** + * Symbol of Token + * @example "ACC" + */ + symbol: string; + /** + * Name of Token + * @example "ACC Coin" + */ + name: string; + /** + * Decimals of Token + * @example 18 + */ + decimals: number; + }; + exchangeRate: { + token: { + /** + * Symbol of Token (info. decimals is 18) + * @example "ACC" + */ + symbol: string; + /** + * Amount of Token (info. decimals is 18) + * @example "1000000000000000000" + */ + value: string; + }; + currency: { + /** + * Symbol of Basic Currency (info. decimals is 18) + * @example "php" + */ + symbol: string; + /** + * Basic Currency Value for one token (info. decimals is 18) + * @example "2169736506000000000" + */ + value: string; + }; + }; + provider: { + /** + * If true, this account is a point provider. + * @example false + */ + enable: boolean; + /** + * Technical representatives to provide point + * @example "0x0000000000000000000000000000000000000000" + */ + assistant: string; + }; + ledger: { + point: { + /** + * Balance of point in the Ledger (info. decimals is 18) + * @example "3895000000000000000000" + */ + balance: string; + /** + * Basic Currency Value of point in the Ledger (info. decimals is 18) + * @example "3895000000000000000000" + */ + value: string; + }; + token: { + /** + * Balance of token in the Ledger (info. decimals is 18) + * @example "1661929627132000000000" + */ + balance: string; + /** + * Basic Currency Value of token in the Ledger (info. decimals is 18) + * @example "3605949382391000000000" + */ + value: string; + }; + }; + mainChain: { + point: { + /** + * Balance of point in the Main Chain (info. decimals is 18) + * @example "0" + */ + balance: string; + /** + * Basic Currency Value of point in the Main Chain (info. decimals is 18) + * @example "0" + */ + value: string; + }; + token: { + /** + * Balance of token in the Main Chain (info. decimals is 18) + * @example "99900000000000000000" + */ + balance: string; + /** + * Basic Currency Value of token in the Main Chain (info. decimals is 18) + * @example "216756676949000000000" + */ + value: string; + }; + }; + sideChain: { + point: { + /** + * Balance of point in the Side Chain (info. decimals is 18) + * @example "0" + */ + balance: string; + /** + * Basic Currency Value of point in the Side Chain (info. decimals is 18) + * @example "0" + */ + value: string; + }; + token: { + /** + * Balance of token in the Side Chain (info. decimals is 18) + * @example "0" + */ + balance: string; + /** + * Basic Currency Value of token in the Side Chain (info. decimals is 18) + * @example "0" + */ + value: string; + }; + }; + protocolFees: { + /** + * Protocol fees required to use the transfer function (info. decimals is 18) + * @example "100000000000000000" + */ + transfer: string; + /** + * Protocol fees required to use the withdrawal function (info. decimals is 18) + * @example "100000000000000000" + */ + withdraw: string; + /** + * Protocol fees required to use the deposit function (info. decimals is 18) + * @example "100000000000000000" + */ + deposit: string; + }; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + }; +}>; + +export type Summary2ApiSpec = Tspec.DefineApiSpec<{ + tags: ["Summary", "Shop"]; + paths: { + "/v1/summary/shop/{shopId}": { + get: { + summary: "Provide general information corresponding to the ID of shop"; + path: { + /** + * ID of Shop + * @example "0x0001be96d74202df38fd21462ffcef10dfe0fcbd7caa3947689a3903e8b6b874" + */ + shopId: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + shopInfo: { + /** + * ID of Shop + * @example "0x0001be96d74202df38fd21462ffcef10dfe0fcbd7caa3947689a3903e8b6b874" + */ + shopId: string; + /** + * Name of Shop + * @example "Coffee Nine" + */ + name: string; + /** + * Basic currency symbol of Shop + * @example "php" + */ + currency: string; + /** + * Active status of Shop ( 0: None, 1: ACTIVE, 2: INACTIVE ) + * @example 1 + */ + status: number; + /** + * Wallet address of the shop owner + * @example "0xafFe745418Ad24c272175e5B58610A8a35e2EcDa" + */ + account: string; + /** + * Wallet address that authorizes cancellation on behalf of the shop owner + * @example "0xD10ADf251463A260242c216c8c7D3e736eBdB398" + */ + delegator: string; + /** + * Amount of provided + * @example "0" + */ + providedAmount: string; + /** + * Amount of used + * @example "0" + */ + usedAmount: string; + /** + * Amount of refunded + * @example "0" + */ + refundedAmount: string; + /** + * Basic currency amount of refundable + * @example "0" + */ + refundableAmount: string; + /** + * Token amount of refundable + * @example "0" + */ + refundableToken: string; + }; + tokenInfo: { + /** + * Symbol of Token + * @example "ACC" + */ + symbol: string; + /** + * Name of Token + * @example "ACC Coin" + */ + name: string; + /** + * Decimals of Token + * @example 18 + */ + decimals: number; + }; + exchangeRate: { + token: { + /** + * Symbol of Token (info. decimals is 18) + * @example "ACC" + */ + symbol: string; + /** + * Amount of Token (info. decimals is 18) + * @example "1000000000000000000" + */ + value: string; + }; + currency: { + /** + * Symbol of Basic Currency (info. decimals is 18) + * @example "php" + */ + symbol: string; + /** + * Basic Currency Value for one token (info. decimals is 18) + * @example "2169736506000000000" + */ + value: string; + }; + }; + ledger: { + point: { + /** + * Balance of point in the Ledger (info. decimals is 18) + * @example "3895000000000000000000" + */ + balance: string; + /** + * Basic Currency Value of point in the Ledger (info. decimals is 18) + * @example "3895000000000000000000" + */ + value: string; + }; + token: { + /** + * Balance of token in the Ledger (info. decimals is 18) + * @example "1661929627132000000000" + */ + balance: string; + /** + * Basic Currency Value of token in the Ledger (info. decimals is 18) + * @example "3605949382391000000000" + */ + value: string; + }; + }; + mainChain: { + point: { + /** + * Balance of point in the Main Chain (info. decimals is 18) + * @example "0" + */ + balance: string; + /** + * Basic Currency Value of point in the Main Chain (info. decimals is 18) + * @example "0" + */ + value: string; + }; + token: { + /** + * Balance of token in the Main Chain (info. decimals is 18) + * @example "99900000000000000000" + */ + balance: string; + /** + * Basic Currency Value of token in the Main Chain (info. decimals is 18) + * @example "216756676949000000000" + */ + value: string; + }; + }; + sideChain: { + point: { + /** + * Balance of point in the Side Chain (info. decimals is 18) + * @example "0" + */ + balance: string; + /** + * Basic Currency Value of point in the Side Chain (info. decimals is 18) + * @example "0" + */ + value: string; + }; + token: { + /** + * Balance of token in the Side Chain (info. decimals is 18) + * @example "0" + */ + balance: string; + /** + * Basic Currency Value of token in the Side Chain (info. decimals is 18) + * @example "0" + */ + value: string; + }; + }; + protocolFees: { + /** + * Protocol fees required to use the transfer function (info. decimals is 18) + * @example "100000000000000000" + */ + transfer: string; + /** + * Protocol fees required to use the withdrawal function (info. decimals is 18) + * @example "100000000000000000" + */ + withdraw: string; + /** + * Protocol fees required to use the deposit function (info. decimals is 18) + * @example "100000000000000000" + */ + deposit: string; + }; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + }; +}>; diff --git a/packages/relay/tspec/08_Bridge.ts b/packages/relay/tspec/08_Bridge.ts new file mode 100644 index 00000000..680d4ad2 --- /dev/null +++ b/packages/relay/tspec/08_Bridge.ts @@ -0,0 +1,274 @@ +import { Tspec } from "tspec"; +import { ResultCode } from "./types"; + +export type ChainBridgeApiSpec = Tspec.DefineApiSpec<{ + tags: ["Bridge"]; + paths: { + "/v1/bridge/deposit": { + post: { + summary: "Move token from Main Chain to Side Chain"; + body: { + /** + * Wallet address of the user + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + /** + * Token amount to move + * @example "10000000000000000000000000" + */ + amount: string; + /** + * Expiration time of signature + * @example 16745119473 + */ + expiry: number; + /** + * Signature of user wallet + * @example "0x020d671b80fbd20466d8cb65cef79a24e3bca3fdf82e9dd89d78e7a4c4c045bd72944c20bb1d839e76ee6bb69fed61f64376c37799598b40b8c49148f3cdd88a1b" + */ + signature: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * ID of token + * @example "0x4d59fb5e21082f35b28aa792d8a0f71fccfe22d6c7138946d4840ba68b3d6fae" + */ + tokenId: string; + /** + * ID of deposit + * @example "0x4347a36f5867097f26f0a6f8698a78a1ba0e367fce9ef72ba0b07e0af5bb42ff" + */ + depositId: string; + /** + * Token amount to move + * @example "10000000000000000000000000" + */ + amount: string; + /** + * Hash of transaction + * @example "0xe5502185d39057bd82e6dde675821b87313570df77d3e23d8e5712bd5f3fa6b6" + */ + txHash: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/bridge/withdraw": { + post: { + summary: "Move token from Side Chain to Main Chain"; + body: { + /** + * Wallet address of the user + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + /** + * Token amount to move + * @example "10000000000000000000000000" + */ + amount: string; + /** + * Expiration time of signature + * @example 16745119473 + */ + expiry: number; + /** + * Signature of user wallet + * @example "0x020d671b80fbd20466d8cb65cef79a24e3bca3fdf82e9dd89d78e7a4c4c045bd72944c20bb1d839e76ee6bb69fed61f64376c37799598b40b8c49148f3cdd88a1b" + */ + signature: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * ID of token + * @example "0x4d59fb5e21082f35b28aa792d8a0f71fccfe22d6c7138946d4840ba68b3d6fae" + */ + tokenId: string; + /** + * ID of deposit + * @example "0x4347a36f5867097f26f0a6f8698a78a1ba0e367fce9ef72ba0b07e0af5bb42ff" + */ + depositId: string; + /** + * Token amount to move + * @example "10000000000000000000000000" + */ + amount: string; + /** + * Hash of transaction + * @example "0xe5502185d39057bd82e6dde675821b87313570df77d3e23d8e5712bd5f3fa6b6" + */ + txHash: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + }; +}>; + +export type LoyaltyBridgeApiSpec = Tspec.DefineApiSpec<{ + tags: ["Bridge", "Ledger"]; + paths: { + "/v1/ledger/deposit_via_bridge": { + post: { + summary: "Move token from Main Chain to Ledger"; + body: { + /** + * Wallet address of the user + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + /** + * Token amount to move + * @example "10000000000000000000000000" + */ + amount: string; + /** + * Expiration time of signature + * @example 16745119473 + */ + expiry: number; + /** + * Signature of user wallet + * @example "0x020d671b80fbd20466d8cb65cef79a24e3bca3fdf82e9dd89d78e7a4c4c045bd72944c20bb1d839e76ee6bb69fed61f64376c37799598b40b8c49148f3cdd88a1b" + */ + signature: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * ID of token + * @example "0x4d59fb5e21082f35b28aa792d8a0f71fccfe22d6c7138946d4840ba68b3d6fae" + */ + tokenId: string; + /** + * ID of deposit + * @example "0x4347a36f5867097f26f0a6f8698a78a1ba0e367fce9ef72ba0b07e0af5bb42ff" + */ + depositId: string; + /** + * Token amount to move + * @example "10000000000000000000000000" + */ + amount: string; + /** + * Hash of transaction + * @example "0xe5502185d39057bd82e6dde675821b87313570df77d3e23d8e5712bd5f3fa6b6" + */ + txHash: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/ledger/withdraw_via_bridge": { + post: { + summary: "Move token from Ledger to Main Chain"; + body: { + /** + * Wallet address of the user + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + /** + * Token amount to move + * @example "10000000000000000000000000" + */ + amount: string; + /** + * Expiration time of signature + * @example 16745119473 + */ + expiry: number; + /** + * Signature of user wallet + * @example "0x020d671b80fbd20466d8cb65cef79a24e3bca3fdf82e9dd89d78e7a4c4c045bd72944c20bb1d839e76ee6bb69fed61f64376c37799598b40b8c49148f3cdd88a1b" + */ + signature: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * ID of token + * @example "0x4d59fb5e21082f35b28aa792d8a0f71fccfe22d6c7138946d4840ba68b3d6fae" + */ + tokenId: string; + /** + * ID of deposit + * @example "0x4347a36f5867097f26f0a6f8698a78a1ba0e367fce9ef72ba0b07e0af5bb42ff" + */ + depositId: string; + /** + * Token amount to move + * @example "10000000000000000000000000" + */ + amount: string; + /** + * Hash of transaction + * @example "0xe5502185d39057bd82e6dde675821b87313570df77d3e23d8e5712bd5f3fa6b6" + */ + txHash: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + }; +}>; diff --git a/packages/relay/tspec/09_Chain.ts b/packages/relay/tspec/09_Chain.ts new file mode 100644 index 00000000..7d9abd37 --- /dev/null +++ b/packages/relay/tspec/09_Chain.ts @@ -0,0 +1,520 @@ +import { Tspec } from "tspec"; +import { ResultCode } from "./types"; + +export type MainChainApiSpec = Tspec.DefineApiSpec<{ + tags: ["Chain Info", "Main Chain"]; + paths: { + "/v1/chain/main/info": { + get: { + summary: "Provide information of main chain"; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Endpoint of RPC + * @example "https://testnet.bosagora.org/" + */ + url: string; + network: { + /** + * Name of Network + * @example "main-chain" + */ + name: string; + /** + * Chain ID of Network + * @example 2019 + */ + chainId: number; + /** + * ENS Address + * @example "0x0000000000000000000000000000000000000000" + */ + ensAddress: string; + /** + * Fee of Transfer + * @example "100000000000000000" + */ + chainTransferFee: string; + /** + * Fee of Bridge + * @example "100000000000000000" + */ + chainBridgeFee: string; + /** + * Fee of Loyalty Transfer + * @example "0" + */ + loyaltyTransferFee: string; + /** + * Fee of Loyalty Bridge + * @example "100000000000000000" + */ + loyaltyBridgeFee: string; + }; + contract: { + /** + * Address of token contract + * @example "0xBd837b831cA3aA1e9eE388959d9f5B81262ccfA6" + */ + token: string; + /** + * Address of chain bridge + * @example "0x097C7543464d3De422f86248F1CE803879a4077e" + */ + chainBridge: string; + /** + * Address of loyalty bridge + * @example "0x22B98e18c51D02AF225b3fBa726865fB497B1afD" + */ + loyaltyBridge: string; + }; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + }; +}>; + +export type SideChainApiSpec = Tspec.DefineApiSpec<{ + tags: ["Chain Info", "Side Chain"]; + paths: { + "/v1/chain/side/info": { + get: { + summary: "Provide information of side chain"; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Endpoint of RPC + * @example "https://rpc.test.acccoin.io/" + */ + url: string; + network: { + /** + * Name of Network + * @example "side-chain" + */ + name: string; + /** + * Chain ID of Network + * @example 215115 + */ + chainId: number; + /** + * ENS Address + * @example "0x0000000000000000000000000000000000000000" + */ + ensAddress: string; + /** + * Fee of Transfer + * @example "100000000000000000" + */ + chainTransferFee: string; + /** + * Fee of Bridge + * @example "100000000000000000" + */ + chainBridgeFee: string; + /** + * Fee of Loyalty Transfer + * @example "0" + */ + loyaltyTransferFee: string; + /** + * Fee of Loyalty Bridge + * @example "100000000000000000" + */ + loyaltyBridgeFee: string; + }; + contract: { + /** + * Address of token contract + * @example "0x8D34D6102AD64abDa8bcF36c278140bAC4D97323" + */ + token: string; + /** + * Address of PhoneLinkCollection contract + * @example "0x23074adeD2E687C30483A64869AaA0e8C22e90C9" + */ + phoneLink: string; + /** + * Address of CurrencyRate contract + * @example "0x8374a5b754cb708C05E846AE9BbEA10f732F1283" + */ + currencyRate: string; + /** + * Address of LoyaltyProvider contract + * @example "0xBF330C5c5f7b83631160Eef4e7C8d0dEd17eE350" + */ + loyaltyProvider: string; + /** + * Address of LoyaltyConsumer contract + * @example "0x9929a4c45dA7650D690103df1c46Da2DadaC0288" + */ + loyaltyConsumer: string; + /** + * Address of loyaltyTransfer contract + * @example "0x1cda3562c535E65C501bda87a2cda792Feb931c1" + */ + loyaltyTransfer: string; + /** + * Address of loyaltyExchanger contract + * @example "0x69328a59c9826FedBADF0C412B59DE350771ff28" + */ + loyaltyExchanger: string; + /** + * Address of LoyaltyBridge contract + * @example "0x877ab4A2d858926EE65769723d4ea825E055024e" + */ + loyaltyBridge: string; + /** + * Address of Shop contract + * @example "0x911b2749053f966c651777A4485DDB4E33CE495F" + */ + shop: string; + /** + * Address of Ledger contract + * @example "0xe782E73900613EF72E972C9e73669e1e0aBc859E" + */ + ledger: string; + /** + * Address of chain bridge + * @example "0x2902aa3D47075AB2b87e8345094Ea1c87e5B5019" + */ + chainBridge: string; + }; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + }; +}>; + +export type MainChainTokenApiSpec = Tspec.DefineApiSpec<{ + tags: ["Main Chain", "Loyalty Token"]; + paths: { + "/v1/token/main/balance/{account}": { + get: { + summary: "Provide token balance in the main chain"; + path: { + /** + * Address of user wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Address of user wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + /** + * Balance of Token (info. decimals are 18) + * @example "10000000000000000000000000" + */ + balance: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/token/main/nonce/{account}": { + get: { + summary: "Provide nonce in the main chain"; + path: { + /** + * Address of user wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Address of wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + + /** + * Nonce for address of wallet in Ledger Contract + * @example "45" + */ + nonce: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/token/main/transfer": { + post: { + summary: "Transfer token in the main chain"; + body: { + /** + * Token amount to be transfer + * @example "10000000000000000000000000" + */ + amount: string; + /** + * Wallet address of sender + * @example "0x64D111eA9763c93a003cef491941A011B8df5a49" + */ + from: string; + /** + * Wallet address of receiver + * @example "0x3FE8D00143bd0eAd2397D48ba0E31E5E1268dBfb" + */ + to: string; + /** + * Expiration time of signature + * @example 16745119473 + */ + expiry: string; + /** + * Signature of sender wallet + * @example "0x020d671b80fbd20466d8cb65cef79a24e3bca3fdf82e9dd89d78e7a4c4c045bd72944c20bb1d839e76ee6bb69fed61f64376c37799598b40b8c49148f3cdd88a1b" + */ + signature: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Wallet address of sender + * @example "0x64D111eA9763c93a003cef491941A011B8df5a49" + */ + from: string; + /** + * Wallet address of receiver + * @example "0x3FE8D00143bd0eAd2397D48ba0E31E5E1268dBfb" + */ + to: string; + /** + * Token amount to be transfer + * @example "10000000000000000000000000" + */ + amount: string; + /** + * Hash of transaction + * @example "0xe5502185d39057bd82e6dde675821b87313570df77d3e23d8e5712bd5f3fa6b6" + */ + txHash: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + }; +}>; + +export type SideChainTokenApiSpec = Tspec.DefineApiSpec<{ + tags: ["Side Chain", "Loyalty Token"]; + paths: { + "/v1/token/side/balance/{account}": { + get: { + summary: "Provide token balance in the side chain"; + path: { account: string }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Address of user wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + /** + * Balance of Token (info. decimals are 18) + * @example "10000000000000000000000000" + */ + balance: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/token/side/nonce/{account}": { + get: { + summary: "Provide nonce in the side chain"; + path: { account: string }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Address of wallet + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + + /** + * Nonce for address of wallet in Ledger Contract + * @example "45" + */ + nonce: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/token/side/transfer": { + post: { + summary: "Transfer token in the side chain"; + body: { + /** + * Token amount to be transfer + * @example "10000000000000000000000000" + */ + amount: string; + /** + * Wallet address of sender + * @example "0x64D111eA9763c93a003cef491941A011B8df5a49" + */ + from: string; + /** + * Wallet address of receiver + * @example "0x3FE8D00143bd0eAd2397D48ba0E31E5E1268dBfb" + */ + to: string; + /** + * Expiration time of signature + * @example 16745119473 + */ + expiry: string; + /** + * Signature of sender wallet + * @example "0x020d671b80fbd20466d8cb65cef79a24e3bca3fdf82e9dd89d78e7a4c4c045bd72944c20bb1d839e76ee6bb69fed61f64376c37799598b40b8c49148f3cdd88a1b" + */ + signature: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Wallet address of sender + * @example "0x64D111eA9763c93a003cef491941A011B8df5a49" + */ + from: string; + /** + * Wallet address of receiver + * @example "0x3FE8D00143bd0eAd2397D48ba0E31E5E1268dBfb" + */ + to: string; + /** + * Token amount to be transfer + * @example "10000000000000000000000000" + */ + amount: string; + /** + * Hash of transaction + * @example "0xe5502185d39057bd82e6dde675821b87313570df77d3e23d8e5712bd5f3fa6b6" + */ + txHash: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + }; +}>; diff --git a/packages/relay/tspec/10_Provider.ts b/packages/relay/tspec/10_Provider.ts new file mode 100644 index 00000000..5d436b73 --- /dev/null +++ b/packages/relay/tspec/10_Provider.ts @@ -0,0 +1,360 @@ +import { Tspec } from "tspec"; +import { ResultCode } from "./types"; + +export type ProviderApiSpec = Tspec.DefineApiSpec<{ + tags: ["Loyalty Point Provider"]; + paths: { + "/v1/provider/assistant/{provider}": { + get: { + summary: "Provides the assistant's information"; + path: { + /** + * Wallet address of the provider + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + provider: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Wallet address of the provider + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + provider: string; + /** + * Wallet address of the assistant + * @example "0x3FE8D00143bd0eAd2397D48ba0E31E5E1268dBfb" + */ + assistant: string; + /** + * Hash of transaction + * @example "0xe5502185d39057bd82e6dde675821b87313570df77d3e23d8e5712bd5f3fa6b6" + */ + txHash: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/provider/assistant/register": { + post: { + summary: "Register the provider's assistant. The assistant can only process the instructions of the point transfer"; + body: { + /** + * Wallet address of the provider + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + provider: string; + /** + * Wallet address of the assistant + * @example "0x3FE8D00143bd0eAd2397D48ba0E31E5E1268dBfb" + */ + assistant: string; + /** + * Signature of provider or assistant + * @example "0x020d671b80fbd20466d8cb65cef79a24e3bca3fdf82e9dd89d78e7a4c4c045bd72944c20bb1d839e76ee6bb69fed61f64376c37799598b40b8c49148f3cdd88a1b" + */ + signature: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Wallet address of the provider + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + provider: string; + /** + * Wallet address of the assistant + * @example "0x3FE8D00143bd0eAd2397D48ba0E31E5E1268dBfb" + */ + assistant: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/provider/balance/{provider}": { + get: { + summary: "Provide a point provider's assets"; + path: { + /** + * Wallet address of the provider + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + provider: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Wallet address of the provider + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + provider: string; + providable: { + /** + * Amount of tokens that can be provided (info. decimals are 18) + * @example "100000000000000000000000" + */ + token: string; + /** + * Amount of points corresponding to tokens that can be provided (info. decimals are 18) + * @example "112108371800000000000000" + */ + point: string; + }; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/provider/register": { + post: { + summary: "Register the provider. To become a point provider, you must first deposit 50,000 tokens"; + body: { + /** + * Wallet address of the provider + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + provider: string; + /** + * Signature of user wallet + * @example "0x020d671b80fbd20466d8cb65cef79a24e3bca3fdf82e9dd89d78e7a4c4c045bd72944c20bb1d839e76ee6bb69fed61f64376c37799598b40b8c49148f3cdd88a1b" + */ + signature: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Wallet address of the provider + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + provider: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/provider/send/account": { + post: { + summary: "Request the ability to provide points to the recipient's wallet address"; + body: { + /** + * Wallet address of the provider + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + provider: string; + /** + * Wallet address of the receiver + * @example "0x3FE8D00143bd0eAd2397D48ba0E31E5E1268dBfb" + */ + receiver: string; + /** + * Point amount to be provided + * @example "10000000000000000000000000" + */ + amount: string; + /** + * Signature of provider or assistant + * @example "0x020d671b80fbd20466d8cb65cef79a24e3bca3fdf82e9dd89d78e7a4c4c045bd72944c20bb1d839e76ee6bb69fed61f64376c37799598b40b8c49148f3cdd88a1b" + */ + signature: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Wallet address of the provider + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + provider: string; + /** + * Wallet address of the receiver + * @example "0x3FE8D00143bd0eAd2397D48ba0E31E5E1268dBfb" + */ + receiver: string; + /** + * Point amount to be provided + * @example "10000000000000000000000000" + */ + amount: string; + /** + * Hash of transaction + * @example "0xe5502185d39057bd82e6dde675821b87313570df77d3e23d8e5712bd5f3fa6b6" + */ + txHash: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/provider/send/phoneHash": { + post: { + summary: "Request the ability to provide points to the recipient's phone number hash"; + body: { + /** + * Wallet address of the provider + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + provider: string; + /** + * Phone number hash of the receiver + * @example "0xF48F4BF6C8B5B285F0D9EB5D52623EE14B6F2B5980E87FAC89E4B968995FAE2B" + */ + receiver: string; + /** + * Point amount to be provided + * @example "10000000000000000000000000" + */ + amount: string; + /** + * Signature of provider or assistant + * @example "0x020d671b80fbd20466d8cb65cef79a24e3bca3fdf82e9dd89d78e7a4c4c045bd72944c20bb1d839e76ee6bb69fed61f64376c37799598b40b8c49148f3cdd88a1b" + */ + signature: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Wallet address of the provider + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + provider: string; + /** + * Phone number hash of the receiver + * @example "0xF48F4BF6C8B5B285F0D9EB5D52623EE14B6F2B5980E87FAC89E4B968995FAE2B" + */ + receiver: string; + /** + * Point amount to be provided + * @example "10000000000000000000000000" + */ + amount: string; + /** + * Hash of transaction + * @example "0xe5502185d39057bd82e6dde675821b87313570df77d3e23d8e5712bd5f3fa6b6" + */ + txHash: string; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/provider/status/{provider}": { + get: { + summary: "Provides the status value of the point provider"; + path: { + /** + * Wallet address of the provider + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + provider: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Wallet address of the provider + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + provider: string; + /** + * If this value is true, it is an approved point provider, otherwise it is not a point provider. + * @example true + */ + enable: boolean; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + }; +}>; diff --git a/packages/relay/tspec/15_History.ts b/packages/relay/tspec/15_History.ts new file mode 100644 index 00000000..44a46f86 --- /dev/null +++ b/packages/relay/tspec/15_History.ts @@ -0,0 +1,404 @@ +import { Tspec } from "tspec"; +import { ResultCode } from "./types"; + +export type HistoryApiSpec = Tspec.DefineApiSpec<{ + tags: ["History"]; + paths: { + "/v1/token/main/history/{account}": { + get: { + summary: "Provider the history of token transfers for the account in the main chain"; + path: { + /** + * Wallet address of the provider + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + }; + query: { + /** + * Current Page Number + * @example 1 + */ + pageNumber: number; + /** + * Number of items per page + * @example 10 + */ + pageSize: number; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Wallet address of the sender + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + from: string; + /** + * Wallet address of the receiver + * @example "0x3FE8D00143bd0eAd2397D48ba0E31E5E1268dBfb" + */ + to: string; + /** + * Transferred amount + * @example "10000000000000000000000000" + */ + value: string; + /** + * Timestamp of block + * @example "1722945138" + */ + blockTimestamp: string; + }[]; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/token/side/history/{account}": { + post: { + summary: "Provider the history of token transfers for the account in the side chain"; + path: { + /** + * Wallet address of the provider + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + }; + query: { + /** + * Current Page Number + * @example 1 + */ + pageNumber: number; + /** + * Number of items per page + * @example 10 + */ + pageSize: number; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + /** + * Wallet address of the sender + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + from: string; + /** + * Wallet address of the receiver + * @example "0x3FE8D00143bd0eAd2397D48ba0E31E5E1268dBfb" + */ + to: string; + /** + * Transferred amount + * @example "10000000000000000000000000" + */ + value: string; + /** + * Timestamp of block + * @example "16745119473" + */ + blockTimestamp: string; + }[]; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/ledger/history/account/{account}": { + get: { + summary: "Provide a history for the account"; + path: { + /** + * Wallet address of the provider + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + }; + query: { + /** + * Current Page Number + * @example 1 + */ + pageNumber: number; + /** + * Number of items per page + * @example 10 + */ + pageSize: number; + /** + * Filter + * @example "1,2" + */ + actions: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + pageInfo: { + /** + * The Number of Items + * @example 3 + */ + totalCount: number; + /** + * The Number of Pages + * @example 1 + */ + totalPages: number; + }; + items: { + /** + * Wallet address of the provider + * @example "0x5650CD3E6E8963B43D21FAE60EE7A03BCEFCE766" + */ + account: string; + /** + * Reason the item was created + * @example 1 + */ + action: string; + /** + * Is Cancel Payment? + * @example false + */ + cancel: boolean; + /** + * Point Amount + * @example "5000000000000000000000000" + */ + amountPoint: string; + /** + * Token Amount + * @example "0" + */ + amountToken: string; + /** + * Value of Used Amount + * @example "5000000000000000000000000" + */ + amountValue: string; + /** + * Fee Point + * @example 0" + */ + feePoint: string; + /** + * Fee Token + * @example 0" + */ + feeToken: string; + /** + * Value of Fee + * @example 0" + */ + feeValue: string; + /** + * Balance of point + * @example "10000000000000000000000000" + */ + balancePoint: string; + /** + * Balance of token + * @example "100000000000000000000000" + */ + balanceToken: string; + /** + * ID of Purchase + * @example "P00000002200843" + */ + purchaseId: string; + /** + * ID of Payment + * @example "0x0000000000000000000000000000000000000000000000000000000000000000" + */ + paymentId: string; + /** + * ID of Shop + * @example "0x00012a23595cf31762a61502546e8b9f947baf3bd55040d9bd535f8afdbff409" + */ + shopId: string; + /** + * Block Number + * @example "559" + */ + blockNumber: string; + /** + * Block TimeStamp + * @example "1722945138" + */ + blockTimestamp: string; + /** + * Transaction Hash + * @example "0xbf7a697d5047973737cd255b49c521c520fc82c21459bff55e3499acb54e6f63" + */ + transactionHash: string; + }[]; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + "/v1/shop/history/{shopId}": { + get: { + summary: "Provide a history for the shop"; + path: { + /** + * ID of Shop + * @example "0x00011936a68f7c26797fa2ab64d444ea82c2fb1af36cdea6d4ff845da635f287" + */ + shopId: string; + }; + query: { + /** + * Current Page Number + * @example 1 + */ + pageNumber: number; + /** + * Number of items per page + * @example 10 + */ + pageSize: number; + /** + * Filter + * @example "1,2" + */ + actions: string; + }; + responses: { + 200: { + /** + * Result Code + * @example 0 + */ + code: ResultCode; + data: { + pageInfo: { + /** + * The Number of Items + * @example 3 + */ + totalCount: number; + /** + * The Number of Pages + * @example 1 + */ + totalPages: number; + }; + items: { + /** + * ID of Shop + * @example "0x00012a23595cf31762a61502546e8b9f947baf3bd55040d9bd535f8afdbff409" + */ + shopId: string; + /** + * Basic currency symbol of Shop + * @example "php" + */ + currency: string; + /** + * Reason the item was created + * @example 1 + */ + action: string; + /** + * Is Cancel Payment? + * @example false + */ + cancel: boolean; + /** + * Amount + * @example "1000000000000000000000" + */ + increase: string; + /** + * Provided Amount + * @example "7000000000000000000000" + */ + providedAmount: string; + /** + * Used Amount + * @example "100000000000000000000" + */ + usedAmount: string; + /** + * Refund Amount + * @example "0" + */ + refundedAmount: string; + /** + * ID of Purchase + * @example "P172294893503200000" + */ + purchaseId: string; + /** + * ID of Payment + * @example null + */ + paymentId: string; + /** + * Block Number + * @example "771" + */ + blockNumber: string; + /** + * Block TimeStamp + * @example "1722948976" + */ + blockTimestamp: string; + /** + * Transaction Hash + * @example "0x17da663a07f3e6a70b6ca8d8a89debf97863687e6ec7effe454824cea9ee2059" + */ + transactionHash: string; + }[]; + }; + error?: { + /** + * Error Message + * @example "Failed to check the validity of parameters" + */ + message: string; + }; + }; + }; + }; + }; + }; +}>; diff --git a/packages/relay/tspec/20_CallBack.ts b/packages/relay/tspec/20_CallBack.ts new file mode 100644 index 00000000..c35b89ff --- /dev/null +++ b/packages/relay/tspec/20_CallBack.ts @@ -0,0 +1,140 @@ +import { Tspec } from "tspec"; +import { LoyaltyPaymentTaskStatus, ResultCode } from "./types"; + +interface PaymentCallBackData { + /** + * ID of Payment + * @example "0x2d9100c28be32e1a29e55b2ead66d472a6271627235778379657d08c9dc1d901" + */ + paymentId: string; + /** + * ID of Purchase + * @example "P00000000000203" + */ + purchaseId: string; + /** + * Amount to be used for payment (info. decimals are 18) + * @example "100000000000000000000" + */ + amount: string; + /** + * Currency symbol for amount to be used for payment + * @example "php" + */ + currency: string; + /** + * ID of shop + * @example "0x00011936a68f7c26797fa2ab64d444ea82c2fb1af36cdea6d4ff845da635f287" + */ + shopId: string; + /** + * Wallet address of user + * @example "0x5A3Fc8990417b3e6ddCdAE0E8039E798A609Ef84" + */ + account: string; + /** + * Amount of points to be paid (info. decimals are 18) + * @example "100000000000000000000" + */ + paidPoint: string; + /** + * Amount of points to be paid converted to payment currency (info. decimals are 18) + * @example "100000000000000000000" + */ + paidValue: string; + /** + * Fee (info. decimals are 18) + * @example "5000000000000000000" + */ + feePoint: string; + /** + * Fee converted to payment currency (info. decimals are 18) + * @example "5000000000000000000" + */ + feeValue: string; + /** + * Amount of points to be paid including fees (info. decimals are 18) + * @example "105000000000000000000" + */ + totalPoint: string; + /** + * Amount of points to be paid including fees converted to payment currency (info. decimals are 18) + * @example "105000000000000000000" + */ + totalValue: string; + /** + * Progress status of payment task + * @example 18 + */ + paymentStatus: LoyaltyPaymentTaskStatus; +} + +interface ShopCallBackData { + /** + * ID of Task + * @example "0x6d335fe57648a92b6024be84fd4f265fb497366a916f5a28a5f2a04e523d9c7b" + */ + taskId: string; + /** + * ID of Shop + * @example "0x0001be96d74202df38fd21462ffcef10dfe0fcbd7caa3947689a3903e8b6b874" + */ + shopId: string; + /** + * New name to be changed of Shop + * @example "Coffee Nine" + */ + name: string; + /** + * New currency symbol to be changed of Shop + * @example "php" + */ + currency: string; + /** + * Active status of Shop ( 0: None, 1: ACTIVE, 2: INACTIVE ) + * @example 1 + */ + status: number; + /** + * Wallet address of shop owner + * @example "0xafFe745418Ad24c272175e5B58610A8a35e2EcDa" + */ + account: string; +} + +interface TaskCallBackRequest { + /** + * Type of Task ( "pay_new", "pay_cancel", "shop_add", "shop_update", "shop_status" ) + * @example "pay_new" + */ + type: string; + /** + * Result Code + * @example 0 + */ + code: ResultCode; + /** + * Result Message + * @example "Success" + */ + message: string; + /** + * Result Data + */ + data: PaymentCallBackData | ShopCallBackData; +} + +export type CallbackApiSpec = Tspec.DefineApiSpec<{ + tags: ["Payment", "Shop", "External CallBack"]; + paths: { + "/external/callback": { + post: { + summary: "Send payment and store tak processing status to the external domain"; + body: TaskCallBackRequest; + responses: { + 200: {}; + }; + }; + }; + }; +}>; diff --git a/packages/relay/tspec/types.ts b/packages/relay/tspec/types.ts new file mode 100644 index 00000000..5acf6e6f --- /dev/null +++ b/packages/relay/tspec/types.ts @@ -0,0 +1,229 @@ +/** + * Progress status of payment task
+ * 11:Opened for New Payment
+ * 12:Failed Approve for New Payment
+ * 13:Reverted Approve for New Payment
+ * 14:Sent Tx for New Payment
+ * 15:Confirm Tx for New Payment
+ * 16:Denied New Payment
+ * 17:Complete New Payment
+ * 18:Close New Payment
+ * 19:Failed New Payment
+ * 51:Opened for Cancel Payment
+ * 52:Failed Approve for Cancel Payment
+ * 53:Failed Approve for Cancel Payment
+ * 54:Sent Tx for Cancel Payment
+ * 55:Confirm Tx for Cancel Payment
+ * 56:Denied Cancel Payment
+ * 57:Complete Cancel Payment
+ * 58:Close Cancel Payment
+ * 59:Failed Cancel Payment
+ */ +export enum LoyaltyPaymentTaskStatus { + NULL = 0, + OPENED_NEW = 11, + APPROVED_NEW_FAILED_TX = 12, + APPROVED_NEW_REVERTED_TX = 13, + APPROVED_NEW_SENT_TX = 14, + APPROVED_NEW_CONFIRMED_TX = 15, + DENIED_NEW = 16, + REPLY_COMPLETED_NEW = 17, + CLOSED_NEW = 18, + FAILED_NEW = 19, + OPENED_CANCEL = 51, + APPROVED_CANCEL_FAILED_TX = 52, + APPROVED_CANCEL_REVERTED_TX = 53, + APPROVED_CANCEL_SENT_TX = 54, + APPROVED_CANCEL_CONFIRMED_TX = 55, + DENIED_CANCEL = 56, + REPLY_COMPLETED_CANCEL = 57, + CLOSED_CANCEL = 58, + FAILED_CANCEL = 59, +} + +/** + * Task progress status
+ * 11:Opened Task
+ * 12:Failed Tx
+ * 13:Reverted Tx
+ * 14:Sent Tx
+ * 15:Denied
+ * 16:Completed
+ * 70:Timeout
+ */ +export enum ShopTaskStatus { + NULL = 0, + OPENED = 11, + FAILED_TX = 12, + REVERTED_TX = 13, + SENT_TX = 14, + DENIED = 15, + COMPLETED = 16, + TIMEOUT = 70, +} + +/** + * ResultCode
+ * 0: Success
+ * 1000: Sender is not validator
+ * 1001: Validator is not active
+ * 1002: Validator is already active
+ * 1003: Validator is already exist
+ * 1010: The last validator cannot be removed
+ * 1020: Not allowed deposit
+ * 1030: Amount not multiple of gwei
+ * 1031: The amount entered is less than the minimum amount
+ * 1050: Sender is not authorized to execute
+ * 1051: Unable to transfer from system account
+ * 1052: Unable to transfer to system account
+ * 1053: Unable to withdraw from the system account
+ * 1054: Sender is not authorized to provide points
+ * 1160: ProvideLoyalty-This is a purchase data that has already been processed
+ * 1161: ProvideLoyalty-Too much royalty paid
+ * 1162: ProvideLoyalty-Registered validator does not exist
+ * 1163: ProvideLoyalty-Too many validators have participated
+ * 1164: ProvideLoyalty-Number of validators who participated did not satisfy the quorum
+ * 1170: Currency-The arrangement is not equal in size
+ * 1171: Currency-The validity of the data has expired.
+ * 1172: Currency-Registered validator does not exist
+ * 1173: Currency-Too many validators have participated
+ * 1174: Currency-Number of validators who participated did not satisfy the quorum
+ * 1200: The shop ID already exists
+ * 1201: The shop ID is not exists
+ * 1202: The shop is not activated
+ * 1211: This exchange rate is not supported
+ * 1220: Insufficient withdrawal amount
+ * 1221: Withdrawal is already opened
+ * 1222: Withdrawal is not opened
+ * 1501: Invalid signature
+ * 1502: Unregistered phone number
+ * 1503: Does not match registered wallet address
+ * 1505: Invalid secret key
+ * 1506: Expired signature
+ * 1510: Insufficient system balance
+ * 1511: Insufficient balance
+ * 1512: Not allowed deposit
+ * 1513: Insufficient fee or system balance
+ * 1514: Insufficient liquidity balance
+ * 1520: Loyalty type is not TOKEN
+ * 1521: Invalid value entered
+ * 1530: The payment ID already exists
+ * 1531: The status of the payment corresponding to the payment ID is not in progress
+ * 1532: The status of the payment corresponding to the payment ID is not a cancellable condition
+ * 1533: The status of the payment corresponding to the payment ID is not being cancelled
+ * 1534: The period for cancellation of payment has expired
+ * 1711: Already Exist Deposit
+ * 1712: No Exist Withdraw
+ * 1714: The value entered is not an appropriate value
+ * 1715: Already Confirm Withdraw
+ * 1716: The amount should be greater than the fee
+ * 1717: Does not match the address registered on the bridge
+ * 1718: Does not match the amount registered on the bridge
+ * 2001: Failed to check the validity of parameters
+ * 2002: The access key entered is not valid
+ * 2003: The payment ID is not exist
+ * 2004: Temporary address that does not exist
+ * 2005: Mobile notification not allowed
+ * 2006: Can not find delegator
+ * 2007: The phone number format is invalid.
+ * 2008: Mobile information not found.
+ * 2020: The status code for this payment cannot be approved
+ * 2022: The status code for this payment cannot be cancelled
+ * 2024: The status code for this payment cannot process closing
+ * 2025: This payment has already been approved
+ * 2026: This payment has already been closed
+ * 2027: This payment has already been approved and failed
+ * 2028: The status code for this payment cannot be denied
+ * 2029: This payment has forced to close
+ * 2030: This payment cannot be closed before it is approved
+ * 2033: The task ID is not exist
+ * 2040: The status code for this task cannot be approved
+ * 3001: Bridge functionality is not yet available
+ * 3072: The shopId is invalid
+ * 4000: Denied by user
+ * 5000: Smart Contract Error
+ * 6000: Server Error
+ * 7000: Timeout period expired
+ */ +export enum ResultCode { + "CODE0000" = 0, + "CODE1000" = 1000, + "CODE1001" = 1001, + "CODE1002" = 1002, + "CODE1003" = 1003, + "CODE1010" = 1010, + "CODE1020" = 1020, + "CODE1030" = 1030, + "CODE1031" = 1031, + "CODE1050" = 1050, + "CODE1051" = 1051, + "CODE1052" = 1052, + "CODE1053" = 1053, + "CODE1054" = 1054, + "CODE1160" = 1160, + "CODE1161" = 1161, + "CODE1162" = 1162, + "CODE1163" = 1163, + "CODE1164" = 1164, + "CODE1170" = 1170, + "CODE1171" = 1171, + "CODE1172" = 1172, + "CODE1173" = 1173, + "CODE1174" = 1174, + "CODE1200" = 1200, + "CODE1201" = 1201, + "CODE1202" = 1202, + "CODE1211" = 1211, + "CODE1220" = 1220, + "CODE1221" = 1221, + "CODE1222" = 1222, + "CODE1501" = 1501, + "CODE1502" = 1502, + "CODE1503" = 1503, + "CODE1505" = 1505, + "CODE1506" = 1506, + "CODE1510" = 1510, + "CODE1511" = 1511, + "CODE1512" = 1512, + "CODE1513" = 1513, + "CODE1514" = 1514, + "CODE1520" = 1520, + "CODE1521" = 1521, + "CODE1530" = 1530, + "CODE1531" = 1531, + "CODE1532" = 1532, + "CODE1533" = 1533, + "CODE1534" = 1534, + "CODE1711" = 1711, + "CODE1712" = 1712, + "CODE1714" = 1714, + "CODE1715" = 1715, + "CODE1716" = 1716, + "CODE1717" = 1717, + "CODE1718" = 1718, + "CODE2001" = 2001, + "CODE2002" = 2002, + "CODE2003" = 2003, + "CODE2004" = 2004, + "CODE2005" = 2005, + "CODE2006" = 2006, + "CODE2007" = 2007, + "CODE2008" = 2008, + "CODE2020" = 2020, + "CODE2022" = 2022, + "CODE2024" = 2024, + "CODE2025" = 2025, + "CODE2026" = 2026, + "CODE2027" = 2027, + "CODE2028" = 2028, + "CODE2029" = 2029, + "CODE2030" = 2030, + "CODE2033" = 2033, + "CODE2040" = 2040, + "CODE3001" = 3001, + "CODE3072" = 3072, + "CODE4000" = 4000, + "CODE5000" = 5000, + "CODE6000" = 6000, + "CODE7000" = 7000, +} diff --git a/yarn.lock b/yarn.lock index a8532aef..0665b627 100644 --- a/yarn.lock +++ b/yarn.lock @@ -93,6 +93,11 @@ "@chainsafe/persistent-merkle-tree" "^0.4.2" case "^1.6.3" +"@cloudflare/json-schema-walker@^0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@cloudflare/json-schema-walker/-/json-schema-walker-0.1.1.tgz#d1cc94065327b0b3800158db40cb78124a3476de" + integrity sha512-P3n0hEgk1m6uKWgL4Yb1owzXVG4pM70G4kRnDQxZXiVvfCRtaqiHu+ZRiRPzmwGBiLTO1LWc2yR1M8oz0YkXww== + "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz" @@ -1584,6 +1589,13 @@ resolved "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz" integrity sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ== +"@types/http-proxy@^1.17.8": + version "1.17.15" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.15.tgz#12118141ce9775a6499ecb4c01d02f90fc839d36" + integrity sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ== + dependencies: + "@types/node" "*" + "@types/ip@^1.1.0": version "1.1.0" resolved "https://registry.npmjs.org/@types/ip/-/ip-1.1.0.tgz" @@ -1596,6 +1608,11 @@ resolved "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz" integrity sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA== +"@types/json-schema@^7.0.9": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + "@types/level-errors@*": version "3.0.0" resolved "https://registry.npmjs.org/@types/level-errors/-/level-errors-3.0.0.tgz" @@ -1690,6 +1707,11 @@ resolved "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz" integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== +"@types/node@^16.9.2": + version "16.18.105" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.105.tgz#7147176852774ec4d6dd626803888adf6b999feb" + integrity sha512-w2d0Z9yMk07uH3+Cx0N8lqFyi3yjXZxlbYappPj+AsOlT02OyxyiuNoNHdGt6EuiSm8Wtgp2YV7vWg+GMFrvFA== + "@types/node@^8.0.0": version "8.10.66" resolved "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz" @@ -2470,7 +2492,7 @@ body-parser@1.20.1: type-is "~1.6.18" unpipe "1.0.0" -body-parser@^1.19.0: +body-parser@1.20.2, body-parser@^1.19.0: version "1.20.2" resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz" integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== @@ -2510,6 +2532,13 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" +braces@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + brorand@^1.0.1, brorand@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz" @@ -3085,6 +3114,11 @@ cookie@0.5.0: resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cookie@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== + cookie@^0.4.1: version "0.4.2" resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz" @@ -3956,6 +3990,11 @@ event-target-shim@^5.0.0: resolved "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz" @@ -4033,6 +4072,43 @@ express@^4.17.1: utils-merge "1.0.1" vary "~1.1.2" +express@^4.18.2: + version "4.19.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" + integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.2" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.6.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + extend@^3.0.2, extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -4144,6 +4220,13 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + finalhandler@1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz" @@ -4203,6 +4286,11 @@ fn.name@1.x.x: resolved "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz" integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== +follow-redirects@^1.0.0: + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== + follow-redirects@^1.12.1, follow-redirects@^1.14.0: version "1.15.2" resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" @@ -4553,7 +4641,7 @@ glob@7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" -glob@8.1.0, glob@^8.0.3: +glob@8.1.0, glob@^8.0.3, glob@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz" integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== @@ -4585,7 +4673,7 @@ glob@^5.0.15: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.1.1, glob@^7.1.3: +glob@^7.0.0, glob@^7.1.1, glob@^7.1.3, glob@^7.1.7: version "7.2.3" resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -4947,6 +5035,26 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" +http-proxy-middleware@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== + dependencies: + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + http-response-object@^3.0.1: version "3.0.2" resolved "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz" @@ -5367,6 +5475,11 @@ is-plain-obj@^2.1.0: resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + is-regex@^1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" @@ -5618,6 +5731,13 @@ json-parse-even-better-errors@^2.3.0: resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== +json-schema-to-openapi-schema@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema-to-openapi-schema/-/json-schema-to-openapi-schema-0.4.0.tgz#64a5f5f3dfe1cc862f8c2cc30995ce8129d286a2" + integrity sha512-/DY8s4l28M5ZIJBhmcUFWbZChJV5v7RCA7RMVxubyD1l5KwIceUq6+EUnqQ2q3wh/2D3Zn8bNSeAu1i2X+sMHQ== + dependencies: + "@cloudflare/json-schema-walker" "^0.1.1" + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" @@ -6147,6 +6267,14 @@ methods@^1.1.2, methods@~1.1.2: resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== +micromatch@^4.0.2: + version "4.0.7" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.7.tgz#33e8190d9fe474a9895525f5618eee136d46c2e5" + integrity sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + micromatch@^4.0.4: version "4.0.5" resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" @@ -6733,6 +6861,11 @@ onetime@^5.1.0, onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" +openapi-types@^12.0.2: + version "12.1.3" + resolved "https://registry.yarnpkg.com/openapi-types/-/openapi-types-12.1.3.tgz#471995eb26c4b97b7bd356aacf7b91b73e777dd3" + integrity sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw== + optionator@^0.8.1: version "0.8.3" resolved "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz" @@ -6885,6 +7018,11 @@ path-browserify@^1.0.0: resolved "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz" integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== +path-equal@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/path-equal/-/path-equal-1.2.5.tgz#9fcbdd5e5daee448e96f43f3bac06c666b5e982a" + integrity sha512-i73IctDr3F2W+bsOWDyyVm/lqsXO47aY9nsFZUjTT/aljSbkxHxxCoyZ9UUrM8jK0JVod+An+rl48RCsvWM+9g== + path-exists@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" @@ -7480,6 +7618,11 @@ require-main-filename@^2.0.0: resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz" @@ -7654,7 +7797,7 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" -safe-stable-stringify@^2.3.1: +safe-stable-stringify@^2.2.0, safe-stable-stringify@^2.3.1: version "2.4.3" resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz" integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== @@ -8311,6 +8454,18 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +swagger-ui-dist@>=4.11.0: + version "5.17.14" + resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-5.17.14.tgz#e2c222e5bf9e15ccf80ec4bc08b4aaac09792fd6" + integrity sha512-CVbSfaLpstV65OnSjbXfVd6Sta3q3F7Cj/yYuvHMp1P90LztOLs6PfUnKEVAeiIVQt9u2SaPwv0LiH/OyMjHRw== + +swagger-ui-express@^4.6.2: + version "4.6.3" + resolved "https://registry.yarnpkg.com/swagger-ui-express/-/swagger-ui-express-4.6.3.tgz#870d0892654fe80e6970a2d680e22521acd2dc19" + integrity sha512-CDje4PndhTD2HkgyKH3pab+LKspDeB/NhPN2OF1j+piYIamQqBYwAXWESOT1Yju2xFg51bRW9sUng2WxDjzArw== + dependencies: + swagger-ui-dist ">=4.11.0" + sync-request@6.1.0, sync-request@^6.0.0: version "6.1.0" resolved "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz" @@ -8560,6 +8715,22 @@ tsort@0.0.1: resolved "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz" integrity sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw== +tspec@^0.1.116: + version "0.1.116" + resolved "https://registry.yarnpkg.com/tspec/-/tspec-0.1.116.tgz#6eee358d06d7e3c621f3faaa79965a99c20cc0b6" + integrity sha512-wPln1/0JR97RWALE7WcMZxZvf5lKWkh+WoWKXvbzwq4l4KZuPEpQXUYl5f/y8sR7sHReWmBVmdtHfTF496S6hA== + dependencies: + debug "^4.3.4" + express "^4.18.2" + glob "^8.1.0" + http-proxy-middleware "^2.0.6" + json-schema-to-openapi-schema "^0.4.0" + openapi-types "^12.0.2" + swagger-ui-express "^4.6.2" + typescript "~5.1.0" + typescript-json-schema "^0.62.0" + yargs "^17.7.1" + tsutils@^2.29.0: version "2.29.0" resolved "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz" @@ -8679,11 +8850,30 @@ typedarray@^0.0.6: resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== +typescript-json-schema@^0.62.0: + version "0.62.0" + resolved "https://registry.yarnpkg.com/typescript-json-schema/-/typescript-json-schema-0.62.0.tgz#774b06b0c9d86d7f3580ea9136363a6eafae1470" + integrity sha512-qRO6pCgyjKJ230QYdOxDRpdQrBeeino4v5p2rYmSD72Jf4rD3O+cJcROv46sQukm46CLWoeusqvBgKpynEv25g== + dependencies: + "@types/json-schema" "^7.0.9" + "@types/node" "^16.9.2" + glob "^7.1.7" + path-equal "^1.2.5" + safe-stable-stringify "^2.2.0" + ts-node "^10.9.1" + typescript "~5.1.0" + yargs "^17.1.1" + typescript@^4.5.5: version "4.9.5" resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== +typescript@~5.1.0: + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== + typical@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz" @@ -9187,7 +9377,7 @@ yargs@16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" -yargs@^17.7.1: +yargs@^17.1.1, yargs@^17.7.1: version "17.7.2" resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==