From f00016b6476d32c557272a716c019db41ae67159 Mon Sep 17 00:00:00 2001 From: microwavedcola1 <89031858+microwavedcola1@users.noreply.github.com> Date: Tue, 22 Feb 2022 14:12:02 +0100 Subject: [PATCH] add support for time in force order type (#23255) Signed-off-by: microwavedcola1 --- explorer/package-lock.json | 194 ++++++++++-------- .../components/instruction/MangoDetails.tsx | 9 + .../mango/PlacePerpOrder2DetailsCard.tsx | 121 +++++++++++ .../src/components/instruction/mango/types.ts | 27 +++ 4 files changed, 262 insertions(+), 89 deletions(-) create mode 100644 explorer/src/components/instruction/mango/PlacePerpOrder2DetailsCard.tsx diff --git a/explorer/package-lock.json b/explorer/package-lock.json index ef696cecd7..5b77d4a013 100644 --- a/explorer/package-lock.json +++ b/explorer/package-lock.json @@ -1579,23 +1579,21 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" }, "node_modules/@blockworks-foundation/mango-client": { - "version": "3.2.16", - "resolved": "https://registry.npmjs.org/@blockworks-foundation/mango-client/-/mango-client-3.2.16.tgz", - "integrity": "sha512-ZI3Tt/k77azt4iBrPiWsm9rS6EPEbGX+IsWKzCTCXLIfwOxpF09FarL+1YL/hBvoRkd8X/jAyQ1/KWpkb3zvUg==", + "version": "3.3.17", + "resolved": "https://registry.npmjs.org/@blockworks-foundation/mango-client/-/mango-client-3.3.17.tgz", + "integrity": "sha512-d7QNaygWKa7qNjtUIbs3r7evN1qaiDlHmgt20RQ15iD8XmuYgpWy6ZLTYu2lhX1feoEqZKv++PEH+yYVHxZNWQ==", "dependencies": { - "@project-serum/anchor": "^0.16.2", + "@project-serum/anchor": "^0.21.0", "@project-serum/serum": "0.13.55", "@project-serum/sol-wallet-adapter": "^0.2.0", "@solana/spl-token": "^0.1.6", - "@solana/web3.js": "1.21.0", + "@solana/web3.js": "^1.31.0", "big.js": "^6.1.1", "bn.js": "^5.2.0", "buffer-layout": "^1.2.1", + "cross-fetch": "^3.1.5", "dotenv": "^10.0.0", "yargs": "^17.0.1" - }, - "engines": { - "node": ">=14.15.3" } }, "node_modules/@blockworks-foundation/mango-client/node_modules/@babel/runtime": { @@ -1610,17 +1608,18 @@ } }, "node_modules/@blockworks-foundation/mango-client/node_modules/@project-serum/anchor": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.16.2.tgz", - "integrity": "sha512-wOJwObd4wOZ5tRRMCKYjeMNsEmf7vuC71KQRnw6wthhErL8c/818n4gYIZCf/1ZPl/8WPruIlmtQHDSEyy2+0Q==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.21.0.tgz", + "integrity": "sha512-flRuW/F+iC8mitNokx82LOXyND7Dyk6n5UUPJpQv/+NfySFrNFlzuQZaBZJ4CG5g9s8HS/uaaIz1nVkDR8V/QA==", "dependencies": { - "@project-serum/borsh": "^0.2.2", + "@project-serum/borsh": "^0.2.4", "@solana/web3.js": "^1.17.0", "base64-js": "^1.5.1", "bn.js": "^5.1.2", "bs58": "^4.0.1", - "buffer-layout": "^1.2.0", + "buffer-layout": "^1.2.2", "camelcase": "^5.3.1", + "cross-fetch": "^3.1.5", "crypto-hash": "^1.3.0", "eventemitter3": "^4.0.7", "find": "^0.3.0", @@ -1726,27 +1725,6 @@ "ieee754": "^1.2.1" } }, - "node_modules/@blockworks-foundation/mango-client/node_modules/@solana/web3.js": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.21.0.tgz", - "integrity": "sha512-x1NXlF92tEjxuTxS0u4n9JV17UKk0Dn2L+qSWGvKOb4iWhzApDj6wicJsrGdSbGdxnZ7eciQ/SNn3zB4ydUllA==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "@solana/buffer-layout": "^3.0.0", - "bn.js": "^5.0.0", - "borsh": "^0.4.0", - "bs58": "^4.0.1", - "buffer": "6.0.1", - "crypto-hash": "^1.2.2", - "jayson": "^3.4.4", - "js-sha3": "^0.8.0", - "node-fetch": "^2.6.1", - "rpc-websockets": "^7.4.2", - "secp256k1": "^4.0.2", - "superstruct": "^0.14.2", - "tweetnacl": "^1.0.0" - } - }, "node_modules/@blockworks-foundation/mango-client/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -1849,11 +1827,6 @@ "node": ">=8" } }, - "node_modules/@blockworks-foundation/mango-client/node_modules/superstruct": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", - "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" - }, "node_modules/@blockworks-foundation/mango-client/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -4544,9 +4517,9 @@ "integrity": "sha512-WjR1hOeg+kki3ZIOjaf4b5WVcay1jaliKSYiEaB1XzwhMQZJxRdQRv0V31EKBYlxb4T7SK3hjfc/jxyU64BoSw==" }, "node_modules/@project-serum/borsh": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.2.tgz", - "integrity": "sha512-Ms+aWmGVW6bWd3b0+MWwoaYig2QD0F90h0uhr7AzY3dpCb5e2S6RsRW02vFTfa085pY2VLB7nTZNbFECQ1liTg==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.5.tgz", + "integrity": "sha512-UmeUkUoKdQ7rhx6Leve1SssMR/Ghv8qrEiyywyxSWg7ooV7StdpPBhciiy5eB3T0qU1BXvdRNC8TdrkxK7WC5Q==", "dependencies": { "bn.js": "^5.1.2", "buffer-layout": "^1.2.0" @@ -9044,11 +9017,49 @@ } }, "node_modules/cross-fetch": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", - "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", "dependencies": { - "node-fetch": "2.6.1" + "node-fetch": "2.6.7" + } + }, + "node_modules/cross-fetch/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/cross-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "node_modules/cross-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "node_modules/cross-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" } }, "node_modules/cross-spawn": { @@ -28311,18 +28322,19 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" }, "@blockworks-foundation/mango-client": { - "version": "3.2.16", - "resolved": "https://registry.npmjs.org/@blockworks-foundation/mango-client/-/mango-client-3.2.16.tgz", - "integrity": "sha512-ZI3Tt/k77azt4iBrPiWsm9rS6EPEbGX+IsWKzCTCXLIfwOxpF09FarL+1YL/hBvoRkd8X/jAyQ1/KWpkb3zvUg==", + "version": "3.3.17", + "resolved": "https://registry.npmjs.org/@blockworks-foundation/mango-client/-/mango-client-3.3.17.tgz", + "integrity": "sha512-d7QNaygWKa7qNjtUIbs3r7evN1qaiDlHmgt20RQ15iD8XmuYgpWy6ZLTYu2lhX1feoEqZKv++PEH+yYVHxZNWQ==", "requires": { - "@project-serum/anchor": "^0.16.2", + "@project-serum/anchor": "^0.21.0", "@project-serum/serum": "0.13.55", "@project-serum/sol-wallet-adapter": "^0.2.0", "@solana/spl-token": "^0.1.6", - "@solana/web3.js": "1.21.0", + "@solana/web3.js": "^1.31.0", "big.js": "^6.1.1", "bn.js": "^5.2.0", "buffer-layout": "^1.2.1", + "cross-fetch": "^3.1.5", "dotenv": "^10.0.0", "yargs": "^17.0.1" }, @@ -28336,17 +28348,18 @@ } }, "@project-serum/anchor": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.16.2.tgz", - "integrity": "sha512-wOJwObd4wOZ5tRRMCKYjeMNsEmf7vuC71KQRnw6wthhErL8c/818n4gYIZCf/1ZPl/8WPruIlmtQHDSEyy2+0Q==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.21.0.tgz", + "integrity": "sha512-flRuW/F+iC8mitNokx82LOXyND7Dyk6n5UUPJpQv/+NfySFrNFlzuQZaBZJ4CG5g9s8HS/uaaIz1nVkDR8V/QA==", "requires": { - "@project-serum/borsh": "^0.2.2", + "@project-serum/borsh": "^0.2.4", "@solana/web3.js": "^1.17.0", "base64-js": "^1.5.1", "bn.js": "^5.1.2", "bs58": "^4.0.1", - "buffer-layout": "^1.2.0", + "buffer-layout": "^1.2.2", "camelcase": "^5.3.1", + "cross-fetch": "^3.1.5", "crypto-hash": "^1.3.0", "eventemitter3": "^4.0.7", "find": "^0.3.0", @@ -28424,27 +28437,6 @@ } } }, - "@solana/web3.js": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.21.0.tgz", - "integrity": "sha512-x1NXlF92tEjxuTxS0u4n9JV17UKk0Dn2L+qSWGvKOb4iWhzApDj6wicJsrGdSbGdxnZ7eciQ/SNn3zB4ydUllA==", - "requires": { - "@babel/runtime": "^7.12.5", - "@solana/buffer-layout": "^3.0.0", - "bn.js": "^5.0.0", - "borsh": "^0.4.0", - "bs58": "^4.0.1", - "buffer": "6.0.1", - "crypto-hash": "^1.2.2", - "jayson": "^3.4.4", - "js-sha3": "^0.8.0", - "node-fetch": "^2.6.1", - "rpc-websockets": "^7.4.2", - "secp256k1": "^4.0.2", - "superstruct": "^0.14.2", - "tweetnacl": "^1.0.0" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -28519,11 +28511,6 @@ "ansi-regex": "^5.0.0" } }, - "superstruct": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", - "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" - }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -30535,9 +30522,9 @@ } }, "@project-serum/borsh": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.2.tgz", - "integrity": "sha512-Ms+aWmGVW6bWd3b0+MWwoaYig2QD0F90h0uhr7AzY3dpCb5e2S6RsRW02vFTfa085pY2VLB7nTZNbFECQ1liTg==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.5.tgz", + "integrity": "sha512-UmeUkUoKdQ7rhx6Leve1SssMR/Ghv8qrEiyywyxSWg7ooV7StdpPBhciiy5eB3T0qU1BXvdRNC8TdrkxK7WC5Q==", "requires": { "bn.js": "^5.1.2", "buffer-layout": "^1.2.0" @@ -34098,11 +34085,40 @@ } }, "cross-fetch": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", - "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", "requires": { - "node-fetch": "2.6.1" + "node-fetch": "2.6.7" + }, + "dependencies": { + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } } }, "cross-spawn": { diff --git a/explorer/src/components/instruction/MangoDetails.tsx b/explorer/src/components/instruction/MangoDetails.tsx index 0d6b7c9b7c..2b39ff9f4a 100644 --- a/explorer/src/components/instruction/MangoDetails.tsx +++ b/explorer/src/components/instruction/MangoDetails.tsx @@ -21,9 +21,11 @@ import { decodeCancelSpotOrder, decodeChangePerpMarketParams, decodePlacePerpOrder, + decodePlacePerpOrder2, decodePlaceSpotOrder, parseMangoInstructionTitle, } from "./mango/types"; +import { PlacePerpOrder2DetailsCard } from "./mango/PlacePerpOrder2DetailsCard"; export function MangoDetailsCard(props: { ix: TransactionInstruction; @@ -99,6 +101,13 @@ export function MangoDetailsCard(props: { {...props} /> ); + case "PlacePerpOrder2": + return ( + + ); case "ConsumeEvents": return ; case "CancelPerpOrder": diff --git a/explorer/src/components/instruction/mango/PlacePerpOrder2DetailsCard.tsx b/explorer/src/components/instruction/mango/PlacePerpOrder2DetailsCard.tsx new file mode 100644 index 0000000000..3d6d41ea40 --- /dev/null +++ b/explorer/src/components/instruction/mango/PlacePerpOrder2DetailsCard.tsx @@ -0,0 +1,121 @@ +import { SignatureResult, TransactionInstruction } from "@solana/web3.js"; +import BN from "bn.js"; +import { Address } from "components/common/Address"; +import { useCluster } from "providers/cluster"; +import { useEffect, useState } from "react"; +import { InstructionCard } from "../InstructionCard"; +import { + getPerpMarketFromInstruction, + getPerpMarketFromPerpMarketConfig, + OrderLotDetails, + PlacePerpOrder2, +} from "./types"; + +export function PlacePerpOrder2DetailsCard(props: { + ix: TransactionInstruction; + index: number; + result: SignatureResult; + info: PlacePerpOrder2; + innerCards?: JSX.Element[]; + childIndex?: number; +}) { + const { ix, index, result, info, innerCards, childIndex } = props; + const mangoAccount = ix.keys[1]; + const perpMarketAccountMeta = ix.keys[4]; + const mangoPerpMarketConfig = getPerpMarketFromInstruction( + ix, + perpMarketAccountMeta + ); + + const cluster = useCluster(); + const [orderLotDetails, setOrderLotDetails] = + useState(null); + useEffect(() => { + async function getOrderLotDetails() { + if (mangoPerpMarketConfig === undefined) { + return; + } + const mangoPerpMarket = await getPerpMarketFromPerpMarketConfig( + cluster.url, + mangoPerpMarketConfig + ); + const maxBaseQuantity = mangoPerpMarket.baseLotsToNumber( + new BN(info.maxBaseQuantity.toString()) + ); + const limitPrice = mangoPerpMarket.priceLotsToNumber( + new BN(info.price.toString()) + ); + setOrderLotDetails({ + price: limitPrice, + size: maxBaseQuantity, + } as OrderLotDetails); + } + getOrderLotDetails(); + }, [cluster.url, info.maxBaseQuantity, info.price, mangoPerpMarketConfig]); + + return ( + + + Mango account + + {" "} +
+ + + {mangoPerpMarketConfig !== undefined && ( + + Perp market + {mangoPerpMarketConfig.name} + + )} + + Perp market address + +
+ + + {info.clientOrderId !== "0" && ( + + Client order Id + {info.clientOrderId} + + )} + + Order type + {info.orderType} + + + Side + {info.side} + + {orderLotDetails !== null && ( + + price + {orderLotDetails?.price} USDC + + )} + {orderLotDetails !== null && ( + + quantity + {orderLotDetails?.size} + + )} + + Reduce only + {info.reduceOnly} + + + + Expiry timestamp + {info.expiryTimestamp} + + + ); +} diff --git a/explorer/src/components/instruction/mango/types.ts b/explorer/src/components/instruction/mango/types.ts index 0d8f7f2fea..317c81ded6 100644 --- a/explorer/src/components/instruction/mango/types.ts +++ b/explorer/src/components/instruction/mango/types.ts @@ -166,6 +166,33 @@ export const decodePlacePerpOrder = ( return placePerpOrder; }; +export type PlacePerpOrder2 = { + price: number; + maxBaseQuantity: number; + clientOrderId: String; + side: String; + orderType: String; + reduceOnly: String; + expiryTimestamp: number; +}; + +export const decodePlacePerpOrder2 = ( + ix: TransactionInstruction +): PlacePerpOrder2 => { + const decoded = MangoInstructionLayout.decode(ix.data, 0); + const placePerpOrder2: PlacePerpOrder2 = { + price: decoded.PlacePerpOrder2.price.toNumber(), + maxBaseQuantity: decoded.PlacePerpOrder2.maxBaseQuantity.toNumber(), + clientOrderId: decoded.PlacePerpOrder2.clientOrderId.toString(), + side: decoded.PlacePerpOrder2.side.toString(), + orderType: decoded.PlacePerpOrder2.orderType.toString(), + reduceOnly: decoded.PlacePerpOrder2.reduceOnly.toString(), + expiryTimestamp: decoded.PlacePerpOrder2.expiryTimestamp.toNumber(), + }; + + return placePerpOrder2; +}; + export type CancelPerpOrder = { orderId: String; invalidIdOk: String;