From 14dbd7bc2865ad2f3220a85d33e0aa1c8ebf02a6 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Tue, 27 Aug 2024 14:39:36 +0100 Subject: [PATCH 01/17] DeployLiquity2 demo mode: add stETH + more troves --- contracts/src/scripts/DeployLiquity2.s.sol | 99 +++++++++++++++++----- 1 file changed, 79 insertions(+), 20 deletions(-) diff --git a/contracts/src/scripts/DeployLiquity2.s.sol b/contracts/src/scripts/DeployLiquity2.s.sol index 329809b8..3ad80b93 100644 --- a/contracts/src/scripts/DeployLiquity2.s.sol +++ b/contracts/src/scripts/DeployLiquity2.s.sol @@ -26,6 +26,8 @@ import "../CollateralRegistry.sol"; import "../MockInterestRouter.sol"; import "../test/TestContracts/PriceFeedTestnet.sol"; import {WETHTester} from "../test/TestContracts/WETHTester.sol"; +import {Strings} from "openzeppelin-contracts/contracts/utils/Strings.sol"; +import "forge-std/console.sol"; contract DeployLiquity2Script is Script, StdCheats { bytes32 SALT; @@ -82,10 +84,12 @@ contract DeployLiquity2Script is Script, StdCheats { } struct DemoTroveParams { - uint256 coll; - uint256 debt; + uint256 collIndex; uint256 owner; uint256 ownerIndex; + uint256 coll; + uint256 debt; + uint256 annualInterestRate; } function run() external { @@ -102,9 +106,10 @@ contract DeployLiquity2Script is Script, StdCheats { vm.startBroadcast(privateKey); } - TroveManagerParams[] memory troveManagerParamsArray = new TroveManagerParams[](1); + TroveManagerParams[] memory troveManagerParamsArray = new TroveManagerParams[](2); - troveManagerParamsArray[0] = TroveManagerParams(150e16, 110e16, 110e16, 5e16, 10e16); + troveManagerParamsArray[0] = TroveManagerParams(150e16, 110e16, 110e16, 5e16, 10e16); // WETH + troveManagerParamsArray[1] = TroveManagerParams(150e16, 110e16, 110e16, 5e16, 10e16); // stETH // used for gas compensation and as collateral of the first branch IWETH WETH = new WETHTester( @@ -113,7 +118,6 @@ contract DeployLiquity2Script is Script, StdCheats { ); (LiquityContractsTestnet[] memory contractsArray,,,,) = _deployAndConnectContracts(troveManagerParamsArray, WETH); - LiquityContractsTestnet memory contracts = contractsArray[0]; vm.stopBroadcast(); if (vm.envOr("OPEN_DEMO_TROVES", false)) { @@ -129,35 +133,71 @@ contract DeployLiquity2Script is Script, StdCheats { demoAccounts[6] = 0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e; demoAccounts[7] = 0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356; - DemoTroveParams[] memory demoTroves = new DemoTroveParams[](4); - demoTroves[0] = DemoTroveParams({owner: demoAccounts[0], ownerIndex: 0, coll: 25e18, debt: 2800e18}); - demoTroves[1] = DemoTroveParams({owner: demoAccounts[1], ownerIndex: 0, coll: 37e18, debt: 2400e18}); - demoTroves[2] = DemoTroveParams({owner: demoAccounts[2], ownerIndex: 0, coll: 30e18, debt: 4000e18}); - demoTroves[3] = DemoTroveParams({owner: demoAccounts[3], ownerIndex: 0, coll: 65e18, debt: 6000e18}); + DemoTroveParams[] memory demoTroves = new DemoTroveParams[](16); + + demoTroves[0] = DemoTroveParams(0, demoAccounts[0], 0, 25e18, 2800e18, 5.0e16); + demoTroves[1] = DemoTroveParams(0, demoAccounts[1], 0, 37e18, 2400e18, 4.7e16); + demoTroves[2] = DemoTroveParams(0, demoAccounts[2], 0, 30e18, 4000e18, 3.3e16); + demoTroves[3] = DemoTroveParams(0, demoAccounts[3], 0, 65e18, 6000e18, 4.3e16); + + demoTroves[4] = DemoTroveParams(0, demoAccounts[4], 0, 19e18, 2280e18, 5.0e16); + demoTroves[5] = DemoTroveParams(0, demoAccounts[5], 0, 48.37e18, 4400e18, 4.7e16); + demoTroves[6] = DemoTroveParams(0, demoAccounts[6], 0, 33.92e18, 5500e18, 3.8e16); + demoTroves[7] = DemoTroveParams(0, demoAccounts[7], 0, 47.2e18, 6000e18, 4.3e16); - tapFaucet(demoAccounts, contracts); - openDemoTroves(demoTroves, contracts); + demoTroves[8] = DemoTroveParams(1, demoAccounts[0], 0, 21e18, 2000e18, 3.3e16); + demoTroves[9] = DemoTroveParams(1, demoAccounts[1], 1, 16e18, 2000e18, 4.1e16); + demoTroves[10] = DemoTroveParams(1, demoAccounts[2], 1, 18e18, 2300e18, 3.8e16); + demoTroves[11] = DemoTroveParams(1, demoAccounts[3], 1, 22e18, 2200e18, 4.3e16); + + demoTroves[12] = DemoTroveParams(1, demoAccounts[4], 1, 85e18, 12000e18, 7.0e16); + demoTroves[13] = DemoTroveParams(1, demoAccounts[5], 1, 87e18, 4000e18, 4.4e16); + demoTroves[14] = DemoTroveParams(1, demoAccounts[6], 1, 61e18, 11000e18, 3.3e16); + demoTroves[15] = DemoTroveParams(1, demoAccounts[7], 1, 84e18, 14800e18, 4.4e16); + + for (uint256 i = 0; i < contractsArray.length; i++) { + tapFaucet(demoAccounts, contractsArray[i]); + } + + openDemoTroves(demoTroves, contractsArray); } } function tapFaucet(uint256[] memory accounts, LiquityContractsTestnet memory contracts) internal { for (uint256 i = 0; i < accounts.length; i++) { + ERC20Faucet token = ERC20Faucet(address(contracts.collToken)); + vm.startBroadcast(accounts[i]); - ERC20Faucet(address(contracts.collToken)).tap(); + token.tap(); vm.stopBroadcast(); + + console.log( + "%s.tap() => %s (balance: %s)", + token.symbol(), + vm.addr(accounts[i]), + string.concat(formatAmount(token.balanceOf(vm.addr(accounts[i])), 18, 2), " ", token.symbol()) + ); } } - function openDemoTroves(DemoTroveParams[] memory troves, LiquityContractsTestnet memory contracts) internal { - for (uint256 i = 0; i < troves.length; i++) { - DemoTroveParams memory trove = troves[i]; + function openDemoTroves(DemoTroveParams[] memory demoTroves, LiquityContractsTestnet[] memory contractsArray) + internal + { + for (uint256 i = 0; i < demoTroves.length; i++) { + DemoTroveParams memory trove = demoTroves[i]; + LiquityContractsTestnet memory contracts = contractsArray[trove.collIndex]; vm.startBroadcast(trove.owner); - // Approve collToken to BorrowerOperations - IERC20(contracts.collToken).approve( - address(contracts.borrowerOperations), trove.coll + ETH_GAS_COMPENSATION - ); + IERC20 collToken = IERC20(contracts.collToken); + IERC20 wethToken = IERC20(contracts.addressesRegistry.WETH()); + + if (collToken == wethToken) { + wethToken.approve(address(contracts.borrowerOperations), trove.coll + ETH_GAS_COMPENSATION); + } else { + wethToken.approve(address(contracts.borrowerOperations), ETH_GAS_COMPENSATION); + collToken.approve(address(contracts.borrowerOperations), trove.coll); + } IBorrowerOperations(contracts.borrowerOperations).openTrove( vm.addr(trove.owner), // _owner @@ -360,4 +400,23 @@ contract DeployLiquity2Script is Script, StdCheats { address(contracts.activePool) ); } + + function formatAmount(uint256 amount, uint256 decimals, uint256 digits) internal pure returns (string memory) { + if (digits > decimals) { + digits = decimals; + } + + uint256 scaled = amount / (10 ** (decimals - digits)); + string memory whole = Strings.toString(scaled / (10 ** digits)); + + if (digits == 0) { + return whole; + } + + string memory fractional = Strings.toString(scaled % (10 ** digits)); + for (uint256 i = bytes(fractional).length; i < digits; i++) { + fractional = string.concat("0", fractional); + } + return string.concat(whole, ".", fractional); + } } From c84e538227cc948bac837fc9d684ed625c8e5d8e Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Tue, 27 Aug 2024 14:41:51 +0100 Subject: [PATCH 02/17] Contracts deploy script: fix debug mode output --- contracts/utils/deploy-cli.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/contracts/utils/deploy-cli.ts b/contracts/utils/deploy-cli.ts index 52cec718..379f92f0 100644 --- a/contracts/utils/deploy-cli.ts +++ b/contracts/utils/deploy-cli.ts @@ -174,12 +174,13 @@ Deploying Liquity contracts with the following settings: delete process.env.CI; } - // deploy - const deploymentOutput = await $`forge ${forgeArgs}`; if (options.debug) { - console.log(deploymentOutput.text()); + $.verbose = true; } + // deploy + await $`forge ${forgeArgs}`; + const deployedContracts = await getDeployedContracts( `broadcast/DeployLiquity2.s.sol/${options.chainId}/run-latest.json`, ); From 10b04c1a3491d2229f62f9fd06a26236c586c08c Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Tue, 27 Aug 2024 17:02:27 +0100 Subject: [PATCH 03/17] Subgraph MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See subgraph/README.md for instructions on how to deploy the subgraph locally. - Add subgraph/ to the workspaces. - A script, ./deploy-subgraph, can be used to deploy the subgraph in a convenient way. See --help for details. Some context: - The subgraph uses subgraph templates for the collateral contracts. - The script can update the collateral registry address in the subgraph.yaml if it doesn’t match the one found in the latest deployment context. - In ./deploy-subgraph, only the local preset is implemented. --- pnpm-lock.yaml | 39 +--- pnpm-workspace.yaml | 1 + subgraph/.gitignore | 3 + subgraph/README.md | 35 ++++ subgraph/cli/deploy.ts | 203 +++++++++++++++++++++ subgraph/deploy-subgraph | 8 + subgraph/docker-compose.yml | 49 +++++ subgraph/package.json | 13 ++ subgraph/schema.graphql | 48 +++++ subgraph/src/CollateralRegistry.mapping.ts | 61 +++++++ subgraph/src/TroveManager.mapping.ts | 80 ++++++++ subgraph/subgraph.yaml | 48 +++++ 12 files changed, 558 insertions(+), 30 deletions(-) create mode 100644 subgraph/.gitignore create mode 100644 subgraph/README.md create mode 100644 subgraph/cli/deploy.ts create mode 100755 subgraph/deploy-subgraph create mode 100644 subgraph/docker-compose.yml create mode 100644 subgraph/package.json create mode 100644 subgraph/schema.graphql create mode 100644 subgraph/src/CollateralRegistry.mapping.ts create mode 100644 subgraph/src/TroveManager.mapping.ts create mode 100644 subgraph/subgraph.yaml diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e67ce602..13e97e13 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -320,6 +320,15 @@ importers: '@graphprotocol/graph-ts': specifier: ^0.35.1 version: 0.35.1 + tsx: + specifier: ^4.16.5 + version: 4.16.5 + yaml: + specifier: ^2.5.0 + version: 2.5.0 + zx: + specifier: ^8.1.4 + version: 8.1.4 devDependencies: '@graphprotocol/graph-cli': specifier: ^0.80.0 @@ -2386,7 +2395,6 @@ packages: cpu: [ppc64] os: [aix] requiresBuild: true - dev: true optional: true /@esbuild/android-arm64@0.20.2: @@ -2403,7 +2411,6 @@ packages: cpu: [arm64] os: [android] requiresBuild: true - dev: true optional: true /@esbuild/android-arm@0.20.2: @@ -2420,7 +2427,6 @@ packages: cpu: [arm] os: [android] requiresBuild: true - dev: true optional: true /@esbuild/android-x64@0.20.2: @@ -2437,7 +2443,6 @@ packages: cpu: [x64] os: [android] requiresBuild: true - dev: true optional: true /@esbuild/darwin-arm64@0.20.2: @@ -2454,7 +2459,6 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true - dev: true optional: true /@esbuild/darwin-x64@0.20.2: @@ -2471,7 +2475,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: true optional: true /@esbuild/freebsd-arm64@0.20.2: @@ -2488,7 +2491,6 @@ packages: cpu: [arm64] os: [freebsd] requiresBuild: true - dev: true optional: true /@esbuild/freebsd-x64@0.20.2: @@ -2505,7 +2507,6 @@ packages: cpu: [x64] os: [freebsd] requiresBuild: true - dev: true optional: true /@esbuild/linux-arm64@0.20.2: @@ -2522,7 +2523,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-arm@0.20.2: @@ -2539,7 +2539,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-ia32@0.20.2: @@ -2556,7 +2555,6 @@ packages: cpu: [ia32] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-loong64@0.20.2: @@ -2573,7 +2571,6 @@ packages: cpu: [loong64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-mips64el@0.20.2: @@ -2590,7 +2587,6 @@ packages: cpu: [mips64el] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-ppc64@0.20.2: @@ -2607,7 +2603,6 @@ packages: cpu: [ppc64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-riscv64@0.20.2: @@ -2624,7 +2619,6 @@ packages: cpu: [riscv64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-s390x@0.20.2: @@ -2641,7 +2635,6 @@ packages: cpu: [s390x] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-x64@0.20.2: @@ -2658,7 +2651,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/netbsd-x64@0.20.2: @@ -2675,7 +2667,6 @@ packages: cpu: [x64] os: [netbsd] requiresBuild: true - dev: true optional: true /@esbuild/openbsd-x64@0.20.2: @@ -2692,7 +2683,6 @@ packages: cpu: [x64] os: [openbsd] requiresBuild: true - dev: true optional: true /@esbuild/sunos-x64@0.20.2: @@ -2709,7 +2699,6 @@ packages: cpu: [x64] os: [sunos] requiresBuild: true - dev: true optional: true /@esbuild/win32-arm64@0.20.2: @@ -2726,7 +2715,6 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true - dev: true optional: true /@esbuild/win32-ia32@0.20.2: @@ -2743,7 +2731,6 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true - dev: true optional: true /@esbuild/win32-x64@0.20.2: @@ -2760,7 +2747,6 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: true optional: true /@eslint-community/eslint-utils@4.4.0(eslint@8.57.0): @@ -6971,7 +6957,6 @@ packages: dependencies: '@types/jsonfile': 6.1.4 '@types/node': 22.0.2 - dev: true optional: true /@types/glob@7.2.0: @@ -7016,7 +7001,6 @@ packages: requiresBuild: true dependencies: '@types/node': 22.0.2 - dev: true optional: true /@types/keyv@3.1.4: @@ -10624,7 +10608,6 @@ packages: '@esbuild/win32-arm64': 0.21.5 '@esbuild/win32-ia32': 0.21.5 '@esbuild/win32-x64': 0.21.5 - dev: true /escalade@3.1.2: resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} @@ -11953,7 +11936,6 @@ packages: resolution: {integrity: sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==} dependencies: resolve-pkg-maps: 1.0.0 - dev: true /getpass@0.1.7: resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} @@ -16779,7 +16761,6 @@ packages: /resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - dev: true /resolve@1.1.7: resolution: {integrity: sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==} @@ -18339,7 +18320,6 @@ packages: get-tsconfig: 4.7.6 optionalDependencies: fsevents: 2.3.3 - dev: true /tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} @@ -20385,4 +20365,3 @@ packages: optionalDependencies: '@types/fs-extra': 11.0.4 '@types/node': 22.0.2 - dev: true diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 1ddecd45..49c356a8 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,3 +3,4 @@ packages: - './frontend/app' - './frontend/uikit' - './frontend/uikit-gallery' + - './subgraph' diff --git a/subgraph/.gitignore b/subgraph/.gitignore new file mode 100644 index 00000000..aec35498 --- /dev/null +++ b/subgraph/.gitignore @@ -0,0 +1,3 @@ +/data/ +/build/ +/generated/ diff --git a/subgraph/README.md b/subgraph/README.md new file mode 100644 index 00000000..d13a7264 --- /dev/null +++ b/subgraph/README.md @@ -0,0 +1,35 @@ +# Liquity v2 Subgraph + +## Run the subgraph locally + +```sh +# 1. Run anvil +anvil --host 0.0.0.0 --gas-limit 100000000000 --base-fee 1 --block-time 2 + +# 2. Deploy the contracts +cd contracts +./deploy-subgraph local --open-demo-troves + +# 3. Run the graph node +cd subgraph +docker-compose up + +# 4. Deploy the subgraph +cd subgraph +./deploy-subgraph local --version v1 --create +``` + +### Reset the subgraph state + +```sh +# 1. Stop docker-compose (Ctrl+C) + +# 2. Delete the data directory +rm -rf subgraph/data + +# 3. Start docker-compose again +docker-compose up + +# 4. Redeploy the subgraph +./deploy-subgraph local --version v1 --create +``` diff --git a/subgraph/cli/deploy.ts b/subgraph/cli/deploy.ts new file mode 100644 index 00000000..9492112b --- /dev/null +++ b/subgraph/cli/deploy.ts @@ -0,0 +1,203 @@ +import YAML from "yaml"; +import { $, echo, fs, minimist, path, question } from "zx"; + +const SUBGRAPH_PATH = path.join(__dirname, "../subgraph.yaml"); +const LATEST_DEPLOYMENT_CONTEXT_PATH = path.join(__dirname, "../../contracts/deployment-context-latest.json"); + +const HELP = ` +deploy - deploy the Liquity v2 subgraph + +Usage: + ./deploy [NETWORK_PRESET] [OPTIONS] + +Arguments: + NETWORK_PRESET A network preset, which is a shorthand for setting certain options. + Options take precedence over network presets. Available presets: + - local: Deploy to a local network + - mainnet: Deploy to the Ethereum mainnet (not implemented) + - liquity-testnet: Deploy to the Liquity v2 testnet (not implemented) + + +Options: + --create Create the subgraph before deploying. + --debug Show debug output. + --graph-node The Graph Node URL to use. + --help, -h Show this help message. + --ipfs-node The IPFS node URL to use. + --name The subgraph name to use. + --version The subgraph version to use. +`; + +const argv = minimist(process.argv.slice(2), { + alias: { + h: "help", + }, + boolean: [ + "create", + "debug", + "help", + ], + string: [ + "graph-node", + "ipfs-node", + "name", + "version", + ], +}); + +export async function main() { + const { networkPreset, options } = await parseArgs(); + + if (options.help) { + echo`${HELP}`; + process.exit(0); + } + + options.name ??= "liquity2/liquity2"; + + // network preset: local + if (networkPreset === "local") { + // pnpm graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 liquity/bold -l v1 + options.graphNode ??= "http://localhost:8020/"; + options.ipfsNode ??= "http://localhost:5001/"; + } + + // network preset: liquity-testnet + if (networkPreset === "liquity-testnet") { + // TODO: implement + } + + // network preset: mainnet + if (networkPreset === "mainnet") { + // TODO: implement + } + + // handle missing options + if (!options.graphNode) { + throw new Error("--graph-node is required"); + } + if (!options.name) { + throw new Error("--name is required"); + } + if (!options.version) { + throw new Error("--version is required"); + } + if (!options.ipfsNode) { + throw new Error("--ipfs-node is required"); + } + + const graphCreateCommand: null | string[] = !options.create ? null : [ + "graph", + "create", + "--node", + options.graphNode, + options.name, + ]; + + const graphDeployCommand: string[] = [ + "graph", + "deploy", + "--node", + options.graphNode, + "--ipfs", + options.ipfsNode, + options.name, + "--version-label", + options.version, + ]; + + await updateCollateralRegistryAddress(); + + echo` +Deploying subgraph: + + NAME: ${options.name} + VERSION: ${options.version} + GRAPH NODE: ${options.graphNode} + IPFS NODE: ${options.ipfsNode} + CREATE: ${options.create ? "yes" : "no"} + DEBUG: ${options.debug ? "yes" : "no"} +`; + + $.verbose = options.debug; + + if (graphCreateCommand) { + await $`pnpm ${graphCreateCommand}`; + } + + await $`pnpm ${graphDeployCommand}`; + + echo("Subgraph deployment complete."); + echo(""); +} + +async function parseArgs() { + const options = { + debug: argv["debug"], + help: argv["help"], + create: argv["create"], + graphNode: argv["graph-node"], + ipfsNode: argv["ipfs-node"], + name: argv["name"], + version: argv["version"], + }; + + const [networkPreset] = argv._; + + return { options, networkPreset }; +} + +async function updateCollateralRegistryAddress() { + const declaration = subgraphDeclaration(); + const latestDeploymentContext = getLatestDeploymentContext(); + + const latestCollateralRegistry = latestDeploymentContext?.deployedContracts.CollateralRegistry; + if (!latestCollateralRegistry || (declaration.collateralRegistry === latestCollateralRegistry)) { + return; + } + + console.log(""); + const answer = await question( + `New CollateralRegistry detected (${latestCollateralRegistry}). Update subgraph.yaml? [Y/n] `, + ); + + const confirmed = answer === "" || answer.toLowerCase() === "y" || answer.toLowerCase() === "yes"; + + if (!confirmed) { + return; + } + + declaration.updateCollateralRegistry(latestCollateralRegistry); + console.log(""); + console.log("Subgraph declaration updated with CollateralRegistry:", latestCollateralRegistry); +} + +function subgraphDeclaration() { + const declaration = YAML.parse(fs.readFileSync(SUBGRAPH_PATH, "utf8")); + const collateralRegistry = declaration.dataSources.find((ds: any) => ds.name === "CollateralRegistry"); + return { + collateralRegistry: collateralRegistry.source.address, + updateCollateralRegistry: (address: string) => { + const updatedDeclaration = { + ...declaration, + dataSources: declaration.dataSources.map((ds: any) => ( + ds.name === "CollateralRegistry" + ? { ...ds, source: { ...ds.source, address } } + : ds + )), + }; + fs.writeFileSync( + SUBGRAPH_PATH, + YAML.stringify(updatedDeclaration, { lineWidth: 120 }), + ); + }, + }; +} + +function getLatestDeploymentContext() { + try { + return JSON.parse(fs.readFileSync(LATEST_DEPLOYMENT_CONTEXT_PATH, "utf8")); + } catch (_) { + return null; + } +} diff --git a/subgraph/deploy-subgraph b/subgraph/deploy-subgraph new file mode 100755 index 00000000..5a049d93 --- /dev/null +++ b/subgraph/deploy-subgraph @@ -0,0 +1,8 @@ +#!/usr/bin/env -S pnpm exec tsx + +require("./cli/deploy").main().catch(({ message }) => { + console.error(""); + console.error(` Error: ${message}`); + console.error(""); + process.exit(1); +}); diff --git a/subgraph/docker-compose.yml b/subgraph/docker-compose.yml new file mode 100644 index 00000000..c356fdc4 --- /dev/null +++ b/subgraph/docker-compose.yml @@ -0,0 +1,49 @@ +services: + graph-node: + image: graphprotocol/graph-node + ports: + - '8000:8000' + - '8001:8001' + - '8020:8020' + - '8030:8030' + - '8040:8040' + depends_on: + - ipfs + - postgres + extra_hosts: + - host.docker.internal:host-gateway + environment: + postgres_host: postgres + postgres_user: graph-node + postgres_pass: let-me-in + postgres_db: graph-node + ipfs: 'ipfs:5001' + ethereum: 'mainnet:http://host.docker.internal:8545' + GRAPH_LOG: info + ipfs: + image: ipfs/kubo:v0.17.0 + ports: + - '5001:5001' + volumes: + - ./data/ipfs:/data/ipfs:Z + postgres: + image: postgres + ports: + - '5432:5432' + command: + [ + "postgres", + "-cshared_preload_libraries=pg_stat_statements", + "-cmax_connections=200" + ] + environment: + POSTGRES_USER: graph-node + POSTGRES_PASSWORD: let-me-in + POSTGRES_DB: graph-node + # FIXME: remove this env. var. which we shouldn't need. Introduced by + # , maybe as a + # workaround for https://github.com/docker/for-mac/issues/6270? + PGDATA: "/var/lib/postgresql/data" + POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C" + volumes: + - ./data/postgres:/var/lib/postgresql/data:Z diff --git a/subgraph/package.json b/subgraph/package.json new file mode 100644 index 00000000..17d08ffd --- /dev/null +++ b/subgraph/package.json @@ -0,0 +1,13 @@ +{ + "name": "@liquity2/subgraph", + "version": "1.0.0", + "devDependencies": { + "@graphprotocol/graph-cli": "^0.80.0" + }, + "dependencies": { + "@graphprotocol/graph-ts": "^0.35.1", + "tsx": "^4.16.5", + "yaml": "^2.5.0", + "zx": "^8.1.4" + } +} diff --git a/subgraph/schema.graphql b/subgraph/schema.graphql new file mode 100644 index 00000000..1d1000b0 --- /dev/null +++ b/subgraph/schema.graphql @@ -0,0 +1,48 @@ +type Collateral @entity { + id: ID! + token: Token! + minCollRatio: BigInt! + troves: [Trove!]! @derivedFrom(field: "collateral") + addresses: CollateralAddresses! @derivedFrom(field: "collateral") +} + +type Token @entity (immutable: true) { + id: ID! + collateral: Collateral! + name: String! + symbol: String! + decimals: Int! +} + +type CollateralAddresses @entity (immutable: true) { + id: ID! + collateral: Collateral! + activePool: Bytes! + borrowerOperations: Bytes! + defaultPool: Bytes! + priceFeed: Bytes! + sortedTroves: Bytes! + stabilityPool: Bytes! + token: Bytes! + troveManager: Bytes! +} + +type Trove @entity { + id: ID! + troveId: BigInt! + borrower: Bytes! + debt: BigInt! + coll: BigInt! + stake: BigInt! + annualInterestRate: BigInt! + createdAt: BigInt! + closedAt: BigInt + collateral: Collateral! +} + +type InterestRateBracket @entity { + id: ID! + rate: BigInt! + totalDebt: BigInt! + totalTroves: Int! +} diff --git a/subgraph/src/CollateralRegistry.mapping.ts b/subgraph/src/CollateralRegistry.mapping.ts new file mode 100644 index 00000000..5e48694d --- /dev/null +++ b/subgraph/src/CollateralRegistry.mapping.ts @@ -0,0 +1,61 @@ +import { Address, BigInt, Bytes, log } from "@graphprotocol/graph-ts"; +import { CollateralRegistry } from "../generated/CollateralRegistry/CollateralRegistry"; +import { BaseRateUpdated as BaseRateUpdatedEvent } from "../generated/CollateralRegistry/CollateralRegistry"; +import { ERC20 } from "../generated/CollateralRegistry/ERC20"; +import { Collateral, CollateralAddresses, Token } from "../generated/schema"; +import { TroveManager as TroveManagerTemplate } from "../generated/templates"; + +function addCollateral( + id: string, + tokenAddress: Address, + troveManagerAddress: Address, +): void { + let collateral = new Collateral(id); + collateral.token = id; + collateral.minCollRatio = BigInt.fromI32(0); + + let token = new Token(id); + let tokenContract = ERC20.bind(tokenAddress); + token.collateral = id; + token.name = tokenContract.name(); + token.symbol = tokenContract.symbol(); + token.decimals = tokenContract.decimals(); + + let addresses = new CollateralAddresses(id); + addresses.collateral = id; + addresses.activePool = Address.zero(); + addresses.borrowerOperations = Address.zero(); + addresses.defaultPool = Address.zero(); + addresses.priceFeed = Address.zero(); + addresses.sortedTroves = Address.zero(); + addresses.stabilityPool = Address.zero(); + addresses.token = tokenAddress; + addresses.troveManager = troveManagerAddress; + + collateral.save(); + addresses.save(); + token.save(); + + TroveManagerTemplate.create(troveManagerAddress); +} + +export function handleBaseRateUpdated(event: BaseRateUpdatedEvent): void { + let registry = CollateralRegistry.bind(event.address); + let colls = registry.totalCollaterals().toI32(); + + for (let i = 0; i < colls; i++) { + let tokenAddress: Address = Address.fromBytes(registry.getToken(BigInt.fromI32(i))); + let troveManagerAddress: Address = Address.fromBytes(registry.getTroveManager(BigInt.fromI32(i))); + + if (tokenAddress.toHex() === Address.zero().toHex() || troveManagerAddress.toHex() === Address.zero().toHex()) { + break; + } + + // we use the token address as the id for the collateral + let id = tokenAddress.toHexString(); + + if (!Collateral.load(id)) { + addCollateral(id, tokenAddress, troveManagerAddress); + } + } +} diff --git a/subgraph/src/TroveManager.mapping.ts b/subgraph/src/TroveManager.mapping.ts new file mode 100644 index 00000000..d8f1ae2a --- /dev/null +++ b/subgraph/src/TroveManager.mapping.ts @@ -0,0 +1,80 @@ +import { BigInt } from "@graphprotocol/graph-ts"; +import { InterestRateBracket, Trove } from "../generated/schema"; +import { + TroveOperation as TroveOperationEvent, + TroveUpdated as TroveUpdatedEvent, +} from "../generated/TroveManager/TroveManager"; + +// see Operation enum in +// contracts/src/Interfaces/ITroveEvents.sol +let OP_CLOSE_TROVE = 1; +// let OP_OPEN_TROVE = 0; +// let OP_ADJUST_TROVE = 2; +// let OP_ADJUST_TROVE_INTEREST_RATE = 3; +// let OP_APPLY_TROVE_INTEREST_PERMISSIONLESS = 4; +// let OP_LIQUIDATE = 5; +// let OP_REDEEM_COLLATERAL = 6; + +let _1e15 = BigInt.fromI32(10).pow(15); +let _1e16 = BigInt.fromI32(10).pow(16); + +export function handleTroveOperation(event: TroveOperationEvent): void { + let troveId = event.params._troveId.toHex(); + + let trove = new Trove(troveId); + if (trove === null) { + return; + } + + if (event.params._operation === OP_CLOSE_TROVE) { + trove.closedAt = event.block.timestamp; + trove.annualInterestRate = BigInt.fromI32(0); + trove.save(); + return; + } +} + +export function handleTroveUpdated(event: TroveUpdatedEvent): void { + let troveId = event.params._troveId.toHex(); + let trove = Trove.load(troveId); + + // previous & new rates, floored to the nearest 0.1% (rate brackets) + let prevRateFloored = trove ? trove.annualInterestRate.div(_1e15).times(_1e16) : null; + let rateFloored = event.params._annualInterestRate.div(_1e15).times(_1e16); + + if (!trove) { + trove = new Trove(troveId); + trove.troveId = event.params._troveId; + trove.createdAt = event.block.timestamp; + trove.borrower = event.transaction.from; + } + + // update interest rate brackets + if (!prevRateFloored || rateFloored.notEqual(prevRateFloored)) { + let prevRateBracket = prevRateFloored ? InterestRateBracket.load(prevRateFloored.toString()) : null; + if (prevRateBracket) { + prevRateBracket.totalDebt = prevRateBracket.totalDebt.minus(trove.debt); + prevRateBracket.totalTroves = prevRateBracket.totalTroves - 1; + prevRateBracket.save(); + } + + let rateBracket = InterestRateBracket.load(rateFloored.toString()); + if (!rateBracket) { + rateBracket = new InterestRateBracket(rateFloored.toString()); + rateBracket.rate = rateFloored; + rateBracket.totalDebt = BigInt.fromI32(0); + rateBracket.totalTroves = 0; + } + rateBracket.totalDebt = rateBracket.totalDebt.plus(event.params._debt); + rateBracket.totalTroves = rateBracket.totalTroves + 1; + rateBracket.save(); + } + + trove.debt = event.params._debt; + trove.coll = event.params._coll; + trove.stake = event.params._stake; + trove.annualInterestRate = event.params._annualInterestRate; + trove.collateral = "1"; + + trove.save(); +} diff --git a/subgraph/subgraph.yaml b/subgraph/subgraph.yaml new file mode 100644 index 00000000..86efa8fd --- /dev/null +++ b/subgraph/subgraph.yaml @@ -0,0 +1,48 @@ +specVersion: 1.2.0 +schema: + file: ./schema.graphql +dataSources: + - name: CollateralRegistry + kind: ethereum/contract + network: mainnet + source: + address: "0x5fc8d32690cc91d4c39d9d3abcbd16989f875707" + abi: CollateralRegistry + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + entities: + - Collateral + - CollateralAddresses + - Token + abis: + - name: CollateralRegistry + file: ../contracts/artifacts/src/CollateralRegistry.sol/CollateralRegistry.json + - name: ERC20 + file: ../contracts/artifacts/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol/ERC20.json + eventHandlers: + - event: BaseRateUpdated(uint256) + handler: handleBaseRateUpdated + file: ./src/CollateralRegistry.mapping.ts +templates: + - name: TroveManager + kind: ethereum/contract + network: mainnet + source: + abi: TroveManager + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + file: ./src/TroveManager.mapping.ts + entities: + - Trove + abis: + - name: TroveManager + file: ../contracts/artifacts/src/TroveManager.sol/TroveManager.json + eventHandlers: + - event: TroveOperation(indexed uint256,uint8,uint256,uint256,uint256,int256,uint256,int256) + handler: handleTroveOperation + - event: TroveUpdated(indexed uint256,uint256,uint256,uint256,uint256,uint256,uint256) + handler: handleTroveUpdated From 6c0d4b185ec195f9f27559d783de74739d3a0dce Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Tue, 27 Aug 2024 22:38:09 +0100 Subject: [PATCH 04/17] Remove comment --- subgraph/cli/deploy.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/subgraph/cli/deploy.ts b/subgraph/cli/deploy.ts index 9492112b..d1314bc8 100644 --- a/subgraph/cli/deploy.ts +++ b/subgraph/cli/deploy.ts @@ -57,7 +57,6 @@ export async function main() { // network preset: local if (networkPreset === "local") { - // pnpm graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 liquity/bold -l v1 options.graphNode ??= "http://localhost:8020/"; options.ipfsNode ??= "http://localhost:5001/"; } From 3d01fca99e242a624620435de4ab76a3ea5e5ed6 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Mon, 2 Sep 2024 13:11:10 +0100 Subject: [PATCH 05/17] Docker compose: move to volumes (+ add a cleanup script) --- subgraph/.gitignore | 1 - subgraph/docker-cleanup.sh | 21 +++++++++++++++++++++ subgraph/docker-compose.yml | 8 ++++++-- 3 files changed, 27 insertions(+), 3 deletions(-) create mode 100755 subgraph/docker-cleanup.sh diff --git a/subgraph/.gitignore b/subgraph/.gitignore index aec35498..52b33fb5 100644 --- a/subgraph/.gitignore +++ b/subgraph/.gitignore @@ -1,3 +1,2 @@ -/data/ /build/ /generated/ diff --git a/subgraph/docker-cleanup.sh b/subgraph/docker-cleanup.sh new file mode 100755 index 00000000..bedff77b --- /dev/null +++ b/subgraph/docker-cleanup.sh @@ -0,0 +1,21 @@ +#!/bin/env bash + +echo -n "Are you sure you want to remove all containers and volumes? [y/N] " +read -r response + +if [[ ! "$response" =~ ^[yY]$ ]]; then + echo "Aborted." + exit 1 +fi + +echo "" +echo "Stopping and removing containers..." +docker compose rm -fsv + +echo "" +echo "Removing volumes..." +docker volume rm subgraph_ipfs +docker volume rm subgraph_postgres + +echo "" +echo "Done." diff --git a/subgraph/docker-compose.yml b/subgraph/docker-compose.yml index c356fdc4..d1b2b833 100644 --- a/subgraph/docker-compose.yml +++ b/subgraph/docker-compose.yml @@ -25,7 +25,7 @@ services: ports: - '5001:5001' volumes: - - ./data/ipfs:/data/ipfs:Z + - ipfs:/data/ipfs postgres: image: postgres ports: @@ -46,4 +46,8 @@ services: PGDATA: "/var/lib/postgresql/data" POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C" volumes: - - ./data/postgres:/var/lib/postgresql/data:Z + - postgres:/var/lib/postgresql/data + +volumes: + postgres: + ipfs: From c829da4bcbe3fd798aff8be1bc98b3570a770d99 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Mon, 2 Sep 2024 13:12:07 +0100 Subject: [PATCH 06/17] DeployLiquity2: fix incorrect trove index --- contracts/src/scripts/DeployLiquity2.s.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/src/scripts/DeployLiquity2.s.sol b/contracts/src/scripts/DeployLiquity2.s.sol index e7a68664..7cf47421 100644 --- a/contracts/src/scripts/DeployLiquity2.s.sol +++ b/contracts/src/scripts/DeployLiquity2.s.sol @@ -147,7 +147,7 @@ contract DeployLiquity2Script is Script, StdCheats, MetadataDeployment { demoTroves[6] = DemoTroveParams(0, demoAccounts[6], 0, 33.92e18, 5500e18, 3.8e16); demoTroves[7] = DemoTroveParams(0, demoAccounts[7], 0, 47.2e18, 6000e18, 4.3e16); - demoTroves[8] = DemoTroveParams(1, demoAccounts[0], 0, 21e18, 2000e18, 3.3e16); + demoTroves[8] = DemoTroveParams(1, demoAccounts[0], 1, 21e18, 2000e18, 3.3e16); demoTroves[9] = DemoTroveParams(1, demoAccounts[1], 1, 16e18, 2000e18, 4.1e16); demoTroves[10] = DemoTroveParams(1, demoAccounts[2], 1, 18e18, 2300e18, 3.8e16); demoTroves[11] = DemoTroveParams(1, demoAccounts[3], 1, 22e18, 2200e18, 4.3e16); From 071536489573a4de8662de6b6b133767a43a0555 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Mon, 2 Sep 2024 13:14:00 +0100 Subject: [PATCH 07/17] Subgraph: various updates --- subgraph/schema.graphql | 5 +- subgraph/src/CollateralRegistry.mapping.ts | 8 ++- subgraph/src/TroveManager.mapping.ts | 63 ++++++++++++++-------- 3 files changed, 49 insertions(+), 27 deletions(-) diff --git a/subgraph/schema.graphql b/subgraph/schema.graphql index 1d1000b0..e40e0309 100644 --- a/subgraph/schema.graphql +++ b/subgraph/schema.graphql @@ -29,12 +29,11 @@ type CollateralAddresses @entity (immutable: true) { type Trove @entity { id: ID! - troveId: BigInt! borrower: Bytes! debt: BigInt! - coll: BigInt! + deposit: BigInt! stake: BigInt! - annualInterestRate: BigInt! + interestRate: BigInt! createdAt: BigInt! closedAt: BigInt collateral: Collateral! diff --git a/subgraph/src/CollateralRegistry.mapping.ts b/subgraph/src/CollateralRegistry.mapping.ts index 5e48694d..7ce3c5ce 100644 --- a/subgraph/src/CollateralRegistry.mapping.ts +++ b/subgraph/src/CollateralRegistry.mapping.ts @@ -1,4 +1,4 @@ -import { Address, BigInt, Bytes, log } from "@graphprotocol/graph-ts"; +import { Address, BigInt, Bytes, DataSourceContext } from "@graphprotocol/graph-ts"; import { CollateralRegistry } from "../generated/CollateralRegistry/CollateralRegistry"; import { BaseRateUpdated as BaseRateUpdatedEvent } from "../generated/CollateralRegistry/CollateralRegistry"; import { ERC20 } from "../generated/CollateralRegistry/ERC20"; @@ -36,7 +36,11 @@ function addCollateral( addresses.save(); token.save(); - TroveManagerTemplate.create(troveManagerAddress); + let context = new DataSourceContext(); + context.setBytes("tokenAddress", tokenAddress); + context.setBytes("troveManagerAddress", troveManagerAddress); + + TroveManagerTemplate.createWithContext(troveManagerAddress, context); } export function handleBaseRateUpdated(event: BaseRateUpdatedEvent): void { diff --git a/subgraph/src/TroveManager.mapping.ts b/subgraph/src/TroveManager.mapping.ts index d8f1ae2a..0d85d0e9 100644 --- a/subgraph/src/TroveManager.mapping.ts +++ b/subgraph/src/TroveManager.mapping.ts @@ -1,4 +1,4 @@ -import { BigInt } from "@graphprotocol/graph-ts"; +import { Address, BigInt, dataSource, log } from "@graphprotocol/graph-ts"; import { InterestRateBracket, Trove } from "../generated/schema"; import { TroveOperation as TroveOperationEvent, @@ -19,37 +19,60 @@ let _1e15 = BigInt.fromI32(10).pow(15); let _1e16 = BigInt.fromI32(10).pow(16); export function handleTroveOperation(event: TroveOperationEvent): void { - let troveId = event.params._troveId.toHex(); + let id = event.params._troveId.toHex(); + let trove = Trove.load(id); - let trove = new Trove(troveId); - if (trove === null) { + if (!trove) { return; } if (event.params._operation === OP_CLOSE_TROVE) { trove.closedAt = event.block.timestamp; - trove.annualInterestRate = BigInt.fromI32(0); + + // update rate bracket + let rateFloored = event.params._annualInterestRate.div(_1e15).times(_1e16); + let rateBracket = InterestRateBracket.load(rateFloored.toString()); + if (rateBracket) { + rateBracket.totalDebt = rateBracket.totalDebt.minus(trove.debt); + rateBracket.totalTroves = rateBracket.totalTroves - 1; + rateBracket.save(); + } + + trove.interestRate = BigInt.fromI32(0); trove.save(); return; } } +function loadOrCreateInterestRateBracket(rateFloored: BigInt): InterestRateBracket { + let rateBracket = InterestRateBracket.load(rateFloored.toString()); + if (!rateBracket) { + rateBracket = new InterestRateBracket(rateFloored.toString()); + rateBracket.rate = rateFloored; + rateBracket.totalDebt = BigInt.fromI32(0); + rateBracket.totalTroves = 0; + } + rateBracket.save(); + return rateBracket; +} + export function handleTroveUpdated(event: TroveUpdatedEvent): void { - let troveId = event.params._troveId.toHex(); - let trove = Trove.load(troveId); + let id = event.params._troveId.toHex(); + let trove = Trove.load(id); // previous & new rates, floored to the nearest 0.1% (rate brackets) - let prevRateFloored = trove ? trove.annualInterestRate.div(_1e15).times(_1e16) : null; + let prevRateFloored = trove ? trove.interestRate.div(_1e15).times(_1e16) : null; let rateFloored = event.params._annualInterestRate.div(_1e15).times(_1e16); + // create trove if it doesn't exist if (!trove) { - trove = new Trove(troveId); - trove.troveId = event.params._troveId; - trove.createdAt = event.block.timestamp; + trove = new Trove(id); trove.borrower = event.transaction.from; + trove.createdAt = event.block.timestamp; } // update interest rate brackets + let rateBracket = loadOrCreateInterestRateBracket(rateFloored); if (!prevRateFloored || rateFloored.notEqual(prevRateFloored)) { let prevRateBracket = prevRateFloored ? InterestRateBracket.load(prevRateFloored.toString()) : null; if (prevRateBracket) { @@ -58,23 +81,19 @@ export function handleTroveUpdated(event: TroveUpdatedEvent): void { prevRateBracket.save(); } - let rateBracket = InterestRateBracket.load(rateFloored.toString()); - if (!rateBracket) { - rateBracket = new InterestRateBracket(rateFloored.toString()); - rateBracket.rate = rateFloored; - rateBracket.totalDebt = BigInt.fromI32(0); - rateBracket.totalTroves = 0; - } rateBracket.totalDebt = rateBracket.totalDebt.plus(event.params._debt); rateBracket.totalTroves = rateBracket.totalTroves + 1; - rateBracket.save(); + } else { + rateBracket.totalDebt = rateBracket.totalDebt.minus(trove.debt).plus(event.params._debt); } + rateBracket.save(); + + trove.deposit = event.params._coll; trove.debt = event.params._debt; - trove.coll = event.params._coll; + trove.interestRate = event.params._annualInterestRate; + trove.collateral = dataSource.context().getBytes("tokenAddress").toHexString(); trove.stake = event.params._stake; - trove.annualInterestRate = event.params._annualInterestRate; - trove.collateral = "1"; trove.save(); } From c4aad580af775c1e23348c1ec2330994d62b6f4c Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Mon, 2 Sep 2024 13:14:22 +0100 Subject: [PATCH 08/17] Update README + add a codegen script --- subgraph/README.md | 2 +- subgraph/package.json | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/subgraph/README.md b/subgraph/README.md index d13a7264..e2309925 100644 --- a/subgraph/README.md +++ b/subgraph/README.md @@ -4,7 +4,7 @@ ```sh # 1. Run anvil -anvil --host 0.0.0.0 --gas-limit 100000000000 --base-fee 1 --block-time 2 +anvil --host 0.0.0.0 --gas-limit 100000000000 --base-fee 1 # 2. Deploy the contracts cd contracts diff --git a/subgraph/package.json b/subgraph/package.json index 17d08ffd..73d4baa9 100644 --- a/subgraph/package.json +++ b/subgraph/package.json @@ -1,6 +1,9 @@ { "name": "@liquity2/subgraph", "version": "1.0.0", + "scripts": { + "codegen": "pnpm graph codegen" + }, "devDependencies": { "@graphprotocol/graph-cli": "^0.80.0" }, From 5522079746b282c8f6bab182ee42f2b320af5220 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Wed, 4 Sep 2024 01:14:54 +0100 Subject: [PATCH 09/17] Instantiate TroveManager from BoldToken This allows to initiate things when `CollateralRegistryAddressChanged` gets emitted on BoldToken, which happens at the very end of the deployment process. Also: - Use troveNFT.ownerOf() to determinate the trove owner. - Update README instructions. --- subgraph/README.md | 13 +++- subgraph/cli/deploy.ts | 23 ++++--- subgraph/schema.graphql | 6 +- subgraph/src/BoldToken.mapping.ts | 72 ++++++++++++++++++++++ subgraph/src/CollateralRegistry.mapping.ts | 65 ------------------- subgraph/src/TroveManager.mapping.ts | 16 ++--- subgraph/subgraph.yaml | 24 +++++--- 7 files changed, 119 insertions(+), 100 deletions(-) create mode 100644 subgraph/src/BoldToken.mapping.ts delete mode 100644 subgraph/src/CollateralRegistry.mapping.ts diff --git a/subgraph/README.md b/subgraph/README.md index e2309925..e728d2a1 100644 --- a/subgraph/README.md +++ b/subgraph/README.md @@ -8,7 +8,9 @@ anvil --host 0.0.0.0 --gas-limit 100000000000 --base-fee 1 # 2. Deploy the contracts cd contracts -./deploy-subgraph local --open-demo-troves +./deploy-subgraph local +# or with demo troves: +# ./deploy-subgraph local --open-demo-troves # 3. Run the graph node cd subgraph @@ -16,6 +18,9 @@ docker-compose up # 4. Deploy the subgraph cd subgraph +# Note: this script detects if new versions of the contract it needs +# have been deployed, and will automatically update their addresses in the +# subgraph.yaml file (after confirmation). ./deploy-subgraph local --version v1 --create ``` @@ -24,12 +29,14 @@ cd subgraph ```sh # 1. Stop docker-compose (Ctrl+C) -# 2. Delete the data directory -rm -rf subgraph/data +# 2. Delete the docker volumes +./docker-cleanup.sh # 3. Start docker-compose again +cd subgraph docker-compose up # 4. Redeploy the subgraph +cd subgraph ./deploy-subgraph local --version v1 --create ``` diff --git a/subgraph/cli/deploy.ts b/subgraph/cli/deploy.ts index d1314bc8..4b8d9d3d 100644 --- a/subgraph/cli/deploy.ts +++ b/subgraph/cli/deploy.ts @@ -105,7 +105,7 @@ export async function main() { options.version, ]; - await updateCollateralRegistryAddress(); + await updateDeclarationWithLatestBoldToken(); echo` Deploying subgraph: @@ -146,18 +146,17 @@ async function parseArgs() { return { options, networkPreset }; } -async function updateCollateralRegistryAddress() { +async function updateDeclarationWithLatestBoldToken() { const declaration = subgraphDeclaration(); const latestDeploymentContext = getLatestDeploymentContext(); - const latestCollateralRegistry = latestDeploymentContext?.deployedContracts.CollateralRegistry; - if (!latestCollateralRegistry || (declaration.collateralRegistry === latestCollateralRegistry)) { + const deployedAddress = latestDeploymentContext?.deployedContracts.BoldToken; + if (!deployedAddress || (declaration.boldTokenAddress === deployedAddress)) { return; } - console.log(""); const answer = await question( - `New CollateralRegistry detected (${latestCollateralRegistry}). Update subgraph.yaml? [Y/n] `, + `\nNew BoldToken detected (${deployedAddress}). Update subgraph.yaml? [Y/n] `, ); const confirmed = answer === "" || answer.toLowerCase() === "y" || answer.toLowerCase() === "yes"; @@ -166,21 +165,21 @@ async function updateCollateralRegistryAddress() { return; } - declaration.updateCollateralRegistry(latestCollateralRegistry); + declaration.updateBoldTokenAddress(deployedAddress); console.log(""); - console.log("Subgraph declaration updated with CollateralRegistry:", latestCollateralRegistry); + console.log("Subgraph declaration updated with CollateralRegistry:", deployedAddress); } function subgraphDeclaration() { const declaration = YAML.parse(fs.readFileSync(SUBGRAPH_PATH, "utf8")); - const collateralRegistry = declaration.dataSources.find((ds: any) => ds.name === "CollateralRegistry"); + const boldToken = declaration.dataSources.find((ds: any) => ds.name === "BoldToken"); return { - collateralRegistry: collateralRegistry.source.address, - updateCollateralRegistry: (address: string) => { + boldTokenAddress: boldToken.source.address, + updateBoldTokenAddress: (address: string) => { const updatedDeclaration = { ...declaration, dataSources: declaration.dataSources.map((ds: any) => ( - ds.name === "CollateralRegistry" + ds.name === "BoldToken" ? { ...ds, source: { ...ds.source, address } } : ds )), diff --git a/subgraph/schema.graphql b/subgraph/schema.graphql index e40e0309..1334b713 100644 --- a/subgraph/schema.graphql +++ b/subgraph/schema.graphql @@ -16,15 +16,13 @@ type Token @entity (immutable: true) { type CollateralAddresses @entity (immutable: true) { id: ID! - collateral: Collateral! - activePool: Bytes! borrowerOperations: Bytes! - defaultPool: Bytes! - priceFeed: Bytes! + collateral: Collateral! sortedTroves: Bytes! stabilityPool: Bytes! token: Bytes! troveManager: Bytes! + troveNft: Bytes! } type Trove @entity { diff --git a/subgraph/src/BoldToken.mapping.ts b/subgraph/src/BoldToken.mapping.ts new file mode 100644 index 00000000..d9b39009 --- /dev/null +++ b/subgraph/src/BoldToken.mapping.ts @@ -0,0 +1,72 @@ +import { Address, BigInt, Bytes, DataSourceContext, log } from "@graphprotocol/graph-ts"; +import { + CollateralRegistryAddressChanged as CollateralRegistryAddressChangedEvent, +} from "../generated/BoldToken/BoldToken"; +import { CollateralRegistry } from "../generated/BoldToken/CollateralRegistry"; +import { ERC20 } from "../generated/BoldToken/ERC20"; +import { TroveManager } from "../generated/BoldToken/TroveManager"; +import { Collateral, CollateralAddresses, Token } from "../generated/schema"; +import { TroveManager as TroveManagerTemplate } from "../generated/templates"; + +function addCollateral( + id: string, + tokenAddress: Address, + troveManagerAddress: Address, +): void { + let collateral = new Collateral(id); + collateral.token = id; + collateral.minCollRatio = BigInt.fromI32(0); + + let token = new Token(id); + let tokenContract = ERC20.bind(tokenAddress); + token.collateral = id; + token.name = tokenContract.name(); + token.symbol = tokenContract.symbol(); + token.decimals = tokenContract.decimals(); + + let troveManager = TroveManager.bind(troveManagerAddress); + + let addresses = new CollateralAddresses(id); + addresses.collateral = id; + addresses.borrowerOperations = troveManager.borrowerOperations(); + addresses.sortedTroves = troveManager.sortedTroves(); + addresses.stabilityPool = troveManager.stabilityPool(); + addresses.token = tokenAddress; + addresses.troveManager = troveManagerAddress; + addresses.troveNft = troveManager.troveNFT(); + + collateral.save(); + addresses.save(); + token.save(); + + let context = new DataSourceContext(); + context.setBytes("address:borrowerOperations", addresses.borrowerOperations); + context.setBytes("address:sortedTroves", addresses.sortedTroves); + context.setBytes("address:stabilityPool", addresses.stabilityPool); + context.setBytes("address:token", addresses.token); + context.setBytes("address:troveManager", addresses.troveManager); + context.setBytes("address:troveNft", addresses.troveNft); + + TroveManagerTemplate.createWithContext(troveManagerAddress, context); +} + +export function handleCollateralRegistryAddressChanged(event: CollateralRegistryAddressChangedEvent): void { + let registry = CollateralRegistry.bind(event.params._newCollateralRegistryAddress); + let colls = registry.totalCollaterals().toI32(); + + for (let i = 0; i < colls; i++) { + let tokenAddress = Address.fromBytes(registry.getToken(BigInt.fromI32(i))); + let troveManagerAddress = Address.fromBytes(registry.getTroveManager(BigInt.fromI32(i))); + + if (tokenAddress.toHex() === Address.zero().toHex() || troveManagerAddress.toHex() === Address.zero().toHex()) { + break; + } + + // we use the token address as the id for the collateral + let id = tokenAddress.toHexString(); + + if (!Collateral.load(id)) { + addCollateral(id, tokenAddress, troveManagerAddress); + } + } +} diff --git a/subgraph/src/CollateralRegistry.mapping.ts b/subgraph/src/CollateralRegistry.mapping.ts deleted file mode 100644 index 7ce3c5ce..00000000 --- a/subgraph/src/CollateralRegistry.mapping.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Address, BigInt, Bytes, DataSourceContext } from "@graphprotocol/graph-ts"; -import { CollateralRegistry } from "../generated/CollateralRegistry/CollateralRegistry"; -import { BaseRateUpdated as BaseRateUpdatedEvent } from "../generated/CollateralRegistry/CollateralRegistry"; -import { ERC20 } from "../generated/CollateralRegistry/ERC20"; -import { Collateral, CollateralAddresses, Token } from "../generated/schema"; -import { TroveManager as TroveManagerTemplate } from "../generated/templates"; - -function addCollateral( - id: string, - tokenAddress: Address, - troveManagerAddress: Address, -): void { - let collateral = new Collateral(id); - collateral.token = id; - collateral.minCollRatio = BigInt.fromI32(0); - - let token = new Token(id); - let tokenContract = ERC20.bind(tokenAddress); - token.collateral = id; - token.name = tokenContract.name(); - token.symbol = tokenContract.symbol(); - token.decimals = tokenContract.decimals(); - - let addresses = new CollateralAddresses(id); - addresses.collateral = id; - addresses.activePool = Address.zero(); - addresses.borrowerOperations = Address.zero(); - addresses.defaultPool = Address.zero(); - addresses.priceFeed = Address.zero(); - addresses.sortedTroves = Address.zero(); - addresses.stabilityPool = Address.zero(); - addresses.token = tokenAddress; - addresses.troveManager = troveManagerAddress; - - collateral.save(); - addresses.save(); - token.save(); - - let context = new DataSourceContext(); - context.setBytes("tokenAddress", tokenAddress); - context.setBytes("troveManagerAddress", troveManagerAddress); - - TroveManagerTemplate.createWithContext(troveManagerAddress, context); -} - -export function handleBaseRateUpdated(event: BaseRateUpdatedEvent): void { - let registry = CollateralRegistry.bind(event.address); - let colls = registry.totalCollaterals().toI32(); - - for (let i = 0; i < colls; i++) { - let tokenAddress: Address = Address.fromBytes(registry.getToken(BigInt.fromI32(i))); - let troveManagerAddress: Address = Address.fromBytes(registry.getTroveManager(BigInt.fromI32(i))); - - if (tokenAddress.toHex() === Address.zero().toHex() || troveManagerAddress.toHex() === Address.zero().toHex()) { - break; - } - - // we use the token address as the id for the collateral - let id = tokenAddress.toHexString(); - - if (!Collateral.load(id)) { - addCollateral(id, tokenAddress, troveManagerAddress); - } - } -} diff --git a/subgraph/src/TroveManager.mapping.ts b/subgraph/src/TroveManager.mapping.ts index 0d85d0e9..7a602339 100644 --- a/subgraph/src/TroveManager.mapping.ts +++ b/subgraph/src/TroveManager.mapping.ts @@ -1,5 +1,6 @@ import { Address, BigInt, dataSource, log } from "@graphprotocol/graph-ts"; import { InterestRateBracket, Trove } from "../generated/schema"; +import { TroveNFT } from "../generated/templates/TroveManager/TroveNFT"; import { TroveOperation as TroveOperationEvent, TroveUpdated as TroveUpdatedEvent, @@ -19,8 +20,8 @@ let _1e15 = BigInt.fromI32(10).pow(15); let _1e16 = BigInt.fromI32(10).pow(16); export function handleTroveOperation(event: TroveOperationEvent): void { - let id = event.params._troveId.toHex(); - let trove = Trove.load(id); + let id = event.params._troveId; + let trove = Trove.load(id.toHex()); if (!trove) { return; @@ -57,8 +58,9 @@ function loadOrCreateInterestRateBracket(rateFloored: BigInt): InterestRateBrack } export function handleTroveUpdated(event: TroveUpdatedEvent): void { - let id = event.params._troveId.toHex(); - let trove = Trove.load(id); + let id = event.params._troveId; + let trove = Trove.load(id.toHex()); + let context = dataSource.context(); // previous & new rates, floored to the nearest 0.1% (rate brackets) let prevRateFloored = trove ? trove.interestRate.div(_1e15).times(_1e16) : null; @@ -66,8 +68,8 @@ export function handleTroveUpdated(event: TroveUpdatedEvent): void { // create trove if it doesn't exist if (!trove) { - trove = new Trove(id); - trove.borrower = event.transaction.from; + trove = new Trove(id.toHex()); + trove.borrower = TroveNFT.bind(Address.fromBytes(context.getBytes("address:troveNft"))).ownerOf(id); trove.createdAt = event.block.timestamp; } @@ -92,7 +94,7 @@ export function handleTroveUpdated(event: TroveUpdatedEvent): void { trove.deposit = event.params._coll; trove.debt = event.params._debt; trove.interestRate = event.params._annualInterestRate; - trove.collateral = dataSource.context().getBytes("tokenAddress").toHexString(); + trove.collateral = context.getBytes("address:token").toHexString(); trove.stake = event.params._stake; trove.save(); diff --git a/subgraph/subgraph.yaml b/subgraph/subgraph.yaml index 86efa8fd..2733ddb4 100644 --- a/subgraph/subgraph.yaml +++ b/subgraph/subgraph.yaml @@ -2,12 +2,12 @@ specVersion: 1.2.0 schema: file: ./schema.graphql dataSources: - - name: CollateralRegistry + - name: BoldToken kind: ethereum/contract network: mainnet source: - address: "0x5fc8d32690cc91d4c39d9d3abcbd16989f875707" - abi: CollateralRegistry + address: "0x5df37c979d7da88687a90ab73fe3cf809de674d9" + abi: BoldToken mapping: kind: ethereum/events apiVersion: 0.0.9 @@ -17,14 +17,18 @@ dataSources: - CollateralAddresses - Token abis: + - name: BoldToken + file: ../contracts/out/BoldToken.sol/BoldToken.json - name: CollateralRegistry - file: ../contracts/artifacts/src/CollateralRegistry.sol/CollateralRegistry.json + file: ../contracts/out/CollateralRegistry.sol/CollateralRegistry.json - name: ERC20 - file: ../contracts/artifacts/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol/ERC20.json + file: ../contracts/out/ERC20.sol/ERC20.json + - name: TroveManager + file: ../contracts/out/TroveManager.sol/TroveManager.json eventHandlers: - - event: BaseRateUpdated(uint256) - handler: handleBaseRateUpdated - file: ./src/CollateralRegistry.mapping.ts + - event: CollateralRegistryAddressChanged(address) + handler: handleCollateralRegistryAddressChanged + file: ./src/BoldToken.mapping.ts templates: - name: TroveManager kind: ethereum/contract @@ -40,7 +44,9 @@ templates: - Trove abis: - name: TroveManager - file: ../contracts/artifacts/src/TroveManager.sol/TroveManager.json + file: ../contracts/out/TroveManager.sol/TroveManager.json + - name: TroveNFT + file: ../contracts/out/TroveNFT.sol/TroveNFT.json eventHandlers: - event: TroveOperation(indexed uint256,uint8,uint256,uint256,uint256,int256,uint256,int256) handler: handleTroveOperation From 308e622834c461084e0619f37f77c991b568e846 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Wed, 4 Sep 2024 02:03:14 +0100 Subject: [PATCH 10/17] DeployLiquity2: set interest rate from the demo troves --- contracts/src/scripts/DeployLiquity2.s.sol | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/contracts/src/scripts/DeployLiquity2.s.sol b/contracts/src/scripts/DeployLiquity2.s.sol index 7cf47421..16d81a0c 100644 --- a/contracts/src/scripts/DeployLiquity2.s.sol +++ b/contracts/src/scripts/DeployLiquity2.s.sol @@ -203,17 +203,17 @@ contract DeployLiquity2Script is Script, StdCheats, MetadataDeployment { } IBorrowerOperations(contracts.borrowerOperations).openTrove( - vm.addr(trove.owner), // _owner - trove.ownerIndex, // _ownerIndex - trove.coll, // _collAmount - trove.debt, // _boldAmount - 0, // _upperHint - 0, // _lowerHint - 0.05e18, // _annualInterestRate - type(uint256).max, // _maxUpfrontFee - address(0), // _addManager - address(0), // _removeManager - address(0) // _receiver + vm.addr(trove.owner), // _owner + trove.ownerIndex, // _ownerIndex + trove.coll, // _collAmount + trove.debt, // _boldAmount + 0, // _upperHint + 0, // _lowerHint + trove.annualInterestRate, // _annualInterestRate + type(uint256).max, // _maxUpfrontFee + address(0), // _addManager + address(0), // _removeManager + address(0) // _receiver ); vm.stopBroadcast(); From 043d61033ca23b4baa0ac66ced11754b6d9776bc Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Wed, 4 Sep 2024 02:04:42 +0100 Subject: [PATCH 11/17] Subgraph: preserve the magnitude when flooring the rates --- subgraph/src/TroveManager.mapping.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/subgraph/src/TroveManager.mapping.ts b/subgraph/src/TroveManager.mapping.ts index 7a602339..6f2876b7 100644 --- a/subgraph/src/TroveManager.mapping.ts +++ b/subgraph/src/TroveManager.mapping.ts @@ -1,4 +1,4 @@ -import { Address, BigInt, dataSource, log } from "@graphprotocol/graph-ts"; +import { Address, BigInt, dataSource } from "@graphprotocol/graph-ts"; import { InterestRateBracket, Trove } from "../generated/schema"; import { TroveNFT } from "../generated/templates/TroveManager/TroveNFT"; import { @@ -16,8 +16,10 @@ let OP_CLOSE_TROVE = 1; // let OP_LIQUIDATE = 5; // let OP_REDEEM_COLLATERAL = 6; -let _1e15 = BigInt.fromI32(10).pow(15); -let _1e16 = BigInt.fromI32(10).pow(16); +function floorToDecimals(value: BigInt, decimals: u8): BigInt { + let factor = BigInt.fromI32(10).pow(18 - decimals); + return value.div(factor).times(factor); +} export function handleTroveOperation(event: TroveOperationEvent): void { let id = event.params._troveId; @@ -31,7 +33,7 @@ export function handleTroveOperation(event: TroveOperationEvent): void { trove.closedAt = event.block.timestamp; // update rate bracket - let rateFloored = event.params._annualInterestRate.div(_1e15).times(_1e16); + let rateFloored = floorToDecimals(event.params._annualInterestRate, 3); let rateBracket = InterestRateBracket.load(rateFloored.toString()); if (rateBracket) { rateBracket.totalDebt = rateBracket.totalDebt.minus(trove.debt); @@ -63,8 +65,8 @@ export function handleTroveUpdated(event: TroveUpdatedEvent): void { let context = dataSource.context(); // previous & new rates, floored to the nearest 0.1% (rate brackets) - let prevRateFloored = trove ? trove.interestRate.div(_1e15).times(_1e16) : null; - let rateFloored = event.params._annualInterestRate.div(_1e15).times(_1e16); + let prevRateFloored = trove ? floorToDecimals(trove.interestRate, 3) : null; + let rateFloored = floorToDecimals(event.params._annualInterestRate, 3); // create trove if it doesn't exist if (!trove) { From b6770bcd2c005895bb399f15403bbef5a4600d58 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Wed, 4 Sep 2024 11:06:11 +0100 Subject: [PATCH 12/17] Update default BoldToken address --- subgraph/subgraph.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subgraph/subgraph.yaml b/subgraph/subgraph.yaml index 2733ddb4..a07d7bc9 100644 --- a/subgraph/subgraph.yaml +++ b/subgraph/subgraph.yaml @@ -6,7 +6,7 @@ dataSources: kind: ethereum/contract network: mainnet source: - address: "0x5df37c979d7da88687a90ab73fe3cf809de674d9" + address: "0x13c9af280ae9147de75639e86a2d399116b9c608" abi: BoldToken mapping: kind: ethereum/events From 4352c72f7a35f05d07f58b8dd5f0bf6c5e867829 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Tue, 10 Sep 2024 16:23:44 +0100 Subject: [PATCH 13/17] Subgraph: update scripts - Add ./start-graph - Remove ./docker-cleanup.sh (replaced by ./start-graph --reset) - Rename ./deploy to ./deploy-subgraph for clarity - Update README with new instructions --- subgraph/README.md | 27 ++------ .../cli/{deploy.ts => deploy-subgraph.ts} | 6 +- subgraph/cli/start-graph.ts | 66 +++++++++++++++++++ subgraph/deploy-subgraph | 2 +- subgraph/docker-cleanup.sh | 21 ------ subgraph/start-graph | 8 +++ 6 files changed, 84 insertions(+), 46 deletions(-) rename subgraph/cli/{deploy.ts => deploy-subgraph.ts} (97%) create mode 100644 subgraph/cli/start-graph.ts delete mode 100755 subgraph/docker-cleanup.sh create mode 100755 subgraph/start-graph diff --git a/subgraph/README.md b/subgraph/README.md index e728d2a1..893370ed 100644 --- a/subgraph/README.md +++ b/subgraph/README.md @@ -8,13 +8,15 @@ anvil --host 0.0.0.0 --gas-limit 100000000000 --base-fee 1 # 2. Deploy the contracts cd contracts -./deploy-subgraph local -# or with demo troves: -# ./deploy-subgraph local --open-demo-troves +./deploy local +# use --open-demo-troves to start with some demo data: +# ./deploy local --open-demo-troves # 3. Run the graph node cd subgraph -docker-compose up +./start-graph +# use --reset to clear the state: +# ./start-graph --reset # 4. Deploy the subgraph cd subgraph @@ -23,20 +25,3 @@ cd subgraph # subgraph.yaml file (after confirmation). ./deploy-subgraph local --version v1 --create ``` - -### Reset the subgraph state - -```sh -# 1. Stop docker-compose (Ctrl+C) - -# 2. Delete the docker volumes -./docker-cleanup.sh - -# 3. Start docker-compose again -cd subgraph -docker-compose up - -# 4. Redeploy the subgraph -cd subgraph -./deploy-subgraph local --version v1 --create -``` diff --git a/subgraph/cli/deploy.ts b/subgraph/cli/deploy-subgraph.ts similarity index 97% rename from subgraph/cli/deploy.ts rename to subgraph/cli/deploy-subgraph.ts index 4b8d9d3d..384fe25b 100644 --- a/subgraph/cli/deploy.ts +++ b/subgraph/cli/deploy-subgraph.ts @@ -5,10 +5,10 @@ const SUBGRAPH_PATH = path.join(__dirname, "../subgraph.yaml"); const LATEST_DEPLOYMENT_CONTEXT_PATH = path.join(__dirname, "../../contracts/deployment-context-latest.json"); const HELP = ` -deploy - deploy the Liquity v2 subgraph +deploy-subgraph - deploy the Liquity v2 subgraph Usage: - ./deploy [NETWORK_PRESET] [OPTIONS] + ./deploy-subgraph [NETWORK_PRESET] [OPTIONS] Arguments: NETWORK_PRESET A network preset, which is a shorthand for setting certain options. @@ -150,7 +150,7 @@ async function updateDeclarationWithLatestBoldToken() { const declaration = subgraphDeclaration(); const latestDeploymentContext = getLatestDeploymentContext(); - const deployedAddress = latestDeploymentContext?.deployedContracts.BoldToken; + const deployedAddress = latestDeploymentContext?.protocolContracts.BoldToken; if (!deployedAddress || (declaration.boldTokenAddress === deployedAddress)) { return; } diff --git a/subgraph/cli/start-graph.ts b/subgraph/cli/start-graph.ts new file mode 100644 index 00000000..c4b35596 --- /dev/null +++ b/subgraph/cli/start-graph.ts @@ -0,0 +1,66 @@ +import { $, echo, minimist, question } from "zx"; + +const HELP = ` +start-graph - start a Graph Node + +Usage: + ./start-graph [OPTIONS] + +Options: + --reset Remove all containers and volumes. + --help, -h Show this help message. +`; + +const argv = minimist(process.argv.slice(2), { + alias: { + h: "help", + }, + boolean: [ + "reset", + "help", + ], +}); + +async function resetCheck() { + if (argv.reset) { + return true; + } + const response = ( + await question("Do you want to remove all containers and volumes? [y/N] ") + ).toLowerCase(); + return response === "y" || response === "yes"; +} + +export async function main() { + if (argv.help) { + echo`${HELP}`; + process.exit(0); + } + + $.verbose = true; + + if (await resetCheck()) { + echo``; + echo`Stopping and removing containers…`; + echo``; + await $`docker compose rm -fsv`; + + echo``; + echo`Removing volumes…`; + echo``; + await $`docker volume rm subgraph_ipfs`; + await $`docker volume rm subgraph_postgres`; + } + + echo``; + echo`Starting Graph Node…`; + + // TODO: handle SIGINT + // process.on("SIGINT", async () => { + // echo`Caught interrupt signal. Shutting down containers…`; + // await $`docker compose down`; + // process.exit(); + // }); + + await $`docker compose up`; +} diff --git a/subgraph/deploy-subgraph b/subgraph/deploy-subgraph index 5a049d93..03a77a12 100755 --- a/subgraph/deploy-subgraph +++ b/subgraph/deploy-subgraph @@ -1,6 +1,6 @@ #!/usr/bin/env -S pnpm exec tsx -require("./cli/deploy").main().catch(({ message }) => { +require("./cli/deploy-subgraph").main().catch(({ message }) => { console.error(""); console.error(` Error: ${message}`); console.error(""); diff --git a/subgraph/docker-cleanup.sh b/subgraph/docker-cleanup.sh deleted file mode 100755 index bedff77b..00000000 --- a/subgraph/docker-cleanup.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/env bash - -echo -n "Are you sure you want to remove all containers and volumes? [y/N] " -read -r response - -if [[ ! "$response" =~ ^[yY]$ ]]; then - echo "Aborted." - exit 1 -fi - -echo "" -echo "Stopping and removing containers..." -docker compose rm -fsv - -echo "" -echo "Removing volumes..." -docker volume rm subgraph_ipfs -docker volume rm subgraph_postgres - -echo "" -echo "Done." diff --git a/subgraph/start-graph b/subgraph/start-graph new file mode 100755 index 00000000..03dbcb96 --- /dev/null +++ b/subgraph/start-graph @@ -0,0 +1,8 @@ +#!/usr/bin/env -S pnpm exec tsx + +require("./cli/start-graph").main().catch(({ message }) => { + console.error(""); + console.error(` Error: ${message}`); + console.error(""); + process.exit(1); +}); From 6d00b9c62428c4ea728facc8bd2b1b2c4fbd63db Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Thu, 12 Sep 2024 01:23:15 +0100 Subject: [PATCH 14/17] Collateral: add totalDeposited, totalDebt, minCollRatio --- subgraph/schema.graphql | 3 +++ subgraph/src/BoldToken.mapping.ts | 8 ++++++-- subgraph/src/TroveManager.mapping.ts | 20 +++++++++++++++++++- subgraph/subgraph.yaml | 4 +++- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/subgraph/schema.graphql b/subgraph/schema.graphql index 1334b713..f66d0644 100644 --- a/subgraph/schema.graphql +++ b/subgraph/schema.graphql @@ -4,6 +4,8 @@ type Collateral @entity { minCollRatio: BigInt! troves: [Trove!]! @derivedFrom(field: "collateral") addresses: CollateralAddresses! @derivedFrom(field: "collateral") + totalDeposited: BigInt! + totalDebt: BigInt! } type Token @entity (immutable: true) { @@ -43,3 +45,4 @@ type InterestRateBracket @entity { totalDebt: BigInt! totalTroves: Int! } + diff --git a/subgraph/src/BoldToken.mapping.ts b/subgraph/src/BoldToken.mapping.ts index d9b39009..a475733a 100644 --- a/subgraph/src/BoldToken.mapping.ts +++ b/subgraph/src/BoldToken.mapping.ts @@ -1,7 +1,8 @@ -import { Address, BigInt, Bytes, DataSourceContext, log } from "@graphprotocol/graph-ts"; +import { Address, BigInt, DataSourceContext } from "@graphprotocol/graph-ts"; import { CollateralRegistryAddressChanged as CollateralRegistryAddressChangedEvent, } from "../generated/BoldToken/BoldToken"; +import { BorrowerOperations } from "../generated/BoldToken/BorrowerOperations"; import { CollateralRegistry } from "../generated/BoldToken/CollateralRegistry"; import { ERC20 } from "../generated/BoldToken/ERC20"; import { TroveManager } from "../generated/BoldToken/TroveManager"; @@ -15,7 +16,8 @@ function addCollateral( ): void { let collateral = new Collateral(id); collateral.token = id; - collateral.minCollRatio = BigInt.fromI32(0); + collateral.totalDebt = BigInt.fromI32(0); + collateral.totalDeposited = BigInt.fromI32(0); let token = new Token(id); let tokenContract = ERC20.bind(tokenAddress); @@ -35,6 +37,8 @@ function addCollateral( addresses.troveManager = troveManagerAddress; addresses.troveNft = troveManager.troveNFT(); + collateral.minCollRatio = BorrowerOperations.bind(Address.fromBytes(addresses.borrowerOperations)).MCR(); + collateral.save(); addresses.save(); token.save(); diff --git a/subgraph/src/TroveManager.mapping.ts b/subgraph/src/TroveManager.mapping.ts index 6f2876b7..b80269df 100644 --- a/subgraph/src/TroveManager.mapping.ts +++ b/subgraph/src/TroveManager.mapping.ts @@ -1,5 +1,5 @@ import { Address, BigInt, dataSource } from "@graphprotocol/graph-ts"; -import { InterestRateBracket, Trove } from "../generated/schema"; +import { Collateral, InterestRateBracket, Trove } from "../generated/schema"; import { TroveNFT } from "../generated/templates/TroveManager/TroveNFT"; import { TroveOperation as TroveOperationEvent, @@ -68,6 +68,24 @@ export function handleTroveUpdated(event: TroveUpdatedEvent): void { let prevRateFloored = trove ? floorToDecimals(trove.interestRate, 3) : null; let rateFloored = floorToDecimals(event.params._annualInterestRate, 3); + let prevDeposit = trove ? trove.deposit : BigInt.fromI32(0); + let deposit = event.params._coll; + + let prevDebt = trove ? trove.debt : BigInt.fromI32(0); + let debt = event.params._debt; + + let collId = context.getBytes("address:token").toHexString(); + let collateral = Collateral.load(collId); + + // should never happen + if (!collateral) { + return; + } + + collateral.totalDeposited = collateral.totalDeposited.minus(prevDeposit).plus(deposit); + collateral.totalDebt = collateral.totalDebt.minus(prevDebt).plus(debt); + collateral.save(); + // create trove if it doesn't exist if (!trove) { trove = new Trove(id.toHex()); diff --git a/subgraph/subgraph.yaml b/subgraph/subgraph.yaml index a07d7bc9..95279d3a 100644 --- a/subgraph/subgraph.yaml +++ b/subgraph/subgraph.yaml @@ -6,7 +6,7 @@ dataSources: kind: ethereum/contract network: mainnet source: - address: "0x13c9af280ae9147de75639e86a2d399116b9c608" + address: "0x2705179df91e93d2be0f3b56454002f52e27ef87" abi: BoldToken mapping: kind: ethereum/events @@ -17,6 +17,8 @@ dataSources: - CollateralAddresses - Token abis: + - name: BorrowerOperations + file: ../contracts/out/BorrowerOperations.sol/BorrowerOperations.json - name: BoldToken file: ../contracts/out/BoldToken.sol/BoldToken.json - name: CollateralRegistry From 50b21f4c03e53ec93f32995b8a50be0b8f6aca74 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Fri, 13 Sep 2024 00:27:45 +0100 Subject: [PATCH 15/17] Syntax --- subgraph/schema.graphql | 19 +++++++++---------- subgraph/src/BoldToken.mapping.ts | 8 +++----- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/subgraph/schema.graphql b/subgraph/schema.graphql index f66d0644..64c029cd 100644 --- a/subgraph/schema.graphql +++ b/subgraph/schema.graphql @@ -8,7 +8,7 @@ type Collateral @entity { totalDebt: BigInt! } -type Token @entity (immutable: true) { +type Token @entity(immutable: true) { id: ID! collateral: Collateral! name: String! @@ -16,7 +16,7 @@ type Token @entity (immutable: true) { decimals: Int! } -type CollateralAddresses @entity (immutable: true) { +type CollateralAddresses @entity(immutable: true) { id: ID! borrowerOperations: Bytes! collateral: Collateral! @@ -27,6 +27,13 @@ type CollateralAddresses @entity (immutable: true) { troveNft: Bytes! } +type InterestRateBracket @entity { + id: ID! + rate: BigInt! + totalDebt: BigInt! + totalTroves: Int! +} + type Trove @entity { id: ID! borrower: Bytes! @@ -38,11 +45,3 @@ type Trove @entity { closedAt: BigInt collateral: Collateral! } - -type InterestRateBracket @entity { - id: ID! - rate: BigInt! - totalDebt: BigInt! - totalTroves: Int! -} - diff --git a/subgraph/src/BoldToken.mapping.ts b/subgraph/src/BoldToken.mapping.ts index a475733a..a5184be8 100644 --- a/subgraph/src/BoldToken.mapping.ts +++ b/subgraph/src/BoldToken.mapping.ts @@ -10,10 +10,10 @@ import { Collateral, CollateralAddresses, Token } from "../generated/schema"; import { TroveManager as TroveManagerTemplate } from "../generated/templates"; function addCollateral( - id: string, tokenAddress: Address, troveManagerAddress: Address, ): void { + let id = tokenAddress.toHexString(); let collateral = new Collateral(id); collateral.token = id; collateral.totalDebt = BigInt.fromI32(0); @@ -67,10 +67,8 @@ export function handleCollateralRegistryAddressChanged(event: CollateralRegistry } // we use the token address as the id for the collateral - let id = tokenAddress.toHexString(); - - if (!Collateral.load(id)) { - addCollateral(id, tokenAddress, troveManagerAddress); + if (!Collateral.load(tokenAddress.toHexString())) { + addCollateral(tokenAddress, troveManagerAddress); } } } From ea5c78c377b03178e5fe73081dd0b61c09e5c99a Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Fri, 13 Sep 2024 00:28:10 +0100 Subject: [PATCH 16/17] dprint: add graphql --- dprint.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dprint.json b/dprint.json index 24a51e8f..942a12c2 100644 --- a/dprint.json +++ b/dprint.json @@ -5,7 +5,7 @@ "json": {}, "markdown": {}, "toml": {}, - "includes": ["**/*.{ts,tsx,js,jsx,mjs,json,md,html,css}"], + "includes": ["**/*.{ts,tsx,js,jsx,mjs,json,md,html,css,graphql}"], "excludes": [ "**/node_modules", "**/*-lock.json", @@ -20,6 +20,7 @@ "https://plugins.dprint.dev/json-0.19.2.wasm", "https://plugins.dprint.dev/markdown-0.16.4.wasm", "https://plugins.dprint.dev/toml-0.6.1.wasm", - "https://plugins.dprint.dev/g-plane/malva-v0.1.5.wasm" + "https://plugins.dprint.dev/g-plane/malva-v0.1.5.wasm", + "https://plugins.dprint.dev/g-plane/pretty_graphql-v0.2.0.wasm" ] } From c6224eecace6fa6c51ee4872a1a22a2e168a62b0 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Fri, 13 Sep 2024 00:34:21 +0100 Subject: [PATCH 17/17] App: fetch loans from the subgraph --- frontend/app/.graphclient/index.ts | 1370 +++ .../.graphclient/persisted_operations.json | 3 + frontend/app/.graphclient/schema.graphql | 856 ++ .../sources/liquity2/introspectionSchema.ts | 10096 ++++++++++++++++ .../sources/liquity2/schema.graphql | 856 ++ .../.graphclient/sources/liquity2/types.ts | 856 ++ frontend/app/.graphclientrc.yml | 20 + frontend/app/package.json | 4 +- .../app/src/comps/AppLayout/AppLayout.tsx | 9 + frontend/app/src/comps/Debug/UpdatePrices.tsx | 2 +- .../InterestRateField/InterestRateField.tsx | 30 +- frontend/app/src/comps/Position/Position.tsx | 303 - .../app/src/comps/Positions/Positions.tsx | 166 +- .../src/comps/ProtocolStats/ProtocolStats.tsx | 222 +- frontend/app/src/demo-mode/demo-data.ts | 6 +- frontend/app/src/dnum-utils.ts | 4 + frontend/app/src/liquity-utils.ts | 23 +- .../src/screens/BorrowScreen/BorrowScreen.tsx | 6 +- .../screens/EarnPoolScreen/EarnPoolScreen.tsx | 17 +- .../screens/HomeScreen/HomeProtocolStats.tsx | 63 - .../app/src/screens/HomeScreen/HomeScreen.tsx | 8 - .../screens/LeverageScreen/LeverageScreen.tsx | 6 +- .../app/src/screens/LoanScreen/LoanCard.tsx | 513 + .../app/src/screens/LoanScreen/LoanScreen.tsx | 217 +- frontend/app/src/services/Prices.tsx | 3 +- frontend/app/src/subgraph-hooks.ts | 94 + frontend/app/src/subgraph-queries.graphql | 41 + frontend/app/src/types.ts | 10 +- frontend/uikit/src/tokens.ts | 4 + 29 files changed, 15120 insertions(+), 688 deletions(-) create mode 100644 frontend/app/.graphclient/index.ts create mode 100644 frontend/app/.graphclient/persisted_operations.json create mode 100644 frontend/app/.graphclient/schema.graphql create mode 100644 frontend/app/.graphclient/sources/liquity2/introspectionSchema.ts create mode 100644 frontend/app/.graphclient/sources/liquity2/schema.graphql create mode 100644 frontend/app/.graphclient/sources/liquity2/types.ts create mode 100644 frontend/app/.graphclientrc.yml delete mode 100644 frontend/app/src/comps/Position/Position.tsx create mode 100644 frontend/app/src/screens/LoanScreen/LoanCard.tsx create mode 100644 frontend/app/src/subgraph-hooks.ts create mode 100644 frontend/app/src/subgraph-queries.graphql diff --git a/frontend/app/.graphclient/index.ts b/frontend/app/.graphclient/index.ts new file mode 100644 index 00000000..87fe6975 --- /dev/null +++ b/frontend/app/.graphclient/index.ts @@ -0,0 +1,1370 @@ +// @ts-nocheck +import { GraphQLResolveInfo, SelectionSetNode, FieldNode, GraphQLScalarType, GraphQLScalarTypeConfig } from 'graphql'; +import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; +import { gql } from '@graphql-mesh/utils'; + +import type { GetMeshOptions } from '@graphql-mesh/runtime'; +import type { YamlConfig } from '@graphql-mesh/types'; +import { PubSub } from '@graphql-mesh/utils'; +import { DefaultLogger } from '@graphql-mesh/utils'; +import MeshCache from "@graphql-mesh/cache-localforage"; +import { fetch as fetchFn } from '@whatwg-node/fetch'; + +import { MeshResolvedSource } from '@graphql-mesh/runtime'; +import { MeshTransform, MeshPlugin } from '@graphql-mesh/types'; +import GraphqlHandler from "@graphql-mesh/graphql" +import BareMerger from "@graphql-mesh/merger-bare"; +import { printWithCache } from '@graphql-mesh/utils'; +import { usePersistedOperations } from '@graphql-yoga/plugin-persisted-operations'; +import { createMeshHTTPHandler, MeshHTTPHandler } from '@graphql-mesh/http'; +import { getMesh, ExecuteMeshFn, SubscribeMeshFn, MeshContext as BaseMeshContext, MeshInstance } from '@graphql-mesh/runtime'; +import { MeshStore, FsStoreStorageAdapter } from '@graphql-mesh/store'; +import { path as pathModule } from '@graphql-mesh/cross-helpers'; +import { ImportFn } from '@graphql-mesh/types'; +import type { Liquity2Types } from './sources/liquity2/types'; +import * as importedModule$0 from "./sources/liquity2/introspectionSchema"; +export type Maybe = T | null; +export type InputMaybe = Maybe; +export type Exact = { [K in keyof T]: T[K] }; +export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; +export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; +export type MakeEmpty = { [_ in K]?: never }; +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; +export type RequireFields = Omit & { [P in K]-?: NonNullable }; + + + +/** All built-in and custom scalars, mapped to their actual values */ +export type Scalars = { + ID: { input: string; output: string; } + String: { input: string; output: string; } + Boolean: { input: boolean; output: boolean; } + Int: { input: number; output: number; } + Float: { input: number; output: number; } + BigDecimal: { input: bigint; output: bigint; } + BigInt: { input: bigint; output: bigint; } + Bytes: { input: string; output: string; } + Int8: { input: number; output: number; } + Timestamp: { input: string; output: string; } +}; + +export type Aggregation_interval = + | 'hour' + | 'day'; + +export type BlockChangedFilter = { + readonly number_gte: Scalars['Int']['input']; +}; + +export type Block_height = { + readonly hash?: InputMaybe; + readonly number?: InputMaybe; + readonly number_gte?: InputMaybe; +}; + +export type Collateral = { + readonly id: Scalars['ID']['output']; + readonly token: Token; + readonly minCollRatio: Scalars['BigInt']['output']; + readonly troves: ReadonlyArray; + readonly addresses: CollateralAddresses; + readonly totalDeposited: Scalars['BigInt']['output']; + readonly totalDebt: Scalars['BigInt']['output']; +}; + + +export type CollateraltrovesArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; +}; + +export type CollateralAddresses = { + readonly id: Scalars['ID']['output']; + readonly borrowerOperations: Scalars['Bytes']['output']; + readonly collateral: Collateral; + readonly sortedTroves: Scalars['Bytes']['output']; + readonly stabilityPool: Scalars['Bytes']['output']; + readonly token: Scalars['Bytes']['output']; + readonly troveManager: Scalars['Bytes']['output']; + readonly troveNft: Scalars['Bytes']['output']; +}; + +export type CollateralAddresses_filter = { + readonly id?: InputMaybe; + readonly id_not?: InputMaybe; + readonly id_gt?: InputMaybe; + readonly id_lt?: InputMaybe; + readonly id_gte?: InputMaybe; + readonly id_lte?: InputMaybe; + readonly id_in?: InputMaybe>; + readonly id_not_in?: InputMaybe>; + readonly borrowerOperations?: InputMaybe; + readonly borrowerOperations_not?: InputMaybe; + readonly borrowerOperations_gt?: InputMaybe; + readonly borrowerOperations_lt?: InputMaybe; + readonly borrowerOperations_gte?: InputMaybe; + readonly borrowerOperations_lte?: InputMaybe; + readonly borrowerOperations_in?: InputMaybe>; + readonly borrowerOperations_not_in?: InputMaybe>; + readonly borrowerOperations_contains?: InputMaybe; + readonly borrowerOperations_not_contains?: InputMaybe; + readonly collateral?: InputMaybe; + readonly collateral_not?: InputMaybe; + readonly collateral_gt?: InputMaybe; + readonly collateral_lt?: InputMaybe; + readonly collateral_gte?: InputMaybe; + readonly collateral_lte?: InputMaybe; + readonly collateral_in?: InputMaybe>; + readonly collateral_not_in?: InputMaybe>; + readonly collateral_contains?: InputMaybe; + readonly collateral_contains_nocase?: InputMaybe; + readonly collateral_not_contains?: InputMaybe; + readonly collateral_not_contains_nocase?: InputMaybe; + readonly collateral_starts_with?: InputMaybe; + readonly collateral_starts_with_nocase?: InputMaybe; + readonly collateral_not_starts_with?: InputMaybe; + readonly collateral_not_starts_with_nocase?: InputMaybe; + readonly collateral_ends_with?: InputMaybe; + readonly collateral_ends_with_nocase?: InputMaybe; + readonly collateral_not_ends_with?: InputMaybe; + readonly collateral_not_ends_with_nocase?: InputMaybe; + readonly collateral_?: InputMaybe; + readonly sortedTroves?: InputMaybe; + readonly sortedTroves_not?: InputMaybe; + readonly sortedTroves_gt?: InputMaybe; + readonly sortedTroves_lt?: InputMaybe; + readonly sortedTroves_gte?: InputMaybe; + readonly sortedTroves_lte?: InputMaybe; + readonly sortedTroves_in?: InputMaybe>; + readonly sortedTroves_not_in?: InputMaybe>; + readonly sortedTroves_contains?: InputMaybe; + readonly sortedTroves_not_contains?: InputMaybe; + readonly stabilityPool?: InputMaybe; + readonly stabilityPool_not?: InputMaybe; + readonly stabilityPool_gt?: InputMaybe; + readonly stabilityPool_lt?: InputMaybe; + readonly stabilityPool_gte?: InputMaybe; + readonly stabilityPool_lte?: InputMaybe; + readonly stabilityPool_in?: InputMaybe>; + readonly stabilityPool_not_in?: InputMaybe>; + readonly stabilityPool_contains?: InputMaybe; + readonly stabilityPool_not_contains?: InputMaybe; + readonly token?: InputMaybe; + readonly token_not?: InputMaybe; + readonly token_gt?: InputMaybe; + readonly token_lt?: InputMaybe; + readonly token_gte?: InputMaybe; + readonly token_lte?: InputMaybe; + readonly token_in?: InputMaybe>; + readonly token_not_in?: InputMaybe>; + readonly token_contains?: InputMaybe; + readonly token_not_contains?: InputMaybe; + readonly troveManager?: InputMaybe; + readonly troveManager_not?: InputMaybe; + readonly troveManager_gt?: InputMaybe; + readonly troveManager_lt?: InputMaybe; + readonly troveManager_gte?: InputMaybe; + readonly troveManager_lte?: InputMaybe; + readonly troveManager_in?: InputMaybe>; + readonly troveManager_not_in?: InputMaybe>; + readonly troveManager_contains?: InputMaybe; + readonly troveManager_not_contains?: InputMaybe; + readonly troveNft?: InputMaybe; + readonly troveNft_not?: InputMaybe; + readonly troveNft_gt?: InputMaybe; + readonly troveNft_lt?: InputMaybe; + readonly troveNft_gte?: InputMaybe; + readonly troveNft_lte?: InputMaybe; + readonly troveNft_in?: InputMaybe>; + readonly troveNft_not_in?: InputMaybe>; + readonly troveNft_contains?: InputMaybe; + readonly troveNft_not_contains?: InputMaybe; + /** Filter for the block changed event. */ + readonly _change_block?: InputMaybe; + readonly and?: InputMaybe>>; + readonly or?: InputMaybe>>; +}; + +export type CollateralAddresses_orderBy = + | 'id' + | 'borrowerOperations' + | 'collateral' + | 'collateral__id' + | 'collateral__minCollRatio' + | 'collateral__totalDeposited' + | 'collateral__totalDebt' + | 'sortedTroves' + | 'stabilityPool' + | 'token' + | 'troveManager' + | 'troveNft'; + +export type Collateral_filter = { + readonly id?: InputMaybe; + readonly id_not?: InputMaybe; + readonly id_gt?: InputMaybe; + readonly id_lt?: InputMaybe; + readonly id_gte?: InputMaybe; + readonly id_lte?: InputMaybe; + readonly id_in?: InputMaybe>; + readonly id_not_in?: InputMaybe>; + readonly token?: InputMaybe; + readonly token_not?: InputMaybe; + readonly token_gt?: InputMaybe; + readonly token_lt?: InputMaybe; + readonly token_gte?: InputMaybe; + readonly token_lte?: InputMaybe; + readonly token_in?: InputMaybe>; + readonly token_not_in?: InputMaybe>; + readonly token_contains?: InputMaybe; + readonly token_contains_nocase?: InputMaybe; + readonly token_not_contains?: InputMaybe; + readonly token_not_contains_nocase?: InputMaybe; + readonly token_starts_with?: InputMaybe; + readonly token_starts_with_nocase?: InputMaybe; + readonly token_not_starts_with?: InputMaybe; + readonly token_not_starts_with_nocase?: InputMaybe; + readonly token_ends_with?: InputMaybe; + readonly token_ends_with_nocase?: InputMaybe; + readonly token_not_ends_with?: InputMaybe; + readonly token_not_ends_with_nocase?: InputMaybe; + readonly token_?: InputMaybe; + readonly minCollRatio?: InputMaybe; + readonly minCollRatio_not?: InputMaybe; + readonly minCollRatio_gt?: InputMaybe; + readonly minCollRatio_lt?: InputMaybe; + readonly minCollRatio_gte?: InputMaybe; + readonly minCollRatio_lte?: InputMaybe; + readonly minCollRatio_in?: InputMaybe>; + readonly minCollRatio_not_in?: InputMaybe>; + readonly troves_?: InputMaybe; + readonly addresses_?: InputMaybe; + readonly totalDeposited?: InputMaybe; + readonly totalDeposited_not?: InputMaybe; + readonly totalDeposited_gt?: InputMaybe; + readonly totalDeposited_lt?: InputMaybe; + readonly totalDeposited_gte?: InputMaybe; + readonly totalDeposited_lte?: InputMaybe; + readonly totalDeposited_in?: InputMaybe>; + readonly totalDeposited_not_in?: InputMaybe>; + readonly totalDebt?: InputMaybe; + readonly totalDebt_not?: InputMaybe; + readonly totalDebt_gt?: InputMaybe; + readonly totalDebt_lt?: InputMaybe; + readonly totalDebt_gte?: InputMaybe; + readonly totalDebt_lte?: InputMaybe; + readonly totalDebt_in?: InputMaybe>; + readonly totalDebt_not_in?: InputMaybe>; + /** Filter for the block changed event. */ + readonly _change_block?: InputMaybe; + readonly and?: InputMaybe>>; + readonly or?: InputMaybe>>; +}; + +export type Collateral_orderBy = + | 'id' + | 'token' + | 'token__id' + | 'token__name' + | 'token__symbol' + | 'token__decimals' + | 'minCollRatio' + | 'troves' + | 'addresses' + | 'addresses__id' + | 'addresses__borrowerOperations' + | 'addresses__sortedTroves' + | 'addresses__stabilityPool' + | 'addresses__token' + | 'addresses__troveManager' + | 'addresses__troveNft' + | 'totalDeposited' + | 'totalDebt'; + +export type InterestRateBracket = { + readonly id: Scalars['ID']['output']; + readonly rate: Scalars['BigInt']['output']; + readonly totalDebt: Scalars['BigInt']['output']; + readonly totalTroves: Scalars['Int']['output']; +}; + +export type InterestRateBracket_filter = { + readonly id?: InputMaybe; + readonly id_not?: InputMaybe; + readonly id_gt?: InputMaybe; + readonly id_lt?: InputMaybe; + readonly id_gte?: InputMaybe; + readonly id_lte?: InputMaybe; + readonly id_in?: InputMaybe>; + readonly id_not_in?: InputMaybe>; + readonly rate?: InputMaybe; + readonly rate_not?: InputMaybe; + readonly rate_gt?: InputMaybe; + readonly rate_lt?: InputMaybe; + readonly rate_gte?: InputMaybe; + readonly rate_lte?: InputMaybe; + readonly rate_in?: InputMaybe>; + readonly rate_not_in?: InputMaybe>; + readonly totalDebt?: InputMaybe; + readonly totalDebt_not?: InputMaybe; + readonly totalDebt_gt?: InputMaybe; + readonly totalDebt_lt?: InputMaybe; + readonly totalDebt_gte?: InputMaybe; + readonly totalDebt_lte?: InputMaybe; + readonly totalDebt_in?: InputMaybe>; + readonly totalDebt_not_in?: InputMaybe>; + readonly totalTroves?: InputMaybe; + readonly totalTroves_not?: InputMaybe; + readonly totalTroves_gt?: InputMaybe; + readonly totalTroves_lt?: InputMaybe; + readonly totalTroves_gte?: InputMaybe; + readonly totalTroves_lte?: InputMaybe; + readonly totalTroves_in?: InputMaybe>; + readonly totalTroves_not_in?: InputMaybe>; + /** Filter for the block changed event. */ + readonly _change_block?: InputMaybe; + readonly and?: InputMaybe>>; + readonly or?: InputMaybe>>; +}; + +export type InterestRateBracket_orderBy = + | 'id' + | 'rate' + | 'totalDebt' + | 'totalTroves'; + +/** Defines the order direction, either ascending or descending */ +export type OrderDirection = + | 'asc' + | 'desc'; + +export type Query = { + readonly collateral?: Maybe; + readonly collaterals: ReadonlyArray; + readonly token?: Maybe; + readonly tokens: ReadonlyArray; + readonly collateralAddresses?: Maybe; + readonly collateralAddresses_collection: ReadonlyArray; + readonly interestRateBracket?: Maybe; + readonly interestRateBrackets: ReadonlyArray; + readonly trove?: Maybe; + readonly troves: ReadonlyArray; + /** Access to subgraph metadata */ + readonly _meta?: Maybe<_Meta_>; +}; + + +export type QuerycollateralArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QuerycollateralsArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QuerytokenArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QuerytokensArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QuerycollateralAddressesArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QuerycollateralAddresses_collectionArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QueryinterestRateBracketArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QueryinterestRateBracketsArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QuerytroveArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QuerytrovesArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type Query_metaArgs = { + block?: InputMaybe; +}; + +export type Subscription = { + readonly collateral?: Maybe; + readonly collaterals: ReadonlyArray; + readonly token?: Maybe; + readonly tokens: ReadonlyArray; + readonly collateralAddresses?: Maybe; + readonly collateralAddresses_collection: ReadonlyArray; + readonly interestRateBracket?: Maybe; + readonly interestRateBrackets: ReadonlyArray; + readonly trove?: Maybe; + readonly troves: ReadonlyArray; + /** Access to subgraph metadata */ + readonly _meta?: Maybe<_Meta_>; +}; + + +export type SubscriptioncollateralArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptioncollateralsArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptiontokenArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptiontokensArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptioncollateralAddressesArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptioncollateralAddresses_collectionArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptioninterestRateBracketArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptioninterestRateBracketsArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptiontroveArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptiontrovesArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type Subscription_metaArgs = { + block?: InputMaybe; +}; + +export type Token = { + readonly id: Scalars['ID']['output']; + readonly collateral: Collateral; + readonly name: Scalars['String']['output']; + readonly symbol: Scalars['String']['output']; + readonly decimals: Scalars['Int']['output']; +}; + +export type Token_filter = { + readonly id?: InputMaybe; + readonly id_not?: InputMaybe; + readonly id_gt?: InputMaybe; + readonly id_lt?: InputMaybe; + readonly id_gte?: InputMaybe; + readonly id_lte?: InputMaybe; + readonly id_in?: InputMaybe>; + readonly id_not_in?: InputMaybe>; + readonly collateral?: InputMaybe; + readonly collateral_not?: InputMaybe; + readonly collateral_gt?: InputMaybe; + readonly collateral_lt?: InputMaybe; + readonly collateral_gte?: InputMaybe; + readonly collateral_lte?: InputMaybe; + readonly collateral_in?: InputMaybe>; + readonly collateral_not_in?: InputMaybe>; + readonly collateral_contains?: InputMaybe; + readonly collateral_contains_nocase?: InputMaybe; + readonly collateral_not_contains?: InputMaybe; + readonly collateral_not_contains_nocase?: InputMaybe; + readonly collateral_starts_with?: InputMaybe; + readonly collateral_starts_with_nocase?: InputMaybe; + readonly collateral_not_starts_with?: InputMaybe; + readonly collateral_not_starts_with_nocase?: InputMaybe; + readonly collateral_ends_with?: InputMaybe; + readonly collateral_ends_with_nocase?: InputMaybe; + readonly collateral_not_ends_with?: InputMaybe; + readonly collateral_not_ends_with_nocase?: InputMaybe; + readonly collateral_?: InputMaybe; + readonly name?: InputMaybe; + readonly name_not?: InputMaybe; + readonly name_gt?: InputMaybe; + readonly name_lt?: InputMaybe; + readonly name_gte?: InputMaybe; + readonly name_lte?: InputMaybe; + readonly name_in?: InputMaybe>; + readonly name_not_in?: InputMaybe>; + readonly name_contains?: InputMaybe; + readonly name_contains_nocase?: InputMaybe; + readonly name_not_contains?: InputMaybe; + readonly name_not_contains_nocase?: InputMaybe; + readonly name_starts_with?: InputMaybe; + readonly name_starts_with_nocase?: InputMaybe; + readonly name_not_starts_with?: InputMaybe; + readonly name_not_starts_with_nocase?: InputMaybe; + readonly name_ends_with?: InputMaybe; + readonly name_ends_with_nocase?: InputMaybe; + readonly name_not_ends_with?: InputMaybe; + readonly name_not_ends_with_nocase?: InputMaybe; + readonly symbol?: InputMaybe; + readonly symbol_not?: InputMaybe; + readonly symbol_gt?: InputMaybe; + readonly symbol_lt?: InputMaybe; + readonly symbol_gte?: InputMaybe; + readonly symbol_lte?: InputMaybe; + readonly symbol_in?: InputMaybe>; + readonly symbol_not_in?: InputMaybe>; + readonly symbol_contains?: InputMaybe; + readonly symbol_contains_nocase?: InputMaybe; + readonly symbol_not_contains?: InputMaybe; + readonly symbol_not_contains_nocase?: InputMaybe; + readonly symbol_starts_with?: InputMaybe; + readonly symbol_starts_with_nocase?: InputMaybe; + readonly symbol_not_starts_with?: InputMaybe; + readonly symbol_not_starts_with_nocase?: InputMaybe; + readonly symbol_ends_with?: InputMaybe; + readonly symbol_ends_with_nocase?: InputMaybe; + readonly symbol_not_ends_with?: InputMaybe; + readonly symbol_not_ends_with_nocase?: InputMaybe; + readonly decimals?: InputMaybe; + readonly decimals_not?: InputMaybe; + readonly decimals_gt?: InputMaybe; + readonly decimals_lt?: InputMaybe; + readonly decimals_gte?: InputMaybe; + readonly decimals_lte?: InputMaybe; + readonly decimals_in?: InputMaybe>; + readonly decimals_not_in?: InputMaybe>; + /** Filter for the block changed event. */ + readonly _change_block?: InputMaybe; + readonly and?: InputMaybe>>; + readonly or?: InputMaybe>>; +}; + +export type Token_orderBy = + | 'id' + | 'collateral' + | 'collateral__id' + | 'collateral__minCollRatio' + | 'collateral__totalDeposited' + | 'collateral__totalDebt' + | 'name' + | 'symbol' + | 'decimals'; + +export type Trove = { + readonly id: Scalars['ID']['output']; + readonly borrower: Scalars['Bytes']['output']; + readonly debt: Scalars['BigInt']['output']; + readonly deposit: Scalars['BigInt']['output']; + readonly stake: Scalars['BigInt']['output']; + readonly interestRate: Scalars['BigInt']['output']; + readonly createdAt: Scalars['BigInt']['output']; + readonly closedAt?: Maybe; + readonly collateral: Collateral; +}; + +export type Trove_filter = { + readonly id?: InputMaybe; + readonly id_not?: InputMaybe; + readonly id_gt?: InputMaybe; + readonly id_lt?: InputMaybe; + readonly id_gte?: InputMaybe; + readonly id_lte?: InputMaybe; + readonly id_in?: InputMaybe>; + readonly id_not_in?: InputMaybe>; + readonly borrower?: InputMaybe; + readonly borrower_not?: InputMaybe; + readonly borrower_gt?: InputMaybe; + readonly borrower_lt?: InputMaybe; + readonly borrower_gte?: InputMaybe; + readonly borrower_lte?: InputMaybe; + readonly borrower_in?: InputMaybe>; + readonly borrower_not_in?: InputMaybe>; + readonly borrower_contains?: InputMaybe; + readonly borrower_not_contains?: InputMaybe; + readonly debt?: InputMaybe; + readonly debt_not?: InputMaybe; + readonly debt_gt?: InputMaybe; + readonly debt_lt?: InputMaybe; + readonly debt_gte?: InputMaybe; + readonly debt_lte?: InputMaybe; + readonly debt_in?: InputMaybe>; + readonly debt_not_in?: InputMaybe>; + readonly deposit?: InputMaybe; + readonly deposit_not?: InputMaybe; + readonly deposit_gt?: InputMaybe; + readonly deposit_lt?: InputMaybe; + readonly deposit_gte?: InputMaybe; + readonly deposit_lte?: InputMaybe; + readonly deposit_in?: InputMaybe>; + readonly deposit_not_in?: InputMaybe>; + readonly stake?: InputMaybe; + readonly stake_not?: InputMaybe; + readonly stake_gt?: InputMaybe; + readonly stake_lt?: InputMaybe; + readonly stake_gte?: InputMaybe; + readonly stake_lte?: InputMaybe; + readonly stake_in?: InputMaybe>; + readonly stake_not_in?: InputMaybe>; + readonly interestRate?: InputMaybe; + readonly interestRate_not?: InputMaybe; + readonly interestRate_gt?: InputMaybe; + readonly interestRate_lt?: InputMaybe; + readonly interestRate_gte?: InputMaybe; + readonly interestRate_lte?: InputMaybe; + readonly interestRate_in?: InputMaybe>; + readonly interestRate_not_in?: InputMaybe>; + readonly createdAt?: InputMaybe; + readonly createdAt_not?: InputMaybe; + readonly createdAt_gt?: InputMaybe; + readonly createdAt_lt?: InputMaybe; + readonly createdAt_gte?: InputMaybe; + readonly createdAt_lte?: InputMaybe; + readonly createdAt_in?: InputMaybe>; + readonly createdAt_not_in?: InputMaybe>; + readonly closedAt?: InputMaybe; + readonly closedAt_not?: InputMaybe; + readonly closedAt_gt?: InputMaybe; + readonly closedAt_lt?: InputMaybe; + readonly closedAt_gte?: InputMaybe; + readonly closedAt_lte?: InputMaybe; + readonly closedAt_in?: InputMaybe>; + readonly closedAt_not_in?: InputMaybe>; + readonly collateral?: InputMaybe; + readonly collateral_not?: InputMaybe; + readonly collateral_gt?: InputMaybe; + readonly collateral_lt?: InputMaybe; + readonly collateral_gte?: InputMaybe; + readonly collateral_lte?: InputMaybe; + readonly collateral_in?: InputMaybe>; + readonly collateral_not_in?: InputMaybe>; + readonly collateral_contains?: InputMaybe; + readonly collateral_contains_nocase?: InputMaybe; + readonly collateral_not_contains?: InputMaybe; + readonly collateral_not_contains_nocase?: InputMaybe; + readonly collateral_starts_with?: InputMaybe; + readonly collateral_starts_with_nocase?: InputMaybe; + readonly collateral_not_starts_with?: InputMaybe; + readonly collateral_not_starts_with_nocase?: InputMaybe; + readonly collateral_ends_with?: InputMaybe; + readonly collateral_ends_with_nocase?: InputMaybe; + readonly collateral_not_ends_with?: InputMaybe; + readonly collateral_not_ends_with_nocase?: InputMaybe; + readonly collateral_?: InputMaybe; + /** Filter for the block changed event. */ + readonly _change_block?: InputMaybe; + readonly and?: InputMaybe>>; + readonly or?: InputMaybe>>; +}; + +export type Trove_orderBy = + | 'id' + | 'borrower' + | 'debt' + | 'deposit' + | 'stake' + | 'interestRate' + | 'createdAt' + | 'closedAt' + | 'collateral' + | 'collateral__id' + | 'collateral__minCollRatio' + | 'collateral__totalDeposited' + | 'collateral__totalDebt'; + +export type _Block_ = { + /** The hash of the block */ + readonly hash?: Maybe; + /** The block number */ + readonly number: Scalars['Int']['output']; + /** Integer representation of the timestamp stored in blocks for the chain */ + readonly timestamp?: Maybe; + /** The hash of the parent block */ + readonly parentHash?: Maybe; +}; + +/** The type for the top-level _meta field */ +export type _Meta_ = { + /** + * Information about a specific subgraph block. The hash of the block + * will be null if the _meta field has a block constraint that asks for + * a block number. It will be filled if the _meta field has no block constraint + * and therefore asks for the latest block + * + */ + readonly block: _Block_; + /** The deployment ID */ + readonly deployment: Scalars['String']['output']; + /** If `true`, the subgraph encountered indexing errors at some past block */ + readonly hasIndexingErrors: Scalars['Boolean']['output']; +}; + +export type _SubgraphErrorPolicy_ = + /** Data will be returned even if the subgraph has indexing errors */ + | 'allow' + /** If the subgraph has indexing errors, data will be omitted. The default. */ + | 'deny'; + +export type WithIndex = TObject & Record; +export type ResolversObject = WithIndex; + +export type ResolverTypeWrapper = Promise | T; + + +export type ResolverWithResolve = { + resolve: ResolverFn; +}; + +export type LegacyStitchingResolver = { + fragment: string; + resolve: ResolverFn; +}; + +export type NewStitchingResolver = { + selectionSet: string | ((fieldNode: FieldNode) => SelectionSetNode); + resolve: ResolverFn; +}; +export type StitchingResolver = LegacyStitchingResolver | NewStitchingResolver; +export type Resolver = + | ResolverFn + | ResolverWithResolve + | StitchingResolver; + +export type ResolverFn = ( + parent: TParent, + args: TArgs, + context: TContext, + info: GraphQLResolveInfo +) => Promise | TResult; + +export type SubscriptionSubscribeFn = ( + parent: TParent, + args: TArgs, + context: TContext, + info: GraphQLResolveInfo +) => AsyncIterable | Promise>; + +export type SubscriptionResolveFn = ( + parent: TParent, + args: TArgs, + context: TContext, + info: GraphQLResolveInfo +) => TResult | Promise; + +export interface SubscriptionSubscriberObject { + subscribe: SubscriptionSubscribeFn<{ [key in TKey]: TResult }, TParent, TContext, TArgs>; + resolve?: SubscriptionResolveFn; +} + +export interface SubscriptionResolverObject { + subscribe: SubscriptionSubscribeFn; + resolve: SubscriptionResolveFn; +} + +export type SubscriptionObject = + | SubscriptionSubscriberObject + | SubscriptionResolverObject; + +export type SubscriptionResolver = + | ((...args: any[]) => SubscriptionObject) + | SubscriptionObject; + +export type TypeResolveFn = ( + parent: TParent, + context: TContext, + info: GraphQLResolveInfo +) => Maybe | Promise>; + +export type IsTypeOfResolverFn = (obj: T, context: TContext, info: GraphQLResolveInfo) => boolean | Promise; + +export type NextResolverFn = () => Promise; + +export type DirectiveResolverFn = ( + next: NextResolverFn, + parent: TParent, + args: TArgs, + context: TContext, + info: GraphQLResolveInfo +) => TResult | Promise; + + + +/** Mapping between all available schema types and the resolvers types */ +export type ResolversTypes = ResolversObject<{ + Aggregation_interval: Aggregation_interval; + BigDecimal: ResolverTypeWrapper; + BigInt: ResolverTypeWrapper; + BlockChangedFilter: BlockChangedFilter; + Block_height: Block_height; + Boolean: ResolverTypeWrapper; + Bytes: ResolverTypeWrapper; + Collateral: ResolverTypeWrapper; + CollateralAddresses: ResolverTypeWrapper; + CollateralAddresses_filter: CollateralAddresses_filter; + CollateralAddresses_orderBy: CollateralAddresses_orderBy; + Collateral_filter: Collateral_filter; + Collateral_orderBy: Collateral_orderBy; + Float: ResolverTypeWrapper; + ID: ResolverTypeWrapper; + Int: ResolverTypeWrapper; + Int8: ResolverTypeWrapper; + InterestRateBracket: ResolverTypeWrapper; + InterestRateBracket_filter: InterestRateBracket_filter; + InterestRateBracket_orderBy: InterestRateBracket_orderBy; + OrderDirection: OrderDirection; + Query: ResolverTypeWrapper<{}>; + String: ResolverTypeWrapper; + Subscription: ResolverTypeWrapper<{}>; + Timestamp: ResolverTypeWrapper; + Token: ResolverTypeWrapper; + Token_filter: Token_filter; + Token_orderBy: Token_orderBy; + Trove: ResolverTypeWrapper; + Trove_filter: Trove_filter; + Trove_orderBy: Trove_orderBy; + _Block_: ResolverTypeWrapper<_Block_>; + _Meta_: ResolverTypeWrapper<_Meta_>; + _SubgraphErrorPolicy_: _SubgraphErrorPolicy_; +}>; + +/** Mapping between all available schema types and the resolvers parents */ +export type ResolversParentTypes = ResolversObject<{ + BigDecimal: Scalars['BigDecimal']['output']; + BigInt: Scalars['BigInt']['output']; + BlockChangedFilter: BlockChangedFilter; + Block_height: Block_height; + Boolean: Scalars['Boolean']['output']; + Bytes: Scalars['Bytes']['output']; + Collateral: Collateral; + CollateralAddresses: CollateralAddresses; + CollateralAddresses_filter: CollateralAddresses_filter; + Collateral_filter: Collateral_filter; + Float: Scalars['Float']['output']; + ID: Scalars['ID']['output']; + Int: Scalars['Int']['output']; + Int8: Scalars['Int8']['output']; + InterestRateBracket: InterestRateBracket; + InterestRateBracket_filter: InterestRateBracket_filter; + Query: {}; + String: Scalars['String']['output']; + Subscription: {}; + Timestamp: Scalars['Timestamp']['output']; + Token: Token; + Token_filter: Token_filter; + Trove: Trove; + Trove_filter: Trove_filter; + _Block_: _Block_; + _Meta_: _Meta_; +}>; + +export type entityDirectiveArgs = { }; + +export type entityDirectiveResolver = DirectiveResolverFn; + +export type subgraphIdDirectiveArgs = { + id: Scalars['String']['input']; +}; + +export type subgraphIdDirectiveResolver = DirectiveResolverFn; + +export type derivedFromDirectiveArgs = { + field: Scalars['String']['input']; +}; + +export type derivedFromDirectiveResolver = DirectiveResolverFn; + +export interface BigDecimalScalarConfig extends GraphQLScalarTypeConfig { + name: 'BigDecimal'; +} + +export interface BigIntScalarConfig extends GraphQLScalarTypeConfig { + name: 'BigInt'; +} + +export interface BytesScalarConfig extends GraphQLScalarTypeConfig { + name: 'Bytes'; +} + +export type CollateralResolvers = ResolversObject<{ + id?: Resolver; + token?: Resolver; + minCollRatio?: Resolver; + troves?: Resolver, ParentType, ContextType, RequireFields>; + addresses?: Resolver; + totalDeposited?: Resolver; + totalDebt?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}>; + +export type CollateralAddressesResolvers = ResolversObject<{ + id?: Resolver; + borrowerOperations?: Resolver; + collateral?: Resolver; + sortedTroves?: Resolver; + stabilityPool?: Resolver; + token?: Resolver; + troveManager?: Resolver; + troveNft?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}>; + +export interface Int8ScalarConfig extends GraphQLScalarTypeConfig { + name: 'Int8'; +} + +export type InterestRateBracketResolvers = ResolversObject<{ + id?: Resolver; + rate?: Resolver; + totalDebt?: Resolver; + totalTroves?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}>; + +export type QueryResolvers = ResolversObject<{ + collateral?: Resolver, ParentType, ContextType, RequireFields>; + collaterals?: Resolver, ParentType, ContextType, RequireFields>; + token?: Resolver, ParentType, ContextType, RequireFields>; + tokens?: Resolver, ParentType, ContextType, RequireFields>; + collateralAddresses?: Resolver, ParentType, ContextType, RequireFields>; + collateralAddresses_collection?: Resolver, ParentType, ContextType, RequireFields>; + interestRateBracket?: Resolver, ParentType, ContextType, RequireFields>; + interestRateBrackets?: Resolver, ParentType, ContextType, RequireFields>; + trove?: Resolver, ParentType, ContextType, RequireFields>; + troves?: Resolver, ParentType, ContextType, RequireFields>; + _meta?: Resolver, ParentType, ContextType, Partial>; +}>; + +export type SubscriptionResolvers = ResolversObject<{ + collateral?: SubscriptionResolver, "collateral", ParentType, ContextType, RequireFields>; + collaterals?: SubscriptionResolver, "collaterals", ParentType, ContextType, RequireFields>; + token?: SubscriptionResolver, "token", ParentType, ContextType, RequireFields>; + tokens?: SubscriptionResolver, "tokens", ParentType, ContextType, RequireFields>; + collateralAddresses?: SubscriptionResolver, "collateralAddresses", ParentType, ContextType, RequireFields>; + collateralAddresses_collection?: SubscriptionResolver, "collateralAddresses_collection", ParentType, ContextType, RequireFields>; + interestRateBracket?: SubscriptionResolver, "interestRateBracket", ParentType, ContextType, RequireFields>; + interestRateBrackets?: SubscriptionResolver, "interestRateBrackets", ParentType, ContextType, RequireFields>; + trove?: SubscriptionResolver, "trove", ParentType, ContextType, RequireFields>; + troves?: SubscriptionResolver, "troves", ParentType, ContextType, RequireFields>; + _meta?: SubscriptionResolver, "_meta", ParentType, ContextType, Partial>; +}>; + +export interface TimestampScalarConfig extends GraphQLScalarTypeConfig { + name: 'Timestamp'; +} + +export type TokenResolvers = ResolversObject<{ + id?: Resolver; + collateral?: Resolver; + name?: Resolver; + symbol?: Resolver; + decimals?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}>; + +export type TroveResolvers = ResolversObject<{ + id?: Resolver; + borrower?: Resolver; + debt?: Resolver; + deposit?: Resolver; + stake?: Resolver; + interestRate?: Resolver; + createdAt?: Resolver; + closedAt?: Resolver, ParentType, ContextType>; + collateral?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}>; + +export type _Block_Resolvers = ResolversObject<{ + hash?: Resolver, ParentType, ContextType>; + number?: Resolver; + timestamp?: Resolver, ParentType, ContextType>; + parentHash?: Resolver, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}>; + +export type _Meta_Resolvers = ResolversObject<{ + block?: Resolver; + deployment?: Resolver; + hasIndexingErrors?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}>; + +export type Resolvers = ResolversObject<{ + BigDecimal?: GraphQLScalarType; + BigInt?: GraphQLScalarType; + Bytes?: GraphQLScalarType; + Collateral?: CollateralResolvers; + CollateralAddresses?: CollateralAddressesResolvers; + Int8?: GraphQLScalarType; + InterestRateBracket?: InterestRateBracketResolvers; + Query?: QueryResolvers; + Subscription?: SubscriptionResolvers; + Timestamp?: GraphQLScalarType; + Token?: TokenResolvers; + Trove?: TroveResolvers; + _Block_?: _Block_Resolvers; + _Meta_?: _Meta_Resolvers; +}>; + +export type DirectiveResolvers = ResolversObject<{ + entity?: entityDirectiveResolver; + subgraphId?: subgraphIdDirectiveResolver; + derivedFrom?: derivedFromDirectiveResolver; +}>; + +export type MeshContext = Liquity2Types.Context & BaseMeshContext; + + +import { fileURLToPath } from '@graphql-mesh/utils'; +const baseDir = pathModule.join(pathModule.dirname(fileURLToPath(import.meta.url)), '..'); + +const importFn: ImportFn = (moduleId: string) => { + const relativeModuleId = (pathModule.isAbsolute(moduleId) ? pathModule.relative(baseDir, moduleId) : moduleId).split('\\').join('/').replace(baseDir + '/', ''); + switch(relativeModuleId) { + case ".graphclient/sources/liquity2/introspectionSchema": + return Promise.resolve(importedModule$0) as T; + + default: + return Promise.reject(new Error(`Cannot find module '${relativeModuleId}'.`)); + } +}; + +const rootStore = new MeshStore('.graphclient', new FsStoreStorageAdapter({ + cwd: baseDir, + importFn, + fileType: "ts", +}), { + readonly: true, + validate: false +}); + +export const rawServeConfig: YamlConfig.Config['serve'] = undefined as any +export async function getMeshOptions(): Promise { +const pubsub = new PubSub(); +const sourcesStore = rootStore.child('sources'); +const logger = new DefaultLogger("GraphClient"); +const cache = new (MeshCache as any)({ + ...({} as any), + importFn, + store: rootStore.child('cache'), + pubsub, + logger, + } as any) + +const sources: MeshResolvedSource[] = []; +const transforms: MeshTransform[] = []; +const additionalEnvelopPlugins: MeshPlugin[] = []; +const liquity2Transforms = []; +const additionalTypeDefs = [] as any[]; +const liquity2Handler = new GraphqlHandler({ + name: "liquity2", + config: {"endpoint":"http://localhost:8000/subgraphs/name/liquity2/liquity2"}, + baseDir, + cache, + pubsub, + store: sourcesStore.child("liquity2"), + logger: logger.child("liquity2"), + importFn, + }); +sources[0] = { + name: 'liquity2', + handler: liquity2Handler, + transforms: liquity2Transforms + } +const additionalResolvers = [] as any[] +const merger = new(BareMerger as any)({ + cache, + pubsub, + logger: logger.child('bareMerger'), + store: rootStore.child('bareMerger') + }) +const documentHashMap = { + "45745732d955f1e9e56be85453b7766bb2b5d776bad265e1e6734958fbc111c8": TrovesByAccountDocument, +"45745732d955f1e9e56be85453b7766bb2b5d776bad265e1e6734958fbc111c8": TroveByIdDocument + } +additionalEnvelopPlugins.push(usePersistedOperations({ + getPersistedOperation(key) { + return documentHashMap[key]; + }, + ...{} + })) + + return { + sources, + transforms, + additionalTypeDefs, + additionalResolvers, + cache, + pubsub, + merger, + logger, + additionalEnvelopPlugins, + get documents() { + return [ + { + document: TrovesByAccountDocument, + get rawSDL() { + return printWithCache(TrovesByAccountDocument); + }, + location: 'TrovesByAccountDocument.graphql', + sha256Hash: '45745732d955f1e9e56be85453b7766bb2b5d776bad265e1e6734958fbc111c8' + },{ + document: TroveByIdDocument, + get rawSDL() { + return printWithCache(TroveByIdDocument); + }, + location: 'TroveByIdDocument.graphql', + sha256Hash: '45745732d955f1e9e56be85453b7766bb2b5d776bad265e1e6734958fbc111c8' + } + ]; + }, + fetchFn, + }; +} + +export function createBuiltMeshHTTPHandler(): MeshHTTPHandler { + return createMeshHTTPHandler({ + baseDir, + getBuiltMesh: getBuiltGraphClient, + rawServeConfig: undefined, + }) +} + + +let meshInstance$: Promise | undefined; + +export const pollingInterval = null; + +export function getBuiltGraphClient(): Promise { + if (meshInstance$ == null) { + if (pollingInterval) { + setInterval(() => { + getMeshOptions() + .then(meshOptions => getMesh(meshOptions)) + .then(newMesh => + meshInstance$.then(oldMesh => { + oldMesh.destroy() + meshInstance$ = Promise.resolve(newMesh) + }) + ).catch(err => { + console.error("Mesh polling failed so the existing version will be used:", err); + }); + }, pollingInterval) + } + meshInstance$ = getMeshOptions().then(meshOptions => getMesh(meshOptions)).then(mesh => { + const id = mesh.pubsub.subscribe('destroy', () => { + meshInstance$ = undefined; + mesh.pubsub.unsubscribe(id); + }); + return mesh; + }); + } + return meshInstance$; +} + +export const execute: ExecuteMeshFn = (...args) => getBuiltGraphClient().then(({ execute }) => execute(...args)); + +export const subscribe: SubscribeMeshFn = (...args) => getBuiltGraphClient().then(({ subscribe }) => subscribe(...args)); +export function getBuiltGraphSDK(globalContext?: TGlobalContext) { + const sdkRequester$ = getBuiltGraphClient().then(({ sdkRequesterFactory }) => sdkRequesterFactory(globalContext)); + return getSdk((...args) => sdkRequester$.then(sdkRequester => sdkRequester(...args))); +} +export type TrovesByAccountQueryVariables = Exact<{ + account: Scalars['Bytes']['input']; +}>; + + +export type TrovesByAccountQuery = { readonly troves: ReadonlyArray<( + Pick + & { readonly collateral: ( + Pick + & { readonly token: Pick } + ) } + )> }; + +export type TroveByIdQueryVariables = Exact<{ + id: Scalars['ID']['input']; +}>; + + +export type TroveByIdQuery = { readonly trove?: Maybe<( + Pick + & { readonly collateral: ( + Pick + & { readonly token: Pick } + ) } + )> }; + + +export const TrovesByAccountDocument = gql` + query TrovesByAccount($account: Bytes!) { + troves(where: {borrower: $account}) { + id + borrower + debt + deposit + stake + interestRate + createdAt + closedAt + collateral { + id + token { + symbol + name + } + minCollRatio + } + } +} + ` as unknown as DocumentNode; +export const TroveByIdDocument = gql` + query TroveById($id: ID!) { + trove(id: $id) { + id + borrower + debt + deposit + stake + interestRate + createdAt + closedAt + collateral { + id + token { + symbol + name + } + minCollRatio + } + } +} + ` as unknown as DocumentNode; + + + +export type Requester = (doc: DocumentNode, vars?: V, options?: C) => Promise | AsyncIterable +export function getSdk(requester: Requester) { + return { + TrovesByAccount(variables: TrovesByAccountQueryVariables, options?: C): Promise { + return requester(TrovesByAccountDocument, variables, options) as Promise; + }, + TroveById(variables: TroveByIdQueryVariables, options?: C): Promise { + return requester(TroveByIdDocument, variables, options) as Promise; + } + }; +} +export type Sdk = ReturnType; \ No newline at end of file diff --git a/frontend/app/.graphclient/persisted_operations.json b/frontend/app/.graphclient/persisted_operations.json new file mode 100644 index 00000000..5c0346b7 --- /dev/null +++ b/frontend/app/.graphclient/persisted_operations.json @@ -0,0 +1,3 @@ +{ + "45745732d955f1e9e56be85453b7766bb2b5d776bad265e1e6734958fbc111c8": "query TrovesByAccount($account: Bytes!) {\n troves(where: {borrower: $account}) {\n id\n borrower\n debt\n deposit\n stake\n interestRate\n createdAt\n closedAt\n collateral {\n id\n token {\n symbol\n name\n }\n minCollRatio\n }\n }\n}\n\nquery TroveById($id: ID!) {\n trove(id: $id) {\n id\n borrower\n debt\n deposit\n stake\n interestRate\n createdAt\n closedAt\n collateral {\n id\n token {\n symbol\n name\n }\n minCollRatio\n }\n }\n}" +} \ No newline at end of file diff --git a/frontend/app/.graphclient/schema.graphql b/frontend/app/.graphclient/schema.graphql new file mode 100644 index 00000000..d53c0294 --- /dev/null +++ b/frontend/app/.graphclient/schema.graphql @@ -0,0 +1,856 @@ +schema { + query: Query + subscription: Subscription +} + +""" +Marks the GraphQL type as indexable entity. Each type that should be an entity is required to be annotated with this directive. +""" +directive @entity on OBJECT + +"""Defined a Subgraph ID for an object type""" +directive @subgraphId(id: String!) on OBJECT + +""" +creates a virtual field on the entity that may be queried but cannot be set manually through the mappings API. +""" +directive @derivedFrom(field: String!) on FIELD_DEFINITION + +enum Aggregation_interval { + hour + day +} + +scalar BigDecimal + +scalar BigInt + +input BlockChangedFilter { + number_gte: Int! +} + +input Block_height { + hash: Bytes + number: Int + number_gte: Int +} + +scalar Bytes + +type Collateral { + id: ID! + token: Token! + minCollRatio: BigInt! + troves(skip: Int = 0, first: Int = 100, orderBy: Trove_orderBy, orderDirection: OrderDirection, where: Trove_filter): [Trove!]! + addresses: CollateralAddresses! + totalDeposited: BigInt! + totalDebt: BigInt! +} + +type CollateralAddresses { + id: ID! + borrowerOperations: Bytes! + collateral: Collateral! + sortedTroves: Bytes! + stabilityPool: Bytes! + token: Bytes! + troveManager: Bytes! + troveNft: Bytes! +} + +input CollateralAddresses_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + borrowerOperations: Bytes + borrowerOperations_not: Bytes + borrowerOperations_gt: Bytes + borrowerOperations_lt: Bytes + borrowerOperations_gte: Bytes + borrowerOperations_lte: Bytes + borrowerOperations_in: [Bytes!] + borrowerOperations_not_in: [Bytes!] + borrowerOperations_contains: Bytes + borrowerOperations_not_contains: Bytes + collateral: String + collateral_not: String + collateral_gt: String + collateral_lt: String + collateral_gte: String + collateral_lte: String + collateral_in: [String!] + collateral_not_in: [String!] + collateral_contains: String + collateral_contains_nocase: String + collateral_not_contains: String + collateral_not_contains_nocase: String + collateral_starts_with: String + collateral_starts_with_nocase: String + collateral_not_starts_with: String + collateral_not_starts_with_nocase: String + collateral_ends_with: String + collateral_ends_with_nocase: String + collateral_not_ends_with: String + collateral_not_ends_with_nocase: String + collateral_: Collateral_filter + sortedTroves: Bytes + sortedTroves_not: Bytes + sortedTroves_gt: Bytes + sortedTroves_lt: Bytes + sortedTroves_gte: Bytes + sortedTroves_lte: Bytes + sortedTroves_in: [Bytes!] + sortedTroves_not_in: [Bytes!] + sortedTroves_contains: Bytes + sortedTroves_not_contains: Bytes + stabilityPool: Bytes + stabilityPool_not: Bytes + stabilityPool_gt: Bytes + stabilityPool_lt: Bytes + stabilityPool_gte: Bytes + stabilityPool_lte: Bytes + stabilityPool_in: [Bytes!] + stabilityPool_not_in: [Bytes!] + stabilityPool_contains: Bytes + stabilityPool_not_contains: Bytes + token: Bytes + token_not: Bytes + token_gt: Bytes + token_lt: Bytes + token_gte: Bytes + token_lte: Bytes + token_in: [Bytes!] + token_not_in: [Bytes!] + token_contains: Bytes + token_not_contains: Bytes + troveManager: Bytes + troveManager_not: Bytes + troveManager_gt: Bytes + troveManager_lt: Bytes + troveManager_gte: Bytes + troveManager_lte: Bytes + troveManager_in: [Bytes!] + troveManager_not_in: [Bytes!] + troveManager_contains: Bytes + troveManager_not_contains: Bytes + troveNft: Bytes + troveNft_not: Bytes + troveNft_gt: Bytes + troveNft_lt: Bytes + troveNft_gte: Bytes + troveNft_lte: Bytes + troveNft_in: [Bytes!] + troveNft_not_in: [Bytes!] + troveNft_contains: Bytes + troveNft_not_contains: Bytes + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [CollateralAddresses_filter] + or: [CollateralAddresses_filter] +} + +enum CollateralAddresses_orderBy { + id + borrowerOperations + collateral + collateral__id + collateral__minCollRatio + collateral__totalDeposited + collateral__totalDebt + sortedTroves + stabilityPool + token + troveManager + troveNft +} + +input Collateral_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + token: String + token_not: String + token_gt: String + token_lt: String + token_gte: String + token_lte: String + token_in: [String!] + token_not_in: [String!] + token_contains: String + token_contains_nocase: String + token_not_contains: String + token_not_contains_nocase: String + token_starts_with: String + token_starts_with_nocase: String + token_not_starts_with: String + token_not_starts_with_nocase: String + token_ends_with: String + token_ends_with_nocase: String + token_not_ends_with: String + token_not_ends_with_nocase: String + token_: Token_filter + minCollRatio: BigInt + minCollRatio_not: BigInt + minCollRatio_gt: BigInt + minCollRatio_lt: BigInt + minCollRatio_gte: BigInt + minCollRatio_lte: BigInt + minCollRatio_in: [BigInt!] + minCollRatio_not_in: [BigInt!] + troves_: Trove_filter + addresses_: CollateralAddresses_filter + totalDeposited: BigInt + totalDeposited_not: BigInt + totalDeposited_gt: BigInt + totalDeposited_lt: BigInt + totalDeposited_gte: BigInt + totalDeposited_lte: BigInt + totalDeposited_in: [BigInt!] + totalDeposited_not_in: [BigInt!] + totalDebt: BigInt + totalDebt_not: BigInt + totalDebt_gt: BigInt + totalDebt_lt: BigInt + totalDebt_gte: BigInt + totalDebt_lte: BigInt + totalDebt_in: [BigInt!] + totalDebt_not_in: [BigInt!] + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Collateral_filter] + or: [Collateral_filter] +} + +enum Collateral_orderBy { + id + token + token__id + token__name + token__symbol + token__decimals + minCollRatio + troves + addresses + addresses__id + addresses__borrowerOperations + addresses__sortedTroves + addresses__stabilityPool + addresses__token + addresses__troveManager + addresses__troveNft + totalDeposited + totalDebt +} + +""" +8 bytes signed integer + +""" +scalar Int8 + +type InterestRateBracket { + id: ID! + rate: BigInt! + totalDebt: BigInt! + totalTroves: Int! +} + +input InterestRateBracket_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + rate: BigInt + rate_not: BigInt + rate_gt: BigInt + rate_lt: BigInt + rate_gte: BigInt + rate_lte: BigInt + rate_in: [BigInt!] + rate_not_in: [BigInt!] + totalDebt: BigInt + totalDebt_not: BigInt + totalDebt_gt: BigInt + totalDebt_lt: BigInt + totalDebt_gte: BigInt + totalDebt_lte: BigInt + totalDebt_in: [BigInt!] + totalDebt_not_in: [BigInt!] + totalTroves: Int + totalTroves_not: Int + totalTroves_gt: Int + totalTroves_lt: Int + totalTroves_gte: Int + totalTroves_lte: Int + totalTroves_in: [Int!] + totalTroves_not_in: [Int!] + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [InterestRateBracket_filter] + or: [InterestRateBracket_filter] +} + +enum InterestRateBracket_orderBy { + id + rate + totalDebt + totalTroves +} + +"""Defines the order direction, either ascending or descending""" +enum OrderDirection { + asc + desc +} + +type Query { + collateral( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Collateral + collaterals( + skip: Int = 0 + first: Int = 100 + orderBy: Collateral_orderBy + orderDirection: OrderDirection + where: Collateral_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Collateral!]! + token( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Token + tokens( + skip: Int = 0 + first: Int = 100 + orderBy: Token_orderBy + orderDirection: OrderDirection + where: Token_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Token!]! + collateralAddresses( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): CollateralAddresses + collateralAddresses_collection( + skip: Int = 0 + first: Int = 100 + orderBy: CollateralAddresses_orderBy + orderDirection: OrderDirection + where: CollateralAddresses_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [CollateralAddresses!]! + interestRateBracket( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): InterestRateBracket + interestRateBrackets( + skip: Int = 0 + first: Int = 100 + orderBy: InterestRateBracket_orderBy + orderDirection: OrderDirection + where: InterestRateBracket_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [InterestRateBracket!]! + trove( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Trove + troves( + skip: Int = 0 + first: Int = 100 + orderBy: Trove_orderBy + orderDirection: OrderDirection + where: Trove_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Trove!]! + """Access to subgraph metadata""" + _meta(block: Block_height): _Meta_ +} + +type Subscription { + collateral( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Collateral + collaterals( + skip: Int = 0 + first: Int = 100 + orderBy: Collateral_orderBy + orderDirection: OrderDirection + where: Collateral_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Collateral!]! + token( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Token + tokens( + skip: Int = 0 + first: Int = 100 + orderBy: Token_orderBy + orderDirection: OrderDirection + where: Token_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Token!]! + collateralAddresses( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): CollateralAddresses + collateralAddresses_collection( + skip: Int = 0 + first: Int = 100 + orderBy: CollateralAddresses_orderBy + orderDirection: OrderDirection + where: CollateralAddresses_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [CollateralAddresses!]! + interestRateBracket( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): InterestRateBracket + interestRateBrackets( + skip: Int = 0 + first: Int = 100 + orderBy: InterestRateBracket_orderBy + orderDirection: OrderDirection + where: InterestRateBracket_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [InterestRateBracket!]! + trove( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Trove + troves( + skip: Int = 0 + first: Int = 100 + orderBy: Trove_orderBy + orderDirection: OrderDirection + where: Trove_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Trove!]! + """Access to subgraph metadata""" + _meta(block: Block_height): _Meta_ +} + +""" +A string representation of microseconds UNIX timestamp (16 digits) + +""" +scalar Timestamp + +type Token { + id: ID! + collateral: Collateral! + name: String! + symbol: String! + decimals: Int! +} + +input Token_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + collateral: String + collateral_not: String + collateral_gt: String + collateral_lt: String + collateral_gte: String + collateral_lte: String + collateral_in: [String!] + collateral_not_in: [String!] + collateral_contains: String + collateral_contains_nocase: String + collateral_not_contains: String + collateral_not_contains_nocase: String + collateral_starts_with: String + collateral_starts_with_nocase: String + collateral_not_starts_with: String + collateral_not_starts_with_nocase: String + collateral_ends_with: String + collateral_ends_with_nocase: String + collateral_not_ends_with: String + collateral_not_ends_with_nocase: String + collateral_: Collateral_filter + name: String + name_not: String + name_gt: String + name_lt: String + name_gte: String + name_lte: String + name_in: [String!] + name_not_in: [String!] + name_contains: String + name_contains_nocase: String + name_not_contains: String + name_not_contains_nocase: String + name_starts_with: String + name_starts_with_nocase: String + name_not_starts_with: String + name_not_starts_with_nocase: String + name_ends_with: String + name_ends_with_nocase: String + name_not_ends_with: String + name_not_ends_with_nocase: String + symbol: String + symbol_not: String + symbol_gt: String + symbol_lt: String + symbol_gte: String + symbol_lte: String + symbol_in: [String!] + symbol_not_in: [String!] + symbol_contains: String + symbol_contains_nocase: String + symbol_not_contains: String + symbol_not_contains_nocase: String + symbol_starts_with: String + symbol_starts_with_nocase: String + symbol_not_starts_with: String + symbol_not_starts_with_nocase: String + symbol_ends_with: String + symbol_ends_with_nocase: String + symbol_not_ends_with: String + symbol_not_ends_with_nocase: String + decimals: Int + decimals_not: Int + decimals_gt: Int + decimals_lt: Int + decimals_gte: Int + decimals_lte: Int + decimals_in: [Int!] + decimals_not_in: [Int!] + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Token_filter] + or: [Token_filter] +} + +enum Token_orderBy { + id + collateral + collateral__id + collateral__minCollRatio + collateral__totalDeposited + collateral__totalDebt + name + symbol + decimals +} + +type Trove { + id: ID! + borrower: Bytes! + debt: BigInt! + deposit: BigInt! + stake: BigInt! + interestRate: BigInt! + createdAt: BigInt! + closedAt: BigInt + collateral: Collateral! +} + +input Trove_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + borrower: Bytes + borrower_not: Bytes + borrower_gt: Bytes + borrower_lt: Bytes + borrower_gte: Bytes + borrower_lte: Bytes + borrower_in: [Bytes!] + borrower_not_in: [Bytes!] + borrower_contains: Bytes + borrower_not_contains: Bytes + debt: BigInt + debt_not: BigInt + debt_gt: BigInt + debt_lt: BigInt + debt_gte: BigInt + debt_lte: BigInt + debt_in: [BigInt!] + debt_not_in: [BigInt!] + deposit: BigInt + deposit_not: BigInt + deposit_gt: BigInt + deposit_lt: BigInt + deposit_gte: BigInt + deposit_lte: BigInt + deposit_in: [BigInt!] + deposit_not_in: [BigInt!] + stake: BigInt + stake_not: BigInt + stake_gt: BigInt + stake_lt: BigInt + stake_gte: BigInt + stake_lte: BigInt + stake_in: [BigInt!] + stake_not_in: [BigInt!] + interestRate: BigInt + interestRate_not: BigInt + interestRate_gt: BigInt + interestRate_lt: BigInt + interestRate_gte: BigInt + interestRate_lte: BigInt + interestRate_in: [BigInt!] + interestRate_not_in: [BigInt!] + createdAt: BigInt + createdAt_not: BigInt + createdAt_gt: BigInt + createdAt_lt: BigInt + createdAt_gte: BigInt + createdAt_lte: BigInt + createdAt_in: [BigInt!] + createdAt_not_in: [BigInt!] + closedAt: BigInt + closedAt_not: BigInt + closedAt_gt: BigInt + closedAt_lt: BigInt + closedAt_gte: BigInt + closedAt_lte: BigInt + closedAt_in: [BigInt!] + closedAt_not_in: [BigInt!] + collateral: String + collateral_not: String + collateral_gt: String + collateral_lt: String + collateral_gte: String + collateral_lte: String + collateral_in: [String!] + collateral_not_in: [String!] + collateral_contains: String + collateral_contains_nocase: String + collateral_not_contains: String + collateral_not_contains_nocase: String + collateral_starts_with: String + collateral_starts_with_nocase: String + collateral_not_starts_with: String + collateral_not_starts_with_nocase: String + collateral_ends_with: String + collateral_ends_with_nocase: String + collateral_not_ends_with: String + collateral_not_ends_with_nocase: String + collateral_: Collateral_filter + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Trove_filter] + or: [Trove_filter] +} + +enum Trove_orderBy { + id + borrower + debt + deposit + stake + interestRate + createdAt + closedAt + collateral + collateral__id + collateral__minCollRatio + collateral__totalDeposited + collateral__totalDebt +} + +type _Block_ { + """The hash of the block""" + hash: Bytes + """The block number""" + number: Int! + """Integer representation of the timestamp stored in blocks for the chain""" + timestamp: Int + """The hash of the parent block""" + parentHash: Bytes +} + +"""The type for the top-level _meta field""" +type _Meta_ { + """ + Information about a specific subgraph block. The hash of the block + will be null if the _meta field has a block constraint that asks for + a block number. It will be filled if the _meta field has no block constraint + and therefore asks for the latest block + + """ + block: _Block_! + """The deployment ID""" + deployment: String! + """If `true`, the subgraph encountered indexing errors at some past block""" + hasIndexingErrors: Boolean! +} + +enum _SubgraphErrorPolicy_ { + """Data will be returned even if the subgraph has indexing errors""" + allow + """ + If the subgraph has indexing errors, data will be omitted. The default. + """ + deny +} \ No newline at end of file diff --git a/frontend/app/.graphclient/sources/liquity2/introspectionSchema.ts b/frontend/app/.graphclient/sources/liquity2/introspectionSchema.ts new file mode 100644 index 00000000..4d3350be --- /dev/null +++ b/frontend/app/.graphclient/sources/liquity2/introspectionSchema.ts @@ -0,0 +1,10096 @@ +// @ts-nocheck +import { buildASTSchema } from 'graphql'; + +const schemaAST = { + "kind": "Document", + "definitions": [ + { + "kind": "SchemaDefinition", + "operationTypes": [ + { + "kind": "OperationTypeDefinition", + "operation": "query", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Query" + } + } + }, + { + "kind": "OperationTypeDefinition", + "operation": "subscription", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Subscription" + } + } + } + ], + "directives": [] + }, + { + "kind": "DirectiveDefinition", + "description": { + "kind": "StringValue", + "value": "Marks the GraphQL type as indexable entity. Each type that should be an entity is required to be annotated with this directive.", + "block": true + }, + "name": { + "kind": "Name", + "value": "entity" + }, + "arguments": [], + "repeatable": false, + "locations": [ + { + "kind": "Name", + "value": "OBJECT" + } + ] + }, + { + "kind": "DirectiveDefinition", + "description": { + "kind": "StringValue", + "value": "Defined a Subgraph ID for an object type", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphId" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + "directives": [] + } + ], + "repeatable": false, + "locations": [ + { + "kind": "Name", + "value": "OBJECT" + } + ] + }, + { + "kind": "DirectiveDefinition", + "description": { + "kind": "StringValue", + "value": "creates a virtual field on the entity that may be queried but cannot be set manually through the mappings API.", + "block": true + }, + "name": { + "kind": "Name", + "value": "derivedFrom" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "field" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + "directives": [] + } + ], + "repeatable": false, + "locations": [ + { + "kind": "Name", + "value": "FIELD_DEFINITION" + } + ] + }, + { + "kind": "EnumTypeDefinition", + "name": { + "kind": "Name", + "value": "Aggregation_interval" + }, + "values": [ + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "hour" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "day" + }, + "directives": [] + } + ], + "directives": [] + }, + { + "kind": "ScalarTypeDefinition", + "name": { + "kind": "Name", + "value": "BigDecimal" + }, + "directives": [] + }, + { + "kind": "ScalarTypeDefinition", + "name": { + "kind": "Name", + "value": "BigInt" + }, + "directives": [] + }, + { + "kind": "InputObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "BlockChangedFilter" + }, + "fields": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "number_gte" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + } + }, + "directives": [] + } + ], + "directives": [] + }, + { + "kind": "InputObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "Block_height" + }, + "fields": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "hash" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "number" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "number_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "directives": [] + } + ], + "directives": [] + }, + { + "kind": "ScalarTypeDefinition", + "name": { + "kind": "Name", + "value": "Bytes" + }, + "directives": [] + }, + { + "kind": "ObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "Collateral" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "token" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Token" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "minCollRatio" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "troves" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "skip" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "0" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "first" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "100" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderBy" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Trove_orderBy" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderDirection" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "OrderDirection" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "where" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Trove_filter" + } + }, + "directives": [] + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Trove" + } + } + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "addresses" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "CollateralAddresses" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "totalDeposited" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "totalDebt" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + }, + "directives": [] + } + ], + "interfaces": [], + "directives": [] + }, + { + "kind": "ObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "CollateralAddresses" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "borrowerOperations" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "collateral" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collateral" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "sortedTroves" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "stabilityPool" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "token" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "troveManager" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "troveNft" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + }, + "directives": [] + } + ], + "interfaces": [], + "directives": [] + }, + { + "kind": "InputObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "CollateralAddresses_filter" + }, + "fields": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrowerOperations" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrowerOperations_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrowerOperations_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrowerOperations_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrowerOperations_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrowerOperations_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrowerOperations_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrowerOperations_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrowerOperations_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrowerOperations_not_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_contains_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_contains_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_starts_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_starts_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_starts_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_starts_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_ends_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_ends_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_ends_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_ends_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collateral_filter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "sortedTroves" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "sortedTroves_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "sortedTroves_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "sortedTroves_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "sortedTroves_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "sortedTroves_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "sortedTroves_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "sortedTroves_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "sortedTroves_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "sortedTroves_not_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "stabilityPool" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "stabilityPool_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "stabilityPool_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "stabilityPool_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "stabilityPool_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "stabilityPool_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "stabilityPool_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "stabilityPool_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "stabilityPool_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "stabilityPool_not_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_not_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveManager" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveManager_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveManager_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveManager_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveManager_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveManager_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveManager_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveManager_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveManager_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveManager_not_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveNft" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveNft_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveNft_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveNft_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveNft_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveNft_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveNft_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveNft_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveNft_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troveNft_not_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Filter for the block changed event.", + "block": true + }, + "name": { + "kind": "Name", + "value": "_change_block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BlockChangedFilter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "and" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "CollateralAddresses_filter" + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "or" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "CollateralAddresses_filter" + } + } + }, + "directives": [] + } + ], + "directives": [] + }, + { + "kind": "EnumTypeDefinition", + "name": { + "kind": "Name", + "value": "CollateralAddresses_orderBy" + }, + "values": [ + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "borrowerOperations" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "collateral" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "collateral__id" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "collateral__minCollRatio" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "collateral__totalDeposited" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "collateral__totalDebt" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "sortedTroves" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "stabilityPool" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "token" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "troveManager" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "troveNft" + }, + "directives": [] + } + ], + "directives": [] + }, + { + "kind": "InputObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "Collateral_filter" + }, + "fields": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_contains_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_not_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_not_contains_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_starts_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_starts_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_not_starts_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_not_starts_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_ends_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_ends_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_not_ends_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_not_ends_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "token_" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Token_filter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "minCollRatio" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "minCollRatio_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "minCollRatio_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "minCollRatio_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "minCollRatio_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "minCollRatio_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "minCollRatio_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "minCollRatio_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "troves_" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Trove_filter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "addresses_" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "CollateralAddresses_filter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDeposited" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDeposited_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDeposited_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDeposited_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDeposited_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDeposited_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDeposited_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDeposited_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDebt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDebt_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDebt_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDebt_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDebt_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDebt_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDebt_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDebt_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Filter for the block changed event.", + "block": true + }, + "name": { + "kind": "Name", + "value": "_change_block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BlockChangedFilter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "and" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collateral_filter" + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "or" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collateral_filter" + } + } + }, + "directives": [] + } + ], + "directives": [] + }, + { + "kind": "EnumTypeDefinition", + "name": { + "kind": "Name", + "value": "Collateral_orderBy" + }, + "values": [ + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "token" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "token__id" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "token__name" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "token__symbol" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "token__decimals" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "minCollRatio" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "troves" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "addresses" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "addresses__id" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "addresses__borrowerOperations" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "addresses__sortedTroves" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "addresses__stabilityPool" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "addresses__token" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "addresses__troveManager" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "addresses__troveNft" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "totalDeposited" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "totalDebt" + }, + "directives": [] + } + ], + "directives": [] + }, + { + "kind": "ScalarTypeDefinition", + "description": { + "kind": "StringValue", + "value": "8 bytes signed integer\n", + "block": true + }, + "name": { + "kind": "Name", + "value": "Int8" + }, + "directives": [] + }, + { + "kind": "ObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "InterestRateBracket" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "rate" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "totalDebt" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "totalTroves" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + } + }, + "directives": [] + } + ], + "interfaces": [], + "directives": [] + }, + { + "kind": "InputObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "InterestRateBracket_filter" + }, + "fields": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "rate" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "rate_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "rate_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "rate_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "rate_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "rate_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "rate_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "rate_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDebt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDebt_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDebt_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDebt_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDebt_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDebt_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDebt_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalDebt_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalTroves" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalTroves_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalTroves_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalTroves_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalTroves_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalTroves_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalTroves_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "totalTroves_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Filter for the block changed event.", + "block": true + }, + "name": { + "kind": "Name", + "value": "_change_block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BlockChangedFilter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "and" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "InterestRateBracket_filter" + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "or" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "InterestRateBracket_filter" + } + } + }, + "directives": [] + } + ], + "directives": [] + }, + { + "kind": "EnumTypeDefinition", + "name": { + "kind": "Name", + "value": "InterestRateBracket_orderBy" + }, + "values": [ + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "rate" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "totalDebt" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "totalTroves" + }, + "directives": [] + } + ], + "directives": [] + }, + { + "kind": "EnumTypeDefinition", + "description": { + "kind": "StringValue", + "value": "Defines the order direction, either ascending or descending", + "block": true + }, + "name": { + "kind": "Name", + "value": "OrderDirection" + }, + "values": [ + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "asc" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "desc" + }, + "directives": [] + } + ], + "directives": [] + }, + { + "kind": "ObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "Query" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "collateral" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collateral" + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "collaterals" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "skip" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "0" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "first" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "100" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderBy" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collateral_orderBy" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderDirection" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "OrderDirection" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "where" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collateral_filter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collateral" + } + } + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "token" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Token" + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "tokens" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "skip" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "0" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "first" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "100" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderBy" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Token_orderBy" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderDirection" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "OrderDirection" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "where" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Token_filter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Token" + } + } + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "collateralAddresses" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "CollateralAddresses" + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "collateralAddresses_collection" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "skip" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "0" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "first" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "100" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderBy" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "CollateralAddresses_orderBy" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderDirection" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "OrderDirection" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "where" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "CollateralAddresses_filter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "CollateralAddresses" + } + } + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "interestRateBracket" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "InterestRateBracket" + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "interestRateBrackets" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "skip" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "0" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "first" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "100" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderBy" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "InterestRateBracket_orderBy" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderDirection" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "OrderDirection" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "where" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "InterestRateBracket_filter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "InterestRateBracket" + } + } + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "trove" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Trove" + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "troves" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "skip" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "0" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "first" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "100" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderBy" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Trove_orderBy" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderDirection" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "OrderDirection" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "where" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Trove_filter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Trove" + } + } + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "description": { + "kind": "StringValue", + "value": "Access to subgraph metadata", + "block": true + }, + "name": { + "kind": "Name", + "value": "_meta" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + } + ], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_Meta_" + } + }, + "directives": [] + } + ], + "interfaces": [], + "directives": [] + }, + { + "kind": "ObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "Subscription" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "collateral" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collateral" + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "collaterals" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "skip" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "0" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "first" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "100" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderBy" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collateral_orderBy" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderDirection" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "OrderDirection" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "where" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collateral_filter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collateral" + } + } + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "token" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Token" + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "tokens" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "skip" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "0" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "first" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "100" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderBy" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Token_orderBy" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderDirection" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "OrderDirection" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "where" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Token_filter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Token" + } + } + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "collateralAddresses" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "CollateralAddresses" + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "collateralAddresses_collection" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "skip" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "0" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "first" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "100" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderBy" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "CollateralAddresses_orderBy" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderDirection" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "OrderDirection" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "where" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "CollateralAddresses_filter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "CollateralAddresses" + } + } + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "interestRateBracket" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "InterestRateBracket" + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "interestRateBrackets" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "skip" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "0" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "first" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "100" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderBy" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "InterestRateBracket_orderBy" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderDirection" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "OrderDirection" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "where" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "InterestRateBracket_filter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "InterestRateBracket" + } + } + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "trove" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Trove" + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "troves" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "skip" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "0" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "first" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "defaultValue": { + "kind": "IntValue", + "value": "100" + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderBy" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Trove_orderBy" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "orderDirection" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "OrderDirection" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "where" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Trove_filter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted.", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Set to `allow` to receive data even if the subgraph has skipped over errors while syncing.", + "block": true + }, + "name": { + "kind": "Name", + "value": "subgraphError" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + } + } + }, + "defaultValue": { + "kind": "EnumValue", + "value": "deny" + }, + "directives": [] + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Trove" + } + } + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "description": { + "kind": "StringValue", + "value": "Access to subgraph metadata", + "block": true + }, + "name": { + "kind": "Name", + "value": "_meta" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Block_height" + } + }, + "directives": [] + } + ], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_Meta_" + } + }, + "directives": [] + } + ], + "interfaces": [], + "directives": [] + }, + { + "kind": "ScalarTypeDefinition", + "description": { + "kind": "StringValue", + "value": "A string representation of microseconds UNIX timestamp (16 digits)\n", + "block": true + }, + "name": { + "kind": "Name", + "value": "Timestamp" + }, + "directives": [] + }, + { + "kind": "ObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "Token" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "collateral" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collateral" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "name" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "symbol" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "decimals" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + } + }, + "directives": [] + } + ], + "interfaces": [], + "directives": [] + }, + { + "kind": "InputObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "Token_filter" + }, + "fields": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_contains_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_contains_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_starts_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_starts_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_starts_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_starts_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_ends_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_ends_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_ends_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_ends_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collateral_filter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_contains_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_not_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_not_contains_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_starts_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_starts_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_not_starts_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_not_starts_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_ends_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_ends_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_not_ends_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name_not_ends_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_contains_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_not_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_not_contains_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_starts_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_starts_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_not_starts_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_not_starts_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_ends_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_ends_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_not_ends_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "symbol_not_ends_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "decimals" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "decimals_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "decimals_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "decimals_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "decimals_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "decimals_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "decimals_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "decimals_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Filter for the block changed event.", + "block": true + }, + "name": { + "kind": "Name", + "value": "_change_block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BlockChangedFilter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "and" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Token_filter" + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "or" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Token_filter" + } + } + }, + "directives": [] + } + ], + "directives": [] + }, + { + "kind": "EnumTypeDefinition", + "name": { + "kind": "Name", + "value": "Token_orderBy" + }, + "values": [ + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "collateral" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "collateral__id" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "collateral__minCollRatio" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "collateral__totalDeposited" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "collateral__totalDebt" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "name" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "symbol" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "decimals" + }, + "directives": [] + } + ], + "directives": [] + }, + { + "kind": "ObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "Trove" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "borrower" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "debt" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "deposit" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "stake" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "interestRate" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "createdAt" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "closedAt" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "collateral" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collateral" + } + } + }, + "directives": [] + } + ], + "interfaces": [], + "directives": [] + }, + { + "kind": "InputObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "Trove_filter" + }, + "fields": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrower" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrower_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrower_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrower_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrower_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrower_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrower_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrower_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrower_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "borrower_not_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "debt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "debt_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "debt_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "debt_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "debt_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "debt_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "debt_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "debt_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "deposit" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "deposit_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "deposit_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "deposit_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "deposit_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "deposit_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "deposit_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "deposit_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "stake" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "stake_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "stake_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "stake_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "stake_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "stake_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "stake_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "stake_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "interestRate" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "interestRate_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "interestRate_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "interestRate_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "interestRate_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "interestRate_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "interestRate_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "interestRate_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "createdAt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "createdAt_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "createdAt_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "createdAt_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "createdAt_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "createdAt_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "createdAt_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "createdAt_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "closedAt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "closedAt_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "closedAt_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "closedAt_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "closedAt_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "closedAt_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "closedAt_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "closedAt_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BigInt" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_gt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_lt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_gte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_lte" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_in" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_contains_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_contains" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_contains_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_starts_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_starts_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_starts_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_starts_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_ends_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_ends_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_ends_with" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_not_ends_with_nocase" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collateral_" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collateral_filter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "description": { + "kind": "StringValue", + "value": "Filter for the block changed event.", + "block": true + }, + "name": { + "kind": "Name", + "value": "_change_block" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "BlockChangedFilter" + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "and" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Trove_filter" + } + } + }, + "directives": [] + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "or" + }, + "type": { + "kind": "ListType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Trove_filter" + } + } + }, + "directives": [] + } + ], + "directives": [] + }, + { + "kind": "EnumTypeDefinition", + "name": { + "kind": "Name", + "value": "Trove_orderBy" + }, + "values": [ + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "borrower" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "debt" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "deposit" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "stake" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "interestRate" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "createdAt" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "closedAt" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "collateral" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "collateral__id" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "collateral__minCollRatio" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "collateral__totalDeposited" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "name": { + "kind": "Name", + "value": "collateral__totalDebt" + }, + "directives": [] + } + ], + "directives": [] + }, + { + "kind": "ObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "_Block_" + }, + "fields": [ + { + "kind": "FieldDefinition", + "description": { + "kind": "StringValue", + "value": "The hash of the block", + "block": true + }, + "name": { + "kind": "Name", + "value": "hash" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "description": { + "kind": "StringValue", + "value": "The block number", + "block": true + }, + "name": { + "kind": "Name", + "value": "number" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "description": { + "kind": "StringValue", + "value": "Integer representation of the timestamp stored in blocks for the chain", + "block": true + }, + "name": { + "kind": "Name", + "value": "timestamp" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Int" + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "description": { + "kind": "StringValue", + "value": "The hash of the parent block", + "block": true + }, + "name": { + "kind": "Name", + "value": "parentHash" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Bytes" + } + }, + "directives": [] + } + ], + "interfaces": [], + "directives": [] + }, + { + "kind": "ObjectTypeDefinition", + "description": { + "kind": "StringValue", + "value": "The type for the top-level _meta field", + "block": true + }, + "name": { + "kind": "Name", + "value": "_Meta_" + }, + "fields": [ + { + "kind": "FieldDefinition", + "description": { + "kind": "StringValue", + "value": "Information about a specific subgraph block. The hash of the block\nwill be null if the _meta field has a block constraint that asks for\na block number. It will be filled if the _meta field has no block constraint\nand therefore asks for the latest block\n", + "block": true + }, + "name": { + "kind": "Name", + "value": "block" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "_Block_" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "description": { + "kind": "StringValue", + "value": "The deployment ID", + "block": true + }, + "name": { + "kind": "Name", + "value": "deployment" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + "directives": [] + }, + { + "kind": "FieldDefinition", + "description": { + "kind": "StringValue", + "value": "If `true`, the subgraph encountered indexing errors at some past block", + "block": true + }, + "name": { + "kind": "Name", + "value": "hasIndexingErrors" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Boolean" + } + } + }, + "directives": [] + } + ], + "interfaces": [], + "directives": [] + }, + { + "kind": "EnumTypeDefinition", + "name": { + "kind": "Name", + "value": "_SubgraphErrorPolicy_" + }, + "values": [ + { + "kind": "EnumValueDefinition", + "description": { + "kind": "StringValue", + "value": "Data will be returned even if the subgraph has indexing errors", + "block": true + }, + "name": { + "kind": "Name", + "value": "allow" + }, + "directives": [] + }, + { + "kind": "EnumValueDefinition", + "description": { + "kind": "StringValue", + "value": "If the subgraph has indexing errors, data will be omitted. The default.", + "block": true + }, + "name": { + "kind": "Name", + "value": "deny" + }, + "directives": [] + } + ], + "directives": [] + } + ] +}; + +export default buildASTSchema(schemaAST, { + assumeValid: true, + assumeValidSDL: true +}); \ No newline at end of file diff --git a/frontend/app/.graphclient/sources/liquity2/schema.graphql b/frontend/app/.graphclient/sources/liquity2/schema.graphql new file mode 100644 index 00000000..d53c0294 --- /dev/null +++ b/frontend/app/.graphclient/sources/liquity2/schema.graphql @@ -0,0 +1,856 @@ +schema { + query: Query + subscription: Subscription +} + +""" +Marks the GraphQL type as indexable entity. Each type that should be an entity is required to be annotated with this directive. +""" +directive @entity on OBJECT + +"""Defined a Subgraph ID for an object type""" +directive @subgraphId(id: String!) on OBJECT + +""" +creates a virtual field on the entity that may be queried but cannot be set manually through the mappings API. +""" +directive @derivedFrom(field: String!) on FIELD_DEFINITION + +enum Aggregation_interval { + hour + day +} + +scalar BigDecimal + +scalar BigInt + +input BlockChangedFilter { + number_gte: Int! +} + +input Block_height { + hash: Bytes + number: Int + number_gte: Int +} + +scalar Bytes + +type Collateral { + id: ID! + token: Token! + minCollRatio: BigInt! + troves(skip: Int = 0, first: Int = 100, orderBy: Trove_orderBy, orderDirection: OrderDirection, where: Trove_filter): [Trove!]! + addresses: CollateralAddresses! + totalDeposited: BigInt! + totalDebt: BigInt! +} + +type CollateralAddresses { + id: ID! + borrowerOperations: Bytes! + collateral: Collateral! + sortedTroves: Bytes! + stabilityPool: Bytes! + token: Bytes! + troveManager: Bytes! + troveNft: Bytes! +} + +input CollateralAddresses_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + borrowerOperations: Bytes + borrowerOperations_not: Bytes + borrowerOperations_gt: Bytes + borrowerOperations_lt: Bytes + borrowerOperations_gte: Bytes + borrowerOperations_lte: Bytes + borrowerOperations_in: [Bytes!] + borrowerOperations_not_in: [Bytes!] + borrowerOperations_contains: Bytes + borrowerOperations_not_contains: Bytes + collateral: String + collateral_not: String + collateral_gt: String + collateral_lt: String + collateral_gte: String + collateral_lte: String + collateral_in: [String!] + collateral_not_in: [String!] + collateral_contains: String + collateral_contains_nocase: String + collateral_not_contains: String + collateral_not_contains_nocase: String + collateral_starts_with: String + collateral_starts_with_nocase: String + collateral_not_starts_with: String + collateral_not_starts_with_nocase: String + collateral_ends_with: String + collateral_ends_with_nocase: String + collateral_not_ends_with: String + collateral_not_ends_with_nocase: String + collateral_: Collateral_filter + sortedTroves: Bytes + sortedTroves_not: Bytes + sortedTroves_gt: Bytes + sortedTroves_lt: Bytes + sortedTroves_gte: Bytes + sortedTroves_lte: Bytes + sortedTroves_in: [Bytes!] + sortedTroves_not_in: [Bytes!] + sortedTroves_contains: Bytes + sortedTroves_not_contains: Bytes + stabilityPool: Bytes + stabilityPool_not: Bytes + stabilityPool_gt: Bytes + stabilityPool_lt: Bytes + stabilityPool_gte: Bytes + stabilityPool_lte: Bytes + stabilityPool_in: [Bytes!] + stabilityPool_not_in: [Bytes!] + stabilityPool_contains: Bytes + stabilityPool_not_contains: Bytes + token: Bytes + token_not: Bytes + token_gt: Bytes + token_lt: Bytes + token_gte: Bytes + token_lte: Bytes + token_in: [Bytes!] + token_not_in: [Bytes!] + token_contains: Bytes + token_not_contains: Bytes + troveManager: Bytes + troveManager_not: Bytes + troveManager_gt: Bytes + troveManager_lt: Bytes + troveManager_gte: Bytes + troveManager_lte: Bytes + troveManager_in: [Bytes!] + troveManager_not_in: [Bytes!] + troveManager_contains: Bytes + troveManager_not_contains: Bytes + troveNft: Bytes + troveNft_not: Bytes + troveNft_gt: Bytes + troveNft_lt: Bytes + troveNft_gte: Bytes + troveNft_lte: Bytes + troveNft_in: [Bytes!] + troveNft_not_in: [Bytes!] + troveNft_contains: Bytes + troveNft_not_contains: Bytes + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [CollateralAddresses_filter] + or: [CollateralAddresses_filter] +} + +enum CollateralAddresses_orderBy { + id + borrowerOperations + collateral + collateral__id + collateral__minCollRatio + collateral__totalDeposited + collateral__totalDebt + sortedTroves + stabilityPool + token + troveManager + troveNft +} + +input Collateral_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + token: String + token_not: String + token_gt: String + token_lt: String + token_gte: String + token_lte: String + token_in: [String!] + token_not_in: [String!] + token_contains: String + token_contains_nocase: String + token_not_contains: String + token_not_contains_nocase: String + token_starts_with: String + token_starts_with_nocase: String + token_not_starts_with: String + token_not_starts_with_nocase: String + token_ends_with: String + token_ends_with_nocase: String + token_not_ends_with: String + token_not_ends_with_nocase: String + token_: Token_filter + minCollRatio: BigInt + minCollRatio_not: BigInt + minCollRatio_gt: BigInt + minCollRatio_lt: BigInt + minCollRatio_gte: BigInt + minCollRatio_lte: BigInt + minCollRatio_in: [BigInt!] + minCollRatio_not_in: [BigInt!] + troves_: Trove_filter + addresses_: CollateralAddresses_filter + totalDeposited: BigInt + totalDeposited_not: BigInt + totalDeposited_gt: BigInt + totalDeposited_lt: BigInt + totalDeposited_gte: BigInt + totalDeposited_lte: BigInt + totalDeposited_in: [BigInt!] + totalDeposited_not_in: [BigInt!] + totalDebt: BigInt + totalDebt_not: BigInt + totalDebt_gt: BigInt + totalDebt_lt: BigInt + totalDebt_gte: BigInt + totalDebt_lte: BigInt + totalDebt_in: [BigInt!] + totalDebt_not_in: [BigInt!] + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Collateral_filter] + or: [Collateral_filter] +} + +enum Collateral_orderBy { + id + token + token__id + token__name + token__symbol + token__decimals + minCollRatio + troves + addresses + addresses__id + addresses__borrowerOperations + addresses__sortedTroves + addresses__stabilityPool + addresses__token + addresses__troveManager + addresses__troveNft + totalDeposited + totalDebt +} + +""" +8 bytes signed integer + +""" +scalar Int8 + +type InterestRateBracket { + id: ID! + rate: BigInt! + totalDebt: BigInt! + totalTroves: Int! +} + +input InterestRateBracket_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + rate: BigInt + rate_not: BigInt + rate_gt: BigInt + rate_lt: BigInt + rate_gte: BigInt + rate_lte: BigInt + rate_in: [BigInt!] + rate_not_in: [BigInt!] + totalDebt: BigInt + totalDebt_not: BigInt + totalDebt_gt: BigInt + totalDebt_lt: BigInt + totalDebt_gte: BigInt + totalDebt_lte: BigInt + totalDebt_in: [BigInt!] + totalDebt_not_in: [BigInt!] + totalTroves: Int + totalTroves_not: Int + totalTroves_gt: Int + totalTroves_lt: Int + totalTroves_gte: Int + totalTroves_lte: Int + totalTroves_in: [Int!] + totalTroves_not_in: [Int!] + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [InterestRateBracket_filter] + or: [InterestRateBracket_filter] +} + +enum InterestRateBracket_orderBy { + id + rate + totalDebt + totalTroves +} + +"""Defines the order direction, either ascending or descending""" +enum OrderDirection { + asc + desc +} + +type Query { + collateral( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Collateral + collaterals( + skip: Int = 0 + first: Int = 100 + orderBy: Collateral_orderBy + orderDirection: OrderDirection + where: Collateral_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Collateral!]! + token( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Token + tokens( + skip: Int = 0 + first: Int = 100 + orderBy: Token_orderBy + orderDirection: OrderDirection + where: Token_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Token!]! + collateralAddresses( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): CollateralAddresses + collateralAddresses_collection( + skip: Int = 0 + first: Int = 100 + orderBy: CollateralAddresses_orderBy + orderDirection: OrderDirection + where: CollateralAddresses_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [CollateralAddresses!]! + interestRateBracket( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): InterestRateBracket + interestRateBrackets( + skip: Int = 0 + first: Int = 100 + orderBy: InterestRateBracket_orderBy + orderDirection: OrderDirection + where: InterestRateBracket_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [InterestRateBracket!]! + trove( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Trove + troves( + skip: Int = 0 + first: Int = 100 + orderBy: Trove_orderBy + orderDirection: OrderDirection + where: Trove_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Trove!]! + """Access to subgraph metadata""" + _meta(block: Block_height): _Meta_ +} + +type Subscription { + collateral( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Collateral + collaterals( + skip: Int = 0 + first: Int = 100 + orderBy: Collateral_orderBy + orderDirection: OrderDirection + where: Collateral_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Collateral!]! + token( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Token + tokens( + skip: Int = 0 + first: Int = 100 + orderBy: Token_orderBy + orderDirection: OrderDirection + where: Token_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Token!]! + collateralAddresses( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): CollateralAddresses + collateralAddresses_collection( + skip: Int = 0 + first: Int = 100 + orderBy: CollateralAddresses_orderBy + orderDirection: OrderDirection + where: CollateralAddresses_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [CollateralAddresses!]! + interestRateBracket( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): InterestRateBracket + interestRateBrackets( + skip: Int = 0 + first: Int = 100 + orderBy: InterestRateBracket_orderBy + orderDirection: OrderDirection + where: InterestRateBracket_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [InterestRateBracket!]! + trove( + id: ID! + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Trove + troves( + skip: Int = 0 + first: Int = 100 + orderBy: Trove_orderBy + orderDirection: OrderDirection + where: Trove_filter + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Trove!]! + """Access to subgraph metadata""" + _meta(block: Block_height): _Meta_ +} + +""" +A string representation of microseconds UNIX timestamp (16 digits) + +""" +scalar Timestamp + +type Token { + id: ID! + collateral: Collateral! + name: String! + symbol: String! + decimals: Int! +} + +input Token_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + collateral: String + collateral_not: String + collateral_gt: String + collateral_lt: String + collateral_gte: String + collateral_lte: String + collateral_in: [String!] + collateral_not_in: [String!] + collateral_contains: String + collateral_contains_nocase: String + collateral_not_contains: String + collateral_not_contains_nocase: String + collateral_starts_with: String + collateral_starts_with_nocase: String + collateral_not_starts_with: String + collateral_not_starts_with_nocase: String + collateral_ends_with: String + collateral_ends_with_nocase: String + collateral_not_ends_with: String + collateral_not_ends_with_nocase: String + collateral_: Collateral_filter + name: String + name_not: String + name_gt: String + name_lt: String + name_gte: String + name_lte: String + name_in: [String!] + name_not_in: [String!] + name_contains: String + name_contains_nocase: String + name_not_contains: String + name_not_contains_nocase: String + name_starts_with: String + name_starts_with_nocase: String + name_not_starts_with: String + name_not_starts_with_nocase: String + name_ends_with: String + name_ends_with_nocase: String + name_not_ends_with: String + name_not_ends_with_nocase: String + symbol: String + symbol_not: String + symbol_gt: String + symbol_lt: String + symbol_gte: String + symbol_lte: String + symbol_in: [String!] + symbol_not_in: [String!] + symbol_contains: String + symbol_contains_nocase: String + symbol_not_contains: String + symbol_not_contains_nocase: String + symbol_starts_with: String + symbol_starts_with_nocase: String + symbol_not_starts_with: String + symbol_not_starts_with_nocase: String + symbol_ends_with: String + symbol_ends_with_nocase: String + symbol_not_ends_with: String + symbol_not_ends_with_nocase: String + decimals: Int + decimals_not: Int + decimals_gt: Int + decimals_lt: Int + decimals_gte: Int + decimals_lte: Int + decimals_in: [Int!] + decimals_not_in: [Int!] + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Token_filter] + or: [Token_filter] +} + +enum Token_orderBy { + id + collateral + collateral__id + collateral__minCollRatio + collateral__totalDeposited + collateral__totalDebt + name + symbol + decimals +} + +type Trove { + id: ID! + borrower: Bytes! + debt: BigInt! + deposit: BigInt! + stake: BigInt! + interestRate: BigInt! + createdAt: BigInt! + closedAt: BigInt + collateral: Collateral! +} + +input Trove_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + borrower: Bytes + borrower_not: Bytes + borrower_gt: Bytes + borrower_lt: Bytes + borrower_gte: Bytes + borrower_lte: Bytes + borrower_in: [Bytes!] + borrower_not_in: [Bytes!] + borrower_contains: Bytes + borrower_not_contains: Bytes + debt: BigInt + debt_not: BigInt + debt_gt: BigInt + debt_lt: BigInt + debt_gte: BigInt + debt_lte: BigInt + debt_in: [BigInt!] + debt_not_in: [BigInt!] + deposit: BigInt + deposit_not: BigInt + deposit_gt: BigInt + deposit_lt: BigInt + deposit_gte: BigInt + deposit_lte: BigInt + deposit_in: [BigInt!] + deposit_not_in: [BigInt!] + stake: BigInt + stake_not: BigInt + stake_gt: BigInt + stake_lt: BigInt + stake_gte: BigInt + stake_lte: BigInt + stake_in: [BigInt!] + stake_not_in: [BigInt!] + interestRate: BigInt + interestRate_not: BigInt + interestRate_gt: BigInt + interestRate_lt: BigInt + interestRate_gte: BigInt + interestRate_lte: BigInt + interestRate_in: [BigInt!] + interestRate_not_in: [BigInt!] + createdAt: BigInt + createdAt_not: BigInt + createdAt_gt: BigInt + createdAt_lt: BigInt + createdAt_gte: BigInt + createdAt_lte: BigInt + createdAt_in: [BigInt!] + createdAt_not_in: [BigInt!] + closedAt: BigInt + closedAt_not: BigInt + closedAt_gt: BigInt + closedAt_lt: BigInt + closedAt_gte: BigInt + closedAt_lte: BigInt + closedAt_in: [BigInt!] + closedAt_not_in: [BigInt!] + collateral: String + collateral_not: String + collateral_gt: String + collateral_lt: String + collateral_gte: String + collateral_lte: String + collateral_in: [String!] + collateral_not_in: [String!] + collateral_contains: String + collateral_contains_nocase: String + collateral_not_contains: String + collateral_not_contains_nocase: String + collateral_starts_with: String + collateral_starts_with_nocase: String + collateral_not_starts_with: String + collateral_not_starts_with_nocase: String + collateral_ends_with: String + collateral_ends_with_nocase: String + collateral_not_ends_with: String + collateral_not_ends_with_nocase: String + collateral_: Collateral_filter + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Trove_filter] + or: [Trove_filter] +} + +enum Trove_orderBy { + id + borrower + debt + deposit + stake + interestRate + createdAt + closedAt + collateral + collateral__id + collateral__minCollRatio + collateral__totalDeposited + collateral__totalDebt +} + +type _Block_ { + """The hash of the block""" + hash: Bytes + """The block number""" + number: Int! + """Integer representation of the timestamp stored in blocks for the chain""" + timestamp: Int + """The hash of the parent block""" + parentHash: Bytes +} + +"""The type for the top-level _meta field""" +type _Meta_ { + """ + Information about a specific subgraph block. The hash of the block + will be null if the _meta field has a block constraint that asks for + a block number. It will be filled if the _meta field has no block constraint + and therefore asks for the latest block + + """ + block: _Block_! + """The deployment ID""" + deployment: String! + """If `true`, the subgraph encountered indexing errors at some past block""" + hasIndexingErrors: Boolean! +} + +enum _SubgraphErrorPolicy_ { + """Data will be returned even if the subgraph has indexing errors""" + allow + """ + If the subgraph has indexing errors, data will be omitted. The default. + """ + deny +} \ No newline at end of file diff --git a/frontend/app/.graphclient/sources/liquity2/types.ts b/frontend/app/.graphclient/sources/liquity2/types.ts new file mode 100644 index 00000000..4852f8c1 --- /dev/null +++ b/frontend/app/.graphclient/sources/liquity2/types.ts @@ -0,0 +1,856 @@ +// @ts-nocheck + +import { InContextSdkMethod } from '@graphql-mesh/types'; +import { MeshContext } from '@graphql-mesh/runtime'; + +export namespace Liquity2Types { + export type Maybe = T | null; +export type InputMaybe = Maybe; +export type Exact = { [K in keyof T]: T[K] }; +export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; +export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; +export type MakeEmpty = { [_ in K]?: never }; +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; +/** All built-in and custom scalars, mapped to their actual values */ +export type Scalars = { + ID: { input: string; output: string; } + String: { input: string; output: string; } + Boolean: { input: boolean; output: boolean; } + Int: { input: number; output: number; } + Float: { input: number; output: number; } + BigDecimal: { input: bigint; output: bigint; } + BigInt: { input: bigint; output: bigint; } + Bytes: { input: string; output: string; } + Int8: { input: number; output: number; } + Timestamp: { input: string; output: string; } +}; + +export type Aggregation_interval = + | 'hour' + | 'day'; + +export type BlockChangedFilter = { + readonly number_gte: Scalars['Int']['input']; +}; + +export type Block_height = { + readonly hash?: InputMaybe; + readonly number?: InputMaybe; + readonly number_gte?: InputMaybe; +}; + +export type Collateral = { + readonly id: Scalars['ID']['output']; + readonly token: Token; + readonly minCollRatio: Scalars['BigInt']['output']; + readonly troves: ReadonlyArray; + readonly addresses: CollateralAddresses; + readonly totalDeposited: Scalars['BigInt']['output']; + readonly totalDebt: Scalars['BigInt']['output']; +}; + + +export type CollateraltrovesArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; +}; + +export type CollateralAddresses = { + readonly id: Scalars['ID']['output']; + readonly borrowerOperations: Scalars['Bytes']['output']; + readonly collateral: Collateral; + readonly sortedTroves: Scalars['Bytes']['output']; + readonly stabilityPool: Scalars['Bytes']['output']; + readonly token: Scalars['Bytes']['output']; + readonly troveManager: Scalars['Bytes']['output']; + readonly troveNft: Scalars['Bytes']['output']; +}; + +export type CollateralAddresses_filter = { + readonly id?: InputMaybe; + readonly id_not?: InputMaybe; + readonly id_gt?: InputMaybe; + readonly id_lt?: InputMaybe; + readonly id_gte?: InputMaybe; + readonly id_lte?: InputMaybe; + readonly id_in?: InputMaybe>; + readonly id_not_in?: InputMaybe>; + readonly borrowerOperations?: InputMaybe; + readonly borrowerOperations_not?: InputMaybe; + readonly borrowerOperations_gt?: InputMaybe; + readonly borrowerOperations_lt?: InputMaybe; + readonly borrowerOperations_gte?: InputMaybe; + readonly borrowerOperations_lte?: InputMaybe; + readonly borrowerOperations_in?: InputMaybe>; + readonly borrowerOperations_not_in?: InputMaybe>; + readonly borrowerOperations_contains?: InputMaybe; + readonly borrowerOperations_not_contains?: InputMaybe; + readonly collateral?: InputMaybe; + readonly collateral_not?: InputMaybe; + readonly collateral_gt?: InputMaybe; + readonly collateral_lt?: InputMaybe; + readonly collateral_gte?: InputMaybe; + readonly collateral_lte?: InputMaybe; + readonly collateral_in?: InputMaybe>; + readonly collateral_not_in?: InputMaybe>; + readonly collateral_contains?: InputMaybe; + readonly collateral_contains_nocase?: InputMaybe; + readonly collateral_not_contains?: InputMaybe; + readonly collateral_not_contains_nocase?: InputMaybe; + readonly collateral_starts_with?: InputMaybe; + readonly collateral_starts_with_nocase?: InputMaybe; + readonly collateral_not_starts_with?: InputMaybe; + readonly collateral_not_starts_with_nocase?: InputMaybe; + readonly collateral_ends_with?: InputMaybe; + readonly collateral_ends_with_nocase?: InputMaybe; + readonly collateral_not_ends_with?: InputMaybe; + readonly collateral_not_ends_with_nocase?: InputMaybe; + readonly collateral_?: InputMaybe; + readonly sortedTroves?: InputMaybe; + readonly sortedTroves_not?: InputMaybe; + readonly sortedTroves_gt?: InputMaybe; + readonly sortedTroves_lt?: InputMaybe; + readonly sortedTroves_gte?: InputMaybe; + readonly sortedTroves_lte?: InputMaybe; + readonly sortedTroves_in?: InputMaybe>; + readonly sortedTroves_not_in?: InputMaybe>; + readonly sortedTroves_contains?: InputMaybe; + readonly sortedTroves_not_contains?: InputMaybe; + readonly stabilityPool?: InputMaybe; + readonly stabilityPool_not?: InputMaybe; + readonly stabilityPool_gt?: InputMaybe; + readonly stabilityPool_lt?: InputMaybe; + readonly stabilityPool_gte?: InputMaybe; + readonly stabilityPool_lte?: InputMaybe; + readonly stabilityPool_in?: InputMaybe>; + readonly stabilityPool_not_in?: InputMaybe>; + readonly stabilityPool_contains?: InputMaybe; + readonly stabilityPool_not_contains?: InputMaybe; + readonly token?: InputMaybe; + readonly token_not?: InputMaybe; + readonly token_gt?: InputMaybe; + readonly token_lt?: InputMaybe; + readonly token_gte?: InputMaybe; + readonly token_lte?: InputMaybe; + readonly token_in?: InputMaybe>; + readonly token_not_in?: InputMaybe>; + readonly token_contains?: InputMaybe; + readonly token_not_contains?: InputMaybe; + readonly troveManager?: InputMaybe; + readonly troveManager_not?: InputMaybe; + readonly troveManager_gt?: InputMaybe; + readonly troveManager_lt?: InputMaybe; + readonly troveManager_gte?: InputMaybe; + readonly troveManager_lte?: InputMaybe; + readonly troveManager_in?: InputMaybe>; + readonly troveManager_not_in?: InputMaybe>; + readonly troveManager_contains?: InputMaybe; + readonly troveManager_not_contains?: InputMaybe; + readonly troveNft?: InputMaybe; + readonly troveNft_not?: InputMaybe; + readonly troveNft_gt?: InputMaybe; + readonly troveNft_lt?: InputMaybe; + readonly troveNft_gte?: InputMaybe; + readonly troveNft_lte?: InputMaybe; + readonly troveNft_in?: InputMaybe>; + readonly troveNft_not_in?: InputMaybe>; + readonly troveNft_contains?: InputMaybe; + readonly troveNft_not_contains?: InputMaybe; + /** Filter for the block changed event. */ + readonly _change_block?: InputMaybe; + readonly and?: InputMaybe>>; + readonly or?: InputMaybe>>; +}; + +export type CollateralAddresses_orderBy = + | 'id' + | 'borrowerOperations' + | 'collateral' + | 'collateral__id' + | 'collateral__minCollRatio' + | 'collateral__totalDeposited' + | 'collateral__totalDebt' + | 'sortedTroves' + | 'stabilityPool' + | 'token' + | 'troveManager' + | 'troveNft'; + +export type Collateral_filter = { + readonly id?: InputMaybe; + readonly id_not?: InputMaybe; + readonly id_gt?: InputMaybe; + readonly id_lt?: InputMaybe; + readonly id_gte?: InputMaybe; + readonly id_lte?: InputMaybe; + readonly id_in?: InputMaybe>; + readonly id_not_in?: InputMaybe>; + readonly token?: InputMaybe; + readonly token_not?: InputMaybe; + readonly token_gt?: InputMaybe; + readonly token_lt?: InputMaybe; + readonly token_gte?: InputMaybe; + readonly token_lte?: InputMaybe; + readonly token_in?: InputMaybe>; + readonly token_not_in?: InputMaybe>; + readonly token_contains?: InputMaybe; + readonly token_contains_nocase?: InputMaybe; + readonly token_not_contains?: InputMaybe; + readonly token_not_contains_nocase?: InputMaybe; + readonly token_starts_with?: InputMaybe; + readonly token_starts_with_nocase?: InputMaybe; + readonly token_not_starts_with?: InputMaybe; + readonly token_not_starts_with_nocase?: InputMaybe; + readonly token_ends_with?: InputMaybe; + readonly token_ends_with_nocase?: InputMaybe; + readonly token_not_ends_with?: InputMaybe; + readonly token_not_ends_with_nocase?: InputMaybe; + readonly token_?: InputMaybe; + readonly minCollRatio?: InputMaybe; + readonly minCollRatio_not?: InputMaybe; + readonly minCollRatio_gt?: InputMaybe; + readonly minCollRatio_lt?: InputMaybe; + readonly minCollRatio_gte?: InputMaybe; + readonly minCollRatio_lte?: InputMaybe; + readonly minCollRatio_in?: InputMaybe>; + readonly minCollRatio_not_in?: InputMaybe>; + readonly troves_?: InputMaybe; + readonly addresses_?: InputMaybe; + readonly totalDeposited?: InputMaybe; + readonly totalDeposited_not?: InputMaybe; + readonly totalDeposited_gt?: InputMaybe; + readonly totalDeposited_lt?: InputMaybe; + readonly totalDeposited_gte?: InputMaybe; + readonly totalDeposited_lte?: InputMaybe; + readonly totalDeposited_in?: InputMaybe>; + readonly totalDeposited_not_in?: InputMaybe>; + readonly totalDebt?: InputMaybe; + readonly totalDebt_not?: InputMaybe; + readonly totalDebt_gt?: InputMaybe; + readonly totalDebt_lt?: InputMaybe; + readonly totalDebt_gte?: InputMaybe; + readonly totalDebt_lte?: InputMaybe; + readonly totalDebt_in?: InputMaybe>; + readonly totalDebt_not_in?: InputMaybe>; + /** Filter for the block changed event. */ + readonly _change_block?: InputMaybe; + readonly and?: InputMaybe>>; + readonly or?: InputMaybe>>; +}; + +export type Collateral_orderBy = + | 'id' + | 'token' + | 'token__id' + | 'token__name' + | 'token__symbol' + | 'token__decimals' + | 'minCollRatio' + | 'troves' + | 'addresses' + | 'addresses__id' + | 'addresses__borrowerOperations' + | 'addresses__sortedTroves' + | 'addresses__stabilityPool' + | 'addresses__token' + | 'addresses__troveManager' + | 'addresses__troveNft' + | 'totalDeposited' + | 'totalDebt'; + +export type InterestRateBracket = { + readonly id: Scalars['ID']['output']; + readonly rate: Scalars['BigInt']['output']; + readonly totalDebt: Scalars['BigInt']['output']; + readonly totalTroves: Scalars['Int']['output']; +}; + +export type InterestRateBracket_filter = { + readonly id?: InputMaybe; + readonly id_not?: InputMaybe; + readonly id_gt?: InputMaybe; + readonly id_lt?: InputMaybe; + readonly id_gte?: InputMaybe; + readonly id_lte?: InputMaybe; + readonly id_in?: InputMaybe>; + readonly id_not_in?: InputMaybe>; + readonly rate?: InputMaybe; + readonly rate_not?: InputMaybe; + readonly rate_gt?: InputMaybe; + readonly rate_lt?: InputMaybe; + readonly rate_gte?: InputMaybe; + readonly rate_lte?: InputMaybe; + readonly rate_in?: InputMaybe>; + readonly rate_not_in?: InputMaybe>; + readonly totalDebt?: InputMaybe; + readonly totalDebt_not?: InputMaybe; + readonly totalDebt_gt?: InputMaybe; + readonly totalDebt_lt?: InputMaybe; + readonly totalDebt_gte?: InputMaybe; + readonly totalDebt_lte?: InputMaybe; + readonly totalDebt_in?: InputMaybe>; + readonly totalDebt_not_in?: InputMaybe>; + readonly totalTroves?: InputMaybe; + readonly totalTroves_not?: InputMaybe; + readonly totalTroves_gt?: InputMaybe; + readonly totalTroves_lt?: InputMaybe; + readonly totalTroves_gte?: InputMaybe; + readonly totalTroves_lte?: InputMaybe; + readonly totalTroves_in?: InputMaybe>; + readonly totalTroves_not_in?: InputMaybe>; + /** Filter for the block changed event. */ + readonly _change_block?: InputMaybe; + readonly and?: InputMaybe>>; + readonly or?: InputMaybe>>; +}; + +export type InterestRateBracket_orderBy = + | 'id' + | 'rate' + | 'totalDebt' + | 'totalTroves'; + +/** Defines the order direction, either ascending or descending */ +export type OrderDirection = + | 'asc' + | 'desc'; + +export type Query = { + readonly collateral?: Maybe; + readonly collaterals: ReadonlyArray; + readonly token?: Maybe; + readonly tokens: ReadonlyArray; + readonly collateralAddresses?: Maybe; + readonly collateralAddresses_collection: ReadonlyArray; + readonly interestRateBracket?: Maybe; + readonly interestRateBrackets: ReadonlyArray; + readonly trove?: Maybe; + readonly troves: ReadonlyArray; + /** Access to subgraph metadata */ + readonly _meta?: Maybe<_Meta_>; +}; + + +export type QuerycollateralArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QuerycollateralsArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QuerytokenArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QuerytokensArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QuerycollateralAddressesArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QuerycollateralAddresses_collectionArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QueryinterestRateBracketArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QueryinterestRateBracketsArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QuerytroveArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QuerytrovesArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type Query_metaArgs = { + block?: InputMaybe; +}; + +export type Subscription = { + readonly collateral?: Maybe; + readonly collaterals: ReadonlyArray; + readonly token?: Maybe; + readonly tokens: ReadonlyArray; + readonly collateralAddresses?: Maybe; + readonly collateralAddresses_collection: ReadonlyArray; + readonly interestRateBracket?: Maybe; + readonly interestRateBrackets: ReadonlyArray; + readonly trove?: Maybe; + readonly troves: ReadonlyArray; + /** Access to subgraph metadata */ + readonly _meta?: Maybe<_Meta_>; +}; + + +export type SubscriptioncollateralArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptioncollateralsArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptiontokenArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptiontokensArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptioncollateralAddressesArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptioncollateralAddresses_collectionArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptioninterestRateBracketArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptioninterestRateBracketsArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptiontroveArgs = { + id: Scalars['ID']['input']; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptiontrovesArgs = { + skip?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + where?: InputMaybe; + block?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type Subscription_metaArgs = { + block?: InputMaybe; +}; + +export type Token = { + readonly id: Scalars['ID']['output']; + readonly collateral: Collateral; + readonly name: Scalars['String']['output']; + readonly symbol: Scalars['String']['output']; + readonly decimals: Scalars['Int']['output']; +}; + +export type Token_filter = { + readonly id?: InputMaybe; + readonly id_not?: InputMaybe; + readonly id_gt?: InputMaybe; + readonly id_lt?: InputMaybe; + readonly id_gte?: InputMaybe; + readonly id_lte?: InputMaybe; + readonly id_in?: InputMaybe>; + readonly id_not_in?: InputMaybe>; + readonly collateral?: InputMaybe; + readonly collateral_not?: InputMaybe; + readonly collateral_gt?: InputMaybe; + readonly collateral_lt?: InputMaybe; + readonly collateral_gte?: InputMaybe; + readonly collateral_lte?: InputMaybe; + readonly collateral_in?: InputMaybe>; + readonly collateral_not_in?: InputMaybe>; + readonly collateral_contains?: InputMaybe; + readonly collateral_contains_nocase?: InputMaybe; + readonly collateral_not_contains?: InputMaybe; + readonly collateral_not_contains_nocase?: InputMaybe; + readonly collateral_starts_with?: InputMaybe; + readonly collateral_starts_with_nocase?: InputMaybe; + readonly collateral_not_starts_with?: InputMaybe; + readonly collateral_not_starts_with_nocase?: InputMaybe; + readonly collateral_ends_with?: InputMaybe; + readonly collateral_ends_with_nocase?: InputMaybe; + readonly collateral_not_ends_with?: InputMaybe; + readonly collateral_not_ends_with_nocase?: InputMaybe; + readonly collateral_?: InputMaybe; + readonly name?: InputMaybe; + readonly name_not?: InputMaybe; + readonly name_gt?: InputMaybe; + readonly name_lt?: InputMaybe; + readonly name_gte?: InputMaybe; + readonly name_lte?: InputMaybe; + readonly name_in?: InputMaybe>; + readonly name_not_in?: InputMaybe>; + readonly name_contains?: InputMaybe; + readonly name_contains_nocase?: InputMaybe; + readonly name_not_contains?: InputMaybe; + readonly name_not_contains_nocase?: InputMaybe; + readonly name_starts_with?: InputMaybe; + readonly name_starts_with_nocase?: InputMaybe; + readonly name_not_starts_with?: InputMaybe; + readonly name_not_starts_with_nocase?: InputMaybe; + readonly name_ends_with?: InputMaybe; + readonly name_ends_with_nocase?: InputMaybe; + readonly name_not_ends_with?: InputMaybe; + readonly name_not_ends_with_nocase?: InputMaybe; + readonly symbol?: InputMaybe; + readonly symbol_not?: InputMaybe; + readonly symbol_gt?: InputMaybe; + readonly symbol_lt?: InputMaybe; + readonly symbol_gte?: InputMaybe; + readonly symbol_lte?: InputMaybe; + readonly symbol_in?: InputMaybe>; + readonly symbol_not_in?: InputMaybe>; + readonly symbol_contains?: InputMaybe; + readonly symbol_contains_nocase?: InputMaybe; + readonly symbol_not_contains?: InputMaybe; + readonly symbol_not_contains_nocase?: InputMaybe; + readonly symbol_starts_with?: InputMaybe; + readonly symbol_starts_with_nocase?: InputMaybe; + readonly symbol_not_starts_with?: InputMaybe; + readonly symbol_not_starts_with_nocase?: InputMaybe; + readonly symbol_ends_with?: InputMaybe; + readonly symbol_ends_with_nocase?: InputMaybe; + readonly symbol_not_ends_with?: InputMaybe; + readonly symbol_not_ends_with_nocase?: InputMaybe; + readonly decimals?: InputMaybe; + readonly decimals_not?: InputMaybe; + readonly decimals_gt?: InputMaybe; + readonly decimals_lt?: InputMaybe; + readonly decimals_gte?: InputMaybe; + readonly decimals_lte?: InputMaybe; + readonly decimals_in?: InputMaybe>; + readonly decimals_not_in?: InputMaybe>; + /** Filter for the block changed event. */ + readonly _change_block?: InputMaybe; + readonly and?: InputMaybe>>; + readonly or?: InputMaybe>>; +}; + +export type Token_orderBy = + | 'id' + | 'collateral' + | 'collateral__id' + | 'collateral__minCollRatio' + | 'collateral__totalDeposited' + | 'collateral__totalDebt' + | 'name' + | 'symbol' + | 'decimals'; + +export type Trove = { + readonly id: Scalars['ID']['output']; + readonly borrower: Scalars['Bytes']['output']; + readonly debt: Scalars['BigInt']['output']; + readonly deposit: Scalars['BigInt']['output']; + readonly stake: Scalars['BigInt']['output']; + readonly interestRate: Scalars['BigInt']['output']; + readonly createdAt: Scalars['BigInt']['output']; + readonly closedAt?: Maybe; + readonly collateral: Collateral; +}; + +export type Trove_filter = { + readonly id?: InputMaybe; + readonly id_not?: InputMaybe; + readonly id_gt?: InputMaybe; + readonly id_lt?: InputMaybe; + readonly id_gte?: InputMaybe; + readonly id_lte?: InputMaybe; + readonly id_in?: InputMaybe>; + readonly id_not_in?: InputMaybe>; + readonly borrower?: InputMaybe; + readonly borrower_not?: InputMaybe; + readonly borrower_gt?: InputMaybe; + readonly borrower_lt?: InputMaybe; + readonly borrower_gte?: InputMaybe; + readonly borrower_lte?: InputMaybe; + readonly borrower_in?: InputMaybe>; + readonly borrower_not_in?: InputMaybe>; + readonly borrower_contains?: InputMaybe; + readonly borrower_not_contains?: InputMaybe; + readonly debt?: InputMaybe; + readonly debt_not?: InputMaybe; + readonly debt_gt?: InputMaybe; + readonly debt_lt?: InputMaybe; + readonly debt_gte?: InputMaybe; + readonly debt_lte?: InputMaybe; + readonly debt_in?: InputMaybe>; + readonly debt_not_in?: InputMaybe>; + readonly deposit?: InputMaybe; + readonly deposit_not?: InputMaybe; + readonly deposit_gt?: InputMaybe; + readonly deposit_lt?: InputMaybe; + readonly deposit_gte?: InputMaybe; + readonly deposit_lte?: InputMaybe; + readonly deposit_in?: InputMaybe>; + readonly deposit_not_in?: InputMaybe>; + readonly stake?: InputMaybe; + readonly stake_not?: InputMaybe; + readonly stake_gt?: InputMaybe; + readonly stake_lt?: InputMaybe; + readonly stake_gte?: InputMaybe; + readonly stake_lte?: InputMaybe; + readonly stake_in?: InputMaybe>; + readonly stake_not_in?: InputMaybe>; + readonly interestRate?: InputMaybe; + readonly interestRate_not?: InputMaybe; + readonly interestRate_gt?: InputMaybe; + readonly interestRate_lt?: InputMaybe; + readonly interestRate_gte?: InputMaybe; + readonly interestRate_lte?: InputMaybe; + readonly interestRate_in?: InputMaybe>; + readonly interestRate_not_in?: InputMaybe>; + readonly createdAt?: InputMaybe; + readonly createdAt_not?: InputMaybe; + readonly createdAt_gt?: InputMaybe; + readonly createdAt_lt?: InputMaybe; + readonly createdAt_gte?: InputMaybe; + readonly createdAt_lte?: InputMaybe; + readonly createdAt_in?: InputMaybe>; + readonly createdAt_not_in?: InputMaybe>; + readonly closedAt?: InputMaybe; + readonly closedAt_not?: InputMaybe; + readonly closedAt_gt?: InputMaybe; + readonly closedAt_lt?: InputMaybe; + readonly closedAt_gte?: InputMaybe; + readonly closedAt_lte?: InputMaybe; + readonly closedAt_in?: InputMaybe>; + readonly closedAt_not_in?: InputMaybe>; + readonly collateral?: InputMaybe; + readonly collateral_not?: InputMaybe; + readonly collateral_gt?: InputMaybe; + readonly collateral_lt?: InputMaybe; + readonly collateral_gte?: InputMaybe; + readonly collateral_lte?: InputMaybe; + readonly collateral_in?: InputMaybe>; + readonly collateral_not_in?: InputMaybe>; + readonly collateral_contains?: InputMaybe; + readonly collateral_contains_nocase?: InputMaybe; + readonly collateral_not_contains?: InputMaybe; + readonly collateral_not_contains_nocase?: InputMaybe; + readonly collateral_starts_with?: InputMaybe; + readonly collateral_starts_with_nocase?: InputMaybe; + readonly collateral_not_starts_with?: InputMaybe; + readonly collateral_not_starts_with_nocase?: InputMaybe; + readonly collateral_ends_with?: InputMaybe; + readonly collateral_ends_with_nocase?: InputMaybe; + readonly collateral_not_ends_with?: InputMaybe; + readonly collateral_not_ends_with_nocase?: InputMaybe; + readonly collateral_?: InputMaybe; + /** Filter for the block changed event. */ + readonly _change_block?: InputMaybe; + readonly and?: InputMaybe>>; + readonly or?: InputMaybe>>; +}; + +export type Trove_orderBy = + | 'id' + | 'borrower' + | 'debt' + | 'deposit' + | 'stake' + | 'interestRate' + | 'createdAt' + | 'closedAt' + | 'collateral' + | 'collateral__id' + | 'collateral__minCollRatio' + | 'collateral__totalDeposited' + | 'collateral__totalDebt'; + +export type _Block_ = { + /** The hash of the block */ + readonly hash?: Maybe; + /** The block number */ + readonly number: Scalars['Int']['output']; + /** Integer representation of the timestamp stored in blocks for the chain */ + readonly timestamp?: Maybe; + /** The hash of the parent block */ + readonly parentHash?: Maybe; +}; + +/** The type for the top-level _meta field */ +export type _Meta_ = { + /** + * Information about a specific subgraph block. The hash of the block + * will be null if the _meta field has a block constraint that asks for + * a block number. It will be filled if the _meta field has no block constraint + * and therefore asks for the latest block + * + */ + readonly block: _Block_; + /** The deployment ID */ + readonly deployment: Scalars['String']['output']; + /** If `true`, the subgraph encountered indexing errors at some past block */ + readonly hasIndexingErrors: Scalars['Boolean']['output']; +}; + +export type _SubgraphErrorPolicy_ = + /** Data will be returned even if the subgraph has indexing errors */ + | 'allow' + /** If the subgraph has indexing errors, data will be omitted. The default. */ + | 'deny'; + + export type QuerySdk = { + /** null **/ + collateral: InContextSdkMethod, + /** null **/ + collaterals: InContextSdkMethod, + /** null **/ + token: InContextSdkMethod, + /** null **/ + tokens: InContextSdkMethod, + /** null **/ + collateralAddresses: InContextSdkMethod, + /** null **/ + collateralAddresses_collection: InContextSdkMethod, + /** null **/ + interestRateBracket: InContextSdkMethod, + /** null **/ + interestRateBrackets: InContextSdkMethod, + /** null **/ + trove: InContextSdkMethod, + /** null **/ + troves: InContextSdkMethod, + /** Access to subgraph metadata **/ + _meta: InContextSdkMethod + }; + + export type MutationSdk = { + + }; + + export type SubscriptionSdk = { + /** null **/ + collateral: InContextSdkMethod, + /** null **/ + collaterals: InContextSdkMethod, + /** null **/ + token: InContextSdkMethod, + /** null **/ + tokens: InContextSdkMethod, + /** null **/ + collateralAddresses: InContextSdkMethod, + /** null **/ + collateralAddresses_collection: InContextSdkMethod, + /** null **/ + interestRateBracket: InContextSdkMethod, + /** null **/ + interestRateBrackets: InContextSdkMethod, + /** null **/ + trove: InContextSdkMethod, + /** null **/ + troves: InContextSdkMethod, + /** Access to subgraph metadata **/ + _meta: InContextSdkMethod + }; + + export type Context = { + ["liquity2"]: { Query: QuerySdk, Mutation: MutationSdk, Subscription: SubscriptionSdk }, + + }; +} diff --git a/frontend/app/.graphclientrc.yml b/frontend/app/.graphclientrc.yml new file mode 100644 index 00000000..77649ff9 --- /dev/null +++ b/frontend/app/.graphclientrc.yml @@ -0,0 +1,20 @@ +sources: + - name: liquity2 + handler: + graphql: + endpoint: http://localhost:8000/subgraphs/name/liquity2/liquity2 + +codegen: + strictScalars: true + immutableTypes: true + useTypeImports: false # import name conflict if set to true + dedupeFragments: true + scalars: + BigDecimal: bigint + BigInt: bigint + Bytes: string + Int8: number + Timestamp: string + +documents: + - ./src/subgraph-queries.graphql diff --git a/frontend/app/package.json b/frontend/app/package.json index 2f3f4533..399b94c5 100644 --- a/frontend/app/package.json +++ b/frontend/app/package.json @@ -6,15 +6,17 @@ "scripts": { "build": "pnpm build-uikit && pnpm panda-codegen && next build", "build-uikit": "cd ../uikit && pnpm build && pnpm panda-codegen", + "coverage": "vitest run --coverage ./src", "dev": "rm -rf ./.next && next dev", "fmt": "dprint fmt **/*.{ts,tsx,js,json,html,md}", "lint": "pnpm oxlint ./src --import-plugin --nextjs-plugin --react-perf-plugin --jsx-a11y-plugin --allow pedantic", "panda-codegen": "panda codegen --silent", + "subgraph-codegen": "pnpm graphclient build", "test": "vitest", - "coverage": "vitest run --coverage ./src", "update-liquity-abis": "node --loader ts-node/esm ./scripts/update-liquity-abis.ts" }, "dependencies": { + "@graphprotocol/client-cli": "^3.0.7", "@liquity2/uikit": "workspace:*", "@rainbow-me/rainbowkit": "^2.1.3", "@react-spring/web": "^9.7.4", diff --git a/frontend/app/src/comps/AppLayout/AppLayout.tsx b/frontend/app/src/comps/AppLayout/AppLayout.tsx index 632de09d..790443d3 100644 --- a/frontend/app/src/comps/AppLayout/AppLayout.tsx +++ b/frontend/app/src/comps/AppLayout/AppLayout.tsx @@ -1,6 +1,7 @@ import type { ReactNode } from "react"; import { UpdatePrices } from "@/src/comps/Debug/UpdatePrices"; +import { ProtocolStats } from "@/src/comps/ProtocolStats/ProtocolStats"; import { TopBar } from "@/src/comps/TopBar/TopBar"; import { css } from "@/styled-system/css"; @@ -45,6 +46,14 @@ export function AppLayout({ })} > {children} +
+ +
diff --git a/frontend/app/src/comps/Debug/UpdatePrices.tsx b/frontend/app/src/comps/Debug/UpdatePrices.tsx index 20c2a7b2..a5b30a46 100644 --- a/frontend/app/src/comps/Debug/UpdatePrices.tsx +++ b/frontend/app/src/comps/Debug/UpdatePrices.tsx @@ -44,7 +44,7 @@ export function UpdatePrices() { color: "contentAlt", })} > - Simulate prices + simulate prices {" "}
void; -}) { - const position = ( - DEMO_MODE - ? ACCOUNT_POSITIONS.find((position) => ( - (position.type === "borrow" || position.type === "leverage") && position.troveId === troveId - )) - : undefined - ) as PositionLoan | undefined; - - const collateral = position && TOKENS_BY_SYMBOL[position.collateral]; - - const collPriceUsd = usePrice(collateral ? collateral.symbol : null); - - if (!position || !collPriceUsd || !collateral) { - return null; - } - - const { deposit, borrowed, interestRate } = position; - - const loanDetails = getLoanDetails( - deposit, - borrowed, - interestRate, - collateral.collateralRatio, - collPriceUsd, - ); - - const { - ltv, - depositPreLeverage, - leverageFactor, - redemptionRisk, - liquidationRisk, - } = loanDetails; - - const maxLtv = dn.div(dn.from(1, 18), collateral.collateralRatio); - - return ( -
-

-
-
- {leverageMode - ? - : } -
- {leverageMode ? "Leverage loan" : "BOLD loan"} -
-

-
-
- {leverageMode - ? ( -
-
{fmtnum(position.deposit)}
- -
-
- - {loanDetails.status === "underwater" || leverageFactor === null - ? INFINITY - : `${roundToDecimal(leverageFactor, 1)}x`} - -
- { - /*
- ${fmtnum(dn.mul(position.deposit, collPriceUsd), { digits: 2 })} -
*/ - } -
-
- ) - : ( -
- {fmtnum(position.borrowed)} - -
- )} -
-
-
-
- -
- {leverageMode - ? ( - - - {fmtnum(depositPreLeverage)} {TOKENS_BY_SYMBOL[position.collateral].name} - - - ) - : ( - -
- {fmtnum(position.deposit)} {TOKENS_BY_SYMBOL[position.collateral].name} -
-
- )} - - - ${fmtnum(loanDetails.liquidationPrice)} - - - - {fmtnum(dn.mul(position.interestRate, 100))}% - - -
- {ltv && fmtnum(dn.mul(ltv, 100))}% -
-
- - - - {formatRisk(liquidationRisk)} - - - {redemptionRisk && ( - - - - {formatRisk(redemptionRisk)} - - - )} -
-
- ); -} - -function GridItem({ - children, - label, -}: { - children: ReactNode; - label: string; -}) { - return ( -
-
- {label} -
-
- {children} -
-
- ); -} diff --git a/frontend/app/src/comps/Positions/Positions.tsx b/frontend/app/src/comps/Positions/Positions.tsx index 6b5c2190..b729804a 100644 --- a/frontend/app/src/comps/Positions/Positions.tsx +++ b/frontend/app/src/comps/Positions/Positions.tsx @@ -5,10 +5,12 @@ import { ActionCard } from "@/src/comps/ActionCard/ActionCard"; import { LQTY_SUPPLY } from "@/src/constants"; import content from "@/src/content"; import { ACCOUNT_POSITIONS } from "@/src/demo-mode"; +import { DEMO_MODE } from "@/src/env"; import { formatLiquidationRisk, formatRedemptionRisk } from "@/src/formatting"; import { getLiquidationRisk, getLtv, getRedemptionRisk } from "@/src/liquity-math"; import { useAccount } from "@/src/services/Ethereum"; import { usePrice } from "@/src/services/Prices"; +import { useLoansByAccount } from "@/src/subgraph-hooks"; import { riskLevelToStatusMode } from "@/src/uikit-utils"; import { css } from "@/styled-system/css"; import { @@ -26,12 +28,16 @@ import { import { a, useTransition } from "@react-spring/web"; import * as dn from "dnum"; import Link from "next/link"; +import { useState } from "react"; import { match } from "ts-pattern"; export function Positions() { const account = useAccount(); + const loans = useLoansByAccount(account.address); - const positionCards = ACCOUNT_POSITIONS.map((position, index) => ( + const positions = DEMO_MODE ? ACCOUNT_POSITIONS : loans.data ?? []; + + const positionCards = positions.map((position, index) => ( match(position) .with({ type: "borrow" }, ({ type, ...props }) => [index, ]) .with({ type: "earn" }, ({ type, ...props }) => [index, ]) @@ -40,7 +46,7 @@ export function Positions() { .exhaustive() )); - const mode = account.isConnected && positionCards.length > 0 ? "positions" : "actions"; + const mode = account.isConnected && (positionCards.length > 0 || loans.isLoading) ? "positions" : "actions"; const actionCards = [ , @@ -49,52 +55,152 @@ export function Positions() { , ].map((card, index) => [index, card]); - const positionTransitions = useTransition(mode === "positions" ? positionCards : actionCards, { - keys: ([index]) => `${index}${mode}`, - from: { opacity: 0, transform: "scale3d(0.95, 0.95, 1)" }, - enter: { opacity: 1, transform: "scale3d(1, 1, 1)" }, - leave: { display: "none", immediate: true }, - trail: 10, + const [increment, setIncrement] = useState(0); + + const positionTransitions = useTransition( + mode === "positions" ? positionCards : actionCards, + { + keys: ([index]) => `${index}${mode}${increment}`, + from: { opacity: 0, transform: "scale3d(0.95, 0.95, 1)" }, + enter: { opacity: 1, transform: "scale3d(1, 1, 1)" }, + leave: { display: "none", immediate: true }, + trail: 10, + config: { + mass: 1, + tension: 2800, + friction: 80, + }, + }, + ); + + const [forceLoading, setForceLoading] = useState(false); + + return ( + { + setForceLoading(true); + setTimeout(() => { + setForceLoading(false); + setIncrement((i) => i + 1); + }, 1000); + }} + > + {positionTransitions((style, [_, card]) => ( + + {card} + + ))} + + ); +} + +function PositionsGroup({ + children, + loading, + mode, + onTitleClick, +}: { + children: ReactNode; + loading?: boolean; + mode: "positions" | "actions"; + onTitleClick?: () => void; +}) { + const loadingTransition = useTransition(loading, { + from: { + opacity: 0, + transform: "scale3d(0.95, 0.95, 1)", + }, + enter: { + opacity: 1, + transform: "scale3d(1, 1, 1)", + }, + leave: { + opacity: 0, + transform: "scale3d(0.95, 0.95, 1)", + }, config: { mass: 1, - tension: 2800, + tension: 1800, friction: 80, }, }); - return (

{mode === "positions" ? content.home.myPositionsTitle : content.home.openPositionTitle}

- {positionTransitions((style, [_, card]) => ( - ( + loading && ( + +
+
+ Fetching positions… +
+ + ) + ))} + {!loading && ( +
- {card} - - ))} + {children} +
+ )}
); @@ -131,13 +237,13 @@ function PositionBorrow({ - {dn.format(dn.add(deposit, borrowed), 4)} + {dn.format(dn.add(deposit, borrowed), 2)} ), - label: "Total debt", + // label: "Total debt", + label: ( +
+ Backed by {deposit ? dn.format(deposit, 2) : "−"} {token.name} + +
+ ), }} secondary={ diff --git a/frontend/app/src/comps/ProtocolStats/ProtocolStats.tsx b/frontend/app/src/comps/ProtocolStats/ProtocolStats.tsx index b15eddc8..4dfb54dc 100644 --- a/frontend/app/src/comps/ProtocolStats/ProtocolStats.tsx +++ b/frontend/app/src/comps/ProtocolStats/ProtocolStats.tsx @@ -1,194 +1,66 @@ -import type { SpringValue } from "@react-spring/web"; -import type { Dnum } from "dnum"; -import type { ComponentProps } from "react"; +"use client"; import content from "@/src/content"; +import { BORROW_STATS } from "@/src/demo-mode"; +import { usePrice } from "@/src/services/Prices"; import { css } from "@/styled-system/css"; -import { TokenIcon } from "@liquity2/uikit"; -import { a, useTransition } from "@react-spring/web"; +import { HFlex, TokenIcon } from "@liquity2/uikit"; import * as dn from "dnum"; -import { useEffect, useState } from "react"; -import { stringify } from "viem"; - -type Stat = { - amount: Dnum | string; - label: string; - token?: ComponentProps["symbol"]; -}; export function ProtocolStats() { - const stats = useStats(); - - const transitions = useTransition(stats, { - keys: (stat) => stat.label, - from: { progress: 0 }, - initial: { progress: 0 }, - enter: { progress: 1 }, - leave: { progress: 0, immediate: true }, - config: { - mass: 1, - tension: 1800, - friction: 60, - }, - trail: 60, - }); + const prices = [ + ["LQTY", usePrice("LQTY")], + ["BOLD", usePrice("BOLD")], + ["ETH", usePrice("ETH")], + ] as const; - return ( -
-

{content.home.statsBar.label}

- {stats.length > 0 - ? ( -
- {transitions(({ progress }, item) => { - return ( - - ); - })} -
- ) - : ( -
- Loading… -
- )} -
+ const totalTvl = Object.values(BORROW_STATS).reduce( + (acc, { tvl }) => dn.add(acc, tvl), + dn.from(0, 18), ); -} -function AmountUsd({ - amount, - label, - tokenSymbol, - progress, -}: { - amount?: Dnum | string; - label: string; - tokenSymbol?: ComponentProps["symbol"]; - progress: SpringValue; -}) { return (
- {tokenSymbol && ( - `scale(${1.4 - v * 0.4})`), - }} - > - - - )} - {content.home.statsBar.label}
+ + + TVL{" "} + + ${dn.format(totalTvl, { compact: true })} + + + {prices.map(([symbol, price]) => { + return ( + + + + {symbol} + + ${price && dn.format(price, { + digits: 2, + trailingZeros: true, + })} + + + + ); })} - style={{ - opacity: progress, - transform: progress.to((v) => `scale(${1 - (1 - v) * 0.2})`), - }} - > -
{label}
- - {typeof amount === "string" ? amount : amount && dn.format(amount, { - digits: 2, - trailingZeros: true, - })} - - - {" $"} - - +
); } - -function formatMillions(amount: Dnum) { - return dn.gt(amount, 1_000_000) - ? `${dn.format(dn.div(amount, 1_000_000))}M` - : dn.format(amount, { compact: true }); -} - -function useStats() { - const [stats, setStats] = useState([]); - useEffect(() => { - const update = () => { - setStats([{ - amount: formatMillions([1_408_000_000n, 0]), - label: "TVL", - }, { - amount: [13_72n + BigInt(-100 + Math.round(Math.random() * 200)), 2], - label: "LQTY", - token: "LQTY", - }, { - amount: [1_01n + BigInt(-10 + Math.round(Math.random() * 20)), 2], - label: "BOLD", - token: "BOLD", - }, { - amount: [3421_55n, 2], - label: "ETH", - token: "ETH", - }]); - }; - - update(); - - const timer = setInterval(update, 30_000); - - return () => { - clearInterval(timer); - }; - }, []); - - return stats; -} diff --git a/frontend/app/src/demo-mode/demo-data.ts b/frontend/app/src/demo-mode/demo-data.ts index 23db0b4a..3fb9d64f 100644 --- a/frontend/app/src/demo-mode/demo-data.ts +++ b/frontend/app/src/demo-mode/demo-data.ts @@ -7,7 +7,7 @@ import * as dn from "dnum"; export const PRICE_UPDATE_INTERVAL = 15_000; export const PRICE_UPDATE_VARIATION = 0.003; -export const PRICE_UPDATE_MANUAL = true; +export const PRICE_UPDATE_MANUAL = false; export const LQTY_PRICE = dn.from(0.64832, 18); export const ETH_PRICE = dn.from(2_580.293872, 18); @@ -38,7 +38,7 @@ export const ACCOUNT_POSITIONS: Position[] = [ collateral: "RETH", deposit: dn.from(5.5, 18), interestRate: dn.from(0.067, 18), - troveId: 1n, + troveId: "0x01", }, { type: "leverage", @@ -46,7 +46,7 @@ export const ACCOUNT_POSITIONS: Position[] = [ collateral: "ETH", deposit: dn.from(19.20, 18), // 8 ETH @ 2.4 leverage interestRate: dn.from(0.045, 18), - troveId: 2n, + troveId: "0x02", }, { type: "earn", diff --git a/frontend/app/src/dnum-utils.ts b/frontend/app/src/dnum-utils.ts index 87deb50c..a5d3dcab 100644 --- a/frontend/app/src/dnum-utils.ts +++ b/frontend/app/src/dnum-utils.ts @@ -2,6 +2,10 @@ import type { Dnum } from "dnum"; import * as dn from "dnum"; +export function dnum18(value: string | bigint | number): Dnum { + return [BigInt(value), 18]; +} + export function formatAmountCompact(value: Dnum, digits: number = 2) { const valueAbs = dn.abs(value); if (dn.eq(valueAbs, 1e9) || dn.gt(valueAbs, 1e9)) { diff --git a/frontend/app/src/liquity-utils.ts b/frontend/app/src/liquity-utils.ts index 0645c4c2..9143adcf 100644 --- a/frontend/app/src/liquity-utils.ts +++ b/frontend/app/src/liquity-utils.ts @@ -1,5 +1,5 @@ import type { TroveId } from "@/src/types"; -import type { Address } from "@liquity2/uikit"; +import type { Address, CollateralSymbol } from "@liquity2/uikit"; import type { Dnum } from "dnum"; import { useCollateralContract, useProtocolContract } from "@/src/contracts"; @@ -34,6 +34,12 @@ type Rewards = { bold: Dnum; }; +export function shortenTroveId(troveId: TroveId, chars = 4) { + return troveId.length < chars * 2 + 2 + ? troveId + : troveId.slice(0, chars + 2) + "…" + troveId.slice(-chars); +} + function troveStatusFromNumber(value: number): TroveStatus { return match(value) .with(0, () => "nonExistent") @@ -333,6 +339,21 @@ export function getTroveId(owner: Address, ownerIndex: bigint | number) { ))); } +export function getCollateralFromTroveSymbol(symbol: string): null | CollateralSymbol { + symbol = symbol.toUpperCase(); + if (symbol === "ETH" || symbol === "WETH") { + return "ETH"; + } + // this is to handle symbols used for testing, like stETH1, stETH2, etc. + if (symbol.startsWith("RETH")) { + return "RETH"; + } + if (symbol.startsWith("STETH")) { + return "STETH"; + } + return null; +} + export function useCollTokenAllowance() { const account = useAccount(); diff --git a/frontend/app/src/screens/BorrowScreen/BorrowScreen.tsx b/frontend/app/src/screens/BorrowScreen/BorrowScreen.tsx index 30662d3c..988c6e85 100644 --- a/frontend/app/src/screens/BorrowScreen/BorrowScreen.tsx +++ b/frontend/app/src/screens/BorrowScreen/BorrowScreen.tsx @@ -24,6 +24,7 @@ import { IconSuggestion, InfoTooltip, InputField, + isCollateralSymbol, PillButton, TextButton, TokenIcon, @@ -35,11 +36,6 @@ import { match, P } from "ts-pattern"; const collateralSymbols = COLLATERALS.map(({ symbol }) => symbol); -function isCollateralSymbol(symbol: string): symbol is typeof collateralSymbols[number] { - const c: string[] = collateralSymbols; - return c.includes(symbol); -} - export function BorrowScreen() { const account = useAccount(); diff --git a/frontend/app/src/screens/EarnPoolScreen/EarnPoolScreen.tsx b/frontend/app/src/screens/EarnPoolScreen/EarnPoolScreen.tsx index a7fa0e6c..33ef2231 100644 --- a/frontend/app/src/screens/EarnPoolScreen/EarnPoolScreen.tsx +++ b/frontend/app/src/screens/EarnPoolScreen/EarnPoolScreen.tsx @@ -11,7 +11,15 @@ import { ACCOUNT_BALANCES, ACCOUNT_POSITIONS, EARN_POOLS } from "@/src/demo-mode import { useAccount } from "@/src/services/Ethereum"; import { infoTooltipProps } from "@/src/uikit-utils"; import { css } from "@/styled-system/css"; -import { COLLATERALS, HFlex, InfoTooltip, Tabs, TokenIcon, TokenIconGroup, TOKENS_BY_SYMBOL } from "@liquity2/uikit"; +import { + HFlex, + InfoTooltip, + isCollateralSymbol, + Tabs, + TokenIcon, + TokenIconGroup, + TOKENS_BY_SYMBOL, +} from "@liquity2/uikit"; import * as dn from "dnum"; import { useParams, useRouter } from "next/navigation"; import { DepositPanel } from "./DepositPanel"; @@ -24,13 +32,6 @@ const TABS = [ { action: "claim", label: content.earnScreen.tabs.claim }, ] as const; -const collateralSymbols = COLLATERALS.map(({ symbol }) => symbol); -function isCollateralSymbol(symbol: string): symbol is typeof collateralSymbols[number] { - console.log(symbol, collateralSymbols); - const c: string[] = collateralSymbols; - return c.includes(symbol); -} - export function EarnPoolScreen() { const account = useAccount(); const router = useRouter(); diff --git a/frontend/app/src/screens/HomeScreen/HomeProtocolStats.tsx b/frontend/app/src/screens/HomeScreen/HomeProtocolStats.tsx index b83141f4..e69de29b 100644 --- a/frontend/app/src/screens/HomeScreen/HomeProtocolStats.tsx +++ b/frontend/app/src/screens/HomeScreen/HomeProtocolStats.tsx @@ -1,63 +0,0 @@ -import content from "@/src/content"; -import { BORROW_STATS } from "@/src/demo-mode"; -import { usePrice } from "@/src/services/Prices"; -import { css } from "@/styled-system/css"; -import { HFlex, TokenIcon } from "@liquity2/uikit"; -import * as dn from "dnum"; - -export function HomeProtocolStats() { - const prices = [ - ["LQTY", usePrice("LQTY")], - ["BOLD", usePrice("BOLD")], - ["ETH", usePrice("ETH")], - ] as const; - - const totalTvl = Object.values(BORROW_STATS).reduce( - (acc, { tvl }) => dn.add(acc, tvl), - dn.from(0, 18), - ); - - return ( -
-
{content.home.statsBar.label}
- - - TVL{" "} - - ${dn.format(totalTvl, { compact: true })} - - - {prices.map(([symbol, price]) => { - return ( - - - - {symbol} - - ${price && dn.format(price, { - digits: 2, - trailingZeros: true, - })} - - - - ); - })} - -
- ); -} diff --git a/frontend/app/src/screens/HomeScreen/HomeScreen.tsx b/frontend/app/src/screens/HomeScreen/HomeScreen.tsx index 24734982..92907da4 100644 --- a/frontend/app/src/screens/HomeScreen/HomeScreen.tsx +++ b/frontend/app/src/screens/HomeScreen/HomeScreen.tsx @@ -6,7 +6,6 @@ import { css } from "@/styled-system/css"; import { AnchorTextButton, COLLATERALS, IconBorrow, IconEarn, TokenIcon } from "@liquity2/uikit"; import * as dn from "dnum"; import Link from "next/link"; -import { HomeProtocolStats } from "./HomeProtocolStats"; import { HomeTable } from "./HomeTable"; export function HomeScreen() { @@ -152,13 +151,6 @@ export function HomeScreen() { })} />
-
- -
); } diff --git a/frontend/app/src/screens/LeverageScreen/LeverageScreen.tsx b/frontend/app/src/screens/LeverageScreen/LeverageScreen.tsx index d8c4cdae..1406f188 100644 --- a/frontend/app/src/screens/LeverageScreen/LeverageScreen.tsx +++ b/frontend/app/src/screens/LeverageScreen/LeverageScreen.tsx @@ -23,6 +23,7 @@ import { IconSuggestion, InfoTooltip, InputField, + isCollateralSymbol, TextButton, TokenIcon, VFlex, @@ -33,11 +34,6 @@ import { useEffect, useState } from "react"; const collateralSymbols = COLLATERALS.map(({ symbol }) => symbol); -function isCollateralSymbol(symbol: string): symbol is typeof collateralSymbols[number] { - const c: string[] = collateralSymbols; - return c.includes(symbol); -} - export function LeverageScreen() { const account = useAccount(); const router = useRouter(); diff --git a/frontend/app/src/screens/LoanScreen/LoanCard.tsx b/frontend/app/src/screens/LoanScreen/LoanCard.tsx new file mode 100644 index 00000000..5d25be80 --- /dev/null +++ b/frontend/app/src/screens/LoanScreen/LoanCard.tsx @@ -0,0 +1,513 @@ +import type { PositionLoan, TroveId } from "@/src/types"; +import type { ReactNode } from "react"; +import type { LoanLoadingState } from "./LoanScreen"; + +import { INFINITY } from "@/src/characters"; +import { Value } from "@/src/comps/Value/Value"; +import { formatRisk } from "@/src/formatting"; +import { fmtnum } from "@/src/formatting"; +import { getLoanDetails } from "@/src/liquity-math"; +import { shortenTroveId } from "@/src/liquity-utils"; +import { usePrice } from "@/src/services/Prices"; +import { riskLevelToStatusMode } from "@/src/uikit-utils"; +import { roundToDecimal } from "@/src/utils"; +import { css } from "@/styled-system/css"; +import { token } from "@/styled-system/tokens"; +import { Button, HFlex, IconBorrow, IconLeverage, StatusDot, TokenIcon, TOKENS_BY_SYMBOL } from "@liquity2/uikit"; +import { a, useSpring } from "@react-spring/web"; +import * as dn from "dnum"; +import { match, P } from "ts-pattern"; + +const LOAN_CARD_HEIGHT = 246; + +export function LoanCard({ + leverageMode, + loadingState, + loan, + onLeverageModeChange, + onRetry, + troveId, +}: { + leverageMode: boolean; + loadingState: LoanLoadingState; + loan: PositionLoan | null; + onLeverageModeChange: (leverageMode: boolean) => void; + onRetry: () => void; + troveId: TroveId; +}) { + const collateral = loan && TOKENS_BY_SYMBOL[loan.collateral]; + const collPriceUsd = usePrice(collateral ? collateral.symbol : null); + + const loanDetails = loan && collateral && getLoanDetails( + loan.deposit, + loan.borrowed, + loan.interestRate, + collateral.collateralRatio, + collPriceUsd, + ); + + const { + ltv, + depositPreLeverage, + leverageFactor, + redemptionRisk, + liquidationRisk, + } = loanDetails || {}; + + const maxLtv = collateral && dn.div( + dn.from(1, 18), + collateral.collateralRatio, + ); + + return ( + + {loan + && loanDetails + && collateral + && typeof leverageFactor === "number" + && depositPreLeverage + && maxLtv + && liquidationRisk + && ( + <> +
+
+ {leverageMode + ? ( +
+
{fmtnum(loan.deposit)}
+ +
+
+ + {loanDetails.status === "underwater" || leverageFactor === null + ? INFINITY + : `${roundToDecimal(leverageFactor, 1)}x`} + +
+
+
+ ) + : ( +
+ {fmtnum(loan.borrowed)} + +
+ )} +
+
+
+
+
+ {leverageMode + ? ( + + + {fmtnum(depositPreLeverage)} {collateral.name} + + + ) + : ( + +
+ {fmtnum(loan.deposit)} {collateral.name} +
+
+ )} + + + ${fmtnum(loanDetails.liquidationPrice)} + + + + {fmtnum(dn.mul(loan.interestRate, 100))}% + + +
+ {ltv && fmtnum(dn.mul(ltv, 100))}% +
+
+ + + + {formatRisk(liquidationRisk)} + + + {redemptionRisk && ( + + + + {formatRisk(redemptionRisk)} + + + )} +
+ + )} +
+ ); +} + +function LoadingCard({ + children, + leverage, + loadingState, + loan, + onRetry, + troveId, +}: { + children: ReactNode; + leverage: boolean; + loadingState: LoanLoadingState; + loan: PositionLoan | null; + onRetry: () => void; + troveId: TroveId; +}) { + const title = leverage ? "Leverage loan" : "BOLD loan"; + const titleFull = loan && `${title}: ${troveId}`; + + const spring = useSpring({ + to: match(loadingState) + .with( + P.union( + "loading", + "error", + "awaiting-confirmation", + "not-found", + ), + (s) => ({ + cardtransform: "scale3d(0.95, 0.95, 1)", + containerHeight: ( + window.innerHeight + - 120 // top bar + - 24 * 2 // padding + - 48 // bottom bar 1 + - 40 + // - 40 // bottom bar 2 + ), + cardHeight: s === "error" || s === "not-found" ? 180 : 120, + cardBackground: token("colors.blue:50"), + cardColor: token("colors.blue:950"), + }), + ) + .otherwise(() => ({ + cardtransform: "scale3d(1, 1, 1)", + containerHeight: LOAN_CARD_HEIGHT, + cardHeight: LOAN_CARD_HEIGHT, + cardBackground: token("colors.blue:950"), + cardColor: token("colors.white"), + })), + config: { + mass: 1, + tension: 2000, + friction: 120, + }, + }); + + return ( + + +

+
+
+ {leverage + ? + : } +
+ {title} +
+

+ {match(loadingState) + .with(P.union("loading", "awaiting-confirmation"), () => ( +
+ Fetching loan + + {shortenTroveId(troveId)}… + + +
+ )) + .with("error", () => ( +
+
+ Error fetching loan{" "} + + {shortenTroveId(troveId)} + . +
+
+ )) + .with("not-found", () => ( +
+
+ Loan{" "} + + {shortenTroveId(troveId)} + {" "} + not found. +
+
+ )) + .otherwise(() => ( +
+ {children} +
+ ))} +
+
+ ); +} + +function Spinner({ + size = 24, +}: { + size?: number; +}) { + const spring = useSpring({ + from: { rotate: 0 }, + to: { rotate: 360 }, + loop: true, + config: { + duration: 1000, + }, + }); + return ( + `rotate(${r}deg)`), + }} + > + + + ); +} + +function GridItem({ + children, + label, +}: { + children: ReactNode; + label: string; +}) { + return ( +
+
+ {label} +
+
+ {children} +
+
+ ); +} diff --git a/frontend/app/src/screens/LoanScreen/LoanScreen.tsx b/frontend/app/src/screens/LoanScreen/LoanScreen.tsx index b1abcc4b..17367871 100644 --- a/frontend/app/src/screens/LoanScreen/LoanScreen.tsx +++ b/frontend/app/src/screens/LoanScreen/LoanScreen.tsx @@ -1,14 +1,15 @@ "use client"; -import type { PositionLoan } from "@/src/types"; - -import { Position } from "@/src/comps/Position/Position"; import { Screen } from "@/src/comps/Screen/Screen"; -import { ACCOUNT_POSITIONS } from "@/src/demo-mode"; +import { useLoanById } from "@/src/subgraph-hooks"; +import { isTroveId } from "@/src/types"; import { css } from "@/styled-system/css"; -import { IconSettings, Tabs, VFlex } from "@liquity2/uikit"; +import { Button, IconSettings, Tabs, VFlex } from "@liquity2/uikit"; +import { a, useTransition } from "@react-spring/web"; import { notFound, useRouter, useSearchParams, useSelectedLayoutSegment } from "next/navigation"; -import { useMemo, useState } from "react"; +import { useState } from "react"; +import { match, P } from "ts-pattern"; +import { LoanCard } from "./LoanCard"; import { PanelClosePosition } from "./PanelClosePosition"; import { PanelUpdateBorrowPosition } from "./PanelUpdateBorrowPosition"; import { PanelUpdateLeveragePosition } from "./PanelUpdateLeveragePosition"; @@ -20,89 +21,161 @@ const TABS = [ { label: "Close position", id: "close" }, ]; +export type LoanLoadingState = + | "awaiting-confirmation" + | "error" + | "loading" + | "not-found" + | "success"; + +export const LOAN_STATES: LoanLoadingState[] = [ + "success", + "loading", + "awaiting-confirmation", + "error", + "not-found", +]; + export function LoanScreen() { const router = useRouter(); const action = useSelectedLayoutSegment() ?? "colldebt"; const searchParams = useSearchParams(); - const trove = useTrove(searchParams.get("id")); + const paramId = searchParams.get("id"); + const troveId = isTroveId(paramId) ? paramId : null; - const [leverageMode, setLeverageMode] = useState(trove?.type === "leverage"); - - if (!trove) { + const loan = useLoanById(troveId); + if (loan.isLoadingError || !troveId) { notFound(); } const tab = TABS.findIndex(({ id }) => id === action); + const [leverageMode, setLeverageMode] = useState(false); + + const [forcedLoadingState, setForcedLoadingState] = useState(null); + const loadingState = forcedLoadingState ?? match(loan) + .returnType() + .with({ status: "error" }, () => "error") + .with({ status: "pending" }, () => "loading") + .with({ data: null }, () => "not-found") + .with({ data: P.nonNullable }, () => "success") + .otherwise(() => "error"); + + const setLoadingstate = (state: LoanLoadingState) => { + setForcedLoadingState(state); + }; + // const [loadingState, setLoadingstate] = useState("loading"); + + const tabsTransition = useTransition(loadingState, { + from: { opacity: 0 }, + enter: { opacity: 1 }, + leave: { opacity: 0 }, + config: { + mass: 1, + tension: 2000, + friction: 120, + }, + }); return ( +
+ loan state: {LOAN_STATES.map((s) => ( +
- { + setLoadingstate("loading"); + loan.refetch(); + }} + troveId={troveId} /> -
-
Manage your position
-
- -
-
- - ({ - label, - panelId: `p-${id}`, - tabId: `t-${id}`, - }))} - selected={tab} - onSelect={(index) => { - router.push(`/loan/${TABS[index].id}?id=${trove.troveId}`, { scroll: false }); - }} - /> - {action === "colldebt" && ( - leverageMode - ? - : - )} - {action === "rate" && } - {action === "close" && } - + {tabsTransition((style, item) => ( + item === "success" && loan.data && ( + +
+
Manage your position
+
+ +
+
+ + ({ + label, + panelId: `p-${id}`, + tabId: `t-${id}`, + }))} + selected={tab} + onSelect={(index) => { + router.push( + `/loan/${TABS[index].id}?id=${loan.data?.troveId}`, + { scroll: false }, + ); + }} + /> + {action === "colldebt" && ( + leverageMode + ? + : + )} + {action === "rate" && } + {action === "close" && } + +
+ ) + ))}
); } - -function useTrove(troveId: string | null) { - return useMemo(() => { - if (troveId === null) { - return null; - } - let troveIdInt: bigint; - try { - troveIdInt = BigInt(troveId); - } catch { - return null; - } - const position = ACCOUNT_POSITIONS.find((position) => (( - position.type === "borrow" || position.type === "leverage" - ) && position.troveId === troveIdInt)) ?? null; - return position as PositionLoan | null; - }, [troveId]); -} diff --git a/frontend/app/src/services/Prices.tsx b/frontend/app/src/services/Prices.tsx index 5943c694..9288901c 100644 --- a/frontend/app/src/services/Prices.tsx +++ b/frontend/app/src/services/Prices.tsx @@ -65,7 +65,8 @@ let useWatchPrices = function useWatchPrices(callback: (prices: Prices) => void) ]); }; -if (DEMO_MODE) { +// if (DEMO_MODE) { +if (true) { // TODO: fix useWatchPrices above so we only use this if DEMO_MODE=true // in demo mode, simulate a variation of the prices useWatchPrices = (callback) => { useEffect(() => { diff --git a/frontend/app/src/subgraph-hooks.ts b/frontend/app/src/subgraph-hooks.ts new file mode 100644 index 00000000..42ebe0ae --- /dev/null +++ b/frontend/app/src/subgraph-hooks.ts @@ -0,0 +1,94 @@ +import type { Address, PositionLoan, TroveId } from "@/src/types"; + +import { getBuiltGraphSDK } from "@/.graphclient"; +import { ACCOUNT_POSITIONS } from "@/src/demo-mode"; +import { dnum18 } from "@/src/dnum-utils"; +import { DEMO_MODE } from "@/src/env"; +import { getCollateralFromTroveSymbol } from "@/src/liquity-utils"; +import { isPositionLoan, isTroveId } from "@/src/types"; +import { sleep } from "@/src/utils"; +import { useQuery } from "@tanstack/react-query"; + +const graphSdk = getBuiltGraphSDK(); + +function subgraphTroveToLoan( + trove: Awaited>["troves"][0], +): PositionLoan { + if (!isTroveId(trove.id)) { + throw new Error(`Invalid trove ID: ${trove.id}`); + } + const collSymbol = getCollateralFromTroveSymbol(trove.collateral.token.symbol); + if (!collSymbol) { + throw new Error(`Invalid collateral symbol: ${collSymbol}`); + } + return { + type: "borrow", + borrowed: dnum18(trove.debt), + collateral: collSymbol, + deposit: dnum18(trove.deposit), + interestRate: dnum18(trove.interestRate), + troveId: trove.id, + }; +} + +export let useLoansByAccount = (account?: Address) => { + return useQuery({ + queryKey: ["TrovesByAccount", account], + queryFn: async () => { + if (!account) { + return null; + } + const { troves } = await graphSdk.TrovesByAccount({ account }); + return troves.map(subgraphTroveToLoan); + }, + }); +}; + +if (DEMO_MODE) { + useLoansByAccount = (account?: Address) => { + return useQuery({ + queryKey: ["TrovesByAccount", account], + queryFn: async () => { + if (!account) { + return []; + } + return ACCOUNT_POSITIONS.filter(isPositionLoan); + }, + }); + }; +} + +export let useLoanById = (troveId?: TroveId | null) => { + return useQuery({ + queryKey: ["TroveById", troveId], + queryFn: async () => { + if (!troveId || !isTroveId(troveId)) { + return null; + } + await sleep(500); + const { trove } = await graphSdk.TroveById({ id: troveId }); + return trove && isTroveId(trove.id) + ? subgraphTroveToLoan(trove) + : null; + }, + }); +}; + +if (DEMO_MODE) { + useLoanById = (troveId?: TroveId | null) => { + return useQuery({ + queryKey: ["TroveById", troveId], + queryFn: async () => { + if (!troveId || !isTroveId(troveId)) { + return null; + } + for (const position of ACCOUNT_POSITIONS) { + if (isPositionLoan(position) && position.troveId === troveId) { + return position; + } + } + return null; + }, + }); + }; +} diff --git a/frontend/app/src/subgraph-queries.graphql b/frontend/app/src/subgraph-queries.graphql new file mode 100644 index 00000000..44a43cad --- /dev/null +++ b/frontend/app/src/subgraph-queries.graphql @@ -0,0 +1,41 @@ +query TrovesByAccount($account: Bytes!) { + troves(where: { borrower: $account }) { + id + borrower + debt + deposit + stake + interestRate + createdAt + closedAt + collateral { + id + token { + symbol + name + } + minCollRatio + } + } +} + +query TroveById($id: ID!) { + trove(id: $id) { + id + borrower + debt + deposit + stake + interestRate + createdAt + closedAt + collateral { + id + token { + symbol + name + } + minCollRatio + } + } +} diff --git a/frontend/app/src/types.ts b/frontend/app/src/types.ts index 1e403354..d004bc6d 100644 --- a/frontend/app/src/types.ts +++ b/frontend/app/src/types.ts @@ -6,7 +6,11 @@ export type { Address, CollateralSymbol, Dnum, Token }; export type RiskLevel = "low" | "medium" | "high"; -export type TroveId = bigint; +export type TroveId = `0x${string}`; + +export function isTroveId(value: unknown): value is TroveId { + return typeof value === "string" && /^0x[0-9a-f]+$/.test(value); +} // Utility type to get type-safe entries of an object, // to be used like this: Object.entries(o) as Entries) @@ -34,6 +38,10 @@ export type PositionLoan = { troveId: TroveId; }; +export function isPositionLoan(position: Position): position is PositionLoan { + return position.type === "borrow" || position.type === "leverage"; +} + export type PositionEarn = { type: "earn"; apr: Dnum; diff --git a/frontend/uikit/src/tokens.ts b/frontend/uikit/src/tokens.ts index f63990de..6003bced 100644 --- a/frontend/uikit/src/tokens.ts +++ b/frontend/uikit/src/tokens.ts @@ -9,6 +9,10 @@ import tokenSteth from "./token-icons/wsteth.svg"; export type CollateralSymbol = "ETH" | "RETH" | "STETH"; +export function isCollateralSymbol(symbol: string): symbol is CollateralSymbol { + return symbol === "ETH" || symbol === "RETH" || symbol === "STETH"; +} + export type CollateralToken = Token & { collateralRatio: number; symbol: CollateralSymbol;