From 069ace1c7e0b8f92b62fc812e8d7ed33cfe64c21 Mon Sep 17 00:00:00 2001 From: Dhruv Chauhan Date: Wed, 27 Sep 2023 00:04:42 +0530 Subject: [PATCH 01/10] add friend-tech subgraph --- deployment/deployment.json | 30 + subgraphs/friend-tech/.gitignore | 3 + subgraphs/friend-tech/README.md | 5 + .../friend-tech/abis/ChainLinkAggregator.json | 1009 +++ subgraphs/friend-tech/abis/Shares.json | 1 + .../configurations/configurations.ts | 20 + .../configurations/configurations/deploy.ts | 3 + .../configurations/interface.ts | 9 + .../configurations/configure.mustache | 6 + subgraphs/friend-tech/package-lock.json | 5605 +++++++++++++++++ subgraphs/friend-tech/package.json | 14 + .../friend-tech-base/configurations.json | 12 + .../friend-tech-base/configurations.ts | 26 + .../templates/friend.tech.template.yaml | 34 + subgraphs/friend-tech/schema.graphql | 806 +++ subgraphs/friend-tech/src/common/constants.ts | 102 + subgraphs/friend-tech/src/common/events.ts | 70 + subgraphs/friend-tech/src/common/getters.ts | 593 ++ subgraphs/friend-tech/src/common/metrics.ts | 307 + subgraphs/friend-tech/src/common/prices.ts | 28 + subgraphs/friend-tech/src/common/snapshots.ts | 366 ++ subgraphs/friend-tech/src/common/types.ts | 11 + subgraphs/friend-tech/src/common/utils.ts | 26 + .../friend-tech/src/mappings/handlers.ts | 73 + subgraphs/friend-tech/tsconfig.json | 8 + 25 files changed, 9167 insertions(+) create mode 100644 subgraphs/friend-tech/.gitignore create mode 100644 subgraphs/friend-tech/README.md create mode 100644 subgraphs/friend-tech/abis/ChainLinkAggregator.json create mode 100644 subgraphs/friend-tech/abis/Shares.json create mode 100644 subgraphs/friend-tech/configurations/configurations/configurations.ts create mode 100644 subgraphs/friend-tech/configurations/configurations/deploy.ts create mode 100644 subgraphs/friend-tech/configurations/configurations/interface.ts create mode 100644 subgraphs/friend-tech/configurations/configure.mustache create mode 100644 subgraphs/friend-tech/package-lock.json create mode 100644 subgraphs/friend-tech/package.json create mode 100644 subgraphs/friend-tech/protocols/friend-tech/config/deployments/friend-tech-base/configurations.json create mode 100644 subgraphs/friend-tech/protocols/friend-tech/config/deployments/friend-tech-base/configurations.ts create mode 100644 subgraphs/friend-tech/protocols/friend-tech/config/templates/friend.tech.template.yaml create mode 100644 subgraphs/friend-tech/schema.graphql create mode 100644 subgraphs/friend-tech/src/common/constants.ts create mode 100644 subgraphs/friend-tech/src/common/events.ts create mode 100644 subgraphs/friend-tech/src/common/getters.ts create mode 100644 subgraphs/friend-tech/src/common/metrics.ts create mode 100644 subgraphs/friend-tech/src/common/prices.ts create mode 100644 subgraphs/friend-tech/src/common/snapshots.ts create mode 100644 subgraphs/friend-tech/src/common/types.ts create mode 100644 subgraphs/friend-tech/src/common/utils.ts create mode 100644 subgraphs/friend-tech/src/mappings/handlers.ts create mode 100644 subgraphs/friend-tech/tsconfig.json diff --git a/deployment/deployment.json b/deployment/deployment.json index 584706c396..95bb7e8e74 100644 --- a/deployment/deployment.json +++ b/deployment/deployment.json @@ -9758,5 +9758,35 @@ } } } + }, + "friend-tech": { + "schema": "non-standard", + "base": "friend-tech", + "protocol": "friend-tech", + "project": "friend-tech", + "deployments": { + "friend-tech-base": { + "network": "base", + "status": "dev", + "versions": { + "schema": "1.0.0", + "subgraph": "1.0.0", + "methodology": "1.0.0" + }, + "files": { + "template": "friend.tech.template.yaml" + }, + "options": { + "prepare:yaml": true, + "prepare:constants": true + }, + "services": { + "hosted-service": { + "slug": "friend-tech-base", + "query-id": "friend-tech-base" + } + } + } + } } } diff --git a/subgraphs/friend-tech/.gitignore b/subgraphs/friend-tech/.gitignore new file mode 100644 index 0000000000..03a253692f --- /dev/null +++ b/subgraphs/friend-tech/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +configure.ts +docs/ diff --git a/subgraphs/friend-tech/README.md b/subgraphs/friend-tech/README.md new file mode 100644 index 0000000000..5e36da0efb --- /dev/null +++ b/subgraphs/friend-tech/README.md @@ -0,0 +1,5 @@ +# Friend Tech Protocol Subgraph Metrics Methodology v1.0.0 + +friend-tech subgraph based on a non-standard schema. + +...[WIP] diff --git a/subgraphs/friend-tech/abis/ChainLinkAggregator.json b/subgraphs/friend-tech/abis/ChainLinkAggregator.json new file mode 100644 index 0000000000..7e45419800 --- /dev/null +++ b/subgraphs/friend-tech/abis/ChainLinkAggregator.json @@ -0,0 +1,1009 @@ +[ + { + "inputs": [ + { + "internalType": "uint32", + "name": "_maximumGasPrice", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "_reasonableGasPrice", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "_microLinkPerEth", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "_linkGweiPerObservation", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "_linkGweiPerTransmission", + "type": "uint32" + }, + { + "internalType": "contract LinkTokenInterface", + "name": "_link", + "type": "address" + }, + { "internalType": "int192", "name": "_minAnswer", "type": "int192" }, + { "internalType": "int192", "name": "_maxAnswer", "type": "int192" }, + { + "internalType": "contract AccessControllerInterface", + "name": "_billingAccessController", + "type": "address" + }, + { + "internalType": "contract AccessControllerInterface", + "name": "_requesterAccessController", + "type": "address" + }, + { "internalType": "uint8", "name": "_decimals", "type": "uint8" }, + { "internalType": "string", "name": "description", "type": "string" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "AddedAccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "int256", + "name": "current", + "type": "int256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "roundId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + } + ], + "name": "AnswerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract AccessControllerInterface", + "name": "old", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract AccessControllerInterface", + "name": "current", + "type": "address" + } + ], + "name": "BillingAccessControllerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "maximumGasPrice", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "reasonableGasPrice", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "microLinkPerEth", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "linkGweiPerObservation", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "linkGweiPerTransmission", + "type": "uint32" + } + ], + "name": "BillingSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "CheckAccessDisabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "CheckAccessEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "previousConfigBlockNumber", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "configCount", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "signers", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "transmitters", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "threshold", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "encodedConfigVersion", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "encoded", + "type": "bytes" + } + ], + "name": "ConfigSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract LinkTokenInterface", + "name": "_oldLinkToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract LinkTokenInterface", + "name": "_newLinkToken", + "type": "address" + } + ], + "name": "LinkTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "roundId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "startedBy", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + } + ], + "name": "NewRound", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint32", + "name": "aggregatorRoundId", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "int192", + "name": "answer", + "type": "int192" + }, + { + "indexed": false, + "internalType": "address", + "name": "transmitter", + "type": "address" + }, + { + "indexed": false, + "internalType": "int192[]", + "name": "observations", + "type": "int192[]" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "observers", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "rawReportContext", + "type": "bytes32" + } + ], + "name": "NewTransmission", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "transmitter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "payee", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract LinkTokenInterface", + "name": "linkToken", + "type": "address" + } + ], + "name": "OraclePaid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "OwnershipTransferRequested", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "transmitter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "current", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "proposed", + "type": "address" + } + ], + "name": "PayeeshipTransferRequested", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "transmitter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "previous", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "current", + "type": "address" + } + ], + "name": "PayeeshipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "RemovedAccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract AccessControllerInterface", + "name": "old", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract AccessControllerInterface", + "name": "current", + "type": "address" + } + ], + "name": "RequesterAccessControllerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "requester", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes16", + "name": "configDigest", + "type": "bytes16" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "epoch", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "round", + "type": "uint8" + } + ], + "name": "RoundRequested", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract AggregatorValidatorInterface", + "name": "previousValidator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "previousGasLimit", + "type": "uint32" + }, + { + "indexed": true, + "internalType": "contract AggregatorValidatorInterface", + "name": "currentValidator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "currentGasLimit", + "type": "uint32" + } + ], + "name": "ValidatorConfigSet", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_transmitter", "type": "address" } + ], + "name": "acceptPayeeship", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" } + ], + "name": "addAccess", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "billingAccessController", + "outputs": [ + { + "internalType": "contract AccessControllerInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "checkEnabled", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "description", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disableAccessCheck", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "enableAccessCheck", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_roundId", "type": "uint256" } + ], + "name": "getAnswer", + "outputs": [{ "internalType": "int256", "name": "", "type": "int256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBilling", + "outputs": [ + { "internalType": "uint32", "name": "maximumGasPrice", "type": "uint32" }, + { + "internalType": "uint32", + "name": "reasonableGasPrice", + "type": "uint32" + }, + { "internalType": "uint32", "name": "microLinkPerEth", "type": "uint32" }, + { + "internalType": "uint32", + "name": "linkGweiPerObservation", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "linkGweiPerTransmission", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLinkToken", + "outputs": [ + { + "internalType": "contract LinkTokenInterface", + "name": "linkToken", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint80", "name": "_roundId", "type": "uint80" } + ], + "name": "getRoundData", + "outputs": [ + { "internalType": "uint80", "name": "roundId", "type": "uint80" }, + { "internalType": "int256", "name": "answer", "type": "int256" }, + { "internalType": "uint256", "name": "startedAt", "type": "uint256" }, + { "internalType": "uint256", "name": "updatedAt", "type": "uint256" }, + { "internalType": "uint80", "name": "answeredInRound", "type": "uint80" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_roundId", "type": "uint256" } + ], + "name": "getTimestamp", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" }, + { "internalType": "bytes", "name": "_calldata", "type": "bytes" } + ], + "name": "hasAccess", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestAnswer", + "outputs": [{ "internalType": "int256", "name": "", "type": "int256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestConfigDetails", + "outputs": [ + { "internalType": "uint32", "name": "configCount", "type": "uint32" }, + { "internalType": "uint32", "name": "blockNumber", "type": "uint32" }, + { "internalType": "bytes16", "name": "configDigest", "type": "bytes16" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestRound", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestRoundData", + "outputs": [ + { "internalType": "uint80", "name": "roundId", "type": "uint80" }, + { "internalType": "int256", "name": "answer", "type": "int256" }, + { "internalType": "uint256", "name": "startedAt", "type": "uint256" }, + { "internalType": "uint256", "name": "updatedAt", "type": "uint256" }, + { "internalType": "uint80", "name": "answeredInRound", "type": "uint80" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestTimestamp", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestTransmissionDetails", + "outputs": [ + { "internalType": "bytes16", "name": "configDigest", "type": "bytes16" }, + { "internalType": "uint32", "name": "epoch", "type": "uint32" }, + { "internalType": "uint8", "name": "round", "type": "uint8" }, + { "internalType": "int192", "name": "latestAnswer", "type": "int192" }, + { "internalType": "uint64", "name": "latestTimestamp", "type": "uint64" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "linkAvailableForPayment", + "outputs": [ + { "internalType": "int256", "name": "availableBalance", "type": "int256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxAnswer", + "outputs": [{ "internalType": "int192", "name": "", "type": "int192" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minAnswer", + "outputs": [{ "internalType": "int192", "name": "", "type": "int192" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_signerOrTransmitter", + "type": "address" + } + ], + "name": "oracleObservationCount", + "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_transmitter", "type": "address" } + ], + "name": "owedPayment", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { "internalType": "address payable", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" } + ], + "name": "removeAccess", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "requestNewRound", + "outputs": [{ "internalType": "uint80", "name": "", "type": "uint80" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "requesterAccessController", + "outputs": [ + { + "internalType": "contract AccessControllerInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_maximumGasPrice", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "_reasonableGasPrice", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "_microLinkPerEth", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "_linkGweiPerObservation", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "_linkGweiPerTransmission", + "type": "uint32" + } + ], + "name": "setBilling", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AccessControllerInterface", + "name": "_billingAccessController", + "type": "address" + } + ], + "name": "setBillingAccessController", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_signers", "type": "address[]" }, + { + "internalType": "address[]", + "name": "_transmitters", + "type": "address[]" + }, + { "internalType": "uint8", "name": "_threshold", "type": "uint8" }, + { + "internalType": "uint64", + "name": "_encodedConfigVersion", + "type": "uint64" + }, + { "internalType": "bytes", "name": "_encoded", "type": "bytes" } + ], + "name": "setConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract LinkTokenInterface", + "name": "_linkToken", + "type": "address" + }, + { "internalType": "address", "name": "_recipient", "type": "address" } + ], + "name": "setLinkToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_transmitters", + "type": "address[]" + }, + { "internalType": "address[]", "name": "_payees", "type": "address[]" } + ], + "name": "setPayees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AccessControllerInterface", + "name": "_requesterAccessController", + "type": "address" + } + ], + "name": "setRequesterAccessController", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AggregatorValidatorInterface", + "name": "_newValidator", + "type": "address" + }, + { "internalType": "uint32", "name": "_newGasLimit", "type": "uint32" } + ], + "name": "setValidatorConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_to", "type": "address" }], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_transmitter", "type": "address" }, + { "internalType": "address", "name": "_proposed", "type": "address" } + ], + "name": "transferPayeeship", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes", "name": "_report", "type": "bytes" }, + { "internalType": "bytes32[]", "name": "_rs", "type": "bytes32[]" }, + { "internalType": "bytes32[]", "name": "_ss", "type": "bytes32[]" }, + { "internalType": "bytes32", "name": "_rawVs", "type": "bytes32" } + ], + "name": "transmit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "transmitters", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "typeAndVersion", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "validatorConfig", + "outputs": [ + { + "internalType": "contract AggregatorValidatorInterface", + "name": "validator", + "type": "address" + }, + { "internalType": "uint32", "name": "gasLimit", "type": "uint32" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_recipient", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_transmitter", "type": "address" } + ], + "name": "withdrawPayment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/subgraphs/friend-tech/abis/Shares.json b/subgraphs/friend-tech/abis/Shares.json new file mode 100644 index 0000000000..c3044ce178 --- /dev/null +++ b/subgraphs/friend-tech/abis/Shares.json @@ -0,0 +1 @@ +[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"trader","type":"address"},{"indexed":false,"internalType":"address","name":"subject","type":"address"},{"indexed":false,"internalType":"bool","name":"isBuy","type":"bool"},{"indexed":false,"internalType":"uint256","name":"shareAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"protocolEthAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"subjectEthAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"supply","type":"uint256"}],"name":"Trade","type":"event"},{"inputs":[{"internalType":"address","name":"sharesSubject","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"buyShares","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"sharesSubject","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getBuyPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sharesSubject","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getBuyPriceAfterFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"sharesSubject","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getSellPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sharesSubject","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getSellPriceAfterFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeeDestination","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sharesSubject","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sellShares","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeDestination","type":"address"}],"name":"setFeeDestination","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feePercent","type":"uint256"}],"name":"setProtocolFeePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feePercent","type":"uint256"}],"name":"setSubjectFeePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"sharesBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"sharesSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"subjectFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/subgraphs/friend-tech/configurations/configurations/configurations.ts b/subgraphs/friend-tech/configurations/configurations/configurations.ts new file mode 100644 index 0000000000..0b2e9b78ad --- /dev/null +++ b/subgraphs/friend-tech/configurations/configurations/configurations.ts @@ -0,0 +1,20 @@ +import { log } from "@graphprotocol/graph-ts"; + +import { Configurations } from "./interface"; +import { Deploy } from "./deploy"; +import { FriendTechBaseConfigurations } from "../../protocols/friend-tech/config/deployments/friend-tech-base/configurations"; + +export function getNetworkConfigurations(deploy: i32): Configurations { + switch (deploy) { + case Deploy.FRIEND_TECH_BASE: { + return new FriendTechBaseConfigurations(); + } + default: { + log.critical( + "No configurations found for deployment protocol/network", + [] + ); + return new FriendTechBaseConfigurations(); + } + } +} diff --git a/subgraphs/friend-tech/configurations/configurations/deploy.ts b/subgraphs/friend-tech/configurations/configurations/deploy.ts new file mode 100644 index 0000000000..d5ef14f9e0 --- /dev/null +++ b/subgraphs/friend-tech/configurations/configurations/deploy.ts @@ -0,0 +1,3 @@ +export namespace Deploy { + export const FRIEND_TECH_BASE = 0; +} diff --git a/subgraphs/friend-tech/configurations/configurations/interface.ts b/subgraphs/friend-tech/configurations/configurations/interface.ts new file mode 100644 index 0000000000..8742bf4648 --- /dev/null +++ b/subgraphs/friend-tech/configurations/configurations/interface.ts @@ -0,0 +1,9 @@ +import { Address } from "@graphprotocol/graph-ts"; + +export interface Configurations { + getNetwork(): string; + getProtocolName(): string; + getProtocolSlug(): string; + getFactoryAddress(): Address; + getTreasuryAddress(): Address; +} diff --git a/subgraphs/friend-tech/configurations/configure.mustache b/subgraphs/friend-tech/configurations/configure.mustache new file mode 100644 index 0000000000..971ba89573 --- /dev/null +++ b/subgraphs/friend-tech/configurations/configure.mustache @@ -0,0 +1,6 @@ +import { getNetworkConfigurations } from "./configurations/configurations"; +import { Deploy } from "./configurations/deploy"; + +let deployment = Deploy.{{ deployment }}; + +export const NetworkConfigs = getNetworkConfigurations(deployment); diff --git a/subgraphs/friend-tech/package-lock.json b/subgraphs/friend-tech/package-lock.json new file mode 100644 index 0000000000..456d306fc8 --- /dev/null +++ b/subgraphs/friend-tech/package-lock.json @@ -0,0 +1,5605 @@ +{ + "name": "friends-tech", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "friends-tech", + "license": "MIT", + "dependencies": { + "@graphprotocol/graph-cli": "^0.58.0", + "@graphprotocol/graph-ts": "^0.31.0" + }, + "devDependencies": { + "prettier": "^3.0.3" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "dependencies": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@ethersproject/abi": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", + "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", + "dependencies": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ] + }, + "node_modules/@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@float-capital/float-subgraph-uncrashable": { + "version": "0.0.0-internal-testing.5", + "resolved": "https://registry.npmjs.org/@float-capital/float-subgraph-uncrashable/-/float-subgraph-uncrashable-0.0.0-internal-testing.5.tgz", + "integrity": "sha512-yZ0H5e3EpAYKokX/AbtplzlvSxEJY7ZfpvQyDzyODkks0hakAAlDG6fQu1SlDJMWorY7bbq1j7fCiFeTWci6TA==", + "dependencies": { + "@rescript/std": "9.0.0", + "graphql": "^16.6.0", + "graphql-import-node": "^0.0.5", + "js-yaml": "^4.1.0" + }, + "bin": { + "uncrashable": "bin/uncrashable" + } + }, + "node_modules/@float-capital/float-subgraph-uncrashable/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/@float-capital/float-subgraph-uncrashable/node_modules/graphql": { + "version": "16.8.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.0.tgz", + "integrity": "sha512-0oKGaR+y3qcS5mCu1vb7KG+a89vjn06C7Ihq/dDl3jA+A8B3TKomvi3CiEcVLJQGalbu8F52LxkOym7U5sSfbg==", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, + "node_modules/@float-capital/float-subgraph-uncrashable/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@graphprotocol/graph-cli": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@graphprotocol/graph-cli/-/graph-cli-0.58.0.tgz", + "integrity": "sha512-EbdL5LZFmIMAuItQXv7LXgd7cqYQ3BdIJR2jxNr+LRL0juBAxmEz6zVvYnIUmgXoa5SB5rxE9ZT6pfe+fhbD6Q==", + "dependencies": { + "@float-capital/float-subgraph-uncrashable": "^0.0.0-alpha.4", + "@oclif/core": "2.8.6", + "@oclif/plugin-autocomplete": "^2.3.6", + "@oclif/plugin-not-found": "^2.4.0", + "@whatwg-node/fetch": "^0.8.4", + "assemblyscript": "0.19.23", + "binary-install-raw": "0.0.13", + "chalk": "3.0.0", + "chokidar": "3.5.3", + "debug": "4.3.4", + "docker-compose": "0.23.19", + "dockerode": "2.5.8", + "fs-extra": "9.1.0", + "glob": "9.3.5", + "gluegun": "5.1.2", + "graphql": "15.5.0", + "immutable": "4.2.1", + "ipfs-http-client": "55.0.0", + "jayson": "4.0.0", + "js-yaml": "3.14.1", + "prettier": "1.19.1", + "request": "2.88.2", + "semver": "7.4.0", + "sync-request": "6.1.0", + "tmp-promise": "3.0.3", + "web3-eth-abi": "1.7.0", + "which": "2.0.2", + "yaml": "1.10.2" + }, + "bin": { + "graph": "bin/run" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@graphprotocol/graph-cli/node_modules/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@graphprotocol/graph-ts": { + "version": "0.31.0", + "resolved": "https://registry.npmjs.org/@graphprotocol/graph-ts/-/graph-ts-0.31.0.tgz", + "integrity": "sha512-xreRVM6ho2BtolyOh2flDkNoGZximybnzUnF53zJVp0+Ed0KnAlO1/KOCUYw06euVI9tk0c9nA2Z/D5SIQV2Rg==", + "dependencies": { + "assemblyscript": "0.19.10" + } + }, + "node_modules/@graphprotocol/graph-ts/node_modules/assemblyscript": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.19.10.tgz", + "integrity": "sha512-HavcUBXB3mBTRGJcpvaQjmnmaqKHBGREjSPNsIvnAk2f9dj78y4BkMaSSdvBQYWcDDzsHQjyUC8stICFkD1Odg==", + "dependencies": { + "binaryen": "101.0.0-nightly.20210723", + "long": "^4.0.0" + }, + "bin": { + "asc": "bin/asc", + "asinit": "bin/asinit" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/assemblyscript" + } + }, + "node_modules/@graphprotocol/graph-ts/node_modules/binaryen": { + "version": "101.0.0-nightly.20210723", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-101.0.0-nightly.20210723.tgz", + "integrity": "sha512-eioJNqhHlkguVSbblHOtLqlhtC882SOEPKmNFZaDuz1hzQjolxZ+eu3/kaS10n3sGPONsIZsO7R9fR00UyhEUA==", + "bin": { + "wasm-opt": "bin/wasm-opt" + } + }, + "node_modules/@graphprotocol/graph-ts/node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "node_modules/@ipld/dag-cbor": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@ipld/dag-cbor/-/dag-cbor-7.0.3.tgz", + "integrity": "sha512-1VVh2huHsuohdXC1bGJNE8WR72slZ9XE2T3wbBBq31dm7ZBatmKLLxrB+XAqafxfRFjv08RZmj/W/ZqaM13AuA==", + "dependencies": { + "cborg": "^1.6.0", + "multiformats": "^9.5.4" + } + }, + "node_modules/@ipld/dag-json": { + "version": "8.0.11", + "resolved": "https://registry.npmjs.org/@ipld/dag-json/-/dag-json-8.0.11.tgz", + "integrity": "sha512-Pea7JXeYHTWXRTIhBqBlhw7G53PJ7yta3G/sizGEZyzdeEwhZRr0od5IQ0r2ZxOt1Do+2czddjeEPp+YTxDwCA==", + "dependencies": { + "cborg": "^1.5.4", + "multiformats": "^9.5.4" + } + }, + "node_modules/@ipld/dag-pb": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/@ipld/dag-pb/-/dag-pb-2.1.18.tgz", + "integrity": "sha512-ZBnf2fuX9y3KccADURG5vb9FaOeMjFkCrNysB0PtftME/4iCTjxfaLoNq/IAh5fTqUOMXvryN6Jyka4ZGuMLIg==", + "dependencies": { + "multiformats": "^9.5.4" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@oclif/core": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-2.8.6.tgz", + "integrity": "sha512-1QlPaHMhOORySCXkQyzjsIsy2GYTilOw3LkjeHkCgsPJQjAT4IclVytJusWktPbYNys9O+O4V23J44yomQvnBQ==", + "dependencies": { + "@types/cli-progress": "^3.11.0", + "ansi-escapes": "^4.3.2", + "ansi-styles": "^4.3.0", + "cardinal": "^2.1.1", + "chalk": "^4.1.2", + "clean-stack": "^3.0.1", + "cli-progress": "^3.12.0", + "debug": "^4.3.4", + "ejs": "^3.1.8", + "fs-extra": "^9.1.0", + "get-package-type": "^0.1.0", + "globby": "^11.1.0", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^2.2.0", + "js-yaml": "^3.14.1", + "natural-orderby": "^2.0.3", + "object-treeify": "^1.1.33", + "password-prompt": "^1.1.2", + "semver": "^7.3.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "supports-color": "^8.1.1", + "supports-hyperlinks": "^2.2.0", + "ts-node": "^10.9.1", + "tslib": "^2.5.0", + "widest-line": "^3.1.0", + "wordwrap": "^1.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oclif/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@oclif/core/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@oclif/plugin-autocomplete": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@oclif/plugin-autocomplete/-/plugin-autocomplete-2.3.8.tgz", + "integrity": "sha512-cmRPss9OQxz8sRoaw5C/4t/Da7eBEIDJWKRsuzUSQBcPJCN3kTgjp24VTjPHT3j86197s/qkjCRct+3P0IGArg==", + "dependencies": { + "@oclif/core": "^2.15.0", + "chalk": "^4.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@oclif/plugin-autocomplete/node_modules/@oclif/core": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-2.15.0.tgz", + "integrity": "sha512-fNEMG5DzJHhYmI3MgpByTvltBOMyFcnRIUMxbiz2ai8rhaYgaTHMG3Q38HcosfIvtw9nCjxpcQtC8MN8QtVCcA==", + "dependencies": { + "@types/cli-progress": "^3.11.0", + "ansi-escapes": "^4.3.2", + "ansi-styles": "^4.3.0", + "cardinal": "^2.1.1", + "chalk": "^4.1.2", + "clean-stack": "^3.0.1", + "cli-progress": "^3.12.0", + "debug": "^4.3.4", + "ejs": "^3.1.8", + "get-package-type": "^0.1.0", + "globby": "^11.1.0", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^2.2.0", + "js-yaml": "^3.14.1", + "natural-orderby": "^2.0.3", + "object-treeify": "^1.1.33", + "password-prompt": "^1.1.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "supports-color": "^8.1.1", + "supports-hyperlinks": "^2.2.0", + "ts-node": "^10.9.1", + "tslib": "^2.5.0", + "widest-line": "^3.1.0", + "wordwrap": "^1.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oclif/plugin-autocomplete/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@oclif/plugin-autocomplete/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@oclif/plugin-not-found": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@oclif/plugin-not-found/-/plugin-not-found-2.4.1.tgz", + "integrity": "sha512-LqW7qpw5Q8ploRiup2jEIMQJXcxHP1tpwj45GApKQMe7GRdGdRdjBT9Tu+U2tdEgMqgMplAIhOsYCx2nc2nMSw==", + "dependencies": { + "@oclif/core": "^2.15.0", + "chalk": "^4", + "fast-levenshtein": "^3.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@oclif/plugin-not-found/node_modules/@oclif/core": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-2.15.0.tgz", + "integrity": "sha512-fNEMG5DzJHhYmI3MgpByTvltBOMyFcnRIUMxbiz2ai8rhaYgaTHMG3Q38HcosfIvtw9nCjxpcQtC8MN8QtVCcA==", + "dependencies": { + "@types/cli-progress": "^3.11.0", + "ansi-escapes": "^4.3.2", + "ansi-styles": "^4.3.0", + "cardinal": "^2.1.1", + "chalk": "^4.1.2", + "clean-stack": "^3.0.1", + "cli-progress": "^3.12.0", + "debug": "^4.3.4", + "ejs": "^3.1.8", + "get-package-type": "^0.1.0", + "globby": "^11.1.0", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^2.2.0", + "js-yaml": "^3.14.1", + "natural-orderby": "^2.0.3", + "object-treeify": "^1.1.33", + "password-prompt": "^1.1.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "supports-color": "^8.1.1", + "supports-hyperlinks": "^2.2.0", + "ts-node": "^10.9.1", + "tslib": "^2.5.0", + "widest-line": "^3.1.0", + "wordwrap": "^1.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oclif/plugin-not-found/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@oclif/plugin-not-found/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@peculiar/asn1-schema": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.3.6.tgz", + "integrity": "sha512-izNRxPoaeJeg/AyH8hER6s+H7p4itk+03QCa4sbxI3lNdseQYCuxzgsuNK8bTXChtLTjpJz6NmXKA73qLa3rCA==", + "dependencies": { + "asn1js": "^3.0.5", + "pvtsutils": "^1.3.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@peculiar/json-schema": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz", + "integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@peculiar/webcrypto": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.4.3.tgz", + "integrity": "sha512-VtaY4spKTdN5LjJ04im/d/joXuvLbQdgy5Z4DXF4MFZhQ+MTrejbNMkfZBp1Bs3O5+bFqnJgyGdPuZQflvIa5A==", + "dependencies": { + "@peculiar/asn1-schema": "^2.3.6", + "@peculiar/json-schema": "^1.1.12", + "pvtsutils": "^1.3.2", + "tslib": "^2.5.0", + "webcrypto-core": "^1.7.7" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "node_modules/@rescript/std": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@rescript/std/-/std-9.0.0.tgz", + "integrity": "sha512-zGzFsgtZ44mgL4Xef2gOy1hrRVdrs9mcxCOOKZrIPsmbZW14yTkaF591GXxpQvjXiHtgZ/iA9qLyWH6oSReIxQ==" + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + }, + "node_modules/@types/bn.js": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.2.tgz", + "integrity": "sha512-dkpZu0szUtn9UXTmw+e0AJFd4D2XAxDnsCLdc05SfqpqzPEBft8eQr8uaFitfo/dUUOZERaLec2hHMG87A4Dxg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cli-progress": { + "version": "3.11.2", + "resolved": "https://registry.npmjs.org/@types/cli-progress/-/cli-progress-3.11.2.tgz", + "integrity": "sha512-Yt/8rEJalfa9ve2SbfQnwFHrc9QF52JIZYHW3FDaTMpkCvnns26ueKiPHDxyJ0CS//IqjMINTx7R5Xa7k7uFHQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.36", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz", + "integrity": "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==" + }, + "node_modules/@types/node": { + "version": "20.6.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.2.tgz", + "integrity": "sha512-Y+/1vGBHV/cYk6OI1Na/LHzwnlNCAfU3ZNGrc1LdRe/LAIbdDPTTv/HU3M7yXN448aTVDq3eKRm2cg7iKLb8gw==" + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + }, + "node_modules/@types/pbkdf2": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", + "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.9.8", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", + "integrity": "sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==" + }, + "node_modules/@types/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@whatwg-node/events": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.0.3.tgz", + "integrity": "sha512-IqnKIDWfXBJkvy/k6tzskWTc2NK3LcqHlb+KHGCrjOCH4jfQckRX0NAiIcC/vIqQkzLYw2r2CTSwAxcrtcD6lA==" + }, + "node_modules/@whatwg-node/fetch": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.8.8.tgz", + "integrity": "sha512-CdcjGC2vdKhc13KKxgsc6/616BQ7ooDIgPeTuAiE8qfCnS0mGzcfCOoZXypQSz73nxI+GWc7ZReIAVhxoE1KCg==", + "dependencies": { + "@peculiar/webcrypto": "^1.4.0", + "@whatwg-node/node-fetch": "^0.3.6", + "busboy": "^1.6.0", + "urlpattern-polyfill": "^8.0.0", + "web-streams-polyfill": "^3.2.1" + } + }, + "node_modules/@whatwg-node/node-fetch": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.3.6.tgz", + "integrity": "sha512-w9wKgDO4C95qnXZRwZTfCmLWqyRnooGjcIwG0wADWjw9/HN0p7dtvtgSvItZtUyNteEvgTrd8QojNEqV6DAGTA==", + "dependencies": { + "@whatwg-node/events": "^0.0.3", + "busboy": "^1.6.0", + "fast-querystring": "^1.1.1", + "fast-url-parser": "^1.1.3", + "tslib": "^2.3.1" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==" + }, + "node_modules/any-signal": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/any-signal/-/any-signal-2.1.2.tgz", + "integrity": "sha512-B+rDnWasMi/eWcajPcCWSlYc7muXOrcYrqgyzcdKisl2H/WTlQ0gip1KyQfr0ZlxJdsuWCj/LWwQm7fhyhRfIQ==", + "dependencies": { + "abort-controller": "^3.0.0", + "native-abort-controller": "^1.0.3" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/apisauce": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/apisauce/-/apisauce-2.1.6.tgz", + "integrity": "sha512-MdxR391op/FucS2YQRfB/NMRyCnHEPDd4h17LRIuVYi0BpGmMhpxc0shbOpfs5ahABuBEffNCGal5EcsydbBWg==", + "dependencies": { + "axios": "^0.21.4" + } + }, + "node_modules/app-module-path": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==" + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/asn1js": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.5.tgz", + "integrity": "sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==", + "dependencies": { + "pvtsutils": "^1.3.2", + "pvutils": "^1.1.3", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/assemblyscript": { + "version": "0.19.23", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.19.23.tgz", + "integrity": "sha512-fwOQNZVTMga5KRsfY80g7cpOl4PsFQczMwHzdtgoqLXaYhkhavufKb0sB0l3T1DUxpAufA0KNhlbpuuhZUwxMA==", + "dependencies": { + "binaryen": "102.0.0-nightly.20211028", + "long": "^5.2.0", + "source-map-support": "^0.5.20" + }, + "bin": { + "asc": "bin/asc", + "asinit": "bin/asinit" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/assemblyscript" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" + }, + "node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/binary-install-raw": { + "version": "0.0.13", + "resolved": "https://registry.npmjs.org/binary-install-raw/-/binary-install-raw-0.0.13.tgz", + "integrity": "sha512-v7ms6N/H7iciuk6QInon3/n2mu7oRX+6knJ9xFPsJ3rQePgAqcR3CRTwUheFd8SLbiq4LL7Z4G/44L9zscdt9A==", + "dependencies": { + "axios": "^0.21.1", + "rimraf": "^3.0.2", + "tar": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/binaryen": { + "version": "102.0.0-nightly.20211028", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-102.0.0-nightly.20211028.tgz", + "integrity": "sha512-GCJBVB5exbxzzvyt8MGDv/MeUjs6gkXDvf4xOIItRBptYl0Tz5sm1o/uG95YK0L0VeG5ajDu3hRtkBP2kzqC5w==", + "bin": { + "wasm-opt": "bin/wasm-opt" + } + }, + "node_modules/bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + }, + "node_modules/blob-to-it": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/blob-to-it/-/blob-to-it-1.0.4.tgz", + "integrity": "sha512-iCmk0W4NdbrWgRRuxOriU8aM5ijeVLI61Zulsmg/lUHNr7pYjoj+U77opLefNagevtrrbMt3JQ5Qip7ar178kA==", + "dependencies": { + "browser-readablestream-to-it": "^1.0.3" + } + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "node_modules/browser-readablestream-to-it": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/browser-readablestream-to-it/-/browser-readablestream-to-it-1.0.3.tgz", + "integrity": "sha512-+12sHB+Br8HIh6VAMVEG5r3UXCyESIgDW7kzk3BjIXa43DVqVwL7GC5TW3jeh+72dtcH99pPVpw0X8i0jt+/kw==" + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dependencies": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "node_modules/buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "node_modules/buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "dependencies": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + }, + "bin": { + "cdl": "bin/cdl.js" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + }, + "node_modules/cborg": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/cborg/-/cborg-1.10.2.tgz", + "integrity": "sha512-b3tFPA9pUr2zCUiCfRd2+wok2/LBSNUMKOuRRok+WlvvAgEt/PlbgPTsZUcwCOs53IJvLgTp0eotwtosE6njug==", + "bin": { + "cborg": "cli.js" + } + }, + "node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/clean-stack": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", + "integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==", + "dependencies": { + "escape-string-regexp": "4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-progress": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.12.0.tgz", + "integrity": "sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==", + "dependencies": { + "string-width": "^4.2.3" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.1.tgz", + "integrity": "sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.0.tgz", + "integrity": "sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ==", + "dependencies": { + "object-assign": "^4.1.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "colors": "^1.1.2" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cosmiconfig": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delay": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-over-http-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/dns-over-http-resolver/-/dns-over-http-resolver-1.2.3.tgz", + "integrity": "sha512-miDiVSI6KSNbi4SVifzO/reD8rMnxgrlnkrlkugOLQpWQTe2qMdHsZp5DmfKjxNE+/T3VAAYLQUZMv9SMr6+AA==", + "dependencies": { + "debug": "^4.3.1", + "native-fetch": "^3.0.0", + "receptacle": "^1.3.2" + } + }, + "node_modules/docker-compose": { + "version": "0.23.19", + "resolved": "https://registry.npmjs.org/docker-compose/-/docker-compose-0.23.19.tgz", + "integrity": "sha512-v5vNLIdUqwj4my80wxFDkNH+4S85zsRuH29SO7dCWVWPCMt/ohZBsGN6g6KXWifT0pzQ7uOxqEKCYCDPJ8Vz4g==", + "dependencies": { + "yaml": "^1.10.2" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/docker-modem": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-1.0.9.tgz", + "integrity": "sha512-lVjqCSCIAUDZPAZIeyM125HXfNvOmYYInciphNrLrylUtKyW66meAjSPXWchKVzoIYZx69TPnAepVSSkeawoIw==", + "dependencies": { + "debug": "^3.2.6", + "JSONStream": "1.3.2", + "readable-stream": "~1.0.26-4", + "split-ca": "^1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/docker-modem/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/docker-modem/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "node_modules/docker-modem/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/docker-modem/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, + "node_modules/dockerode": { + "version": "2.5.8", + "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-2.5.8.tgz", + "integrity": "sha512-+7iOUYBeDTScmOmQqpUYQaE7F4vvIt6+gIZNHWhqAQEI887tiPFB9OvXI/HzQYqfUNvukMK+9myLW63oTJPZpw==", + "dependencies": { + "concat-stream": "~1.6.2", + "docker-modem": "^1.0.8", + "tar-fs": "~1.16.3" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ejs": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-fetch": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/electron-fetch/-/electron-fetch-1.9.1.tgz", + "integrity": "sha512-M9qw6oUILGVrcENMSRRefE1MbHPIz0h79EKIeJWK9v563aT9Qkh8aEHPO1H5vi970wPirNY+jO9OpFoLiMsMGA==", + "dependencies": { + "encoding": "^0.1.13" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/err-code": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-3.0.1.tgz", + "integrity": "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==" + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", + "dependencies": { + "es6-promise": "^4.0.3" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ethereum-bloom-filters": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", + "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", + "dependencies": { + "js-sha3": "^0.8.0" + } + }, + "node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethereumjs-util": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==", + "engines": { + "node": "> 0.1.90" + } + }, + "node_modules/fast-decode-uri-component": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fast-levenshtein": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", + "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", + "dependencies": { + "fastest-levenshtein": "^1.0.7" + } + }, + "node_modules/fast-querystring": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", + "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", + "dependencies": { + "fast-decode-uri-component": "^1.0.1" + } + }, + "node_modules/fast-url-parser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", + "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", + "dependencies": { + "punycode": "^1.3.2" + } + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs-jetpack": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/fs-jetpack/-/fs-jetpack-4.3.1.tgz", + "integrity": "sha512-dbeOK84F6BiQzk2yqqCVwCPWTxAvVGJ3fMQc6E2wuEohS28mR6yHngbrKuVCK1KHRx/ccByDylqu4H5PCP2urQ==", + "dependencies": { + "minimatch": "^3.0.2", + "rimraf": "^2.6.3" + } + }, + "node_modules/fs-jetpack/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/fs-jetpack/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fs-jetpack/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/fs-jetpack/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-iterator": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-iterator/-/get-iterator-1.0.2.tgz", + "integrity": "sha512-v+dm9bNVfOYsY1OrhaCrmyOcYoSeVvbt+hHZ0Au+T+p1y+0Uyj9aMaGIeUTT6xdpRbWzDeYKvfOslPhggQMcsg==" + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gluegun": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/gluegun/-/gluegun-5.1.2.tgz", + "integrity": "sha512-Cwx/8S8Z4YQg07a6AFsaGnnnmd8mN17414NcPS3OoDtZRwxgsvwRNJNg69niD6fDa8oNwslCG0xH7rEpRNNE/g==", + "dependencies": { + "apisauce": "^2.1.5", + "app-module-path": "^2.2.0", + "cli-table3": "0.6.0", + "colors": "1.4.0", + "cosmiconfig": "7.0.1", + "cross-spawn": "7.0.3", + "ejs": "3.1.6", + "enquirer": "2.3.6", + "execa": "5.1.1", + "fs-jetpack": "4.3.1", + "lodash.camelcase": "^4.3.0", + "lodash.kebabcase": "^4.1.1", + "lodash.lowercase": "^4.3.0", + "lodash.lowerfirst": "^4.3.1", + "lodash.pad": "^4.5.1", + "lodash.padend": "^4.6.1", + "lodash.padstart": "^4.6.1", + "lodash.repeat": "^4.1.0", + "lodash.snakecase": "^4.1.1", + "lodash.startcase": "^4.4.0", + "lodash.trim": "^4.5.1", + "lodash.trimend": "^4.5.1", + "lodash.trimstart": "^4.5.1", + "lodash.uppercase": "^4.3.0", + "lodash.upperfirst": "^4.3.1", + "ora": "4.0.2", + "pluralize": "^8.0.0", + "semver": "7.3.5", + "which": "2.0.2", + "yargs-parser": "^21.0.0" + }, + "bin": { + "gluegun": "bin/gluegun" + } + }, + "node_modules/gluegun/node_modules/ejs": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", + "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", + "dependencies": { + "jake": "^10.6.1" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gluegun/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gluegun/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/graphql": { + "version": "15.5.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.5.0.tgz", + "integrity": "sha512-OmaM7y0kaK31NKG31q4YbD2beNYa6jBBKtMFT6gLYJljHLJr42IqJ8KX08u3Li/0ifzTU5HjmoOOrwa5BRLeDA==", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/graphql-import-node": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/graphql-import-node/-/graphql-import-node-0.0.5.tgz", + "integrity": "sha512-OXbou9fqh9/Lm7vwXT0XoRN9J5+WCYKnbiTalgFDvkQERITRmcfncZs6aVABedd5B85yQU5EULS4a5pnbpuI0Q==", + "peerDependencies": { + "graphql": "*" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash-base/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hash-base/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "dependencies": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "dependencies": { + "@types/node": "^10.0.3" + } + }, + "node_modules/http-response-object/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/hyperlinker": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz", + "integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immutable": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.2.1.tgz", + "integrity": "sha512-7WYV7Q5BTs0nlQm7tl92rDYYoyELLKHoDMBKhrxEoiV4mrfVdRz8hzPiYOzH7yWjzoVEamxRuAqhxL2PLRwZYQ==" + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/interface-datastore": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/interface-datastore/-/interface-datastore-6.1.1.tgz", + "integrity": "sha512-AmCS+9CT34pp2u0QQVXjKztkuq3y5T+BIciuiHDDtDZucZD8VudosnSdUyXJV6IsRkN5jc4RFDhCk1O6Q3Gxjg==", + "dependencies": { + "interface-store": "^2.0.2", + "nanoid": "^3.0.2", + "uint8arrays": "^3.0.0" + } + }, + "node_modules/interface-store": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/interface-store/-/interface-store-2.0.2.tgz", + "integrity": "sha512-rScRlhDcz6k199EkHqT8NpM87ebN89ICOzILoBHgaG36/WX50N32BnU/kpZgCGPLhARRAWUUX5/cyaIjt7Kipg==" + }, + "node_modules/ip-regex": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", + "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ipfs-core-types": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/ipfs-core-types/-/ipfs-core-types-0.9.0.tgz", + "integrity": "sha512-VJ8vJSHvI1Zm7/SxsZo03T+zzpsg8pkgiIi5hfwSJlsrJ1E2v68QPlnLshGHUSYw89Oxq0IbETYl2pGTFHTWfg==", + "deprecated": "js-IPFS has been deprecated in favour of Helia - please see https://github.com/ipfs/js-ipfs/issues/4336 for details", + "dependencies": { + "interface-datastore": "^6.0.2", + "multiaddr": "^10.0.0", + "multiformats": "^9.4.13" + } + }, + "node_modules/ipfs-core-utils": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/ipfs-core-utils/-/ipfs-core-utils-0.13.0.tgz", + "integrity": "sha512-HP5EafxU4/dLW3U13CFsgqVO5Ika8N4sRSIb/dTg16NjLOozMH31TXV0Grtu2ZWo1T10ahTzMvrfT5f4mhioXw==", + "deprecated": "js-IPFS has been deprecated in favour of Helia - please see https://github.com/ipfs/js-ipfs/issues/4336 for details", + "dependencies": { + "any-signal": "^2.1.2", + "blob-to-it": "^1.0.1", + "browser-readablestream-to-it": "^1.0.1", + "debug": "^4.1.1", + "err-code": "^3.0.1", + "ipfs-core-types": "^0.9.0", + "ipfs-unixfs": "^6.0.3", + "ipfs-utils": "^9.0.2", + "it-all": "^1.0.4", + "it-map": "^1.0.4", + "it-peekable": "^1.0.2", + "it-to-stream": "^1.0.0", + "merge-options": "^3.0.4", + "multiaddr": "^10.0.0", + "multiaddr-to-uri": "^8.0.0", + "multiformats": "^9.4.13", + "nanoid": "^3.1.23", + "parse-duration": "^1.0.0", + "timeout-abort-controller": "^2.0.0", + "uint8arrays": "^3.0.0" + } + }, + "node_modules/ipfs-http-client": { + "version": "55.0.0", + "resolved": "https://registry.npmjs.org/ipfs-http-client/-/ipfs-http-client-55.0.0.tgz", + "integrity": "sha512-GpvEs7C7WL9M6fN/kZbjeh4Y8YN7rY8b18tVWZnKxRsVwM25cIFrRI8CwNt3Ugin9yShieI3i9sPyzYGMrLNnQ==", + "deprecated": "js-IPFS has been deprecated in favour of Helia - please see https://github.com/ipfs/js-ipfs/issues/4336 for details", + "dependencies": { + "@ipld/dag-cbor": "^7.0.0", + "@ipld/dag-json": "^8.0.1", + "@ipld/dag-pb": "^2.1.3", + "abort-controller": "^3.0.0", + "any-signal": "^2.1.2", + "debug": "^4.1.1", + "err-code": "^3.0.1", + "ipfs-core-types": "^0.9.0", + "ipfs-core-utils": "^0.13.0", + "ipfs-utils": "^9.0.2", + "it-first": "^1.0.6", + "it-last": "^1.0.4", + "merge-options": "^3.0.4", + "multiaddr": "^10.0.0", + "multiformats": "^9.4.13", + "native-abort-controller": "^1.0.3", + "parse-duration": "^1.0.0", + "stream-to-it": "^0.2.2", + "uint8arrays": "^3.0.0" + }, + "engines": { + "node": ">=14.0.0", + "npm": ">=3.0.0" + } + }, + "node_modules/ipfs-unixfs": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/ipfs-unixfs/-/ipfs-unixfs-6.0.9.tgz", + "integrity": "sha512-0DQ7p0/9dRB6XCb0mVCTli33GzIzSVx5udpJuVM47tGcD+W+Bl4LsnoLswd3ggNnNEakMv1FdoFITiEnchXDqQ==", + "dependencies": { + "err-code": "^3.0.1", + "protobufjs": "^6.10.2" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/ipfs-utils": { + "version": "9.0.14", + "resolved": "https://registry.npmjs.org/ipfs-utils/-/ipfs-utils-9.0.14.tgz", + "integrity": "sha512-zIaiEGX18QATxgaS0/EOQNoo33W0islREABAcxXE8n7y2MGAlB+hdsxXn4J0hGZge8IqVQhW8sWIb+oJz2yEvg==", + "dependencies": { + "any-signal": "^3.0.0", + "browser-readablestream-to-it": "^1.0.0", + "buffer": "^6.0.1", + "electron-fetch": "^1.7.2", + "err-code": "^3.0.1", + "is-electron": "^2.2.0", + "iso-url": "^1.1.5", + "it-all": "^1.0.4", + "it-glob": "^1.0.1", + "it-to-stream": "^1.0.0", + "merge-options": "^3.0.4", + "nanoid": "^3.1.20", + "native-fetch": "^3.0.0", + "node-fetch": "^2.6.8", + "react-native-fetch-api": "^3.0.0", + "stream-to-it": "^0.2.2" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/ipfs-utils/node_modules/any-signal": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/any-signal/-/any-signal-3.0.1.tgz", + "integrity": "sha512-xgZgJtKEa9YmDqXodIgl7Fl1C8yNXr8w6gXjqK3LW4GcEiYT+6AQfJSE/8SPsEpLLmcvbv8YU+qet94UewHxqg==" + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-electron": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.2.2.tgz", + "integrity": "sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==" + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ip": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz", + "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==", + "dependencies": { + "ip-regex": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/iso-url": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iso-url/-/iso-url-1.2.1.tgz", + "integrity": "sha512-9JPDgCN4B7QPkLtYAAOrEuAWvP9rWvR5offAr0/SeF046wIkglqH3VXgYYP6NcsKslH80UIVgmPqNe3j7tG2ng==", + "engines": { + "node": ">=12" + } + }, + "node_modules/isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + }, + "node_modules/it-all": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/it-all/-/it-all-1.0.6.tgz", + "integrity": "sha512-3cmCc6Heqe3uWi3CVM/k51fa/XbMFpQVzFoDsV0IZNHSQDyAXl3c4MjHkFX5kF3922OGj7Myv1nSEUgRtcuM1A==" + }, + "node_modules/it-first": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/it-first/-/it-first-1.0.7.tgz", + "integrity": "sha512-nvJKZoBpZD/6Rtde6FXqwDqDZGF1sCADmr2Zoc0hZsIvnE449gRFnGctxDf09Bzc/FWnHXAdaHVIetY6lrE0/g==" + }, + "node_modules/it-glob": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/it-glob/-/it-glob-1.0.2.tgz", + "integrity": "sha512-Ch2Dzhw4URfB9L/0ZHyY+uqOnKvBNeS/SMcRiPmJfpHiM0TsUZn+GkpcZxAoF3dJVdPm/PuIk3A4wlV7SUo23Q==", + "dependencies": { + "@types/minimatch": "^3.0.4", + "minimatch": "^3.0.4" + } + }, + "node_modules/it-glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/it-glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/it-last": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/it-last/-/it-last-1.0.6.tgz", + "integrity": "sha512-aFGeibeiX/lM4bX3JY0OkVCFkAw8+n9lkukkLNivbJRvNz8lI3YXv5xcqhFUV2lDJiraEK3OXRDbGuevnnR67Q==" + }, + "node_modules/it-map": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/it-map/-/it-map-1.0.6.tgz", + "integrity": "sha512-XT4/RM6UHIFG9IobGlQPFQUrlEKkU4eBUFG3qhWhfAdh1JfF2x11ShCrKCdmZ0OiZppPfoLuzcfA4cey6q3UAQ==" + }, + "node_modules/it-peekable": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/it-peekable/-/it-peekable-1.0.3.tgz", + "integrity": "sha512-5+8zemFS+wSfIkSZyf0Zh5kNN+iGyccN02914BY4w/Dj+uoFEoPSvj5vaWn8pNZJNSxzjW0zHRxC3LUb2KWJTQ==" + }, + "node_modules/it-to-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/it-to-stream/-/it-to-stream-1.0.0.tgz", + "integrity": "sha512-pLULMZMAB/+vbdvbZtebC0nWBTbG581lk6w8P7DfIIIKUfa8FbY7Oi0FxZcFPbxvISs7A9E+cMpLDBc1XhpAOA==", + "dependencies": { + "buffer": "^6.0.3", + "fast-fifo": "^1.0.0", + "get-iterator": "^1.0.2", + "p-defer": "^3.0.0", + "p-fifo": "^1.0.0", + "readable-stream": "^3.6.0" + } + }, + "node_modules/it-to-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jake": { + "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/jake/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jake/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jake/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jayson": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-4.0.0.tgz", + "integrity": "sha512-v2RNpDCMu45fnLzSk47vx7I+QUaOsox6f5X0CUlabAFwxoP+8MfAY0NQRFwOEYXIxm8Ih5y6OaEa5KYiQMkyAA==", + "dependencies": { + "@types/connect": "^3.4.33", + "@types/node": "^12.12.54", + "@types/ws": "^7.4.4", + "commander": "^2.20.3", + "delay": "^5.0.0", + "es6-promisify": "^5.0.0", + "eyes": "^0.1.8", + "isomorphic-ws": "^4.0.1", + "json-stringify-safe": "^5.0.1", + "JSONStream": "^1.3.5", + "uuid": "^8.3.2", + "ws": "^7.4.5" + }, + "bin": { + "jayson": "bin/jayson.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jayson/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" + }, + "node_modules/jayson/node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/JSONStream": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", + "integrity": "sha512-mn0KSip7N4e0UDPZHnqDsHECo5uGQrixQKnAskOM1BIB8hd7QKbd6il8IPRPudPHOeHiECoCFqhyMaRO9+nWyA==", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/keccak": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.3.tgz", + "integrity": "sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==", + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/keccak/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==" + }, + "node_modules/lodash.lowercase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.lowercase/-/lodash.lowercase-4.3.0.tgz", + "integrity": "sha512-UcvP1IZYyDKyEL64mmrwoA1AbFu5ahojhTtkOUr1K9dbuxzS9ev8i4TxMMGCqRC9TE8uDaSoufNAXxRPNTseVA==" + }, + "node_modules/lodash.lowerfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.lowerfirst/-/lodash.lowerfirst-4.3.1.tgz", + "integrity": "sha512-UUKX7VhP1/JL54NXg2aq/E1Sfnjjes8fNYTNkPU8ZmsaVeBvPHKdbNaN79Re5XRL01u6wbq3j0cbYZj71Fcu5w==" + }, + "node_modules/lodash.pad": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", + "integrity": "sha512-mvUHifnLqM+03YNzeTBS1/Gr6JRFjd3rRx88FHWUvamVaT9k2O/kXha3yBSOwB9/DTQrSTLJNHvLBBt2FdX7Mg==" + }, + "node_modules/lodash.padend": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", + "integrity": "sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw==" + }, + "node_modules/lodash.padstart": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", + "integrity": "sha512-sW73O6S8+Tg66eY56DBk85aQzzUJDtpoXFBgELMd5P/SotAguo+1kYO6RuYgXxA4HJH3LFTFPASX6ET6bjfriw==" + }, + "node_modules/lodash.repeat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.repeat/-/lodash.repeat-4.1.0.tgz", + "integrity": "sha512-eWsgQW89IewS95ZOcr15HHCX6FVDxq3f2PNUIng3fyzsPev9imFQxIYdFZ6crl8L56UR6ZlGDLcEb3RZsCSSqw==" + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==" + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==" + }, + "node_modules/lodash.trim": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.trim/-/lodash.trim-4.5.1.tgz", + "integrity": "sha512-nJAlRl/K+eiOehWKDzoBVrSMhK0K3A3YQsUNXHQa5yIrKBAhsZgSu3KoAFoFT+mEgiyBHddZ0pRk1ITpIp90Wg==" + }, + "node_modules/lodash.trimend": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.trimend/-/lodash.trimend-4.5.1.tgz", + "integrity": "sha512-lsD+k73XztDsMBKPKvzHXRKFNMohTjoTKIIo4ADLn5dA65LZ1BqlAvSXhR2rPEC3BgAUQnzMnorqDtqn2z4IHA==" + }, + "node_modules/lodash.trimstart": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.trimstart/-/lodash.trimstart-4.5.1.tgz", + "integrity": "sha512-b/+D6La8tU76L/61/aN0jULWHkT0EeJCmVstPBn/K9MtD2qBW83AsBNrr63dKuWYwVMO7ucv13QNO/Ek/2RKaQ==" + }, + "node_modules/lodash.uppercase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.uppercase/-/lodash.uppercase-4.3.0.tgz", + "integrity": "sha512-+Nbnxkj7s8K5U8z6KnEYPGUOGp3woZbB7Ecs7v3LkkjLQSm2kP9SKIILitN1ktn2mB/tmM9oSlku06I+/lH7QA==" + }, + "node_modules/lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==" + }, + "node_modules/log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dependencies": { + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/log-symbols/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, + "node_modules/lru-cache": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/merge-options": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz", + "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==", + "dependencies": { + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "node_modules/minimatch": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/multiaddr": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/multiaddr/-/multiaddr-10.0.1.tgz", + "integrity": "sha512-G5upNcGzEGuTHkzxezPrrD6CaIHR9uo+7MwqhNVcXTs33IInon4y7nMiGxl2CY5hG7chvYQUQhz5V52/Qe3cbg==", + "deprecated": "This module is deprecated, please upgrade to @multiformats/multiaddr", + "dependencies": { + "dns-over-http-resolver": "^1.2.3", + "err-code": "^3.0.1", + "is-ip": "^3.1.0", + "multiformats": "^9.4.5", + "uint8arrays": "^3.0.0", + "varint": "^6.0.0" + } + }, + "node_modules/multiaddr-to-uri": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/multiaddr-to-uri/-/multiaddr-to-uri-8.0.0.tgz", + "integrity": "sha512-dq4p/vsOOUdVEd1J1gl+R2GFrXJQH8yjLtz4hodqdVbieg39LvBOdMQRdQnfbg5LSM/q1BYNVf5CBbwZFFqBgA==", + "deprecated": "This module is deprecated, please upgrade to @multiformats/multiaddr-to-uri", + "dependencies": { + "multiaddr": "^10.0.0" + } + }, + "node_modules/multiformats": { + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", + "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==" + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/native-abort-controller": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/native-abort-controller/-/native-abort-controller-1.0.4.tgz", + "integrity": "sha512-zp8yev7nxczDJMoP6pDxyD20IU0T22eX8VwN2ztDccKvSZhRaV33yP1BGwKSZfXuqWUzsXopVFjBdau9OOAwMQ==", + "peerDependencies": { + "abort-controller": "*" + } + }, + "node_modules/native-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/native-fetch/-/native-fetch-3.0.0.tgz", + "integrity": "sha512-G3Z7vx0IFb/FQ4JxvtqGABsOTIqRWvgQz6e+erkB+JJD6LrszQtMozEHI4EkmgZQvnGHrpLVzUWk7t4sJCIkVw==", + "peerDependencies": { + "node-fetch": "*" + } + }, + "node_modules/natural-orderby": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/natural-orderby/-/natural-orderby-2.0.3.tgz", + "integrity": "sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q==", + "engines": { + "node": "*" + } + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.1.tgz", + "integrity": "sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", + "dependencies": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-treeify": { + "version": "1.1.33", + "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz", + "integrity": "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/ora/-/ora-4.0.2.tgz", + "integrity": "sha512-YUOZbamht5mfLxPmk4M35CD/5DuOkAacxlEUbStVXpBAt4fyhBf+vZHI/HRkI++QUp3sNoeA2Gw4C+hi4eGSig==", + "dependencies": { + "chalk": "^2.4.2", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.2.0", + "is-interactive": "^1.0.0", + "log-symbols": "^3.0.0", + "strip-ansi": "^5.2.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ora/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/ora/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ora/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-defer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-3.0.0.tgz", + "integrity": "sha512-ugZxsxmtTln604yeYd29EGrNhazN2lywetzpKhfmQjW/VJmhpDmWbiX+h0zL8V91R0UXkhb3KtPmyq9PZw3aYw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-fifo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-fifo/-/p-fifo-1.0.0.tgz", + "integrity": "sha512-IjoCxXW48tqdtDFz6fqo5q1UfFVjjVZe8TC1QRflvNUJtNfCUhxOUw6MOVZhDPjqhSzc26xKdugsO17gmzd5+A==", + "dependencies": { + "fast-fifo": "^1.0.0", + "p-defer": "^3.0.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==" + }, + "node_modules/parse-duration": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-1.1.0.tgz", + "integrity": "sha512-z6t9dvSJYaPoQq7quMzdEagSFtpGu+utzHqqxmpVWNNZRIXnvqyCvn9XsTdh7c/w0Bqmdz3RB3YnRaKtpRtEXQ==" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/password-prompt": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/password-prompt/-/password-prompt-1.1.3.tgz", + "integrity": "sha512-HkrjG2aJlvF0t2BMH0e2LB/EHf3Lcq3fNMzy4GYHcQblAvOl+QQji1Lx7WRBMqpVK8p+KR7bCg7oqAMXtdgqyw==", + "dependencies": { + "ansi-escapes": "^4.3.2", + "cross-spawn": "^7.0.3" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", + "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/prettier": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", + "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/protobufjs": { + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", + "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/protobufjs/node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "node_modules/pump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", + "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + }, + "node_modules/pvtsutils": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.5.tgz", + "integrity": "sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==", + "dependencies": { + "tslib": "^2.6.1" + } + }, + "node_modules/pvutils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz", + "integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/react-native-fetch-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-native-fetch-api/-/react-native-fetch-api-3.0.0.tgz", + "integrity": "sha512-g2rtqPjdroaboDKTsJCTlcmtw54E25OjyaunUP0anOZn4Fuo2IKs8BVfe02zVggA/UysbmfSnRJIqtNkAgggNA==", + "dependencies": { + "p-defer": "^3.0.0" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/receptacle": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/receptacle/-/receptacle-1.3.2.tgz", + "integrity": "sha512-HrsFvqZZheusncQRiEE7GatOAETrARKV/lnfYicIm8lbvp/JQOdADOfhjBd2DajvoszEyxSM6RlAAIZgEoeu/A==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", + "dependencies": { + "esprima": "~4.0.0" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retimer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/retimer/-/retimer-3.0.0.tgz", + "integrity": "sha512-WKE0j11Pa0ZJI5YIk0nflGI7SQsfl2ljihVy7ogh7DeQSeYAUi0ubZ/yEueGtDfUPk6GH5LRw1hBdLq4IwUBWA==" + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "dependencies": { + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "hasInstallScript": true, + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/semver": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/split-ca": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz", + "integrity": "sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==" + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stream-to-it": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/stream-to-it/-/stream-to-it-0.2.4.tgz", + "integrity": "sha512-4vEbkSs83OahpmBybNJXlJd7d6/RxzkkSdT3I0mnGt79Xd2Kk+e1JqbvAvsQfCeKj3aKb0QIWkyK3/n0j506vQ==", + "dependencies": { + "get-iterator": "^1.0.2" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "dependencies": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "dependencies": { + "get-port": "^3.1.0" + } + }, + "node_modules/tar": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", + "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-fs": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", + "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", + "dependencies": { + "chownr": "^1.0.1", + "mkdirp": "^0.5.1", + "pump": "^1.0.0", + "tar-stream": "^1.1.2" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/tar-fs/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dependencies": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "dependencies": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/then-request/node_modules/@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "node_modules/timeout-abort-controller": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/timeout-abort-controller/-/timeout-abort-controller-2.0.0.tgz", + "integrity": "sha512-2FAPXfzTPYEgw27bQGTHc0SzrbmnU2eso4qo172zMLZzaGqeu09PFa5B2FCUHM1tflgRqPgn5KQgp6+Vex4uNA==", + "dependencies": { + "abort-controller": "^3.0.0", + "native-abort-controller": "^1.0.4", + "retimer": "^3.0.0" + } + }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "dependencies": { + "tmp": "^0.2.0" + } + }, + "node_modules/to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tough-cookie/node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uint8arrays": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz", + "integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==", + "dependencies": { + "multiformats": "^9.4.2" + } + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/urlpattern-polyfill": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz", + "integrity": "sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==" + }, + "node_modules/utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "node_modules/varint": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", + "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==" + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/web3-eth-abi": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.0.tgz", + "integrity": "sha512-heqR0bWxgCJwjWIhq2sGyNj9bwun5+Xox/LdZKe+WMyTSy0cXDXEAgv3XKNkXC4JqdDt/ZlbTEx4TWak4TRMSg==", + "dependencies": { + "@ethersproject/abi": "5.0.7", + "web3-utils": "1.7.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-utils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.0.tgz", + "integrity": "sha512-O8Tl4Ky40Sp6pe89Olk2FsaUkgHyb5QAXuaKo38ms3CxZZ4d3rPGfjP9DNKGm5+IUgAZBNpF1VmlSmNCqfDI1w==", + "dependencies": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-utils/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/webcrypto-core": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.7.7.tgz", + "integrity": "sha512-7FjigXNsBfopEj+5DV2nhNpfic2vumtjjgPmeDKk45z+MJwXKKfhPB7118Pfzrmh4jqOMST6Ch37iPAHoImg5g==", + "dependencies": { + "@peculiar/asn1-schema": "^2.3.6", + "@peculiar/json-schema": "^1.1.12", + "asn1js": "^3.0.1", + "pvtsutils": "^1.3.2", + "tslib": "^2.4.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } + } + } +} diff --git a/subgraphs/friend-tech/package.json b/subgraphs/friend-tech/package.json new file mode 100644 index 0000000000..c113dcffed --- /dev/null +++ b/subgraphs/friend-tech/package.json @@ -0,0 +1,14 @@ +{ + "name": "friends-tech", + "license": "MIT", + "scripts": { + "prepare:constants": "mustache protocols/${npm_config_protocol}/config/deployments/${npm_config_id}/configurations.json configurations/configure.mustache > configurations/configure.ts" + }, + "dependencies": { + "@graphprotocol/graph-cli": "^0.58.0", + "@graphprotocol/graph-ts": "^0.31.0" + }, + "devDependencies": { + "prettier": "^3.0.3" + } +} diff --git a/subgraphs/friend-tech/protocols/friend-tech/config/deployments/friend-tech-base/configurations.json b/subgraphs/friend-tech/protocols/friend-tech/config/deployments/friend-tech-base/configurations.json new file mode 100644 index 0000000000..bbb6651897 --- /dev/null +++ b/subgraphs/friend-tech/protocols/friend-tech/config/deployments/friend-tech-base/configurations.json @@ -0,0 +1,12 @@ +{ + "deployment": "FRIEND_TECH_BASE", + "network": "base", + "file": "./src/mappings/handlers.ts", + "graftEnabled": false, + "subgraphId": "", + "graftStartBlock": 0, + "shares": { + "address": "0xCF205808Ed36593aa40a44F10c7f7C2F67d4A4d4", + "startBlock": "2430440" + } +} diff --git a/subgraphs/friend-tech/protocols/friend-tech/config/deployments/friend-tech-base/configurations.ts b/subgraphs/friend-tech/protocols/friend-tech/config/deployments/friend-tech-base/configurations.ts new file mode 100644 index 0000000000..294d85af58 --- /dev/null +++ b/subgraphs/friend-tech/protocols/friend-tech/config/deployments/friend-tech-base/configurations.ts @@ -0,0 +1,26 @@ +import { Address } from "@graphprotocol/graph-ts"; + +import { Configurations } from "../../../../../configurations/configurations/interface"; +import { + Network, + PROTOCOL_NAME, + PROTOCOL_SLUG, +} from "../../../../../src/common/constants"; + +export class FriendTechBaseConfigurations implements Configurations { + getNetwork(): string { + return Network.BASE; + } + getProtocolName(): string { + return PROTOCOL_NAME; + } + getProtocolSlug(): string { + return PROTOCOL_SLUG; + } + getFactoryAddress(): Address { + return Address.fromString("0xCF205808Ed36593aa40a44F10c7f7C2F67d4A4d4"); + } + getTreasuryAddress(): Address { + return Address.fromString("0xdd9176eA3E7559D6B68b537eF555D3e89403f742"); + } +} diff --git a/subgraphs/friend-tech/protocols/friend-tech/config/templates/friend.tech.template.yaml b/subgraphs/friend-tech/protocols/friend-tech/config/templates/friend.tech.template.yaml new file mode 100644 index 0000000000..c42404f9fa --- /dev/null +++ b/subgraphs/friend-tech/protocols/friend-tech/config/templates/friend.tech.template.yaml @@ -0,0 +1,34 @@ +specVersion: 0.0.4 +schema: + file: ./schema.graphql +{{#graftEnabled}} +description: ... +features: + - grafting +graft: + base: {{subgraphId}} # Subgraph ID of base subgraph + block: {{graftStartBlock}} # Block number +{{/graftEnabled}} +dataSources: + - kind: ethereum + name: Shares + network: {{ network }} + source: + address: "{{ shares.address }}" + abi: Shares + startBlock: {{ shares.startBlock }} + mapping: + kind: ethereum/events + apiVersion: 0.0.6 + language: wasm/assemblyscript + entities: + - Protocol + abis: + - name: Shares + file: ./abis/Shares.json + - name: ChainLinkAggregator + file: ./abis/ChainLinkAggregator.json + eventHandlers: + - event: Trade(address,address,bool,uint256,uint256,uint256,uint256,uint256) + handler: handleTrade + file: {{{ file }}} diff --git a/subgraphs/friend-tech/schema.graphql b/subgraphs/friend-tech/schema.graphql new file mode 100644 index 0000000000..d2de4c687d --- /dev/null +++ b/subgraphs/friend-tech/schema.graphql @@ -0,0 +1,806 @@ +# Subgraph Schema: Non-Standard +# Version: 1.0.0 +# See https://github.com/messari/subgraphs/blob/master/docs/SCHEMA.md for details + +enum Network { + ARBITRUM_ONE + ARWEAVE_MAINNET + AURORA + AVALANCHE + BASE + BOBA + BSC # aka BNB Chain + CELO + COSMOS + CRONOS + MAINNET # Ethereum Mainnet + FANTOM + FUSE + HARMONY + JUNO + MOONBEAM + MOONRIVER + NEAR_MAINNET + OPTIMISM + OSMOSIS + MATIC # aka Polygon + GNOSIS +} + +enum ProtocolType { + EXCHANGE + LENDING + YIELD + BRIDGE + GENERIC + SOCIAL + # Will add more +} + +enum TradeType { + BUY + SELL +} + +type Token @entity @regularPolling { + " Smart contract address of the token " + id: Bytes! + + " Name of the token, mirrored from the smart contract " + name: String! + + " Symbol of the token, mirrored from the smart contract " + symbol: String! + + " The number of decimal places this token uses, default to 18 " + decimals: Int! + + " Optional field to track the price of a token, mostly for caching purposes " + lastPriceUSD: BigDecimal + + " Optional field to track the block number of the last token price " + lastPriceBlockNumber: BigInt +} + +############################# +##### Protocol Metadata ##### +############################# + +type Protocol @entity @regularPolling { + " Smart contract address of the protocol's main contract (Factory, Registry, etc) " + id: Bytes! + + " Name of the protocol, including version. e.g. Uniswap v3 " + name: String! + + " Slug of protocol, including version. e.g. uniswap-v3 " + slug: String! + + " Version of the subgraph schema, in SemVer format (e.g. 1.0.0) " + schemaVersion: String! + + " Version of the subgraph implementation, in SemVer format (e.g. 1.0.0) " + subgraphVersion: String! + + " Version of the methodology used to compute metrics, loosely based on SemVer format (e.g. 1.0.0) " + methodologyVersion: String! + + " The blockchain network this subgraph is indexing on " + network: Network! + + " The type of protocol (e.g. DEX, Lending, Yield, etc) " + type: ProtocolType! + + ##### Quantitative Data ##### + + " Current TVL (Total Value Locked) of the entire protocol " + totalValueLockedETH: BigInt! + totalValueLockedUSD: BigDecimal! + + " Revenue claimed by suppliers to the protocol. LPs on DEXs (e.g. 0.25% of the swap fee in Sushiswap). Depositors on Lending Protocols. NFT sellers on OpenSea. " + cumulativeSupplySideRevenueETH: BigInt! + cumulativeSupplySideRevenueUSD: BigDecimal! + + " Gross revenue for the protocol (revenue claimed by protocol). Examples: AMM protocol fee (Sushi’s 0.05%). OpenSea 10% sell fee. " + cumulativeProtocolSideRevenueETH: BigInt! + cumulativeProtocolSideRevenueUSD: BigDecimal! + + " All revenue generated by the protocol. e.g. 0.30% of swap fee in Sushiswap, all yield generated by Yearn. " + cumulativeTotalRevenueETH: BigInt! + cumulativeTotalRevenueUSD: BigDecimal! + + " Cumulative value of shares bought " + cumulativeBuyVolumeETH: BigInt! + cumulativeBuyVolumeUSD: BigDecimal! + + " Cumulative value of shares sold " + cumulativeSellVolumeETH: BigInt! + cumulativeSellVolumeUSD: BigDecimal! + + " Volume bought plus volume sold " + cumulativeTotalVolumeETH: BigInt! + cumulativeTotalVolumeUSD: BigDecimal! + + " Volume bought minus volume sold " + netVolumeETH: BigInt! + netVolumeUSD: BigDecimal! + + ##### Usage Data ##### + + " Number of cumulative unique addresses that bought shares " + cumulativeUniqueBuyers: Int! + + " Number of cumulative unique addresses that sold shares " + cumulativeUniqueSellers: Int! + + " Number of cumulative unique addresses that bought or sold shares " + cumulativeUniqueTraders: Int! + + " Number of cumulative unique addresses that registered and minted their shares on the protocol " + cumulativeUniqueSubjects: Int! + + " Number of cumulative unique addresses that interacted with the protocol " + cumulativeUniqueUsers: Int! + + " Total number of buy trades " + cumulativeBuyCount: Int! + + " Total number of sell trades " + cumulativeSellCount: Int! + + " Total number of trades " + cumulativeTradesCount: Int! + + ##### Snapshots ##### + + " Daily usage metrics for this protocol " + usageMetrics: [UsageMetricsDailySnapshot!]! @derivedFrom(field: "protocol") + + " Daily financial metrics for this protocol " + financialMetrics: [FinancialsDailySnapshot!]! @derivedFrom(field: "protocol") + + " Day ID of the most recent daily snapshot " + lastSnapshotDayID: Int! + + " Timestamp of the last time this entity was updated " + lastUpdateTimestamp: BigInt! +} + +############################### +##### Protocol Timeseries ##### +############################### + +type UsageMetricsDailySnapshot @entity @dailySnapshot { + " ID is # of days since Unix epoch time " + id: Bytes! + + " Number of days since Unix epoch time " + day: Int! + + " Protocol this snapshot is associated with " + protocol: Protocol! + + " Number of unique daily active buyers " + dailyActiveBuyers: Int! + + " Number of cumulative unique buyers " + cumulativeUniqueBuyers: Int! + + " Number of unique daily active sellers " + dailyActiveSellers: Int! + + " Number of cumulative unique sellers " + cumulativeUniqueSellers: Int! + + " Number of unique daily active traders " + dailyActiveTraders: Int! + + " Number of cumulative unique traders " + cumulativeUniqueTraders: Int! + + " Number of unique daily active subjects " + dailyActiveSubjects: Int! + + " Number of cumulative unique subjects " + cumulativeUniqueSubjects: Int! + + " Number of unique daily active users " + dailyActiveUsers: Int! + + " Number of cumulative unique users " + cumulativeUniqueUsers: Int! + + " Number of daily buy trades " + dailyBuyCount: Int! + + " Number of cumulative buy trades " + cumulativeBuyCount: Int! + + " Number of daily sell trades " + dailySellCount: Int! + + " Number of cumulative sell trades " + cumulativeSellCount: Int! + + " Number of daily trades " + dailyTradesCount: Int! + + " Number of cumulative trades " + cumulativeTradesCount: Int! + + " Timestamp of when this snapshot was taken/last modified (May be taken after interval has passed) " + timestamp: BigInt! + + " Block number of when this snapshot was taken/last modified (May be taken after interval has passed) " + blockNumber: BigInt! +} + +type FinancialsDailySnapshot @entity @dailySnapshot { + " ID is # of days since Unix epoch time " + id: Bytes! + + " Number of days since Unix epoch time " + day: Int! + + " Protocol this snapshot is associated with " + protocol: Protocol! + + " Current TVL (Total Value Locked) of the entire protocol " + totalValueLockedETH: BigInt! + totalValueLockedUSD: BigDecimal! + + " Daily revenue claimed by suppliers to the protocol. LPs on DEXs (e.g. 0.25% of the swap fee in Sushiswap). Depositors on Lending Protocols. NFT sellers on OpenSea. " + dailySupplySideRevenueETH: BigInt! + dailySupplySideRevenueUSD: BigDecimal! + + " Cumulative revenue claimed by suppliers to the protocol. LPs on DEXs (e.g. 0.25% of the swap fee in Sushiswap). Depositors on Lending Protocols. NFT sellers on OpenSea. " + cumulativeSupplySideRevenueETH: BigInt! + cumulativeSupplySideRevenueUSD: BigDecimal! + + " Daily gross revenue for the protocol (revenue claimed by protocol). Examples: AMM protocol fee (Sushi’s 0.05%). OpenSea 10% sell fee. " + dailyProtocolSideRevenueETH: BigInt! + dailyProtocolSideRevenueUSD: BigDecimal! + + " Cumulative gross revenue for the protocol (revenue claimed by protocol). Examples: AMM protocol fee (Sushi’s 0.05%). OpenSea 10% sell fee. " + cumulativeProtocolSideRevenueETH: BigInt! + cumulativeProtocolSideRevenueUSD: BigDecimal! + + " Daily revenue generated by the protocol. e.g. 0.30% of swap fee in Sushiswap, all yield generated by Yearn. " + dailyTotalRevenueETH: BigInt! + dailyTotalRevenueUSD: BigDecimal! + + " All revenue generated by the protocol. e.g. 0.30% of swap fee in Sushiswap, all yield generated by Yearn. " + cumulativeTotalRevenueETH: BigInt! + cumulativeTotalRevenueUSD: BigDecimal! + + " Daily value of shares bought " + dailyBuyVolumeETH: BigInt! + dailyBuyVolumeUSD: BigDecimal! + + " Cumulative value of shares bought " + cumulativeBuyVolumeETH: BigInt! + cumulativeBuyVolumeUSD: BigDecimal! + + " Daily value of shares sold " + dailySellVolumeETH: BigInt! + dailySellVolumeUSD: BigDecimal! + + " Cumulative value of shares sold " + cumulativeSellVolumeETH: BigInt! + cumulativeSellVolumeUSD: BigDecimal! + + " Daily volume bought minus daily volume sold " + dailyTotalVolumeETH: BigInt! + dailyTotalVolumeUSD: BigDecimal! + + " Volume bought plus volume sold " + cumulativeTotalVolumeETH: BigInt! + cumulativeTotalVolumeUSD: BigDecimal! + + " Daily volume bought minus daily volume sold " + dailyNetVolumeETH: BigInt! + dailyNetVolumeUSD: BigDecimal! + + " Volume bought minus volume sold " + netVolumeETH: BigInt! + netVolumeUSD: BigDecimal! + + " Timestamp of when this snapshot was taken/last modified (May be taken after interval has passed) " + timestamp: BigInt! + + " Block number of when this snapshot was taken/last modified (May be taken after interval has passed) " + blockNumber: BigInt! +} + +########################### +##### User-Level Data ##### +########################### + +type Trader @entity @regularPolling { + " Address of the trader " + id: Bytes! + + " Cumulative value of shares bought by the trader " + cumulativeBuyVolumeETH: BigInt! + cumulativeBuyVolumeUSD: BigDecimal! + + " Cumulative value of shares sold by the trader " + cumulativeSellVolumeETH: BigInt! + cumulativeSellVolumeUSD: BigDecimal! + + " Volume bought plus volume sold by the trader " + cumulativeTotalVolumeETH: BigInt! + cumulativeTotalVolumeUSD: BigDecimal! + + " Volume bought minus volume sold by the trader " + netVolumeETH: BigInt! + netVolumeUSD: BigDecimal! + + " Total number of buy trades by the trader " + cumulativeBuyCount: Int! + + " Total number of sell trades by the trader " + cumulativeSellCount: Int! + + " Total number of trades by the trader " + cumulativeTradesCount: Int! + + " Timestamp of when this trader first used the protocol " + registeredAt: BigInt! + + " Info about the connection between a trader and a subject " + connections: [Connection!]! +} + +type Subject @entity @regularPolling { + " Address of the subject " + id: Bytes! + + " All revenue generated by the subject " + cumulativeRevenueETH: BigInt! + cumulativeRevenueUSD: BigDecimal! + + " Cumulative value bought of subject shares " + cumulativeBuyVolumeETH: BigInt! + cumulativeBuyVolumeUSD: BigDecimal! + + " Cumulative value sold of subject shares " + cumulativeSellVolumeETH: BigInt! + cumulativeSellVolumeUSD: BigDecimal! + + " Volume bought plus volume sold of subject shares " + cumulativeTotalVolumeETH: BigInt! + cumulativeTotalVolumeUSD: BigDecimal! + + " Volume bought minus volume sold of subject shares " + netVolumeETH: BigInt! + netVolumeUSD: BigDecimal! + + " Total number of buy trades of subject shares " + cumulativeBuyCount: Int! + + " Total number of sell trades of subject shares " + cumulativeSellCount: Int! + + " Total number of trades of subject shares " + cumulativeTradesCount: Int! + + " Total supply of subject shares " + supply: BigInt! + + " Last price of subject shares " + sharePriceETH: BigInt! + sharePriceUSD: BigDecimal! + + " Timestamp of when this subject first used the protocol " + registeredAt: BigInt! + + " Info about the connection between a trader and a subject " + connections: [Connection!]! +} + +type Connection @entity @regularPolling { + " {Trader ID}-{Subject ID} " + id: Bytes! + + " Trader and Subject between which this connection exists " + trader: Trader! + subject: Subject! + + " Number of subject shares held by the trader " + shares: BigInt! + + " Cumulative value of subject shares bought by the trader " + cumulativeBuyVolumeETH: BigInt! + cumulativeBuyVolumeUSD: BigDecimal! + + " Cumulative value of subject shares sold by the trader " + cumulativeSellVolumeETH: BigInt! + cumulativeSellVolumeUSD: BigDecimal! + + " Volume bought plus volume sold of subject shares by the trader " + cumulativeTotalVolumeETH: BigInt! + cumulativeTotalVolumeUSD: BigDecimal! + + " Volume bought minus volume sold of subject shares by the trader " + netVolumeETH: BigInt! + netVolumeUSD: BigDecimal! + + " Total number of buy trades of subject shares by the trader " + cumulativeBuyCount: Int! + + " Total number of sell trades of subject shares by the trader " + cumulativeSellCount: Int! + + " Total number of trades of subject shares by the trader " + cumulativeTradesCount: Int! + + " Timestamp in which this connection is created or first time used " + createdTimestamp: BigInt! + + " Block number in which this connection is created or first time used " + createdBlockNumber: BigInt! +} + +############################### +####### User Timeseries ####### +############################### + +type TraderDailySnapshot @entity @dailySnapshot { + " {ID is # of days since Unix epoch time}-{Trader ID} " + id: Bytes! + + " Number of days since Unix epoch time " + day: Int! + + " Protocol this snapshot is associated with " + protocol: Protocol! + + " Trader this snapshot is associated with " + trader: Trader! + + " Daily value of shares bought by the trader " + dailyBuyVolumeETH: BigInt! + dailyBuyVolumeUSD: BigDecimal! + + " Cumulative value of shares bought by the trader " + cumulativeBuyVolumeETH: BigInt! + cumulativeBuyVolumeUSD: BigDecimal! + + " Daily value of shares sold by the trader " + dailySellVolumeETH: BigInt! + dailySellVolumeUSD: BigDecimal! + + " Cumulative value of shares sold by the trader " + cumulativeSellVolumeETH: BigInt! + cumulativeSellVolumeUSD: BigDecimal! + + " Daily volume bought plus daily volume sold by the trader " + dailyTotalVolumeETH: BigInt! + dailyTotalVolumeUSD: BigDecimal! + + " Volume bought plus volume sold by the trader " + cumulativeTotalVolumeETH: BigInt! + cumulativeTotalVolumeUSD: BigDecimal! + + " Daily volume bought minus daily volume sold by the trader " + dailyNetVolumeETH: BigInt! + dailyNetVolumeUSD: BigDecimal! + + " Volume bought minus volume sold by the trader " + netVolumeETH: BigInt! + netVolumeUSD: BigDecimal! + + " Number of daily buy trades by the trader " + dailyBuyCount: Int! + + " Number of cumulative buy trades by the trader " + cumulativeBuyCount: Int! + + " Number of daily sell trades by the trader " + dailySellCount: Int! + + " Number of cumulative sell trades by the trader " + cumulativeSellCount: Int! + + " Number of daily trades by the trader " + dailyTradesCount: Int! + + " Number of cumulative trades by the trader " + cumulativeTradesCount: Int! + + " Info about the connection between a trader and a subject " + connections: [ConnectionDailySnapshot!]! + + " Timestamp of when this snapshot was taken/last modified (May be taken after interval has passed) " + timestamp: BigInt! + + " Block number of when this snapshot was taken/last modified (May be taken after interval has passed) " + blockNumber: BigInt! +} + +type SubjectDailySnapshot @entity @dailySnapshot { + " {ID is # of days since Unix epoch time}-{Subject ID} " + id: Bytes! + + " Number of days since Unix epoch time " + day: Int! + + " Protocol this snapshot is associated with " + protocol: Protocol! + + " Subject this snapshot is associated with " + subject: Subject! + + " Daily revenue generated by the subject " + dailyRevenueETH: BigInt! + dailyRevenueUSD: BigDecimal! + + " All revenue generated by the subject " + cumulativeRevenueETH: BigInt! + cumulativeRevenueUSD: BigDecimal! + + " Daily value bought of subject shares " + dailyBuyVolumeETH: BigInt! + dailyBuyVolumeUSD: BigDecimal! + + " Cumulative value bought of subject shares " + cumulativeBuyVolumeETH: BigInt! + cumulativeBuyVolumeUSD: BigDecimal! + + " Daily value sold of subject shares " + dailySellVolumeETH: BigInt! + dailySellVolumeUSD: BigDecimal! + + " Cumulative value sold of subject shares " + cumulativeSellVolumeETH: BigInt! + cumulativeSellVolumeUSD: BigDecimal! + + " Daily volume bought plus daily volume sold of subject shares " + dailyTotalVolumeETH: BigInt! + dailyTotalVolumeUSD: BigDecimal! + + " Volume bought plus volume sold of subject shares " + cumulativeTotalVolumeETH: BigInt! + cumulativeTotalVolumeUSD: BigDecimal! + + " Daily volume bought minus daily volume sold of subject shares " + dailyNetVolumeETH: BigInt! + dailyNetVolumeUSD: BigDecimal! + + " Volume bought minus volume sold of subject shares " + netVolumeETH: BigInt! + netVolumeUSD: BigDecimal! + + " Daily number of buy trades of subject shares " + dailyBuyCount: Int! + + " Total number of buy trades of subject shares " + cumulativeBuyCount: Int! + + " Daily number of sell trades of subject shares " + dailySellCount: Int! + + " Total number of sell trades of subject shares " + cumulativeSellCount: Int! + + " Daily number of trades of subject shares " + dailyTradesCount: Int! + + " Total number of trades of subject shares " + cumulativeTradesCount: Int! + + " Total supply of subject shares " + supply: BigInt! + + " Last price of subject shares " + sharePriceETH: BigInt! + sharePriceUSD: BigDecimal! + + " Info about the connection between a trader and a subject " + connections: [ConnectionDailySnapshot!]! + + " Timestamp of when this trader first used the protocol " + timestamp: BigInt! + + " Info about the connection between a trader and a subject " + blockNumber: BigInt! +} + +type ConnectionDailySnapshot @entity @regularPolling { + " {Day ID}-{Trader ID}-{Subject ID} " + id: Bytes! + + " Number of days since Unix epoch time " + day: Int! + + " Protocol this snapshot is associated with " + protocol: Protocol! + + " Trader and Subject between which this connection exists " + trader: Trader! + subject: Subject! + + " Number of subject shares held by the trader " + shares: BigInt! + + " Daily value of subject shares bought by the trader " + dailyBuyVolumeETH: BigInt! + dailyBuyVolumeUSD: BigDecimal! + + " Cumulative value of subject shares bought by the trader " + cumulativeBuyVolumeETH: BigInt! + cumulativeBuyVolumeUSD: BigDecimal! + + " Daily value of subject shares sold by the trader " + dailySellVolumeETH: BigInt! + dailySellVolumeUSD: BigDecimal! + + " Cumulative value of subject shares sold by the trader " + cumulativeSellVolumeETH: BigInt! + cumulativeSellVolumeUSD: BigDecimal! + + " Daily volume bought plus daily volume sold of subject shares by the trader " + dailyTotalVolumeETH: BigInt! + dailyTotalVolumeUSD: BigDecimal! + + " Volume bought plus volume sold of subject shares by the trader " + cumulativeTotalVolumeETH: BigInt! + cumulativeTotalVolumeUSD: BigDecimal! + + " Daily volume bought minus daily volume sold of subject shares by the trader " + dailyNetVolumeETH: BigInt! + dailyNetVolumeUSD: BigDecimal! + + " Volume bought minus volume sold of subject shares by the trader " + netVolumeETH: BigInt! + netVolumeUSD: BigDecimal! + + " Daily number of buy trades of subject shares by the trader " + dailyBuyCount: Int! + + " Total number of buy trades of subject shares by the trader " + cumulativeBuyCount: Int! + + " Daily number of sell trades of subject shares by the trader " + dailySellCount: Int! + + " Total number of sell trades of subject shares by the trader " + cumulativeSellCount: Int! + + " Daily number of trades of subject shares by the trader " + dailyTradesCount: Int! + + " Total number of trades of subject shares by the trader " + cumulativeTradesCount: Int! + + " Timestamp in which this route is created or first time used " + createdTimestamp: BigInt! + + " Block number in which this route is created or first time used " + createdBlockNumber: BigInt! +} + +################################## +##### Transaction-Level Data ##### +################################## + +interface Event { + " event.transaction.hash.concatI32(event.logIndex) " + id: Bytes! + + " Transaction hash of the transaction that emitted this event " + hash: Bytes! + + " Event log index. For transactions that don't emit event, create arbitrary index starting from 0 " + logIndex: Int! + + " The protocol this transaction belongs to " + protocol: Protocol! + + " Address that received the tokens " + to: Bytes! + + " Address that sent the tokens " + from: Bytes! + + " Block number of this event " + blockNumber: BigInt! + + " Timestamp of this event " + timestamp: BigInt! +} + +type Trade implements Event @entity(immutable: true) @transaction { + " event.transaction.hash.concatI32(event.logIndex) " + id: Bytes! + + " Transaction hash of the transaction that emitted this event " + hash: Bytes! + + " Event log index. For transactions that don't emit event, create arbitrary index starting from 0 " + logIndex: Int! + + " The protocol this transaction belongs to " + protocol: Protocol! + + " Address that received the tokens " + to: Bytes! + + " Address that sent the tokens " + from: Bytes! + + " Trader address" + trader: Trader! + + " Subject address" + subject: Subject! + + " trade type - BUY / SELL " + type: TradeType! + + " Number of shares " + shares: BigInt! + + " price of shares " + sharePriceETH: BigInt! + sharePriceUSD: BigDecimal! + + " protocol fee " + protocolFeeETH: BigInt! + protocolFeeUSD: BigDecimal! + + " subject fee " + subjectFeeETH: BigInt! + subjectFeeUSD: BigDecimal! + + " total trade amount (sharePrice + protocolFee + subjectFee) " + amountETH: BigInt! + amountUSD: BigDecimal! + + " Block number of this event " + blockNumber: BigInt! + + " Timestamp of this event " + timestamp: BigInt! +} + +################################## +############# Helpers ############ +################################## + +# Helps to accumulate total unique users +type _Account @entity @regularPolling { + " Address of the Account " + id: Bytes! +} + +# Helper entity for calculating daily active users +type _ActiveAccount @entity @regularPolling { + " { Address of the Account }-{ Days since Unix epoch } " + id: Bytes! +} + +# Helper entity for calculating daily active traders +type _ActiveTrader @entity @regularPolling { + " { Address of the Trader }-{ Days since Unix epoch } " + id: Bytes! +} + +# Helper entity for calculating daily active subjects +type _ActiveSubject @entity @regularPolling { + " { Address of the Subject }-{ Days since Unix epoch } " + id: Bytes! +} + +# Helps to accumulate total unique buyers / sellers +type _TraderOfType @entity @regularPolling { + " { Trade Type }-{ Address of the Trader } " + id: Bytes! +} + +# Helper entity for calculating daily active buyers / sellers +type _ActiveTraderOfType @entity @regularPolling { + " { Trade Type }-{ Address of the Trader }-{ Days since Unix epoch } " + id: Bytes! +} diff --git a/subgraphs/friend-tech/src/common/constants.ts b/subgraphs/friend-tech/src/common/constants.ts new file mode 100644 index 0000000000..e883973b6b --- /dev/null +++ b/subgraphs/friend-tech/src/common/constants.ts @@ -0,0 +1,102 @@ +import { BigDecimal, BigInt } from "@graphprotocol/graph-ts"; + +//////////////////// +///// Versions ///// +//////////////////// + +export const PROTOCOL_NAME = "Friend Tech"; +export const PROTOCOL_SLUG = "friend-tech"; + +//////////////////////// +///// Schema Enums ///// +//////////////////////// + +// The network names corresponding to the Network enum in the schema. +// They also correspond to the ones in `dataSource.network()` after converting to lower case. +// See below for a complete list: +// https://thegraph.com/docs/en/hosted-service/what-is-hosted-service/#supported-networks-on-the-hosted-service +export namespace Network { + export const ARBITRUM_ONE = "ARBITRUM_ONE"; + export const ARWEAVE_MAINNET = "ARWEAVE_MAINNET"; + export const AURORA = "AURORA"; + export const AVALANCHE = "AVALANCHE"; + export const BASE = "BASE"; + export const BOBA = "BOBA"; + export const BSC = "BSC"; // aka BNB Chain + export const CELO = "CELO"; + export const COSMOS = "COSMOS"; + export const CRONOS = "CRONOS"; + export const MAINNET = "MAINNET"; // Ethereum mainnet + export const FANTOM = "FANTOM"; + export const FUSE = "FUSE"; + export const HARMONY = "HARMONY"; + export const JUNO = "JUNO"; + export const MOONBEAM = "MOONBEAM"; + export const MOONRIVER = "MOONRIVER"; + export const NEAR_MAINNET = "NEAR_MAINNET"; + export const OPTIMISM = "OPTIMISM"; + export const OSMOSIS = "OSMOSIS"; + export const MATIC = "MATIC"; // aka Polygon + export const XDAI = "XDAI"; // aka Gnosis Chain +} + +export namespace ProtocolType { + export const EXCHANGE = "EXCHANGE"; + export const LENDING = "LENDING"; + export const YIELD = "YIELD"; + export const BRIDGE = "BRIDGE"; + export const GENERIC = "GENERIC"; + export const SOCIAL = "SOCIAL"; +} + +export namespace TradeType { + export const BUY = "BUY"; + export const SELL = "SELL"; +} + +//////////////////// +///// Ethereum ///// +//////////////////// + +export const ETH_NAME = "Ether"; +export const ETH_SYMBOL = "ETH"; +export const ETH_DECIMALS = 18; +export const ETH_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; + +//////////////////////// +///// Type Helpers ///// +//////////////////////// + +export const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; + +export const BIGINT_ZERO = BigInt.fromI32(0); +export const BIGINT_ONE = BigInt.fromI32(1); +export const BIGINT_TWO = BigInt.fromI32(2); +export const BIGINT_TEN = BigInt.fromI32(10); +export const BIGINT_HUNDRED = BigInt.fromI32(100); +export const BIGINT_THOUSAND = BigInt.fromI32(1000); +export const BIGINT_TEN_TO_EIGHTEENTH = BigInt.fromString("10").pow(18); +export const BIGINT_MAX = BigInt.fromString( + "115792089237316195423570985008687907853269984665640564039457584007913129639935" +); + +export const INT_NEGATIVE_ONE = -1 as i32; +export const INT_ZERO = 0 as i32; +export const INT_ONE = 1 as i32; +export const INT_TWO = 2 as i32; +export const INT_FOUR = 4 as i32; + +export const BIGDECIMAL_ZERO = new BigDecimal(BIGINT_ZERO); +export const BIGDECIMAL_ONE = new BigDecimal(BIGINT_ONE); +export const BIGDECIMAL_TWO = new BigDecimal(BIGINT_TWO); + +export const MAX_UINT = BigInt.fromI32(2).times(BigInt.fromI32(255)); + +export const SECONDS_PER_DAY = 60 * 60 * 24; + +//////////////////////// +/// Protocol Specific // +//////////////////////// + +export const CHAINLINK_AGGREGATOR_ETH_USD = + "0x57d2d46Fc7ff2A7142d479F2f59e1E3F95447077"; diff --git a/subgraphs/friend-tech/src/common/events.ts b/subgraphs/friend-tech/src/common/events.ts new file mode 100644 index 0000000000..401c48f08b --- /dev/null +++ b/subgraphs/friend-tech/src/common/events.ts @@ -0,0 +1,70 @@ +import { Address, Bytes, BigInt, ethereum } from "@graphprotocol/graph-ts"; + +import { getOrCreateEthToken } from "./getters"; +import { BIGINT_TEN, ETH_DECIMALS, TradeType, ZERO_ADDRESS } from "./constants"; +import { NetworkConfigs } from "../../configurations/configure"; + +import { Trade } from "../../generated/schema"; + +export function createEvent( + traderAddress: Address, + subjectAddress: Address, + shares: BigInt, + sharePriceETH: BigInt, + subjectFeeETH: BigInt, + protocolFeeETH: BigInt, + tradeAmountETH: BigInt, + isBuy: boolean, + event: ethereum.Event +): void { + const id = Bytes.empty() + .concat(event.transaction.hash) + .concatI32(event.logIndex.toI32()); + + const tradeEvent = new Trade(id); + tradeEvent.hash = event.transaction.hash; + tradeEvent.logIndex = event.logIndex.toI32(); + tradeEvent.protocol = NetworkConfigs.getFactoryAddress(); + tradeEvent.to = event.transaction.to + ? event.transaction.to! + : Address.fromString(ZERO_ADDRESS); + tradeEvent.from = event.transaction.from; + + tradeEvent.trader = traderAddress; + tradeEvent.subject = subjectAddress; + tradeEvent.type = isBuy ? TradeType.BUY : TradeType.SELL; + tradeEvent.shares = shares; + + const eth = getOrCreateEthToken(event); + const sharePriceUSD = sharePriceETH + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); + const protocolFeeUSD = protocolFeeETH + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); + const subjectFeeUSD = subjectFeeETH + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); + const tradeAmountUSD = tradeAmountETH + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); + + tradeEvent.sharePriceETH = sharePriceETH; + tradeEvent.sharePriceUSD = sharePriceUSD; + tradeEvent.protocolFeeETH = protocolFeeETH; + tradeEvent.protocolFeeUSD = protocolFeeUSD; + tradeEvent.subjectFeeETH = subjectFeeETH; + tradeEvent.subjectFeeUSD = subjectFeeUSD; + tradeEvent.amountETH = tradeAmountETH; + tradeEvent.amountUSD = tradeAmountUSD; + + tradeEvent.blockNumber = event.block.number; + tradeEvent.timestamp = event.block.timestamp; + + tradeEvent.save(); + return; +} diff --git a/subgraphs/friend-tech/src/common/getters.ts b/subgraphs/friend-tech/src/common/getters.ts new file mode 100644 index 0000000000..f23a47e0e8 --- /dev/null +++ b/subgraphs/friend-tech/src/common/getters.ts @@ -0,0 +1,593 @@ +import { Address, Bytes, ethereum } from "@graphprotocol/graph-ts"; + +import { + BIGDECIMAL_ZERO, + BIGINT_ZERO, + ETH_ADDRESS, + ETH_DECIMALS, + ETH_NAME, + ETH_SYMBOL, + INT_ZERO, + PROTOCOL_NAME, + PROTOCOL_SLUG, + ProtocolType, + TradeType, +} from "./constants"; +import { getEthPriceUSD } from "./prices"; +import { Versions } from "../versions"; +import { NetworkConfigs } from "../../configurations/configure"; +import { SubjectResponse, TraderResponse } from "./types"; +import { getDaysSinceEpoch } from "./utils"; + +import { + _Account, + _ActiveAccount, + _ActiveSubject, + _ActiveTrader, + _ActiveTraderOfType, + _TraderOfType, + Connection, + ConnectionDailySnapshot, + FinancialsDailySnapshot, + Protocol, + Subject, + SubjectDailySnapshot, + Token, + Trader, + TraderDailySnapshot, + UsageMetricsDailySnapshot, +} from "../../generated/schema"; + +export function getOrCreateProtocol(): Protocol { + let protocol = Protocol.load(NetworkConfigs.getFactoryAddress()); + + if (!protocol) { + protocol = new Protocol(NetworkConfigs.getFactoryAddress()); + protocol.name = PROTOCOL_NAME; + protocol.slug = PROTOCOL_SLUG; + protocol.network = NetworkConfigs.getNetwork(); + protocol.type = ProtocolType.SOCIAL; + + protocol.totalValueLockedETH = BIGINT_ZERO; + protocol.totalValueLockedUSD = BIGDECIMAL_ZERO; + protocol.cumulativeSupplySideRevenueETH = BIGINT_ZERO; + protocol.cumulativeSupplySideRevenueUSD = BIGDECIMAL_ZERO; + protocol.cumulativeProtocolSideRevenueETH = BIGINT_ZERO; + protocol.cumulativeProtocolSideRevenueUSD = BIGDECIMAL_ZERO; + protocol.cumulativeTotalRevenueETH = BIGINT_ZERO; + protocol.cumulativeTotalRevenueUSD = BIGDECIMAL_ZERO; + + protocol.cumulativeBuyVolumeETH = BIGINT_ZERO; + protocol.cumulativeBuyVolumeUSD = BIGDECIMAL_ZERO; + protocol.cumulativeSellVolumeETH = BIGINT_ZERO; + protocol.cumulativeSellVolumeUSD = BIGDECIMAL_ZERO; + protocol.cumulativeTotalVolumeETH = BIGINT_ZERO; + protocol.cumulativeTotalVolumeUSD = BIGDECIMAL_ZERO; + protocol.netVolumeETH = BIGINT_ZERO; + protocol.netVolumeUSD = BIGDECIMAL_ZERO; + + protocol.cumulativeUniqueBuyers = INT_ZERO; + protocol.cumulativeUniqueSellers = INT_ZERO; + protocol.cumulativeUniqueTraders = INT_ZERO; + protocol.cumulativeUniqueSubjects = INT_ZERO; + protocol.cumulativeUniqueUsers = INT_ZERO; + + protocol.cumulativeBuyCount = INT_ZERO; + protocol.cumulativeSellCount = INT_ZERO; + protocol.cumulativeTradesCount = INT_ZERO; + + protocol.lastSnapshotDayID = INT_ZERO; + protocol.lastUpdateTimestamp = BIGINT_ZERO; + } + + protocol.schemaVersion = Versions.getSchemaVersion(); + protocol.subgraphVersion = Versions.getSubgraphVersion(); + protocol.methodologyVersion = Versions.getMethodologyVersion(); + + protocol.save(); + return protocol; +} + +export function getOrCreateEthToken(event: ethereum.Event): Token { + const ethAddress = Address.fromString(ETH_ADDRESS); + let token = Token.load(ethAddress); + + if (!token) { + token = new Token(ethAddress); + + token.name = ETH_NAME; + token.symbol = ETH_SYMBOL; + token.decimals = ETH_DECIMALS as i32; + token.lastPriceBlockNumber = event.block.number; + } + + if (!token.lastPriceUSD || token.lastPriceBlockNumber! < event.block.number) { + const priceUSD = getEthPriceUSD(); + + token.lastPriceUSD = priceUSD; + token.lastPriceBlockNumber = event.block.number; + } + token.save(); + return token; +} + +export function getOrCreateTrader( + traderAddress: Address, + event: ethereum.Event +): TraderResponse { + let isNewTrader = false; + let trader = Trader.load(traderAddress); + + if (!trader) { + isNewTrader = true; + trader = new Trader(traderAddress); + + trader.cumulativeBuyVolumeETH = BIGINT_ZERO; + trader.cumulativeBuyVolumeUSD = BIGDECIMAL_ZERO; + trader.cumulativeSellVolumeETH = BIGINT_ZERO; + trader.cumulativeSellVolumeUSD = BIGDECIMAL_ZERO; + trader.cumulativeTotalVolumeETH = BIGINT_ZERO; + trader.cumulativeTotalVolumeUSD = BIGDECIMAL_ZERO; + trader.netVolumeETH = BIGINT_ZERO; + trader.netVolumeUSD = BIGDECIMAL_ZERO; + + trader.cumulativeBuyCount = INT_ZERO; + trader.cumulativeSellCount = INT_ZERO; + trader.cumulativeTradesCount = INT_ZERO; + + trader.registeredAt = event.block.number; + + trader.connections = []; + + trader.save(); + } + return { trader, isNewTrader }; +} + +export function getOrCreateActiveTrader( + traderAddress: Address, + day: i32 +): boolean { + const id = Bytes.empty() + .concat(traderAddress) + .concat(Bytes.fromUTF8("-")) + .concat(Bytes.fromI32(day)); + + let trader = _ActiveTrader.load(id); + if (!trader) { + trader = new _ActiveTrader(id); + trader.save(); + return true; + } + return false; +} + +export function getOrCreateSubject( + subjectAddress: Address, + event: ethereum.Event +): SubjectResponse { + let isNewSubject = false; + let subject = Subject.load(subjectAddress); + + if (!subject) { + isNewSubject = true; + subject = new Subject(subjectAddress); + + subject.cumulativeRevenueETH = BIGINT_ZERO; + subject.cumulativeRevenueUSD = BIGDECIMAL_ZERO; + subject.cumulativeBuyVolumeETH = BIGINT_ZERO; + subject.cumulativeBuyVolumeUSD = BIGDECIMAL_ZERO; + subject.cumulativeSellVolumeETH = BIGINT_ZERO; + subject.cumulativeSellVolumeUSD = BIGDECIMAL_ZERO; + subject.cumulativeTotalVolumeETH = BIGINT_ZERO; + subject.cumulativeTotalVolumeUSD = BIGDECIMAL_ZERO; + subject.netVolumeETH = BIGINT_ZERO; + subject.netVolumeUSD = BIGDECIMAL_ZERO; + + subject.cumulativeBuyCount = INT_ZERO; + subject.cumulativeSellCount = INT_ZERO; + subject.cumulativeTradesCount = INT_ZERO; + + subject.registeredAt = event.block.number; + + subject.supply = BIGINT_ZERO; + subject.sharePriceETH = BIGINT_ZERO; + subject.sharePriceUSD = BIGDECIMAL_ZERO; + + subject.connections = []; + + subject.save(); + } + return { subject, isNewSubject }; +} + +export function getOrCreateActiveSubject( + subjectAddress: Address, + day: i32 +): boolean { + const id = Bytes.empty() + .concat(subjectAddress) + .concat(Bytes.fromUTF8("-")) + .concat(Bytes.fromI32(day)); + + let subject = _ActiveSubject.load(id); + if (!subject) { + subject = new _ActiveSubject(id); + subject.save(); + return true; + } + return false; +} + +export function getOrCreateConnection( + traderAddress: Address, + subjectAddress: Address, + event: ethereum.Event +): Connection { + const id = Bytes.empty() + .concat(traderAddress) + .concat(Bytes.fromUTF8("-")) + .concat(subjectAddress); + + let connection = Connection.load(id); + + if (!connection) { + connection = new Connection(id); + + connection.trader = traderAddress; + connection.subject = subjectAddress; + connection.shares = BIGINT_ZERO; + + connection.cumulativeBuyVolumeETH = BIGINT_ZERO; + connection.cumulativeBuyVolumeUSD = BIGDECIMAL_ZERO; + connection.cumulativeSellVolumeETH = BIGINT_ZERO; + connection.cumulativeSellVolumeUSD = BIGDECIMAL_ZERO; + connection.cumulativeTotalVolumeETH = BIGINT_ZERO; + connection.cumulativeTotalVolumeUSD = BIGDECIMAL_ZERO; + connection.netVolumeETH = BIGINT_ZERO; + connection.netVolumeUSD = BIGDECIMAL_ZERO; + + connection.cumulativeBuyCount = INT_ZERO; + connection.cumulativeSellCount = INT_ZERO; + connection.cumulativeTradesCount = INT_ZERO; + + connection.createdTimestamp = event.block.timestamp; + connection.createdBlockNumber = event.block.number; + + connection.save(); + } + return connection; +} + +export function getOrCreateAccount(accountAddress: Address): boolean { + let account = _Account.load(accountAddress); + if (!account) { + account = new _Account(accountAddress); + account.save(); + return true; + } + return false; +} + +export function getOrCreateActiveAccount( + accountAddress: Address, + day: i32 +): boolean { + const id = Bytes.empty() + .concat(accountAddress) + .concat(Bytes.fromUTF8("-")) + .concat(Bytes.fromI32(day)); + + let account = _ActiveAccount.load(id); + if (!account) { + account = new _ActiveAccount(id); + account.save(); + return true; + } + return false; +} + +export function getOrCreateTraderOfType( + traderAddress: Address, + isBuy: boolean +): boolean { + const tradeType = isBuy ? TradeType.BUY : TradeType.SELL; + const id = Bytes.empty() + .concat(Bytes.fromUTF8(tradeType)) + .concat(Bytes.fromUTF8("-")) + .concat(traderAddress); + + let trader = _TraderOfType.load(id); + if (!trader) { + trader = new _TraderOfType(id); + trader.save(); + return true; + } + return false; +} + +export function getOrCreateActiveTraderOfType( + traderAddress: Address, + isBuy: boolean, + day: i32 +): boolean { + const tradeType = isBuy ? TradeType.BUY : TradeType.SELL; + const id = Bytes.empty() + .concat(Bytes.fromUTF8(tradeType)) + .concat(Bytes.fromUTF8("-")) + .concat(traderAddress) + .concat(Bytes.fromUTF8("-")) + .concat(Bytes.fromI32(day)); + + let trader = _ActiveTraderOfType.load(id); + if (!trader) { + trader = new _ActiveTraderOfType(id); + trader.save(); + return true; + } + return false; +} + +export function getOrCreateUsageMetricsDailySnapshot( + event: ethereum.Event +): UsageMetricsDailySnapshot { + const day = getDaysSinceEpoch(event.block.timestamp.toI32()); + + let snapshot = UsageMetricsDailySnapshot.load(Bytes.fromI32(day)); + + if (!snapshot) { + snapshot = new UsageMetricsDailySnapshot(Bytes.fromI32(day)); + + snapshot.day = day; + snapshot.protocol = NetworkConfigs.getFactoryAddress(); + + snapshot.dailyActiveBuyers = INT_ZERO; + snapshot.cumulativeUniqueBuyers = INT_ZERO; + snapshot.dailyActiveSellers = INT_ZERO; + snapshot.cumulativeUniqueSellers = INT_ZERO; + snapshot.dailyActiveTraders = INT_ZERO; + snapshot.cumulativeUniqueTraders = INT_ZERO; + snapshot.dailyActiveSubjects = INT_ZERO; + snapshot.cumulativeUniqueSubjects = INT_ZERO; + snapshot.dailyActiveUsers = INT_ZERO; + snapshot.cumulativeUniqueUsers = INT_ZERO; + + snapshot.dailyBuyCount = INT_ZERO; + snapshot.cumulativeBuyCount = INT_ZERO; + snapshot.dailySellCount = INT_ZERO; + snapshot.cumulativeSellCount = INT_ZERO; + snapshot.dailyTradesCount = INT_ZERO; + snapshot.cumulativeTradesCount = INT_ZERO; + + snapshot.timestamp = event.block.timestamp; + snapshot.blockNumber = event.block.number; + + snapshot.save(); + } + return snapshot; +} + +export function getOrCreateFinancialsDailySnapshot( + event: ethereum.Event +): FinancialsDailySnapshot { + const day = getDaysSinceEpoch(event.block.timestamp.toI32()); + + let snapshot = FinancialsDailySnapshot.load(Bytes.fromI32(day)); + + if (!snapshot) { + snapshot = new FinancialsDailySnapshot(Bytes.fromI32(day)); + + snapshot.day = day; + snapshot.protocol = NetworkConfigs.getFactoryAddress(); + + snapshot.totalValueLockedETH = BIGINT_ZERO; + snapshot.totalValueLockedUSD = BIGDECIMAL_ZERO; + + snapshot.dailySupplySideRevenueETH = BIGINT_ZERO; + snapshot.cumulativeSupplySideRevenueETH = BIGINT_ZERO; + snapshot.dailySupplySideRevenueUSD = BIGDECIMAL_ZERO; + snapshot.cumulativeSupplySideRevenueUSD = BIGDECIMAL_ZERO; + snapshot.dailyProtocolSideRevenueETH = BIGINT_ZERO; + snapshot.cumulativeProtocolSideRevenueETH = BIGINT_ZERO; + snapshot.dailyProtocolSideRevenueUSD = BIGDECIMAL_ZERO; + snapshot.cumulativeProtocolSideRevenueUSD = BIGDECIMAL_ZERO; + snapshot.dailyTotalRevenueETH = BIGINT_ZERO; + snapshot.cumulativeTotalRevenueETH = BIGINT_ZERO; + snapshot.dailyTotalRevenueUSD = BIGDECIMAL_ZERO; + snapshot.cumulativeTotalRevenueUSD = BIGDECIMAL_ZERO; + + snapshot.dailyBuyVolumeETH = BIGINT_ZERO; + snapshot.cumulativeBuyVolumeETH = BIGINT_ZERO; + snapshot.dailyBuyVolumeUSD = BIGDECIMAL_ZERO; + snapshot.cumulativeBuyVolumeUSD = BIGDECIMAL_ZERO; + snapshot.dailySellVolumeETH = BIGINT_ZERO; + snapshot.cumulativeSellVolumeETH = BIGINT_ZERO; + snapshot.dailySellVolumeUSD = BIGDECIMAL_ZERO; + snapshot.cumulativeSellVolumeUSD = BIGDECIMAL_ZERO; + snapshot.dailyTotalVolumeETH = BIGINT_ZERO; + snapshot.cumulativeTotalVolumeETH = BIGINT_ZERO; + snapshot.dailyTotalVolumeUSD = BIGDECIMAL_ZERO; + snapshot.cumulativeTotalVolumeUSD = BIGDECIMAL_ZERO; + snapshot.dailyNetVolumeETH = BIGINT_ZERO; + snapshot.netVolumeETH = BIGINT_ZERO; + snapshot.dailyNetVolumeUSD = BIGDECIMAL_ZERO; + snapshot.netVolumeUSD = BIGDECIMAL_ZERO; + + snapshot.timestamp = event.block.timestamp; + snapshot.blockNumber = event.block.number; + + snapshot.save(); + } + return snapshot; +} + +export function getOrCreateTraderDailySnapshot( + traderAddress: Address, + event: ethereum.Event +): TraderDailySnapshot { + const day = getDaysSinceEpoch(event.block.timestamp.toI32()); + const id = Bytes.empty() + .concat(Bytes.fromI32(day)) + .concat(Bytes.fromUTF8("-")) + .concat(traderAddress); + + let snapshot = TraderDailySnapshot.load(id); + + if (!snapshot) { + snapshot = new TraderDailySnapshot(id); + + snapshot.day = day; + snapshot.protocol = NetworkConfigs.getFactoryAddress(); + snapshot.trader = traderAddress; + + snapshot.dailyBuyVolumeETH = BIGINT_ZERO; + snapshot.cumulativeBuyVolumeETH = BIGINT_ZERO; + snapshot.dailyBuyVolumeUSD = BIGDECIMAL_ZERO; + snapshot.cumulativeBuyVolumeUSD = BIGDECIMAL_ZERO; + snapshot.dailySellVolumeETH = BIGINT_ZERO; + snapshot.cumulativeSellVolumeETH = BIGINT_ZERO; + snapshot.dailySellVolumeUSD = BIGDECIMAL_ZERO; + snapshot.cumulativeSellVolumeUSD = BIGDECIMAL_ZERO; + snapshot.dailyTotalVolumeETH = BIGINT_ZERO; + snapshot.cumulativeTotalVolumeETH = BIGINT_ZERO; + snapshot.dailyTotalVolumeUSD = BIGDECIMAL_ZERO; + snapshot.cumulativeTotalVolumeUSD = BIGDECIMAL_ZERO; + snapshot.dailyNetVolumeETH = BIGINT_ZERO; + snapshot.netVolumeETH = BIGINT_ZERO; + snapshot.dailyNetVolumeUSD = BIGDECIMAL_ZERO; + snapshot.netVolumeUSD = BIGDECIMAL_ZERO; + + snapshot.dailyBuyCount = INT_ZERO; + snapshot.cumulativeBuyCount = INT_ZERO; + snapshot.dailySellCount = INT_ZERO; + snapshot.cumulativeSellCount = INT_ZERO; + snapshot.dailyTradesCount = INT_ZERO; + snapshot.cumulativeTradesCount = INT_ZERO; + + snapshot.connections = []; + + snapshot.timestamp = event.block.timestamp; + snapshot.blockNumber = event.block.number; + + snapshot.save(); + } + return snapshot; +} + +export function getOrCreateSubjectDailySnapshot( + subjectAddress: Address, + event: ethereum.Event +): SubjectDailySnapshot { + const day = getDaysSinceEpoch(event.block.timestamp.toI32()); + const id = Bytes.empty() + .concat(Bytes.fromI32(day)) + .concat(Bytes.fromUTF8("-")) + .concat(subjectAddress); + + let snapshot = SubjectDailySnapshot.load(id); + + if (!snapshot) { + snapshot = new SubjectDailySnapshot(id); + + snapshot.day = day; + snapshot.protocol = NetworkConfigs.getFactoryAddress(); + snapshot.subject = subjectAddress; + + snapshot.dailyRevenueETH = BIGINT_ZERO; + snapshot.cumulativeRevenueETH = BIGINT_ZERO; + snapshot.dailyRevenueUSD = BIGDECIMAL_ZERO; + snapshot.cumulativeRevenueUSD = BIGDECIMAL_ZERO; + + snapshot.dailyBuyVolumeETH = BIGINT_ZERO; + snapshot.cumulativeBuyVolumeETH = BIGINT_ZERO; + snapshot.dailyBuyVolumeUSD = BIGDECIMAL_ZERO; + snapshot.cumulativeBuyVolumeUSD = BIGDECIMAL_ZERO; + snapshot.dailySellVolumeETH = BIGINT_ZERO; + snapshot.cumulativeSellVolumeETH = BIGINT_ZERO; + snapshot.dailySellVolumeUSD = BIGDECIMAL_ZERO; + snapshot.cumulativeSellVolumeUSD = BIGDECIMAL_ZERO; + snapshot.dailyTotalVolumeETH = BIGINT_ZERO; + snapshot.cumulativeTotalVolumeETH = BIGINT_ZERO; + snapshot.dailyTotalVolumeUSD = BIGDECIMAL_ZERO; + snapshot.cumulativeTotalVolumeUSD = BIGDECIMAL_ZERO; + snapshot.dailyNetVolumeETH = BIGINT_ZERO; + snapshot.netVolumeETH = BIGINT_ZERO; + snapshot.dailyNetVolumeUSD = BIGDECIMAL_ZERO; + snapshot.netVolumeUSD = BIGDECIMAL_ZERO; + + snapshot.dailyBuyCount = INT_ZERO; + snapshot.cumulativeBuyCount = INT_ZERO; + snapshot.dailySellCount = INT_ZERO; + snapshot.cumulativeSellCount = INT_ZERO; + snapshot.dailyTradesCount = INT_ZERO; + snapshot.cumulativeTradesCount = INT_ZERO; + + snapshot.supply = BIGINT_ZERO; + snapshot.sharePriceETH = BIGINT_ZERO; + snapshot.sharePriceUSD = BIGDECIMAL_ZERO; + + snapshot.connections = []; + + snapshot.timestamp = event.block.timestamp; + snapshot.blockNumber = event.block.number; + + snapshot.save(); + } + return snapshot; +} + +export function getOrCreateConnectionDailySnapshot( + traderAddress: Address, + subjectAddress: Address, + event: ethereum.Event +): ConnectionDailySnapshot { + const day = getDaysSinceEpoch(event.block.timestamp.toI32()); + const id = Bytes.empty() + .concat(Bytes.fromI32(day)) + .concat(Bytes.fromUTF8("-")) + .concat(traderAddress) + .concat(Bytes.fromUTF8("-")) + .concat(subjectAddress); + + let snapshot = ConnectionDailySnapshot.load(id); + + if (!snapshot) { + snapshot = new ConnectionDailySnapshot(id); + + snapshot.day = day; + snapshot.protocol = NetworkConfigs.getFactoryAddress(); + snapshot.trader = traderAddress; + snapshot.subject = subjectAddress; + snapshot.shares = BIGINT_ZERO; + + snapshot.dailyBuyVolumeETH = BIGINT_ZERO; + snapshot.cumulativeBuyVolumeETH = BIGINT_ZERO; + snapshot.dailyBuyVolumeUSD = BIGDECIMAL_ZERO; + snapshot.cumulativeBuyVolumeUSD = BIGDECIMAL_ZERO; + snapshot.dailySellVolumeETH = BIGINT_ZERO; + snapshot.cumulativeSellVolumeETH = BIGINT_ZERO; + snapshot.dailySellVolumeUSD = BIGDECIMAL_ZERO; + snapshot.cumulativeSellVolumeUSD = BIGDECIMAL_ZERO; + snapshot.dailyTotalVolumeETH = BIGINT_ZERO; + snapshot.cumulativeTotalVolumeETH = BIGINT_ZERO; + snapshot.dailyTotalVolumeUSD = BIGDECIMAL_ZERO; + snapshot.cumulativeTotalVolumeUSD = BIGDECIMAL_ZERO; + snapshot.dailyNetVolumeETH = BIGINT_ZERO; + snapshot.netVolumeETH = BIGINT_ZERO; + snapshot.dailyNetVolumeUSD = BIGDECIMAL_ZERO; + snapshot.netVolumeUSD = BIGDECIMAL_ZERO; + + snapshot.dailyBuyCount = INT_ZERO; + snapshot.cumulativeBuyCount = INT_ZERO; + snapshot.dailySellCount = INT_ZERO; + snapshot.cumulativeSellCount = INT_ZERO; + snapshot.dailyTradesCount = INT_ZERO; + snapshot.cumulativeTradesCount = INT_ZERO; + + snapshot.createdTimestamp = event.block.timestamp; + snapshot.createdBlockNumber = event.block.number; + + snapshot.save(); + } + return snapshot; +} diff --git a/subgraphs/friend-tech/src/common/metrics.ts b/subgraphs/friend-tech/src/common/metrics.ts new file mode 100644 index 0000000000..5bc7cea3d1 --- /dev/null +++ b/subgraphs/friend-tech/src/common/metrics.ts @@ -0,0 +1,307 @@ +import { ethereum, BigInt, Address } from "@graphprotocol/graph-ts"; + +import { + getOrCreateProtocol, + getOrCreateEthToken, + getOrCreateAccount, + getOrCreateTrader, + getOrCreateSubject, + getOrCreateTraderOfType, + getOrCreateConnection, +} from "./getters"; +import { BIGINT_TEN, ETH_DECIMALS, INT_ONE } from "./constants"; +import { addToArrayAtIndex } from "./utils"; + +export function updateTVL( + amountETH: BigInt, + isBuy: boolean, + event: ethereum.Event +): void { + const protocol = getOrCreateProtocol(); + const eth = getOrCreateEthToken(event); + + const amountUSD = amountETH + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); + + if (isBuy) { + protocol.totalValueLockedETH = protocol.totalValueLockedETH.plus(amountETH); + protocol.totalValueLockedUSD = protocol.totalValueLockedUSD.plus(amountUSD); + } else { + protocol.totalValueLockedETH = + protocol.totalValueLockedETH.minus(amountETH); + protocol.totalValueLockedUSD = + protocol.totalValueLockedUSD.minus(amountUSD); + } + + protocol.save(); +} + +export function updateUsage( + traderAddress: Address, + subjectAddress: Address, + isBuy: boolean, + event: ethereum.Event +): void { + const traderResponse = getOrCreateTrader(traderAddress, event); + const subjectResponse = getOrCreateSubject(subjectAddress, event); + + const protocol = getOrCreateProtocol(); + const trader = traderResponse.trader; + const subject = subjectResponse.subject; + + const isNewTrader = traderResponse.isNewTrader; + const isNewAccountForTrader = getOrCreateAccount(traderAddress); + const isNewTraderOfType = getOrCreateTraderOfType(traderAddress, isBuy); + + const isNewSubject = subjectResponse.isNewSubject; + const isNewAccountForSubject = getOrCreateAccount(subjectAddress); + + if (isNewTrader) protocol.cumulativeUniqueTraders += INT_ONE; + if (isNewAccountForTrader) protocol.cumulativeUniqueUsers += INT_ONE; + if (isNewSubject) protocol.cumulativeUniqueSubjects += INT_ONE; + if (isNewAccountForSubject) protocol.cumulativeUniqueUsers += INT_ONE; + + trader.cumulativeTradesCount += INT_ONE; + subject.cumulativeTradesCount += INT_ONE; + protocol.cumulativeTradesCount += INT_ONE; + + if (isBuy) { + if (isNewTraderOfType) protocol.cumulativeUniqueBuyers += INT_ONE; + + trader.cumulativeBuyCount += INT_ONE; + subject.cumulativeBuyCount += INT_ONE; + protocol.cumulativeBuyCount += INT_ONE; + } else { + if (isNewTraderOfType) protocol.cumulativeUniqueSellers += INT_ONE; + + trader.cumulativeSellCount += INT_ONE; + subject.cumulativeSellCount += INT_ONE; + protocol.cumulativeSellCount += INT_ONE; + } + + trader.save(); + subject.save(); + protocol.save(); +} + +export function updateRevenue( + subjectAddress: Address, + subjectFeeETH: BigInt, + protocolFeeETH: BigInt, + event: ethereum.Event +): void { + const protocol = getOrCreateProtocol(); + const subject = getOrCreateSubject(subjectAddress, event).subject; + + const eth = getOrCreateEthToken(event); + const subjectFeeUSD = subjectFeeETH + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); + const protocolFeeUSD = protocolFeeETH + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); + + subject.cumulativeRevenueETH = + subject.cumulativeRevenueETH.plus(subjectFeeETH); + subject.cumulativeRevenueUSD = + subject.cumulativeRevenueUSD.plus(subjectFeeUSD); + + protocol.cumulativeSupplySideRevenueETH = + protocol.cumulativeSupplySideRevenueETH.plus(subjectFeeETH); + protocol.cumulativeSupplySideRevenueUSD = + protocol.cumulativeSupplySideRevenueUSD.plus(subjectFeeUSD); + protocol.cumulativeProtocolSideRevenueETH = + protocol.cumulativeProtocolSideRevenueETH.plus(protocolFeeETH); + protocol.cumulativeProtocolSideRevenueUSD = + protocol.cumulativeProtocolSideRevenueUSD.plus(protocolFeeUSD); + protocol.cumulativeTotalRevenueETH = protocol.cumulativeTotalRevenueETH.plus( + subjectFeeETH.plus(protocolFeeETH) + ); + protocol.cumulativeTotalRevenueUSD = protocol.cumulativeTotalRevenueUSD.plus( + subjectFeeUSD.plus(protocolFeeUSD) + ); + + subject.save(); + protocol.save(); +} + +export function updateVolume( + traderAddress: Address, + subjectAddress: Address, + amountETH: BigInt, + isBuy: boolean, + event: ethereum.Event +): void { + const protocol = getOrCreateProtocol(); + const trader = getOrCreateTrader(traderAddress, event).trader; + const subject = getOrCreateSubject(subjectAddress, event).subject; + + const eth = getOrCreateEthToken(event); + const amountUSD = amountETH + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); + + if (isBuy) { + trader.cumulativeBuyVolumeETH = + trader.cumulativeBuyVolumeETH.plus(amountETH); + trader.cumulativeBuyVolumeUSD = + trader.cumulativeBuyVolumeUSD.plus(amountUSD); + + subject.cumulativeBuyVolumeETH = + subject.cumulativeBuyVolumeETH.plus(amountETH); + subject.cumulativeBuyVolumeUSD = + subject.cumulativeBuyVolumeUSD.plus(amountUSD); + + protocol.cumulativeBuyVolumeETH = + protocol.cumulativeBuyVolumeETH.plus(amountETH); + protocol.cumulativeBuyVolumeUSD = + protocol.cumulativeBuyVolumeUSD.plus(amountUSD); + } else { + trader.cumulativeSellVolumeETH = + trader.cumulativeSellVolumeETH.plus(amountETH); + trader.cumulativeSellVolumeUSD = + trader.cumulativeSellVolumeUSD.plus(amountUSD); + + subject.cumulativeSellVolumeETH = + subject.cumulativeSellVolumeETH.plus(amountETH); + subject.cumulativeSellVolumeUSD = + subject.cumulativeSellVolumeUSD.plus(amountUSD); + + protocol.cumulativeSellVolumeETH = + protocol.cumulativeSellVolumeETH.plus(amountETH); + protocol.cumulativeSellVolumeUSD = + protocol.cumulativeSellVolumeUSD.plus(amountUSD); + } + + trader.cumulativeTotalVolumeETH = trader.cumulativeBuyVolumeETH.plus( + trader.cumulativeSellVolumeETH + ); + trader.cumulativeTotalVolumeUSD = trader.cumulativeBuyVolumeUSD.plus( + trader.cumulativeSellVolumeUSD + ); + trader.netVolumeETH = trader.cumulativeBuyVolumeETH.minus( + trader.cumulativeSellVolumeETH + ); + trader.netVolumeUSD = trader.cumulativeBuyVolumeUSD.minus( + trader.cumulativeSellVolumeUSD + ); + + subject.cumulativeTotalVolumeETH = subject.cumulativeBuyVolumeETH.plus( + subject.cumulativeSellVolumeETH + ); + subject.cumulativeTotalVolumeUSD = subject.cumulativeBuyVolumeUSD.plus( + subject.cumulativeSellVolumeUSD + ); + subject.netVolumeETH = subject.cumulativeBuyVolumeETH.minus( + subject.cumulativeSellVolumeETH + ); + subject.netVolumeUSD = subject.cumulativeBuyVolumeUSD.minus( + subject.cumulativeSellVolumeUSD + ); + + protocol.cumulativeTotalVolumeETH = protocol.cumulativeBuyVolumeETH.plus( + protocol.cumulativeSellVolumeETH + ); + protocol.cumulativeTotalVolumeUSD = protocol.cumulativeBuyVolumeUSD.plus( + protocol.cumulativeSellVolumeUSD + ); + protocol.netVolumeETH = protocol.cumulativeBuyVolumeETH.minus( + protocol.cumulativeSellVolumeETH + ); + protocol.netVolumeUSD = protocol.cumulativeBuyVolumeUSD.minus( + protocol.cumulativeSellVolumeUSD + ); + + trader.save(); + subject.save(); + protocol.save(); +} + +export function updateConnections( + traderAddress: Address, + subjectAddress: Address, + shares: BigInt, + amountETH: BigInt, + isBuy: boolean, + event: ethereum.Event +): void { + const trader = getOrCreateTrader(traderAddress, event).trader; + const subject = getOrCreateSubject(subjectAddress, event).subject; + const connection = getOrCreateConnection( + traderAddress, + subjectAddress, + event + ); + + const eth = getOrCreateEthToken(event); + const amountUSD = amountETH + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); + + if (isBuy) { + connection.shares = connection.shares.plus(shares); + connection.cumulativeBuyVolumeETH = + connection.cumulativeBuyVolumeETH.plus(amountETH); + connection.cumulativeBuyVolumeUSD = + connection.cumulativeBuyVolumeUSD.plus(amountUSD); + connection.cumulativeBuyCount += INT_ONE; + } else { + connection.shares = connection.shares.minus(shares); + connection.cumulativeSellVolumeETH = + connection.cumulativeSellVolumeETH.plus(amountETH); + connection.cumulativeSellVolumeUSD = + connection.cumulativeSellVolumeUSD.plus(amountUSD); + connection.cumulativeSellCount += INT_ONE; + } + + connection.cumulativeTotalVolumeETH = connection.cumulativeBuyVolumeETH.plus( + connection.cumulativeSellVolumeETH + ); + connection.cumulativeTotalVolumeUSD = connection.cumulativeBuyVolumeUSD.plus( + connection.cumulativeSellVolumeUSD + ); + connection.netVolumeETH = connection.cumulativeBuyVolumeETH.minus( + connection.cumulativeSellVolumeETH + ); + connection.netVolumeUSD = connection.cumulativeBuyVolumeUSD.minus( + connection.cumulativeSellVolumeUSD + ); + connection.cumulativeTradesCount += INT_ONE; + + if (!trader.connections.includes(connection.id)) { + addToArrayAtIndex(trader.connections, connection.id); + } + if (!subject.connections.includes(connection.id)) { + addToArrayAtIndex(subject.connections, connection.id); + } + + trader.save(); + subject.save(); +} + +export function updateSubjectPrice( + subjectAddress: Address, + supply: BigInt, + amountETH: BigInt, + event: ethereum.Event +): void { + const subject = getOrCreateSubject(subjectAddress, event).subject; + + const eth = getOrCreateEthToken(event); + const amountUSD = amountETH + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); + + subject.sharePriceETH = amountETH; + subject.sharePriceUSD = amountUSD; + subject.supply = supply; + + subject.save(); +} diff --git a/subgraphs/friend-tech/src/common/prices.ts b/subgraphs/friend-tech/src/common/prices.ts new file mode 100644 index 0000000000..5bc319e6e2 --- /dev/null +++ b/subgraphs/friend-tech/src/common/prices.ts @@ -0,0 +1,28 @@ +import { Address, BigDecimal } from "@graphprotocol/graph-ts"; + +import { + BIGDECIMAL_ZERO, + BIGINT_TEN, + CHAINLINK_AGGREGATOR_ETH_USD, +} from "./constants"; + +import { ChainLinkAggregator } from "../../generated/Shares/ChainLinkAggregator"; + +export function getEthPriceUSD(): BigDecimal { + const chainLinkAggregator = ChainLinkAggregator.bind( + Address.fromString(CHAINLINK_AGGREGATOR_ETH_USD) + ); + + const latestAnswerCall = chainLinkAggregator.try_latestAnswer(); + if (latestAnswerCall.reverted) { + return BIGDECIMAL_ZERO; + } + const decimalsCall = chainLinkAggregator.try_decimals(); + if (decimalsCall.reverted) { + return BIGDECIMAL_ZERO; + } + + return latestAnswerCall.value + .toBigDecimal() + .div(BIGINT_TEN.pow(decimalsCall.value as u8).toBigDecimal()); +} diff --git a/subgraphs/friend-tech/src/common/snapshots.ts b/subgraphs/friend-tech/src/common/snapshots.ts new file mode 100644 index 0000000000..70dab9eb54 --- /dev/null +++ b/subgraphs/friend-tech/src/common/snapshots.ts @@ -0,0 +1,366 @@ +import { Address, BigInt, ethereum } from "@graphprotocol/graph-ts"; + +import { + getOrCreateActiveAccount, + getOrCreateActiveSubject, + getOrCreateActiveTrader, + getOrCreateActiveTraderOfType, + getOrCreateConnection, + getOrCreateConnectionDailySnapshot, + getOrCreateEthToken, + getOrCreateFinancialsDailySnapshot, + getOrCreateProtocol, + getOrCreateSubject, + getOrCreateSubjectDailySnapshot, + getOrCreateTrader, + getOrCreateTraderDailySnapshot, + getOrCreateUsageMetricsDailySnapshot, +} from "./getters"; +import { BIGINT_TEN, ETH_DECIMALS, INT_ONE } from "./constants"; +import { getDaysSinceEpoch } from "./utils"; + +export function updateUsageMetricsDailySnapshot( + traderAddress: Address, + subjectAddress: Address, + isBuy: boolean, + event: ethereum.Event +): void { + const protocol = getOrCreateProtocol(); + const snapshot = getOrCreateUsageMetricsDailySnapshot(event); + + const day = getDaysSinceEpoch(event.block.timestamp.toI32()); + + const isActiveTrader = getOrCreateActiveTrader(traderAddress, day); + const isActiveAccountForTrader = getOrCreateActiveAccount(traderAddress, day); + const isActiveTraderOfType = getOrCreateActiveTraderOfType( + traderAddress, + isBuy, + day + ); + + const isActiveSubject = getOrCreateActiveSubject(subjectAddress, day); + const isActiveAccountForSubject = getOrCreateActiveAccount( + subjectAddress, + day + ); + + if (isActiveTrader) snapshot.dailyActiveTraders += INT_ONE; + if (isActiveAccountForTrader) snapshot.dailyActiveUsers += INT_ONE; + if (isActiveSubject) snapshot.dailyActiveSubjects += INT_ONE; + if (isActiveAccountForSubject) snapshot.dailyActiveUsers += INT_ONE; + + if (isBuy) { + if (isActiveTraderOfType) snapshot.dailyActiveBuyers += INT_ONE; + snapshot.dailyBuyCount += INT_ONE; + } else { + if (isActiveTraderOfType) snapshot.dailyActiveSellers += INT_ONE; + snapshot.dailySellCount += INT_ONE; + } + + snapshot.dailyTradesCount += INT_ONE; + + snapshot.cumulativeUniqueBuyers = protocol.cumulativeUniqueBuyers; + snapshot.cumulativeUniqueSellers = protocol.cumulativeUniqueSellers; + snapshot.cumulativeUniqueTraders = protocol.cumulativeUniqueTraders; + snapshot.cumulativeUniqueSubjects = protocol.cumulativeUniqueSubjects; + snapshot.cumulativeUniqueUsers = protocol.cumulativeUniqueUsers; + + snapshot.cumulativeBuyCount = protocol.cumulativeBuyCount; + snapshot.cumulativeSellCount = protocol.cumulativeSellCount; + snapshot.cumulativeTradesCount = protocol.cumulativeTradesCount; + + snapshot.blockNumber = event.block.number; + snapshot.timestamp = event.block.timestamp; + + protocol.lastSnapshotDayID = day; + protocol.lastUpdateTimestamp = event.block.timestamp; + + snapshot.save(); + protocol.save(); +} + +export function updateFinancialsDailySnapshot( + amountETH: BigInt, + subjectFeeETH: BigInt, + protocolFeeETH: BigInt, + isBuy: boolean, + event: ethereum.Event +): void { + const protocol = getOrCreateProtocol(); + const snapshot = getOrCreateFinancialsDailySnapshot(event); + + const eth = getOrCreateEthToken(event); + const amountUSD = amountETH + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); + const subjectFeeUSD = subjectFeeETH + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); + const protocolFeeUSD = protocolFeeETH + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); + + snapshot.dailySupplySideRevenueETH = + snapshot.dailySupplySideRevenueETH.plus(subjectFeeETH); + snapshot.dailySupplySideRevenueUSD = + snapshot.dailySupplySideRevenueUSD.plus(subjectFeeUSD); + snapshot.dailyProtocolSideRevenueETH = + snapshot.dailyProtocolSideRevenueETH.plus(protocolFeeETH); + snapshot.dailyProtocolSideRevenueUSD = + snapshot.dailyProtocolSideRevenueUSD.plus(protocolFeeUSD); + snapshot.dailyTotalRevenueETH = snapshot.dailyTotalRevenueETH.plus( + subjectFeeETH.plus(protocolFeeETH) + ); + snapshot.dailyTotalRevenueUSD = snapshot.dailyTotalRevenueUSD.plus( + subjectFeeUSD.plus(protocolFeeUSD) + ); + + if (isBuy) { + snapshot.dailyBuyVolumeETH = snapshot.dailyBuyVolumeETH.plus(amountETH); + snapshot.dailyBuyVolumeUSD = snapshot.dailyBuyVolumeUSD.plus(amountUSD); + } else { + snapshot.dailySellVolumeETH = snapshot.dailySellVolumeETH.plus(amountETH); + snapshot.dailySellVolumeUSD = snapshot.dailySellVolumeUSD.plus(amountUSD); + } + + snapshot.dailyTotalVolumeETH = snapshot.dailyBuyVolumeETH.plus( + snapshot.dailySellVolumeETH + ); + snapshot.dailyTotalVolumeUSD = snapshot.dailyBuyVolumeUSD.plus( + snapshot.dailySellVolumeUSD + ); + snapshot.dailyNetVolumeETH = snapshot.dailyBuyVolumeETH.minus( + snapshot.dailySellVolumeETH + ); + snapshot.dailyNetVolumeUSD = snapshot.dailyBuyVolumeUSD.minus( + snapshot.dailySellVolumeUSD + ); + + snapshot.totalValueLockedETH = protocol.totalValueLockedETH; + snapshot.totalValueLockedUSD = protocol.totalValueLockedUSD; + snapshot.cumulativeSupplySideRevenueETH = + protocol.cumulativeSupplySideRevenueETH; + snapshot.cumulativeSupplySideRevenueUSD = + protocol.cumulativeSupplySideRevenueUSD; + snapshot.cumulativeProtocolSideRevenueETH = + protocol.cumulativeProtocolSideRevenueETH; + snapshot.cumulativeProtocolSideRevenueUSD = + protocol.cumulativeProtocolSideRevenueUSD; + snapshot.cumulativeTotalRevenueETH = protocol.cumulativeTotalRevenueETH; + snapshot.cumulativeTotalRevenueUSD = protocol.cumulativeTotalRevenueUSD; + snapshot.cumulativeBuyVolumeETH = protocol.cumulativeBuyVolumeETH; + snapshot.cumulativeBuyVolumeUSD = protocol.cumulativeBuyVolumeUSD; + snapshot.cumulativeSellVolumeETH = protocol.cumulativeSellVolumeETH; + snapshot.cumulativeSellVolumeUSD = protocol.cumulativeSellVolumeUSD; + snapshot.cumulativeTotalVolumeETH = protocol.cumulativeTotalVolumeETH; + snapshot.cumulativeTotalVolumeUSD = protocol.cumulativeTotalVolumeUSD; + snapshot.netVolumeETH = protocol.netVolumeETH; + snapshot.netVolumeUSD = protocol.netVolumeUSD; + + snapshot.blockNumber = event.block.number; + snapshot.timestamp = event.block.timestamp; + + snapshot.save(); +} + +export function updateTraderDailySnapshot( + traderAddress: Address, + amountETH: BigInt, + isBuy: boolean, + event: ethereum.Event +): void { + const trader = getOrCreateTrader(traderAddress, event).trader; + const snapshot = getOrCreateTraderDailySnapshot(traderAddress, event); + + const eth = getOrCreateEthToken(event); + const amountUSD = amountETH + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); + + if (isBuy) { + snapshot.dailyBuyVolumeETH = snapshot.dailyBuyVolumeETH.plus(amountETH); + snapshot.dailyBuyVolumeUSD = snapshot.dailyBuyVolumeUSD.plus(amountUSD); + snapshot.dailyBuyCount += INT_ONE; + } else { + snapshot.dailySellVolumeETH = snapshot.dailySellVolumeETH.plus(amountETH); + snapshot.dailySellVolumeUSD = snapshot.dailySellVolumeUSD.plus(amountUSD); + snapshot.dailySellCount += INT_ONE; + } + + snapshot.dailyTotalVolumeETH = snapshot.dailyBuyVolumeETH.plus( + snapshot.dailySellVolumeETH + ); + snapshot.dailyTotalVolumeUSD = snapshot.dailyBuyVolumeUSD.plus( + snapshot.dailySellVolumeUSD + ); + snapshot.dailyNetVolumeETH = snapshot.dailyBuyVolumeETH.minus( + snapshot.dailySellVolumeETH + ); + snapshot.dailyNetVolumeUSD = snapshot.dailyBuyVolumeUSD.minus( + snapshot.dailySellVolumeUSD + ); + snapshot.dailyTradesCount += INT_ONE; + + snapshot.cumulativeBuyVolumeETH = trader.cumulativeBuyVolumeETH; + snapshot.cumulativeBuyVolumeUSD = trader.cumulativeBuyVolumeUSD; + snapshot.cumulativeSellVolumeETH = trader.cumulativeSellVolumeETH; + snapshot.cumulativeSellVolumeUSD = trader.cumulativeSellVolumeUSD; + snapshot.cumulativeTotalVolumeETH = trader.cumulativeTotalVolumeETH; + snapshot.cumulativeTotalVolumeUSD = trader.cumulativeTotalVolumeUSD; + snapshot.netVolumeETH = trader.netVolumeETH; + snapshot.netVolumeUSD = trader.netVolumeUSD; + + snapshot.cumulativeBuyCount = trader.cumulativeBuyCount; + snapshot.cumulativeSellCount = trader.cumulativeSellCount; + snapshot.cumulativeTradesCount = trader.cumulativeTradesCount; + + snapshot.blockNumber = event.block.number; + snapshot.timestamp = event.block.timestamp; + + snapshot.save(); +} + +export function updateSubjectDailySnapshot( + subjectAddress: Address, + supply: BigInt, + amountETH: BigInt, + subjectFeeETH: BigInt, + isBuy: boolean, + event: ethereum.Event +): void { + const subject = getOrCreateSubject(subjectAddress, event).subject; + const snapshot = getOrCreateSubjectDailySnapshot(subjectAddress, event); + + const eth = getOrCreateEthToken(event); + const amountUSD = amountETH + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); + const subjectFeeUSD = subjectFeeETH + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); + + snapshot.dailyRevenueETH = snapshot.dailyRevenueETH.plus(subjectFeeETH); + snapshot.dailyRevenueUSD = snapshot.dailyRevenueUSD.plus(subjectFeeUSD); + + if (isBuy) { + snapshot.dailyBuyVolumeETH = snapshot.dailyBuyVolumeETH.plus(amountETH); + snapshot.dailyBuyVolumeUSD = snapshot.dailyBuyVolumeUSD.plus(amountUSD); + snapshot.dailyBuyCount += INT_ONE; + } else { + snapshot.dailySellVolumeETH = snapshot.dailySellVolumeETH.plus(amountETH); + snapshot.dailySellVolumeUSD = snapshot.dailySellVolumeUSD.plus(amountUSD); + snapshot.dailySellCount += INT_ONE; + } + + snapshot.dailyTotalVolumeETH = snapshot.dailyBuyVolumeETH.plus( + snapshot.dailySellVolumeETH + ); + snapshot.dailyTotalVolumeUSD = snapshot.dailyBuyVolumeUSD.plus( + snapshot.dailySellVolumeUSD + ); + snapshot.dailyNetVolumeETH = snapshot.dailyBuyVolumeETH.minus( + snapshot.dailySellVolumeETH + ); + snapshot.dailyNetVolumeUSD = snapshot.dailyBuyVolumeUSD.minus( + snapshot.dailySellVolumeUSD + ); + snapshot.dailyTradesCount += INT_ONE; + + snapshot.supply = supply; + snapshot.sharePriceETH = amountETH; + snapshot.sharePriceUSD = amountUSD; + + snapshot.cumulativeRevenueETH = subject.cumulativeRevenueETH; + snapshot.cumulativeRevenueUSD = subject.cumulativeRevenueUSD; + snapshot.cumulativeBuyVolumeETH = subject.cumulativeBuyVolumeETH; + snapshot.cumulativeBuyVolumeUSD = subject.cumulativeBuyVolumeUSD; + snapshot.cumulativeSellVolumeETH = subject.cumulativeSellVolumeETH; + snapshot.cumulativeSellVolumeUSD = subject.cumulativeSellVolumeUSD; + snapshot.cumulativeTotalVolumeETH = subject.cumulativeTotalVolumeETH; + snapshot.cumulativeTotalVolumeUSD = subject.cumulativeTotalVolumeUSD; + snapshot.netVolumeETH = subject.netVolumeETH; + snapshot.netVolumeUSD = subject.netVolumeUSD; + + snapshot.cumulativeBuyCount = subject.cumulativeBuyCount; + snapshot.cumulativeSellCount = subject.cumulativeSellCount; + snapshot.cumulativeTradesCount = subject.cumulativeTradesCount; + + snapshot.blockNumber = event.block.number; + snapshot.timestamp = event.block.timestamp; + + snapshot.save(); +} + +export function updateConnectionDailySnapshot( + traderAddress: Address, + subjectAddress: Address, + amountETH: BigInt, + isBuy: boolean, + event: ethereum.Event +): void { + const connection = getOrCreateConnection( + traderAddress, + subjectAddress, + event + ); + const snapshot = getOrCreateConnectionDailySnapshot( + traderAddress, + subjectAddress, + event + ); + + const eth = getOrCreateEthToken(event); + const amountUSD = amountETH + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); + + if (isBuy) { + snapshot.dailyBuyVolumeETH = snapshot.dailyBuyVolumeETH.plus(amountETH); + snapshot.dailyBuyVolumeUSD = snapshot.dailyBuyVolumeUSD.plus(amountUSD); + snapshot.dailyBuyCount += INT_ONE; + } else { + snapshot.dailySellVolumeETH = snapshot.dailySellVolumeETH.plus(amountETH); + snapshot.dailySellVolumeUSD = snapshot.dailySellVolumeUSD.plus(amountUSD); + snapshot.dailySellCount += INT_ONE; + } + + snapshot.dailyTotalVolumeETH = snapshot.dailyBuyVolumeETH.plus( + snapshot.dailySellVolumeETH + ); + snapshot.dailyTotalVolumeUSD = snapshot.dailyBuyVolumeUSD.plus( + snapshot.dailySellVolumeUSD + ); + snapshot.dailyNetVolumeETH = snapshot.dailyBuyVolumeETH.minus( + snapshot.dailySellVolumeETH + ); + snapshot.dailyNetVolumeUSD = snapshot.dailyBuyVolumeUSD.minus( + snapshot.dailySellVolumeUSD + ); + snapshot.dailyTradesCount += INT_ONE; + + snapshot.shares = connection.shares; + snapshot.cumulativeBuyVolumeETH = connection.cumulativeBuyVolumeETH; + snapshot.cumulativeBuyVolumeUSD = connection.cumulativeBuyVolumeUSD; + snapshot.cumulativeSellVolumeETH = connection.cumulativeSellVolumeETH; + snapshot.cumulativeSellVolumeUSD = connection.cumulativeSellVolumeUSD; + snapshot.cumulativeTotalVolumeETH = connection.cumulativeTotalVolumeETH; + snapshot.cumulativeTotalVolumeUSD = connection.cumulativeTotalVolumeUSD; + snapshot.netVolumeETH = connection.netVolumeETH; + snapshot.netVolumeUSD = connection.netVolumeUSD; + + snapshot.cumulativeBuyCount = connection.cumulativeBuyCount; + snapshot.cumulativeSellCount = connection.cumulativeSellCount; + snapshot.cumulativeTradesCount = connection.cumulativeTradesCount; + + snapshot.createdBlockNumber = event.block.number; + snapshot.createdTimestamp = event.block.timestamp; + + snapshot.save(); +} diff --git a/subgraphs/friend-tech/src/common/types.ts b/subgraphs/friend-tech/src/common/types.ts new file mode 100644 index 0000000000..ef0408e85d --- /dev/null +++ b/subgraphs/friend-tech/src/common/types.ts @@ -0,0 +1,11 @@ +import { Subject, Trader } from "../../generated/schema"; + +export class TraderResponse { + trader: Trader; + isNewTrader: boolean; +} + +export class SubjectResponse { + subject: Subject; + isNewSubject: boolean; +} diff --git a/subgraphs/friend-tech/src/common/utils.ts b/subgraphs/friend-tech/src/common/utils.ts new file mode 100644 index 0000000000..c99363fbdb --- /dev/null +++ b/subgraphs/friend-tech/src/common/utils.ts @@ -0,0 +1,26 @@ +import { SECONDS_PER_DAY } from "./constants"; + +export function addToArrayAtIndex(x: T[], item: T, index: i32 = -1): T[] { + if (x.length == 0) { + return [item]; + } + if (index == -1 || index > x.length) { + index = x.length; + } + let retval = new Array(); + let i = 0; + while (i < index) { + retval.push(x[i]); + i += 1; + } + retval.push(item); + while (i < x.length) { + retval.push(x[i]); + i += 1; + } + return retval; +} + +export function getDaysSinceEpoch(secondsSinceEpoch: number): i32 { + return Math.floor(secondsSinceEpoch / SECONDS_PER_DAY); +} diff --git a/subgraphs/friend-tech/src/mappings/handlers.ts b/subgraphs/friend-tech/src/mappings/handlers.ts new file mode 100644 index 0000000000..5d89fc9b74 --- /dev/null +++ b/subgraphs/friend-tech/src/mappings/handlers.ts @@ -0,0 +1,73 @@ +import { + updateConnections, + updateRevenue, + updateSubjectPrice, + updateTVL, + updateUsage, + updateVolume, +} from "../common/metrics"; +import { + updateConnectionDailySnapshot, + updateFinancialsDailySnapshot, + updateSubjectDailySnapshot, + updateTraderDailySnapshot, + updateUsageMetricsDailySnapshot, +} from "../common/snapshots"; +import { createEvent } from "../common/events"; + +import { Trade } from "../../generated/Shares/Shares"; + +export function handleTrade(event: Trade): void { + const trader = event.params.trader; + const subject = event.params.subject; + const isBuy = event.params.isBuy; + const shares = event.params.shareAmount; + const supply = event.params.supply; + const tradeAmountETH = event.params.ethAmount; + const subjectFeeETH = event.params.subjectEthAmount; + const protocolFeeETH = event.params.protocolEthAmount; + const sharePriceETH = event.params.ethAmount.minus( + event.params.subjectEthAmount.plus(event.params.protocolEthAmount) + ); + + updateTVL(sharePriceETH, isBuy, event); + updateUsage(trader, subject, isBuy, event); + updateRevenue(subject, subjectFeeETH, protocolFeeETH, event); + updateVolume(trader, subject, sharePriceETH, isBuy, event); + + updateConnections(trader, subject, shares, sharePriceETH, isBuy, event); + updateSubjectPrice(subject, supply, tradeAmountETH, event); + + updateUsageMetricsDailySnapshot(trader, subject, isBuy, event); + updateFinancialsDailySnapshot( + sharePriceETH, + subjectFeeETH, + protocolFeeETH, + isBuy, + event + ); + updateTraderDailySnapshot(trader, sharePriceETH, isBuy, event); + updateSubjectDailySnapshot( + subject, + supply, + sharePriceETH, + subjectFeeETH, + isBuy, + event + ); + updateConnectionDailySnapshot(trader, subject, sharePriceETH, isBuy, event); + + createEvent( + trader, + subject, + shares, + sharePriceETH, + subjectFeeETH, + protocolFeeETH, + tradeAmountETH, + isBuy, + event + ); + + return; +} diff --git a/subgraphs/friend-tech/tsconfig.json b/subgraphs/friend-tech/tsconfig.json new file mode 100644 index 0000000000..f723f84e69 --- /dev/null +++ b/subgraphs/friend-tech/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "./node_modules/@graphprotocol/graph-ts/types/tsconfig.base.json", + "compilerOptions": { + "target": "es5" + }, + "include": ["src"], + "exclude": ["node_modules"] +} \ No newline at end of file From 4415297e0b685384650d444413a1d767eb52b1cd Mon Sep 17 00:00:00 2001 From: Dhruv Chauhan Date: Wed, 27 Sep 2023 00:09:56 +0530 Subject: [PATCH 02/10] fix lint --- .../config/deployments/friend-tech-base/configurations.ts | 4 ++-- subgraphs/friend-tech/src/common/constants.ts | 4 ++-- subgraphs/friend-tech/src/common/utils.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/subgraphs/friend-tech/protocols/friend-tech/config/deployments/friend-tech-base/configurations.ts b/subgraphs/friend-tech/protocols/friend-tech/config/deployments/friend-tech-base/configurations.ts index 294d85af58..5cdf74e684 100644 --- a/subgraphs/friend-tech/protocols/friend-tech/config/deployments/friend-tech-base/configurations.ts +++ b/subgraphs/friend-tech/protocols/friend-tech/config/deployments/friend-tech-base/configurations.ts @@ -18,9 +18,9 @@ export class FriendTechBaseConfigurations implements Configurations { return PROTOCOL_SLUG; } getFactoryAddress(): Address { - return Address.fromString("0xCF205808Ed36593aa40a44F10c7f7C2F67d4A4d4"); + return Address.fromString("0xcf205808ed36593aa40a44f10c7f7c2f67d4a4d4"); } getTreasuryAddress(): Address { - return Address.fromString("0xdd9176eA3E7559D6B68b537eF555D3e89403f742"); + return Address.fromString("0xdd9176ea3e7559d6b68b537ef555d3e89403f742"); } } diff --git a/subgraphs/friend-tech/src/common/constants.ts b/subgraphs/friend-tech/src/common/constants.ts index e883973b6b..8a823244ae 100644 --- a/subgraphs/friend-tech/src/common/constants.ts +++ b/subgraphs/friend-tech/src/common/constants.ts @@ -61,7 +61,7 @@ export namespace TradeType { export const ETH_NAME = "Ether"; export const ETH_SYMBOL = "ETH"; export const ETH_DECIMALS = 18; -export const ETH_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +export const ETH_ADDRESS = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; //////////////////////// ///// Type Helpers ///// @@ -99,4 +99,4 @@ export const SECONDS_PER_DAY = 60 * 60 * 24; //////////////////////// export const CHAINLINK_AGGREGATOR_ETH_USD = - "0x57d2d46Fc7ff2A7142d479F2f59e1E3F95447077"; + "0x57d2d46fc7ff2a7142d479f2f59e1e3f95447077"; diff --git a/subgraphs/friend-tech/src/common/utils.ts b/subgraphs/friend-tech/src/common/utils.ts index c99363fbdb..0b8f8560a7 100644 --- a/subgraphs/friend-tech/src/common/utils.ts +++ b/subgraphs/friend-tech/src/common/utils.ts @@ -7,7 +7,7 @@ export function addToArrayAtIndex(x: T[], item: T, index: i32 = -1): T[] { if (index == -1 || index > x.length) { index = x.length; } - let retval = new Array(); + const retval = new Array(); let i = 0; while (i < index) { retval.push(x[i]); From 6a6061d1bfc3601d26e358f2b8464bc19feaf29e Mon Sep 17 00:00:00 2001 From: Dhruv Chauhan Date: Thu, 28 Sep 2023 17:16:01 +0530 Subject: [PATCH 03/10] update README --- subgraphs/friend-tech/README.md | 45 ++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/subgraphs/friend-tech/README.md b/subgraphs/friend-tech/README.md index 5e36da0efb..13119e16bf 100644 --- a/subgraphs/friend-tech/README.md +++ b/subgraphs/friend-tech/README.md @@ -2,4 +2,47 @@ friend-tech subgraph based on a non-standard schema. -...[WIP] +## Business Summary + +- Friend.tech is a decentralized social network. Users can buy and sell `keys` (previously known as `shares`) that are linked to Twitter (now X) accounts. These keys offer access to private in-app chatrooms and exclusive content from that X user. +- Social tokens combine aspects of traditional cryptocurrencies with patronage systems, allowing influencers, creators, and others to monetize a fan base in exchange for exclusive offers and content. +- The price of keys is determined based on the concept of a bonding curve. The price follows a mathematical relationship to the supply of the keys within a given group. Therefore, the more shares purchased, the higher the chances of the prices increasing. +- Every key-related buy-sell transaction attracts a 10% fee — half of which goes to the creator, and the other half goes to the treasury. +- Every user is either a "subject" or a "trader" at Friend.tech. + - Subjects (the creators) register on the platform by connecting their Twitter account, and enable people to speculate on their keys. They earn a fee on each trade. + - Traders (the followers) buy / sell keys of subjects. Depending on how big the subject’s network grows, the key price appreciates, and traders can then sell it for a profit, or keep holding. + +## Financial and Usage Metrics + +> Note: `trade value = key value + subject fee + protocol fee` + +Total Value Locked: + +- TVL = ∑ (key value in Buy trades) - ∑ (key value in Sell trades) + +Revenue: + +- Total Revenue = 10% total fee on trade value +- Supply Side Revenue = 5% subject fee on trade value +- Protocol Side Revenue = 5% protocol fee on trade value + +Volume: + +- Buy Volume = ∑ (key value in Buy trades) +- Sell Volume = ∑ (key value in Sell trades) +- Total Volume = Buy Volume + Sell Volume +- Net Volume = Buy Volume - Sell Volume + +Activity: + +- There are two groups of users, `Traders` and `Subjects` + - Traders can further be classified into `Buyers` and `Sellers` + +## Links: + +- Protocol: https://www.friend.tech/ +- Main Contract: https://basescan.org/address/0xcf205808ed36593aa40a44f10c7f7c2f67d4a4d4 +- Stats Dashboards: + - https://dune.com/cryptokoryo/friendtech + - https://dune.com/austin_adams/friendstech-dashboard + - https://dune.com/hildobby/friendtech From 5d96729569c2a0c6d393f7b98234b5176e1b818b Mon Sep 17 00:00:00 2001 From: Dhruv Chauhan Date: Tue, 3 Oct 2023 16:11:00 +0530 Subject: [PATCH 04/10] cleanup --- subgraphs/friend-tech/schema.graphql | 40 ++---- subgraphs/friend-tech/src/common/events.ts | 25 +--- subgraphs/friend-tech/src/common/getters.ts | 125 ++++------------- subgraphs/friend-tech/src/common/metrics.ts | 129 ++++++++---------- subgraphs/friend-tech/src/common/prices.ts | 2 +- subgraphs/friend-tech/src/common/snapshots.ts | 127 ++++++++--------- subgraphs/friend-tech/src/common/types.ts | 14 +- subgraphs/friend-tech/src/common/utils.ts | 17 ++- 8 files changed, 185 insertions(+), 294 deletions(-) diff --git a/subgraphs/friend-tech/schema.graphql b/subgraphs/friend-tech/schema.graphql index d2de4c687d..fee9bdc567 100644 --- a/subgraphs/friend-tech/schema.graphql +++ b/subgraphs/friend-tech/schema.graphql @@ -170,7 +170,7 @@ type Protocol @entity @regularPolling { ##### Protocol Timeseries ##### ############################### -type UsageMetricsDailySnapshot @entity @dailySnapshot { +type UsageMetricsDailySnapshot @entity @dailySnapshot(immutable: true) { " ID is # of days since Unix epoch time " id: Bytes! @@ -235,7 +235,7 @@ type UsageMetricsDailySnapshot @entity @dailySnapshot { blockNumber: BigInt! } -type FinancialsDailySnapshot @entity @dailySnapshot { +type FinancialsDailySnapshot @entity @dailySnapshot(immutable: true) { " ID is # of days since Unix epoch time " id: Bytes! @@ -446,7 +446,7 @@ type Connection @entity @regularPolling { ####### User Timeseries ####### ############################### -type TraderDailySnapshot @entity @dailySnapshot { +type TraderDailySnapshot @entity @dailySnapshot(immutable: true) { " {ID is # of days since Unix epoch time}-{Trader ID} " id: Bytes! @@ -519,7 +519,7 @@ type TraderDailySnapshot @entity @dailySnapshot { blockNumber: BigInt! } -type SubjectDailySnapshot @entity @dailySnapshot { +type SubjectDailySnapshot @entity @dailySnapshot(immutable: true) { " {ID is # of days since Unix epoch time}-{Subject ID} " id: Bytes! @@ -607,7 +607,7 @@ type SubjectDailySnapshot @entity @dailySnapshot { blockNumber: BigInt! } -type ConnectionDailySnapshot @entity @regularPolling { +type ConnectionDailySnapshot @entity @regularPolling(immutable: true) { " {Day ID}-{Trader ID}-{Subject ID} " id: Bytes! @@ -773,34 +773,16 @@ type Trade implements Event @entity(immutable: true) @transaction { type _Account @entity @regularPolling { " Address of the Account " id: Bytes! + isBuyer: Boolean! + isSeller: Boolean! + isSubject: Boolean! } # Helper entity for calculating daily active users type _ActiveAccount @entity @regularPolling { " { Address of the Account }-{ Days since Unix epoch } " id: Bytes! -} - -# Helper entity for calculating daily active traders -type _ActiveTrader @entity @regularPolling { - " { Address of the Trader }-{ Days since Unix epoch } " - id: Bytes! -} - -# Helper entity for calculating daily active subjects -type _ActiveSubject @entity @regularPolling { - " { Address of the Subject }-{ Days since Unix epoch } " - id: Bytes! -} - -# Helps to accumulate total unique buyers / sellers -type _TraderOfType @entity @regularPolling { - " { Trade Type }-{ Address of the Trader } " - id: Bytes! -} - -# Helper entity for calculating daily active buyers / sellers -type _ActiveTraderOfType @entity @regularPolling { - " { Trade Type }-{ Address of the Trader }-{ Days since Unix epoch } " - id: Bytes! + isActiveBuyer: Boolean! + isActiveSeller: Boolean! + isActiveSubject: Boolean! } diff --git a/subgraphs/friend-tech/src/common/events.ts b/subgraphs/friend-tech/src/common/events.ts index 401c48f08b..cbcb48bf96 100644 --- a/subgraphs/friend-tech/src/common/events.ts +++ b/subgraphs/friend-tech/src/common/events.ts @@ -1,7 +1,7 @@ import { Address, Bytes, BigInt, ethereum } from "@graphprotocol/graph-ts"; -import { getOrCreateEthToken } from "./getters"; -import { BIGINT_TEN, ETH_DECIMALS, TradeType, ZERO_ADDRESS } from "./constants"; +import { getUsdPriceForEthAmount } from "./utils"; +import { TradeType, ZERO_ADDRESS } from "./constants"; import { NetworkConfigs } from "../../configurations/configure"; import { Trade } from "../../generated/schema"; @@ -35,23 +35,10 @@ export function createEvent( tradeEvent.type = isBuy ? TradeType.BUY : TradeType.SELL; tradeEvent.shares = shares; - const eth = getOrCreateEthToken(event); - const sharePriceUSD = sharePriceETH - .toBigDecimal() - .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) - .times(eth.lastPriceUSD!); - const protocolFeeUSD = protocolFeeETH - .toBigDecimal() - .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) - .times(eth.lastPriceUSD!); - const subjectFeeUSD = subjectFeeETH - .toBigDecimal() - .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) - .times(eth.lastPriceUSD!); - const tradeAmountUSD = tradeAmountETH - .toBigDecimal() - .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) - .times(eth.lastPriceUSD!); + const sharePriceUSD = getUsdPriceForEthAmount(sharePriceETH, event); + const protocolFeeUSD = getUsdPriceForEthAmount(protocolFeeETH, event); + const subjectFeeUSD = getUsdPriceForEthAmount(subjectFeeETH, event); + const tradeAmountUSD = getUsdPriceForEthAmount(tradeAmountETH, event); tradeEvent.sharePriceETH = sharePriceETH; tradeEvent.sharePriceUSD = sharePriceUSD; diff --git a/subgraphs/friend-tech/src/common/getters.ts b/subgraphs/friend-tech/src/common/getters.ts index f23a47e0e8..060e19689c 100644 --- a/subgraphs/friend-tech/src/common/getters.ts +++ b/subgraphs/friend-tech/src/common/getters.ts @@ -13,19 +13,15 @@ import { ProtocolType, TradeType, } from "./constants"; -import { getEthPriceUSD } from "./prices"; +import { getUsdPricePerEth } from "./prices"; import { Versions } from "../versions"; import { NetworkConfigs } from "../../configurations/configure"; -import { SubjectResponse, TraderResponse } from "./types"; +import { AccountResponse, ActiveAccountResponse } from "./types"; import { getDaysSinceEpoch } from "./utils"; import { _Account, _ActiveAccount, - _ActiveSubject, - _ActiveTrader, - _ActiveTraderOfType, - _TraderOfType, Connection, ConnectionDailySnapshot, FinancialsDailySnapshot, @@ -102,7 +98,7 @@ export function getOrCreateEthToken(event: ethereum.Event): Token { } if (!token.lastPriceUSD || token.lastPriceBlockNumber! < event.block.number) { - const priceUSD = getEthPriceUSD(); + const priceUSD = getUsdPricePerEth(); token.lastPriceUSD = priceUSD; token.lastPriceBlockNumber = event.block.number; @@ -114,7 +110,7 @@ export function getOrCreateEthToken(event: ethereum.Event): Token { export function getOrCreateTrader( traderAddress: Address, event: ethereum.Event -): TraderResponse { +): Trader { let isNewTrader = false; let trader = Trader.load(traderAddress); @@ -141,36 +137,16 @@ export function getOrCreateTrader( trader.save(); } - return { trader, isNewTrader }; -} - -export function getOrCreateActiveTrader( - traderAddress: Address, - day: i32 -): boolean { - const id = Bytes.empty() - .concat(traderAddress) - .concat(Bytes.fromUTF8("-")) - .concat(Bytes.fromI32(day)); - - let trader = _ActiveTrader.load(id); - if (!trader) { - trader = new _ActiveTrader(id); - trader.save(); - return true; - } - return false; + return trader; } export function getOrCreateSubject( subjectAddress: Address, event: ethereum.Event -): SubjectResponse { - let isNewSubject = false; +): Subject { let subject = Subject.load(subjectAddress); if (!subject) { - isNewSubject = true; subject = new Subject(subjectAddress); subject.cumulativeRevenueETH = BIGINT_ZERO; @@ -198,25 +174,7 @@ export function getOrCreateSubject( subject.save(); } - return { subject, isNewSubject }; -} - -export function getOrCreateActiveSubject( - subjectAddress: Address, - day: i32 -): boolean { - const id = Bytes.empty() - .concat(subjectAddress) - .concat(Bytes.fromUTF8("-")) - .concat(Bytes.fromI32(day)); - - let subject = _ActiveSubject.load(id); - if (!subject) { - subject = new _ActiveSubject(id); - subject.save(); - return true; - } - return false; + return subject; } export function getOrCreateConnection( @@ -259,73 +217,40 @@ export function getOrCreateConnection( return connection; } -export function getOrCreateAccount(accountAddress: Address): boolean { +export function getOrCreateAccount(accountAddress: Address): AccountResponse { + let isNewAccount = false; let account = _Account.load(accountAddress); if (!account) { + isNewAccount = true; account = new _Account(accountAddress); + account.isBuyer = false; + account.isSeller = false; + account.isSubject = false; account.save(); - return true; } - return false; + return { account, isNewAccount }; } export function getOrCreateActiveAccount( accountAddress: Address, day: i32 -): boolean { +): ActiveAccountResponse { + let isNewActiveAccount = false; const id = Bytes.empty() .concat(accountAddress) .concat(Bytes.fromUTF8("-")) .concat(Bytes.fromI32(day)); - let account = _ActiveAccount.load(id); - if (!account) { - account = new _ActiveAccount(id); - account.save(); - return true; - } - return false; -} - -export function getOrCreateTraderOfType( - traderAddress: Address, - isBuy: boolean -): boolean { - const tradeType = isBuy ? TradeType.BUY : TradeType.SELL; - const id = Bytes.empty() - .concat(Bytes.fromUTF8(tradeType)) - .concat(Bytes.fromUTF8("-")) - .concat(traderAddress); - - let trader = _TraderOfType.load(id); - if (!trader) { - trader = new _TraderOfType(id); - trader.save(); - return true; - } - return false; -} - -export function getOrCreateActiveTraderOfType( - traderAddress: Address, - isBuy: boolean, - day: i32 -): boolean { - const tradeType = isBuy ? TradeType.BUY : TradeType.SELL; - const id = Bytes.empty() - .concat(Bytes.fromUTF8(tradeType)) - .concat(Bytes.fromUTF8("-")) - .concat(traderAddress) - .concat(Bytes.fromUTF8("-")) - .concat(Bytes.fromI32(day)); - - let trader = _ActiveTraderOfType.load(id); - if (!trader) { - trader = new _ActiveTraderOfType(id); - trader.save(); - return true; + let activeAccount = _ActiveAccount.load(id); + if (!activeAccount) { + isNewActiveAccount = true; + activeAccount = new _ActiveAccount(id); + activeAccount.isActiveBuyer = false; + activeAccount.isActiveSeller = false; + activeAccount.isActiveSubject = false; + activeAccount.save(); } - return false; + return { activeAccount, isNewActiveAccount }; } export function getOrCreateUsageMetricsDailySnapshot( diff --git a/subgraphs/friend-tech/src/common/metrics.ts b/subgraphs/friend-tech/src/common/metrics.ts index 5bc7cea3d1..d56bd7158d 100644 --- a/subgraphs/friend-tech/src/common/metrics.ts +++ b/subgraphs/friend-tech/src/common/metrics.ts @@ -2,15 +2,13 @@ import { ethereum, BigInt, Address } from "@graphprotocol/graph-ts"; import { getOrCreateProtocol, - getOrCreateEthToken, getOrCreateAccount, getOrCreateTrader, getOrCreateSubject, - getOrCreateTraderOfType, getOrCreateConnection, } from "./getters"; -import { BIGINT_TEN, ETH_DECIMALS, INT_ONE } from "./constants"; -import { addToArrayAtIndex } from "./utils"; +import { INT_ONE } from "./constants"; +import { addToArrayAtIndex, getUsdPriceForEthAmount } from "./utils"; export function updateTVL( amountETH: BigInt, @@ -18,22 +16,17 @@ export function updateTVL( event: ethereum.Event ): void { const protocol = getOrCreateProtocol(); - const eth = getOrCreateEthToken(event); - - const amountUSD = amountETH - .toBigDecimal() - .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) - .times(eth.lastPriceUSD!); if (isBuy) { protocol.totalValueLockedETH = protocol.totalValueLockedETH.plus(amountETH); - protocol.totalValueLockedUSD = protocol.totalValueLockedUSD.plus(amountUSD); } else { protocol.totalValueLockedETH = protocol.totalValueLockedETH.minus(amountETH); - protocol.totalValueLockedUSD = - protocol.totalValueLockedUSD.minus(amountUSD); } + protocol.totalValueLockedUSD = getUsdPriceForEthAmount( + protocol.totalValueLockedETH, + event + ); protocol.save(); } @@ -44,42 +37,49 @@ export function updateUsage( isBuy: boolean, event: ethereum.Event ): void { - const traderResponse = getOrCreateTrader(traderAddress, event); - const subjectResponse = getOrCreateSubject(subjectAddress, event); - const protocol = getOrCreateProtocol(); - const trader = traderResponse.trader; - const subject = subjectResponse.subject; - - const isNewTrader = traderResponse.isNewTrader; - const isNewAccountForTrader = getOrCreateAccount(traderAddress); - const isNewTraderOfType = getOrCreateTraderOfType(traderAddress, isBuy); - - const isNewSubject = subjectResponse.isNewSubject; - const isNewAccountForSubject = getOrCreateAccount(subjectAddress); - - if (isNewTrader) protocol.cumulativeUniqueTraders += INT_ONE; - if (isNewAccountForTrader) protocol.cumulativeUniqueUsers += INT_ONE; - if (isNewSubject) protocol.cumulativeUniqueSubjects += INT_ONE; - if (isNewAccountForSubject) protocol.cumulativeUniqueUsers += INT_ONE; + const trader = getOrCreateTrader(traderAddress, event); + const subject = getOrCreateSubject(subjectAddress, event); - trader.cumulativeTradesCount += INT_ONE; - subject.cumulativeTradesCount += INT_ONE; - protocol.cumulativeTradesCount += INT_ONE; + const subjectAccount = getOrCreateAccount(subjectAddress); + if (subjectAccount.isNewAccount) { + protocol.cumulativeUniqueUsers += INT_ONE; + } + if (!subjectAccount.account.isSubject) { + protocol.cumulativeUniqueSubjects += INT_ONE; + subjectAccount.account.isSubject = true; + } + subjectAccount.account.save(); + const traderAccount = getOrCreateAccount(traderAddress); + if (traderAccount.isNewAccount) { + protocol.cumulativeUniqueUsers += INT_ONE; + } + if (!traderAccount.account.isBuyer && !traderAccount.account.isSeller) { + protocol.cumulativeUniqueTraders += INT_ONE; + } if (isBuy) { - if (isNewTraderOfType) protocol.cumulativeUniqueBuyers += INT_ONE; - + if (!traderAccount.account.isBuyer) { + protocol.cumulativeUniqueBuyers += INT_ONE; + traderAccount.account.isBuyer = true; + } trader.cumulativeBuyCount += INT_ONE; subject.cumulativeBuyCount += INT_ONE; protocol.cumulativeBuyCount += INT_ONE; } else { - if (isNewTraderOfType) protocol.cumulativeUniqueSellers += INT_ONE; - + if (!traderAccount.account.isSeller) { + protocol.cumulativeUniqueSellers += INT_ONE; + traderAccount.account.isSeller = true; + } trader.cumulativeSellCount += INT_ONE; subject.cumulativeSellCount += INT_ONE; protocol.cumulativeSellCount += INT_ONE; } + traderAccount.account.save(); + + trader.cumulativeTradesCount += INT_ONE; + subject.cumulativeTradesCount += INT_ONE; + protocol.cumulativeTradesCount += INT_ONE; trader.save(); subject.save(); @@ -93,17 +93,10 @@ export function updateRevenue( event: ethereum.Event ): void { const protocol = getOrCreateProtocol(); - const subject = getOrCreateSubject(subjectAddress, event).subject; - - const eth = getOrCreateEthToken(event); - const subjectFeeUSD = subjectFeeETH - .toBigDecimal() - .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) - .times(eth.lastPriceUSD!); - const protocolFeeUSD = protocolFeeETH - .toBigDecimal() - .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) - .times(eth.lastPriceUSD!); + const subject = getOrCreateSubject(subjectAddress, event); + + const subjectFeeUSD = getUsdPriceForEthAmount(subjectFeeETH, event); + const protocolFeeUSD = getUsdPriceForEthAmount(protocolFeeETH, event); subject.cumulativeRevenueETH = subject.cumulativeRevenueETH.plus(subjectFeeETH); @@ -137,14 +130,9 @@ export function updateVolume( event: ethereum.Event ): void { const protocol = getOrCreateProtocol(); - const trader = getOrCreateTrader(traderAddress, event).trader; - const subject = getOrCreateSubject(subjectAddress, event).subject; - - const eth = getOrCreateEthToken(event); - const amountUSD = amountETH - .toBigDecimal() - .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) - .times(eth.lastPriceUSD!); + const trader = getOrCreateTrader(traderAddress, event); + const subject = getOrCreateSubject(subjectAddress, event); + const amountUSD = getUsdPriceForEthAmount(amountETH, event); if (isBuy) { trader.cumulativeBuyVolumeETH = @@ -230,19 +218,14 @@ export function updateConnections( isBuy: boolean, event: ethereum.Event ): void { - const trader = getOrCreateTrader(traderAddress, event).trader; - const subject = getOrCreateSubject(subjectAddress, event).subject; + const trader = getOrCreateTrader(traderAddress, event); + const subject = getOrCreateSubject(subjectAddress, event); const connection = getOrCreateConnection( traderAddress, subjectAddress, event ); - - const eth = getOrCreateEthToken(event); - const amountUSD = amountETH - .toBigDecimal() - .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) - .times(eth.lastPriceUSD!); + const amountUSD = getUsdPriceForEthAmount(amountETH, event); if (isBuy) { connection.shares = connection.shares.plus(shares); @@ -273,15 +256,16 @@ export function updateConnections( connection.cumulativeSellVolumeUSD ); connection.cumulativeTradesCount += INT_ONE; + connection.save(); if (!trader.connections.includes(connection.id)) { - addToArrayAtIndex(trader.connections, connection.id); + trader.connections = addToArrayAtIndex(trader.connections, connection.id); } + trader.save(); + if (!subject.connections.includes(connection.id)) { - addToArrayAtIndex(subject.connections, connection.id); + subject.connections = addToArrayAtIndex(subject.connections, connection.id); } - - trader.save(); subject.save(); } @@ -291,13 +275,8 @@ export function updateSubjectPrice( amountETH: BigInt, event: ethereum.Event ): void { - const subject = getOrCreateSubject(subjectAddress, event).subject; - - const eth = getOrCreateEthToken(event); - const amountUSD = amountETH - .toBigDecimal() - .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) - .times(eth.lastPriceUSD!); + const subject = getOrCreateSubject(subjectAddress, event); + const amountUSD = getUsdPriceForEthAmount(amountETH, event); subject.sharePriceETH = amountETH; subject.sharePriceUSD = amountUSD; diff --git a/subgraphs/friend-tech/src/common/prices.ts b/subgraphs/friend-tech/src/common/prices.ts index 5bc319e6e2..ff6da58b8e 100644 --- a/subgraphs/friend-tech/src/common/prices.ts +++ b/subgraphs/friend-tech/src/common/prices.ts @@ -8,7 +8,7 @@ import { import { ChainLinkAggregator } from "../../generated/Shares/ChainLinkAggregator"; -export function getEthPriceUSD(): BigDecimal { +export function getUsdPricePerEth(): BigDecimal { const chainLinkAggregator = ChainLinkAggregator.bind( Address.fromString(CHAINLINK_AGGREGATOR_ETH_USD) ); diff --git a/subgraphs/friend-tech/src/common/snapshots.ts b/subgraphs/friend-tech/src/common/snapshots.ts index 70dab9eb54..cbaab65535 100644 --- a/subgraphs/friend-tech/src/common/snapshots.ts +++ b/subgraphs/friend-tech/src/common/snapshots.ts @@ -2,12 +2,8 @@ import { Address, BigInt, ethereum } from "@graphprotocol/graph-ts"; import { getOrCreateActiveAccount, - getOrCreateActiveSubject, - getOrCreateActiveTrader, - getOrCreateActiveTraderOfType, getOrCreateConnection, getOrCreateConnectionDailySnapshot, - getOrCreateEthToken, getOrCreateFinancialsDailySnapshot, getOrCreateProtocol, getOrCreateSubject, @@ -16,8 +12,12 @@ import { getOrCreateTraderDailySnapshot, getOrCreateUsageMetricsDailySnapshot, } from "./getters"; -import { BIGINT_TEN, ETH_DECIMALS, INT_ONE } from "./constants"; -import { getDaysSinceEpoch } from "./utils"; +import { INT_ONE } from "./constants"; +import { + addToArrayAtIndex, + getDaysSinceEpoch, + getUsdPriceForEthAmount, +} from "./utils"; export function updateUsageMetricsDailySnapshot( traderAddress: Address, @@ -30,32 +30,40 @@ export function updateUsageMetricsDailySnapshot( const day = getDaysSinceEpoch(event.block.timestamp.toI32()); - const isActiveTrader = getOrCreateActiveTrader(traderAddress, day); - const isActiveAccountForTrader = getOrCreateActiveAccount(traderAddress, day); - const isActiveTraderOfType = getOrCreateActiveTraderOfType( - traderAddress, - isBuy, - day - ); - - const isActiveSubject = getOrCreateActiveSubject(subjectAddress, day); - const isActiveAccountForSubject = getOrCreateActiveAccount( - subjectAddress, - day - ); - - if (isActiveTrader) snapshot.dailyActiveTraders += INT_ONE; - if (isActiveAccountForTrader) snapshot.dailyActiveUsers += INT_ONE; - if (isActiveSubject) snapshot.dailyActiveSubjects += INT_ONE; - if (isActiveAccountForSubject) snapshot.dailyActiveUsers += INT_ONE; + const activeSubject = getOrCreateActiveAccount(subjectAddress, day); + if (activeSubject.isNewActiveAccount) { + snapshot.dailyActiveUsers += INT_ONE; + } + if (!activeSubject.activeAccount.isActiveSubject) { + snapshot.dailyActiveSubjects += INT_ONE; + activeSubject.activeAccount.isActiveSubject = true; + } + activeSubject.activeAccount.save(); + const activeTrader = getOrCreateActiveAccount(traderAddress, day); + if (activeTrader.isNewActiveAccount) { + snapshot.dailyActiveUsers += INT_ONE; + } + if ( + !activeTrader.activeAccount.isActiveBuyer && + !activeTrader.activeAccount.isActiveSeller + ) { + snapshot.dailyActiveTraders += INT_ONE; + } if (isBuy) { - if (isActiveTraderOfType) snapshot.dailyActiveBuyers += INT_ONE; + if (!activeTrader.activeAccount.isActiveBuyer) { + snapshot.dailyActiveBuyers += INT_ONE; + activeTrader.activeAccount.isActiveBuyer = true; + } snapshot.dailyBuyCount += INT_ONE; } else { - if (isActiveTraderOfType) snapshot.dailyActiveSellers += INT_ONE; + if (!activeTrader.activeAccount.isActiveSeller) { + snapshot.dailyActiveSellers += INT_ONE; + activeTrader.activeAccount.isActiveSeller = true; + } snapshot.dailySellCount += INT_ONE; } + activeTrader.activeAccount.save(); snapshot.dailyTradesCount += INT_ONE; @@ -89,19 +97,9 @@ export function updateFinancialsDailySnapshot( const protocol = getOrCreateProtocol(); const snapshot = getOrCreateFinancialsDailySnapshot(event); - const eth = getOrCreateEthToken(event); - const amountUSD = amountETH - .toBigDecimal() - .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) - .times(eth.lastPriceUSD!); - const subjectFeeUSD = subjectFeeETH - .toBigDecimal() - .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) - .times(eth.lastPriceUSD!); - const protocolFeeUSD = protocolFeeETH - .toBigDecimal() - .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) - .times(eth.lastPriceUSD!); + const amountUSD = getUsdPriceForEthAmount(amountETH, event); + const subjectFeeUSD = getUsdPriceForEthAmount(subjectFeeETH, event); + const protocolFeeUSD = getUsdPriceForEthAmount(protocolFeeETH, event); snapshot.dailySupplySideRevenueETH = snapshot.dailySupplySideRevenueETH.plus(subjectFeeETH); @@ -172,14 +170,9 @@ export function updateTraderDailySnapshot( isBuy: boolean, event: ethereum.Event ): void { - const trader = getOrCreateTrader(traderAddress, event).trader; + const trader = getOrCreateTrader(traderAddress, event); const snapshot = getOrCreateTraderDailySnapshot(traderAddress, event); - - const eth = getOrCreateEthToken(event); - const amountUSD = amountETH - .toBigDecimal() - .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) - .times(eth.lastPriceUSD!); + const amountUSD = getUsdPriceForEthAmount(amountETH, event); if (isBuy) { snapshot.dailyBuyVolumeETH = snapshot.dailyBuyVolumeETH.plus(amountETH); @@ -232,18 +225,11 @@ export function updateSubjectDailySnapshot( isBuy: boolean, event: ethereum.Event ): void { - const subject = getOrCreateSubject(subjectAddress, event).subject; + const subject = getOrCreateSubject(subjectAddress, event); const snapshot = getOrCreateSubjectDailySnapshot(subjectAddress, event); - const eth = getOrCreateEthToken(event); - const amountUSD = amountETH - .toBigDecimal() - .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) - .times(eth.lastPriceUSD!); - const subjectFeeUSD = subjectFeeETH - .toBigDecimal() - .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) - .times(eth.lastPriceUSD!); + const amountUSD = getUsdPriceForEthAmount(amountETH, event); + const subjectFeeUSD = getUsdPriceForEthAmount(subjectFeeETH, event); snapshot.dailyRevenueETH = snapshot.dailyRevenueETH.plus(subjectFeeETH); snapshot.dailyRevenueUSD = snapshot.dailyRevenueUSD.plus(subjectFeeUSD); @@ -304,6 +290,12 @@ export function updateConnectionDailySnapshot( isBuy: boolean, event: ethereum.Event ): void { + const traderSnapshot = getOrCreateTraderDailySnapshot(traderAddress, event); + const subjectSnapshot = getOrCreateSubjectDailySnapshot( + subjectAddress, + event + ); + const connection = getOrCreateConnection( traderAddress, subjectAddress, @@ -314,12 +306,7 @@ export function updateConnectionDailySnapshot( subjectAddress, event ); - - const eth = getOrCreateEthToken(event); - const amountUSD = amountETH - .toBigDecimal() - .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) - .times(eth.lastPriceUSD!); + const amountUSD = getUsdPriceForEthAmount(amountETH, event); if (isBuy) { snapshot.dailyBuyVolumeETH = snapshot.dailyBuyVolumeETH.plus(amountETH); @@ -363,4 +350,20 @@ export function updateConnectionDailySnapshot( snapshot.createdTimestamp = event.block.timestamp; snapshot.save(); + + if (!traderSnapshot.connections.includes(snapshot.id)) { + traderSnapshot.connections = addToArrayAtIndex( + traderSnapshot.connections, + snapshot.id + ); + } + traderSnapshot.save(); + + if (!subjectSnapshot.connections.includes(snapshot.id)) { + subjectSnapshot.connections = addToArrayAtIndex( + subjectSnapshot.connections, + snapshot.id + ); + } + subjectSnapshot.save(); } diff --git a/subgraphs/friend-tech/src/common/types.ts b/subgraphs/friend-tech/src/common/types.ts index ef0408e85d..10fd5aecbd 100644 --- a/subgraphs/friend-tech/src/common/types.ts +++ b/subgraphs/friend-tech/src/common/types.ts @@ -1,11 +1,11 @@ -import { Subject, Trader } from "../../generated/schema"; +import { _Account, _ActiveAccount } from "../../generated/schema"; -export class TraderResponse { - trader: Trader; - isNewTrader: boolean; +export class AccountResponse { + account: _Account; + isNewAccount: boolean; } -export class SubjectResponse { - subject: Subject; - isNewSubject: boolean; +export class ActiveAccountResponse { + activeAccount: _ActiveAccount; + isNewActiveAccount: boolean; } diff --git a/subgraphs/friend-tech/src/common/utils.ts b/subgraphs/friend-tech/src/common/utils.ts index 0b8f8560a7..a4bc88a3be 100644 --- a/subgraphs/friend-tech/src/common/utils.ts +++ b/subgraphs/friend-tech/src/common/utils.ts @@ -1,4 +1,7 @@ -import { SECONDS_PER_DAY } from "./constants"; +import { BigDecimal, BigInt, ethereum } from "@graphprotocol/graph-ts"; + +import { BIGINT_TEN, ETH_DECIMALS, SECONDS_PER_DAY } from "./constants"; +import { getOrCreateEthToken } from "./getters"; export function addToArrayAtIndex(x: T[], item: T, index: i32 = -1): T[] { if (x.length == 0) { @@ -24,3 +27,15 @@ export function addToArrayAtIndex(x: T[], item: T, index: i32 = -1): T[] { export function getDaysSinceEpoch(secondsSinceEpoch: number): i32 { return Math.floor(secondsSinceEpoch / SECONDS_PER_DAY); } + +export function getUsdPriceForEthAmount( + amount: BigInt, + event: ethereum.Event +): BigDecimal { + const eth = getOrCreateEthToken(event); + + return amount + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); +} From b10c26b0fb3f8366f14a02382557404cba9f3982 Mon Sep 17 00:00:00 2001 From: Dhruv Chauhan Date: Tue, 3 Oct 2023 16:15:06 +0530 Subject: [PATCH 05/10] fix lint --- subgraphs/friend-tech/src/common/getters.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/subgraphs/friend-tech/src/common/getters.ts b/subgraphs/friend-tech/src/common/getters.ts index 060e19689c..1f2d46e33b 100644 --- a/subgraphs/friend-tech/src/common/getters.ts +++ b/subgraphs/friend-tech/src/common/getters.ts @@ -11,7 +11,6 @@ import { PROTOCOL_NAME, PROTOCOL_SLUG, ProtocolType, - TradeType, } from "./constants"; import { getUsdPricePerEth } from "./prices"; import { Versions } from "../versions"; @@ -111,11 +110,9 @@ export function getOrCreateTrader( traderAddress: Address, event: ethereum.Event ): Trader { - let isNewTrader = false; let trader = Trader.load(traderAddress); if (!trader) { - isNewTrader = true; trader = new Trader(traderAddress); trader.cumulativeBuyVolumeETH = BIGINT_ZERO; From 69d55dd8dafd129d4754a97eceba835074722ebf Mon Sep 17 00:00:00 2001 From: Dhruv Chauhan Date: Wed, 4 Oct 2023 00:37:08 +0530 Subject: [PATCH 06/10] make protocol snapshots immutable --- subgraphs/friend-tech/schema.graphql | 26 +- subgraphs/friend-tech/src/common/events.ts | 2 +- subgraphs/friend-tech/src/common/getters.ts | 123 +------- subgraphs/friend-tech/src/common/metrics.ts | 3 +- subgraphs/friend-tech/src/common/prices.ts | 16 +- subgraphs/friend-tech/src/common/snapshots.ts | 282 +++++++++++------- subgraphs/friend-tech/src/common/types.ts | 7 +- subgraphs/friend-tech/src/common/utils.ts | 17 +- .../friend-tech/src/mappings/handlers.ts | 16 +- 9 files changed, 204 insertions(+), 288 deletions(-) diff --git a/subgraphs/friend-tech/schema.graphql b/subgraphs/friend-tech/schema.graphql index fee9bdc567..f032e48e53 100644 --- a/subgraphs/friend-tech/schema.graphql +++ b/subgraphs/friend-tech/schema.graphql @@ -159,18 +159,15 @@ type Protocol @entity @regularPolling { " Daily financial metrics for this protocol " financialMetrics: [FinancialsDailySnapshot!]! @derivedFrom(field: "protocol") - " Day ID of the most recent daily snapshot " - lastSnapshotDayID: Int! - - " Timestamp of the last time this entity was updated " - lastUpdateTimestamp: BigInt! + " Helper field for taking daily snapshots " + _lastDailySnapshotTimestamp: BigInt! } ############################### ##### Protocol Timeseries ##### ############################### -type UsageMetricsDailySnapshot @entity @dailySnapshot(immutable: true) { +type UsageMetricsDailySnapshot @entity(immutable: true) @dailySnapshot { " ID is # of days since Unix epoch time " id: Bytes! @@ -235,7 +232,7 @@ type UsageMetricsDailySnapshot @entity @dailySnapshot(immutable: true) { blockNumber: BigInt! } -type FinancialsDailySnapshot @entity @dailySnapshot(immutable: true) { +type FinancialsDailySnapshot @entity(immutable: true) @dailySnapshot { " ID is # of days since Unix epoch time " id: Bytes! @@ -446,7 +443,7 @@ type Connection @entity @regularPolling { ####### User Timeseries ####### ############################### -type TraderDailySnapshot @entity @dailySnapshot(immutable: true) { +type TraderDailySnapshot @entity @dailySnapshot { " {ID is # of days since Unix epoch time}-{Trader ID} " id: Bytes! @@ -519,7 +516,7 @@ type TraderDailySnapshot @entity @dailySnapshot(immutable: true) { blockNumber: BigInt! } -type SubjectDailySnapshot @entity @dailySnapshot(immutable: true) { +type SubjectDailySnapshot @entity @dailySnapshot { " {ID is # of days since Unix epoch time}-{Subject ID} " id: Bytes! @@ -607,7 +604,7 @@ type SubjectDailySnapshot @entity @dailySnapshot(immutable: true) { blockNumber: BigInt! } -type ConnectionDailySnapshot @entity @regularPolling(immutable: true) { +type ConnectionDailySnapshot @entity @regularPolling { " {Day ID}-{Trader ID}-{Subject ID} " id: Bytes! @@ -777,12 +774,3 @@ type _Account @entity @regularPolling { isSeller: Boolean! isSubject: Boolean! } - -# Helper entity for calculating daily active users -type _ActiveAccount @entity @regularPolling { - " { Address of the Account }-{ Days since Unix epoch } " - id: Bytes! - isActiveBuyer: Boolean! - isActiveSeller: Boolean! - isActiveSubject: Boolean! -} diff --git a/subgraphs/friend-tech/src/common/events.ts b/subgraphs/friend-tech/src/common/events.ts index cbcb48bf96..6d16cf06f6 100644 --- a/subgraphs/friend-tech/src/common/events.ts +++ b/subgraphs/friend-tech/src/common/events.ts @@ -1,6 +1,6 @@ import { Address, Bytes, BigInt, ethereum } from "@graphprotocol/graph-ts"; -import { getUsdPriceForEthAmount } from "./utils"; +import { getUsdPriceForEthAmount } from "./prices"; import { TradeType, ZERO_ADDRESS } from "./constants"; import { NetworkConfigs } from "../../configurations/configure"; diff --git a/subgraphs/friend-tech/src/common/getters.ts b/subgraphs/friend-tech/src/common/getters.ts index 1f2d46e33b..9af185f18e 100644 --- a/subgraphs/friend-tech/src/common/getters.ts +++ b/subgraphs/friend-tech/src/common/getters.ts @@ -15,22 +15,19 @@ import { import { getUsdPricePerEth } from "./prices"; import { Versions } from "../versions"; import { NetworkConfigs } from "../../configurations/configure"; -import { AccountResponse, ActiveAccountResponse } from "./types"; +import { AccountResponse } from "./types"; import { getDaysSinceEpoch } from "./utils"; import { _Account, - _ActiveAccount, Connection, ConnectionDailySnapshot, - FinancialsDailySnapshot, Protocol, Subject, SubjectDailySnapshot, Token, Trader, TraderDailySnapshot, - UsageMetricsDailySnapshot, } from "../../generated/schema"; export function getOrCreateProtocol(): Protocol { @@ -71,8 +68,7 @@ export function getOrCreateProtocol(): Protocol { protocol.cumulativeSellCount = INT_ZERO; protocol.cumulativeTradesCount = INT_ZERO; - protocol.lastSnapshotDayID = INT_ZERO; - protocol.lastUpdateTimestamp = BIGINT_ZERO; + protocol._lastDailySnapshotTimestamp = BIGINT_ZERO; } protocol.schemaVersion = Versions.getSchemaVersion(); @@ -228,121 +224,6 @@ export function getOrCreateAccount(accountAddress: Address): AccountResponse { return { account, isNewAccount }; } -export function getOrCreateActiveAccount( - accountAddress: Address, - day: i32 -): ActiveAccountResponse { - let isNewActiveAccount = false; - const id = Bytes.empty() - .concat(accountAddress) - .concat(Bytes.fromUTF8("-")) - .concat(Bytes.fromI32(day)); - - let activeAccount = _ActiveAccount.load(id); - if (!activeAccount) { - isNewActiveAccount = true; - activeAccount = new _ActiveAccount(id); - activeAccount.isActiveBuyer = false; - activeAccount.isActiveSeller = false; - activeAccount.isActiveSubject = false; - activeAccount.save(); - } - return { activeAccount, isNewActiveAccount }; -} - -export function getOrCreateUsageMetricsDailySnapshot( - event: ethereum.Event -): UsageMetricsDailySnapshot { - const day = getDaysSinceEpoch(event.block.timestamp.toI32()); - - let snapshot = UsageMetricsDailySnapshot.load(Bytes.fromI32(day)); - - if (!snapshot) { - snapshot = new UsageMetricsDailySnapshot(Bytes.fromI32(day)); - - snapshot.day = day; - snapshot.protocol = NetworkConfigs.getFactoryAddress(); - - snapshot.dailyActiveBuyers = INT_ZERO; - snapshot.cumulativeUniqueBuyers = INT_ZERO; - snapshot.dailyActiveSellers = INT_ZERO; - snapshot.cumulativeUniqueSellers = INT_ZERO; - snapshot.dailyActiveTraders = INT_ZERO; - snapshot.cumulativeUniqueTraders = INT_ZERO; - snapshot.dailyActiveSubjects = INT_ZERO; - snapshot.cumulativeUniqueSubjects = INT_ZERO; - snapshot.dailyActiveUsers = INT_ZERO; - snapshot.cumulativeUniqueUsers = INT_ZERO; - - snapshot.dailyBuyCount = INT_ZERO; - snapshot.cumulativeBuyCount = INT_ZERO; - snapshot.dailySellCount = INT_ZERO; - snapshot.cumulativeSellCount = INT_ZERO; - snapshot.dailyTradesCount = INT_ZERO; - snapshot.cumulativeTradesCount = INT_ZERO; - - snapshot.timestamp = event.block.timestamp; - snapshot.blockNumber = event.block.number; - - snapshot.save(); - } - return snapshot; -} - -export function getOrCreateFinancialsDailySnapshot( - event: ethereum.Event -): FinancialsDailySnapshot { - const day = getDaysSinceEpoch(event.block.timestamp.toI32()); - - let snapshot = FinancialsDailySnapshot.load(Bytes.fromI32(day)); - - if (!snapshot) { - snapshot = new FinancialsDailySnapshot(Bytes.fromI32(day)); - - snapshot.day = day; - snapshot.protocol = NetworkConfigs.getFactoryAddress(); - - snapshot.totalValueLockedETH = BIGINT_ZERO; - snapshot.totalValueLockedUSD = BIGDECIMAL_ZERO; - - snapshot.dailySupplySideRevenueETH = BIGINT_ZERO; - snapshot.cumulativeSupplySideRevenueETH = BIGINT_ZERO; - snapshot.dailySupplySideRevenueUSD = BIGDECIMAL_ZERO; - snapshot.cumulativeSupplySideRevenueUSD = BIGDECIMAL_ZERO; - snapshot.dailyProtocolSideRevenueETH = BIGINT_ZERO; - snapshot.cumulativeProtocolSideRevenueETH = BIGINT_ZERO; - snapshot.dailyProtocolSideRevenueUSD = BIGDECIMAL_ZERO; - snapshot.cumulativeProtocolSideRevenueUSD = BIGDECIMAL_ZERO; - snapshot.dailyTotalRevenueETH = BIGINT_ZERO; - snapshot.cumulativeTotalRevenueETH = BIGINT_ZERO; - snapshot.dailyTotalRevenueUSD = BIGDECIMAL_ZERO; - snapshot.cumulativeTotalRevenueUSD = BIGDECIMAL_ZERO; - - snapshot.dailyBuyVolumeETH = BIGINT_ZERO; - snapshot.cumulativeBuyVolumeETH = BIGINT_ZERO; - snapshot.dailyBuyVolumeUSD = BIGDECIMAL_ZERO; - snapshot.cumulativeBuyVolumeUSD = BIGDECIMAL_ZERO; - snapshot.dailySellVolumeETH = BIGINT_ZERO; - snapshot.cumulativeSellVolumeETH = BIGINT_ZERO; - snapshot.dailySellVolumeUSD = BIGDECIMAL_ZERO; - snapshot.cumulativeSellVolumeUSD = BIGDECIMAL_ZERO; - snapshot.dailyTotalVolumeETH = BIGINT_ZERO; - snapshot.cumulativeTotalVolumeETH = BIGINT_ZERO; - snapshot.dailyTotalVolumeUSD = BIGDECIMAL_ZERO; - snapshot.cumulativeTotalVolumeUSD = BIGDECIMAL_ZERO; - snapshot.dailyNetVolumeETH = BIGINT_ZERO; - snapshot.netVolumeETH = BIGINT_ZERO; - snapshot.dailyNetVolumeUSD = BIGDECIMAL_ZERO; - snapshot.netVolumeUSD = BIGDECIMAL_ZERO; - - snapshot.timestamp = event.block.timestamp; - snapshot.blockNumber = event.block.number; - - snapshot.save(); - } - return snapshot; -} - export function getOrCreateTraderDailySnapshot( traderAddress: Address, event: ethereum.Event diff --git a/subgraphs/friend-tech/src/common/metrics.ts b/subgraphs/friend-tech/src/common/metrics.ts index d56bd7158d..41d22a0802 100644 --- a/subgraphs/friend-tech/src/common/metrics.ts +++ b/subgraphs/friend-tech/src/common/metrics.ts @@ -8,7 +8,8 @@ import { getOrCreateConnection, } from "./getters"; import { INT_ONE } from "./constants"; -import { addToArrayAtIndex, getUsdPriceForEthAmount } from "./utils"; +import { addToArrayAtIndex } from "./utils"; +import { getUsdPriceForEthAmount } from "./prices"; export function updateTVL( amountETH: BigInt, diff --git a/subgraphs/friend-tech/src/common/prices.ts b/subgraphs/friend-tech/src/common/prices.ts index ff6da58b8e..80f12974a9 100644 --- a/subgraphs/friend-tech/src/common/prices.ts +++ b/subgraphs/friend-tech/src/common/prices.ts @@ -1,10 +1,12 @@ -import { Address, BigDecimal } from "@graphprotocol/graph-ts"; +import { Address, BigDecimal, BigInt, ethereum } from "@graphprotocol/graph-ts"; import { BIGDECIMAL_ZERO, BIGINT_TEN, CHAINLINK_AGGREGATOR_ETH_USD, + ETH_DECIMALS, } from "./constants"; +import { getOrCreateEthToken } from "./getters"; import { ChainLinkAggregator } from "../../generated/Shares/ChainLinkAggregator"; @@ -26,3 +28,15 @@ export function getUsdPricePerEth(): BigDecimal { .toBigDecimal() .div(BIGINT_TEN.pow(decimalsCall.value as u8).toBigDecimal()); } + +export function getUsdPriceForEthAmount( + amount: BigInt, + event: ethereum.Event +): BigDecimal { + const eth = getOrCreateEthToken(event); + + return amount + .toBigDecimal() + .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) + .times(eth.lastPriceUSD!); +} diff --git a/subgraphs/friend-tech/src/common/snapshots.ts b/subgraphs/friend-tech/src/common/snapshots.ts index cbaab65535..cf4bcddf5a 100644 --- a/subgraphs/friend-tech/src/common/snapshots.ts +++ b/subgraphs/friend-tech/src/common/snapshots.ts @@ -1,141 +1,104 @@ -import { Address, BigInt, ethereum } from "@graphprotocol/graph-ts"; +import { Address, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts"; import { - getOrCreateActiveAccount, getOrCreateConnection, getOrCreateConnectionDailySnapshot, - getOrCreateFinancialsDailySnapshot, getOrCreateProtocol, getOrCreateSubject, getOrCreateSubjectDailySnapshot, getOrCreateTrader, getOrCreateTraderDailySnapshot, - getOrCreateUsageMetricsDailySnapshot, } from "./getters"; -import { INT_ONE } from "./constants"; +import { INT_ONE, SECONDS_PER_DAY } from "./constants"; +import { addToArrayAtIndex, getDaysSinceEpoch } from "./utils"; +import { getUsdPriceForEthAmount } from "./prices"; + import { - addToArrayAtIndex, - getDaysSinceEpoch, - getUsdPriceForEthAmount, -} from "./utils"; + FinancialsDailySnapshot, + Protocol, + UsageMetricsDailySnapshot, +} from "../../generated/schema"; -export function updateUsageMetricsDailySnapshot( - traderAddress: Address, - subjectAddress: Address, - isBuy: boolean, +export function takeUsageMetricsDailySnapshot( + protocol: Protocol, event: ethereum.Event ): void { - const protocol = getOrCreateProtocol(); - const snapshot = getOrCreateUsageMetricsDailySnapshot(event); - const day = getDaysSinceEpoch(event.block.timestamp.toI32()); + const snapshot = new UsageMetricsDailySnapshot(Bytes.fromI32(day)); - const activeSubject = getOrCreateActiveAccount(subjectAddress, day); - if (activeSubject.isNewActiveAccount) { - snapshot.dailyActiveUsers += INT_ONE; - } - if (!activeSubject.activeAccount.isActiveSubject) { - snapshot.dailyActiveSubjects += INT_ONE; - activeSubject.activeAccount.isActiveSubject = true; - } - activeSubject.activeAccount.save(); - - const activeTrader = getOrCreateActiveAccount(traderAddress, day); - if (activeTrader.isNewActiveAccount) { - snapshot.dailyActiveUsers += INT_ONE; - } - if ( - !activeTrader.activeAccount.isActiveBuyer && - !activeTrader.activeAccount.isActiveSeller - ) { - snapshot.dailyActiveTraders += INT_ONE; - } - if (isBuy) { - if (!activeTrader.activeAccount.isActiveBuyer) { - snapshot.dailyActiveBuyers += INT_ONE; - activeTrader.activeAccount.isActiveBuyer = true; - } - snapshot.dailyBuyCount += INT_ONE; - } else { - if (!activeTrader.activeAccount.isActiveSeller) { - snapshot.dailyActiveSellers += INT_ONE; - activeTrader.activeAccount.isActiveSeller = true; - } - snapshot.dailySellCount += INT_ONE; - } - activeTrader.activeAccount.save(); - - snapshot.dailyTradesCount += INT_ONE; + snapshot.day = day; + snapshot.protocol = protocol.id; + snapshot.blockNumber = event.block.number; + snapshot.timestamp = event.block.timestamp; snapshot.cumulativeUniqueBuyers = protocol.cumulativeUniqueBuyers; snapshot.cumulativeUniqueSellers = protocol.cumulativeUniqueSellers; snapshot.cumulativeUniqueTraders = protocol.cumulativeUniqueTraders; snapshot.cumulativeUniqueSubjects = protocol.cumulativeUniqueSubjects; snapshot.cumulativeUniqueUsers = protocol.cumulativeUniqueUsers; - snapshot.cumulativeBuyCount = protocol.cumulativeBuyCount; snapshot.cumulativeSellCount = protocol.cumulativeSellCount; snapshot.cumulativeTradesCount = protocol.cumulativeTradesCount; - snapshot.blockNumber = event.block.number; - snapshot.timestamp = event.block.timestamp; - - protocol.lastSnapshotDayID = day; - protocol.lastUpdateTimestamp = event.block.timestamp; + let activeBuyersDelta = snapshot.cumulativeUniqueBuyers; + let activeSellersDelta = snapshot.cumulativeUniqueSellers; + let activeTradersDelta = snapshot.cumulativeUniqueTraders; + let activeSubjectsDelta = snapshot.cumulativeUniqueSubjects; + let activeUsersDelta = snapshot.cumulativeUniqueUsers; + let buyCountDelta = snapshot.cumulativeBuyCount; + let sellCountDelta = snapshot.cumulativeSellCount; + let tradesCountDelta = snapshot.cumulativeTradesCount; + + const previousDay = getDaysSinceEpoch( + protocol._lastDailySnapshotTimestamp!.toI32() + ); + const previousSnapshot = UsageMetricsDailySnapshot.load( + Bytes.fromI32(previousDay) + ); + if (previousSnapshot) { + activeBuyersDelta = + snapshot.cumulativeUniqueBuyers - previousSnapshot.cumulativeUniqueBuyers; + activeSellersDelta = + snapshot.cumulativeUniqueSellers - + previousSnapshot.cumulativeUniqueSellers; + activeTradersDelta = + snapshot.cumulativeUniqueTraders - + previousSnapshot.cumulativeUniqueTraders; + activeSubjectsDelta = + snapshot.cumulativeUniqueSubjects - + previousSnapshot.cumulativeUniqueSubjects; + activeUsersDelta = + snapshot.cumulativeUniqueUsers - previousSnapshot.cumulativeUniqueUsers; + buyCountDelta = + snapshot.cumulativeBuyCount - previousSnapshot.cumulativeBuyCount; + sellCountDelta = + snapshot.cumulativeSellCount - previousSnapshot.cumulativeSellCount; + tradesCountDelta = + snapshot.cumulativeTradesCount - previousSnapshot.cumulativeTradesCount; + } + snapshot.dailyActiveBuyers = activeBuyersDelta; + snapshot.dailyActiveSellers = activeSellersDelta; + snapshot.dailyActiveTraders = activeTradersDelta; + snapshot.dailyActiveSubjects = activeSubjectsDelta; + snapshot.dailyActiveUsers = activeUsersDelta; + snapshot.dailyBuyCount = buyCountDelta; + snapshot.dailySellCount = sellCountDelta; + snapshot.dailyTradesCount = tradesCountDelta; snapshot.save(); - protocol.save(); } -export function updateFinancialsDailySnapshot( - amountETH: BigInt, - subjectFeeETH: BigInt, - protocolFeeETH: BigInt, - isBuy: boolean, +export function takeFinancialsDailySnapshot( + protocol: Protocol, event: ethereum.Event ): void { - const protocol = getOrCreateProtocol(); - const snapshot = getOrCreateFinancialsDailySnapshot(event); - - const amountUSD = getUsdPriceForEthAmount(amountETH, event); - const subjectFeeUSD = getUsdPriceForEthAmount(subjectFeeETH, event); - const protocolFeeUSD = getUsdPriceForEthAmount(protocolFeeETH, event); - - snapshot.dailySupplySideRevenueETH = - snapshot.dailySupplySideRevenueETH.plus(subjectFeeETH); - snapshot.dailySupplySideRevenueUSD = - snapshot.dailySupplySideRevenueUSD.plus(subjectFeeUSD); - snapshot.dailyProtocolSideRevenueETH = - snapshot.dailyProtocolSideRevenueETH.plus(protocolFeeETH); - snapshot.dailyProtocolSideRevenueUSD = - snapshot.dailyProtocolSideRevenueUSD.plus(protocolFeeUSD); - snapshot.dailyTotalRevenueETH = snapshot.dailyTotalRevenueETH.plus( - subjectFeeETH.plus(protocolFeeETH) - ); - snapshot.dailyTotalRevenueUSD = snapshot.dailyTotalRevenueUSD.plus( - subjectFeeUSD.plus(protocolFeeUSD) - ); - - if (isBuy) { - snapshot.dailyBuyVolumeETH = snapshot.dailyBuyVolumeETH.plus(amountETH); - snapshot.dailyBuyVolumeUSD = snapshot.dailyBuyVolumeUSD.plus(amountUSD); - } else { - snapshot.dailySellVolumeETH = snapshot.dailySellVolumeETH.plus(amountETH); - snapshot.dailySellVolumeUSD = snapshot.dailySellVolumeUSD.plus(amountUSD); - } + const day = getDaysSinceEpoch(event.block.timestamp.toI32()); + const snapshot = new FinancialsDailySnapshot(Bytes.fromI32(day)); - snapshot.dailyTotalVolumeETH = snapshot.dailyBuyVolumeETH.plus( - snapshot.dailySellVolumeETH - ); - snapshot.dailyTotalVolumeUSD = snapshot.dailyBuyVolumeUSD.plus( - snapshot.dailySellVolumeUSD - ); - snapshot.dailyNetVolumeETH = snapshot.dailyBuyVolumeETH.minus( - snapshot.dailySellVolumeETH - ); - snapshot.dailyNetVolumeUSD = snapshot.dailyBuyVolumeUSD.minus( - snapshot.dailySellVolumeUSD - ); + snapshot.day = day; + snapshot.protocol = protocol.id; + snapshot.blockNumber = event.block.number; + snapshot.timestamp = event.block.timestamp; snapshot.totalValueLockedETH = protocol.totalValueLockedETH; snapshot.totalValueLockedUSD = protocol.totalValueLockedUSD; @@ -158,12 +121,106 @@ export function updateFinancialsDailySnapshot( snapshot.netVolumeETH = protocol.netVolumeETH; snapshot.netVolumeUSD = protocol.netVolumeUSD; - snapshot.blockNumber = event.block.number; - snapshot.timestamp = event.block.timestamp; + let supplySideRevenueETHDelta = snapshot.cumulativeSupplySideRevenueETH; + let supplySideRevenueUSDDelta = snapshot.cumulativeSupplySideRevenueUSD; + let protocolSideRevenueETHDelta = snapshot.cumulativeProtocolSideRevenueETH; + let protocolSideRevenueUSDDelta = snapshot.cumulativeProtocolSideRevenueUSD; + let totalRevenueETHDelta = snapshot.cumulativeTotalRevenueETH; + let totalRevenueUSDDelta = snapshot.cumulativeTotalRevenueUSD; + let buyVolumeETHDelta = snapshot.cumulativeBuyVolumeETH; + let buyVolumeUSDDelta = snapshot.cumulativeBuyVolumeUSD; + let sellVolumeETHDelta = snapshot.cumulativeSellVolumeETH; + let sellVolumeUSDDelta = snapshot.cumulativeSellVolumeUSD; + let totalVolumeETHDelta = snapshot.cumulativeTotalVolumeETH; + let totalVolumeUSDDelta = snapshot.cumulativeTotalVolumeUSD; + let netVolumeETHDelta = snapshot.netVolumeETH; + let netVolumeUSDDelta = snapshot.netVolumeUSD; + + const previousDay = getDaysSinceEpoch( + protocol._lastDailySnapshotTimestamp!.toI32() + ); + const previousSnapshot = FinancialsDailySnapshot.load( + Bytes.fromI32(previousDay) + ); + if (previousSnapshot) { + supplySideRevenueETHDelta = snapshot.cumulativeSupplySideRevenueETH.minus( + previousSnapshot.cumulativeSupplySideRevenueETH + ); + supplySideRevenueUSDDelta = snapshot.cumulativeSupplySideRevenueUSD.minus( + previousSnapshot.cumulativeSupplySideRevenueUSD + ); + protocolSideRevenueETHDelta = + snapshot.cumulativeProtocolSideRevenueETH.minus( + previousSnapshot.cumulativeProtocolSideRevenueETH + ); + protocolSideRevenueUSDDelta = + snapshot.cumulativeProtocolSideRevenueUSD.minus( + previousSnapshot.cumulativeProtocolSideRevenueUSD + ); + totalRevenueETHDelta = snapshot.cumulativeTotalRevenueETH.minus( + previousSnapshot.cumulativeTotalRevenueETH + ); + totalRevenueUSDDelta = snapshot.cumulativeTotalRevenueUSD.minus( + previousSnapshot.cumulativeTotalRevenueUSD + ); + buyVolumeETHDelta = snapshot.cumulativeBuyVolumeETH.minus( + previousSnapshot.cumulativeBuyVolumeETH + ); + buyVolumeUSDDelta = snapshot.cumulativeBuyVolumeUSD.minus( + previousSnapshot.cumulativeBuyVolumeUSD + ); + sellVolumeETHDelta = snapshot.cumulativeSellVolumeETH.minus( + previousSnapshot.cumulativeSellVolumeETH + ); + sellVolumeUSDDelta = snapshot.cumulativeSellVolumeUSD.minus( + previousSnapshot.cumulativeSellVolumeUSD + ); + totalVolumeETHDelta = snapshot.cumulativeTotalVolumeETH.minus( + previousSnapshot.cumulativeTotalVolumeETH + ); + totalVolumeUSDDelta = snapshot.cumulativeTotalVolumeUSD.minus( + previousSnapshot.cumulativeTotalVolumeUSD + ); + netVolumeETHDelta = snapshot.netVolumeETH.minus( + previousSnapshot.netVolumeETH + ); + netVolumeUSDDelta = snapshot.netVolumeUSD.minus( + previousSnapshot.netVolumeUSD + ); + } + snapshot.dailySupplySideRevenueETH = supplySideRevenueETHDelta; + snapshot.dailySupplySideRevenueUSD = supplySideRevenueUSDDelta; + snapshot.dailyProtocolSideRevenueETH = protocolSideRevenueETHDelta; + snapshot.dailyProtocolSideRevenueUSD = protocolSideRevenueUSDDelta; + snapshot.dailyTotalRevenueETH = totalRevenueETHDelta; + snapshot.dailyTotalRevenueUSD = totalRevenueUSDDelta; + snapshot.dailyBuyVolumeETH = buyVolumeETHDelta; + snapshot.dailyBuyVolumeUSD = buyVolumeUSDDelta; + snapshot.dailySellVolumeETH = sellVolumeETHDelta; + snapshot.dailySellVolumeUSD = sellVolumeUSDDelta; + snapshot.dailyTotalVolumeETH = totalVolumeETHDelta; + snapshot.dailyTotalVolumeUSD = totalVolumeUSDDelta; + snapshot.dailyNetVolumeETH = netVolumeETHDelta; + snapshot.dailyNetVolumeUSD = netVolumeUSDDelta; snapshot.save(); } +export function updateProtocolSnapshots(event: ethereum.Event): void { + const protocol = getOrCreateProtocol(); + if ( + protocol._lastDailySnapshotTimestamp + .plus(BigInt.fromI32(SECONDS_PER_DAY)) + .lt(event.block.timestamp) + ) { + takeUsageMetricsDailySnapshot(protocol, event); + takeFinancialsDailySnapshot(protocol, event); + + protocol._lastDailySnapshotTimestamp = event.block.timestamp; + protocol.save(); + } +} + export function updateTraderDailySnapshot( traderAddress: Address, amountETH: BigInt, @@ -290,12 +347,6 @@ export function updateConnectionDailySnapshot( isBuy: boolean, event: ethereum.Event ): void { - const traderSnapshot = getOrCreateTraderDailySnapshot(traderAddress, event); - const subjectSnapshot = getOrCreateSubjectDailySnapshot( - subjectAddress, - event - ); - const connection = getOrCreateConnection( traderAddress, subjectAddress, @@ -351,6 +402,7 @@ export function updateConnectionDailySnapshot( snapshot.save(); + const traderSnapshot = getOrCreateTraderDailySnapshot(traderAddress, event); if (!traderSnapshot.connections.includes(snapshot.id)) { traderSnapshot.connections = addToArrayAtIndex( traderSnapshot.connections, @@ -359,6 +411,10 @@ export function updateConnectionDailySnapshot( } traderSnapshot.save(); + const subjectSnapshot = getOrCreateSubjectDailySnapshot( + subjectAddress, + event + ); if (!subjectSnapshot.connections.includes(snapshot.id)) { subjectSnapshot.connections = addToArrayAtIndex( subjectSnapshot.connections, diff --git a/subgraphs/friend-tech/src/common/types.ts b/subgraphs/friend-tech/src/common/types.ts index 10fd5aecbd..515160c65c 100644 --- a/subgraphs/friend-tech/src/common/types.ts +++ b/subgraphs/friend-tech/src/common/types.ts @@ -1,11 +1,6 @@ -import { _Account, _ActiveAccount } from "../../generated/schema"; +import { _Account } from "../../generated/schema"; export class AccountResponse { account: _Account; isNewAccount: boolean; } - -export class ActiveAccountResponse { - activeAccount: _ActiveAccount; - isNewActiveAccount: boolean; -} diff --git a/subgraphs/friend-tech/src/common/utils.ts b/subgraphs/friend-tech/src/common/utils.ts index a4bc88a3be..0b8f8560a7 100644 --- a/subgraphs/friend-tech/src/common/utils.ts +++ b/subgraphs/friend-tech/src/common/utils.ts @@ -1,7 +1,4 @@ -import { BigDecimal, BigInt, ethereum } from "@graphprotocol/graph-ts"; - -import { BIGINT_TEN, ETH_DECIMALS, SECONDS_PER_DAY } from "./constants"; -import { getOrCreateEthToken } from "./getters"; +import { SECONDS_PER_DAY } from "./constants"; export function addToArrayAtIndex(x: T[], item: T, index: i32 = -1): T[] { if (x.length == 0) { @@ -27,15 +24,3 @@ export function addToArrayAtIndex(x: T[], item: T, index: i32 = -1): T[] { export function getDaysSinceEpoch(secondsSinceEpoch: number): i32 { return Math.floor(secondsSinceEpoch / SECONDS_PER_DAY); } - -export function getUsdPriceForEthAmount( - amount: BigInt, - event: ethereum.Event -): BigDecimal { - const eth = getOrCreateEthToken(event); - - return amount - .toBigDecimal() - .div(BIGINT_TEN.pow(ETH_DECIMALS as u8).toBigDecimal()) - .times(eth.lastPriceUSD!); -} diff --git a/subgraphs/friend-tech/src/mappings/handlers.ts b/subgraphs/friend-tech/src/mappings/handlers.ts index 5d89fc9b74..cc37a2f347 100644 --- a/subgraphs/friend-tech/src/mappings/handlers.ts +++ b/subgraphs/friend-tech/src/mappings/handlers.ts @@ -1,3 +1,5 @@ +import { BigInt } from "@graphprotocol/graph-ts"; + import { updateConnections, updateRevenue, @@ -8,12 +10,13 @@ import { } from "../common/metrics"; import { updateConnectionDailySnapshot, - updateFinancialsDailySnapshot, + updateProtocolSnapshots, updateSubjectDailySnapshot, updateTraderDailySnapshot, - updateUsageMetricsDailySnapshot, } from "../common/snapshots"; import { createEvent } from "../common/events"; +import { getOrCreateProtocol } from "../common/getters"; +import { SECONDS_PER_DAY } from "../common/constants"; import { Trade } from "../../generated/Shares/Shares"; @@ -38,14 +41,7 @@ export function handleTrade(event: Trade): void { updateConnections(trader, subject, shares, sharePriceETH, isBuy, event); updateSubjectPrice(subject, supply, tradeAmountETH, event); - updateUsageMetricsDailySnapshot(trader, subject, isBuy, event); - updateFinancialsDailySnapshot( - sharePriceETH, - subjectFeeETH, - protocolFeeETH, - isBuy, - event - ); + updateProtocolSnapshots(event); updateTraderDailySnapshot(trader, sharePriceETH, isBuy, event); updateSubjectDailySnapshot( subject, From 7eeaeb6e7d581b71a2f4458243e4900a4689b96f Mon Sep 17 00:00:00 2001 From: Dhruv Chauhan Date: Wed, 4 Oct 2023 00:40:02 +0530 Subject: [PATCH 07/10] fix lint --- subgraphs/friend-tech/src/mappings/handlers.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/subgraphs/friend-tech/src/mappings/handlers.ts b/subgraphs/friend-tech/src/mappings/handlers.ts index cc37a2f347..88e882cc62 100644 --- a/subgraphs/friend-tech/src/mappings/handlers.ts +++ b/subgraphs/friend-tech/src/mappings/handlers.ts @@ -1,5 +1,3 @@ -import { BigInt } from "@graphprotocol/graph-ts"; - import { updateConnections, updateRevenue, @@ -15,8 +13,6 @@ import { updateTraderDailySnapshot, } from "../common/snapshots"; import { createEvent } from "../common/events"; -import { getOrCreateProtocol } from "../common/getters"; -import { SECONDS_PER_DAY } from "../common/constants"; import { Trade } from "../../generated/Shares/Shares"; From 193c970bbb09811807f356fb88b28b16fc501560 Mon Sep 17 00:00:00 2001 From: Dhruv Chauhan Date: Tue, 31 Oct 2023 12:29:37 +0530 Subject: [PATCH 08/10] move to generic-based schema --- deployment/deployment.json | 2 +- subgraphs/friend-tech/README.md | 2 +- .../templates/friend.tech.template.yaml | 2 +- subgraphs/friend-tech/schema.graphql | 672 ++++++++++-------- subgraphs/friend-tech/src/common/constants.ts | 2 +- subgraphs/friend-tech/src/common/events.ts | 51 +- subgraphs/friend-tech/src/common/getters.ts | 372 +++------- subgraphs/friend-tech/src/common/metrics.ts | 347 ++++----- subgraphs/friend-tech/src/common/prices.ts | 4 +- subgraphs/friend-tech/src/common/snapshots.ts | 492 ++++++------- subgraphs/friend-tech/src/common/utils.ts | 20 +- .../friend-tech/src/mappings/handlers.ts | 86 ++- 12 files changed, 934 insertions(+), 1118 deletions(-) diff --git a/deployment/deployment.json b/deployment/deployment.json index 1c817b9b25..83bd38114d 100644 --- a/deployment/deployment.json +++ b/deployment/deployment.json @@ -9760,7 +9760,7 @@ } }, "friend-tech": { - "schema": "non-standard", + "schema": "generic", "base": "friend-tech", "protocol": "friend-tech", "project": "friend-tech", diff --git a/subgraphs/friend-tech/README.md b/subgraphs/friend-tech/README.md index 13119e16bf..1c9a4a69fc 100644 --- a/subgraphs/friend-tech/README.md +++ b/subgraphs/friend-tech/README.md @@ -1,6 +1,6 @@ # Friend Tech Protocol Subgraph Metrics Methodology v1.0.0 -friend-tech subgraph based on a non-standard schema. +friend-tech subgraph based on a non-standard schema - (derived from generic schema v2.1.1). ## Business Summary diff --git a/subgraphs/friend-tech/protocols/friend-tech/config/templates/friend.tech.template.yaml b/subgraphs/friend-tech/protocols/friend-tech/config/templates/friend.tech.template.yaml index c42404f9fa..009cd78ba3 100644 --- a/subgraphs/friend-tech/protocols/friend-tech/config/templates/friend.tech.template.yaml +++ b/subgraphs/friend-tech/protocols/friend-tech/config/templates/friend.tech.template.yaml @@ -1,4 +1,4 @@ -specVersion: 0.0.4 +specVersion: 0.0.6 schema: file: ./schema.graphql {{#graftEnabled}} diff --git a/subgraphs/friend-tech/schema.graphql b/subgraphs/friend-tech/schema.graphql index f032e48e53..2e0ac42bcf 100644 --- a/subgraphs/friend-tech/schema.graphql +++ b/subgraphs/friend-tech/schema.graphql @@ -1,5 +1,6 @@ # Subgraph Schema: Non-Standard # Version: 1.0.0 +# (Based on Subgraph Schema: Generic - Version: 2.1.1) # See https://github.com/messari/subgraphs/blob/master/docs/SCHEMA.md for details enum Network { @@ -33,7 +34,6 @@ enum ProtocolType { YIELD BRIDGE GENERIC - SOCIAL # Will add more } @@ -62,6 +62,25 @@ type Token @entity @regularPolling { lastPriceBlockNumber: BigInt } +enum RewardTokenType { + " For reward tokens awarded to LPs/lenders " + DEPOSIT + + " For reward tokens awarded to borrowers " + BORROW +} + +type RewardToken @entity @regularPolling { + " { Reward token type }-{ Smart contract address of the reward token } " + id: Bytes! + + " Reference to the actual token " + token: Token! + + " The type of the reward token " + type: RewardTokenType! +} + ############################# ##### Protocol Metadata ##### ############################# @@ -94,35 +113,30 @@ type Protocol @entity @regularPolling { ##### Quantitative Data ##### " Current TVL (Total Value Locked) of the entire protocol " - totalValueLockedETH: BigInt! totalValueLockedUSD: BigDecimal! + " Current PCV (Protocol Controlled Value). Only relevant for protocols with PCV. " + protocolControlledValueUSD: BigDecimal + " Revenue claimed by suppliers to the protocol. LPs on DEXs (e.g. 0.25% of the swap fee in Sushiswap). Depositors on Lending Protocols. NFT sellers on OpenSea. " - cumulativeSupplySideRevenueETH: BigInt! cumulativeSupplySideRevenueUSD: BigDecimal! " Gross revenue for the protocol (revenue claimed by protocol). Examples: AMM protocol fee (Sushi’s 0.05%). OpenSea 10% sell fee. " - cumulativeProtocolSideRevenueETH: BigInt! cumulativeProtocolSideRevenueUSD: BigDecimal! " All revenue generated by the protocol. e.g. 0.30% of swap fee in Sushiswap, all yield generated by Yearn. " - cumulativeTotalRevenueETH: BigInt! cumulativeTotalRevenueUSD: BigDecimal! " Cumulative value of shares bought " - cumulativeBuyVolumeETH: BigInt! cumulativeBuyVolumeUSD: BigDecimal! " Cumulative value of shares sold " - cumulativeSellVolumeETH: BigInt! cumulativeSellVolumeUSD: BigDecimal! " Volume bought plus volume sold " - cumulativeTotalVolumeETH: BigInt! cumulativeTotalVolumeUSD: BigDecimal! " Volume bought minus volume sold " - netVolumeETH: BigInt! netVolumeUSD: BigDecimal! ##### Usage Data ##### @@ -133,12 +147,6 @@ type Protocol @entity @regularPolling { " Number of cumulative unique addresses that sold shares " cumulativeUniqueSellers: Int! - " Number of cumulative unique addresses that bought or sold shares " - cumulativeUniqueTraders: Int! - - " Number of cumulative unique addresses that registered and minted their shares on the protocol " - cumulativeUniqueSubjects: Int! - " Number of cumulative unique addresses that interacted with the protocol " cumulativeUniqueUsers: Int! @@ -149,18 +157,34 @@ type Protocol @entity @regularPolling { cumulativeSellCount: Int! " Total number of trades " - cumulativeTradesCount: Int! + cumulativeTransactionCount: Int! + + ##### Pools ##### + + " Total number of Subjects " + totalPoolCount: Int! + + " All pools that belong to this protocol " + pools: [Pool!]! @derivedFrom(field: "protocol") ##### Snapshots ##### " Daily usage metrics for this protocol " - usageMetrics: [UsageMetricsDailySnapshot!]! @derivedFrom(field: "protocol") + dailyUsageMetrics: [UsageMetricsDailySnapshot!]! + @derivedFrom(field: "protocol") + + " Hourly usage metrics for this protocol " + hourlyUsageMetrics: [UsageMetricsHourlySnapshot!]! + @derivedFrom(field: "protocol") " Daily financial metrics for this protocol " financialMetrics: [FinancialsDailySnapshot!]! @derivedFrom(field: "protocol") " Helper field for taking daily snapshots " _lastDailySnapshotTimestamp: BigInt! + + " Helper field for taking hourly snapshots " + _lastHourlySnapshotTimestamp: BigInt! } ############################### @@ -189,18 +213,6 @@ type UsageMetricsDailySnapshot @entity(immutable: true) @dailySnapshot { " Number of cumulative unique sellers " cumulativeUniqueSellers: Int! - " Number of unique daily active traders " - dailyActiveTraders: Int! - - " Number of cumulative unique traders " - cumulativeUniqueTraders: Int! - - " Number of unique daily active subjects " - dailyActiveSubjects: Int! - - " Number of cumulative unique subjects " - cumulativeUniqueSubjects: Int! - " Number of unique daily active users " dailyActiveUsers: Int! @@ -220,10 +232,42 @@ type UsageMetricsDailySnapshot @entity(immutable: true) @dailySnapshot { cumulativeSellCount: Int! " Number of daily trades " - dailyTradesCount: Int! + dailyTransactionCount: Int! + + " Total number of trades " + cumulativeTransactionCount: Int! + + " Total number of pools " + totalPoolCount: Int! + + " Timestamp of when this snapshot was taken/last modified (May be taken after interval has passed) " + timestamp: BigInt! + + " Block number of when this snapshot was taken/last modified (May be taken after interval has passed) " + blockNumber: BigInt! +} + +type UsageMetricsHourlySnapshot @entity(immutable: true) @hourlySnapshot { + " ID is # of hours since Unix epoch time " + id: Bytes! + + " Number of hours since Unix epoch time " + hour: Int! + + " Protocol this snapshot is associated with " + protocol: Protocol! + + " Number of unique hourly active users " + hourlyActiveUsers: Int! + + " Number of cumulative unique users " + cumulativeUniqueUsers: Int! - " Number of cumulative trades " - cumulativeTradesCount: Int! + " Total number of transactions occurred in an hour. Transactions include all entities that implement the Event interface. " + hourlyTransactionCount: Int! + + " Total number of transactions. Transactions include events triggered by outside users (ie, deposit, withdraw, etc.)" + cumulativeTransactionCount: Int! " Timestamp of when this snapshot was taken/last modified (May be taken after interval has passed) " timestamp: BigInt! @@ -243,63 +287,51 @@ type FinancialsDailySnapshot @entity(immutable: true) @dailySnapshot { protocol: Protocol! " Current TVL (Total Value Locked) of the entire protocol " - totalValueLockedETH: BigInt! totalValueLockedUSD: BigDecimal! + " Current PCV (Protocol Controlled Value). Only relevant for protocols with PCV. " + protocolControlledValueUSD: BigDecimal + " Daily revenue claimed by suppliers to the protocol. LPs on DEXs (e.g. 0.25% of the swap fee in Sushiswap). Depositors on Lending Protocols. NFT sellers on OpenSea. " - dailySupplySideRevenueETH: BigInt! dailySupplySideRevenueUSD: BigDecimal! " Cumulative revenue claimed by suppliers to the protocol. LPs on DEXs (e.g. 0.25% of the swap fee in Sushiswap). Depositors on Lending Protocols. NFT sellers on OpenSea. " - cumulativeSupplySideRevenueETH: BigInt! cumulativeSupplySideRevenueUSD: BigDecimal! " Daily gross revenue for the protocol (revenue claimed by protocol). Examples: AMM protocol fee (Sushi’s 0.05%). OpenSea 10% sell fee. " - dailyProtocolSideRevenueETH: BigInt! dailyProtocolSideRevenueUSD: BigDecimal! " Cumulative gross revenue for the protocol (revenue claimed by protocol). Examples: AMM protocol fee (Sushi’s 0.05%). OpenSea 10% sell fee. " - cumulativeProtocolSideRevenueETH: BigInt! cumulativeProtocolSideRevenueUSD: BigDecimal! " Daily revenue generated by the protocol. e.g. 0.30% of swap fee in Sushiswap, all yield generated by Yearn. " - dailyTotalRevenueETH: BigInt! dailyTotalRevenueUSD: BigDecimal! " All revenue generated by the protocol. e.g. 0.30% of swap fee in Sushiswap, all yield generated by Yearn. " - cumulativeTotalRevenueETH: BigInt! cumulativeTotalRevenueUSD: BigDecimal! " Daily value of shares bought " - dailyBuyVolumeETH: BigInt! dailyBuyVolumeUSD: BigDecimal! " Cumulative value of shares bought " - cumulativeBuyVolumeETH: BigInt! cumulativeBuyVolumeUSD: BigDecimal! " Daily value of shares sold " - dailySellVolumeETH: BigInt! dailySellVolumeUSD: BigDecimal! " Cumulative value of shares sold " - cumulativeSellVolumeETH: BigInt! cumulativeSellVolumeUSD: BigDecimal! - " Daily volume bought minus daily volume sold " - dailyTotalVolumeETH: BigInt! + " Daily volume bought plus daily volume sold " dailyTotalVolumeUSD: BigDecimal! " Volume bought plus volume sold " - cumulativeTotalVolumeETH: BigInt! cumulativeTotalVolumeUSD: BigDecimal! " Daily volume bought minus daily volume sold " - dailyNetVolumeETH: BigInt! dailyNetVolumeUSD: BigDecimal! " Volume bought minus volume sold " - netVolumeETH: BigInt! netVolumeUSD: BigDecimal! " Timestamp of when this snapshot was taken/last modified (May be taken after interval has passed) " @@ -310,69 +342,89 @@ type FinancialsDailySnapshot @entity(immutable: true) @dailySnapshot { } ########################### -##### User-Level Data ##### +##### Pool-Level Data ##### ########################### -type Trader @entity @regularPolling { - " Address of the trader " +type Pool @entity @regularPolling { + " Address of the subject " id: Bytes! - " Cumulative value of shares bought by the trader " - cumulativeBuyVolumeETH: BigInt! - cumulativeBuyVolumeUSD: BigDecimal! + " The protocol this pool belongs to " + protocol: Protocol! - " Cumulative value of shares sold by the trader " - cumulativeSellVolumeETH: BigInt! - cumulativeSellVolumeUSD: BigDecimal! + " Name of the pool " + name: String - " Volume bought plus volume sold by the trader " - cumulativeTotalVolumeETH: BigInt! - cumulativeTotalVolumeUSD: BigDecimal! + " Symbol of liquidity pool " + symbol: String - " Volume bought minus volume sold by the trader " - netVolumeETH: BigInt! - netVolumeUSD: BigDecimal! + " Tokens that need to be deposited to take a position in protocol. e.g. WETH and USDC to deposit into the WETH-USDC pool. Array to account for multi-asset pools like Curve and Balancer " + inputTokens: [Token!]! - " Total number of buy trades by the trader " - cumulativeBuyCount: Int! + " Token that is minted to track ownership of position in protocol " + outputToken: Token - " Total number of sell trades by the trader " - cumulativeSellCount: Int! + " Aditional tokens that are given as reward for position in a protocol, usually in liquidity mining programs. e.g. SUSHI in the Onsen program, MATIC for Aave Polygon, usually in liquidity mining programs. e.g. SUSHI in the Onsen program, MATIC for Aave Polygon " + rewardTokens: [RewardToken!] - " Total number of trades by the trader " - cumulativeTradesCount: Int! + " Creation timestamp " + createdTimestamp: BigInt! - " Timestamp of when this trader first used the protocol " - registeredAt: BigInt! + " Creation block number " + createdBlockNumber: BigInt! - " Info about the connection between a trader and a subject " - connections: [Connection!]! -} + ##### Quantitative Data ##### -type Subject @entity @regularPolling { - " Address of the subject " - id: Bytes! + " Current TVL (Total Value Locked) of the pool " + totalValueLockedUSD: BigDecimal! + + " All revenue generated by the pool, accrued to the supply side. " + cumulativeSupplySideRevenueUSD: BigDecimal! - " All revenue generated by the subject " - cumulativeRevenueETH: BigInt! - cumulativeRevenueUSD: BigDecimal! + " All revenue generated by the pool, accrued to the protocol. " + cumulativeProtocolSideRevenueUSD: BigDecimal! + + " All revenue generated by the pool. " + cumulativeTotalRevenueUSD: BigDecimal! + + " Amount & Value of input tokens in the pool. The ordering should be the same as the pool's inputTokens field. " + inputTokenBalances: [BigInt!]! + inputTokenBalancesUSD: [BigDecimal!]! + + " Total supply of output token. Note that certain DEXes don't have an output token (e.g. Bancor) " + outputTokenSupply: BigInt + + " Price per share of output token in USD " + outputTokenPriceUSD: BigDecimal + + " Total supply of output tokens that are staked (usually in the MasterChef contract). Used to calculate reward APY. " + stakedOutputTokenAmount: BigInt + + " Per-block reward token emission as of the current block normalized to a day. This should be ideally calculated as the theoretical rate instead of the realized amount. " + rewardTokenEmissionsAmount: [BigInt!] + rewardTokenEmissionsUSD: [BigDecimal!] " Cumulative value bought of subject shares " - cumulativeBuyVolumeETH: BigInt! + cumulativeBuyVolumeAmount: BigInt! cumulativeBuyVolumeUSD: BigDecimal! " Cumulative value sold of subject shares " - cumulativeSellVolumeETH: BigInt! + cumulativeSellVolumeAmount: BigInt! cumulativeSellVolumeUSD: BigDecimal! " Volume bought plus volume sold of subject shares " - cumulativeTotalVolumeETH: BigInt! + cumulativeTotalVolumeAmount: BigInt! cumulativeTotalVolumeUSD: BigDecimal! " Volume bought minus volume sold of subject shares " - netVolumeETH: BigInt! + netVolumeAmount: BigInt! netVolumeUSD: BigDecimal! + ##### Usage Data ##### + + " Number of cumulative unique addresses that bought or sold subject shares " + cumulativeUniqueUsers: Int! + " Total number of buy trades of subject shares " cumulativeBuyCount: Int! @@ -380,302 +432,220 @@ type Subject @entity @regularPolling { cumulativeSellCount: Int! " Total number of trades of subject shares " - cumulativeTradesCount: Int! + cumulativeTransactionCount: Int! + + ##### Shares ##### " Total supply of subject shares " supply: BigInt! " Last price of subject shares " - sharePriceETH: BigInt! + sharePriceAmount: BigInt! sharePriceUSD: BigDecimal! - " Timestamp of when this subject first used the protocol " - registeredAt: BigInt! - - " Info about the connection between a trader and a subject " - connections: [Connection!]! -} - -type Connection @entity @regularPolling { - " {Trader ID}-{Subject ID} " - id: Bytes! - - " Trader and Subject between which this connection exists " - trader: Trader! - subject: Subject! - - " Number of subject shares held by the trader " - shares: BigInt! - - " Cumulative value of subject shares bought by the trader " - cumulativeBuyVolumeETH: BigInt! - cumulativeBuyVolumeUSD: BigDecimal! - - " Cumulative value of subject shares sold by the trader " - cumulativeSellVolumeETH: BigInt! - cumulativeSellVolumeUSD: BigDecimal! + ##### Connections ##### - " Volume bought plus volume sold of subject shares by the trader " - cumulativeTotalVolumeETH: BigInt! - cumulativeTotalVolumeUSD: BigDecimal! + " Traders that have bought subject shares " + traders: [Account!]! - " Volume bought minus volume sold of subject shares by the trader " - netVolumeETH: BigInt! - netVolumeUSD: BigDecimal! + " Info about the connection between a trader and a subject " + connections: [Connection!]! @derivedFrom(field: "subject") - " Total number of buy trades of subject shares by the trader " - cumulativeBuyCount: Int! + ##### Snapshots ##### - " Total number of sell trades of subject shares by the trader " - cumulativeSellCount: Int! + " Pool daily snapshots " + dailySnapshots: [PoolDailySnapshot!]! @derivedFrom(field: "pool") - " Total number of trades of subject shares by the trader " - cumulativeTradesCount: Int! + " Pool hourly snapshots " + hourlySnapshots: [PoolHourlySnapshot!]! @derivedFrom(field: "pool") - " Timestamp in which this connection is created or first time used " - createdTimestamp: BigInt! + " Helper field for taking daily snapshots " + _lastDailySnapshotTimestamp: BigInt! - " Block number in which this connection is created or first time used " - createdBlockNumber: BigInt! + " Helper field for taking hourly snapshots " + _lastHourlySnapshotTimestamp: BigInt! } ############################### -####### User Timeseries ####### +####### Pool Timeseries ####### ############################### -type TraderDailySnapshot @entity @dailySnapshot { - " {ID is # of days since Unix epoch time}-{Trader ID} " +type PoolDailySnapshot @entity(immutable: true) @dailySnapshot { + " { Smart contract address of the pool }-{ ID is # of days since Unix epoch time } " id: Bytes! " Number of days since Unix epoch time " day: Int! - " Protocol this snapshot is associated with " - protocol: Protocol! + " The pool this snapshot belongs to " + pool: Pool! - " Trader this snapshot is associated with " - trader: Trader! - - " Daily value of shares bought by the trader " - dailyBuyVolumeETH: BigInt! - dailyBuyVolumeUSD: BigDecimal! - - " Cumulative value of shares bought by the trader " - cumulativeBuyVolumeETH: BigInt! - cumulativeBuyVolumeUSD: BigDecimal! - - " Daily value of shares sold by the trader " - dailySellVolumeETH: BigInt! - dailySellVolumeUSD: BigDecimal! - - " Cumulative value of shares sold by the trader " - cumulativeSellVolumeETH: BigInt! - cumulativeSellVolumeUSD: BigDecimal! - - " Daily volume bought plus daily volume sold by the trader " - dailyTotalVolumeETH: BigInt! - dailyTotalVolumeUSD: BigDecimal! - - " Volume bought plus volume sold by the trader " - cumulativeTotalVolumeETH: BigInt! - cumulativeTotalVolumeUSD: BigDecimal! - - " Daily volume bought minus daily volume sold by the trader " - dailyNetVolumeETH: BigInt! - dailyNetVolumeUSD: BigDecimal! - - " Volume bought minus volume sold by the trader " - netVolumeETH: BigInt! - netVolumeUSD: BigDecimal! - - " Number of daily buy trades by the trader " - dailyBuyCount: Int! - - " Number of cumulative buy trades by the trader " - cumulativeBuyCount: Int! + " The protocol this snapshot belongs to " + protocol: Protocol! - " Number of daily sell trades by the trader " - dailySellCount: Int! + ##### Quantitative Data ##### - " Number of cumulative sell trades by the trader " - cumulativeSellCount: Int! + " Current TVL (Total Value Locked) of the pool " + totalValueLockedUSD: BigDecimal! - " Number of daily trades by the trader " - dailyTradesCount: Int! + " All revenue generated by the pool, accrued to the supply side. " + cumulativeSupplySideRevenueUSD: BigDecimal! - " Number of cumulative trades by the trader " - cumulativeTradesCount: Int! + " Daily revenue generated by the pool, accrued to the supply side. " + dailySupplySideRevenueUSD: BigDecimal! - " Info about the connection between a trader and a subject " - connections: [ConnectionDailySnapshot!]! + " All revenue generated by the pool, accrued to the protocol. " + cumulativeProtocolSideRevenueUSD: BigDecimal! - " Timestamp of when this snapshot was taken/last modified (May be taken after interval has passed) " - timestamp: BigInt! + " Daily revenue generated by the pool, accrued to the protocol. " + dailyProtocolSideRevenueUSD: BigDecimal! - " Block number of when this snapshot was taken/last modified (May be taken after interval has passed) " - blockNumber: BigInt! -} + " All revenue generated by the pool. " + cumulativeTotalRevenueUSD: BigDecimal! -type SubjectDailySnapshot @entity @dailySnapshot { - " {ID is # of days since Unix epoch time}-{Subject ID} " - id: Bytes! + " Daily revenue generated by the pool. " + dailyTotalRevenueUSD: BigDecimal! - " Number of days since Unix epoch time " - day: Int! + " Amount & Value of input tokens in the pool. The ordering should be the same as the pool's `inputTokens` field. " + inputTokenBalances: [BigInt!]! + inputTokenBalancesUSD: [BigDecimal!]! - " Protocol this snapshot is associated with " - protocol: Protocol! + " Total supply of output token. Note that certain DEXes don't have an output token (e.g. Bancor) " + outputTokenSupply: BigInt - " Subject this snapshot is associated with " - subject: Subject! + " Price per share of output token in USD " + outputTokenPriceUSD: BigDecimal - " Daily revenue generated by the subject " - dailyRevenueETH: BigInt! - dailyRevenueUSD: BigDecimal! + " Total supply of output tokens that are staked (usually in the MasterChef contract). Used to calculate reward APY. " + stakedOutputTokenAmount: BigInt - " All revenue generated by the subject " - cumulativeRevenueETH: BigInt! - cumulativeRevenueUSD: BigDecimal! + " Per-block reward token emission as of the current block normalized to a day. This should be ideally calculated as the theoretical rate instead of the realized amount. " + rewardTokenEmissionsAmount: [BigInt!] + rewardTokenEmissionsUSD: [BigDecimal!] - " Daily value bought of subject shares " - dailyBuyVolumeETH: BigInt! + " Daily value of shares bought " + dailyBuyVolumeAmount: BigInt! dailyBuyVolumeUSD: BigDecimal! - " Cumulative value bought of subject shares " - cumulativeBuyVolumeETH: BigInt! + " Cumulative value of shares bought " + cumulativeBuyVolumeAmount: BigInt! cumulativeBuyVolumeUSD: BigDecimal! - " Daily value sold of subject shares " - dailySellVolumeETH: BigInt! + " Daily value of shares sold " + dailySellVolumeAmount: BigInt! dailySellVolumeUSD: BigDecimal! - " Cumulative value sold of subject shares " - cumulativeSellVolumeETH: BigInt! + " Cumulative value of shares sold " + cumulativeSellVolumeAmount: BigInt! cumulativeSellVolumeUSD: BigDecimal! - " Daily volume bought plus daily volume sold of subject shares " - dailyTotalVolumeETH: BigInt! + " Daily volume bought plus daily volume sold " + dailyTotalVolumeAmount: BigInt! dailyTotalVolumeUSD: BigDecimal! - " Volume bought plus volume sold of subject shares " - cumulativeTotalVolumeETH: BigInt! + " Volume bought plus volume sold " + cumulativeTotalVolumeAmount: BigInt! cumulativeTotalVolumeUSD: BigDecimal! - " Daily volume bought minus daily volume sold of subject shares " - dailyNetVolumeETH: BigInt! + " Daily volume bought minus daily volume sold " + dailyNetVolumeAmount: BigInt! dailyNetVolumeUSD: BigDecimal! - " Volume bought minus volume sold of subject shares " - netVolumeETH: BigInt! + " Volume bought minus volume sold " + netVolumeAmount: BigInt! netVolumeUSD: BigDecimal! - " Daily number of buy trades of subject shares " + ##### Usage Data ##### + + " Number of unique daily active users " + dailyActiveUsers: Int! + + " Number of cumulative unique active users " + cumulativeUniqueUsers: Int! + + " Number of daily buy trades " dailyBuyCount: Int! - " Total number of buy trades of subject shares " + " Number of cumulative buy trades " cumulativeBuyCount: Int! - " Daily number of sell trades of subject shares " + " Number of daily sell trades " dailySellCount: Int! - " Total number of sell trades of subject shares " + " Number of cumulative sell trades " cumulativeSellCount: Int! - " Daily number of trades of subject shares " - dailyTradesCount: Int! - - " Total number of trades of subject shares " - cumulativeTradesCount: Int! - - " Total supply of subject shares " - supply: BigInt! - - " Last price of subject shares " - sharePriceETH: BigInt! - sharePriceUSD: BigDecimal! + " Number of daily trades " + dailyTransactionCount: Int! - " Info about the connection between a trader and a subject " - connections: [ConnectionDailySnapshot!]! + " Total number of trades " + cumulativeTransactionCount: Int! - " Timestamp of when this trader first used the protocol " + " Timestamp of when this snapshot was taken/last modified (May be taken after interval has passed) " timestamp: BigInt! - " Info about the connection between a trader and a subject " + " Block number of when this snapshot was taken/last modified (May be taken after interval has passed) " blockNumber: BigInt! } -type ConnectionDailySnapshot @entity @regularPolling { - " {Day ID}-{Trader ID}-{Subject ID} " +type PoolHourlySnapshot @entity(immutable: true) @hourlySnapshot { + " { Smart contract address of the pool }-{ ID is # of hours since Unix epoch time } " id: Bytes! - " Number of days since Unix epoch time " - day: Int! - - " Protocol this snapshot is associated with " - protocol: Protocol! - - " Trader and Subject between which this connection exists " - trader: Trader! - subject: Subject! + " Number of hours since Unix epoch time " + hour: Int! - " Number of subject shares held by the trader " - shares: BigInt! + " The pool this snapshot belongs to " + pool: Pool! - " Daily value of subject shares bought by the trader " - dailyBuyVolumeETH: BigInt! - dailyBuyVolumeUSD: BigDecimal! + " The protocol this snapshot belongs to " + protocol: Protocol! - " Cumulative value of subject shares bought by the trader " - cumulativeBuyVolumeETH: BigInt! - cumulativeBuyVolumeUSD: BigDecimal! + ##### Quantitative Data ##### - " Daily value of subject shares sold by the trader " - dailySellVolumeETH: BigInt! - dailySellVolumeUSD: BigDecimal! + " Current TVL (Total Value Locked) of this pool " + totalValueLockedUSD: BigDecimal! - " Cumulative value of subject shares sold by the trader " - cumulativeSellVolumeETH: BigInt! - cumulativeSellVolumeUSD: BigDecimal! + " All revenue generated by the pool, accrued to the supply side. " + cumulativeSupplySideRevenueUSD: BigDecimal! - " Daily volume bought plus daily volume sold of subject shares by the trader " - dailyTotalVolumeETH: BigInt! - dailyTotalVolumeUSD: BigDecimal! + " Hourly revenue generated by the pool, accrued to the supply side. " + hourlySupplySideRevenueUSD: BigDecimal! - " Volume bought plus volume sold of subject shares by the trader " - cumulativeTotalVolumeETH: BigInt! - cumulativeTotalVolumeUSD: BigDecimal! + " All revenue generated by the pool, accrued to the protocol. " + cumulativeProtocolSideRevenueUSD: BigDecimal! - " Daily volume bought minus daily volume sold of subject shares by the trader " - dailyNetVolumeETH: BigInt! - dailyNetVolumeUSD: BigDecimal! + " Hourly revenue generated by the pool, accrued to the protocol. " + hourlyProtocolSideRevenueUSD: BigDecimal! - " Volume bought minus volume sold of subject shares by the trader " - netVolumeETH: BigInt! - netVolumeUSD: BigDecimal! + " All revenue generated by the pool. " + cumulativeTotalRevenueUSD: BigDecimal! - " Daily number of buy trades of subject shares by the trader " - dailyBuyCount: Int! + " Hourly revenue generated by the pool. " + hourlyTotalRevenueUSD: BigDecimal! - " Total number of buy trades of subject shares by the trader " - cumulativeBuyCount: Int! + " Amount & Value of input tokens in the pool. The ordering should be the same as the pool's `inputTokens` field. " + inputTokenBalances: [BigInt!]! + inputTokenBalancesUSD: [BigDecimal!]! - " Daily number of sell trades of subject shares by the trader " - dailySellCount: Int! + " Total supply of output token. Note that certain DEXes don't have an output token (e.g. Bancor) " + outputTokenSupply: BigInt - " Total number of sell trades of subject shares by the trader " - cumulativeSellCount: Int! + " Price per share of output token in USD " + outputTokenPriceUSD: BigDecimal - " Daily number of trades of subject shares by the trader " - dailyTradesCount: Int! + " Total supply of output tokens that are staked (usually in the MasterChef contract). Used to calculate reward APY. " + stakedOutputTokenAmount: BigInt - " Total number of trades of subject shares by the trader " - cumulativeTradesCount: Int! + " Per-block reward token emission as of the current block normalized to a day (not hour). This should be ideally calculated as the theoretical rate instead of the realized amount. " + rewardTokenEmissionsAmount: [BigInt!] + rewardTokenEmissionsUSD: [BigDecimal!] - " Timestamp in which this route is created or first time used " - createdTimestamp: BigInt! + " Timestamp of when this snapshot was taken/last modified (May be taken after interval has passed) " + timestamp: BigInt! - " Block number in which this route is created or first time used " - createdBlockNumber: BigInt! + " Block number of when this snapshot was taken/last modified (May be taken after interval has passed) " + blockNumber: BigInt! } ################################## @@ -728,10 +698,10 @@ type Trade implements Event @entity(immutable: true) @transaction { from: Bytes! " Trader address" - trader: Trader! + trader: Account! " Subject address" - subject: Subject! + subject: Pool! " trade type - BUY / SELL " type: TradeType! @@ -740,19 +710,19 @@ type Trade implements Event @entity(immutable: true) @transaction { shares: BigInt! " price of shares " - sharePriceETH: BigInt! + sharePriceAmount: BigInt! sharePriceUSD: BigDecimal! " protocol fee " - protocolFeeETH: BigInt! + protocolFeeAmount: BigInt! protocolFeeUSD: BigDecimal! " subject fee " - subjectFeeETH: BigInt! + subjectFeeAmount: BigInt! subjectFeeUSD: BigDecimal! " total trade amount (sharePrice + protocolFee + subjectFee) " - amountETH: BigInt! + amount: BigInt! amountUSD: BigDecimal! " Block number of this event " @@ -762,15 +732,105 @@ type Trade implements Event @entity(immutable: true) @transaction { timestamp: BigInt! } -################################## -############# Helpers ############ -################################## +########################### +##### User-Level Data ##### +########################### -# Helps to accumulate total unique users -type _Account @entity @regularPolling { - " Address of the Account " +type Account @entity @regularPolling { + " Address of the trader " id: Bytes! - isBuyer: Boolean! - isSeller: Boolean! - isSubject: Boolean! + + " Cumulative value of shares bought by the trader " + cumulativeBuyVolumeUSD: BigDecimal! + + " Cumulative value of shares sold by the trader " + cumulativeSellVolumeUSD: BigDecimal! + + " Volume bought plus volume sold by the trader " + cumulativeTotalVolumeUSD: BigDecimal! + + " Volume bought minus volume sold by the trader " + netVolumeUSD: BigDecimal! + + " Total number of buy trades by the trader " + cumulativeBuyCount: Int! + + " Total number of sell trades by the trader " + cumulativeSellCount: Int! + + " Total number of trades by the trader " + cumulativeTransactionCount: Int! + + " Creation timestamp " + createdTimestamp: BigInt! + + " Creation block number " + createdBlockNumber: BigInt! + + " All buy events for this account. " + buys: [Trade!]! + + " All sell events for this account. " + sells: [Trade!]! + + " Subjects that have been bought by the trader " + subjects: [Pool!]! + + " Info about the connection between a trader and a subject " + connections: [Connection!]! @derivedFrom(field: "trader") +} + +# Helper entity for calculating daily/hourly active users +type ActiveAccount @entity @regularPolling { + " {daily/hourly}-{ Days since Unix epoch }-{ Address of the account } " + id: Bytes! + + " All buy events for this account. " + buys: [Trade!]! + + " All sell events for this account. " + sells: [Trade!]! +} + +####################### +##### Connections ##### +####################### + +type Connection @entity @regularPolling { + " {Trader ID}-{Subject ID} " + id: Bytes! + + " Trader and Subject between which this connection exists " + trader: Account! + subject: Pool! + + " Number of subject shares held by the trader " + shares: BigInt! + + " Cumulative value of subject shares bought by the trader " + cumulativeBuyVolumeUSD: BigDecimal! + + " Cumulative value of subject shares sold by the trader " + cumulativeSellVolumeUSD: BigDecimal! + + " Volume bought plus volume sold of subject shares by the trader " + cumulativeTotalVolumeUSD: BigDecimal! + + " Volume bought minus volume sold of subject shares by the trader " + netVolumeUSD: BigDecimal! + + " Total number of buy trades of subject shares by the trader " + cumulativeBuyCount: Int! + + " Total number of sell trades of subject shares by the trader " + cumulativeSellCount: Int! + + " Total number of trades of subject shares by the trader " + cumulativeTransactionCount: Int! + + " Creation timestamp " + createdTimestamp: BigInt! + + " Creation block number " + createdBlockNumber: BigInt! } diff --git a/subgraphs/friend-tech/src/common/constants.ts b/subgraphs/friend-tech/src/common/constants.ts index 8a823244ae..b9bce9fa0a 100644 --- a/subgraphs/friend-tech/src/common/constants.ts +++ b/subgraphs/friend-tech/src/common/constants.ts @@ -46,7 +46,6 @@ export namespace ProtocolType { export const YIELD = "YIELD"; export const BRIDGE = "BRIDGE"; export const GENERIC = "GENERIC"; - export const SOCIAL = "SOCIAL"; } export namespace TradeType { @@ -93,6 +92,7 @@ export const BIGDECIMAL_TWO = new BigDecimal(BIGINT_TWO); export const MAX_UINT = BigInt.fromI32(2).times(BigInt.fromI32(255)); export const SECONDS_PER_DAY = 60 * 60 * 24; +export const SECONDS_PER_HOUR = 60 * 60; //////////////////////// /// Protocol Specific // diff --git a/subgraphs/friend-tech/src/common/events.ts b/subgraphs/friend-tech/src/common/events.ts index 6d16cf06f6..82ce3ce6ba 100644 --- a/subgraphs/friend-tech/src/common/events.ts +++ b/subgraphs/friend-tech/src/common/events.ts @@ -1,22 +1,39 @@ import { Address, Bytes, BigInt, ethereum } from "@graphprotocol/graph-ts"; -import { getUsdPriceForEthAmount } from "./prices"; +import { bigIntToBigDecimal } from "./utils"; import { TradeType, ZERO_ADDRESS } from "./constants"; import { NetworkConfigs } from "../../configurations/configure"; -import { Trade } from "../../generated/schema"; +import { Token, Trade } from "../../generated/schema"; -export function createEvent( +export function createTrade( + token: Token, traderAddress: Address, subjectAddress: Address, shares: BigInt, - sharePriceETH: BigInt, - subjectFeeETH: BigInt, - protocolFeeETH: BigInt, - tradeAmountETH: BigInt, + sharePriceAmount: BigInt, + subjectFeeAmount: BigInt, + protocolFeeAmount: BigInt, + tradeAmount: BigInt, isBuy: boolean, event: ethereum.Event -): void { +): Bytes { + const sharePriceUSD = bigIntToBigDecimal( + sharePriceAmount, + token.decimals + ).times(token.lastPriceUSD!); + const protocolFeeUSD = bigIntToBigDecimal( + protocolFeeAmount, + token.decimals + ).times(token.lastPriceUSD!); + const subjectFeeUSD = bigIntToBigDecimal( + subjectFeeAmount, + token.decimals + ).times(token.lastPriceUSD!); + const tradeAmountUSD = bigIntToBigDecimal(tradeAmount, token.decimals).times( + token.lastPriceUSD! + ); + const id = Bytes.empty() .concat(event.transaction.hash) .concatI32(event.logIndex.toI32()); @@ -34,24 +51,18 @@ export function createEvent( tradeEvent.subject = subjectAddress; tradeEvent.type = isBuy ? TradeType.BUY : TradeType.SELL; tradeEvent.shares = shares; - - const sharePriceUSD = getUsdPriceForEthAmount(sharePriceETH, event); - const protocolFeeUSD = getUsdPriceForEthAmount(protocolFeeETH, event); - const subjectFeeUSD = getUsdPriceForEthAmount(subjectFeeETH, event); - const tradeAmountUSD = getUsdPriceForEthAmount(tradeAmountETH, event); - - tradeEvent.sharePriceETH = sharePriceETH; + tradeEvent.sharePriceAmount = sharePriceAmount; tradeEvent.sharePriceUSD = sharePriceUSD; - tradeEvent.protocolFeeETH = protocolFeeETH; + tradeEvent.protocolFeeAmount = protocolFeeAmount; tradeEvent.protocolFeeUSD = protocolFeeUSD; - tradeEvent.subjectFeeETH = subjectFeeETH; + tradeEvent.subjectFeeAmount = subjectFeeAmount; tradeEvent.subjectFeeUSD = subjectFeeUSD; - tradeEvent.amountETH = tradeAmountETH; + tradeEvent.amount = tradeAmount; tradeEvent.amountUSD = tradeAmountUSD; tradeEvent.blockNumber = event.block.number; tradeEvent.timestamp = event.block.timestamp; - tradeEvent.save(); - return; + + return tradeEvent.id; } diff --git a/subgraphs/friend-tech/src/common/getters.ts b/subgraphs/friend-tech/src/common/getters.ts index 9af185f18e..40a022a7e1 100644 --- a/subgraphs/friend-tech/src/common/getters.ts +++ b/subgraphs/friend-tech/src/common/getters.ts @@ -7,6 +7,7 @@ import { ETH_DECIMALS, ETH_NAME, ETH_SYMBOL, + INT_ONE, INT_ZERO, PROTOCOL_NAME, PROTOCOL_SLUG, @@ -15,21 +16,38 @@ import { import { getUsdPricePerEth } from "./prices"; import { Versions } from "../versions"; import { NetworkConfigs } from "../../configurations/configure"; -import { AccountResponse } from "./types"; -import { getDaysSinceEpoch } from "./utils"; import { - _Account, + Account, Connection, - ConnectionDailySnapshot, + Pool, Protocol, - Subject, - SubjectDailySnapshot, Token, - Trader, - TraderDailySnapshot, } from "../../generated/schema"; +export function getOrCreateToken(event: ethereum.Event): Token { + const tokenAddress = Address.fromString(ETH_ADDRESS); + let token = Token.load(tokenAddress); + + if (!token) { + token = new Token(tokenAddress); + + token.name = ETH_NAME; + token.symbol = ETH_SYMBOL; + token.decimals = ETH_DECIMALS as i32; + token.lastPriceBlockNumber = event.block.number; + } + + if (!token.lastPriceUSD || token.lastPriceBlockNumber! < event.block.number) { + const priceUSD = getUsdPricePerEth(); + + token.lastPriceUSD = priceUSD; + token.lastPriceBlockNumber = event.block.number; + } + token.save(); + return token; +} + export function getOrCreateProtocol(): Protocol { let protocol = Protocol.load(NetworkConfigs.getFactoryAddress()); @@ -38,37 +56,30 @@ export function getOrCreateProtocol(): Protocol { protocol.name = PROTOCOL_NAME; protocol.slug = PROTOCOL_SLUG; protocol.network = NetworkConfigs.getNetwork(); - protocol.type = ProtocolType.SOCIAL; + protocol.type = ProtocolType.GENERIC; - protocol.totalValueLockedETH = BIGINT_ZERO; protocol.totalValueLockedUSD = BIGDECIMAL_ZERO; - protocol.cumulativeSupplySideRevenueETH = BIGINT_ZERO; protocol.cumulativeSupplySideRevenueUSD = BIGDECIMAL_ZERO; - protocol.cumulativeProtocolSideRevenueETH = BIGINT_ZERO; protocol.cumulativeProtocolSideRevenueUSD = BIGDECIMAL_ZERO; - protocol.cumulativeTotalRevenueETH = BIGINT_ZERO; protocol.cumulativeTotalRevenueUSD = BIGDECIMAL_ZERO; - protocol.cumulativeBuyVolumeETH = BIGINT_ZERO; protocol.cumulativeBuyVolumeUSD = BIGDECIMAL_ZERO; - protocol.cumulativeSellVolumeETH = BIGINT_ZERO; protocol.cumulativeSellVolumeUSD = BIGDECIMAL_ZERO; - protocol.cumulativeTotalVolumeETH = BIGINT_ZERO; protocol.cumulativeTotalVolumeUSD = BIGDECIMAL_ZERO; - protocol.netVolumeETH = BIGINT_ZERO; protocol.netVolumeUSD = BIGDECIMAL_ZERO; protocol.cumulativeUniqueBuyers = INT_ZERO; protocol.cumulativeUniqueSellers = INT_ZERO; - protocol.cumulativeUniqueTraders = INT_ZERO; - protocol.cumulativeUniqueSubjects = INT_ZERO; protocol.cumulativeUniqueUsers = INT_ZERO; protocol.cumulativeBuyCount = INT_ZERO; protocol.cumulativeSellCount = INT_ZERO; - protocol.cumulativeTradesCount = INT_ZERO; + protocol.cumulativeTransactionCount = INT_ZERO; + + protocol.totalPoolCount = INT_ZERO; protocol._lastDailySnapshotTimestamp = BIGINT_ZERO; + protocol._lastHourlySnapshotTimestamp = BIGINT_ZERO; } protocol.schemaVersion = Versions.getSchemaVersion(); @@ -79,97 +90,89 @@ export function getOrCreateProtocol(): Protocol { return protocol; } -export function getOrCreateEthToken(event: ethereum.Event): Token { - const ethAddress = Address.fromString(ETH_ADDRESS); - let token = Token.load(ethAddress); - - if (!token) { - token = new Token(ethAddress); - - token.name = ETH_NAME; - token.symbol = ETH_SYMBOL; - token.decimals = ETH_DECIMALS as i32; - token.lastPriceBlockNumber = event.block.number; - } - - if (!token.lastPriceUSD || token.lastPriceBlockNumber! < event.block.number) { - const priceUSD = getUsdPricePerEth(); - - token.lastPriceUSD = priceUSD; - token.lastPriceBlockNumber = event.block.number; +export function getOrCreatePool( + poolAddress: Address, + event: ethereum.Event +): Pool { + let pool = Pool.load(poolAddress); + + if (!pool) { + const protocol = getOrCreateProtocol(); + pool = new Pool(poolAddress); + pool.protocol = protocol.id; + pool.name = "Subject-" + poolAddress.toHexString(); + pool.symbol = "S-" + poolAddress.toHexString(); + pool.inputTokens = [Address.fromString(ETH_ADDRESS)]; + pool.createdTimestamp = event.block.timestamp; + pool.createdBlockNumber = event.block.number; + + pool.totalValueLockedUSD = BIGDECIMAL_ZERO; + pool.cumulativeSupplySideRevenueUSD = BIGDECIMAL_ZERO; + pool.cumulativeProtocolSideRevenueUSD = BIGDECIMAL_ZERO; + pool.cumulativeTotalRevenueUSD = BIGDECIMAL_ZERO; + pool.inputTokenBalances = [BIGINT_ZERO]; + pool.inputTokenBalancesUSD = [BIGDECIMAL_ZERO]; + pool.cumulativeBuyVolumeAmount = BIGINT_ZERO; + pool.cumulativeBuyVolumeUSD = BIGDECIMAL_ZERO; + pool.cumulativeSellVolumeAmount = BIGINT_ZERO; + pool.cumulativeSellVolumeUSD = BIGDECIMAL_ZERO; + pool.cumulativeTotalVolumeAmount = BIGINT_ZERO; + pool.cumulativeTotalVolumeUSD = BIGDECIMAL_ZERO; + pool.netVolumeAmount = BIGINT_ZERO; + pool.netVolumeUSD = BIGDECIMAL_ZERO; + + pool.cumulativeUniqueUsers = INT_ZERO; + pool.cumulativeBuyCount = INT_ZERO; + pool.cumulativeSellCount = INT_ZERO; + pool.cumulativeTransactionCount = INT_ZERO; + + pool.supply = BIGINT_ZERO; + pool.sharePriceAmount = BIGINT_ZERO; + pool.sharePriceUSD = BIGDECIMAL_ZERO; + + pool.traders = []; + + pool._lastDailySnapshotTimestamp = BIGINT_ZERO; + pool._lastHourlySnapshotTimestamp = BIGINT_ZERO; + + protocol.totalPoolCount += INT_ONE; + + pool.save(); + protocol.save(); } - token.save(); - return token; + return pool; } -export function getOrCreateTrader( +export function getOrCreateAccount( traderAddress: Address, event: ethereum.Event -): Trader { - let trader = Trader.load(traderAddress); +): Account { + let trader = Account.load(traderAddress); if (!trader) { - trader = new Trader(traderAddress); + trader = new Account(traderAddress); - trader.cumulativeBuyVolumeETH = BIGINT_ZERO; trader.cumulativeBuyVolumeUSD = BIGDECIMAL_ZERO; - trader.cumulativeSellVolumeETH = BIGINT_ZERO; trader.cumulativeSellVolumeUSD = BIGDECIMAL_ZERO; - trader.cumulativeTotalVolumeETH = BIGINT_ZERO; trader.cumulativeTotalVolumeUSD = BIGDECIMAL_ZERO; - trader.netVolumeETH = BIGINT_ZERO; trader.netVolumeUSD = BIGDECIMAL_ZERO; trader.cumulativeBuyCount = INT_ZERO; trader.cumulativeSellCount = INT_ZERO; - trader.cumulativeTradesCount = INT_ZERO; + trader.cumulativeTransactionCount = INT_ZERO; - trader.registeredAt = event.block.number; + trader.createdTimestamp = event.block.timestamp; + trader.createdBlockNumber = event.block.number; - trader.connections = []; + trader.buys = []; + trader.sells = []; + trader.subjects = []; trader.save(); } return trader; } -export function getOrCreateSubject( - subjectAddress: Address, - event: ethereum.Event -): Subject { - let subject = Subject.load(subjectAddress); - - if (!subject) { - subject = new Subject(subjectAddress); - - subject.cumulativeRevenueETH = BIGINT_ZERO; - subject.cumulativeRevenueUSD = BIGDECIMAL_ZERO; - subject.cumulativeBuyVolumeETH = BIGINT_ZERO; - subject.cumulativeBuyVolumeUSD = BIGDECIMAL_ZERO; - subject.cumulativeSellVolumeETH = BIGINT_ZERO; - subject.cumulativeSellVolumeUSD = BIGDECIMAL_ZERO; - subject.cumulativeTotalVolumeETH = BIGINT_ZERO; - subject.cumulativeTotalVolumeUSD = BIGDECIMAL_ZERO; - subject.netVolumeETH = BIGINT_ZERO; - subject.netVolumeUSD = BIGDECIMAL_ZERO; - - subject.cumulativeBuyCount = INT_ZERO; - subject.cumulativeSellCount = INT_ZERO; - subject.cumulativeTradesCount = INT_ZERO; - - subject.registeredAt = event.block.number; - - subject.supply = BIGINT_ZERO; - subject.sharePriceETH = BIGINT_ZERO; - subject.sharePriceUSD = BIGDECIMAL_ZERO; - - subject.connections = []; - - subject.save(); - } - return subject; -} - export function getOrCreateConnection( traderAddress: Address, subjectAddress: Address, @@ -187,20 +190,18 @@ export function getOrCreateConnection( connection.trader = traderAddress; connection.subject = subjectAddress; + + // TODO connection.shares = BIGINT_ZERO; - connection.cumulativeBuyVolumeETH = BIGINT_ZERO; connection.cumulativeBuyVolumeUSD = BIGDECIMAL_ZERO; - connection.cumulativeSellVolumeETH = BIGINT_ZERO; connection.cumulativeSellVolumeUSD = BIGDECIMAL_ZERO; - connection.cumulativeTotalVolumeETH = BIGINT_ZERO; connection.cumulativeTotalVolumeUSD = BIGDECIMAL_ZERO; - connection.netVolumeETH = BIGINT_ZERO; connection.netVolumeUSD = BIGDECIMAL_ZERO; connection.cumulativeBuyCount = INT_ZERO; connection.cumulativeSellCount = INT_ZERO; - connection.cumulativeTradesCount = INT_ZERO; + connection.cumulativeTransactionCount = INT_ZERO; connection.createdTimestamp = event.block.timestamp; connection.createdBlockNumber = event.block.number; @@ -209,188 +210,3 @@ export function getOrCreateConnection( } return connection; } - -export function getOrCreateAccount(accountAddress: Address): AccountResponse { - let isNewAccount = false; - let account = _Account.load(accountAddress); - if (!account) { - isNewAccount = true; - account = new _Account(accountAddress); - account.isBuyer = false; - account.isSeller = false; - account.isSubject = false; - account.save(); - } - return { account, isNewAccount }; -} - -export function getOrCreateTraderDailySnapshot( - traderAddress: Address, - event: ethereum.Event -): TraderDailySnapshot { - const day = getDaysSinceEpoch(event.block.timestamp.toI32()); - const id = Bytes.empty() - .concat(Bytes.fromI32(day)) - .concat(Bytes.fromUTF8("-")) - .concat(traderAddress); - - let snapshot = TraderDailySnapshot.load(id); - - if (!snapshot) { - snapshot = new TraderDailySnapshot(id); - - snapshot.day = day; - snapshot.protocol = NetworkConfigs.getFactoryAddress(); - snapshot.trader = traderAddress; - - snapshot.dailyBuyVolumeETH = BIGINT_ZERO; - snapshot.cumulativeBuyVolumeETH = BIGINT_ZERO; - snapshot.dailyBuyVolumeUSD = BIGDECIMAL_ZERO; - snapshot.cumulativeBuyVolumeUSD = BIGDECIMAL_ZERO; - snapshot.dailySellVolumeETH = BIGINT_ZERO; - snapshot.cumulativeSellVolumeETH = BIGINT_ZERO; - snapshot.dailySellVolumeUSD = BIGDECIMAL_ZERO; - snapshot.cumulativeSellVolumeUSD = BIGDECIMAL_ZERO; - snapshot.dailyTotalVolumeETH = BIGINT_ZERO; - snapshot.cumulativeTotalVolumeETH = BIGINT_ZERO; - snapshot.dailyTotalVolumeUSD = BIGDECIMAL_ZERO; - snapshot.cumulativeTotalVolumeUSD = BIGDECIMAL_ZERO; - snapshot.dailyNetVolumeETH = BIGINT_ZERO; - snapshot.netVolumeETH = BIGINT_ZERO; - snapshot.dailyNetVolumeUSD = BIGDECIMAL_ZERO; - snapshot.netVolumeUSD = BIGDECIMAL_ZERO; - - snapshot.dailyBuyCount = INT_ZERO; - snapshot.cumulativeBuyCount = INT_ZERO; - snapshot.dailySellCount = INT_ZERO; - snapshot.cumulativeSellCount = INT_ZERO; - snapshot.dailyTradesCount = INT_ZERO; - snapshot.cumulativeTradesCount = INT_ZERO; - - snapshot.connections = []; - - snapshot.timestamp = event.block.timestamp; - snapshot.blockNumber = event.block.number; - - snapshot.save(); - } - return snapshot; -} - -export function getOrCreateSubjectDailySnapshot( - subjectAddress: Address, - event: ethereum.Event -): SubjectDailySnapshot { - const day = getDaysSinceEpoch(event.block.timestamp.toI32()); - const id = Bytes.empty() - .concat(Bytes.fromI32(day)) - .concat(Bytes.fromUTF8("-")) - .concat(subjectAddress); - - let snapshot = SubjectDailySnapshot.load(id); - - if (!snapshot) { - snapshot = new SubjectDailySnapshot(id); - - snapshot.day = day; - snapshot.protocol = NetworkConfigs.getFactoryAddress(); - snapshot.subject = subjectAddress; - - snapshot.dailyRevenueETH = BIGINT_ZERO; - snapshot.cumulativeRevenueETH = BIGINT_ZERO; - snapshot.dailyRevenueUSD = BIGDECIMAL_ZERO; - snapshot.cumulativeRevenueUSD = BIGDECIMAL_ZERO; - - snapshot.dailyBuyVolumeETH = BIGINT_ZERO; - snapshot.cumulativeBuyVolumeETH = BIGINT_ZERO; - snapshot.dailyBuyVolumeUSD = BIGDECIMAL_ZERO; - snapshot.cumulativeBuyVolumeUSD = BIGDECIMAL_ZERO; - snapshot.dailySellVolumeETH = BIGINT_ZERO; - snapshot.cumulativeSellVolumeETH = BIGINT_ZERO; - snapshot.dailySellVolumeUSD = BIGDECIMAL_ZERO; - snapshot.cumulativeSellVolumeUSD = BIGDECIMAL_ZERO; - snapshot.dailyTotalVolumeETH = BIGINT_ZERO; - snapshot.cumulativeTotalVolumeETH = BIGINT_ZERO; - snapshot.dailyTotalVolumeUSD = BIGDECIMAL_ZERO; - snapshot.cumulativeTotalVolumeUSD = BIGDECIMAL_ZERO; - snapshot.dailyNetVolumeETH = BIGINT_ZERO; - snapshot.netVolumeETH = BIGINT_ZERO; - snapshot.dailyNetVolumeUSD = BIGDECIMAL_ZERO; - snapshot.netVolumeUSD = BIGDECIMAL_ZERO; - - snapshot.dailyBuyCount = INT_ZERO; - snapshot.cumulativeBuyCount = INT_ZERO; - snapshot.dailySellCount = INT_ZERO; - snapshot.cumulativeSellCount = INT_ZERO; - snapshot.dailyTradesCount = INT_ZERO; - snapshot.cumulativeTradesCount = INT_ZERO; - - snapshot.supply = BIGINT_ZERO; - snapshot.sharePriceETH = BIGINT_ZERO; - snapshot.sharePriceUSD = BIGDECIMAL_ZERO; - - snapshot.connections = []; - - snapshot.timestamp = event.block.timestamp; - snapshot.blockNumber = event.block.number; - - snapshot.save(); - } - return snapshot; -} - -export function getOrCreateConnectionDailySnapshot( - traderAddress: Address, - subjectAddress: Address, - event: ethereum.Event -): ConnectionDailySnapshot { - const day = getDaysSinceEpoch(event.block.timestamp.toI32()); - const id = Bytes.empty() - .concat(Bytes.fromI32(day)) - .concat(Bytes.fromUTF8("-")) - .concat(traderAddress) - .concat(Bytes.fromUTF8("-")) - .concat(subjectAddress); - - let snapshot = ConnectionDailySnapshot.load(id); - - if (!snapshot) { - snapshot = new ConnectionDailySnapshot(id); - - snapshot.day = day; - snapshot.protocol = NetworkConfigs.getFactoryAddress(); - snapshot.trader = traderAddress; - snapshot.subject = subjectAddress; - snapshot.shares = BIGINT_ZERO; - - snapshot.dailyBuyVolumeETH = BIGINT_ZERO; - snapshot.cumulativeBuyVolumeETH = BIGINT_ZERO; - snapshot.dailyBuyVolumeUSD = BIGDECIMAL_ZERO; - snapshot.cumulativeBuyVolumeUSD = BIGDECIMAL_ZERO; - snapshot.dailySellVolumeETH = BIGINT_ZERO; - snapshot.cumulativeSellVolumeETH = BIGINT_ZERO; - snapshot.dailySellVolumeUSD = BIGDECIMAL_ZERO; - snapshot.cumulativeSellVolumeUSD = BIGDECIMAL_ZERO; - snapshot.dailyTotalVolumeETH = BIGINT_ZERO; - snapshot.cumulativeTotalVolumeETH = BIGINT_ZERO; - snapshot.dailyTotalVolumeUSD = BIGDECIMAL_ZERO; - snapshot.cumulativeTotalVolumeUSD = BIGDECIMAL_ZERO; - snapshot.dailyNetVolumeETH = BIGINT_ZERO; - snapshot.netVolumeETH = BIGINT_ZERO; - snapshot.dailyNetVolumeUSD = BIGDECIMAL_ZERO; - snapshot.netVolumeUSD = BIGDECIMAL_ZERO; - - snapshot.dailyBuyCount = INT_ZERO; - snapshot.cumulativeBuyCount = INT_ZERO; - snapshot.dailySellCount = INT_ZERO; - snapshot.cumulativeSellCount = INT_ZERO; - snapshot.dailyTradesCount = INT_ZERO; - snapshot.cumulativeTradesCount = INT_ZERO; - - snapshot.createdTimestamp = event.block.timestamp; - snapshot.createdBlockNumber = event.block.number; - - snapshot.save(); - } - return snapshot; -} diff --git a/subgraphs/friend-tech/src/common/metrics.ts b/subgraphs/friend-tech/src/common/metrics.ts index 41d22a0802..c37df16ef9 100644 --- a/subgraphs/friend-tech/src/common/metrics.ts +++ b/subgraphs/friend-tech/src/common/metrics.ts @@ -1,287 +1,208 @@ -import { ethereum, BigInt, Address } from "@graphprotocol/graph-ts"; +import { BigInt, Bytes } from "@graphprotocol/graph-ts"; -import { - getOrCreateProtocol, - getOrCreateAccount, - getOrCreateTrader, - getOrCreateSubject, - getOrCreateConnection, -} from "./getters"; import { INT_ONE } from "./constants"; -import { addToArrayAtIndex } from "./utils"; -import { getUsdPriceForEthAmount } from "./prices"; - -export function updateTVL( - amountETH: BigInt, - isBuy: boolean, - event: ethereum.Event -): void { - const protocol = getOrCreateProtocol(); - - if (isBuy) { - protocol.totalValueLockedETH = protocol.totalValueLockedETH.plus(amountETH); - } else { - protocol.totalValueLockedETH = - protocol.totalValueLockedETH.minus(amountETH); - } - protocol.totalValueLockedUSD = getUsdPriceForEthAmount( - protocol.totalValueLockedETH, - event - ); +import { addToArrayAtIndex, bigIntToBigDecimal } from "./utils"; - protocol.save(); -} +import { + Account, + Connection, + Pool, + Protocol, + Token, +} from "../../generated/schema"; -export function updateUsage( - traderAddress: Address, - subjectAddress: Address, - isBuy: boolean, - event: ethereum.Event +export function updateTVL( + token: Token, + protocol: Protocol, + pool: Pool, + amount: BigInt, + isBuy: boolean ): void { - const protocol = getOrCreateProtocol(); - const trader = getOrCreateTrader(traderAddress, event); - const subject = getOrCreateSubject(subjectAddress, event); - - const subjectAccount = getOrCreateAccount(subjectAddress); - if (subjectAccount.isNewAccount) { - protocol.cumulativeUniqueUsers += INT_ONE; - } - if (!subjectAccount.account.isSubject) { - protocol.cumulativeUniqueSubjects += INT_ONE; - subjectAccount.account.isSubject = true; - } - subjectAccount.account.save(); - - const traderAccount = getOrCreateAccount(traderAddress); - if (traderAccount.isNewAccount) { - protocol.cumulativeUniqueUsers += INT_ONE; - } - if (!traderAccount.account.isBuyer && !traderAccount.account.isSeller) { - protocol.cumulativeUniqueTraders += INT_ONE; - } if (isBuy) { - if (!traderAccount.account.isBuyer) { - protocol.cumulativeUniqueBuyers += INT_ONE; - traderAccount.account.isBuyer = true; - } - trader.cumulativeBuyCount += INT_ONE; - subject.cumulativeBuyCount += INT_ONE; - protocol.cumulativeBuyCount += INT_ONE; + pool.inputTokenBalances = [pool.inputTokenBalances[0].plus(amount)]; } else { - if (!traderAccount.account.isSeller) { - protocol.cumulativeUniqueSellers += INT_ONE; - traderAccount.account.isSeller = true; - } - trader.cumulativeSellCount += INT_ONE; - subject.cumulativeSellCount += INT_ONE; - protocol.cumulativeSellCount += INT_ONE; + pool.inputTokenBalances = [pool.inputTokenBalances[0].minus(amount)]; } - traderAccount.account.save(); - - trader.cumulativeTradesCount += INT_ONE; - subject.cumulativeTradesCount += INT_ONE; - protocol.cumulativeTradesCount += INT_ONE; + pool.inputTokenBalancesUSD = [ + bigIntToBigDecimal(pool.inputTokenBalances[0]).times(token.lastPriceUSD!), + ]; - trader.save(); - subject.save(); - protocol.save(); + const oldPoolTVL = pool.totalValueLockedUSD; + pool.totalValueLockedUSD = pool.inputTokenBalancesUSD[0]; + protocol.totalValueLockedUSD = protocol.totalValueLockedUSD.plus( + pool.totalValueLockedUSD.minus(oldPoolTVL) + ); } export function updateRevenue( - subjectAddress: Address, - subjectFeeETH: BigInt, - protocolFeeETH: BigInt, - event: ethereum.Event + token: Token, + protocol: Protocol, + pool: Pool, + subjectFeeAmount: BigInt, + protocolFeeAmount: BigInt ): void { - const protocol = getOrCreateProtocol(); - const subject = getOrCreateSubject(subjectAddress, event); - - const subjectFeeUSD = getUsdPriceForEthAmount(subjectFeeETH, event); - const protocolFeeUSD = getUsdPriceForEthAmount(protocolFeeETH, event); + const subjectFeeUSD = bigIntToBigDecimal(subjectFeeAmount).times( + token.lastPriceUSD! + ); + const protocolFeeUSD = bigIntToBigDecimal(protocolFeeAmount).times( + token.lastPriceUSD! + ); + const totalFeeUSD = subjectFeeUSD.plus(protocolFeeUSD); - subject.cumulativeRevenueETH = - subject.cumulativeRevenueETH.plus(subjectFeeETH); - subject.cumulativeRevenueUSD = - subject.cumulativeRevenueUSD.plus(subjectFeeUSD); + pool.cumulativeSupplySideRevenueUSD = + pool.cumulativeSupplySideRevenueUSD.plus(subjectFeeUSD); + pool.cumulativeProtocolSideRevenueUSD = + pool.cumulativeProtocolSideRevenueUSD.plus(protocolFeeUSD); + pool.cumulativeTotalRevenueUSD = + pool.cumulativeTotalRevenueUSD.plus(totalFeeUSD); - protocol.cumulativeSupplySideRevenueETH = - protocol.cumulativeSupplySideRevenueETH.plus(subjectFeeETH); protocol.cumulativeSupplySideRevenueUSD = protocol.cumulativeSupplySideRevenueUSD.plus(subjectFeeUSD); - protocol.cumulativeProtocolSideRevenueETH = - protocol.cumulativeProtocolSideRevenueETH.plus(protocolFeeETH); protocol.cumulativeProtocolSideRevenueUSD = protocol.cumulativeProtocolSideRevenueUSD.plus(protocolFeeUSD); - protocol.cumulativeTotalRevenueETH = protocol.cumulativeTotalRevenueETH.plus( - subjectFeeETH.plus(protocolFeeETH) - ); - protocol.cumulativeTotalRevenueUSD = protocol.cumulativeTotalRevenueUSD.plus( - subjectFeeUSD.plus(protocolFeeUSD) - ); - - subject.save(); - protocol.save(); + protocol.cumulativeTotalRevenueUSD = + protocol.cumulativeTotalRevenueUSD.plus(totalFeeUSD); } export function updateVolume( - traderAddress: Address, - subjectAddress: Address, - amountETH: BigInt, - isBuy: boolean, - event: ethereum.Event + token: Token, + protocol: Protocol, + pool: Pool, + account: Account, + amount: BigInt, + isBuy: boolean ): void { - const protocol = getOrCreateProtocol(); - const trader = getOrCreateTrader(traderAddress, event); - const subject = getOrCreateSubject(subjectAddress, event); - const amountUSD = getUsdPriceForEthAmount(amountETH, event); + const amountUSD = bigIntToBigDecimal(amount).times(token.lastPriceUSD!); if (isBuy) { - trader.cumulativeBuyVolumeETH = - trader.cumulativeBuyVolumeETH.plus(amountETH); - trader.cumulativeBuyVolumeUSD = - trader.cumulativeBuyVolumeUSD.plus(amountUSD); + account.cumulativeBuyVolumeUSD = + account.cumulativeBuyVolumeUSD.plus(amountUSD); - subject.cumulativeBuyVolumeETH = - subject.cumulativeBuyVolumeETH.plus(amountETH); - subject.cumulativeBuyVolumeUSD = - subject.cumulativeBuyVolumeUSD.plus(amountUSD); + pool.cumulativeBuyVolumeAmount = + pool.cumulativeBuyVolumeAmount.plus(amount); + pool.cumulativeBuyVolumeUSD = pool.cumulativeBuyVolumeUSD.plus(amountUSD); - protocol.cumulativeBuyVolumeETH = - protocol.cumulativeBuyVolumeETH.plus(amountETH); protocol.cumulativeBuyVolumeUSD = protocol.cumulativeBuyVolumeUSD.plus(amountUSD); } else { - trader.cumulativeSellVolumeETH = - trader.cumulativeSellVolumeETH.plus(amountETH); - trader.cumulativeSellVolumeUSD = - trader.cumulativeSellVolumeUSD.plus(amountUSD); + account.cumulativeSellVolumeUSD = + account.cumulativeSellVolumeUSD.plus(amountUSD); - subject.cumulativeSellVolumeETH = - subject.cumulativeSellVolumeETH.plus(amountETH); - subject.cumulativeSellVolumeUSD = - subject.cumulativeSellVolumeUSD.plus(amountUSD); + pool.cumulativeSellVolumeAmount = + pool.cumulativeSellVolumeAmount.plus(amount); + pool.cumulativeSellVolumeUSD = pool.cumulativeSellVolumeUSD.plus(amountUSD); - protocol.cumulativeSellVolumeETH = - protocol.cumulativeSellVolumeETH.plus(amountETH); protocol.cumulativeSellVolumeUSD = protocol.cumulativeSellVolumeUSD.plus(amountUSD); } - trader.cumulativeTotalVolumeETH = trader.cumulativeBuyVolumeETH.plus( - trader.cumulativeSellVolumeETH - ); - trader.cumulativeTotalVolumeUSD = trader.cumulativeBuyVolumeUSD.plus( - trader.cumulativeSellVolumeUSD - ); - trader.netVolumeETH = trader.cumulativeBuyVolumeETH.minus( - trader.cumulativeSellVolumeETH + account.cumulativeTotalVolumeUSD = account.cumulativeBuyVolumeUSD.plus( + account.cumulativeSellVolumeUSD ); - trader.netVolumeUSD = trader.cumulativeBuyVolumeUSD.minus( - trader.cumulativeSellVolumeUSD + account.netVolumeUSD = account.cumulativeBuyVolumeUSD.minus( + account.cumulativeSellVolumeUSD ); - subject.cumulativeTotalVolumeETH = subject.cumulativeBuyVolumeETH.plus( - subject.cumulativeSellVolumeETH + pool.cumulativeTotalVolumeAmount = pool.cumulativeBuyVolumeAmount.plus( + pool.cumulativeSellVolumeAmount ); - subject.cumulativeTotalVolumeUSD = subject.cumulativeBuyVolumeUSD.plus( - subject.cumulativeSellVolumeUSD + pool.cumulativeTotalVolumeUSD = pool.cumulativeBuyVolumeUSD.plus( + pool.cumulativeSellVolumeUSD ); - subject.netVolumeETH = subject.cumulativeBuyVolumeETH.minus( - subject.cumulativeSellVolumeETH + pool.netVolumeAmount = pool.cumulativeBuyVolumeAmount.minus( + pool.cumulativeSellVolumeAmount ); - subject.netVolumeUSD = subject.cumulativeBuyVolumeUSD.minus( - subject.cumulativeSellVolumeUSD + pool.netVolumeUSD = pool.cumulativeBuyVolumeUSD.minus( + pool.cumulativeSellVolumeUSD ); - protocol.cumulativeTotalVolumeETH = protocol.cumulativeBuyVolumeETH.plus( - protocol.cumulativeSellVolumeETH - ); protocol.cumulativeTotalVolumeUSD = protocol.cumulativeBuyVolumeUSD.plus( protocol.cumulativeSellVolumeUSD ); - protocol.netVolumeETH = protocol.cumulativeBuyVolumeETH.minus( - protocol.cumulativeSellVolumeETH - ); protocol.netVolumeUSD = protocol.cumulativeBuyVolumeUSD.minus( protocol.cumulativeSellVolumeUSD ); +} + +export function updateShares( + token: Token, + pool: Pool, + amount: BigInt, + supply: BigInt +): void { + const amountUSD = bigIntToBigDecimal(amount).times(token.lastPriceUSD!); - trader.save(); - subject.save(); - protocol.save(); + pool.supply = supply; + pool.sharePriceAmount = amount; + pool.sharePriceUSD = amountUSD; } -export function updateConnections( - traderAddress: Address, - subjectAddress: Address, - shares: BigInt, - amountETH: BigInt, +export function updateUsage( + protocol: Protocol, + pool: Pool, + account: Account, isBuy: boolean, - event: ethereum.Event + tradeID: Bytes ): void { - const trader = getOrCreateTrader(traderAddress, event); - const subject = getOrCreateSubject(subjectAddress, event); - const connection = getOrCreateConnection( - traderAddress, - subjectAddress, - event - ); - const amountUSD = getUsdPriceForEthAmount(amountETH, event); + if (!account.buys.length && !account.sells.length) { + protocol.cumulativeUniqueUsers += INT_ONE; + } + + if (isBuy) { + if (!account.buys.length) { + protocol.cumulativeUniqueBuyers += INT_ONE; + } + account.buys = addToArrayAtIndex(account.buys, tradeID); + account.cumulativeBuyCount += INT_ONE; + pool.cumulativeBuyCount += INT_ONE; + protocol.cumulativeBuyCount += INT_ONE; + } else { + if (!account.sells.length) { + protocol.cumulativeUniqueSellers += INT_ONE; + } + account.sells = addToArrayAtIndex(account.sells, tradeID); + account.cumulativeSellCount += INT_ONE; + pool.cumulativeSellCount += INT_ONE; + protocol.cumulativeSellCount += INT_ONE; + } + account.cumulativeTransactionCount += INT_ONE; + pool.cumulativeTransactionCount += INT_ONE; + protocol.cumulativeTransactionCount += INT_ONE; + + if (!pool.traders.includes(account.id)) { + pool.cumulativeUniqueUsers += INT_ONE; + pool.traders = addToArrayAtIndex(pool.traders, account.id); + } + if (!account.subjects.includes(pool.id)) { + account.subjects = addToArrayAtIndex(account.subjects, account.id); + } +} + +export function updateConnection( + token: Token, + connection: Connection, + shares: BigInt, + amount: BigInt, + isBuy: boolean +): void { + const amountUSD = bigIntToBigDecimal(amount).times(token.lastPriceUSD!); if (isBuy) { connection.shares = connection.shares.plus(shares); - connection.cumulativeBuyVolumeETH = - connection.cumulativeBuyVolumeETH.plus(amountETH); connection.cumulativeBuyVolumeUSD = connection.cumulativeBuyVolumeUSD.plus(amountUSD); connection.cumulativeBuyCount += INT_ONE; } else { connection.shares = connection.shares.minus(shares); - connection.cumulativeSellVolumeETH = - connection.cumulativeSellVolumeETH.plus(amountETH); connection.cumulativeSellVolumeUSD = connection.cumulativeSellVolumeUSD.plus(amountUSD); connection.cumulativeSellCount += INT_ONE; } - - connection.cumulativeTotalVolumeETH = connection.cumulativeBuyVolumeETH.plus( - connection.cumulativeSellVolumeETH - ); connection.cumulativeTotalVolumeUSD = connection.cumulativeBuyVolumeUSD.plus( connection.cumulativeSellVolumeUSD ); - connection.netVolumeETH = connection.cumulativeBuyVolumeETH.minus( - connection.cumulativeSellVolumeETH - ); connection.netVolumeUSD = connection.cumulativeBuyVolumeUSD.minus( connection.cumulativeSellVolumeUSD ); - connection.cumulativeTradesCount += INT_ONE; - connection.save(); - - if (!trader.connections.includes(connection.id)) { - trader.connections = addToArrayAtIndex(trader.connections, connection.id); - } - trader.save(); - - if (!subject.connections.includes(connection.id)) { - subject.connections = addToArrayAtIndex(subject.connections, connection.id); - } - subject.save(); -} - -export function updateSubjectPrice( - subjectAddress: Address, - supply: BigInt, - amountETH: BigInt, - event: ethereum.Event -): void { - const subject = getOrCreateSubject(subjectAddress, event); - const amountUSD = getUsdPriceForEthAmount(amountETH, event); - - subject.sharePriceETH = amountETH; - subject.sharePriceUSD = amountUSD; - subject.supply = supply; - - subject.save(); + connection.cumulativeTransactionCount += INT_ONE; } diff --git a/subgraphs/friend-tech/src/common/prices.ts b/subgraphs/friend-tech/src/common/prices.ts index 80f12974a9..12ea0749ce 100644 --- a/subgraphs/friend-tech/src/common/prices.ts +++ b/subgraphs/friend-tech/src/common/prices.ts @@ -6,7 +6,7 @@ import { CHAINLINK_AGGREGATOR_ETH_USD, ETH_DECIMALS, } from "./constants"; -import { getOrCreateEthToken } from "./getters"; +import { getOrCreateToken } from "./getters"; import { ChainLinkAggregator } from "../../generated/Shares/ChainLinkAggregator"; @@ -33,7 +33,7 @@ export function getUsdPriceForEthAmount( amount: BigInt, event: ethereum.Event ): BigDecimal { - const eth = getOrCreateEthToken(event); + const eth = getOrCreateToken(event); return amount .toBigDecimal() diff --git a/subgraphs/friend-tech/src/common/snapshots.ts b/subgraphs/friend-tech/src/common/snapshots.ts index cf4bcddf5a..5c7cc308ec 100644 --- a/subgraphs/friend-tech/src/common/snapshots.ts +++ b/subgraphs/friend-tech/src/common/snapshots.ts @@ -1,22 +1,17 @@ -import { Address, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts"; +import { BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts"; -import { - getOrCreateConnection, - getOrCreateConnectionDailySnapshot, - getOrCreateProtocol, - getOrCreateSubject, - getOrCreateSubjectDailySnapshot, - getOrCreateTrader, - getOrCreateTraderDailySnapshot, -} from "./getters"; -import { INT_ONE, SECONDS_PER_DAY } from "./constants"; -import { addToArrayAtIndex, getDaysSinceEpoch } from "./utils"; -import { getUsdPriceForEthAmount } from "./prices"; +import { SECONDS_PER_DAY, SECONDS_PER_HOUR } from "./constants"; +import { getDaysSinceEpoch, getHoursSinceEpoch } from "./utils"; +import { NetworkConfigs } from "../../configurations/configure"; import { FinancialsDailySnapshot, + Pool, + PoolDailySnapshot, + PoolHourlySnapshot, Protocol, UsageMetricsDailySnapshot, + UsageMetricsHourlySnapshot, } from "../../generated/schema"; export function takeUsageMetricsDailySnapshot( @@ -33,21 +28,18 @@ export function takeUsageMetricsDailySnapshot( snapshot.cumulativeUniqueBuyers = protocol.cumulativeUniqueBuyers; snapshot.cumulativeUniqueSellers = protocol.cumulativeUniqueSellers; - snapshot.cumulativeUniqueTraders = protocol.cumulativeUniqueTraders; - snapshot.cumulativeUniqueSubjects = protocol.cumulativeUniqueSubjects; snapshot.cumulativeUniqueUsers = protocol.cumulativeUniqueUsers; snapshot.cumulativeBuyCount = protocol.cumulativeBuyCount; snapshot.cumulativeSellCount = protocol.cumulativeSellCount; - snapshot.cumulativeTradesCount = protocol.cumulativeTradesCount; + snapshot.cumulativeTransactionCount = protocol.cumulativeTransactionCount; + snapshot.totalPoolCount = protocol.totalPoolCount; let activeBuyersDelta = snapshot.cumulativeUniqueBuyers; let activeSellersDelta = snapshot.cumulativeUniqueSellers; - let activeTradersDelta = snapshot.cumulativeUniqueTraders; - let activeSubjectsDelta = snapshot.cumulativeUniqueSubjects; let activeUsersDelta = snapshot.cumulativeUniqueUsers; let buyCountDelta = snapshot.cumulativeBuyCount; let sellCountDelta = snapshot.cumulativeSellCount; - let tradesCountDelta = snapshot.cumulativeTradesCount; + let transactionCountDelta = snapshot.cumulativeTransactionCount; const previousDay = getDaysSinceEpoch( protocol._lastDailySnapshotTimestamp!.toI32() @@ -61,29 +53,59 @@ export function takeUsageMetricsDailySnapshot( activeSellersDelta = snapshot.cumulativeUniqueSellers - previousSnapshot.cumulativeUniqueSellers; - activeTradersDelta = - snapshot.cumulativeUniqueTraders - - previousSnapshot.cumulativeUniqueTraders; - activeSubjectsDelta = - snapshot.cumulativeUniqueSubjects - - previousSnapshot.cumulativeUniqueSubjects; activeUsersDelta = snapshot.cumulativeUniqueUsers - previousSnapshot.cumulativeUniqueUsers; buyCountDelta = snapshot.cumulativeBuyCount - previousSnapshot.cumulativeBuyCount; sellCountDelta = snapshot.cumulativeSellCount - previousSnapshot.cumulativeSellCount; - tradesCountDelta = - snapshot.cumulativeTradesCount - previousSnapshot.cumulativeTradesCount; + transactionCountDelta = + snapshot.cumulativeTransactionCount - + previousSnapshot.cumulativeTransactionCount; } snapshot.dailyActiveBuyers = activeBuyersDelta; snapshot.dailyActiveSellers = activeSellersDelta; - snapshot.dailyActiveTraders = activeTradersDelta; - snapshot.dailyActiveSubjects = activeSubjectsDelta; snapshot.dailyActiveUsers = activeUsersDelta; snapshot.dailyBuyCount = buyCountDelta; snapshot.dailySellCount = sellCountDelta; - snapshot.dailyTradesCount = tradesCountDelta; + snapshot.dailyTransactionCount = transactionCountDelta; + + snapshot.save(); +} + +export function takeUsageMetricsHourlySnapshot( + protocol: Protocol, + event: ethereum.Event +): void { + const hour = getHoursSinceEpoch(event.block.timestamp.toI32()); + const snapshot = new UsageMetricsHourlySnapshot(Bytes.fromI32(hour)); + + snapshot.hour = hour; + snapshot.protocol = protocol.id; + snapshot.blockNumber = event.block.number; + snapshot.timestamp = event.block.timestamp; + + snapshot.cumulativeUniqueUsers = protocol.cumulativeUniqueUsers; + snapshot.cumulativeTransactionCount = protocol.cumulativeTransactionCount; + + let activeUsersDelta = snapshot.cumulativeUniqueUsers; + let transactionCountDelta = snapshot.cumulativeTransactionCount; + + const previousHour = getHoursSinceEpoch( + protocol._lastHourlySnapshotTimestamp!.toI32() + ); + const previousSnapshot = UsageMetricsHourlySnapshot.load( + Bytes.fromI32(previousHour) + ); + if (previousSnapshot) { + activeUsersDelta = + snapshot.cumulativeUniqueUsers - previousSnapshot.cumulativeUniqueUsers; + transactionCountDelta = + snapshot.cumulativeTransactionCount - + previousSnapshot.cumulativeTransactionCount; + } + snapshot.hourlyActiveUsers = activeUsersDelta; + snapshot.hourlyTransactionCount = transactionCountDelta; snapshot.save(); } @@ -100,40 +122,23 @@ export function takeFinancialsDailySnapshot( snapshot.blockNumber = event.block.number; snapshot.timestamp = event.block.timestamp; - snapshot.totalValueLockedETH = protocol.totalValueLockedETH; snapshot.totalValueLockedUSD = protocol.totalValueLockedUSD; - snapshot.cumulativeSupplySideRevenueETH = - protocol.cumulativeSupplySideRevenueETH; snapshot.cumulativeSupplySideRevenueUSD = protocol.cumulativeSupplySideRevenueUSD; - snapshot.cumulativeProtocolSideRevenueETH = - protocol.cumulativeProtocolSideRevenueETH; snapshot.cumulativeProtocolSideRevenueUSD = protocol.cumulativeProtocolSideRevenueUSD; - snapshot.cumulativeTotalRevenueETH = protocol.cumulativeTotalRevenueETH; snapshot.cumulativeTotalRevenueUSD = protocol.cumulativeTotalRevenueUSD; - snapshot.cumulativeBuyVolumeETH = protocol.cumulativeBuyVolumeETH; snapshot.cumulativeBuyVolumeUSD = protocol.cumulativeBuyVolumeUSD; - snapshot.cumulativeSellVolumeETH = protocol.cumulativeSellVolumeETH; snapshot.cumulativeSellVolumeUSD = protocol.cumulativeSellVolumeUSD; - snapshot.cumulativeTotalVolumeETH = protocol.cumulativeTotalVolumeETH; snapshot.cumulativeTotalVolumeUSD = protocol.cumulativeTotalVolumeUSD; - snapshot.netVolumeETH = protocol.netVolumeETH; snapshot.netVolumeUSD = protocol.netVolumeUSD; - let supplySideRevenueETHDelta = snapshot.cumulativeSupplySideRevenueETH; let supplySideRevenueUSDDelta = snapshot.cumulativeSupplySideRevenueUSD; - let protocolSideRevenueETHDelta = snapshot.cumulativeProtocolSideRevenueETH; let protocolSideRevenueUSDDelta = snapshot.cumulativeProtocolSideRevenueUSD; - let totalRevenueETHDelta = snapshot.cumulativeTotalRevenueETH; let totalRevenueUSDDelta = snapshot.cumulativeTotalRevenueUSD; - let buyVolumeETHDelta = snapshot.cumulativeBuyVolumeETH; let buyVolumeUSDDelta = snapshot.cumulativeBuyVolumeUSD; - let sellVolumeETHDelta = snapshot.cumulativeSellVolumeETH; let sellVolumeUSDDelta = snapshot.cumulativeSellVolumeUSD; - let totalVolumeETHDelta = snapshot.cumulativeTotalVolumeETH; let totalVolumeUSDDelta = snapshot.cumulativeTotalVolumeUSD; - let netVolumeETHDelta = snapshot.netVolumeETH; let netVolumeUSDDelta = snapshot.netVolumeUSD; const previousDay = getDaysSinceEpoch( @@ -143,71 +148,44 @@ export function takeFinancialsDailySnapshot( Bytes.fromI32(previousDay) ); if (previousSnapshot) { - supplySideRevenueETHDelta = snapshot.cumulativeSupplySideRevenueETH.minus( - previousSnapshot.cumulativeSupplySideRevenueETH - ); supplySideRevenueUSDDelta = snapshot.cumulativeSupplySideRevenueUSD.minus( previousSnapshot.cumulativeSupplySideRevenueUSD ); - protocolSideRevenueETHDelta = - snapshot.cumulativeProtocolSideRevenueETH.minus( - previousSnapshot.cumulativeProtocolSideRevenueETH - ); protocolSideRevenueUSDDelta = snapshot.cumulativeProtocolSideRevenueUSD.minus( previousSnapshot.cumulativeProtocolSideRevenueUSD ); - totalRevenueETHDelta = snapshot.cumulativeTotalRevenueETH.minus( - previousSnapshot.cumulativeTotalRevenueETH - ); totalRevenueUSDDelta = snapshot.cumulativeTotalRevenueUSD.minus( previousSnapshot.cumulativeTotalRevenueUSD ); - buyVolumeETHDelta = snapshot.cumulativeBuyVolumeETH.minus( - previousSnapshot.cumulativeBuyVolumeETH - ); buyVolumeUSDDelta = snapshot.cumulativeBuyVolumeUSD.minus( previousSnapshot.cumulativeBuyVolumeUSD ); - sellVolumeETHDelta = snapshot.cumulativeSellVolumeETH.minus( - previousSnapshot.cumulativeSellVolumeETH - ); sellVolumeUSDDelta = snapshot.cumulativeSellVolumeUSD.minus( previousSnapshot.cumulativeSellVolumeUSD ); - totalVolumeETHDelta = snapshot.cumulativeTotalVolumeETH.minus( - previousSnapshot.cumulativeTotalVolumeETH - ); totalVolumeUSDDelta = snapshot.cumulativeTotalVolumeUSD.minus( previousSnapshot.cumulativeTotalVolumeUSD ); - netVolumeETHDelta = snapshot.netVolumeETH.minus( - previousSnapshot.netVolumeETH - ); netVolumeUSDDelta = snapshot.netVolumeUSD.minus( previousSnapshot.netVolumeUSD ); } - snapshot.dailySupplySideRevenueETH = supplySideRevenueETHDelta; snapshot.dailySupplySideRevenueUSD = supplySideRevenueUSDDelta; - snapshot.dailyProtocolSideRevenueETH = protocolSideRevenueETHDelta; snapshot.dailyProtocolSideRevenueUSD = protocolSideRevenueUSDDelta; - snapshot.dailyTotalRevenueETH = totalRevenueETHDelta; snapshot.dailyTotalRevenueUSD = totalRevenueUSDDelta; - snapshot.dailyBuyVolumeETH = buyVolumeETHDelta; snapshot.dailyBuyVolumeUSD = buyVolumeUSDDelta; - snapshot.dailySellVolumeETH = sellVolumeETHDelta; snapshot.dailySellVolumeUSD = sellVolumeUSDDelta; - snapshot.dailyTotalVolumeETH = totalVolumeETHDelta; snapshot.dailyTotalVolumeUSD = totalVolumeUSDDelta; - snapshot.dailyNetVolumeETH = netVolumeETHDelta; snapshot.dailyNetVolumeUSD = netVolumeUSDDelta; snapshot.save(); } -export function updateProtocolSnapshots(event: ethereum.Event): void { - const protocol = getOrCreateProtocol(); +export function takeProtocolSnapshots( + protocol: Protocol, + event: ethereum.Event +): void { if ( protocol._lastDailySnapshotTimestamp .plus(BigInt.fromI32(SECONDS_PER_DAY)) @@ -219,207 +197,211 @@ export function updateProtocolSnapshots(event: ethereum.Event): void { protocol._lastDailySnapshotTimestamp = event.block.timestamp; protocol.save(); } -} + if ( + protocol._lastHourlySnapshotTimestamp + .plus(BigInt.fromI32(SECONDS_PER_HOUR)) + .lt(event.block.timestamp) + ) { + takeUsageMetricsHourlySnapshot(protocol, event); -export function updateTraderDailySnapshot( - traderAddress: Address, - amountETH: BigInt, - isBuy: boolean, - event: ethereum.Event -): void { - const trader = getOrCreateTrader(traderAddress, event); - const snapshot = getOrCreateTraderDailySnapshot(traderAddress, event); - const amountUSD = getUsdPriceForEthAmount(amountETH, event); - - if (isBuy) { - snapshot.dailyBuyVolumeETH = snapshot.dailyBuyVolumeETH.plus(amountETH); - snapshot.dailyBuyVolumeUSD = snapshot.dailyBuyVolumeUSD.plus(amountUSD); - snapshot.dailyBuyCount += INT_ONE; - } else { - snapshot.dailySellVolumeETH = snapshot.dailySellVolumeETH.plus(amountETH); - snapshot.dailySellVolumeUSD = snapshot.dailySellVolumeUSD.plus(amountUSD); - snapshot.dailySellCount += INT_ONE; + protocol._lastHourlySnapshotTimestamp = event.block.timestamp; + protocol.save(); } +} - snapshot.dailyTotalVolumeETH = snapshot.dailyBuyVolumeETH.plus( - snapshot.dailySellVolumeETH - ); - snapshot.dailyTotalVolumeUSD = snapshot.dailyBuyVolumeUSD.plus( - snapshot.dailySellVolumeUSD - ); - snapshot.dailyNetVolumeETH = snapshot.dailyBuyVolumeETH.minus( - snapshot.dailySellVolumeETH - ); - snapshot.dailyNetVolumeUSD = snapshot.dailyBuyVolumeUSD.minus( - snapshot.dailySellVolumeUSD - ); - snapshot.dailyTradesCount += INT_ONE; - - snapshot.cumulativeBuyVolumeETH = trader.cumulativeBuyVolumeETH; - snapshot.cumulativeBuyVolumeUSD = trader.cumulativeBuyVolumeUSD; - snapshot.cumulativeSellVolumeETH = trader.cumulativeSellVolumeETH; - snapshot.cumulativeSellVolumeUSD = trader.cumulativeSellVolumeUSD; - snapshot.cumulativeTotalVolumeETH = trader.cumulativeTotalVolumeETH; - snapshot.cumulativeTotalVolumeUSD = trader.cumulativeTotalVolumeUSD; - snapshot.netVolumeETH = trader.netVolumeETH; - snapshot.netVolumeUSD = trader.netVolumeUSD; - - snapshot.cumulativeBuyCount = trader.cumulativeBuyCount; - snapshot.cumulativeSellCount = trader.cumulativeSellCount; - snapshot.cumulativeTradesCount = trader.cumulativeTradesCount; +export function takePoolDailySnapshot(pool: Pool, event: ethereum.Event): void { + const day = getDaysSinceEpoch(event.block.timestamp.toI32()); + const id = Bytes.empty() + .concat(pool.id) + .concat(Bytes.fromUTF8("-")) + .concat(Bytes.fromI32(day)); + const snapshot = new PoolDailySnapshot(id); + snapshot.day = day; + snapshot.pool = pool.id; + snapshot.protocol = NetworkConfigs.getFactoryAddress(); snapshot.blockNumber = event.block.number; snapshot.timestamp = event.block.timestamp; - snapshot.save(); -} + snapshot.totalValueLockedUSD = pool.totalValueLockedUSD; + snapshot.inputTokenBalances = pool.inputTokenBalances; + snapshot.inputTokenBalancesUSD = pool.inputTokenBalancesUSD; -export function updateSubjectDailySnapshot( - subjectAddress: Address, - supply: BigInt, - amountETH: BigInt, - subjectFeeETH: BigInt, - isBuy: boolean, - event: ethereum.Event -): void { - const subject = getOrCreateSubject(subjectAddress, event); - const snapshot = getOrCreateSubjectDailySnapshot(subjectAddress, event); - - const amountUSD = getUsdPriceForEthAmount(amountETH, event); - const subjectFeeUSD = getUsdPriceForEthAmount(subjectFeeETH, event); - - snapshot.dailyRevenueETH = snapshot.dailyRevenueETH.plus(subjectFeeETH); - snapshot.dailyRevenueUSD = snapshot.dailyRevenueUSD.plus(subjectFeeUSD); - - if (isBuy) { - snapshot.dailyBuyVolumeETH = snapshot.dailyBuyVolumeETH.plus(amountETH); - snapshot.dailyBuyVolumeUSD = snapshot.dailyBuyVolumeUSD.plus(amountUSD); - snapshot.dailyBuyCount += INT_ONE; - } else { - snapshot.dailySellVolumeETH = snapshot.dailySellVolumeETH.plus(amountETH); - snapshot.dailySellVolumeUSD = snapshot.dailySellVolumeUSD.plus(amountUSD); - snapshot.dailySellCount += INT_ONE; - } + snapshot.cumulativeSupplySideRevenueUSD = pool.cumulativeSupplySideRevenueUSD; + snapshot.cumulativeProtocolSideRevenueUSD = + pool.cumulativeProtocolSideRevenueUSD; + snapshot.cumulativeTotalRevenueUSD = pool.cumulativeTotalRevenueUSD; + + snapshot.cumulativeBuyVolumeAmount = pool.cumulativeBuyVolumeAmount; + snapshot.cumulativeBuyVolumeUSD = pool.cumulativeBuyVolumeUSD; + snapshot.cumulativeSellVolumeAmount = pool.cumulativeSellVolumeAmount; + snapshot.cumulativeSellVolumeUSD = pool.cumulativeSellVolumeUSD; + snapshot.cumulativeTotalVolumeAmount = pool.cumulativeTotalVolumeAmount; + snapshot.cumulativeTotalVolumeUSD = pool.cumulativeTotalVolumeUSD; + snapshot.netVolumeAmount = pool.netVolumeAmount; + snapshot.netVolumeUSD = pool.netVolumeUSD; + + snapshot.cumulativeUniqueUsers = pool.cumulativeUniqueUsers; + snapshot.cumulativeBuyCount = pool.cumulativeBuyCount; + snapshot.cumulativeSellCount = pool.cumulativeSellCount; + snapshot.cumulativeTransactionCount = pool.cumulativeTransactionCount; - snapshot.dailyTotalVolumeETH = snapshot.dailyBuyVolumeETH.plus( - snapshot.dailySellVolumeETH - ); - snapshot.dailyTotalVolumeUSD = snapshot.dailyBuyVolumeUSD.plus( - snapshot.dailySellVolumeUSD - ); - snapshot.dailyNetVolumeETH = snapshot.dailyBuyVolumeETH.minus( - snapshot.dailySellVolumeETH - ); - snapshot.dailyNetVolumeUSD = snapshot.dailyBuyVolumeUSD.minus( - snapshot.dailySellVolumeUSD - ); - snapshot.dailyTradesCount += INT_ONE; - - snapshot.supply = supply; - snapshot.sharePriceETH = amountETH; - snapshot.sharePriceUSD = amountUSD; - - snapshot.cumulativeRevenueETH = subject.cumulativeRevenueETH; - snapshot.cumulativeRevenueUSD = subject.cumulativeRevenueUSD; - snapshot.cumulativeBuyVolumeETH = subject.cumulativeBuyVolumeETH; - snapshot.cumulativeBuyVolumeUSD = subject.cumulativeBuyVolumeUSD; - snapshot.cumulativeSellVolumeETH = subject.cumulativeSellVolumeETH; - snapshot.cumulativeSellVolumeUSD = subject.cumulativeSellVolumeUSD; - snapshot.cumulativeTotalVolumeETH = subject.cumulativeTotalVolumeETH; - snapshot.cumulativeTotalVolumeUSD = subject.cumulativeTotalVolumeUSD; - snapshot.netVolumeETH = subject.netVolumeETH; - snapshot.netVolumeUSD = subject.netVolumeUSD; - - snapshot.cumulativeBuyCount = subject.cumulativeBuyCount; - snapshot.cumulativeSellCount = subject.cumulativeSellCount; - snapshot.cumulativeTradesCount = subject.cumulativeTradesCount; + let supplySideRevenueUSDDelta = snapshot.cumulativeSupplySideRevenueUSD; + let protocolSideRevenueUSDDelta = snapshot.cumulativeProtocolSideRevenueUSD; + let totalRevenueUSDDelta = snapshot.cumulativeTotalRevenueUSD; + let buyVolumeAmountDelta = snapshot.cumulativeBuyVolumeAmount; + let buyVolumeUSDDelta = snapshot.cumulativeBuyVolumeUSD; + let sellVolumeAmountDelta = snapshot.cumulativeSellVolumeAmount; + let sellVolumeUSDDelta = snapshot.cumulativeSellVolumeUSD; + let totalVolumeAmountDelta = snapshot.cumulativeTotalVolumeAmount; + let totalVolumeUSDDelta = snapshot.cumulativeTotalVolumeUSD; + let netVolumeAmountDelta = snapshot.netVolumeAmount; + let netVolumeUSDDelta = snapshot.netVolumeUSD; + let activeUsersDelta = snapshot.cumulativeUniqueUsers; + let buyCountDelta = snapshot.cumulativeBuyCount; + let sellCountDelta = snapshot.cumulativeSellCount; + let transactionCountDelta = snapshot.cumulativeTransactionCount; - snapshot.blockNumber = event.block.number; - snapshot.timestamp = event.block.timestamp; + const previousDay = getDaysSinceEpoch( + pool._lastDailySnapshotTimestamp!.toI32() + ); + const previousSnapshot = PoolDailySnapshot.load(Bytes.fromI32(previousDay)); + if (previousSnapshot) { + supplySideRevenueUSDDelta = snapshot.cumulativeSupplySideRevenueUSD.minus( + previousSnapshot.cumulativeSupplySideRevenueUSD + ); + protocolSideRevenueUSDDelta = + snapshot.cumulativeProtocolSideRevenueUSD.minus( + previousSnapshot.cumulativeProtocolSideRevenueUSD + ); + totalRevenueUSDDelta = snapshot.cumulativeTotalRevenueUSD.minus( + previousSnapshot.cumulativeTotalRevenueUSD + ); + buyVolumeUSDDelta = snapshot.cumulativeBuyVolumeUSD.minus( + previousSnapshot.cumulativeBuyVolumeUSD + ); + buyVolumeAmountDelta = snapshot.cumulativeBuyVolumeAmount.minus( + previousSnapshot.cumulativeBuyVolumeAmount + ); + sellVolumeUSDDelta = snapshot.cumulativeSellVolumeUSD.minus( + previousSnapshot.cumulativeSellVolumeUSD + ); + sellVolumeAmountDelta = snapshot.cumulativeSellVolumeAmount.minus( + previousSnapshot.cumulativeSellVolumeAmount + ); + totalVolumeUSDDelta = snapshot.cumulativeTotalVolumeUSD.minus( + previousSnapshot.cumulativeTotalVolumeUSD + ); + totalVolumeAmountDelta = snapshot.cumulativeTotalVolumeAmount.minus( + previousSnapshot.cumulativeTotalVolumeAmount + ); + netVolumeUSDDelta = snapshot.netVolumeUSD.minus( + previousSnapshot.netVolumeUSD + ); + netVolumeAmountDelta = snapshot.netVolumeAmount.minus( + previousSnapshot.netVolumeAmount + ); + activeUsersDelta = + snapshot.cumulativeUniqueUsers - previousSnapshot.cumulativeUniqueUsers; + buyCountDelta = + snapshot.cumulativeBuyCount - previousSnapshot.cumulativeBuyCount; + sellCountDelta = + snapshot.cumulativeSellCount - previousSnapshot.cumulativeSellCount; + transactionCountDelta = + snapshot.cumulativeTransactionCount - + previousSnapshot.cumulativeTransactionCount; + } + snapshot.dailySupplySideRevenueUSD = supplySideRevenueUSDDelta; + snapshot.dailyProtocolSideRevenueUSD = protocolSideRevenueUSDDelta; + snapshot.dailyTotalRevenueUSD = totalRevenueUSDDelta; + snapshot.dailyBuyVolumeAmount = buyVolumeAmountDelta; + snapshot.dailyBuyVolumeUSD = buyVolumeUSDDelta; + snapshot.dailySellVolumeAmount = sellVolumeAmountDelta; + snapshot.dailySellVolumeUSD = sellVolumeUSDDelta; + snapshot.dailyTotalVolumeAmount = totalVolumeAmountDelta; + snapshot.dailyTotalVolumeUSD = totalVolumeUSDDelta; + snapshot.dailyNetVolumeAmount = netVolumeAmountDelta; + snapshot.dailyNetVolumeUSD = netVolumeUSDDelta; + snapshot.dailyActiveUsers = activeUsersDelta; + snapshot.dailyBuyCount = buyCountDelta; + snapshot.dailySellCount = sellCountDelta; + snapshot.dailyTransactionCount = transactionCountDelta; snapshot.save(); } -export function updateConnectionDailySnapshot( - traderAddress: Address, - subjectAddress: Address, - amountETH: BigInt, - isBuy: boolean, +export function takePoolHourlySnapshot( + pool: Pool, event: ethereum.Event ): void { - const connection = getOrCreateConnection( - traderAddress, - subjectAddress, - event - ); - const snapshot = getOrCreateConnectionDailySnapshot( - traderAddress, - subjectAddress, - event - ); - const amountUSD = getUsdPriceForEthAmount(amountETH, event); - - if (isBuy) { - snapshot.dailyBuyVolumeETH = snapshot.dailyBuyVolumeETH.plus(amountETH); - snapshot.dailyBuyVolumeUSD = snapshot.dailyBuyVolumeUSD.plus(amountUSD); - snapshot.dailyBuyCount += INT_ONE; - } else { - snapshot.dailySellVolumeETH = snapshot.dailySellVolumeETH.plus(amountETH); - snapshot.dailySellVolumeUSD = snapshot.dailySellVolumeUSD.plus(amountUSD); - snapshot.dailySellCount += INT_ONE; - } + const hour = getHoursSinceEpoch(event.block.timestamp.toI32()); + const id = Bytes.empty() + .concat(pool.id) + .concat(Bytes.fromUTF8("-")) + .concat(Bytes.fromI32(hour)); + const snapshot = new PoolHourlySnapshot(id); + + snapshot.hour = hour; + snapshot.pool = pool.id; + snapshot.protocol = NetworkConfigs.getFactoryAddress(); + snapshot.blockNumber = event.block.number; + snapshot.timestamp = event.block.timestamp; - snapshot.dailyTotalVolumeETH = snapshot.dailyBuyVolumeETH.plus( - snapshot.dailySellVolumeETH - ); - snapshot.dailyTotalVolumeUSD = snapshot.dailyBuyVolumeUSD.plus( - snapshot.dailySellVolumeUSD - ); - snapshot.dailyNetVolumeETH = snapshot.dailyBuyVolumeETH.minus( - snapshot.dailySellVolumeETH - ); - snapshot.dailyNetVolumeUSD = snapshot.dailyBuyVolumeUSD.minus( - snapshot.dailySellVolumeUSD - ); - snapshot.dailyTradesCount += INT_ONE; + snapshot.totalValueLockedUSD = pool.totalValueLockedUSD; + snapshot.inputTokenBalances = pool.inputTokenBalances; + snapshot.inputTokenBalancesUSD = pool.inputTokenBalancesUSD; - snapshot.shares = connection.shares; - snapshot.cumulativeBuyVolumeETH = connection.cumulativeBuyVolumeETH; - snapshot.cumulativeBuyVolumeUSD = connection.cumulativeBuyVolumeUSD; - snapshot.cumulativeSellVolumeETH = connection.cumulativeSellVolumeETH; - snapshot.cumulativeSellVolumeUSD = connection.cumulativeSellVolumeUSD; - snapshot.cumulativeTotalVolumeETH = connection.cumulativeTotalVolumeETH; - snapshot.cumulativeTotalVolumeUSD = connection.cumulativeTotalVolumeUSD; - snapshot.netVolumeETH = connection.netVolumeETH; - snapshot.netVolumeUSD = connection.netVolumeUSD; + snapshot.cumulativeSupplySideRevenueUSD = pool.cumulativeSupplySideRevenueUSD; + snapshot.cumulativeProtocolSideRevenueUSD = + pool.cumulativeProtocolSideRevenueUSD; + snapshot.cumulativeTotalRevenueUSD = pool.cumulativeTotalRevenueUSD; - snapshot.cumulativeBuyCount = connection.cumulativeBuyCount; - snapshot.cumulativeSellCount = connection.cumulativeSellCount; - snapshot.cumulativeTradesCount = connection.cumulativeTradesCount; + let supplySideRevenueUSDDelta = snapshot.cumulativeSupplySideRevenueUSD; + let protocolSideRevenueUSDDelta = snapshot.cumulativeProtocolSideRevenueUSD; + let totalRevenueUSDDelta = snapshot.cumulativeTotalRevenueUSD; - snapshot.createdBlockNumber = event.block.number; - snapshot.createdTimestamp = event.block.timestamp; + const previousHour = getHoursSinceEpoch( + pool._lastHourlySnapshotTimestamp!.toI32() + ); + const previousSnapshot = PoolHourlySnapshot.load(Bytes.fromI32(previousHour)); + if (previousSnapshot) { + supplySideRevenueUSDDelta = snapshot.cumulativeSupplySideRevenueUSD.minus( + previousSnapshot.cumulativeSupplySideRevenueUSD + ); + protocolSideRevenueUSDDelta = + snapshot.cumulativeProtocolSideRevenueUSD.minus( + previousSnapshot.cumulativeProtocolSideRevenueUSD + ); + totalRevenueUSDDelta = snapshot.cumulativeTotalRevenueUSD.minus( + previousSnapshot.cumulativeTotalRevenueUSD + ); + } + snapshot.hourlySupplySideRevenueUSD = supplySideRevenueUSDDelta; + snapshot.hourlyProtocolSideRevenueUSD = protocolSideRevenueUSDDelta; + snapshot.hourlyTotalRevenueUSD = totalRevenueUSDDelta; snapshot.save(); +} - const traderSnapshot = getOrCreateTraderDailySnapshot(traderAddress, event); - if (!traderSnapshot.connections.includes(snapshot.id)) { - traderSnapshot.connections = addToArrayAtIndex( - traderSnapshot.connections, - snapshot.id - ); +export function takePoolSnapshots(pool: Pool, event: ethereum.Event): void { + if ( + pool._lastDailySnapshotTimestamp + .plus(BigInt.fromI32(SECONDS_PER_DAY)) + .lt(event.block.timestamp) + ) { + takePoolDailySnapshot(pool, event); + + pool._lastDailySnapshotTimestamp = event.block.timestamp; + pool.save(); } - traderSnapshot.save(); + if ( + pool._lastHourlySnapshotTimestamp + .plus(BigInt.fromI32(SECONDS_PER_HOUR)) + .lt(event.block.timestamp) + ) { + takePoolHourlySnapshot(pool, event); - const subjectSnapshot = getOrCreateSubjectDailySnapshot( - subjectAddress, - event - ); - if (!subjectSnapshot.connections.includes(snapshot.id)) { - subjectSnapshot.connections = addToArrayAtIndex( - subjectSnapshot.connections, - snapshot.id - ); + pool._lastHourlySnapshotTimestamp = event.block.timestamp; + pool.save(); } - subjectSnapshot.save(); } diff --git a/subgraphs/friend-tech/src/common/utils.ts b/subgraphs/friend-tech/src/common/utils.ts index 0b8f8560a7..375804eb3b 100644 --- a/subgraphs/friend-tech/src/common/utils.ts +++ b/subgraphs/friend-tech/src/common/utils.ts @@ -1,4 +1,11 @@ -import { SECONDS_PER_DAY } from "./constants"; +import { BigDecimal, BigInt } from "@graphprotocol/graph-ts"; + +import { + BIGINT_TEN, + ETH_DECIMALS, + SECONDS_PER_DAY, + SECONDS_PER_HOUR, +} from "./constants"; export function addToArrayAtIndex(x: T[], item: T, index: i32 = -1): T[] { if (x.length == 0) { @@ -24,3 +31,14 @@ export function addToArrayAtIndex(x: T[], item: T, index: i32 = -1): T[] { export function getDaysSinceEpoch(secondsSinceEpoch: number): i32 { return Math.floor(secondsSinceEpoch / SECONDS_PER_DAY); } + +export function getHoursSinceEpoch(secondsSinceEpoch: number): i32 { + return Math.floor(secondsSinceEpoch / SECONDS_PER_HOUR); +} + +export function bigIntToBigDecimal( + quantity: BigInt, + decimals: i32 = ETH_DECIMALS +): BigDecimal { + return quantity.divDecimal(BIGINT_TEN.pow(decimals as u8).toBigDecimal()); +} diff --git a/subgraphs/friend-tech/src/mappings/handlers.ts b/subgraphs/friend-tech/src/mappings/handlers.ts index 88e882cc62..14e3bc23b6 100644 --- a/subgraphs/friend-tech/src/mappings/handlers.ts +++ b/subgraphs/friend-tech/src/mappings/handlers.ts @@ -1,65 +1,73 @@ import { - updateConnections, + getOrCreateAccount, + getOrCreateConnection, + getOrCreatePool, + getOrCreateProtocol, + getOrCreateToken, +} from "../common/getters"; +import { + updateConnection, updateRevenue, - updateSubjectPrice, + updateShares, updateTVL, updateUsage, updateVolume, } from "../common/metrics"; -import { - updateConnectionDailySnapshot, - updateProtocolSnapshots, - updateSubjectDailySnapshot, - updateTraderDailySnapshot, -} from "../common/snapshots"; -import { createEvent } from "../common/events"; +import { takePoolSnapshots, takeProtocolSnapshots } from "../common/snapshots"; +import { createTrade } from "../common/events"; import { Trade } from "../../generated/Shares/Shares"; export function handleTrade(event: Trade): void { - const trader = event.params.trader; - const subject = event.params.subject; + const traderAddress = event.params.trader; + const subjectAddress = event.params.subject; const isBuy = event.params.isBuy; const shares = event.params.shareAmount; const supply = event.params.supply; - const tradeAmountETH = event.params.ethAmount; - const subjectFeeETH = event.params.subjectEthAmount; - const protocolFeeETH = event.params.protocolEthAmount; - const sharePriceETH = event.params.ethAmount.minus( + const sharePriceAmount = event.params.ethAmount; + const subjectFeeAmount = event.params.subjectEthAmount; + const protocolFeeAmount = event.params.protocolEthAmount; + const tradeAmount = event.params.ethAmount.plus( event.params.subjectEthAmount.plus(event.params.protocolEthAmount) ); - updateTVL(sharePriceETH, isBuy, event); - updateUsage(trader, subject, isBuy, event); - updateRevenue(subject, subjectFeeETH, protocolFeeETH, event); - updateVolume(trader, subject, sharePriceETH, isBuy, event); - - updateConnections(trader, subject, shares, sharePriceETH, isBuy, event); - updateSubjectPrice(subject, supply, tradeAmountETH, event); - - updateProtocolSnapshots(event); - updateTraderDailySnapshot(trader, sharePriceETH, isBuy, event); - updateSubjectDailySnapshot( - subject, - supply, - sharePriceETH, - subjectFeeETH, - isBuy, + const token = getOrCreateToken(event); + const protocol = getOrCreateProtocol(); + const pool = getOrCreatePool(subjectAddress, event); + const account = getOrCreateAccount(traderAddress, event); + const connection = getOrCreateConnection( + traderAddress, + subjectAddress, event ); - updateConnectionDailySnapshot(trader, subject, sharePriceETH, isBuy, event); - createEvent( - trader, - subject, + const tradeID = createTrade( + token, + traderAddress, + subjectAddress, shares, - sharePriceETH, - subjectFeeETH, - protocolFeeETH, - tradeAmountETH, + sharePriceAmount, + subjectFeeAmount, + protocolFeeAmount, + tradeAmount, isBuy, event ); + updateTVL(token, protocol, pool, sharePriceAmount, isBuy); + updateRevenue(token, protocol, pool, subjectFeeAmount, protocolFeeAmount); + updateVolume(token, protocol, pool, account, sharePriceAmount, isBuy); + updateShares(token, pool, sharePriceAmount, supply); + updateUsage(protocol, pool, account, isBuy, tradeID); + updateConnection(token, connection, shares, sharePriceAmount, isBuy); + + takeProtocolSnapshots(protocol, event); + takePoolSnapshots(pool, event); + + connection.save(); + account.save(); + pool.save(); + protocol.save(); + return; } From f3edcb91105c3e014b9e4626609da4b288291bfb Mon Sep 17 00:00:00 2001 From: Dhruv Chauhan Date: Tue, 28 Nov 2023 12:57:35 +0530 Subject: [PATCH 09/10] fix: totalPoolCount --- subgraphs/friend-tech/src/common/getters.ts | 12 +----------- subgraphs/friend-tech/src/mappings/handlers.ts | 2 +- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/subgraphs/friend-tech/src/common/getters.ts b/subgraphs/friend-tech/src/common/getters.ts index 40a022a7e1..6fb3919cf1 100644 --- a/subgraphs/friend-tech/src/common/getters.ts +++ b/subgraphs/friend-tech/src/common/getters.ts @@ -86,18 +86,17 @@ export function getOrCreateProtocol(): Protocol { protocol.subgraphVersion = Versions.getSubgraphVersion(); protocol.methodologyVersion = Versions.getMethodologyVersion(); - protocol.save(); return protocol; } export function getOrCreatePool( + protocol: Protocol, poolAddress: Address, event: ethereum.Event ): Pool { let pool = Pool.load(poolAddress); if (!pool) { - const protocol = getOrCreateProtocol(); pool = new Pool(poolAddress); pool.protocol = protocol.id; pool.name = "Subject-" + poolAddress.toHexString(); @@ -136,9 +135,6 @@ export function getOrCreatePool( pool._lastHourlySnapshotTimestamp = BIGINT_ZERO; protocol.totalPoolCount += INT_ONE; - - pool.save(); - protocol.save(); } return pool; } @@ -167,8 +163,6 @@ export function getOrCreateAccount( trader.buys = []; trader.sells = []; trader.subjects = []; - - trader.save(); } return trader; } @@ -190,8 +184,6 @@ export function getOrCreateConnection( connection.trader = traderAddress; connection.subject = subjectAddress; - - // TODO connection.shares = BIGINT_ZERO; connection.cumulativeBuyVolumeUSD = BIGDECIMAL_ZERO; @@ -205,8 +197,6 @@ export function getOrCreateConnection( connection.createdTimestamp = event.block.timestamp; connection.createdBlockNumber = event.block.number; - - connection.save(); } return connection; } diff --git a/subgraphs/friend-tech/src/mappings/handlers.ts b/subgraphs/friend-tech/src/mappings/handlers.ts index 14e3bc23b6..ff6367a5d9 100644 --- a/subgraphs/friend-tech/src/mappings/handlers.ts +++ b/subgraphs/friend-tech/src/mappings/handlers.ts @@ -33,7 +33,7 @@ export function handleTrade(event: Trade): void { const token = getOrCreateToken(event); const protocol = getOrCreateProtocol(); - const pool = getOrCreatePool(subjectAddress, event); + const pool = getOrCreatePool(protocol, subjectAddress, event); const account = getOrCreateAccount(traderAddress, event); const connection = getOrCreateConnection( traderAddress, From 0bf60cd2343d069d6b64644619d1965e4acede66 Mon Sep 17 00:00:00 2001 From: Dhruv Chauhan Date: Wed, 29 Nov 2023 11:55:14 +0530 Subject: [PATCH 10/10] cleanup --- deployment/deployment.json | 4 +- subgraphs/friend-tech/abis/Shares.json | 239 ++++++++++++++++++++++++- 2 files changed, 240 insertions(+), 3 deletions(-) diff --git a/deployment/deployment.json b/deployment/deployment.json index 83bd38114d..34d5559b7b 100644 --- a/deployment/deployment.json +++ b/deployment/deployment.json @@ -9767,9 +9767,9 @@ "deployments": { "friend-tech-base": { "network": "base", - "status": "dev", + "status": "prod", "versions": { - "schema": "1.0.0", + "schema": "2.1.1", "subgraph": "1.0.0", "methodology": "1.0.0" }, diff --git a/subgraphs/friend-tech/abis/Shares.json b/subgraphs/friend-tech/abis/Shares.json index c3044ce178..e2058a4df7 100644 --- a/subgraphs/friend-tech/abis/Shares.json +++ b/subgraphs/friend-tech/abis/Shares.json @@ -1 +1,238 @@ -[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"trader","type":"address"},{"indexed":false,"internalType":"address","name":"subject","type":"address"},{"indexed":false,"internalType":"bool","name":"isBuy","type":"bool"},{"indexed":false,"internalType":"uint256","name":"shareAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"protocolEthAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"subjectEthAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"supply","type":"uint256"}],"name":"Trade","type":"event"},{"inputs":[{"internalType":"address","name":"sharesSubject","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"buyShares","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"sharesSubject","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getBuyPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sharesSubject","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getBuyPriceAfterFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"sharesSubject","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getSellPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sharesSubject","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getSellPriceAfterFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeeDestination","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sharesSubject","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sellShares","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeDestination","type":"address"}],"name":"setFeeDestination","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feePercent","type":"uint256"}],"name":"setProtocolFeePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feePercent","type":"uint256"}],"name":"setSubjectFeePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"sharesBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"sharesSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"subjectFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "trader", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "subject", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isBuy", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shareAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ethAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "protocolEthAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "subjectEthAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "supply", + "type": "uint256" + } + ], + "name": "Trade", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "sharesSubject", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "buyShares", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "sharesSubject", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "getBuyPrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "sharesSubject", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "getBuyPriceAfterFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "supply", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "getPrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "sharesSubject", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "getSellPrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "sharesSubject", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "getSellPriceAfterFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFeeDestination", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFeePercent", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "sharesSubject", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "sellShares", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeDestination", + "type": "address" + } + ], + "name": "setFeeDestination", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_feePercent", "type": "uint256" } + ], + "name": "setProtocolFeePercent", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_feePercent", "type": "uint256" } + ], + "name": "setSubjectFeePercent", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "sharesBalance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "sharesSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "subjectFeePercent", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +]