Compare commits
15
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf6d6e70bc | ||
|
|
9e2dc19426 | ||
|
|
344971d5a9 | ||
|
|
de1f8b5895 | ||
|
|
5b826f89d8 | ||
|
|
246c07f355 | ||
|
|
642bc8072b | ||
|
|
de8e543bf4 | ||
|
|
787a8ea1b3 | ||
|
|
d28ff4cfe7 | ||
|
|
71e1a116c7 | ||
|
|
f0fc737e58 | ||
|
|
fe447167ca | ||
|
|
02a8a8d9ec | ||
|
|
f7bee22ba6 |
@@ -70,11 +70,6 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
const step = toDecimal(market.positionDecimalPlaces);
|
||||
const order = watch();
|
||||
const { pubKey } = useVegaWallet();
|
||||
const estMargin = useOrderMargin({
|
||||
order,
|
||||
market,
|
||||
partyId: pubKey || '',
|
||||
});
|
||||
const { message: invalidText, isDisabled } = useOrderValidation({
|
||||
market,
|
||||
order,
|
||||
@@ -127,11 +122,18 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
);
|
||||
return new BigNumber(market?.depth?.lastTrade?.price)
|
||||
.multipliedBy(multiplier)
|
||||
.toNumber();
|
||||
.toString();
|
||||
}
|
||||
return null;
|
||||
return undefined;
|
||||
}, [market?.depth?.lastTrade?.price, order.side, slippage]);
|
||||
|
||||
const estMargin = useOrderMargin({
|
||||
order,
|
||||
market,
|
||||
partyId: pubKey || '',
|
||||
derivedPrice: price,
|
||||
});
|
||||
|
||||
const formattedPrice =
|
||||
price && addDecimalsFormatNumber(price, market.decimalPlaces);
|
||||
|
||||
|
||||
+4
-3
@@ -1,13 +1,14 @@
|
||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||
NX_TENDERMINT_URL=https://n01.stagnet3.vega.xyz/tm
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://n01.stagnet3.vega.xyz/tm/websocket
|
||||
NX_TENDERMINT_URL=https://tm.be.stagnet3.vega.xyz
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.be.stagnet3.vega.xyz/websocket
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
|
||||
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
|
||||
NX_VEGA_ENV=STAGNET3
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_BLOCK_EXPLORER=
|
||||
NX_BLOCK_EXPLORER=https://be.stagnet3.vega.xyz/rest
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
|
||||
# App flags
|
||||
NX_EXPLORER_ASSETS=1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# App configuration variables
|
||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||
NX_TENDERMINT_URL=https://be.explorer.vega.xyz
|
||||
NX_TENDERMINT_URL=https://be.explorer.vega.xyz/websocket
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.explorer.vega.xyz
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/mainnet-network.json
|
||||
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
|
||||
|
||||
@@ -7,7 +7,7 @@ NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
||||
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
|
||||
NX_VEGA_TOKEN_URL=https://stagnet1.token.vega.xyz
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.xyz
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
|
||||
NX_TENDERMINT_URL=https://tm.be.stagnet1.vega.xyz
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.be.stagnet1.vega.xyz/websocket
|
||||
NX_BLOCK_EXPLORER=https://be.stagnet1.vega.xyz/rest
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
# App configuration variables
|
||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||
NX_TENDERMINT_URL=https://tm.n00.stagnet3.vega.xyz
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n00.stagnet3.vega.xyz/websocket
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.be.stagnet3.vega.xyz/websocket
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
|
||||
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
|
||||
NX_VEGA_ENV=STAGNET3
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_BLOCK_EXPLORER=https://be.stagnet3.vega.xyz/rest
|
||||
NX_ETHERSCAN_URL=https://be.stagnet3.vega.xyz/rest
|
||||
NX_BLOCK_EXPLORER=https://be.stagnet3.vega.xyz/rest
|
||||
@@ -1,8 +1,8 @@
|
||||
# App configuration variables
|
||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.be.testnet.vega.xyz/websocket
|
||||
NX_BLOCK_EXPLORER=https://be.testnet.vega.xyz/rest
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.be.testnet.vega.xyz/
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
|
||||
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
|
||||
NX_VEGA_ENV=TESTNET
|
||||
|
||||
@@ -26,7 +26,8 @@ export const TxDetailsWrapper = ({
|
||||
const {
|
||||
state: { data: blockData },
|
||||
} = useFetch<TendermintBlocksResponse>(
|
||||
`${DATA_SOURCES.tendermintUrl}/block?height=${height}`
|
||||
`${DATA_SOURCES.tendermintUrl}/block?height=${height}`,
|
||||
{ cache: 'force-cache' }
|
||||
);
|
||||
|
||||
const child = useMemo(() => getTransactionComponent(txData), [txData]);
|
||||
|
||||
@@ -44,7 +44,7 @@ const Blocks = () => {
|
||||
refetch,
|
||||
} = useFetch<TendermintBlockchainResponse>(
|
||||
`${DATA_SOURCES.tendermintUrl}/blockchain`,
|
||||
undefined,
|
||||
{ cache: 'no-cache' },
|
||||
false
|
||||
);
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@ const Block = () => {
|
||||
const {
|
||||
state: { data: blockData, loading, error },
|
||||
} = useFetch<TendermintBlocksResponse>(
|
||||
`${DATA_SOURCES.tendermintUrl}/block?height=${block}`
|
||||
`${DATA_SOURCES.tendermintUrl}/block?height=${block}`,
|
||||
{ cache: 'force-cache' }
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -351,7 +351,7 @@
|
||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||
"total_added": "129999.45",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "89077.06065926284600326",
|
||||
"locked_amount": "88839.711830710158224655",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "129999.45",
|
||||
@@ -417,7 +417,7 @@
|
||||
"tranche_end": "2023-09-03T00:00:00.000Z",
|
||||
"total_added": "52600",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "40710.3334284627032",
|
||||
"locked_amount": "40566.14878234398856",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "2600",
|
||||
@@ -590,7 +590,7 @@
|
||||
"tranche_end": "2023-09-17T00:00:00.000Z",
|
||||
"total_added": "5000",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "4061.584379756469",
|
||||
"locked_amount": "4047.878614916286",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "5000",
|
||||
@@ -801,7 +801,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "97499.58",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "30598.500226108789835724",
|
||||
"locked_amount": "30365.683135342087052892",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "97499.58",
|
||||
@@ -834,7 +834,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "135173.4239508",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "41822.86719840489469619178036",
|
||||
"locked_amount": "41504.64642952072194908217954",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "135173.4239508",
|
||||
@@ -867,7 +867,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "32499.86",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "12872.2606372887369764782",
|
||||
"locked_amount": "12774.31850773929295347",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "32499.86",
|
||||
@@ -900,7 +900,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "10833.29",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "4189.7959279769199976577",
|
||||
"locked_amount": "4157.916715216503367102",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "10833.29",
|
||||
@@ -933,7 +933,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "22749.93",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "15662.392952797776307689",
|
||||
"locked_amount": "15543.221335405760330901",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "6500",
|
||||
@@ -1072,7 +1072,7 @@
|
||||
"tranche_end": "2023-05-01T00:00:00.000Z",
|
||||
"total_added": "22500",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "19578.18974447513925",
|
||||
"locked_amount": "19453.81560773480775",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "7500",
|
||||
@@ -1125,7 +1125,7 @@
|
||||
"tranche_end": "2023-06-02T00:00:00.000Z",
|
||||
"total_added": "1939928.38",
|
||||
"total_removed": "928642.9598472029154",
|
||||
"locked_amount": "1007145.227895785748862222",
|
||||
"locked_amount": "1001827.587459170315643514",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "1852091.69",
|
||||
@@ -1477,7 +1477,7 @@
|
||||
"tranche_end": "2023-02-01T00:00:00.000Z",
|
||||
"total_added": "42500",
|
||||
"total_removed": "18381.5424969",
|
||||
"locked_amount": "15821.008359752413375",
|
||||
"locked_amount": "15589.90979770531325",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "12500",
|
||||
@@ -6303,8 +6303,8 @@
|
||||
"tranche_id": 11,
|
||||
"tranche_start": "2021-09-03T00:00:00.000Z",
|
||||
"tranche_end": "2022-09-03T00:00:00.000Z",
|
||||
"total_added": "45481.000000000000000003",
|
||||
"total_removed": "27913.75324099301",
|
||||
"total_added": "46610.000000000000000003",
|
||||
"total_removed": "28274.75324099301",
|
||||
"locked_amount": "0",
|
||||
"deposits": [
|
||||
{
|
||||
@@ -6357,6 +6357,201 @@
|
||||
"user": "0xDFc4B2D40D12F0eFf04b5F13D32c847f0a9ba7dD",
|
||||
"tx": "0xa81022fd31ef7c0dc0e50121a8a99a2fd0c7b14a4f99e3f77ebbf8283da4e37d"
|
||||
},
|
||||
{
|
||||
"amount": "10",
|
||||
"user": "0xB12Cdb63E38f9a6ff2C0F68aBC3CA9beFCb7148c",
|
||||
"tx": "0x20746dd7898e20747d4d7331c65d3ba443ce71c99e7ab2cb8332d5e708050dd0"
|
||||
},
|
||||
{
|
||||
"amount": "50",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0x04f0af4557ef852e5132a139f9f9c45315c86cfab2b9147cb279f6a4fb120146"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0xd2fc5b073a66634f75d80de216d4ee83de510a767e44d2a74bce25f66caf3890"
|
||||
},
|
||||
{
|
||||
"amount": "50",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0x24addf02f8ce6aa54a601359d7400e0c4f99aae8fbca961ccc7f5c155984da37"
|
||||
},
|
||||
{
|
||||
"amount": "46",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0x69b7fedbd011b574f6541eae53a4d39212f72a5c9707e244f2b56b14bda40663"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0xb3fc83a99518e3d17281c6a2f26eb9ce68e21b3a97796e6cfb6601355a58e6d1"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0x0c10322e4ac684a17359fe5bff7acb6ad6ac90b0b35fd31068d6254e298f6d06"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0x13e769680c99022af2fe734eda617c638b8bfb6035ca027eba47f20cb4a07a49"
|
||||
},
|
||||
{
|
||||
"amount": "15",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0x8b933a7aaa3b1ea891c4392ec290df935e0ebcd433713df4c07d8583a123b125"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0x0e722eedc0d2c4cca2b38bbe54b914f0833ed77db8e068b4e0580fcc63d05fcf"
|
||||
},
|
||||
{
|
||||
"amount": "15",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0xcfe1c973d4d73770bff8defed041187f405bfdd24835bd08294be8065deed3d5"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0x3a437dda1289198f485de1dce66eda37aaec0d4d2f157a2e8e155962616f9056"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xB12Cdb63E38f9a6ff2C0F68aBC3CA9beFCb7148c",
|
||||
"tx": "0x71e4e558ceb26dc02a6d69dce9852a0379c07054aa9db12f7edef34ee20743ea"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0xd5cc8fd70dcd8ef2e902032c17b0284387a4032f1ecda509d8da1a87faa430de"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xB12Cdb63E38f9a6ff2C0F68aBC3CA9beFCb7148c",
|
||||
"tx": "0x6153b89191f8988680a2fa7cd44965e6fdfe15701b2d1973307d6e2dd3ef93d2"
|
||||
},
|
||||
{
|
||||
"amount": "26",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0xa61b2f4a7962db3e1b3bd008949a45fca273d919236582fac2837fe9338bf09d"
|
||||
},
|
||||
{
|
||||
"amount": "15",
|
||||
"user": "0xB12Cdb63E38f9a6ff2C0F68aBC3CA9beFCb7148c",
|
||||
"tx": "0x1cb55bafcb2c889ae684c764145e4378e029dbb6d395e9cf8670fd82b0aa6a71"
|
||||
},
|
||||
{
|
||||
"amount": "15",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0x3d5e00f458e04b8869a5a800948b27a681babcc008fad092b0cea92bd77ce4d4"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0x4aa20102d2e76f332a83555ee29892be1972fd41a6a647c5dafd0aed9ac08da2"
|
||||
},
|
||||
{
|
||||
"amount": "15",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0x5c94d762403f8c1af0513f22578e4839d191f72230a4bc5e88292294056dc7b1"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0x470364c533cc37371644ceec17d2ecb8efc123ae2a48a67538f1e7a551d87507"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0x005a58c1e9c52919d16b4033924a1d20c8ece3ea8b4ef31c18dc22063b6f0e37"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tx": "0xe84e0f602076c3cbbe1fce4a807cd77b7edc0a5402a60a632fa7210fcf45e519"
|
||||
},
|
||||
{
|
||||
"amount": "60",
|
||||
"user": "0xc7eC0d77a1417C97fb455f404c4B425A69a0004d",
|
||||
"tx": "0x1610a45e4e6cf254dd2344a4f03b81ee4be04e3b4c46b9f1fa5460a500b86c5f"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xc7eC0d77a1417C97fb455f404c4B425A69a0004d",
|
||||
"tx": "0x973127e641cf01314a44e7560be0b54b1b139bad731e1379358e169f31b606e0"
|
||||
},
|
||||
{
|
||||
"amount": "100",
|
||||
"user": "0xc7eC0d77a1417C97fb455f404c4B425A69a0004d",
|
||||
"tx": "0x03ebb823c4a3aa2794b9f9dae9b9fb75e19f518cb8fbd1c245fd07144c2a2760"
|
||||
},
|
||||
{
|
||||
"amount": "46",
|
||||
"user": "0xc7eC0d77a1417C97fb455f404c4B425A69a0004d",
|
||||
"tx": "0xd5bf21ff59df324ce1fadc9acd3edf649904a0be184e91994b6f59255a98170f"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xc7eC0d77a1417C97fb455f404c4B425A69a0004d",
|
||||
"tx": "0x38ac7e75b875453765de7759023d75161f210354cdb09932a60d8e16277e1d92"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xc7eC0d77a1417C97fb455f404c4B425A69a0004d",
|
||||
"tx": "0x676bbb8223541f0527e33572dac4641a527d4719e7958bca495950c4ddc25dab"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xc7eC0d77a1417C97fb455f404c4B425A69a0004d",
|
||||
"tx": "0x8beb66b4f217717342943d8e4ec6f896a5ac4f092f948e3b2dabeaea6269814e"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"tx": "0xbd37ca2a89da18ae711e2fcd7b6b41ed83b2bbdc11e0d704776f9673d7449ecf"
|
||||
},
|
||||
{
|
||||
"amount": "60",
|
||||
"user": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"tx": "0x6c01fda718564da41840d86464a32afd9640b7d599d7fed2a1ff61d7c9d47193"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"tx": "0xe41c66b0f4a6dd290909324fd048ff348f33c59a60974bd231920e00d4e4288d"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"tx": "0xb755c0264b6b31a3aa767b0683da02d9881e7c762587621c5031ce6b4ff8f54f"
|
||||
},
|
||||
{
|
||||
"amount": "26",
|
||||
"user": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"tx": "0xdcd2e1e9f393809c80283575d200a6d87096bb108a0c357a08c5e8e4f1c98de6"
|
||||
},
|
||||
{
|
||||
"amount": "40",
|
||||
"user": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"tx": "0x6cd1e72f959033edd31958e6de7a44f6a1413a3bf98cd44db00c574603a06ea2"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"tx": "0xc70308ea7193419a02d35ee0a39fe47f613bec25e9f681013b64b508f97aa679"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"tx": "0xfd21b34d23162d743a1db14bb2072d88fd50a320c052646667de1bda6124c06c"
|
||||
},
|
||||
{
|
||||
"amount": "10",
|
||||
"user": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"tx": "0x49b6f2f5f8239d2029dda62147d53666e2bae003272cd49de4ee9ffa872d9696"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xB12Cdb63E38f9a6ff2C0F68aBC3CA9beFCb7148c",
|
||||
@@ -14674,6 +14869,16 @@
|
||||
"user": "0xA11f6613272763Dde1F3c139c5bD1c585293c2ec",
|
||||
"tx": "0xf520e07c453a758bba834b04607c7be251d39e69ce510534fdc7e68d8f738775"
|
||||
},
|
||||
{
|
||||
"amount": "65",
|
||||
"user": "0xB12Cdb63E38f9a6ff2C0F68aBC3CA9beFCb7148c",
|
||||
"tx": "0x679502e8d24eb2c2476f3e1976f8b686639ce46358a28119894e75c8e418923b"
|
||||
},
|
||||
{
|
||||
"amount": "296",
|
||||
"user": "0xc7eC0d77a1417C97fb455f404c4B425A69a0004d",
|
||||
"tx": "0xc0fbcdeac8ee69ea6a6be21a7c2865efcc37d5c70d82fc14898aae3651ca3eb7"
|
||||
},
|
||||
{
|
||||
"amount": "565",
|
||||
"user": "0xF488F160Df1975F9D032568f0f60c485f46E744f",
|
||||
@@ -15693,6 +15898,30 @@
|
||||
{
|
||||
"address": "0xB12Cdb63E38f9a6ff2C0F68aBC3CA9beFCb7148c",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "10",
|
||||
"user": "0xB12Cdb63E38f9a6ff2C0F68aBC3CA9beFCb7148c",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x20746dd7898e20747d4d7331c65d3ba443ce71c99e7ab2cb8332d5e708050dd0"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xB12Cdb63E38f9a6ff2C0F68aBC3CA9beFCb7148c",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x71e4e558ceb26dc02a6d69dce9852a0379c07054aa9db12f7edef34ee20743ea"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xB12Cdb63E38f9a6ff2C0F68aBC3CA9beFCb7148c",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x6153b89191f8988680a2fa7cd44965e6fdfe15701b2d1973307d6e2dd3ef93d2"
|
||||
},
|
||||
{
|
||||
"amount": "15",
|
||||
"user": "0xB12Cdb63E38f9a6ff2C0F68aBC3CA9beFCb7148c",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x1cb55bafcb2c889ae684c764145e4378e029dbb6d395e9cf8670fd82b0aa6a71"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xB12Cdb63E38f9a6ff2C0F68aBC3CA9beFCb7148c",
|
||||
@@ -16073,6 +16302,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "65",
|
||||
"user": "0xB12Cdb63E38f9a6ff2C0F68aBC3CA9beFCb7148c",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x679502e8d24eb2c2476f3e1976f8b686639ce46358a28119894e75c8e418923b"
|
||||
},
|
||||
{
|
||||
"amount": "445",
|
||||
"user": "0xB12Cdb63E38f9a6ff2C0F68aBC3CA9beFCb7148c",
|
||||
@@ -16092,10 +16327,333 @@
|
||||
"tx": "0x6940787f6ceaac0846e69f1bc93ad9efee8c39774b91ea29f84328ae64fc9969"
|
||||
}
|
||||
],
|
||||
"total_tokens": "1165",
|
||||
"withdrawn_tokens": "1165",
|
||||
"total_tokens": "1230",
|
||||
"withdrawn_tokens": "1230",
|
||||
"remaining_tokens": "0"
|
||||
},
|
||||
{
|
||||
"address": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "50",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x04f0af4557ef852e5132a139f9f9c45315c86cfab2b9147cb279f6a4fb120146"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xd2fc5b073a66634f75d80de216d4ee83de510a767e44d2a74bce25f66caf3890"
|
||||
},
|
||||
{
|
||||
"amount": "50",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x24addf02f8ce6aa54a601359d7400e0c4f99aae8fbca961ccc7f5c155984da37"
|
||||
},
|
||||
{
|
||||
"amount": "46",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x69b7fedbd011b574f6541eae53a4d39212f72a5c9707e244f2b56b14bda40663"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xb3fc83a99518e3d17281c6a2f26eb9ce68e21b3a97796e6cfb6601355a58e6d1"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x0c10322e4ac684a17359fe5bff7acb6ad6ac90b0b35fd31068d6254e298f6d06"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x13e769680c99022af2fe734eda617c638b8bfb6035ca027eba47f20cb4a07a49"
|
||||
},
|
||||
{
|
||||
"amount": "15",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x8b933a7aaa3b1ea891c4392ec290df935e0ebcd433713df4c07d8583a123b125"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x0e722eedc0d2c4cca2b38bbe54b914f0833ed77db8e068b4e0580fcc63d05fcf"
|
||||
},
|
||||
{
|
||||
"amount": "15",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xcfe1c973d4d73770bff8defed041187f405bfdd24835bd08294be8065deed3d5"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x3a437dda1289198f485de1dce66eda37aaec0d4d2f157a2e8e155962616f9056"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xd5cc8fd70dcd8ef2e902032c17b0284387a4032f1ecda509d8da1a87faa430de"
|
||||
},
|
||||
{
|
||||
"amount": "26",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xa61b2f4a7962db3e1b3bd008949a45fca273d919236582fac2837fe9338bf09d"
|
||||
},
|
||||
{
|
||||
"amount": "15",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x3d5e00f458e04b8869a5a800948b27a681babcc008fad092b0cea92bd77ce4d4"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x4aa20102d2e76f332a83555ee29892be1972fd41a6a647c5dafd0aed9ac08da2"
|
||||
},
|
||||
{
|
||||
"amount": "15",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x5c94d762403f8c1af0513f22578e4839d191f72230a4bc5e88292294056dc7b1"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x470364c533cc37371644ceec17d2ecb8efc123ae2a48a67538f1e7a551d87507"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x005a58c1e9c52919d16b4033924a1d20c8ece3ea8b4ef31c18dc22063b6f0e37"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xe84e0f602076c3cbbe1fce4a807cd77b7edc0a5402a60a632fa7210fcf45e519"
|
||||
},
|
||||
{
|
||||
"amount": "65",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xdea46047ed750a8a035be101bb66dc68e57f08b4c7d674a3e7c5fa72aa186b2b"
|
||||
},
|
||||
{
|
||||
"amount": "120",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x08bbc1418fc1a08ff06ec298c205eb40496e98f9c63636dd750d00c36d4c4852"
|
||||
},
|
||||
{
|
||||
"amount": "10",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x502c6357954fe005d8d26aeb91cc519e2d23b233aeb90a9fe180bfd8087a630c"
|
||||
},
|
||||
{
|
||||
"amount": "15",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x699de41fd489c72412a07eac668a95e676433a8a483e4c94340d9f5ea4e5883a"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xfd7e7aad721f06dc963d1e91401e33051c42740740419c2d89ec4b005d4426af"
|
||||
},
|
||||
{
|
||||
"amount": "26",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x8c0f6f0f3362beecd8ffac3df842e61dbb8634c088871c819473ce7c1f61638f"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x0b1e9eac4f1ad30ec826525769115b4200f0d67a11039eacc7dec254cae4e6ae"
|
||||
},
|
||||
{
|
||||
"amount": "40",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x6fec302369b6cc50b5fdd03f14a8ca5f8dc86d30b6f6695916c442d822c64464"
|
||||
},
|
||||
{
|
||||
"amount": "100",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x51f3812a13b40b8da14240c9e1467b5193302cb45fd99524330c46b561526918"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x1196cc3f61afe969673421c6a00edaf82b48dda42986b98a4edfdb737a7fc18d"
|
||||
},
|
||||
{
|
||||
"amount": "25",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xaa794c4025996e859a907009a44d39eb46f1485042ace3e6f0353f2ab397471a"
|
||||
},
|
||||
{
|
||||
"amount": "10",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x2cc9394dd362b6834b700c6b5c43dd61e6c07aa6f7e0d5c3e3f3a0b5ca54b01d"
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "481",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x536705dd5d8f7944cd5e3414dbd374bef0d96ba8209ba93c9c19da6a0d4d4a9a"
|
||||
}
|
||||
],
|
||||
"total_tokens": "983",
|
||||
"withdrawn_tokens": "481",
|
||||
"remaining_tokens": "502"
|
||||
},
|
||||
{
|
||||
"address": "0xc7eC0d77a1417C97fb455f404c4B425A69a0004d",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "60",
|
||||
"user": "0xc7eC0d77a1417C97fb455f404c4B425A69a0004d",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x1610a45e4e6cf254dd2344a4f03b81ee4be04e3b4c46b9f1fa5460a500b86c5f"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xc7eC0d77a1417C97fb455f404c4B425A69a0004d",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x973127e641cf01314a44e7560be0b54b1b139bad731e1379358e169f31b606e0"
|
||||
},
|
||||
{
|
||||
"amount": "100",
|
||||
"user": "0xc7eC0d77a1417C97fb455f404c4B425A69a0004d",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x03ebb823c4a3aa2794b9f9dae9b9fb75e19f518cb8fbd1c245fd07144c2a2760"
|
||||
},
|
||||
{
|
||||
"amount": "46",
|
||||
"user": "0xc7eC0d77a1417C97fb455f404c4B425A69a0004d",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xd5bf21ff59df324ce1fadc9acd3edf649904a0be184e91994b6f59255a98170f"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xc7eC0d77a1417C97fb455f404c4B425A69a0004d",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x38ac7e75b875453765de7759023d75161f210354cdb09932a60d8e16277e1d92"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xc7eC0d77a1417C97fb455f404c4B425A69a0004d",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x676bbb8223541f0527e33572dac4641a527d4719e7958bca495950c4ddc25dab"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xc7eC0d77a1417C97fb455f404c4B425A69a0004d",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x8beb66b4f217717342943d8e4ec6f896a5ac4f092f948e3b2dabeaea6269814e"
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "296",
|
||||
"user": "0xc7eC0d77a1417C97fb455f404c4B425A69a0004d",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xc0fbcdeac8ee69ea6a6be21a7c2865efcc37d5c70d82fc14898aae3651ca3eb7"
|
||||
}
|
||||
],
|
||||
"total_tokens": "296",
|
||||
"withdrawn_tokens": "296",
|
||||
"remaining_tokens": "0"
|
||||
},
|
||||
{
|
||||
"address": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xbd37ca2a89da18ae711e2fcd7b6b41ed83b2bbdc11e0d704776f9673d7449ecf"
|
||||
},
|
||||
{
|
||||
"amount": "60",
|
||||
"user": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x6c01fda718564da41840d86464a32afd9640b7d599d7fed2a1ff61d7c9d47193"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xe41c66b0f4a6dd290909324fd048ff348f33c59a60974bd231920e00d4e4288d"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xb755c0264b6b31a3aa767b0683da02d9881e7c762587621c5031ce6b4ff8f54f"
|
||||
},
|
||||
{
|
||||
"amount": "26",
|
||||
"user": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xdcd2e1e9f393809c80283575d200a6d87096bb108a0c357a08c5e8e4f1c98de6"
|
||||
},
|
||||
{
|
||||
"amount": "40",
|
||||
"user": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x6cd1e72f959033edd31958e6de7a44f6a1413a3bf98cd44db00c574603a06ea2"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xc70308ea7193419a02d35ee0a39fe47f613bec25e9f681013b64b508f97aa679"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xfd21b34d23162d743a1db14bb2072d88fd50a320c052646667de1bda6124c06c"
|
||||
},
|
||||
{
|
||||
"amount": "10",
|
||||
"user": "0xBF623fEe9460C1a97e0dA2eDe0e5246B45813b6a",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x49b6f2f5f8239d2029dda62147d53666e2bae003272cd49de4ee9ffa872d9696"
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"total_tokens": "266",
|
||||
"withdrawn_tokens": "0",
|
||||
"remaining_tokens": "266"
|
||||
},
|
||||
{
|
||||
"address": "0x4cf8879dC68ebe9F003E6231CB8B704FAbEA8d9c",
|
||||
"deposits": [
|
||||
@@ -18359,94 +18917,6 @@
|
||||
"withdrawn_tokens": "50",
|
||||
"remaining_tokens": "0"
|
||||
},
|
||||
{
|
||||
"address": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "65",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xdea46047ed750a8a035be101bb66dc68e57f08b4c7d674a3e7c5fa72aa186b2b"
|
||||
},
|
||||
{
|
||||
"amount": "120",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x08bbc1418fc1a08ff06ec298c205eb40496e98f9c63636dd750d00c36d4c4852"
|
||||
},
|
||||
{
|
||||
"amount": "10",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x502c6357954fe005d8d26aeb91cc519e2d23b233aeb90a9fe180bfd8087a630c"
|
||||
},
|
||||
{
|
||||
"amount": "15",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x699de41fd489c72412a07eac668a95e676433a8a483e4c94340d9f5ea4e5883a"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xfd7e7aad721f06dc963d1e91401e33051c42740740419c2d89ec4b005d4426af"
|
||||
},
|
||||
{
|
||||
"amount": "26",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x8c0f6f0f3362beecd8ffac3df842e61dbb8634c088871c819473ce7c1f61638f"
|
||||
},
|
||||
{
|
||||
"amount": "20",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x0b1e9eac4f1ad30ec826525769115b4200f0d67a11039eacc7dec254cae4e6ae"
|
||||
},
|
||||
{
|
||||
"amount": "40",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x6fec302369b6cc50b5fdd03f14a8ca5f8dc86d30b6f6695916c442d822c64464"
|
||||
},
|
||||
{
|
||||
"amount": "100",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x51f3812a13b40b8da14240c9e1467b5193302cb45fd99524330c46b561526918"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x1196cc3f61afe969673421c6a00edaf82b48dda42986b98a4edfdb737a7fc18d"
|
||||
},
|
||||
{
|
||||
"amount": "25",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xaa794c4025996e859a907009a44d39eb46f1485042ace3e6f0353f2ab397471a"
|
||||
},
|
||||
{
|
||||
"amount": "10",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x2cc9394dd362b6834b700c6b5c43dd61e6c07aa6f7e0d5c3e3f3a0b5ca54b01d"
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "481",
|
||||
"user": "0xf83aaA5786516F7016DF9ead2CD9F14616dA0A13",
|
||||
"tranche_id": 11,
|
||||
"tx": "0x536705dd5d8f7944cd5e3414dbd374bef0d96ba8209ba93c9c19da6a0d4d4a9a"
|
||||
}
|
||||
],
|
||||
"total_tokens": "481",
|
||||
"withdrawn_tokens": "481",
|
||||
"remaining_tokens": "0"
|
||||
},
|
||||
{
|
||||
"address": "0x57a018724a4518ccA397f2897BD8CB43731899a4",
|
||||
"deposits": [
|
||||
@@ -28928,8 +29398,8 @@
|
||||
"tranche_start": "2022-03-05T00:00:00.000Z",
|
||||
"tranche_end": "2023-06-05T00:00:00.000Z",
|
||||
"total_added": "3732368.4671",
|
||||
"total_removed": "409007.9945382030589",
|
||||
"locked_amount": "1572132.889279723713611887036",
|
||||
"total_removed": "409964.5466205507569",
|
||||
"locked_amount": "1563961.5273344066896779797",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "1998.95815",
|
||||
@@ -29108,6 +29578,11 @@
|
||||
"user": "0xE6CacAE56Cca8dFdB7910b5A13578719D4E57DA0",
|
||||
"tx": "0x7310ed23baf953c36f8c7f71edfde3edb3745ce1f00b73999c56204e3784e7da"
|
||||
},
|
||||
{
|
||||
"amount": "956.552082347698",
|
||||
"user": "0xE6CacAE56Cca8dFdB7910b5A13578719D4E57DA0",
|
||||
"tx": "0xff76825dfd0803f4b17a7498793fed74ad31094cc4150867d2f25493852a369c"
|
||||
},
|
||||
{
|
||||
"amount": "2893.9492727166165",
|
||||
"user": "0xE6CacAE56Cca8dFdB7910b5A13578719D4E57DA0",
|
||||
@@ -29369,6 +29844,12 @@
|
||||
"tranche_id": 1,
|
||||
"tx": "0x7310ed23baf953c36f8c7f71edfde3edb3745ce1f00b73999c56204e3784e7da"
|
||||
},
|
||||
{
|
||||
"amount": "956.552082347698",
|
||||
"user": "0xE6CacAE56Cca8dFdB7910b5A13578719D4E57DA0",
|
||||
"tranche_id": 1,
|
||||
"tx": "0xff76825dfd0803f4b17a7498793fed74ad31094cc4150867d2f25493852a369c"
|
||||
},
|
||||
{
|
||||
"amount": "2893.9492727166165",
|
||||
"user": "0xE6CacAE56Cca8dFdB7910b5A13578719D4E57DA0",
|
||||
@@ -29521,8 +30002,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "187637.95",
|
||||
"withdrawn_tokens": "107964.3534144730895",
|
||||
"remaining_tokens": "79673.5965855269105"
|
||||
"withdrawn_tokens": "108920.9054968207875",
|
||||
"remaining_tokens": "78717.0445031792125"
|
||||
},
|
||||
{
|
||||
"address": "0x1A71e3ED1996CAbB91bB043f880CE963D601707e",
|
||||
@@ -30022,8 +30503,8 @@
|
||||
"tranche_start": "2022-06-05T00:00:00.000Z",
|
||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||
"total_added": "15870102.715470999700000001",
|
||||
"total_removed": "466274.5051748354452444",
|
||||
"locked_amount": "10874369.8704474692093109479818310178872668",
|
||||
"total_removed": "466327.0633126899537444",
|
||||
"locked_amount": "10845394.7456409575582014225413169199432279",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "16249.93",
|
||||
@@ -30562,6 +31043,11 @@
|
||||
"user": "0xF4c75FdbAe821C6B5DBB9f001bB23cBA58D1bA37",
|
||||
"tx": "0xdddf8c03e0672650ca634d16fede3ac80ce6962708da5ac75ac67bd105ff34d8"
|
||||
},
|
||||
{
|
||||
"amount": "52.5581378545085",
|
||||
"user": "0xE6CacAE56Cca8dFdB7910b5A13578719D4E57DA0",
|
||||
"tx": "0x56c7bc1180a45c44004fe214cbecdc94d390ea780465e5ec067b268b4af7979d"
|
||||
},
|
||||
{
|
||||
"amount": "858.1623848394685",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
@@ -33481,6 +33967,12 @@
|
||||
"tranche_id": 2,
|
||||
"tx": "0x2f1edcbd2367384aa1fcefb07035f54b60a5ed9716937f6f3fc3c70603c9ea27"
|
||||
},
|
||||
{
|
||||
"amount": "52.5581378545085",
|
||||
"user": "0xE6CacAE56Cca8dFdB7910b5A13578719D4E57DA0",
|
||||
"tranche_id": 2,
|
||||
"tx": "0x56c7bc1180a45c44004fe214cbecdc94d390ea780465e5ec067b268b4af7979d"
|
||||
},
|
||||
{
|
||||
"amount": "158.9965914292145",
|
||||
"user": "0xE6CacAE56Cca8dFdB7910b5A13578719D4E57DA0",
|
||||
@@ -33615,8 +34107,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "12362.05",
|
||||
"withdrawn_tokens": "3856.419815042606",
|
||||
"remaining_tokens": "8505.630184957394"
|
||||
"withdrawn_tokens": "3908.9779528971145",
|
||||
"remaining_tokens": "8453.0720471028855"
|
||||
},
|
||||
{
|
||||
"address": "0xb091D456d0dFCB94dcba6f355379056C5bb995fC",
|
||||
@@ -34241,7 +34733,7 @@
|
||||
"tranche_end": "2023-05-05T00:00:00.000Z",
|
||||
"total_added": "14597706.0446472999",
|
||||
"total_removed": "3354105.892527157234161157",
|
||||
"locked_amount": "4317703.60459960867008212228336535",
|
||||
"locked_amount": "4290953.95438615584003845285762592",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "129284.449",
|
||||
@@ -40215,7 +40707,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "5778205.3912159303",
|
||||
"total_removed": "2339432.642165343526844507",
|
||||
"locked_amount": "1389047.40389111510815702616078974",
|
||||
"locked_amount": "1378478.45531124214410403158534039",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "552496.6455",
|
||||
@@ -41934,7 +42426,7 @@
|
||||
"tranche_end": "2023-06-05T00:00:00.000Z",
|
||||
"total_added": "472355.6199999996",
|
||||
"total_removed": "16069.665777422296",
|
||||
"locked_amount": "249113.44300109382834670835920848",
|
||||
"locked_amount": "247818.64399136206106747754642312",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "3000",
|
||||
@@ -90415,7 +90907,7 @@
|
||||
"tranche_start": "2021-09-03T00:00:00.000Z",
|
||||
"tranche_end": "2021-09-03T00:00:00.000Z",
|
||||
"total_added": "539489.4799999985",
|
||||
"total_removed": "531366.1399999988",
|
||||
"total_removed": "531432.8099999988",
|
||||
"locked_amount": "0",
|
||||
"deposits": [
|
||||
{
|
||||
@@ -95640,6 +96132,11 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "66.67",
|
||||
"user": "0x63ccc85135edF1EB2F559c4106aBD3B2e96107C3",
|
||||
"tx": "0xc613319b71aa10ffadd89ae92e126339b01bf5a76f2e72e920e0ec6012551610"
|
||||
},
|
||||
{
|
||||
"amount": "66.67",
|
||||
"user": "0x82CEDEAd8B2D52565c157c9f209C4D9659eA8990",
|
||||
@@ -102209,10 +102706,17 @@
|
||||
"tx": "0xee02e72ef8e0755982704385da512cc12c8ff0ea7b58056fa3d5a5932394e9ca"
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "66.67",
|
||||
"user": "0x63ccc85135edF1EB2F559c4106aBD3B2e96107C3",
|
||||
"tranche_id": 7,
|
||||
"tx": "0xc613319b71aa10ffadd89ae92e126339b01bf5a76f2e72e920e0ec6012551610"
|
||||
}
|
||||
],
|
||||
"total_tokens": "66.67",
|
||||
"withdrawn_tokens": "0",
|
||||
"remaining_tokens": "66.67"
|
||||
"withdrawn_tokens": "66.67",
|
||||
"remaining_tokens": "0"
|
||||
},
|
||||
{
|
||||
"address": "0x055c22a4e4b5751bb0B2617F8872DC00278C90F8",
|
||||
|
||||
@@ -116,7 +116,7 @@ context(
|
||||
cy.get(newProposalSubmitButton).click();
|
||||
cy.get(feedbackError).should(
|
||||
'have.text',
|
||||
'proposal_submission.terms.closing_timestamp: cannot be after enactment time'
|
||||
'Invalid params: proposal_submission.terms.closing_timestamp (cannot be after enactment time)'
|
||||
);
|
||||
cy.get(dialogCloseButton).click();
|
||||
cy.get(minVoteDeadline).click();
|
||||
@@ -157,7 +157,7 @@ context(
|
||||
cy.contains('Transaction failed', proposalTimeout).should('be.visible');
|
||||
cy.get(feedbackError).should(
|
||||
'have.text',
|
||||
'*: unknown field "signers" in vega.DataSourceDefinition'
|
||||
'Invalid params: the transaction is malformed'
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ context(
|
||||
before('visit staking tab and connect vega wallet', function () {
|
||||
cy.visit('/');
|
||||
cy.verify_page_header('The $VEGA token');
|
||||
cy.vega_wallet_connect();
|
||||
cy.vega_wallet_set_specified_approval_amount('1000');
|
||||
});
|
||||
|
||||
|
||||
@@ -43,10 +43,6 @@ context(
|
||||
it('Able to open withdrawal form with vega wallet connected', function () {
|
||||
// needs to reload page for withdrawal form to be displayed in ci - not reproducible outside of ci
|
||||
cy.getByTestId(withdraw).should('be.visible').click();
|
||||
cy.visit('/');
|
||||
cy.navigate_to('withdrawals');
|
||||
cy.ethereum_wallet_connect();
|
||||
cy.getByTestId(withdraw).should('be.visible').click();
|
||||
cy.getByTestId(selectAsset)
|
||||
.find('option')
|
||||
.should('have.length.at.least', 2);
|
||||
|
||||
@@ -93,6 +93,7 @@ Cypress.Commands.add('faucet_asset', function (assetEthAddress) {
|
||||
Cypress.Commands.add('vega_wallet_teardown', function () {
|
||||
cy.get(vegaWalletContainer).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance)
|
||||
.first()
|
||||
.invoke('text')
|
||||
.then((balance) => {
|
||||
if (balance != '0.00') {
|
||||
@@ -100,6 +101,10 @@ Cypress.Commands.add('vega_wallet_teardown', function () {
|
||||
cy.vega_wallet_teardown_staking(this.stakingBridgeContract);
|
||||
}
|
||||
});
|
||||
cy.get('[data-test-id="associated-amount"]', { timeout: 30000 }).should(
|
||||
'contain.text',
|
||||
'0.00'
|
||||
);
|
||||
});
|
||||
|
||||
cy.get(vegaWalletContainer).within(() => {
|
||||
|
||||
@@ -3,6 +3,6 @@ NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
||||
NX_VEGA_ENV=STAGNET3
|
||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET3":"https://stagnet3.token.vega.xyz","TESTNET":"https://token.fairground.wtf","MAINNET":"https://token.vega.xyz"}'
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
|
||||
NX_VEGA_EXPLORER_URL=https://staging3.explorer.vega.xyz
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
|
||||
@@ -4,11 +4,11 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
|
||||
NX_VEGA_ENV=STAGNET3
|
||||
NX_VEGA_EXPLORER_URL=https://staging3.explorer.vega.xyz
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"STAGNET3\":\"https://stagnet3.console.vega.xyz\"}
|
||||
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
CYPRESS_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
||||
CYPRESS_EXPLORER_URL=https://staging3.explorer.vega.xyz
|
||||
CYPRESS_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import {
|
||||
generateProposals,
|
||||
marketUpdateProposal,
|
||||
} from '../support/mocks/generate-proposals';
|
||||
|
||||
const marketSummaryBlock = 'header-summary';
|
||||
const marketExpiry = 'market-expiry';
|
||||
@@ -12,6 +17,42 @@ const priceChangeValue = 'price-change';
|
||||
const itemHeader = 'item-header';
|
||||
const itemValue = 'item-value';
|
||||
|
||||
describe('Market proposal notification', { tags: '@smoke' }, () => {
|
||||
before(() => {
|
||||
cy.mockTradingPage(
|
||||
Schema.MarketState.STATE_ACTIVE,
|
||||
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
|
||||
Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
|
||||
);
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(
|
||||
req,
|
||||
'ProposalsList',
|
||||
generateProposals([marketUpdateProposal])
|
||||
);
|
||||
});
|
||||
cy.mockGQLSubscription();
|
||||
cy.visit('/#/markets/market-0');
|
||||
cy.wait('@MarketData');
|
||||
cy.getByTestId(marketSummaryBlock).should('be.visible');
|
||||
});
|
||||
it('should display market proposal notification if proposal found', () => {
|
||||
cy.getByTestId(marketSummaryBlock).within(() => {
|
||||
cy.getByTestId('market-proposal-notification').should(
|
||||
'contain.text',
|
||||
'Changes have been proposed for this market'
|
||||
);
|
||||
cy.getByTestId('market-proposal-notification').within(() => {
|
||||
cy.getByTestId('external-link').should(
|
||||
'have.attr',
|
||||
'href',
|
||||
'https://stagnet3.token.vega.xyz/governance/123'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Market trading page', () => {
|
||||
before(() => {
|
||||
cy.mockTradingPage(
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||
import { generateLedgerEntries } from '../support/mocks/generate-ledger-entries';
|
||||
import { connectVegaWallet } from '../support/vega-wallet';
|
||||
import { generateAssets } from '../support/mocks/generate-assets';
|
||||
import { generateMarkets } from '../support/mocks/generate-markets';
|
||||
|
||||
describe('Portfolio page', { tags: '@regression' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'LedgerEntries', generateLedgerEntries());
|
||||
aliasQuery(req, 'Assets', generateAssets());
|
||||
aliasQuery(req, 'Markets', generateMarkets());
|
||||
});
|
||||
cy.mockGQLSubscription();
|
||||
});
|
||||
describe('Ledger entries', () => {
|
||||
it('List should be properly rendered', () => {
|
||||
cy.visit('/#/portfolio');
|
||||
connectVegaWallet();
|
||||
cy.get('[data-testid="Ledger entries"]').click();
|
||||
const headers = [
|
||||
'Sender',
|
||||
'Receiver',
|
||||
'Transfer Type',
|
||||
'Quantity',
|
||||
'Asset',
|
||||
'Vega Time',
|
||||
];
|
||||
cy.get('.ag-header-row.ag-header-row-column').within(($headers) => {
|
||||
cy.wrap($headers)
|
||||
.get('.ag-header-cell-text')
|
||||
.each(($header, i) => {
|
||||
cy.wrap($header).should('have.text', headers[i]);
|
||||
});
|
||||
});
|
||||
cy.get('.ag-center-cols-container .ag-row').should(
|
||||
'have.length',
|
||||
generateLedgerEntries().ledgerEntries.edges.length
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,258 @@
|
||||
import type { LedgerEntriesQuery } from '@vegaprotocol/ledger';
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
|
||||
const ledgerEntries: LedgerEntriesQuery = {
|
||||
ledgerEntries: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
vegaTime: '1669224476734364000',
|
||||
quantity: '0',
|
||||
assetId: 'asset-id',
|
||||
transferType: Types.TransferType.TRANSFER_TYPE_MARGIN_HIGH,
|
||||
receiverAccountType: Types.AccountType.ACCOUNT_TYPE_EXTERNAL,
|
||||
receiverMarketId: 'market-1',
|
||||
receiverPartyId: 'network',
|
||||
senderAccountType: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
senderMarketId: 'market-0',
|
||||
senderPartyId:
|
||||
'2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
|
||||
__typename: 'AggregatedLedgerEntry',
|
||||
},
|
||||
__typename: 'AggregatedLedgerEntriesEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
vegaTime: '1669221452175594000',
|
||||
quantity: '0',
|
||||
assetId: 'asset-id-2',
|
||||
transferType: Types.TransferType.TRANSFER_TYPE_MARGIN_HIGH,
|
||||
receiverAccountType: Types.AccountType.ACCOUNT_TYPE_EXTERNAL,
|
||||
receiverMarketId: 'market-0',
|
||||
receiverPartyId: 'network',
|
||||
senderAccountType: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
senderMarketId: 'market-2',
|
||||
senderPartyId:
|
||||
'2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
|
||||
__typename: 'AggregatedLedgerEntry',
|
||||
},
|
||||
__typename: 'AggregatedLedgerEntriesEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
vegaTime: '1669209347054198000',
|
||||
quantity: '0',
|
||||
assetId: 'asset-id',
|
||||
transferType: Types.TransferType.TRANSFER_TYPE_MARGIN_HIGH,
|
||||
receiverAccountType: Types.AccountType.ACCOUNT_TYPE_EXTERNAL,
|
||||
receiverMarketId: 'market-3',
|
||||
receiverPartyId: 'network',
|
||||
senderAccountType: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
senderMarketId: 'market-2',
|
||||
senderPartyId: 'sender party id',
|
||||
__typename: 'AggregatedLedgerEntry',
|
||||
},
|
||||
__typename: 'AggregatedLedgerEntriesEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
vegaTime: '1669209345512806000',
|
||||
quantity: '0',
|
||||
assetId: 'asset-id',
|
||||
transferType: Types.TransferType.TRANSFER_TYPE_MARGIN_HIGH,
|
||||
__typename: 'AggregatedLedgerEntry',
|
||||
},
|
||||
__typename: 'AggregatedLedgerEntriesEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
vegaTime: '1669209316163397000',
|
||||
quantity: '0',
|
||||
assetId: 'asset-id-2',
|
||||
transferType: Types.TransferType.TRANSFER_TYPE_MARGIN_HIGH,
|
||||
__typename: 'AggregatedLedgerEntry',
|
||||
},
|
||||
__typename: 'AggregatedLedgerEntriesEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
vegaTime: '1669209299051286000',
|
||||
quantity: '1326783',
|
||||
assetId: 'asset-id-2',
|
||||
transferType: Types.TransferType.TRANSFER_TYPE_MTM_WIN,
|
||||
__typename: 'AggregatedLedgerEntry',
|
||||
},
|
||||
__typename: 'AggregatedLedgerEntriesEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
vegaTime: '1669209151328614000',
|
||||
quantity: '0',
|
||||
assetId:
|
||||
'5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
||||
transferType: Types.TransferType.TRANSFER_TYPE_MARGIN_HIGH,
|
||||
__typename: 'AggregatedLedgerEntry',
|
||||
},
|
||||
__typename: 'AggregatedLedgerEntriesEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
vegaTime: '1669209117655380000',
|
||||
quantity: '0',
|
||||
assetId:
|
||||
'5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
||||
transferType: Types.TransferType.TRANSFER_TYPE_MARGIN_HIGH,
|
||||
__typename: 'AggregatedLedgerEntry',
|
||||
},
|
||||
__typename: 'AggregatedLedgerEntriesEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
vegaTime: '1669209082788024000',
|
||||
quantity: '1326783',
|
||||
assetId:
|
||||
'5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
||||
transferType: Types.TransferType.TRANSFER_TYPE_MTM_WIN,
|
||||
__typename: 'AggregatedLedgerEntry',
|
||||
},
|
||||
__typename: 'AggregatedLedgerEntriesEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
vegaTime: '1669209076546363000',
|
||||
quantity: '0',
|
||||
assetId:
|
||||
'cee709223217281d7893b650850ae8ee8a18b7539b5658f9b4cc24de95dd18ad',
|
||||
transferType: Types.TransferType.TRANSFER_TYPE_MARGIN_HIGH,
|
||||
__typename: 'AggregatedLedgerEntry',
|
||||
},
|
||||
__typename: 'AggregatedLedgerEntriesEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
vegaTime: '2022-11-24T13:36:42.13989Z',
|
||||
quantity: '9078407730948615',
|
||||
assetId:
|
||||
'cee709223217281d7893b650850ae8ee8a18b7539b5658f9b4cc24de95dd18ad',
|
||||
transferType: Types.TransferType.TRANSFER_TYPE_MARGIN_LOW,
|
||||
receiverAccountType: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
receiverMarketId: null,
|
||||
receiverPartyId:
|
||||
'2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
|
||||
senderAccountType: Types.AccountType.ACCOUNT_TYPE_MARGIN,
|
||||
senderMarketId:
|
||||
'0942d767cb2cb5a795e14216e8e53c2b6f75e46dc1732c5aeda8a5aba4ad193d',
|
||||
senderPartyId:
|
||||
'2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
|
||||
__typename: 'AggregatedLedgerEntry',
|
||||
},
|
||||
__typename: 'AggregatedLedgerEntriesEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
vegaTime: '2022-11-24T13:35:49.257039Z',
|
||||
quantity: '263142253070974',
|
||||
assetId:
|
||||
'cee709223217281d7893b650850ae8ee8a18b7539b5658f9b4cc24de95dd18ad',
|
||||
transferType: Types.TransferType.TRANSFER_TYPE_MARGIN_LOW,
|
||||
receiverAccountType: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
receiverMarketId: null,
|
||||
receiverPartyId:
|
||||
'2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
|
||||
senderAccountType: Types.AccountType.ACCOUNT_TYPE_MARGIN,
|
||||
senderMarketId:
|
||||
'0942d767cb2cb5a795e14216e8e53c2b6f75e46dc1732c5aeda8a5aba4ad193d',
|
||||
senderPartyId:
|
||||
'2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
|
||||
__typename: 'AggregatedLedgerEntry',
|
||||
},
|
||||
__typename: 'AggregatedLedgerEntriesEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
vegaTime: '2022-11-24T12:41:22.054428Z',
|
||||
quantity: '1000000000',
|
||||
assetId:
|
||||
'4e4e80abff30cab933b8c4ac6befc618372eb76b2cbddc337eff0b4a3a4d25b8',
|
||||
transferType: Types.TransferType.TRANSFER_TYPE_DEPOSIT,
|
||||
receiverAccountType: Types.AccountType.ACCOUNT_TYPE_EXTERNAL,
|
||||
receiverMarketId: null,
|
||||
receiverPartyId: 'network',
|
||||
senderAccountType: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
senderMarketId: null,
|
||||
senderPartyId:
|
||||
'2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
|
||||
__typename: 'AggregatedLedgerEntry',
|
||||
},
|
||||
__typename: 'AggregatedLedgerEntriesEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
vegaTime: '2022-11-24T12:39:11.516154Z',
|
||||
quantity: '1000000000000',
|
||||
assetId:
|
||||
'c9fe6fc24fce121b2cc72680543a886055abb560043fda394ba5376203b7527d',
|
||||
transferType: Types.TransferType.TRANSFER_TYPE_DEPOSIT,
|
||||
receiverAccountType: Types.AccountType.ACCOUNT_TYPE_EXTERNAL,
|
||||
receiverMarketId: null,
|
||||
receiverPartyId: 'network',
|
||||
senderAccountType: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
senderMarketId: null,
|
||||
senderPartyId:
|
||||
'2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
|
||||
__typename: 'AggregatedLedgerEntry',
|
||||
},
|
||||
__typename: 'AggregatedLedgerEntriesEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
vegaTime: '2022-11-24T12:37:26.832226Z',
|
||||
quantity: '10000000000000000000000',
|
||||
assetId:
|
||||
'c9fe6fc24fce121b2cc72680543a886055abb560043fda394ba5376203b7527d',
|
||||
transferType: Types.TransferType.TRANSFER_TYPE_DEPOSIT,
|
||||
receiverAccountType: Types.AccountType.ACCOUNT_TYPE_EXTERNAL,
|
||||
receiverMarketId: null,
|
||||
receiverPartyId: 'network',
|
||||
senderAccountType: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
senderMarketId: null,
|
||||
senderPartyId:
|
||||
'2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
|
||||
__typename: 'AggregatedLedgerEntry',
|
||||
},
|
||||
__typename: 'AggregatedLedgerEntriesEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
vegaTime: '2022-11-24T12:24:52.844901Z',
|
||||
quantity: '49390000000000000000000',
|
||||
assetId:
|
||||
'c9fe6fc24fce121b2cc72680543a886055abb560043fda394ba5376203b7527d',
|
||||
transferType: Types.TransferType.TRANSFER_TYPE_DEPOSIT,
|
||||
receiverAccountType: Types.AccountType.ACCOUNT_TYPE_EXTERNAL,
|
||||
receiverMarketId: null,
|
||||
receiverPartyId: 'network',
|
||||
senderAccountType: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
senderMarketId: null,
|
||||
senderPartyId:
|
||||
'2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
|
||||
__typename: 'AggregatedLedgerEntry',
|
||||
},
|
||||
__typename: 'AggregatedLedgerEntriesEdge',
|
||||
},
|
||||
],
|
||||
pageInfo: {
|
||||
startCursor:
|
||||
'eyJ2ZWdhX3RpbWUiOiIyMDIyLTExLTIzVDE3OjI3OjU2LjczNDM2NFoifQ==',
|
||||
endCursor: 'eyJ2ZWdhX3RpbWUiOiIyMDIyLTExLTIzVDEzOjExOjE2LjU0NjM2M1oifQ==',
|
||||
hasNextPage: true,
|
||||
hasPreviousPage: false,
|
||||
__typename: 'PageInfo',
|
||||
},
|
||||
__typename: 'AggregatedLedgerEntriesConnection',
|
||||
},
|
||||
};
|
||||
|
||||
export const generateLedgerEntries = () => {
|
||||
return { ...ledgerEntries };
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -3,7 +3,7 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
|
||||
NX_VEGA_ENV=STAGNET3
|
||||
NX_VEGA_EXPLORER_URL=https://staging3.explorer.vega.xyz
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"STAGNET3\":\"https://stagnet3.console.vega.xyz\"}
|
||||
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
|
||||
@@ -3,7 +3,7 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
|
||||
NX_VEGA_ENV=STAGNET3
|
||||
NX_VEGA_EXPLORER_URL=https://staging3.explorer.vega.xyz
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"STAGNET3\":\"https://stagnet3.console.vega.xyz\"}
|
||||
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
|
||||
@@ -69,10 +69,7 @@ export const Liquidity = () => {
|
||||
} = useDataProvider({
|
||||
dataProvider: lpAggregatedDataProvider,
|
||||
update,
|
||||
variables: useMemo(
|
||||
() => ({ marketId, partyId: pubKey }),
|
||||
[marketId, pubKey]
|
||||
),
|
||||
variables: useMemo(() => ({ marketId }), [marketId]),
|
||||
});
|
||||
|
||||
// To be removed when liquidityProvision subscriptions are working
|
||||
|
||||
@@ -36,6 +36,7 @@ import { Last24hPriceChange } from '../../components/last-24h-price-change';
|
||||
import { MarketMarkPrice } from '../../components/market-mark-price';
|
||||
import { MarketTradingModeComponent } from '../../components/market-trading-mode';
|
||||
import { Last24hVolume } from '../../components/last-24h-volume';
|
||||
import { MarketProposalNotification } from '@vegaprotocol/governance';
|
||||
|
||||
const NO_MARKET = t('No market');
|
||||
|
||||
@@ -177,6 +178,7 @@ export const TradeMarketHeader = ({
|
||||
</div>
|
||||
</HeaderStat>
|
||||
) : null}
|
||||
<MarketProposalNotification marketId={market?.id} />
|
||||
</Header>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@ interface TradeMarketHeaderProps {
|
||||
|
||||
export const Header = ({ title, children }: TradeMarketHeaderProps) => {
|
||||
return (
|
||||
<header className="w-screen xl:px-4 pt-4 border-b border-default">
|
||||
<header className="w-screen xl:px-4 pt-3 border-b border-default">
|
||||
<div className="xl:flex xl:gap-4 items-start">
|
||||
<div className="mb-4 xl:mb-0 px-4 xl:px-0">{title}</div>
|
||||
<div
|
||||
@@ -43,7 +43,7 @@ export const HeaderStat = ({
|
||||
testId?: string;
|
||||
}) => {
|
||||
const itemClass =
|
||||
'min-w-min w-[120px] whitespace-nowrap pb-3 px-4 border-l border-default';
|
||||
'min-w-min w-[120px] whitespace-nowrap pb-3 px-4 border-l border-default mt-1';
|
||||
const itemHeading = 'text-neutral-500 dark:text-neutral-400';
|
||||
|
||||
return (
|
||||
|
||||
@@ -144,7 +144,7 @@ export const SelectMarketPopover = ({
|
||||
onCellClick: OnCellClickHandler;
|
||||
}) => {
|
||||
const triggerClasses =
|
||||
'sm:text-lg md:text-xl lg:text-2xl flex items-center gap-2 whitespace-nowrap hover:text-neutral-500 dark:hover:text-neutral-300';
|
||||
'sm:text-lg md:text-xl lg:text-2xl flex items-center gap-2 whitespace-nowrap hover:text-neutral-500 dark:hover:text-neutral-300 mt-1';
|
||||
const { pubKey } = useVegaWallet();
|
||||
const [open, setOpen] = useState(false);
|
||||
const { data, loading: marketsLoading } = useMarketList();
|
||||
|
||||
@@ -7,6 +7,9 @@ fragment AccountFields on AccountBalance {
|
||||
asset {
|
||||
id
|
||||
}
|
||||
party {
|
||||
id
|
||||
}
|
||||
}
|
||||
|
||||
query Accounts($partyId: ID!) {
|
||||
@@ -22,11 +25,12 @@ query Accounts($partyId: ID!) {
|
||||
}
|
||||
}
|
||||
|
||||
subscription AccountEvents($partyId: ID!) {
|
||||
subscription AccountEvents($partyId: ID) {
|
||||
accounts(partyId: $partyId) {
|
||||
type
|
||||
balance
|
||||
assetId
|
||||
marketId
|
||||
partyId
|
||||
}
|
||||
}
|
||||
|
||||
+10
-6
@@ -3,21 +3,21 @@ import { Schema as Types } from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type AccountFieldsFragment = { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, market?: { __typename?: 'Market', id: string } | null, asset: { __typename?: 'Asset', id: string } };
|
||||
export type AccountFieldsFragment = { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, market?: { __typename?: 'Market', id: string } | null, asset: { __typename?: 'Asset', id: string }, party?: { __typename?: 'Party', id: string } | null };
|
||||
|
||||
export type AccountsQueryVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type AccountsQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, market?: { __typename?: 'Market', id: string } | null, asset: { __typename?: 'Asset', id: string } } } | null> | null } | null } | null };
|
||||
export type AccountsQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, market?: { __typename?: 'Market', id: string } | null, asset: { __typename?: 'Asset', id: string }, party?: { __typename?: 'Party', id: string } | null } } | null> | null } | null } | null };
|
||||
|
||||
export type AccountEventsSubscriptionVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
partyId?: Types.InputMaybe<Types.Scalars['ID']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type AccountEventsSubscription = { __typename?: 'Subscription', accounts: Array<{ __typename?: 'AccountUpdate', type: Types.AccountType, balance: string, assetId: string, marketId?: string | null }> };
|
||||
export type AccountEventsSubscription = { __typename?: 'Subscription', accounts: Array<{ __typename?: 'AccountUpdate', type: Types.AccountType, balance: string, assetId: string, marketId?: string | null, partyId: string }> };
|
||||
|
||||
export const AccountFieldsFragmentDoc = gql`
|
||||
fragment AccountFields on AccountBalance {
|
||||
@@ -29,6 +29,9 @@ export const AccountFieldsFragmentDoc = gql`
|
||||
asset {
|
||||
id
|
||||
}
|
||||
party {
|
||||
id
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const AccountsDocument = gql`
|
||||
@@ -74,12 +77,13 @@ export type AccountsQueryHookResult = ReturnType<typeof useAccountsQuery>;
|
||||
export type AccountsLazyQueryHookResult = ReturnType<typeof useAccountsLazyQuery>;
|
||||
export type AccountsQueryResult = Apollo.QueryResult<AccountsQuery, AccountsQueryVariables>;
|
||||
export const AccountEventsDocument = gql`
|
||||
subscription AccountEvents($partyId: ID!) {
|
||||
subscription AccountEvents($partyId: ID) {
|
||||
accounts(partyId: $partyId) {
|
||||
type
|
||||
balance
|
||||
assetId
|
||||
marketId
|
||||
partyId
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -100,7 +104,7 @@ export const AccountEventsDocument = gql`
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useAccountEventsSubscription(baseOptions: Apollo.SubscriptionHookOptions<AccountEventsSubscription, AccountEventsSubscriptionVariables>) {
|
||||
export function useAccountEventsSubscription(baseOptions?: Apollo.SubscriptionHookOptions<AccountEventsSubscription, AccountEventsSubscriptionVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useSubscription<AccountEventsSubscription, AccountEventsSubscriptionVariables>(AccountEventsDocument, options);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ describe('getId', () => {
|
||||
balance: '1',
|
||||
assetId: 'assetId',
|
||||
marketId: '',
|
||||
partyId: 'partyId',
|
||||
})
|
||||
);
|
||||
expect(
|
||||
@@ -41,6 +42,7 @@ describe('getId', () => {
|
||||
balance: '1',
|
||||
assetId: 'assetId',
|
||||
marketId: 'testId',
|
||||
partyId: 'partyId',
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { InMemoryCacheConfig } from '@apollo/client';
|
||||
import type { ApolloError, InMemoryCacheConfig } from '@apollo/client';
|
||||
import {
|
||||
ApolloClient,
|
||||
from,
|
||||
@@ -13,9 +13,12 @@ import { createClient as createWSClient } from 'graphql-ws';
|
||||
import { onError } from '@apollo/client/link/error';
|
||||
import { RetryLink } from '@apollo/client/link/retry';
|
||||
import ApolloLinkTimeout from 'apollo-link-timeout';
|
||||
import type { GraphQLErrors } from '@apollo/client/errors';
|
||||
|
||||
const isBrowser = typeof window !== 'undefined';
|
||||
|
||||
const NOT_FOUND = 'NotFound';
|
||||
|
||||
export function createClient(base?: string, cacheConfig?: InMemoryCacheConfig) {
|
||||
if (!base) {
|
||||
throw new Error('Base must be passed into createClient!');
|
||||
@@ -61,8 +64,16 @@ export function createClient(base?: string, cacheConfig?: InMemoryCacheConfig) {
|
||||
: httpLink;
|
||||
|
||||
const errorLink = onError(({ graphQLErrors, networkError }) => {
|
||||
if (graphQLErrors) console.log(graphQLErrors);
|
||||
if (networkError) console.log(networkError);
|
||||
if (graphQLErrors) {
|
||||
graphQLErrors.forEach((e) => {
|
||||
if (e.extensions && e.extensions['type'] !== NOT_FOUND) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (networkError) {
|
||||
console.log(networkError);
|
||||
}
|
||||
});
|
||||
|
||||
return new ApolloClient({
|
||||
@@ -70,3 +81,21 @@ export function createClient(base?: string, cacheConfig?: InMemoryCacheConfig) {
|
||||
cache: new InMemoryCache(cacheConfig),
|
||||
});
|
||||
}
|
||||
|
||||
const isApolloGraphQLError = (
|
||||
error: ApolloError | Error | undefined
|
||||
): error is ApolloError => {
|
||||
return !!error && !!(error as ApolloError).graphQLErrors;
|
||||
};
|
||||
|
||||
const hasNotFoundGraphQLErrors = (errors: GraphQLErrors) => {
|
||||
return errors.some((e) => e.extensions && e.extensions['type'] === NOT_FOUND);
|
||||
};
|
||||
|
||||
export const isNotFoundGraphQLError = (
|
||||
error: Error | ApolloError | undefined
|
||||
) => {
|
||||
return (
|
||||
isApolloGraphQLError(error) && hasNotFoundGraphQLErrors(error.graphQLErrors)
|
||||
);
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useAssetsDataProvider } from './assets-data-provider';
|
||||
import { Button, Dialog, Icon, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import create from 'zustand';
|
||||
import { AssetDetailsTable } from './asset-details-table';
|
||||
import { AssetProposalNotification } from '@vegaprotocol/governance';
|
||||
|
||||
export type AssetDetailsDialogStore = {
|
||||
isOpen: boolean;
|
||||
@@ -49,6 +50,7 @@ export const AssetDetailsDialog = ({
|
||||
|
||||
const content = asset ? (
|
||||
<div className="my-2">
|
||||
<AssetProposalNotification assetId={asset.id} />
|
||||
<AssetDetailsTable asset={asset} />
|
||||
</div>
|
||||
) : (
|
||||
|
||||
@@ -17,7 +17,7 @@ export const MarginWarning = ({ margin, balance, asset }: Props) => {
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className="text-sm text-vega-orange mb-4"
|
||||
className="text-xs text-vega-orange mb-4"
|
||||
data-testid="dealticket-warning-margin"
|
||||
>
|
||||
<p className="mb-2">
|
||||
|
||||
@@ -5,8 +5,8 @@ import {
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { Input, InputError, Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import { isMarketInAuction, validateAmount } from '../../utils';
|
||||
|
||||
import type { DealTicketAmountProps } from './deal-ticket-amount';
|
||||
import { getMarketPrice } from '../../utils/get-price';
|
||||
|
||||
export type DealTicketMarketAmountProps = Omit<
|
||||
DealTicketAmountProps,
|
||||
@@ -21,21 +21,7 @@ export const DealTicketMarketAmount = ({
|
||||
const quoteName =
|
||||
market.tradableInstrument.instrument.product.settlementAsset.symbol;
|
||||
const sizeStep = toDecimal(market?.positionDecimalPlaces);
|
||||
|
||||
let price;
|
||||
if (isMarketInAuction(market)) {
|
||||
// 0 can never be a valid uncrossing price
|
||||
// as it would require there being orders on the book at that price.
|
||||
if (
|
||||
market.data?.indicativePrice &&
|
||||
market.data.indicativePrice !== '0' &&
|
||||
BigInt(market.data?.indicativePrice) !== BigInt(0)
|
||||
) {
|
||||
price = market.data.indicativePrice;
|
||||
}
|
||||
} else {
|
||||
price = market.depth?.lastTrade?.price;
|
||||
}
|
||||
const price = getMarketPrice(market);
|
||||
|
||||
const priceFormatted = price
|
||||
? addDecimalsFormatNumber(price, market.decimalPlaces)
|
||||
@@ -46,7 +32,7 @@ export const DealTicketMarketAmount = ({
|
||||
<div className="flex items-end gap-4 mb-2">
|
||||
<div className="flex-1 text-sm">Size</div>
|
||||
<div />
|
||||
<div className="flex-1 text-sm text-right">
|
||||
<div className="flex-2 text-sm text-right">
|
||||
{isMarketInAuction(market) && (
|
||||
<Tooltip
|
||||
description={t(
|
||||
|
||||
@@ -69,7 +69,7 @@ describe('DealTicket', () => {
|
||||
// Assert last price is shown
|
||||
expect(screen.getByTestId('last-price')).toHaveTextContent(
|
||||
// eslint-disable-next-line
|
||||
`~${addDecimal(market!.depth!.lastTrade!.price, market.decimalPlaces)} ${
|
||||
`~${addDecimal(market!.data.markPrice, market.decimalPlaces)} ${
|
||||
market.tradableInstrument.instrument.product.settlementAsset.symbol
|
||||
}`
|
||||
);
|
||||
|
||||
@@ -63,9 +63,11 @@ export const DealTicket = ({
|
||||
const order = watch();
|
||||
// When order state changes persist it in local storage
|
||||
useEffect(() => setPersistedOrder(order), [order, setPersistedOrder]);
|
||||
|
||||
const hasNoBalance = useHasNoBalance(
|
||||
market.tradableInstrument.instrument.product.settlementAsset.id
|
||||
);
|
||||
|
||||
const onSubmit = useCallback(
|
||||
(order: OrderSubmissionBody['orderSubmission']) => {
|
||||
if (!pubKey) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { FeesBreakdown } from '@vegaprotocol/market-info';
|
||||
import {
|
||||
addDecimal,
|
||||
addDecimalsFormatNumber,
|
||||
formatNumber,
|
||||
t,
|
||||
@@ -20,34 +21,39 @@ import { useCalculateSlippage } from './use-calculate-slippage';
|
||||
import { useOrderCloseOut } from './use-order-closeout';
|
||||
import { useOrderMargin } from './use-order-margin';
|
||||
import type { OrderMargin } from './use-order-margin';
|
||||
import { getDerivedPrice } from '../utils/get-price';
|
||||
|
||||
export const useFeeDealTicketDetails = (
|
||||
order: OrderSubmissionBody['orderSubmission'],
|
||||
market: MarketDealTicket
|
||||
) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
|
||||
const slippage = useCalculateSlippage({ marketId: market.id, order });
|
||||
|
||||
const price = useMemo(() => {
|
||||
const estPrice = order.price || market.data.markPrice;
|
||||
if (estPrice) {
|
||||
const derivedPrice = useMemo(() => {
|
||||
return getDerivedPrice(order, market);
|
||||
}, [order, market]);
|
||||
|
||||
// Note this isn't currently used anywhere
|
||||
const slippageAdjustedPrice = useMemo(() => {
|
||||
if (derivedPrice) {
|
||||
if (slippage && parseFloat(slippage) !== 0) {
|
||||
const isLong = order.side === Schema.Side.SIDE_BUY;
|
||||
const multiplier = new BigNumber(1)[isLong ? 'plus' : 'minus'](
|
||||
parseFloat(slippage) / 100
|
||||
);
|
||||
return new BigNumber(estPrice).multipliedBy(multiplier).toNumber();
|
||||
return new BigNumber(derivedPrice).multipliedBy(multiplier).toNumber();
|
||||
}
|
||||
return order.price;
|
||||
return derivedPrice;
|
||||
}
|
||||
return null;
|
||||
}, [market.data.markPrice, order.price, order.side, slippage]);
|
||||
}, [derivedPrice, order.side, slippage]);
|
||||
|
||||
const estMargin: OrderMargin | null = useOrderMargin({
|
||||
order,
|
||||
market,
|
||||
partyId: pubKey || '',
|
||||
derivedPrice,
|
||||
});
|
||||
|
||||
const { data: partyBalance } = usePartyBalanceQuery({
|
||||
@@ -62,11 +68,13 @@ export const useFeeDealTicketDetails = (
|
||||
});
|
||||
|
||||
const notionalSize = useMemo(() => {
|
||||
if (order.price && order.size) {
|
||||
return new BigNumber(order.size).multipliedBy(order.price).toString();
|
||||
if (derivedPrice && order.size) {
|
||||
return new BigNumber(order.size)
|
||||
.multipliedBy(addDecimal(derivedPrice, market.decimalPlaces))
|
||||
.toString();
|
||||
}
|
||||
return null;
|
||||
}, [order.price, order.size]);
|
||||
}, [derivedPrice, order.size, market.decimalPlaces]);
|
||||
|
||||
const quoteName = market.tradableInstrument.instrument.product.quoteName;
|
||||
|
||||
@@ -78,7 +86,7 @@ export const useFeeDealTicketDetails = (
|
||||
estMargin,
|
||||
estCloseOut,
|
||||
slippage,
|
||||
price,
|
||||
slippageAdjustedPrice,
|
||||
partyData: partyBalance,
|
||||
};
|
||||
}, [
|
||||
@@ -88,7 +96,7 @@ export const useFeeDealTicketDetails = (
|
||||
estMargin,
|
||||
estCloseOut,
|
||||
slippage,
|
||||
price,
|
||||
slippageAdjustedPrice,
|
||||
partyBalance,
|
||||
]);
|
||||
};
|
||||
@@ -100,7 +108,6 @@ export interface FeeDetails {
|
||||
estMargin: OrderMargin | null;
|
||||
estCloseOut: string | null;
|
||||
slippage: string | null;
|
||||
price?: string | number | null;
|
||||
}
|
||||
|
||||
export const getFeeDetailsValues = ({
|
||||
|
||||
@@ -5,6 +5,7 @@ import type { PositionMargin } from './use-market-positions';
|
||||
import type { Props } from './use-order-margin';
|
||||
import { useOrderMargin } from './use-order-margin';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||
|
||||
let mockEstimateData = {
|
||||
estimateOrder: {
|
||||
@@ -58,7 +59,7 @@ describe('useOrderMargin', () => {
|
||||
indicativePrice: '100',
|
||||
markPrice: '200',
|
||||
},
|
||||
},
|
||||
} as MarketDealTicket,
|
||||
partyId: 'partyId',
|
||||
};
|
||||
|
||||
|
||||
@@ -1,27 +1,16 @@
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import { removeDecimal } from '@vegaprotocol/react-helpers';
|
||||
import { useMarketPositions } from './use-market-positions';
|
||||
import type { EstimateOrderQuery } from './__generated__/EstimateOrder';
|
||||
import { useEstimateOrderQuery } from './__generated__/EstimateOrder';
|
||||
import { isMarketInAuction } from '../utils';
|
||||
|
||||
interface Market {
|
||||
id: string;
|
||||
decimalPlaces: number;
|
||||
positionDecimalPlaces: number;
|
||||
tradingMode: Schema.MarketTradingMode;
|
||||
data: {
|
||||
indicativePrice: string;
|
||||
markPrice: string;
|
||||
};
|
||||
}
|
||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||
|
||||
export interface Props {
|
||||
order: OrderSubmissionBody['orderSubmission'];
|
||||
market: Market;
|
||||
market: MarketDealTicket;
|
||||
partyId: string;
|
||||
derivedPrice?: string;
|
||||
}
|
||||
|
||||
const addFees = (feeObj: EstimateOrderQuery['estimateOrder']['fee']) => {
|
||||
@@ -44,21 +33,21 @@ export const useOrderMargin = ({
|
||||
order,
|
||||
market,
|
||||
partyId,
|
||||
derivedPrice,
|
||||
}: Props): OrderMargin | null => {
|
||||
const marketPositions = useMarketPositions({ marketId: market.id, partyId });
|
||||
const priceForEstimate = getPriceForEstimate(order, market);
|
||||
|
||||
const { data } = useEstimateOrderQuery({
|
||||
variables: {
|
||||
marketId: market.id,
|
||||
partyId,
|
||||
price: priceForEstimate,
|
||||
price: derivedPrice,
|
||||
size: removeDecimal(order.size, market.positionDecimalPlaces),
|
||||
side: order.side,
|
||||
timeInForce: order.timeInForce,
|
||||
type: order.type,
|
||||
},
|
||||
skip: !partyId || !market.id || !order.size || !priceForEstimate,
|
||||
skip: !partyId || !market.id || !order.size || !derivedPrice,
|
||||
});
|
||||
|
||||
if (data?.estimateOrder.marginLevels.initialLevel) {
|
||||
@@ -86,32 +75,3 @@ export const useOrderMargin = ({
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a price to use for estimating order margin and fees.
|
||||
* Market orders should use the markPrice or if in auction mode
|
||||
* the indicative price. If its a limit order use user input price.
|
||||
*/
|
||||
const getPriceForEstimate = (
|
||||
order: {
|
||||
type: Schema.OrderType;
|
||||
price?: string | undefined;
|
||||
},
|
||||
market: Market
|
||||
) => {
|
||||
// If order type is market we should use either the mark price
|
||||
// or the uncrossing price. If order type is limit use the price
|
||||
// the user has input
|
||||
let price;
|
||||
if (order.type === Schema.OrderType.TYPE_LIMIT && order.price) {
|
||||
price = removeDecimal(order.price, market.decimalPlaces);
|
||||
} else {
|
||||
if (isMarketInAuction(market)) {
|
||||
price = market.data.indicativePrice;
|
||||
} else {
|
||||
price = market.data.markPrice;
|
||||
}
|
||||
}
|
||||
|
||||
return price === '0' ? undefined : price;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||
import { removeDecimal } from '@vegaprotocol/react-helpers';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import { isMarketInAuction } from './is-market-in-auction';
|
||||
|
||||
/**
|
||||
* Get the market price based on market mode (auction or not auction)
|
||||
*/
|
||||
export const getMarketPrice = (market: MarketDealTicket) => {
|
||||
if (isMarketInAuction(market)) {
|
||||
// 0 can never be a valid uncrossing price
|
||||
// as it would require there being orders on the book at that price.
|
||||
if (
|
||||
market.data?.indicativePrice &&
|
||||
market.data.indicativePrice !== '0' &&
|
||||
BigInt(market.data?.indicativePrice) !== BigInt(0)
|
||||
) {
|
||||
return market.data.indicativePrice;
|
||||
}
|
||||
} else {
|
||||
return market.data.markPrice;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the price for an order, order limit this is the user
|
||||
* entered value, for market this will be the mark price or
|
||||
* if in auction the indicative uncrossing price
|
||||
*/
|
||||
export const getDerivedPrice = (
|
||||
order: {
|
||||
type: Schema.OrderType;
|
||||
price?: string | undefined;
|
||||
},
|
||||
market: MarketDealTicket
|
||||
) => {
|
||||
// If order type is market we should use either the mark price
|
||||
// or the uncrossing price. If order type is limit use the price
|
||||
// the user has input
|
||||
|
||||
// Use the market price if order is a market order
|
||||
let price;
|
||||
if (order.type === Schema.OrderType.TYPE_LIMIT && order.price) {
|
||||
price = removeDecimal(order.price, market.decimalPlaces);
|
||||
} else {
|
||||
price = getMarketPrice(market);
|
||||
}
|
||||
|
||||
return price === '0' ? undefined : price;
|
||||
};
|
||||
@@ -29,7 +29,12 @@ export const FillsManager = ({ partyId }: FillsManagerProps) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
||||
<AsyncRenderer
|
||||
loading={loading}
|
||||
error={error}
|
||||
data={data}
|
||||
noDataCondition={() => false}
|
||||
>
|
||||
<FillsTable
|
||||
ref={gridRef}
|
||||
partyId={partyId}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { DApp, TOKEN_PROPOSAL, useLinks } from '@vegaprotocol/environment';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import { ExternalLink, Intent, Notification } from '@vegaprotocol/ui-toolkit';
|
||||
import { useUpdateProposal } from '../lib';
|
||||
|
||||
type AssetProposalNotificationProps = {
|
||||
assetId?: string;
|
||||
};
|
||||
export const AssetProposalNotification = ({
|
||||
assetId,
|
||||
}: AssetProposalNotificationProps) => {
|
||||
const tokenLink = useLinks(DApp.Token);
|
||||
const { data: proposal } = useUpdateProposal({
|
||||
id: assetId,
|
||||
proposalType: Schema.ProposalType.TYPE_UPDATE_ASSET,
|
||||
});
|
||||
|
||||
if (proposal) {
|
||||
const proposalLink = tokenLink(
|
||||
TOKEN_PROPOSAL.replace(':id', proposal.id || '')
|
||||
);
|
||||
return (
|
||||
<Notification
|
||||
intent={Intent.Warning}
|
||||
message={t('Changes have been proposed for this asset')}
|
||||
testId="asset-proposal-notification"
|
||||
>
|
||||
<ExternalLink href={proposalLink}>{t('View proposal')}</ExternalLink>
|
||||
</Notification>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './asset-proposal-notification';
|
||||
export * from './market-proposal-notification';
|
||||
@@ -0,0 +1,35 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import { ExternalLink, Intent, Notification } from '@vegaprotocol/ui-toolkit';
|
||||
import { DApp, TOKEN_PROPOSAL, useLinks } from '@vegaprotocol/environment';
|
||||
import { useUpdateProposal } from '../lib';
|
||||
|
||||
type MarketProposalNotificationProps = {
|
||||
marketId?: string;
|
||||
};
|
||||
export const MarketProposalNotification = ({
|
||||
marketId,
|
||||
}: MarketProposalNotificationProps) => {
|
||||
const tokenLink = useLinks(DApp.Token);
|
||||
const { data: proposal } = useUpdateProposal({
|
||||
id: marketId,
|
||||
proposalType: Schema.ProposalType.TYPE_UPDATE_MARKET,
|
||||
});
|
||||
|
||||
if (proposal) {
|
||||
const proposalLink = tokenLink(
|
||||
TOKEN_PROPOSAL.replace(':id', proposal.id || '')
|
||||
);
|
||||
return (
|
||||
<Notification
|
||||
intent={Intent.Warning}
|
||||
message={t('Changes have been proposed for this market')}
|
||||
testId="market-proposal-notification"
|
||||
>
|
||||
<ExternalLink href={proposalLink}>{t('View proposal')}</ExternalLink>
|
||||
</Notification>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './lib';
|
||||
export * from './utils';
|
||||
export * from './components';
|
||||
|
||||
@@ -12,6 +12,63 @@ fragment NewMarketFields on NewMarket {
|
||||
}
|
||||
}
|
||||
|
||||
fragment UpdateMarketFields on UpdateMarket {
|
||||
marketId
|
||||
updateMarketConfiguration {
|
||||
instrument {
|
||||
code
|
||||
product {
|
||||
quoteName
|
||||
}
|
||||
}
|
||||
priceMonitoringParameters {
|
||||
triggers {
|
||||
horizonSecs
|
||||
probability
|
||||
auctionExtensionSecs
|
||||
}
|
||||
}
|
||||
liquidityMonitoringParameters {
|
||||
targetStakeParameters {
|
||||
timeWindow
|
||||
scalingFactor
|
||||
}
|
||||
triggeringRatio
|
||||
}
|
||||
riskParameters {
|
||||
__typename
|
||||
... on UpdateMarketSimpleRiskModel {
|
||||
simple {
|
||||
factorLong
|
||||
factorShort
|
||||
}
|
||||
}
|
||||
... on UpdateMarketLogNormalRiskModel {
|
||||
logNormal {
|
||||
riskAversionParameter
|
||||
tau
|
||||
params {
|
||||
mu
|
||||
r
|
||||
sigma
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment UpdateAssetFields on UpdateAsset {
|
||||
assetId
|
||||
quantum
|
||||
source {
|
||||
... on UpdateERC20 {
|
||||
lifetimeLimit
|
||||
withdrawThreshold
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment ProposalListFields on Proposal {
|
||||
id
|
||||
reference
|
||||
@@ -36,6 +93,12 @@ fragment ProposalListFields on Proposal {
|
||||
... on NewMarket {
|
||||
...NewMarketFields
|
||||
}
|
||||
... on UpdateMarket {
|
||||
...UpdateMarketFields
|
||||
}
|
||||
... on UpdateAsset {
|
||||
...UpdateAssetFields
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,11 @@ import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type NewMarketFieldsFragment = { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', code: string, name: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', id: string, name: string, symbol: string } } | null } };
|
||||
|
||||
export type ProposalListFieldsFragment = { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: string, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalWeight: string }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalWeight: string } }, terms: { __typename?: 'ProposalTerms', closingDatetime: string, enactmentDatetime?: string | null, change: { __typename?: 'NewAsset' } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', code: string, name: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', id: string, name: string, symbol: string } } | null } } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket' } | { __typename?: 'UpdateNetworkParameter' } } };
|
||||
export type UpdateMarketFieldsFragment = { __typename?: 'UpdateMarket', marketId: string, updateMarketConfiguration: { __typename?: 'UpdateMarketConfiguration', instrument: { __typename?: 'UpdateInstrumentConfiguration', code: string, product: { __typename?: 'UpdateFutureProduct', quoteName: string } }, priceMonitoringParameters: { __typename?: 'PriceMonitoringParameters', triggers?: Array<{ __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number }> | null }, liquidityMonitoringParameters: { __typename?: 'LiquidityMonitoringParameters', triggeringRatio: number, targetStakeParameters: { __typename?: 'TargetStakeParameters', timeWindow: number, scalingFactor: number } }, riskParameters: { __typename: 'UpdateMarketLogNormalRiskModel', logNormal?: { __typename?: 'LogNormalRiskModel', riskAversionParameter: number, tau: number, params: { __typename?: 'LogNormalModelParams', mu: number, r: number, sigma: number } } | null } | { __typename: 'UpdateMarketSimpleRiskModel', simple?: { __typename?: 'SimpleRiskModelParams', factorLong: number, factorShort: number } | null } } };
|
||||
|
||||
export type UpdateAssetFieldsFragment = { __typename?: 'UpdateAsset', assetId: string, quantum: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } };
|
||||
|
||||
export type ProposalListFieldsFragment = { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: string, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalWeight: string }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalWeight: string } }, terms: { __typename?: 'ProposalTerms', closingDatetime: string, enactmentDatetime?: string | null, change: { __typename?: 'NewAsset' } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', code: string, name: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', id: string, name: string, symbol: string } } | null } } | { __typename?: 'UpdateAsset', assetId: string, quantum: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } } | { __typename?: 'UpdateMarket', marketId: string, updateMarketConfiguration: { __typename?: 'UpdateMarketConfiguration', instrument: { __typename?: 'UpdateInstrumentConfiguration', code: string, product: { __typename?: 'UpdateFutureProduct', quoteName: string } }, priceMonitoringParameters: { __typename?: 'PriceMonitoringParameters', triggers?: Array<{ __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number }> | null }, liquidityMonitoringParameters: { __typename?: 'LiquidityMonitoringParameters', triggeringRatio: number, targetStakeParameters: { __typename?: 'TargetStakeParameters', timeWindow: number, scalingFactor: number } }, riskParameters: { __typename: 'UpdateMarketLogNormalRiskModel', logNormal?: { __typename?: 'LogNormalRiskModel', riskAversionParameter: number, tau: number, params: { __typename?: 'LogNormalModelParams', mu: number, r: number, sigma: number } } | null } | { __typename: 'UpdateMarketSimpleRiskModel', simple?: { __typename?: 'SimpleRiskModelParams', factorLong: number, factorShort: number } | null } } } | { __typename?: 'UpdateNetworkParameter' } } };
|
||||
|
||||
export type ProposalsListQueryVariables = Types.Exact<{
|
||||
proposalType?: Types.InputMaybe<Types.ProposalType>;
|
||||
@@ -13,7 +17,7 @@ export type ProposalsListQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type ProposalsListQuery = { __typename?: 'Query', proposalsConnection?: { __typename?: 'ProposalsConnection', edges?: Array<{ __typename?: 'ProposalEdge', node: { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: string, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalWeight: string }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalWeight: string } }, terms: { __typename?: 'ProposalTerms', closingDatetime: string, enactmentDatetime?: string | null, change: { __typename?: 'NewAsset' } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', code: string, name: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', id: string, name: string, symbol: string } } | null } } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket' } | { __typename?: 'UpdateNetworkParameter' } } } } | null> | null } | null };
|
||||
export type ProposalsListQuery = { __typename?: 'Query', proposalsConnection?: { __typename?: 'ProposalsConnection', edges?: Array<{ __typename?: 'ProposalEdge', node: { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: string, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalWeight: string }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalWeight: string } }, terms: { __typename?: 'ProposalTerms', closingDatetime: string, enactmentDatetime?: string | null, change: { __typename?: 'NewAsset' } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', code: string, name: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', id: string, name: string, symbol: string } } | null } } | { __typename?: 'UpdateAsset', assetId: string, quantum: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } } | { __typename?: 'UpdateMarket', marketId: string, updateMarketConfiguration: { __typename?: 'UpdateMarketConfiguration', instrument: { __typename?: 'UpdateInstrumentConfiguration', code: string, product: { __typename?: 'UpdateFutureProduct', quoteName: string } }, priceMonitoringParameters: { __typename?: 'PriceMonitoringParameters', triggers?: Array<{ __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number }> | null }, liquidityMonitoringParameters: { __typename?: 'LiquidityMonitoringParameters', triggeringRatio: number, targetStakeParameters: { __typename?: 'TargetStakeParameters', timeWindow: number, scalingFactor: number } }, riskParameters: { __typename: 'UpdateMarketLogNormalRiskModel', logNormal?: { __typename?: 'LogNormalRiskModel', riskAversionParameter: number, tau: number, params: { __typename?: 'LogNormalModelParams', mu: number, r: number, sigma: number } } | null } | { __typename: 'UpdateMarketSimpleRiskModel', simple?: { __typename?: 'SimpleRiskModelParams', factorLong: number, factorShort: number } | null } } } | { __typename?: 'UpdateNetworkParameter' } } } } | null> | null } | null };
|
||||
|
||||
export const NewMarketFieldsFragmentDoc = gql`
|
||||
fragment NewMarketFields on NewMarket {
|
||||
@@ -30,6 +34,65 @@ export const NewMarketFieldsFragmentDoc = gql`
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const UpdateMarketFieldsFragmentDoc = gql`
|
||||
fragment UpdateMarketFields on UpdateMarket {
|
||||
marketId
|
||||
updateMarketConfiguration {
|
||||
instrument {
|
||||
code
|
||||
product {
|
||||
quoteName
|
||||
}
|
||||
}
|
||||
priceMonitoringParameters {
|
||||
triggers {
|
||||
horizonSecs
|
||||
probability
|
||||
auctionExtensionSecs
|
||||
}
|
||||
}
|
||||
liquidityMonitoringParameters {
|
||||
targetStakeParameters {
|
||||
timeWindow
|
||||
scalingFactor
|
||||
}
|
||||
triggeringRatio
|
||||
}
|
||||
riskParameters {
|
||||
__typename
|
||||
... on UpdateMarketSimpleRiskModel {
|
||||
simple {
|
||||
factorLong
|
||||
factorShort
|
||||
}
|
||||
}
|
||||
... on UpdateMarketLogNormalRiskModel {
|
||||
logNormal {
|
||||
riskAversionParameter
|
||||
tau
|
||||
params {
|
||||
mu
|
||||
r
|
||||
sigma
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const UpdateAssetFieldsFragmentDoc = gql`
|
||||
fragment UpdateAssetFields on UpdateAsset {
|
||||
assetId
|
||||
quantum
|
||||
source {
|
||||
... on UpdateERC20 {
|
||||
lifetimeLimit
|
||||
withdrawThreshold
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const ProposalListFieldsFragmentDoc = gql`
|
||||
fragment ProposalListFields on Proposal {
|
||||
id
|
||||
@@ -55,10 +118,18 @@ export const ProposalListFieldsFragmentDoc = gql`
|
||||
... on NewMarket {
|
||||
...NewMarketFields
|
||||
}
|
||||
... on UpdateMarket {
|
||||
...UpdateMarketFields
|
||||
}
|
||||
... on UpdateAsset {
|
||||
...UpdateAssetFields
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
${NewMarketFieldsFragmentDoc}`;
|
||||
${NewMarketFieldsFragmentDoc}
|
||||
${UpdateMarketFieldsFragmentDoc}
|
||||
${UpdateAssetFieldsFragmentDoc}`;
|
||||
export const ProposalsListDocument = gql`
|
||||
query ProposalsList($proposalType: ProposalType, $inState: ProposalState) {
|
||||
proposalsConnection(proposalType: $proposalType, inState: $inState) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './__generated__/Proposal';
|
||||
export * from './use-proposal-event';
|
||||
export * from './use-proposal-submit';
|
||||
export * from './use-update-proposal';
|
||||
|
||||
@@ -0,0 +1,319 @@
|
||||
/* eslint-disable jest/no-conditional-expect */
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
|
||||
import type {
|
||||
ProposalListFieldsFragment,
|
||||
UpdateAssetFieldsFragment,
|
||||
UpdateMarketFieldsFragment,
|
||||
} from '../proposals-data-provider';
|
||||
import {
|
||||
isChangeProposed,
|
||||
UpdateAssetFields,
|
||||
UpdateMarketFields,
|
||||
useUpdateProposal,
|
||||
} from './use-update-proposal';
|
||||
|
||||
const generateUpdateAssetProposal = (
|
||||
id: string,
|
||||
quantum = '',
|
||||
lifetimeLimit = '',
|
||||
withdrawThreshold = ''
|
||||
): ProposalListFieldsFragment => ({
|
||||
reference: '',
|
||||
state: Schema.ProposalState.STATE_OPEN,
|
||||
datetime: '',
|
||||
votes: {
|
||||
__typename: undefined,
|
||||
yes: {
|
||||
__typename: undefined,
|
||||
totalTokens: '',
|
||||
totalNumber: '',
|
||||
totalWeight: '',
|
||||
},
|
||||
no: {
|
||||
__typename: undefined,
|
||||
totalTokens: '',
|
||||
totalNumber: '',
|
||||
totalWeight: '',
|
||||
},
|
||||
},
|
||||
terms: {
|
||||
__typename: 'ProposalTerms',
|
||||
closingDatetime: '',
|
||||
enactmentDatetime: undefined,
|
||||
change: {
|
||||
__typename: 'UpdateAsset',
|
||||
assetId: id,
|
||||
quantum,
|
||||
source: {
|
||||
__typename: 'UpdateERC20',
|
||||
lifetimeLimit,
|
||||
withdrawThreshold,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
type RiskParameters =
|
||||
| {
|
||||
__typename: 'UpdateMarketLogNormalRiskModel';
|
||||
logNormal?: {
|
||||
__typename?: 'LogNormalRiskModel';
|
||||
riskAversionParameter: number;
|
||||
tau: number;
|
||||
params: {
|
||||
__typename?: 'LogNormalModelParams';
|
||||
mu: number;
|
||||
r: number;
|
||||
sigma: number;
|
||||
};
|
||||
} | null;
|
||||
}
|
||||
| {
|
||||
__typename: 'UpdateMarketSimpleRiskModel';
|
||||
simple?: {
|
||||
__typename?: 'SimpleRiskModelParams';
|
||||
factorLong: number;
|
||||
factorShort: number;
|
||||
} | null;
|
||||
};
|
||||
|
||||
const generateRiskParameters = (
|
||||
type:
|
||||
| 'UpdateMarketLogNormalRiskModel'
|
||||
| 'UpdateMarketSimpleRiskModel' = 'UpdateMarketLogNormalRiskModel'
|
||||
): RiskParameters => {
|
||||
if (type === 'UpdateMarketSimpleRiskModel')
|
||||
return {
|
||||
__typename: 'UpdateMarketSimpleRiskModel',
|
||||
simple: {
|
||||
__typename: 'SimpleRiskModelParams',
|
||||
factorLong: 0,
|
||||
factorShort: 0,
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
__typename: 'UpdateMarketLogNormalRiskModel',
|
||||
logNormal: {
|
||||
__typename: 'LogNormalRiskModel',
|
||||
params: {
|
||||
__typename: 'LogNormalModelParams',
|
||||
mu: 0,
|
||||
r: 0,
|
||||
sigma: 0,
|
||||
},
|
||||
riskAversionParameter: 0,
|
||||
tau: 0,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const generateUpdateMarketProposal = (
|
||||
id: string,
|
||||
code = '',
|
||||
quoteName = '',
|
||||
priceMonitoring = false,
|
||||
liquidityMonitoring = false,
|
||||
riskParameters = false,
|
||||
riskParametersType:
|
||||
| 'UpdateMarketLogNormalRiskModel'
|
||||
| 'UpdateMarketSimpleRiskModel' = 'UpdateMarketLogNormalRiskModel'
|
||||
): ProposalListFieldsFragment => ({
|
||||
reference: '',
|
||||
state: Schema.ProposalState.STATE_OPEN,
|
||||
datetime: '',
|
||||
votes: {
|
||||
__typename: undefined,
|
||||
yes: {
|
||||
__typename: undefined,
|
||||
totalTokens: '',
|
||||
totalNumber: '',
|
||||
totalWeight: '',
|
||||
},
|
||||
no: {
|
||||
__typename: undefined,
|
||||
totalTokens: '',
|
||||
totalNumber: '',
|
||||
totalWeight: '',
|
||||
},
|
||||
},
|
||||
terms: {
|
||||
__typename: 'ProposalTerms',
|
||||
closingDatetime: '',
|
||||
enactmentDatetime: undefined,
|
||||
change: {
|
||||
__typename: 'UpdateMarket',
|
||||
marketId: id,
|
||||
updateMarketConfiguration: {
|
||||
__typename: undefined,
|
||||
instrument: {
|
||||
__typename:
|
||||
code.length > 0 || quoteName.length > 0
|
||||
? 'UpdateInstrumentConfiguration'
|
||||
: undefined,
|
||||
code,
|
||||
product: {
|
||||
__typename:
|
||||
quoteName.length > 0 ? 'UpdateFutureProduct' : undefined,
|
||||
quoteName,
|
||||
},
|
||||
},
|
||||
priceMonitoringParameters: {
|
||||
__typename: priceMonitoring ? 'PriceMonitoringParameters' : undefined,
|
||||
triggers: priceMonitoring
|
||||
? [
|
||||
{
|
||||
auctionExtensionSecs: 1,
|
||||
horizonSecs: 2,
|
||||
probability: 3,
|
||||
__typename: 'PriceMonitoringTrigger',
|
||||
},
|
||||
]
|
||||
: [],
|
||||
},
|
||||
liquidityMonitoringParameters: {
|
||||
__typename: liquidityMonitoring
|
||||
? 'LiquidityMonitoringParameters'
|
||||
: undefined,
|
||||
triggeringRatio: 0,
|
||||
targetStakeParameters: {
|
||||
__typename: undefined,
|
||||
scalingFactor: 0,
|
||||
timeWindow: 0,
|
||||
},
|
||||
},
|
||||
riskParameters: riskParameters
|
||||
? generateRiskParameters(riskParametersType)
|
||||
: {
|
||||
__typename: riskParametersType,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const mockDataProviderData: {
|
||||
data: ProposalListFieldsFragment[];
|
||||
error: Error | undefined;
|
||||
loading: boolean;
|
||||
} = {
|
||||
data: [
|
||||
generateUpdateMarketProposal('123'),
|
||||
generateUpdateAssetProposal('456'),
|
||||
],
|
||||
error: undefined,
|
||||
loading: false,
|
||||
};
|
||||
|
||||
const mockDataProvider = jest.fn(() => {
|
||||
return mockDataProviderData;
|
||||
});
|
||||
jest.mock('@vegaprotocol/react-helpers', () => ({
|
||||
...jest.requireActual('@vegaprotocol/react-helpers'),
|
||||
useDataProvider: jest.fn((args) => mockDataProvider()),
|
||||
}));
|
||||
|
||||
describe('useUpdateProposal', () => {
|
||||
it('returns update proposal for a given asset', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useUpdateProposal({
|
||||
id: '456',
|
||||
proposalType: Schema.ProposalType.TYPE_UPDATE_ASSET,
|
||||
})
|
||||
);
|
||||
const change = result.current.data?.terms
|
||||
.change as UpdateAssetFieldsFragment;
|
||||
expect(change.__typename).toEqual('UpdateAsset');
|
||||
expect(change.assetId).toEqual('456');
|
||||
});
|
||||
|
||||
it('returns update proposal for a given market', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useUpdateProposal({
|
||||
id: '123',
|
||||
proposalType: Schema.ProposalType.TYPE_UPDATE_MARKET,
|
||||
})
|
||||
);
|
||||
const change = result.current.data?.terms
|
||||
.change as UpdateMarketFieldsFragment;
|
||||
expect(change.__typename).toEqual('UpdateMarket');
|
||||
expect(change.marketId).toEqual('123');
|
||||
});
|
||||
|
||||
it('does not return a proposal if not found', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useUpdateProposal({
|
||||
id: '789',
|
||||
proposalType: Schema.ProposalType.TYPE_UPDATE_MARKET,
|
||||
})
|
||||
);
|
||||
expect(result.current.data).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('isChangeProposed', () => {
|
||||
it('returns false if a change for the specified asset field is not proposed', () => {
|
||||
const proposal = generateUpdateAssetProposal('123');
|
||||
expect(isChangeProposed(proposal, UpdateAssetFields.Quantum)).toBeFalsy();
|
||||
expect(
|
||||
isChangeProposed(proposal, UpdateAssetFields.LifetimeLimit)
|
||||
).toBeFalsy();
|
||||
expect(
|
||||
isChangeProposed(proposal, UpdateAssetFields.WithdrawThreshold)
|
||||
).toBeFalsy();
|
||||
});
|
||||
|
||||
it('returns true if a change for the specified asset field is proposed', () => {
|
||||
const proposal = generateUpdateAssetProposal('123', '100', '100', '100');
|
||||
expect(isChangeProposed(proposal, UpdateAssetFields.Quantum)).toBeTruthy();
|
||||
expect(
|
||||
isChangeProposed(proposal, UpdateAssetFields.LifetimeLimit)
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
isChangeProposed(proposal, UpdateAssetFields.WithdrawThreshold)
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it('returns false if a change for the specified market field is not proposed', () => {
|
||||
const proposal = generateUpdateMarketProposal('123');
|
||||
expect(isChangeProposed(proposal, UpdateMarketFields.Code)).toBeFalsy();
|
||||
expect(
|
||||
isChangeProposed(proposal, UpdateMarketFields.QuoteName)
|
||||
).toBeFalsy();
|
||||
expect(
|
||||
isChangeProposed(proposal, UpdateMarketFields.PriceMonitoring)
|
||||
).toBeFalsy();
|
||||
expect(
|
||||
isChangeProposed(proposal, UpdateMarketFields.LiquidityMonitoring)
|
||||
).toBeFalsy();
|
||||
expect(
|
||||
isChangeProposed(proposal, UpdateMarketFields.RiskParameters)
|
||||
).toBeFalsy();
|
||||
});
|
||||
|
||||
it('returns true if a change for the specified market field is proposed', () => {
|
||||
const proposal = generateUpdateMarketProposal(
|
||||
'123',
|
||||
'ABCDEF',
|
||||
'qABCDEFq',
|
||||
true,
|
||||
true,
|
||||
true
|
||||
);
|
||||
expect(isChangeProposed(proposal, UpdateMarketFields.Code)).toBeFalsy();
|
||||
expect(
|
||||
isChangeProposed(proposal, UpdateMarketFields.QuoteName)
|
||||
).toBeFalsy();
|
||||
expect(
|
||||
isChangeProposed(proposal, UpdateMarketFields.PriceMonitoring)
|
||||
).toBeFalsy();
|
||||
expect(
|
||||
isChangeProposed(proposal, UpdateMarketFields.LiquidityMonitoring)
|
||||
).toBeFalsy();
|
||||
expect(
|
||||
isChangeProposed(proposal, UpdateMarketFields.RiskParameters)
|
||||
).toBeFalsy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,203 @@
|
||||
import { proposalsListDataProvider } from '..';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { useMemo } from 'react';
|
||||
import first from 'lodash/first';
|
||||
import type { ProposalListFieldsFragment } from '..';
|
||||
|
||||
type UseUpdateProposalProps = {
|
||||
id?: string;
|
||||
proposalType:
|
||||
| Schema.ProposalType.TYPE_UPDATE_ASSET
|
||||
| Schema.ProposalType.TYPE_UPDATE_MARKET;
|
||||
};
|
||||
|
||||
type UseUpdateProposal = {
|
||||
data: ProposalListFieldsFragment | undefined;
|
||||
loading: boolean;
|
||||
error: Error | undefined;
|
||||
};
|
||||
|
||||
const changeCondition = {
|
||||
[Schema.ProposalType.TYPE_UPDATE_ASSET]: (
|
||||
id: string,
|
||||
change: ProposalListFieldsFragment['terms']['change']
|
||||
) => change.__typename === 'UpdateAsset' && change.assetId === id,
|
||||
[Schema.ProposalType.TYPE_UPDATE_MARKET]: (
|
||||
id: string,
|
||||
change: ProposalListFieldsFragment['terms']['change']
|
||||
) => change.__typename === 'UpdateMarket' && change.marketId === id,
|
||||
};
|
||||
|
||||
export const useUpdateProposal = ({
|
||||
id,
|
||||
proposalType,
|
||||
}: UseUpdateProposalProps): UseUpdateProposal => {
|
||||
const variables = useMemo(
|
||||
() => ({
|
||||
proposalType,
|
||||
skipUpdates: true,
|
||||
}),
|
||||
[proposalType]
|
||||
);
|
||||
|
||||
const { data, loading, error } = useDataProvider({
|
||||
dataProvider: proposalsListDataProvider,
|
||||
variables,
|
||||
});
|
||||
|
||||
const proposal = id
|
||||
? first(
|
||||
(data || []).filter(
|
||||
(proposal) =>
|
||||
[
|
||||
Schema.ProposalState.STATE_OPEN,
|
||||
Schema.ProposalState.STATE_PASSED,
|
||||
Schema.ProposalState.STATE_WAITING_FOR_NODE_VOTE,
|
||||
].includes(proposal.state) &&
|
||||
changeCondition[proposalType](id, proposal.terms.change)
|
||||
)
|
||||
)
|
||||
: undefined;
|
||||
|
||||
return { data: proposal, loading, error };
|
||||
};
|
||||
|
||||
export enum UpdateMarketFields {
|
||||
Code,
|
||||
QuoteName,
|
||||
PriceMonitoring,
|
||||
LiquidityMonitoring,
|
||||
RiskParameters,
|
||||
}
|
||||
|
||||
export enum UpdateAssetFields {
|
||||
Quantum,
|
||||
LifetimeLimit,
|
||||
WithdrawThreshold,
|
||||
}
|
||||
|
||||
export type UpdateProposalField = UpdateAssetFields | UpdateMarketFields;
|
||||
|
||||
const fieldGetters = {
|
||||
[UpdateMarketFields.Code]: (
|
||||
change: ProposalListFieldsFragment['terms']['change']
|
||||
) => {
|
||||
if (change.__typename === 'UpdateMarket') {
|
||||
const proposed =
|
||||
change.updateMarketConfiguration.__typename !== undefined &&
|
||||
change.updateMarketConfiguration.instrument.__typename !== undefined;
|
||||
return (
|
||||
proposed && change.updateMarketConfiguration.instrument.code.length > 0
|
||||
);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[UpdateMarketFields.QuoteName]: (
|
||||
change: ProposalListFieldsFragment['terms']['change']
|
||||
) => {
|
||||
if (change.__typename === 'UpdateMarket') {
|
||||
const proposed =
|
||||
change.updateMarketConfiguration.__typename !== undefined &&
|
||||
change.updateMarketConfiguration.instrument.__typename !== undefined &&
|
||||
change.updateMarketConfiguration.instrument.product.__typename !==
|
||||
undefined;
|
||||
return (
|
||||
proposed &&
|
||||
change.updateMarketConfiguration.instrument.product.quoteName.length > 0
|
||||
);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[UpdateMarketFields.PriceMonitoring]: (
|
||||
change: ProposalListFieldsFragment['terms']['change']
|
||||
) => {
|
||||
if (change.__typename === 'UpdateMarket') {
|
||||
const proposed =
|
||||
change.updateMarketConfiguration.__typename !== undefined &&
|
||||
change.updateMarketConfiguration.priceMonitoringParameters
|
||||
.__typename !== undefined &&
|
||||
change.updateMarketConfiguration.priceMonitoringParameters.triggers
|
||||
?.length;
|
||||
return proposed;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[UpdateMarketFields.LiquidityMonitoring]: (
|
||||
change: ProposalListFieldsFragment['terms']['change']
|
||||
) => {
|
||||
if (change.__typename === 'UpdateMarket') {
|
||||
const proposed =
|
||||
change.updateMarketConfiguration.__typename !== undefined &&
|
||||
change.updateMarketConfiguration.liquidityMonitoringParameters
|
||||
.__typename !== undefined;
|
||||
return proposed;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[UpdateMarketFields.RiskParameters]: (
|
||||
change: ProposalListFieldsFragment['terms']['change']
|
||||
) => {
|
||||
if (change.__typename === 'UpdateMarket') {
|
||||
const proposed =
|
||||
change.updateMarketConfiguration.__typename !== undefined &&
|
||||
change.updateMarketConfiguration.riskParameters.__typename !==
|
||||
undefined;
|
||||
const log =
|
||||
change.updateMarketConfiguration.riskParameters.__typename ===
|
||||
'UpdateMarketLogNormalRiskModel' &&
|
||||
change.updateMarketConfiguration.riskParameters.logNormal !== undefined;
|
||||
const simple =
|
||||
change.updateMarketConfiguration.riskParameters.__typename ===
|
||||
'UpdateMarketSimpleRiskModel' &&
|
||||
change.updateMarketConfiguration.riskParameters.simple !== undefined;
|
||||
return proposed && (log || simple);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[UpdateAssetFields.Quantum]: (
|
||||
change: ProposalListFieldsFragment['terms']['change']
|
||||
) => {
|
||||
if (change.__typename === 'UpdateAsset') {
|
||||
const proposed = change.quantum.length > 0;
|
||||
return proposed;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[UpdateAssetFields.LifetimeLimit]: (
|
||||
change: ProposalListFieldsFragment['terms']['change']
|
||||
) => {
|
||||
if (change.__typename === 'UpdateAsset') {
|
||||
const proposed =
|
||||
change.source.__typename === 'UpdateERC20' &&
|
||||
change.source.lifetimeLimit.length > 0;
|
||||
return proposed;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[UpdateAssetFields.WithdrawThreshold]: (
|
||||
change: ProposalListFieldsFragment['terms']['change']
|
||||
) => {
|
||||
if (change.__typename === 'UpdateAsset') {
|
||||
const proposed =
|
||||
change.source.__typename === 'UpdateERC20' &&
|
||||
change.source.withdrawThreshold.length > 0;
|
||||
return proposed;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
export const isChangeProposed = (
|
||||
proposal: ProposalListFieldsFragment | undefined,
|
||||
field: UpdateProposalField
|
||||
) => {
|
||||
if (proposal) {
|
||||
return (
|
||||
(proposal.terms.change.__typename === 'UpdateAsset' ||
|
||||
proposal.terms.change.__typename === 'UpdateMarket') &&
|
||||
fieldGetters[field](proposal.terms.change)
|
||||
);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './lib/ledger-container';
|
||||
export * from './lib/ledger-manager';
|
||||
export * from './lib/__generated__/LedgerEntries';
|
||||
|
||||
@@ -1,26 +1,34 @@
|
||||
fragment LedgerEntry on AggregatedLedgerEntries {
|
||||
fragment LedgerEntry on AggregatedLedgerEntry {
|
||||
vegaTime
|
||||
quantity
|
||||
partyId
|
||||
assetId
|
||||
marketId
|
||||
accountType
|
||||
transferType
|
||||
receiverAccountType
|
||||
receiverMarketId
|
||||
receiverPartyId
|
||||
senderAccountType
|
||||
senderMarketId
|
||||
senderPartyId
|
||||
}
|
||||
|
||||
query LedgerEntries($partyId: ID!) {
|
||||
query LedgerEntries($partyId: ID!, $pagination: Pagination) {
|
||||
ledgerEntries(
|
||||
filter: { AccountFromFilter: { partyIds: [$partyId] } }
|
||||
groupOptions: {
|
||||
ByAccountField: [PartyId, AccountType, AssetId, MarketId]
|
||||
ByLedgerEntryField: [TransferType]
|
||||
filter: {
|
||||
SenderAccountFilter: { partyIds: [$partyId] }
|
||||
ReceiverAccountFilter: { partyIds: [$partyId] }
|
||||
}
|
||||
pagination: { first: 500 }
|
||||
pagination: $pagination
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
...LedgerEntry
|
||||
}
|
||||
}
|
||||
pageInfo {
|
||||
startCursor
|
||||
endCursor
|
||||
hasNextPage
|
||||
hasPreviousPage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+20
-10
@@ -3,38 +3,47 @@ import { Schema as Types } from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type LedgerEntryFragment = { __typename?: 'AggregatedLedgerEntries', vegaTime: string, quantity: string, partyId?: string | null, assetId?: string | null, marketId?: string | null, accountType?: Types.AccountType | null, transferType?: string | null };
|
||||
export type LedgerEntryFragment = { __typename?: 'AggregatedLedgerEntry', vegaTime: any, quantity: string, assetId?: string | null, transferType?: Types.TransferType | null, receiverAccountType?: Types.AccountType | null, receiverMarketId?: string | null, receiverPartyId?: string | null, senderAccountType?: Types.AccountType | null, senderMarketId?: string | null, senderPartyId?: string | null };
|
||||
|
||||
export type LedgerEntriesQueryVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
pagination?: Types.InputMaybe<Types.Pagination>;
|
||||
}>;
|
||||
|
||||
|
||||
export type LedgerEntriesQuery = { __typename?: 'Query', ledgerEntries: { __typename?: 'AggregatedLedgerEntriesConnection', edges: Array<{ __typename?: 'AggregatedLedgerEntriesEdge', node: { __typename?: 'AggregatedLedgerEntries', vegaTime: string, quantity: string, partyId?: string | null, assetId?: string | null, marketId?: string | null, accountType?: Types.AccountType | null, transferType?: string | null } } | null> } };
|
||||
export type LedgerEntriesQuery = { __typename?: 'Query', ledgerEntries: { __typename?: 'AggregatedLedgerEntriesConnection', edges: Array<{ __typename?: 'AggregatedLedgerEntriesEdge', node: { __typename?: 'AggregatedLedgerEntry', vegaTime: any, quantity: string, assetId?: string | null, transferType?: Types.TransferType | null, receiverAccountType?: Types.AccountType | null, receiverMarketId?: string | null, receiverPartyId?: string | null, senderAccountType?: Types.AccountType | null, senderMarketId?: string | null, senderPartyId?: string | null } } | null>, pageInfo: { __typename?: 'PageInfo', startCursor: string, endCursor: string, hasNextPage: boolean, hasPreviousPage: boolean } } };
|
||||
|
||||
export const LedgerEntryFragmentDoc = gql`
|
||||
fragment LedgerEntry on AggregatedLedgerEntries {
|
||||
fragment LedgerEntry on AggregatedLedgerEntry {
|
||||
vegaTime
|
||||
quantity
|
||||
partyId
|
||||
assetId
|
||||
marketId
|
||||
accountType
|
||||
transferType
|
||||
receiverAccountType
|
||||
receiverMarketId
|
||||
receiverPartyId
|
||||
senderAccountType
|
||||
senderMarketId
|
||||
senderPartyId
|
||||
}
|
||||
`;
|
||||
export const LedgerEntriesDocument = gql`
|
||||
query LedgerEntries($partyId: ID!) {
|
||||
query LedgerEntries($partyId: ID!, $pagination: Pagination) {
|
||||
ledgerEntries(
|
||||
filter: {AccountFromFilter: {partyIds: [$partyId]}}
|
||||
groupOptions: {ByAccountField: [PartyId, AccountType, AssetId, MarketId], ByLedgerEntryField: [TransferType]}
|
||||
pagination: {first: 500}
|
||||
filter: {SenderAccountFilter: {partyIds: [$partyId]}, ReceiverAccountFilter: {partyIds: [$partyId]}}
|
||||
pagination: $pagination
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
...LedgerEntry
|
||||
}
|
||||
}
|
||||
pageInfo {
|
||||
startCursor
|
||||
endCursor
|
||||
hasNextPage
|
||||
hasPreviousPage
|
||||
}
|
||||
}
|
||||
}
|
||||
${LedgerEntryFragmentDoc}`;
|
||||
@@ -52,6 +61,7 @@ export const LedgerEntriesDocument = gql`
|
||||
* const { data, loading, error } = useLedgerEntriesQuery({
|
||||
* variables: {
|
||||
* partyId: // value for 'partyId'
|
||||
* pagination: // value for 'pagination'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,9 @@ import type { Asset } from '@vegaprotocol/assets';
|
||||
import { assetsProvider } from '@vegaprotocol/assets';
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
import { marketsProvider } from '@vegaprotocol/market-list';
|
||||
import type { PageInfo } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
defaultAppend as append,
|
||||
makeDataProvider,
|
||||
makeDerivedDataProvider,
|
||||
useDataProvider,
|
||||
@@ -17,20 +19,36 @@ import { LedgerEntriesDocument } from './__generated__/LedgerEntries';
|
||||
export type LedgerEntry = LedgerEntryFragment & {
|
||||
id: number;
|
||||
asset: Asset | null | undefined;
|
||||
market: Market | null | undefined;
|
||||
marketSender: Market | null | undefined;
|
||||
marketReceiver: Market | null | undefined;
|
||||
};
|
||||
|
||||
const getData = (responseData: LedgerEntriesQuery): LedgerEntry[] =>
|
||||
responseData.ledgerEntries?.edges
|
||||
?.filter((e) => Boolean(e?.node))
|
||||
.map((e, i) => ({ id: i, ...e?.node } as LedgerEntry)) ?? [];
|
||||
const getData = (responseData: LedgerEntriesQuery): LedgerEntry[] => {
|
||||
console.log('responseData', responseData);
|
||||
return (
|
||||
responseData.ledgerEntries?.edges
|
||||
?.filter((e) => Boolean(e?.node))
|
||||
.map((e, i) => ({ id: i, ...e?.node } as LedgerEntry)) ?? []
|
||||
);
|
||||
};
|
||||
|
||||
const getPageInfo = (responseData: LedgerEntriesQuery): PageInfo | null =>
|
||||
responseData.ledgerEntries?.pageInfo || null;
|
||||
|
||||
const ledgerEntriesOnlyProvider = makeDataProvider<
|
||||
LedgerEntriesQuery,
|
||||
LedgerEntry[] | null,
|
||||
never,
|
||||
never
|
||||
>({ query: LedgerEntriesDocument, getData });
|
||||
>({
|
||||
query: LedgerEntriesDocument,
|
||||
getData,
|
||||
pagination: {
|
||||
getPageInfo,
|
||||
append,
|
||||
first: 100,
|
||||
},
|
||||
});
|
||||
|
||||
export const ledgerEntriesProvider = makeDerivedDataProvider<
|
||||
LedgerEntry[],
|
||||
@@ -40,10 +58,13 @@ export const ledgerEntriesProvider = makeDerivedDataProvider<
|
||||
([entries, assets, markets]): LedgerEntry[] =>
|
||||
entries.map((entry: LedgerEntry) => {
|
||||
const asset = assets.find((asset: Asset) => asset.id === entry.assetId);
|
||||
const market = markets.find(
|
||||
(market: Market) => market.id === entry.marketId
|
||||
const marketSender = markets.find(
|
||||
(market: Market) => market.id === entry.senderMarketId
|
||||
);
|
||||
return { ...entry, asset, market };
|
||||
const marketReceiver = markets.find(
|
||||
(market: Market) => market.id === entry.receiverMarketId
|
||||
);
|
||||
return { ...entry, asset, marketSender, marketReceiver };
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { LedgerTable } from './ledger-table';
|
||||
// '3ac37999796c2be3546e0c1d87daa8ec7e99d8c423969be44c2f63256c415004'
|
||||
type LedgerManagerProps = { partyId: string };
|
||||
export const LedgerManager = ({ partyId }: LedgerManagerProps) => {
|
||||
console.log('partyId', partyId);
|
||||
const { data, error, loading } = useLedgerEntriesDataProvider(partyId);
|
||||
|
||||
return (
|
||||
|
||||
@@ -3,11 +3,15 @@ import {
|
||||
fromNanoSeconds,
|
||||
getDateTimeFormat,
|
||||
t,
|
||||
truncateByChars,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import type { VegaValueFormatterParams } from '@vegaprotocol/ui-toolkit';
|
||||
import type {
|
||||
VegaValueFormatterParams,
|
||||
VegaICellRendererParams,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit';
|
||||
import { AgGridColumn } from 'ag-grid-react';
|
||||
import type { Schema } from '@vegaprotocol/types';
|
||||
import type { Schema as Types } from '@vegaprotocol/types';
|
||||
import {
|
||||
AccountTypeMapping,
|
||||
DescriptionTransferTypeMapping,
|
||||
@@ -18,7 +22,7 @@ import type { LedgerEntry } from './ledger-entries-data-provider';
|
||||
export const TransferTooltipCellComponent = ({
|
||||
value,
|
||||
}: {
|
||||
value: Schema.TransferType;
|
||||
value: Types.TransferType;
|
||||
}) => {
|
||||
return (
|
||||
<p className="max-w-sm bg-neutral-200 px-4 py-2 z-20 rounded text-sm break-word text-black">
|
||||
@@ -27,11 +31,63 @@ export const TransferTooltipCellComponent = ({
|
||||
);
|
||||
};
|
||||
|
||||
type LedgerCellRendererProps = {
|
||||
accountType?: Types.AccountType | null;
|
||||
partyId?: string | null;
|
||||
marketName?: string;
|
||||
};
|
||||
|
||||
const LedgerCellRenderer = ({
|
||||
accountType,
|
||||
partyId,
|
||||
marketName,
|
||||
}: LedgerCellRendererProps) => {
|
||||
return (
|
||||
<div className="flex flex-col justify-around leading-5 h-full">
|
||||
<div
|
||||
className="flex"
|
||||
title={`${t('ID')}: ${truncateByChars(partyId || '-')}`}
|
||||
>
|
||||
{truncateByChars(partyId || '')}
|
||||
</div>
|
||||
<div
|
||||
className="flex"
|
||||
title={`${t('Account type')}: ${
|
||||
accountType ? AccountTypeMapping[accountType] : '-'
|
||||
}`}
|
||||
>
|
||||
{accountType && AccountTypeMapping[accountType]}
|
||||
</div>
|
||||
<div className="flex" title={`${t('Market')}: ${marketName || '-'}`}>
|
||||
{marketName}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
const SenderCellRenderer = ({ data }: VegaICellRendererParams<LedgerEntry>) => {
|
||||
const props = {
|
||||
accountType: data?.senderAccountType,
|
||||
partyId: data?.senderPartyId,
|
||||
marketName: data?.marketSender?.tradableInstrument?.instrument?.code,
|
||||
};
|
||||
return <LedgerCellRenderer {...props} />;
|
||||
};
|
||||
const ReceiverCellRenderer = ({
|
||||
data,
|
||||
}: VegaICellRendererParams<LedgerEntry>) => {
|
||||
const props = {
|
||||
accountType: data?.receiverAccountType,
|
||||
partyId: data?.receiverPartyId,
|
||||
marketName: data?.marketReceiver?.tradableInstrument?.instrument?.code,
|
||||
};
|
||||
return <LedgerCellRenderer {...props} />;
|
||||
};
|
||||
|
||||
export const LedgerTable = ({ ...props }) => (
|
||||
<AgGrid
|
||||
style={{ width: '100%', height: '100%' }}
|
||||
overlayNoRowsTemplate={t('No entries')}
|
||||
rowHeight={34}
|
||||
rowHeight={70}
|
||||
getRowId={({ data }) => data.id}
|
||||
tooltipShowDelay={500}
|
||||
defaultColDef={{
|
||||
@@ -43,13 +99,14 @@ export const LedgerTable = ({ ...props }) => (
|
||||
{...props}
|
||||
>
|
||||
<AgGridColumn
|
||||
headerName={t('Account Type')}
|
||||
field="accountType"
|
||||
valueFormatter={({
|
||||
value,
|
||||
}: VegaValueFormatterParams<LedgerEntry, 'accountType'>) =>
|
||||
value ? AccountTypeMapping[value] : ''
|
||||
}
|
||||
headerName={t('Sender')}
|
||||
field="senderAccountType"
|
||||
cellRenderer={SenderCellRenderer}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Receiver')}
|
||||
field="receiverAccountType"
|
||||
cellRenderer={ReceiverCellRenderer}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Transfer Type')}
|
||||
@@ -70,7 +127,7 @@ export const LedgerTable = ({ ...props }) => (
|
||||
value,
|
||||
data,
|
||||
}: VegaValueFormatterParams<LedgerEntry, 'quantity'>) => {
|
||||
const marketDecimalPlaces = data?.market?.decimalPlaces;
|
||||
const marketDecimalPlaces = data?.marketSender?.decimalPlaces;
|
||||
const assetDecimalPlaces = data?.asset?.decimals || 0;
|
||||
return value
|
||||
? addDecimalsFormatNumber(
|
||||
@@ -91,20 +148,11 @@ export const LedgerTable = ({ ...props }) => (
|
||||
data?.asset?.symbol || value
|
||||
}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Market')}
|
||||
field="marketId"
|
||||
valueFormatter={({
|
||||
data,
|
||||
}: VegaValueFormatterParams<LedgerEntry, 'market'>) =>
|
||||
data?.market?.tradableInstrument.instrument.code || '-'
|
||||
}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Vega Time')}
|
||||
field="vegaTime"
|
||||
valueFormatter={({ value }: { value: string }) =>
|
||||
getDateTimeFormat().format(fromNanoSeconds(value))
|
||||
valueFormatter={({ value }: { value?: string }) =>
|
||||
value ? getDateTimeFormat().format(fromNanoSeconds(value)) : '-'
|
||||
}
|
||||
filter="agDateColumnFilter"
|
||||
filterParams={{
|
||||
|
||||
+3
-3
@@ -10,14 +10,14 @@ export type MarketLpQueryVariables = Types.Exact<{
|
||||
|
||||
export type MarketLpQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', code: string, name: string, product: { __typename?: 'Future', settlementAsset: { __typename?: 'Asset', id: string, symbol: string, decimals: number } } } }, data?: { __typename?: 'MarketData', marketTradingMode: Types.MarketTradingMode, suppliedStake?: string | null, openInterest: string, targetStake?: string | null, trigger: Types.AuctionTrigger, marketValueProxy: string, market: { __typename?: 'Market', id: string } } | null } | null };
|
||||
|
||||
export type LiquidityProvisionFieldsFragment = { __typename?: 'LiquidityProvision', createdAt: string, updatedAt?: string | null, commitmentAmount: string, fee: string, status: Types.LiquidityProvisionStatus, party: { __typename?: 'Party', id: string, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string } } | null> | null } | null } };
|
||||
export type LiquidityProvisionFieldsFragment = { __typename?: 'LiquidityProvision', createdAt: any, updatedAt?: any | null, commitmentAmount: string, fee: string, status: Types.LiquidityProvisionStatus, party: { __typename?: 'Party', id: string, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string } } | null> | null } | null } };
|
||||
|
||||
export type LiquidityProvisionsQueryVariables = Types.Exact<{
|
||||
marketId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type LiquidityProvisionsQuery = { __typename?: 'Query', market?: { __typename?: 'Market', liquidityProvisionsConnection?: { __typename?: 'LiquidityProvisionsConnection', edges?: Array<{ __typename?: 'LiquidityProvisionsEdge', node: { __typename?: 'LiquidityProvision', createdAt: string, updatedAt?: string | null, commitmentAmount: string, fee: string, status: Types.LiquidityProvisionStatus, party: { __typename?: 'Party', id: string, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string } } | null> | null } | null } } } | null> | null } | null } | null };
|
||||
export type LiquidityProvisionsQuery = { __typename?: 'Query', market?: { __typename?: 'Market', liquidityProvisionsConnection?: { __typename?: 'LiquidityProvisionsConnection', edges?: Array<{ __typename?: 'LiquidityProvisionsEdge', node: { __typename?: 'LiquidityProvision', createdAt: any, updatedAt?: any | null, commitmentAmount: string, fee: string, status: Types.LiquidityProvisionStatus, party: { __typename?: 'Party', id: string, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string } } | null> | null } | null } } } | null> | null } | null } | null };
|
||||
|
||||
export type LiquidityProvisionsUpdateSubscriptionVariables = Types.Exact<{
|
||||
partyId?: Types.InputMaybe<Types.Scalars['ID']>;
|
||||
@@ -25,7 +25,7 @@ export type LiquidityProvisionsUpdateSubscriptionVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type LiquidityProvisionsUpdateSubscription = { __typename?: 'Subscription', liquidityProvisions?: Array<{ __typename?: 'LiquidityProvisionUpdate', id?: string | null, partyID: string, createdAt: string, updatedAt?: string | null, marketID: string, commitmentAmount: string, fee: string, status: Types.LiquidityProvisionStatus }> | null };
|
||||
export type LiquidityProvisionsUpdateSubscription = { __typename?: 'Subscription', liquidityProvisions?: Array<{ __typename?: 'LiquidityProvisionUpdate', id?: string | null, partyID: string, createdAt: any, updatedAt?: any | null, marketID: string, commitmentAmount: string, fee: string, status: Types.LiquidityProvisionStatus }> | null };
|
||||
|
||||
export type LiquidityProviderFeeShareFieldsFragment = { __typename?: 'LiquidityProviderFeeShare', equityLikeShare: string, averageEntryValuation: string, party: { __typename?: 'Party', id: string } };
|
||||
|
||||
|
||||
@@ -189,6 +189,11 @@ export const getLiquidityProvision = (
|
||||
const market = marketLiquidity?.market;
|
||||
const feeShare = liquidityFeeShare.find((f) => f.party.id === lp.party.id);
|
||||
if (!feeShare) return lp;
|
||||
const bondAccounts = accounts?.filter(
|
||||
(a) =>
|
||||
a?.type === Schema.AccountType.ACCOUNT_TYPE_BOND &&
|
||||
(!a.party?.id || a.party?.id === lp.party.id)
|
||||
);
|
||||
const lpData: LiquidityProvisionData = {
|
||||
...lp,
|
||||
averageEntryValuation: feeShare?.averageEntryValuation,
|
||||
@@ -196,8 +201,7 @@ export const getLiquidityProvision = (
|
||||
assetDecimalPlaces:
|
||||
market?.tradableInstrument.instrument.product.settlementAsset.decimals,
|
||||
balance:
|
||||
accounts
|
||||
?.filter((a) => a?.type === Schema.AccountType.ACCOUNT_TYPE_BOND)
|
||||
bondAccounts
|
||||
?.reduce(
|
||||
(acc, a) => acc.plus(new BigNumber(a.balance ?? 0)),
|
||||
new BigNumber(0)
|
||||
|
||||
@@ -31,6 +31,7 @@ import { marketInfoDataProvider } from './market-info-data-provider';
|
||||
import { TokenLinks } from '@vegaprotocol/react-helpers';
|
||||
|
||||
import type { MarketInfoQuery } from './__generated___/MarketInfo';
|
||||
import { MarketProposalNotification } from '@vegaprotocol/governance';
|
||||
|
||||
export interface InfoProps {
|
||||
market: MarketInfoQuery['market'];
|
||||
@@ -405,6 +406,7 @@ export const Info = ({ market, onSelect }: InfoProps) => {
|
||||
<Accordion panels={marketDataPanels} />
|
||||
</div>
|
||||
<div className="mb-8">
|
||||
<MarketProposalNotification marketId={market.id} />
|
||||
<p className={headerClassName}>{t('Market specification')}</p>
|
||||
<Accordion panels={marketSpecPanels} />
|
||||
</div>
|
||||
|
||||
@@ -25,7 +25,13 @@ export const PositionsManager = ({ partyId }: PositionsManagerProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
||||
<AsyncRenderer
|
||||
loading={loading}
|
||||
error={error}
|
||||
data={data}
|
||||
noDataMessage={t('No positions')}
|
||||
noDataCondition={(data) => !(data && data.length)}
|
||||
>
|
||||
<PositionsTable
|
||||
ref={gridRef}
|
||||
rowData={data}
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
import type { AgGridReact } from 'ag-grid-react';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { renderHook, waitFor } from '@testing-library/react';
|
||||
import { usePositionsData } from './use-positions-data';
|
||||
import type { Position } from './positions-data-providers';
|
||||
|
||||
let mockData: Position[] = [
|
||||
{
|
||||
marketName: 'M1',
|
||||
marketId: 'market-0',
|
||||
openVolume: '1',
|
||||
},
|
||||
{
|
||||
marketName: 'M2',
|
||||
marketId: 'market-1',
|
||||
openVolume: '-1985',
|
||||
},
|
||||
{
|
||||
marketName: 'M3',
|
||||
marketId: 'market-2',
|
||||
openVolume: '0',
|
||||
},
|
||||
{
|
||||
marketName: 'M4',
|
||||
marketId: 'market-3',
|
||||
openVolume: '0',
|
||||
},
|
||||
{
|
||||
marketName: 'M5',
|
||||
marketId: 'market-4',
|
||||
openVolume: '3',
|
||||
},
|
||||
] as Position[];
|
||||
|
||||
let mockDataProviderData = {
|
||||
data: mockData,
|
||||
error: undefined,
|
||||
loading: false,
|
||||
totalCount: undefined,
|
||||
};
|
||||
|
||||
let updateMock: jest.Mock;
|
||||
const mockDataProvider = jest.fn((args) => {
|
||||
updateMock = args.update;
|
||||
return mockDataProviderData;
|
||||
});
|
||||
jest.mock('@vegaprotocol/react-helpers', () => ({
|
||||
...jest.requireActual('@vegaprotocol/react-helpers'),
|
||||
useDataProvider: jest.fn((args) => mockDataProvider(args)),
|
||||
}));
|
||||
|
||||
describe('usePositionData Hook', () => {
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
const mockApplyTransactions = jest.fn();
|
||||
const mockApplyTransactionsAsync = jest.fn();
|
||||
const mockGetRowNode = jest
|
||||
.fn()
|
||||
.mockImplementation((id: string) =>
|
||||
mockData.find((position) => position.marketId === id)
|
||||
);
|
||||
const partyId = 'partyId';
|
||||
const aNewOne = {
|
||||
marketId: 'market-5',
|
||||
openVolume: '1',
|
||||
};
|
||||
const toRemoveOne = {
|
||||
marketId: 'market-0',
|
||||
openVolume: '0',
|
||||
};
|
||||
const anUpdatedOne = {
|
||||
marketId: 'market-1',
|
||||
openVolume: '1',
|
||||
};
|
||||
const gridRef = {
|
||||
current: {
|
||||
api: {
|
||||
applyTransaction: mockApplyTransactions,
|
||||
applyTransactionAsync: mockApplyTransactionsAsync,
|
||||
getRowNode: mockGetRowNode,
|
||||
},
|
||||
} as unknown as AgGridReact,
|
||||
};
|
||||
|
||||
it('should return proper data', async () => {
|
||||
const { result } = renderHook(() => usePositionsData(partyId, gridRef), {
|
||||
wrapper: MockedProvider,
|
||||
});
|
||||
expect(result.current.data?.length ?? 0).toEqual(3);
|
||||
});
|
||||
|
||||
it('should append by sync', async () => {
|
||||
renderHook(() => usePositionsData(partyId, gridRef), {
|
||||
wrapper: MockedProvider,
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
updateMock({ delta: [aNewOne, toRemoveOne, anUpdatedOne] as Position[] });
|
||||
});
|
||||
|
||||
expect(mockApplyTransactions).toHaveBeenCalledWith({
|
||||
update: [anUpdatedOne],
|
||||
add: [aNewOne],
|
||||
remove: [toRemoveOne],
|
||||
addIndex: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it('should append by async', async () => {
|
||||
renderHook(() => usePositionsData(partyId, gridRef), {
|
||||
wrapper: MockedProvider,
|
||||
});
|
||||
await waitFor(() => {
|
||||
updateMock({ delta: [anUpdatedOne] as Position[] });
|
||||
});
|
||||
|
||||
expect(mockApplyTransactionsAsync).toHaveBeenCalledWith({
|
||||
update: [anUpdatedOne],
|
||||
add: [],
|
||||
remove: [],
|
||||
addIndex: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it('no data should return null', () => {
|
||||
mockData = [];
|
||||
mockDataProviderData = {
|
||||
...mockDataProviderData,
|
||||
data: mockData,
|
||||
loading: false,
|
||||
};
|
||||
const { result } = renderHook(() => usePositionsData(partyId, gridRef), {
|
||||
wrapper: MockedProvider,
|
||||
});
|
||||
expect(result.current.data).toEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -29,6 +29,7 @@ export const usePositionsData = (
|
||||
|
||||
const update: Position[] = [];
|
||||
const add: Position[] = [];
|
||||
const remove: Position[] = [];
|
||||
if (!gridRef.current?.api) {
|
||||
return false;
|
||||
}
|
||||
@@ -37,18 +38,23 @@ export const usePositionsData = (
|
||||
getRowId({ data: position })
|
||||
);
|
||||
if (rowNode) {
|
||||
update.push(position);
|
||||
} else {
|
||||
if (position.openVolume === '0') {
|
||||
remove.push(position);
|
||||
} else {
|
||||
update.push(position);
|
||||
}
|
||||
} else if (position.openVolume !== '0') {
|
||||
add.push(position);
|
||||
}
|
||||
});
|
||||
if (update.length || add.length) {
|
||||
if (update.length || add.length || remove.length) {
|
||||
const rowDataTransaction = {
|
||||
update,
|
||||
add,
|
||||
remove,
|
||||
addIndex: 0,
|
||||
};
|
||||
if (add.length) {
|
||||
if (add.length || remove.length) {
|
||||
gridRef.current.api.applyTransaction(rowDataTransaction);
|
||||
} else {
|
||||
gridRef.current.api.applyTransactionAsync(rowDataTransaction);
|
||||
@@ -64,7 +70,7 @@ export const usePositionsData = (
|
||||
variables,
|
||||
});
|
||||
return {
|
||||
data,
|
||||
data: data?.filter((position) => position.openVolume !== '0'),
|
||||
error,
|
||||
loading,
|
||||
};
|
||||
|
||||
@@ -136,7 +136,15 @@ export const useDataProvider = <
|
||||
return unsubscribe();
|
||||
};
|
||||
}, [client, initialized, dataProvider, callback, variables, skip, update]);
|
||||
return { data, loading, error, flush, reload, load, totalCount };
|
||||
return {
|
||||
data,
|
||||
loading,
|
||||
error,
|
||||
flush,
|
||||
reload,
|
||||
load,
|
||||
totalCount,
|
||||
};
|
||||
};
|
||||
|
||||
export const useThrottledDataProvider = <Data, Delta>(
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { parseISO, isValid } from 'date-fns';
|
||||
|
||||
export const toNanoSeconds = (date: Date | string) => {
|
||||
return new Date(date).getTime().toString() + '000000';
|
||||
};
|
||||
|
||||
export const fromNanoSeconds = (ts: string) => {
|
||||
if (typeof ts !== 'string') return new Date(0);
|
||||
const validTs = ts.substring(0, ts.length - 6);
|
||||
return new Date(Number(validTs));
|
||||
const val = parseISO(ts);
|
||||
return new Date(isValid(val) ? val : 0);
|
||||
};
|
||||
|
||||
Generated
+117
-519
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
||||
import { Splash } from '../splash';
|
||||
import type { ReactNode } from 'react';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { isNotFoundGraphQLError } from '@vegaprotocol/apollo-client';
|
||||
|
||||
interface AsyncRendererProps<T> {
|
||||
loading: boolean;
|
||||
@@ -25,7 +26,7 @@ export function AsyncRenderer<T = object>({
|
||||
children,
|
||||
render,
|
||||
}: AsyncRendererProps<T>) {
|
||||
if (error) {
|
||||
if (error && !isNotFoundGraphQLError(error)) {
|
||||
return (
|
||||
<Splash>
|
||||
{errorMessage
|
||||
|
||||
@@ -38,3 +38,4 @@ export * from './vega-icons';
|
||||
export * from './vega-logo';
|
||||
export * from './traffic-light';
|
||||
export * from './toast';
|
||||
export * from './notification';
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from './notification';
|
||||
@@ -0,0 +1,57 @@
|
||||
import type { Meta, Story } from '@storybook/react';
|
||||
import { Intent } from '../../utils/intent';
|
||||
import { ExternalLink, Link } from '../link';
|
||||
import { Notification } from './notification';
|
||||
|
||||
export default {
|
||||
component: Notification,
|
||||
title: 'Notification',
|
||||
} as Meta;
|
||||
|
||||
const Template: Story = ({ intent, message, children }) => (
|
||||
<div className="flex">
|
||||
<Notification intent={intent} message={message}>
|
||||
{children}
|
||||
</Notification>
|
||||
</div>
|
||||
);
|
||||
|
||||
const props = {
|
||||
message: 'Exercitationem doloremque neque laborum incidunt consectetur amet',
|
||||
children: (
|
||||
<div className="flex space-x-1">
|
||||
<Link>Action</Link>
|
||||
<ExternalLink>External action</ExternalLink>
|
||||
</div>
|
||||
),
|
||||
};
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
...props,
|
||||
intent: Intent.None,
|
||||
};
|
||||
|
||||
export const Primary = Template.bind({});
|
||||
Primary.args = {
|
||||
...props,
|
||||
intent: Intent.Primary,
|
||||
};
|
||||
|
||||
export const Success = Template.bind({});
|
||||
Success.args = {
|
||||
...props,
|
||||
intent: Intent.Success,
|
||||
};
|
||||
|
||||
export const Warning = Template.bind({});
|
||||
Warning.args = {
|
||||
...props,
|
||||
intent: Intent.Warning,
|
||||
};
|
||||
|
||||
export const Danger = Template.bind({});
|
||||
Danger.args = {
|
||||
...props,
|
||||
intent: Intent.Danger,
|
||||
};
|
||||
@@ -0,0 +1,71 @@
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import type { IconName } from '@blueprintjs/icons';
|
||||
import classNames from 'classnames';
|
||||
import type { ReactNode } from 'react';
|
||||
import { Intent } from '../../utils/intent';
|
||||
import { Icon } from '../icon';
|
||||
|
||||
type NotificationProps = {
|
||||
intent: Intent;
|
||||
message: string;
|
||||
testId?: string;
|
||||
children?: ReactNode;
|
||||
};
|
||||
|
||||
const getIcon = (intent: Intent): IconName => {
|
||||
const mapping = {
|
||||
[Intent.None]: IconNames.HELP,
|
||||
[Intent.Primary]: IconNames.INFO_SIGN,
|
||||
[Intent.Success]: IconNames.TICK_CIRCLE,
|
||||
[Intent.Warning]: IconNames.WARNING_SIGN,
|
||||
[Intent.Danger]: IconNames.ERROR,
|
||||
};
|
||||
return mapping[intent] as IconName;
|
||||
};
|
||||
|
||||
export const Notification = ({
|
||||
intent,
|
||||
message,
|
||||
testId,
|
||||
children,
|
||||
}: NotificationProps) => {
|
||||
return (
|
||||
<div
|
||||
data-testid={testId || 'notification'}
|
||||
className={classNames(
|
||||
{
|
||||
'border-gray-700 dark:border-gray-300': intent === Intent.None,
|
||||
'border-vega-blue': intent === Intent.Primary,
|
||||
'border-vega-green-dark dark:border-vega-green':
|
||||
intent === Intent.Success,
|
||||
'border-yellow-500': intent === Intent.Warning,
|
||||
'border-vega-pink': intent === Intent.Danger,
|
||||
},
|
||||
'border rounded px-3 py-1 text-xs mb-1 mr-1'
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={classNames(
|
||||
{
|
||||
'text-gray-700 dark:text-gray-300': intent === Intent.None,
|
||||
'text-vega-blue': intent === Intent.Primary,
|
||||
'text-vega-green-dark dark:text-vega-green':
|
||||
intent === Intent.Success,
|
||||
'text-yellow-600 dark:text-yellow-500': intent === Intent.Warning,
|
||||
'text-vega-pink': intent === Intent.Danger,
|
||||
},
|
||||
'flex items-start'
|
||||
)}
|
||||
>
|
||||
<Icon size={3} className="mr-1 mt-[2px]" name={getIcon(intent)} />
|
||||
<span
|
||||
title={message}
|
||||
className="whitespace-nowrap overflow-hidden text-ellipsis"
|
||||
>
|
||||
{message}
|
||||
</span>
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -7,7 +7,7 @@ export interface SplashProps {
|
||||
|
||||
export const Splash = ({ children }: SplashProps) => {
|
||||
const splashClasses = classNames(
|
||||
'w-full h-full',
|
||||
'w-full h-full text-xs text-center text-gray-200',
|
||||
'flex items-center justify-center'
|
||||
);
|
||||
return <div className={splashClasses}>{children}</div>;
|
||||
|
||||
Reference in New Issue
Block a user