diff --git a/README-es.md b/README-es.md index 2395a50..9d873d1 100644 --- a/README-es.md +++ b/README-es.md @@ -1,5 +1,4 @@ -Ink! Explorer API -================= +# Ink! Explorer API [![App Build](https://github.com/blockcoders/ink-substrate-explorer-api/actions/workflows/pr.yaml/badge.svg)](https://github.com/blockcoders/ink-substrate-explorer-api/actions/workflows/pr.yaml) [![Coverage Status](https://coveralls.io/repos/github/blockcoders/ink-substrate-explorer-api/badge.svg?branch=main)](https://coveralls.io/github/blockcoders/ink-substrate-explorer-api?branch=main) @@ -144,6 +143,7 @@ Para iniciar los contenedores del servicio de backend, la BD y pgAdmin ejecutar ```sh docker-compose up -d ``` + **Nota**: Se requiere una base de datos postgres en funcionamiento y una conexión válida a un nodo de Substrate. Opcionalmente, comente el servicio de back-end en el archivo docker-compose si desea ejecutar la imagen localmente. @@ -228,14 +228,34 @@ query { } ``` + **Version**: Recupera la version de la aplicación + +```graphql +query { + status +} +``` + + Respuesta: + +```graphql +{ + "data": { + "version": "v1.0.1" + } +} +``` + **getBlock**: Recupera el bloque por hash ```graphql query { - getBlock(hash: "0x05815b7f1706f46d101b6073ebfa6d47ae9089b5ce5db9deb80382198689466a") { + getBlock(hash: "0x0f615cf7edf8a1e8591893a594fe0ef67d5d56c4d9b1a89d8d120c5f821127fe") { hash number parentHash + timestamp + encodedLength transactions { hash } @@ -249,15 +269,17 @@ query { { "data": { "getBlock": { - "hash": "0x05815b7f1706f46d101b6073ebfa6d47ae9089b5ce5db9deb80382198689466a", - "number": 934059, - "parentHash": "0x31c5025aa86e3af7d77991c8ad3442b01be768399d22af004d9ea5fa771e3827", + "hash": "0x0f615cf7edf8a1e8591893a594fe0ef67d5d56c4d9b1a89d8d120c5f821127fe", + "number": 7, + "parentHash": "0xd8ecc752f280a3786c5cdd4d441d71488414fd6132ace481dd6ddb23fd8000b0", + "timestamp": 1666888006111, + "encodedLength": 312, "transactions": [ { - "hash": "0x9bb5a80b80305b4b1acc93214e3a703e2c3c879b3fae91bfc809ad91753195da" + "hash": "0xdb561ee4432e07a959292acf9895ce379e2474a52160b93fd62496806fdf26cd" }, { - "hash": "0xc49a19fe985222ca0b9b2f8b2f83c65e00efd57552ac245a4c362f882b999040" + "hash": "0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b" } ] } @@ -265,14 +287,16 @@ query { } ``` - **getBlocks**: Recupera bloques (use skip and take para paginar) + **getBlocks**: Recupera bloques. Use 'skip' y 'take' para paginar. Use 'orderByNumber: false' para ordenar por tiempo y 'orderAsc: true' para ver primero los bloques más antiguos. ```graphql query { - getBlocks(skip: 0, take: 10) { + getBlocks(skip: 0, take: 1, orderByNumber: false, orderAsc: false) { hash number parentHash + timestamp + encodedLength transactions { hash } @@ -287,19 +311,21 @@ query { "data": { "getBlocks": [ { - "hash": "0xec403717319c75ad80f6c5a43446dac41a44c2ddf086eedad622d8d784f90d46", - "number": 934057, - "parentHash": "0x0b3e49c138c74f0afc9034a325a25c90433990e0dfdf6f6c9697c591f7c8e7b3", + "hash": "0x0f615cf7edf8a1e8591893a594fe0ef67d5d56c4d9b1a89d8d120c5f821127fe", + "number": 7, + "parentHash": "0xd8ecc752f280a3786c5cdd4d441d71488414fd6132ace481dd6ddb23fd8000b0", + "timestamp": 1666888006111, + "encodedLength": 312, "transactions": [ { - "hash": "0x20be54758f8645bfd1b1f38d798271471edef3deadee1d7a4cd74e628120292a" + "hash": "0xdb561ee4432e07a959292acf9895ce379e2474a52160b93fd62496806fdf26cd" }, { - "hash": "0xf9e94bd8286080340a48dd105eb5d4ab7bbf7aa92869b5537c2b3c5fa8c58ba5" + "hash": "0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b" } ] - }, - ...] + } + ] } } ``` @@ -308,15 +334,28 @@ query { ```graphql query { - getTransaction(hash: "0xfaed625a9948f88aac7b1ff353492cd5834108cfecb1ede82d7bc2f763fcbd28") { - hash + getTransaction(hash: "0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b") { + args blockHash + callIndex + decimals + encodedLength + era + events { + method + } + hash method nonce section signature signer + ss58 + timestamp tip + tokens + type + version } } ``` @@ -327,32 +366,131 @@ query { { "data": { "getTransaction": { - "hash": "0xfaed625a9948f88aac7b1ff353492cd5834108cfecb1ede82d7bc2f763fcbd28", - "blockHash": "0xe138e4b9db53b1a552c26d3f4c3e7573d369512bfb402632d48d6c90521c9922", - "method": "setValidationData", - "nonce": 0, - "section": "parachainSystem", - "signature": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "signer": "5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM", - "tip": 0 + "args": "{\"dest\":{\"id\":\"5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8\"},\"value\":0,\"gas_limit\":75000000000,\"storage_deposit_limit\":null,\"data\":\"0x84a15da18eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48005039278c0400000000000000000000\"}", + "blockHash": "0x0f615cf7edf8a1e8591893a594fe0ef67d5d56c4d9b1a89d8d120c5f821127fe", + "callIndex": "7,0", + "decimals": "12", + "encodedLength": 201, + "era": "{\"mortalEra\":\"0x0b00\"}", + "events": [ + { + "method": "ContractEmitted" + } + ], + "hash": "0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b", + "method": "call", + "nonce": 3, + "section": "contracts", + "signature": "0x78582786706e947a6d77ac5b49ba140b4c88ebc644421136bbfa8b66577e1e3efdbc1d981948546fff41600be9a716e4c38a8531a867853f26ba11ee21128f82", + "signer": "5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc", + "ss58": "42", + "timestamp": 1666888006111, + "tip": 0, + "tokens": "Unit", + "type": 4, + "version": 132 } } } ``` - **getTransactions**: Recupera transacciones por hash de bloque (use skip and take para paginar) + **getTransactionsByContract**: Recupera una lista de transacciones de un contrato. ```graphql query { - getTransactions(blockHash: "0xa7ef8085bfad2354e5191e012bd412c0d76c213f43a68187194b7696a0822b93") { + getTransactionsByContract( + address: "5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8" + skip: 0 + take: 1 + orderAsc: false + ) { + args + blockHash + callIndex + decimals + encodedLength + era + events { + method + } hash + method + nonce + section + signature + signer + ss58 + timestamp + tip + tokens + type + version + } +} +``` + + Respuesta: + +```graphql +{ + "data": { + "getTransactionsByContract": [ + { + "args": "{\"dest\":{\"id\":\"5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8\"},\"value\":0,\"gas_limit\":75000000000,\"storage_deposit_limit\":null,\"data\":\"0x84a15da18eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48005039278c0400000000000000000000\"}", + "blockHash": "0x0f615cf7edf8a1e8591893a594fe0ef67d5d56c4d9b1a89d8d120c5f821127fe", + "callIndex": "7,0", + "decimals": "12", + "encodedLength": 201, + "era": "{\"mortalEra\":\"0x0b00\"}", + "events": [ + { + "method": "ContractEmitted" + } + ], + "hash": "0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b", + "method": "call", + "nonce": 3, + "section": "contracts", + "signature": "0x78582786706e947a6d77ac5b49ba140b4c88ebc644421136bbfa8b66577e1e3efdbc1d981948546fff41600be9a716e4c38a8531a867853f26ba11ee21128f82", + "signer": "5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc", + "ss58": "42", + "timestamp": 1666888006111, + "tip": 0, + "tokens": "Unit", + "type": 4, + "version": 132 + } + ] + } +} +``` + + **getTransactions**: Recupera transacciones por hash de bloque (use 'skip' y 'take' para paginar. use 'orderAsc' para ver primero las más antiguas o las más nuevas) + +```graphql +query { + getTransactions(skip: 0, take: 1, orderAsc: false) { + args blockHash + callIndex + decimals + encodedLength + era + events { + method + } + hash method nonce section signature signer + ss58 + timestamp tip + tokens + type + version } } ``` @@ -364,33 +502,86 @@ query { "data": { "getTransactions": [ { - "hash": "0xf715221f0e46c5a666e65e99af70631cc32a46cf6121ed3be56768ff303eda36", - "blockHash": "0xa7ef8085bfad2354e5191e012bd412c0d76c213f43a68187194b7696a0822b93", - "method": "setValidationData", + "args": "{\"now\":1666888006111}", + "blockHash": "0x0f615cf7edf8a1e8591893a594fe0ef67d5d56c4d9b1a89d8d120c5f821127fe", + "callIndex": "2,0", + "decimals": "12", + "encodedLength": 11, + "era": "{\"immortalEra\":\"0x00\"}", + "events": [], + "hash": "0xdb561ee4432e07a959292acf9895ce379e2474a52160b93fd62496806fdf26cd", + "method": "set", "nonce": 0, - "section": "parachainSystem", + "section": "timestamp", "signature": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "signer": "5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM", + "ss58": "42", + "timestamp": 1666888006111, "tip": 0, - "events": [] - }, - ... + "tokens": "Unit", + "type": 4, + "version": 4 + } ] } } ``` - **getEvents**: Recupera eventos por dirección de contrato o hash de transacción (use skip and take para paginar) + **getEvent**: Recupera un evento por su id ```graphql query { - getEvents(contract: "5F7FvAUyB6ok4Sj3j82x315F3pDCZSiGovxWcnjadnpSMi7t") { + getEvent(id: "81735cc9-76d3-5984-83af-5872bc9eaeb7") { id index method section + timestamp topics transactionHash + data + decodedData + formattedData + } +} +``` + + Respuesta: + +```graphql +{ + "data": { + "getEvent": { + "id": "81735cc9-76d3-5984-83af-5872bc9eaeb7", + "index": "0x0703", + "method": "ContractEmitted", + "section": "contracts", + "timestamp": 1666888006111, + "topics": "[0x0045726332303a3a5472616e7366657200000000000000000000000000000000, 0x08be862c40d599dc6f4f28076712bb324c0cd2197c30f07459887b41fadff2c8, 0x2b00c7d40fe6d84d660f3e6bed90f218e022a0909f7e1a7ea35ada8b6e003564]", + "transactionHash": "0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b", + "data": "[\"5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8\",\"0x0001c40e2006bbebf9022c317f9337ad376e56d392917e5ac1397fe09b07c765c050018eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48005039278c0400000000000000000000\"]", + "decodedData": "{\"args\":[\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\",\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\",\"0x00000000000000000000048c27395000\"],\"event\":{\"args\":[{\"name\":\"from\",\"type\":{\"sub\":{\"docs\":[],\"info\":10,\"type\":\"AccountId\",\"namespace\":\"ink_env::types::AccountId\",\"lookupIndex\":2,\"lookupNameRoot\":\"InkEnvAccountId\"},\"docs\":[],\"info\":9,\"type\":\"Option\",\"namespace\":\"Option\",\"lookupIndex\":11}},{\"name\":\"to\",\"type\":{\"sub\":{\"docs\":[],\"info\":10,\"type\":\"AccountId\",\"namespace\":\"ink_env::types::AccountId\",\"lookupIndex\":2,\"lookupNameRoot\":\"InkEnvAccountId\"},\"docs\":[],\"info\":9,\"type\":\"Option\",\"namespace\":\"Option\",\"lookupIndex\":11}},{\"name\":\"value\",\"type\":{\"info\":10,\"type\":\"Balance\"}}],\"docs\":[\" Event emitted when a token transfer occurs.\"],\"index\":0,\"identifier\":\"Transfer\"}}", + "formattedData": "{\"from\":\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\",\"to\":\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\",\"value\":5}" + } + } +} +``` + + **getEvents**: Recupera eventos por dirección de contrato o hash de transacción (use 'skip' y 'take' para paginar, 'orderAsc' para ver primero los más antiguos o los más nuevos) + +```graphql +query { + getEvents(contract: "5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8", skip: 0, take: 1, orderAsc: false) { + id + index + method + section + timestamp + topics + transactionHash + data + decodedData + formattedData } } ``` @@ -402,31 +593,31 @@ query { "data": { "getEvents": [ { - "id": "c3250479-e53e-5a4d-ba0c-b688764cd81b", + "id": "81735cc9-76d3-5984-83af-5872bc9eaeb7", "index": "0x0703", - "section": "contracts", "method": "ContractEmitted", - "transactionHash": "0x1080eb1f8de1ee5b0c1bd584924951c38b998bc7596773ef5e1a92908409a17f", - "topics": "[0x0045726332303a3a5472616e7366657200000000000000000000000000000000, 0x33766995fd9b44bd45f351b3abd7e5041960638db0075c84ab7af1a734e20d1b, 0x5445726332303a3a5472616e736665723a3a66726f6d00000000000000000000]" - }, - { - "id": "509f2fb6-ed61-5dc7-a567-3cfa55e1fa65", - "index": "0x0703", "section": "contracts", - "method": "ContractEmitted", - "transactionHash": "0x2a009bf5fdc388f10953cba4661c3ca74e0252c1fcae6ba7f39f4eb7be707caa", - "topics": "[0x0045726332303a3a5472616e7366657200000000000000000000000000000000, 0x2b00c7d40fe6d84d660f3e6bed90f218e022a0909f7e1a7ea35ada8b6e003564, 0xda2d695d3b5a304e0039e7fc4419c34fa0c1f239189c99bb72a6484f1634782b]" + "timestamp": 1666888006111, + "topics": "[0x0045726332303a3a5472616e7366657200000000000000000000000000000000, 0x08be862c40d599dc6f4f28076712bb324c0cd2197c30f07459887b41fadff2c8, 0x2b00c7d40fe6d84d660f3e6bed90f218e022a0909f7e1a7ea35ada8b6e003564]", + "transactionHash": "0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b", + "data": "[\"5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8\",\"0x0001c40e2006bbebf9022c317f9337ad376e56d392917e5ac1397fe09b07c765c050018eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48005039278c0400000000000000000000\"]", + "decodedData": "{\"args\":[\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\",\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\",\"0x00000000000000000000048c27395000\"],\"event\":{\"args\":[{\"name\":\"from\",\"type\":{\"sub\":{\"docs\":[],\"info\":10,\"type\":\"AccountId\",\"namespace\":\"ink_env::types::AccountId\",\"lookupIndex\":2,\"lookupNameRoot\":\"InkEnvAccountId\"},\"docs\":[],\"info\":9,\"type\":\"Option\",\"namespace\":\"Option\",\"lookupIndex\":11}},{\"name\":\"to\",\"type\":{\"sub\":{\"docs\":[],\"info\":10,\"type\":\"AccountId\",\"namespace\":\"ink_env::types::AccountId\",\"lookupIndex\":2,\"lookupNameRoot\":\"InkEnvAccountId\"},\"docs\":[],\"info\":9,\"type\":\"Option\",\"namespace\":\"Option\",\"lookupIndex\":11}},{\"name\":\"value\",\"type\":{\"info\":10,\"type\":\"Balance\"}}],\"docs\":[\" Event emitted when a token transfer occurs.\"],\"index\":0,\"identifier\":\"Transfer\"}}", + "formattedData": "{\"from\":\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\",\"to\":\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\",\"value\":5}" } ] } } ``` - **decodeEvents**: Decodifica los datos de eventos para un contrato específico. Requiere que los metadatos del contrato ya se hayan subido usando la mutación **uploadMetadata** + **getContract**: Recupera un contrato por address ```graphql query { - decodeEvents(contractAddress: "5G24svh2w4QXNhsHU5XBxf8N3Sw2MPu7sAemofv1bCuyxAzc") + getContract(address: "5G24svh2w4QXNhsHU5XBxf8N3Sw2MPu7sAemofv1bCuyxAzc") { + address + metadata + hasMetadata + } } ``` @@ -435,18 +626,26 @@ query { ```graphql { "data": { - "decodeEvents": "[{\"args\":[null,\"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY\",\"0x000000000000000000038d7ea4c68000\"],\"event\":{\"args\":[{\"name\":\"from\",\"type\":{\"info\":9,\"lookupIndex\":11,\"type\":\"Option\",\"docs\":[],\"namespace\":\"Option\",\"sub\":{\"info\":10,\"lookupIndex\":2,\"type\":\"AccountId\",\"docs\":[],\"namespace\":\"ink_env::types::AccountId\",\"lookupNameRoot\":\"InkEnvAccountId\"}}},{\"name\":\"to\",\"type\":{\"info\":9,\"lookupIndex\":11,\"type\":\"Option\",\"docs\":[],\"namespace\":\"Option\",\"sub\":{\"info\":10,\"lookupIndex\":2,\"type\":\"AccountId\",\"docs\":[],\"namespace\":\"ink_env::types::AccountId\",\"lookupNameRoot\":\"InkEnvAccountId\"}}},{\"name\":\"value\",\"type\":{\"info\":10,\"type\":\"Balance\"}}],\"docs\":[\" Event emitted when a token transfer occurs.\"],\"identifier\":\"Transfer\",\"index\":0}},{\"args\":[\"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY\",\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\",\"0x00000000000000000001c6bf52634000\"],\"event\":{\"args\":[{\"name\":\"from\",\"type\":{\"info\":9,\"lookupIndex\":11,\"type\":\"Option\",\"docs\":[],\"namespace\":\"Option\",\"sub\":{\"info\":10,\"lookupIndex\":2,\"type\":\"AccountId\",\"docs\":[],\"namespace\":\"ink_env::types::AccountId\",\"lookupNameRoot\":\"InkEnvAccountId\"}}},{\"name\":\"to\",\"type\":{\"info\":9,\"lookupIndex\":11,\"type\":\"Option\",\"docs\":[],\"namespace\":\"Option\",\"sub\":{\"info\":10,\"lookupIndex\":2,\"type\":\"AccountId\",\"docs\":[],\"namespace\":\"ink_env::types::AccountId\",\"lookupNameRoot\":\"InkEnvAccountId\"}}},{\"name\":\"value\",\"type\":{\"info\":10,\"type\":\"Balance\"}}],\"docs\":[\" Event emitted when a token transfer occurs.\"],\"identifier\":\"Transfer\",\"index\":0}}]" + "getContract": { + "address": "5G24svh2w4QXNhsHU5XBxf8N3Sw2MPu7sAemofv1bCuyxAzc", + "metadata": "{\n \"source\": {\n \"hash\": ... }\n}\n", + "hasMetadata": true + } } } ``` - **getContract**: Recupera un contrato por dirección + **getContracts**: Recupera una lista de contratos ```graphql query { - getContract(address: "5G24svh2w4QXNhsHU5XBxf8N3Sw2MPu7sAemofv1bCuyxAzc") { + getContracts(skip: 0, take: 10) { address metadata + hasMetadata + events { + method + } } } ``` @@ -456,9 +655,75 @@ query { ```graphql { "data": { - "getContract": { - "address": "5G24svh2w4QXNhsHU5XBxf8N3Sw2MPu7sAemofv1bCuyxAzc", - "metadata": "{\n \"source\": {\n \"hash\": ... }\n}\n" + "getContracts": [ + { + "address": "5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8", + "hasMetadata": true, + "metadata": "{ ... }", + "events": [ + { + "method": "ContractEmitted" + }, + ] + } + ] + } +} +``` + + **getContractQueries**: Recupera un contrato. Si este contrato ha cargado metadatos, también recuperará las consultas y los métodos de transacción que se pueden ejecutar. + +```graphql +query { + getContractQueries(address: "5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8") { + address + hasMetadata + queries { + args + docs + method + name + } + } +} +``` + + Respuesta: + +```graphql +{ + "data": { + "getContractQueries": { + "address": "5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8", + "hasMetadata": true, + "queries": [ + { + "args": [], + "docs": [ + " Returns the total token supply." + ], + "method": "totalSupply", + "name": "Total supply" + }, + { + "args": [ + "{\"name\":\"to\",\"type\":{\"info\":10,\"type\":\"AccountId\"}}", + "{\"name\":\"value\",\"type\":{\"info\":10,\"type\":\"Balance\"}}" + ], + "docs": [ + " Transfers `value` amount of tokens from the caller's account to account `to`.", + "", + " On success a `Transfer` event is emitted.", + "", + " # Errors", + "", + " Returns `InsufficientBalance` error if there are not enough tokens on", + " the caller's account balance." + ], + "method": "transfer", + "name": "Transfer" + } + ] } } } @@ -466,6 +731,45 @@ query { ### **Mutaciones** + **decodeEvent**: Decodifica los datos del evento para un evento específico. Requiere que los metadatos del contrato ya se hayan subido usando la mutación **uploadMetadata** + +```graphql +mutation { + decodeEvent( + contractAddress: "5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8" + id: "81735cc9-76d3-5984-83af-5872bc9eaeb7" + ) +} +``` + + Respuesta: + +```graphql +{ + "data": { + "decodeEvent": "[{\"decodedData\":{\"args\":[\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\",\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\",\"0x00000000000000000000048c27395000\"],\"event\":{\"args\":[{\"name\":\"from\",\"type\":{\"info\":9,\"lookupIndex\":11,\"type\":\"Option\",\"docs\":[],\"namespace\":\"Option\",\"sub\":{\"info\":10,\"lookupIndex\":2,\"type\":\"AccountId\",\"docs\":[],\"namespace\":\"ink_env::types::AccountId\",\"lookupNameRoot\":\"InkEnvAccountId\"}}},{\"name\":\"to\",\"type\":{\"info\":9,\"lookupIndex\":11,\"type\":\"Option\",\"docs\":[],\"namespace\":\"Option\",\"sub\":{\"info\":10,\"lookupIndex\":2,\"type\":\"AccountId\",\"docs\":[],\"namespace\":\"ink_env::types::AccountId\",\"lookupNameRoot\":\"InkEnvAccountId\"}}},{\"name\":\"value\",\"type\":{\"info\":10,\"type\":\"Balance\"}}],\"docs\":[\" Event emitted when a token transfer occurs.\"],\"identifier\":\"Transfer\",\"index\":0}},\"formattedData\":{\"from\":\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\",\"to\":\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\",\"value\":5}}]" + } +} +``` + + **decodeEvents**: Decodifica los datos de eventos para un contrato específico (use 'skip' y 'take' para seleccionar los eventos y 'orderAsc' para ordenar por tiempo). Requiere que los metadatos del contrato ya se hayan subido usando la mutación **uploadMetadata** + +```graphql +mutation { + decodeEvents(contract: "5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8", skip: 0, take: 1, orderAsc: false) +} +``` + + Respuesta: + +```graphql +{ + "data": { + "decodeEvents": "[{\"decodedData\":{\"args\":[\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\",\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\",\"0x00000000000000000000048c27395000\"],\"event\":{\"args\":[{\"name\":\"from\",\"type\":{\"info\":9,\"lookupIndex\":11,\"type\":\"Option\",\"docs\":[],\"namespace\":\"Option\",\"sub\":{\"info\":10,\"lookupIndex\":2,\"type\":\"AccountId\",\"docs\":[],\"namespace\":\"ink_env::types::AccountId\",\"lookupNameRoot\":\"InkEnvAccountId\"}}},{\"name\":\"to\",\"type\":{\"info\":9,\"lookupIndex\":11,\"type\":\"Option\",\"docs\":[],\"namespace\":\"Option\",\"sub\":{\"info\":10,\"lookupIndex\":2,\"type\":\"AccountId\",\"docs\":[],\"namespace\":\"ink_env::types::AccountId\",\"lookupNameRoot\":\"InkEnvAccountId\"}}},{\"name\":\"value\",\"type\":{\"info\":10,\"type\":\"Balance\"}}],\"docs\":[\" Event emitted when a token transfer occurs.\"],\"identifier\":\"Transfer\",\"index\":0}},\"formattedData\":{\"from\":\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\",\"to\":\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\",\"value\":5}}]" + } +} +``` + **uploadMetadata**: Para decodificar eventos es necesario cargar el ABI del contrato. Pasar un ABI en base64 a esta mutación lo guardará en la base de datos. Después de eso, ejecute una consulta **decodeEvents** para ver los datos decodificados en los eventos. ```graphql @@ -619,7 +923,7 @@ Ejemplo de metadatos de un contrato ERC20: ... ``` -Una vez cargado, los eventos se pueden decodificar mediante la consulta _decodeEvents_ que se encuentra en la sección **Consultas**. +Una vez cargado, los eventos se pueden decodificar mediante las mutaciones _decodeEvent_ o _decodeEvents_ que se encuentran en la sección **Mutaciones**. **Nota**: Los metadatos deben cargarse como un texto (string) en **base64**. @@ -659,9 +963,9 @@ Consulte [Changelog](CHANGELOG.md) para más información. ## Colaboradores -* [__Jose Ramirez__](https://github.com/0xslipk) -* [__Fernando Sirni__](https://github.com/fersirni) -* [__Ruben Gutierrez__](https://github.com/RubenGutierrezC) +- [**Jose Ramirez**](https://github.com/0xslipk) +- [**Fernando Sirni**](https://github.com/fersirni) +- [**Ruben Gutierrez**](https://github.com/RubenGutierrezC) ## Licencia diff --git a/README.md b/README.md index d089f99..af8b516 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -Ink! Explorer API -================= +# Ink! Explorer API [![App Build](https://github.com/blockcoders/ink-substrate-explorer-api/actions/workflows/pr.yaml/badge.svg)](https://github.com/blockcoders/ink-substrate-explorer-api/actions/workflows/pr.yaml) [![Coverage Status](https://coveralls.io/repos/github/blockcoders/ink-substrate-explorer-api/badge.svg?branch=main)](https://coveralls.io/github/blockcoders/ink-substrate-explorer-api?branch=main) @@ -144,6 +143,7 @@ To start the backend service, DB and pgAdmin containers run the following comman ```sh docker-compose up -d ``` + **Note**: A postgresDB up and running and a valid connection to a substrate node are required. Optionally comment the backend service in the docker-compose file if you want to run the image locally. @@ -228,14 +228,34 @@ query { } ``` + **Version**: Retrieves the version of the application + +```graphql +query { + status +} +``` + + Response: + +```graphql +{ + "data": { + "version": "v1.0.1" + } +} +``` + **getBlock**: Retrieves the block by hash ```graphql query { - getBlock(hash: "0x05815b7f1706f46d101b6073ebfa6d47ae9089b5ce5db9deb80382198689466a") { + getBlock(hash: "0x0f615cf7edf8a1e8591893a594fe0ef67d5d56c4d9b1a89d8d120c5f821127fe") { hash number parentHash + timestamp + encodedLength transactions { hash } @@ -249,15 +269,17 @@ query { { "data": { "getBlock": { - "hash": "0x05815b7f1706f46d101b6073ebfa6d47ae9089b5ce5db9deb80382198689466a", - "number": 934059, - "parentHash": "0x31c5025aa86e3af7d77991c8ad3442b01be768399d22af004d9ea5fa771e3827", + "hash": "0x0f615cf7edf8a1e8591893a594fe0ef67d5d56c4d9b1a89d8d120c5f821127fe", + "number": 7, + "parentHash": "0xd8ecc752f280a3786c5cdd4d441d71488414fd6132ace481dd6ddb23fd8000b0", + "timestamp": 1666888006111, + "encodedLength": 312, "transactions": [ { - "hash": "0x9bb5a80b80305b4b1acc93214e3a703e2c3c879b3fae91bfc809ad91753195da" + "hash": "0xdb561ee4432e07a959292acf9895ce379e2474a52160b93fd62496806fdf26cd" }, { - "hash": "0xc49a19fe985222ca0b9b2f8b2f83c65e00efd57552ac245a4c362f882b999040" + "hash": "0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b" } ] } @@ -265,14 +287,16 @@ query { } ``` - **getBlocks**: Retrieves blocks (use skip and take to paginate) + **getBlocks**: Retrieves blocks. Use 'skip' and 'take' to paginate. Use 'orderByNumber: false' to order by timestamp instead and 'orderAsc: true' to see older blocks first. ```graphql query { - getBlocks(skip: 0, take: 10) { + getBlocks(skip: 0, take: 1, orderByNumber: false, orderAsc: false) { hash number parentHash + timestamp + encodedLength transactions { hash } @@ -287,19 +311,21 @@ query { "data": { "getBlocks": [ { - "hash": "0xec403717319c75ad80f6c5a43446dac41a44c2ddf086eedad622d8d784f90d46", - "number": 934057, - "parentHash": "0x0b3e49c138c74f0afc9034a325a25c90433990e0dfdf6f6c9697c591f7c8e7b3", + "hash": "0x0f615cf7edf8a1e8591893a594fe0ef67d5d56c4d9b1a89d8d120c5f821127fe", + "number": 7, + "parentHash": "0xd8ecc752f280a3786c5cdd4d441d71488414fd6132ace481dd6ddb23fd8000b0", + "timestamp": 1666888006111, + "encodedLength": 312, "transactions": [ { - "hash": "0x20be54758f8645bfd1b1f38d798271471edef3deadee1d7a4cd74e628120292a" + "hash": "0xdb561ee4432e07a959292acf9895ce379e2474a52160b93fd62496806fdf26cd" }, { - "hash": "0xf9e94bd8286080340a48dd105eb5d4ab7bbf7aa92869b5537c2b3c5fa8c58ba5" + "hash": "0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b" } ] - }, - ...] + } + ] } } ``` @@ -308,15 +334,28 @@ query { ```graphql query { - getTransaction(hash: "0xfaed625a9948f88aac7b1ff353492cd5834108cfecb1ede82d7bc2f763fcbd28") { - hash + getTransaction(hash: "0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b") { + args blockHash + callIndex + decimals + encodedLength + era + events { + method + } + hash method nonce section signature signer + ss58 + timestamp tip + tokens + type + version } } ``` @@ -327,32 +366,131 @@ query { { "data": { "getTransaction": { - "hash": "0xfaed625a9948f88aac7b1ff353492cd5834108cfecb1ede82d7bc2f763fcbd28", - "blockHash": "0xe138e4b9db53b1a552c26d3f4c3e7573d369512bfb402632d48d6c90521c9922", - "method": "setValidationData", - "nonce": 0, - "section": "parachainSystem", - "signature": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "signer": "5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM", - "tip": 0 + "args": "{\"dest\":{\"id\":\"5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8\"},\"value\":0,\"gas_limit\":75000000000,\"storage_deposit_limit\":null,\"data\":\"0x84a15da18eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48005039278c0400000000000000000000\"}", + "blockHash": "0x0f615cf7edf8a1e8591893a594fe0ef67d5d56c4d9b1a89d8d120c5f821127fe", + "callIndex": "7,0", + "decimals": "12", + "encodedLength": 201, + "era": "{\"mortalEra\":\"0x0b00\"}", + "events": [ + { + "method": "ContractEmitted" + } + ], + "hash": "0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b", + "method": "call", + "nonce": 3, + "section": "contracts", + "signature": "0x78582786706e947a6d77ac5b49ba140b4c88ebc644421136bbfa8b66577e1e3efdbc1d981948546fff41600be9a716e4c38a8531a867853f26ba11ee21128f82", + "signer": "5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc", + "ss58": "42", + "timestamp": 1666888006111, + "tip": 0, + "tokens": "Unit", + "type": 4, + "version": 132 } } } ``` - **getTransactions**: Retrieves transactions by block hash (use skip and take to paginate) + **getTransactionsByContract**: Retrieves a list of transactions of a contract. ```graphql query { - getTransactions(blockHash: "0xa7ef8085bfad2354e5191e012bd412c0d76c213f43a68187194b7696a0822b93") { + getTransactionsByContract( + address: "5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8" + skip: 0 + take: 1 + orderAsc: false + ) { + args + blockHash + callIndex + decimals + encodedLength + era + events { + method + } hash + method + nonce + section + signature + signer + ss58 + timestamp + tip + tokens + type + version + } +} +``` + + Response: + +```graphql +{ + "data": { + "getTransactionsByContract": [ + { + "args": "{\"dest\":{\"id\":\"5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8\"},\"value\":0,\"gas_limit\":75000000000,\"storage_deposit_limit\":null,\"data\":\"0x84a15da18eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48005039278c0400000000000000000000\"}", + "blockHash": "0x0f615cf7edf8a1e8591893a594fe0ef67d5d56c4d9b1a89d8d120c5f821127fe", + "callIndex": "7,0", + "decimals": "12", + "encodedLength": 201, + "era": "{\"mortalEra\":\"0x0b00\"}", + "events": [ + { + "method": "ContractEmitted" + } + ], + "hash": "0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b", + "method": "call", + "nonce": 3, + "section": "contracts", + "signature": "0x78582786706e947a6d77ac5b49ba140b4c88ebc644421136bbfa8b66577e1e3efdbc1d981948546fff41600be9a716e4c38a8531a867853f26ba11ee21128f82", + "signer": "5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc", + "ss58": "42", + "timestamp": 1666888006111, + "tip": 0, + "tokens": "Unit", + "type": 4, + "version": 132 + } + ] + } +} +``` + + **getTransactions**: Retrieves transactions by block hash (use 'skip' and 'take' to paginate. use 'orderAsc' to see older or newer first) + +```graphql +query { + getTransactions(skip: 0, take: 1, orderAsc: false) { + args blockHash + callIndex + decimals + encodedLength + era + events { + method + } + hash method nonce section signature signer + ss58 + timestamp tip + tokens + type + version } } ``` @@ -364,33 +502,86 @@ query { "data": { "getTransactions": [ { - "hash": "0xf715221f0e46c5a666e65e99af70631cc32a46cf6121ed3be56768ff303eda36", - "blockHash": "0xa7ef8085bfad2354e5191e012bd412c0d76c213f43a68187194b7696a0822b93", - "method": "setValidationData", + "args": "{\"now\":1666888006111}", + "blockHash": "0x0f615cf7edf8a1e8591893a594fe0ef67d5d56c4d9b1a89d8d120c5f821127fe", + "callIndex": "2,0", + "decimals": "12", + "encodedLength": 11, + "era": "{\"immortalEra\":\"0x00\"}", + "events": [], + "hash": "0xdb561ee4432e07a959292acf9895ce379e2474a52160b93fd62496806fdf26cd", + "method": "set", "nonce": 0, - "section": "parachainSystem", + "section": "timestamp", "signature": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "signer": "5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM", + "ss58": "42", + "timestamp": 1666888006111, "tip": 0, - "events": [] - }, - ... + "tokens": "Unit", + "type": 4, + "version": 4 + } ] } } ``` - **getEvents**: Retrieves events by contract address or transaction hash (use skip and take to paginate) + **getEvent**: Retrieves an event by id ```graphql query { - getEvents(contract: "5F7FvAUyB6ok4Sj3j82x315F3pDCZSiGovxWcnjadnpSMi7t") { + getEvent(id: "81735cc9-76d3-5984-83af-5872bc9eaeb7") { id index method section + timestamp topics transactionHash + data + decodedData + formattedData + } +} +``` + + Response: + +```graphql +{ + "data": { + "getEvent": { + "id": "81735cc9-76d3-5984-83af-5872bc9eaeb7", + "index": "0x0703", + "method": "ContractEmitted", + "section": "contracts", + "timestamp": 1666888006111, + "topics": "[0x0045726332303a3a5472616e7366657200000000000000000000000000000000, 0x08be862c40d599dc6f4f28076712bb324c0cd2197c30f07459887b41fadff2c8, 0x2b00c7d40fe6d84d660f3e6bed90f218e022a0909f7e1a7ea35ada8b6e003564]", + "transactionHash": "0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b", + "data": "[\"5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8\",\"0x0001c40e2006bbebf9022c317f9337ad376e56d392917e5ac1397fe09b07c765c050018eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48005039278c0400000000000000000000\"]", + "decodedData": "{\"args\":[\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\",\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\",\"0x00000000000000000000048c27395000\"],\"event\":{\"args\":[{\"name\":\"from\",\"type\":{\"sub\":{\"docs\":[],\"info\":10,\"type\":\"AccountId\",\"namespace\":\"ink_env::types::AccountId\",\"lookupIndex\":2,\"lookupNameRoot\":\"InkEnvAccountId\"},\"docs\":[],\"info\":9,\"type\":\"Option\",\"namespace\":\"Option\",\"lookupIndex\":11}},{\"name\":\"to\",\"type\":{\"sub\":{\"docs\":[],\"info\":10,\"type\":\"AccountId\",\"namespace\":\"ink_env::types::AccountId\",\"lookupIndex\":2,\"lookupNameRoot\":\"InkEnvAccountId\"},\"docs\":[],\"info\":9,\"type\":\"Option\",\"namespace\":\"Option\",\"lookupIndex\":11}},{\"name\":\"value\",\"type\":{\"info\":10,\"type\":\"Balance\"}}],\"docs\":[\" Event emitted when a token transfer occurs.\"],\"index\":0,\"identifier\":\"Transfer\"}}", + "formattedData": "{\"from\":\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\",\"to\":\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\",\"value\":5}" + } + } +} +``` + + **getEvents**: Retrieves events by contract address or transaction hash (use 'skip' and 'take' to paginate, 'orderAsc' to see older or newer first) + +```graphql +query { + getEvents(contract: "5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8", skip: 0, take: 1, orderAsc: false) { + id + index + method + section + timestamp + topics + transactionHash + data + decodedData + formattedData } } ``` @@ -402,31 +593,31 @@ query { "data": { "getEvents": [ { - "id": "c3250479-e53e-5a4d-ba0c-b688764cd81b", + "id": "81735cc9-76d3-5984-83af-5872bc9eaeb7", "index": "0x0703", - "section": "contracts", "method": "ContractEmitted", - "transactionHash": "0x1080eb1f8de1ee5b0c1bd584924951c38b998bc7596773ef5e1a92908409a17f", - "topics": "[0x0045726332303a3a5472616e7366657200000000000000000000000000000000, 0x33766995fd9b44bd45f351b3abd7e5041960638db0075c84ab7af1a734e20d1b, 0x5445726332303a3a5472616e736665723a3a66726f6d00000000000000000000]" - }, - { - "id": "509f2fb6-ed61-5dc7-a567-3cfa55e1fa65", - "index": "0x0703", "section": "contracts", - "method": "ContractEmitted", - "transactionHash": "0x2a009bf5fdc388f10953cba4661c3ca74e0252c1fcae6ba7f39f4eb7be707caa", - "topics": "[0x0045726332303a3a5472616e7366657200000000000000000000000000000000, 0x2b00c7d40fe6d84d660f3e6bed90f218e022a0909f7e1a7ea35ada8b6e003564, 0xda2d695d3b5a304e0039e7fc4419c34fa0c1f239189c99bb72a6484f1634782b]" + "timestamp": 1666888006111, + "topics": "[0x0045726332303a3a5472616e7366657200000000000000000000000000000000, 0x08be862c40d599dc6f4f28076712bb324c0cd2197c30f07459887b41fadff2c8, 0x2b00c7d40fe6d84d660f3e6bed90f218e022a0909f7e1a7ea35ada8b6e003564]", + "transactionHash": "0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b", + "data": "[\"5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8\",\"0x0001c40e2006bbebf9022c317f9337ad376e56d392917e5ac1397fe09b07c765c050018eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48005039278c0400000000000000000000\"]", + "decodedData": "{\"args\":[\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\",\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\",\"0x00000000000000000000048c27395000\"],\"event\":{\"args\":[{\"name\":\"from\",\"type\":{\"sub\":{\"docs\":[],\"info\":10,\"type\":\"AccountId\",\"namespace\":\"ink_env::types::AccountId\",\"lookupIndex\":2,\"lookupNameRoot\":\"InkEnvAccountId\"},\"docs\":[],\"info\":9,\"type\":\"Option\",\"namespace\":\"Option\",\"lookupIndex\":11}},{\"name\":\"to\",\"type\":{\"sub\":{\"docs\":[],\"info\":10,\"type\":\"AccountId\",\"namespace\":\"ink_env::types::AccountId\",\"lookupIndex\":2,\"lookupNameRoot\":\"InkEnvAccountId\"},\"docs\":[],\"info\":9,\"type\":\"Option\",\"namespace\":\"Option\",\"lookupIndex\":11}},{\"name\":\"value\",\"type\":{\"info\":10,\"type\":\"Balance\"}}],\"docs\":[\" Event emitted when a token transfer occurs.\"],\"index\":0,\"identifier\":\"Transfer\"}}", + "formattedData": "{\"from\":\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\",\"to\":\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\",\"value\":5}" } ] } } ``` - **decodeEvents**: Decodes the events data for a specific contract. Requires that the contract's metadata was already uploaded using the mutation **uploadMetadata** + **getContract**: Retrieves a contract by address ```graphql query { - decodeEvents(contractAddress: "5G24svh2w4QXNhsHU5XBxf8N3Sw2MPu7sAemofv1bCuyxAzc") + getContract(address: "5G24svh2w4QXNhsHU5XBxf8N3Sw2MPu7sAemofv1bCuyxAzc") { + address + metadata + hasMetadata + } } ``` @@ -435,18 +626,26 @@ query { ```graphql { "data": { - "decodeEvents": "[{\"args\":[null,\"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY\",\"0x000000000000000000038d7ea4c68000\"],\"event\":{\"args\":[{\"name\":\"from\",\"type\":{\"info\":9,\"lookupIndex\":11,\"type\":\"Option\",\"docs\":[],\"namespace\":\"Option\",\"sub\":{\"info\":10,\"lookupIndex\":2,\"type\":\"AccountId\",\"docs\":[],\"namespace\":\"ink_env::types::AccountId\",\"lookupNameRoot\":\"InkEnvAccountId\"}}},{\"name\":\"to\",\"type\":{\"info\":9,\"lookupIndex\":11,\"type\":\"Option\",\"docs\":[],\"namespace\":\"Option\",\"sub\":{\"info\":10,\"lookupIndex\":2,\"type\":\"AccountId\",\"docs\":[],\"namespace\":\"ink_env::types::AccountId\",\"lookupNameRoot\":\"InkEnvAccountId\"}}},{\"name\":\"value\",\"type\":{\"info\":10,\"type\":\"Balance\"}}],\"docs\":[\" Event emitted when a token transfer occurs.\"],\"identifier\":\"Transfer\",\"index\":0}},{\"args\":[\"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY\",\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\",\"0x00000000000000000001c6bf52634000\"],\"event\":{\"args\":[{\"name\":\"from\",\"type\":{\"info\":9,\"lookupIndex\":11,\"type\":\"Option\",\"docs\":[],\"namespace\":\"Option\",\"sub\":{\"info\":10,\"lookupIndex\":2,\"type\":\"AccountId\",\"docs\":[],\"namespace\":\"ink_env::types::AccountId\",\"lookupNameRoot\":\"InkEnvAccountId\"}}},{\"name\":\"to\",\"type\":{\"info\":9,\"lookupIndex\":11,\"type\":\"Option\",\"docs\":[],\"namespace\":\"Option\",\"sub\":{\"info\":10,\"lookupIndex\":2,\"type\":\"AccountId\",\"docs\":[],\"namespace\":\"ink_env::types::AccountId\",\"lookupNameRoot\":\"InkEnvAccountId\"}}},{\"name\":\"value\",\"type\":{\"info\":10,\"type\":\"Balance\"}}],\"docs\":[\" Event emitted when a token transfer occurs.\"],\"identifier\":\"Transfer\",\"index\":0}}]" + "getContract": { + "address": "5G24svh2w4QXNhsHU5XBxf8N3Sw2MPu7sAemofv1bCuyxAzc", + "metadata": "{\n \"source\": {\n \"hash\": ... }\n}\n", + "hasMetadata": true + } } } ``` - **getContract**: Retrieves a contract by address + **getContracts**: Retrieves a list of contracts ```graphql query { - getContract(address: "5G24svh2w4QXNhsHU5XBxf8N3Sw2MPu7sAemofv1bCuyxAzc") { + getContracts(skip: 0, take: 10) { address metadata + hasMetadata + events { + method + } } } ``` @@ -456,9 +655,75 @@ query { ```graphql { "data": { - "getContract": { - "address": "5G24svh2w4QXNhsHU5XBxf8N3Sw2MPu7sAemofv1bCuyxAzc", - "metadata": "{\n \"source\": {\n \"hash\": ... }\n}\n" + "getContracts": [ + { + "address": "5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8", + "hasMetadata": true, + "metadata": "{ ... }", + "events": [ + { + "method": "ContractEmitted" + }, + ] + } + ] + } +} +``` + + **getContractQueries**: Retrieves a contract. If this contract has uploaded metadata it will also retrieve the queries and transaction methods that can be executed. + +```graphql +query { + getContractQueries(address: "5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8") { + address + hasMetadata + queries { + args + docs + method + name + } + } +} +``` + + Response: + +```graphql +{ + "data": { + "getContractQueries": { + "address": "5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8", + "hasMetadata": true, + "queries": [ + { + "args": [], + "docs": [ + " Returns the total token supply." + ], + "method": "totalSupply", + "name": "Total supply" + }, + { + "args": [ + "{\"name\":\"to\",\"type\":{\"info\":10,\"type\":\"AccountId\"}}", + "{\"name\":\"value\",\"type\":{\"info\":10,\"type\":\"Balance\"}}" + ], + "docs": [ + " Transfers `value` amount of tokens from the caller's account to account `to`.", + "", + " On success a `Transfer` event is emitted.", + "", + " # Errors", + "", + " Returns `InsufficientBalance` error if there are not enough tokens on", + " the caller's account balance." + ], + "method": "transfer", + "name": "Transfer" + } + ] } } } @@ -466,6 +731,45 @@ query { ### **Mutations** + **decodeEvent**: Decodes the event data for a specific event. Requires that the contract's metadata was already uploaded using the mutation **uploadMetadata** + +```graphql +mutation { + decodeEvent( + contractAddress: "5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8" + id: "81735cc9-76d3-5984-83af-5872bc9eaeb7" + ) +} +``` + + Response: + +```graphql +{ + "data": { + "decodeEvent": "[{\"decodedData\":{\"args\":[\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\",\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\",\"0x00000000000000000000048c27395000\"],\"event\":{\"args\":[{\"name\":\"from\",\"type\":{\"info\":9,\"lookupIndex\":11,\"type\":\"Option\",\"docs\":[],\"namespace\":\"Option\",\"sub\":{\"info\":10,\"lookupIndex\":2,\"type\":\"AccountId\",\"docs\":[],\"namespace\":\"ink_env::types::AccountId\",\"lookupNameRoot\":\"InkEnvAccountId\"}}},{\"name\":\"to\",\"type\":{\"info\":9,\"lookupIndex\":11,\"type\":\"Option\",\"docs\":[],\"namespace\":\"Option\",\"sub\":{\"info\":10,\"lookupIndex\":2,\"type\":\"AccountId\",\"docs\":[],\"namespace\":\"ink_env::types::AccountId\",\"lookupNameRoot\":\"InkEnvAccountId\"}}},{\"name\":\"value\",\"type\":{\"info\":10,\"type\":\"Balance\"}}],\"docs\":[\" Event emitted when a token transfer occurs.\"],\"identifier\":\"Transfer\",\"index\":0}},\"formattedData\":{\"from\":\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\",\"to\":\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\",\"value\":5}}]" + } +} +``` + + **decodeEvents**: Decodes the events data for a specific contract (use 'skip' and 'take' to select the events and 'orderAsc' to order by timestamp). Requires that the contract's metadata was already uploaded using the mutation **uploadMetadata** + +```graphql +mutation { + decodeEvents(contract: "5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8", skip: 0, take: 1, orderAsc: false) +} +``` + + Response: + +```graphql +{ + "data": { + "decodeEvents": "[{\"decodedData\":{\"args\":[\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\",\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\",\"0x00000000000000000000048c27395000\"],\"event\":{\"args\":[{\"name\":\"from\",\"type\":{\"info\":9,\"lookupIndex\":11,\"type\":\"Option\",\"docs\":[],\"namespace\":\"Option\",\"sub\":{\"info\":10,\"lookupIndex\":2,\"type\":\"AccountId\",\"docs\":[],\"namespace\":\"ink_env::types::AccountId\",\"lookupNameRoot\":\"InkEnvAccountId\"}}},{\"name\":\"to\",\"type\":{\"info\":9,\"lookupIndex\":11,\"type\":\"Option\",\"docs\":[],\"namespace\":\"Option\",\"sub\":{\"info\":10,\"lookupIndex\":2,\"type\":\"AccountId\",\"docs\":[],\"namespace\":\"ink_env::types::AccountId\",\"lookupNameRoot\":\"InkEnvAccountId\"}}},{\"name\":\"value\",\"type\":{\"info\":10,\"type\":\"Balance\"}}],\"docs\":[\" Event emitted when a token transfer occurs.\"],\"identifier\":\"Transfer\",\"index\":0}},\"formattedData\":{\"from\":\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\",\"to\":\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\",\"value\":5}}]" + } +} +``` + **uploadMetadata**: To decode events it is necessary to upload the contract's ABI. Passing a base64 string ABI to this mutation will save that to DB. After that run a **decodeEvents** query to see the decoded data on the events. ```graphql @@ -619,7 +923,7 @@ Example of an ERC20 contract metadata: ... ``` -Once it is uploaded the events can be decoded using the _decodeEvents_ query that can be found on section **Queries**. +Once it is uploaded the events can be decoded using the _decodeEvent_ or _decodeEvents_ mutation that can be found on section **Mutations**. **Note**: The metadata should be uploaded as a **base64** string. @@ -659,9 +963,9 @@ Contributions welcome! See [Contributing](CONTRIBUTING.md). ## Collaborators -* [__Jose Ramirez__](https://github.com/0xslipk) -* [__Fernando Sirni__](https://github.com/fersirni) -* [__Ruben Gutierrez__](https://github.com/RubenGutierrezC) +- [**Jose Ramirez**](https://github.com/0xslipk) +- [**Fernando Sirni**](https://github.com/fersirni) +- [**Ruben Gutierrez**](https://github.com/RubenGutierrezC) ## License diff --git a/docker-compose.yaml b/docker-compose.yaml index 770c9b0..e8597d3 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -13,19 +13,19 @@ services: - postgres build: context: . - dockerfile: dev.Dockerfile + dockerfile: Dockerfile #dev.Dockefile ports: - 8080:8080 volumes: - .:/usr/src/app - /usr/src/app/node_modules - /usr/src/app/dist + env_file: + - .env networks: ink-explorer-network: aliases: - "backend" - env_file: - - .env postgres: image: postgres:14.4 restart: always diff --git a/mocks/base64-metadata.mock.ts b/mocks/base64-metadata.mock.ts new file mode 100644 index 0000000..f83be65 --- /dev/null +++ b/mocks/base64-metadata.mock.ts @@ -0,0 +1,2 @@ +export const BASE64_METADATA = + 'ewogICJzb3VyY2UiOiB7CiAgICAiaGFzaCI6ICIweDNhYTFjOGJhNWY1OTAzNGE0MmE5M2MwMGVlMDM5YTk0NjRkNmZhNjNkNzBiNjg4OWEyNTk2ZjQ1MjhiMjhhMTkiLAogICAgImxhbmd1YWdlIjogImluayEgMy4zLjAiLAogICAgImNvbXBpbGVyIjogInJ1c3RjIDEuNjQuMC1uaWdodGx5IgogIH0sCiAgImNvbnRyYWN0IjogewogICAgIm5hbWUiOiAiZXJjMjAiLAogICAgInZlcnNpb24iOiAiMC4xLjAiLAogICAgImF1dGhvcnMiOiBbIlt5b3VyX25hbWVdIDxbeW91cl9lbWFpbF0+Il0KICB9LAogICJWMyI6IHsKICAgICJzcGVjIjogewogICAgICAiY29uc3RydWN0b3JzIjogWwogICAgICAgIHsKICAgICAgICAgICJhcmdzIjogWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgImxhYmVsIjogImluaXRpYWxfc3VwcGx5IiwKICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICJkaXNwbGF5TmFtZSI6IFsiQmFsYW5jZSJdLAogICAgICAgICAgICAgICAgInR5cGUiOiAwCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICBdLAogICAgICAgICAgImRvY3MiOiBbIkNyZWF0ZXMgYSBuZXcgRVJDLTIwIGNvbnRyYWN0IHdpdGggdGhlIHNwZWNpZmllZCBpbml0aWFsIHN1cHBseS4iXSwKICAgICAgICAgICJsYWJlbCI6ICJuZXciLAogICAgICAgICAgInBheWFibGUiOiBmYWxzZSwKICAgICAgICAgICJzZWxlY3RvciI6ICIweDliYWU5ZDVlIgogICAgICAgIH0KICAgICAgXSwKICAgICAgImRvY3MiOiBbXSwKICAgICAgImV2ZW50cyI6IFsKICAgICAgICB7CiAgICAgICAgICAiYXJncyI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICJkb2NzIjogW10sCiAgICAgICAgICAgICAgImluZGV4ZWQiOiB0cnVlLAogICAgICAgICAgICAgICJsYWJlbCI6ICJmcm9tIiwKICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICJkaXNwbGF5TmFtZSI6IFsiT3B0aW9uIl0sCiAgICAgICAgICAgICAgICAidHlwZSI6IDExCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgImRvY3MiOiBbXSwKICAgICAgICAgICAgICAiaW5kZXhlZCI6IHRydWUsCiAgICAgICAgICAgICAgImxhYmVsIjogInRvIiwKICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICJkaXNwbGF5TmFtZSI6IFsiT3B0aW9uIl0sCiAgICAgICAgICAgICAgICAidHlwZSI6IDExCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgImRvY3MiOiBbXSwKICAgICAgICAgICAgICAiaW5kZXhlZCI6IGZhbHNlLAogICAgICAgICAgICAgICJsYWJlbCI6ICJ2YWx1ZSIsCiAgICAgICAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAgICAgICAiZGlzcGxheU5hbWUiOiBbIkJhbGFuY2UiXSwKICAgICAgICAgICAgICAgICJ0eXBlIjogMAogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgXSwKICAgICAgICAgICJkb2NzIjogWyIgRXZlbnQgZW1pdHRlZCB3aGVuIGEgdG9rZW4gdHJhbnNmZXIgb2NjdXJzLiJdLAogICAgICAgICAgImxhYmVsIjogIlRyYW5zZmVyIgogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgImFyZ3MiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAiZG9jcyI6IFtdLAogICAgICAgICAgICAgICJpbmRleGVkIjogdHJ1ZSwKICAgICAgICAgICAgICAibGFiZWwiOiAib3duZXIiLAogICAgICAgICAgICAgICJ0eXBlIjogewogICAgICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJBY2NvdW50SWQiXSwKICAgICAgICAgICAgICAgICJ0eXBlIjogMgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICJkb2NzIjogW10sCiAgICAgICAgICAgICAgImluZGV4ZWQiOiB0cnVlLAogICAgICAgICAgICAgICJsYWJlbCI6ICJzcGVuZGVyIiwKICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICJkaXNwbGF5TmFtZSI6IFsiQWNjb3VudElkIl0sCiAgICAgICAgICAgICAgICAidHlwZSI6IDIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAiZG9jcyI6IFtdLAogICAgICAgICAgICAgICJpbmRleGVkIjogZmFsc2UsCiAgICAgICAgICAgICAgImxhYmVsIjogInZhbHVlIiwKICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICJkaXNwbGF5TmFtZSI6IFsiQmFsYW5jZSJdLAogICAgICAgICAgICAgICAgInR5cGUiOiAwCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICBdLAogICAgICAgICAgImRvY3MiOiBbCiAgICAgICAgICAgICIgRXZlbnQgZW1pdHRlZCB3aGVuIGFuIGFwcHJvdmFsIG9jY3VycyB0aGF0IGBzcGVuZGVyYCBpcyBhbGxvd2VkIHRvIHdpdGhkcmF3IiwKICAgICAgICAgICAgIiB1cCB0byB0aGUgYW1vdW50IG9mIGB2YWx1ZWAgdG9rZW5zIGZyb20gYG93bmVyYC4iCiAgICAgICAgICBdLAogICAgICAgICAgImxhYmVsIjogIkFwcHJvdmFsIgogICAgICAgIH0KICAgICAgXSwKICAgICAgIm1lc3NhZ2VzIjogWwogICAgICAgIHsKICAgICAgICAgICJhcmdzIjogW10sCiAgICAgICAgICAiZG9jcyI6IFsiIFJldHVybnMgdGhlIHRvdGFsIHRva2VuIHN1cHBseS4iXSwKICAgICAgICAgICJsYWJlbCI6ICJ0b3RhbF9zdXBwbHkiLAogICAgICAgICAgIm11dGF0ZXMiOiBmYWxzZSwKICAgICAgICAgICJwYXlhYmxlIjogZmFsc2UsCiAgICAgICAgICAicmV0dXJuVHlwZSI6IHsKICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJCYWxhbmNlIl0sCiAgICAgICAgICAgICJ0eXBlIjogMAogICAgICAgICAgfSwKICAgICAgICAgICJzZWxlY3RvciI6ICIweGRiNjM3NWE4IgogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgImFyZ3MiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAibGFiZWwiOiAib3duZXIiLAogICAgICAgICAgICAgICJ0eXBlIjogewogICAgICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJBY2NvdW50SWQiXSwKICAgICAgICAgICAgICAgICJ0eXBlIjogMgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgXSwKICAgICAgICAgICJkb2NzIjogWwogICAgICAgICAgICAiIFJldHVybnMgdGhlIGFjY291bnQgYmFsYW5jZSBmb3IgdGhlIHNwZWNpZmllZCBgb3duZXJgLiIsCiAgICAgICAgICAgICIiLAogICAgICAgICAgICAiIFJldHVybnMgYDBgIGlmIHRoZSBhY2NvdW50IGlzIG5vbi1leGlzdGVudC4iCiAgICAgICAgICBdLAogICAgICAgICAgImxhYmVsIjogImJhbGFuY2Vfb2YiLAogICAgICAgICAgIm11dGF0ZXMiOiBmYWxzZSwKICAgICAgICAgICJwYXlhYmxlIjogZmFsc2UsCiAgICAgICAgICAicmV0dXJuVHlwZSI6IHsKICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJCYWxhbmNlIl0sCiAgICAgICAgICAgICJ0eXBlIjogMAogICAgICAgICAgfSwKICAgICAgICAgICJzZWxlY3RvciI6ICIweDBmNzU1YTU2IgogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgImFyZ3MiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAibGFiZWwiOiAib3duZXIiLAogICAgICAgICAgICAgICJ0eXBlIjogewogICAgICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJBY2NvdW50SWQiXSwKICAgICAgICAgICAgICAgICJ0eXBlIjogMgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICJsYWJlbCI6ICJzcGVuZGVyIiwKICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICJkaXNwbGF5TmFtZSI6IFsiQWNjb3VudElkIl0sCiAgICAgICAgICAgICAgICAidHlwZSI6IDIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIF0sCiAgICAgICAgICAiZG9jcyI6IFsKICAgICAgICAgICAgIiBSZXR1cm5zIHRoZSBhbW91bnQgd2hpY2ggYHNwZW5kZXJgIGlzIHN0aWxsIGFsbG93ZWQgdG8gd2l0aGRyYXcgZnJvbSBgb3duZXJgLiIsCiAgICAgICAgICAgICIiLAogICAgICAgICAgICAiIFJldHVybnMgYDBgIGlmIG5vIGFsbG93YW5jZSBoYXMgYmVlbiBzZXQuIgogICAgICAgICAgXSwKICAgICAgICAgICJsYWJlbCI6ICJhbGxvd2FuY2UiLAogICAgICAgICAgIm11dGF0ZXMiOiBmYWxzZSwKICAgICAgICAgICJwYXlhYmxlIjogZmFsc2UsCiAgICAgICAgICAicmV0dXJuVHlwZSI6IHsKICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJCYWxhbmNlIl0sCiAgICAgICAgICAgICJ0eXBlIjogMAogICAgICAgICAgfSwKICAgICAgICAgICJzZWxlY3RvciI6ICIweDZhMDAxNjVlIgogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgImFyZ3MiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAibGFiZWwiOiAidG8iLAogICAgICAgICAgICAgICJ0eXBlIjogewogICAgICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJBY2NvdW50SWQiXSwKICAgICAgICAgICAgICAgICJ0eXBlIjogMgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICJsYWJlbCI6ICJ2YWx1ZSIsCiAgICAgICAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAgICAgICAiZGlzcGxheU5hbWUiOiBbIkJhbGFuY2UiXSwKICAgICAgICAgICAgICAgICJ0eXBlIjogMAogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgXSwKICAgICAgICAgICJkb2NzIjogWwogICAgICAgICAgICAiIFRyYW5zZmVycyBgdmFsdWVgIGFtb3VudCBvZiB0b2tlbnMgZnJvbSB0aGUgY2FsbGVyJ3MgYWNjb3VudCB0byBhY2NvdW50IGB0b2AuIiwKICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICIgT24gc3VjY2VzcyBhIGBUcmFuc2ZlcmAgZXZlbnQgaXMgZW1pdHRlZC4iLAogICAgICAgICAgICAiIiwKICAgICAgICAgICAgIiAjIEVycm9ycyIsCiAgICAgICAgICAgICIiLAogICAgICAgICAgICAiIFJldHVybnMgYEluc3VmZmljaWVudEJhbGFuY2VgIGVycm9yIGlmIHRoZXJlIGFyZSBub3QgZW5vdWdoIHRva2VucyBvbiIsCiAgICAgICAgICAgICIgdGhlIGNhbGxlcidzIGFjY291bnQgYmFsYW5jZS4iCiAgICAgICAgICBdLAogICAgICAgICAgImxhYmVsIjogInRyYW5zZmVyIiwKICAgICAgICAgICJtdXRhdGVzIjogdHJ1ZSwKICAgICAgICAgICJwYXlhYmxlIjogZmFsc2UsCiAgICAgICAgICAicmV0dXJuVHlwZSI6IHsKICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJSZXN1bHQiXSwKICAgICAgICAgICAgInR5cGUiOiA4CiAgICAgICAgICB9LAogICAgICAgICAgInNlbGVjdG9yIjogIjB4ODRhMTVkYTEiCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAiYXJncyI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICJsYWJlbCI6ICJzcGVuZGVyIiwKICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICJkaXNwbGF5TmFtZSI6IFsiQWNjb3VudElkIl0sCiAgICAgICAgICAgICAgICAidHlwZSI6IDIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAibGFiZWwiOiAidmFsdWUiLAogICAgICAgICAgICAgICJ0eXBlIjogewogICAgICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJCYWxhbmNlIl0sCiAgICAgICAgICAgICAgICAidHlwZSI6IDAKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIF0sCiAgICAgICAgICAiZG9jcyI6IFsKICAgICAgICAgICAgIiBBbGxvd3MgYHNwZW5kZXJgIHRvIHdpdGhkcmF3IGZyb20gdGhlIGNhbGxlcidzIGFjY291bnQgbXVsdGlwbGUgdGltZXMsIHVwIHRvIiwKICAgICAgICAgICAgIiB0aGUgYHZhbHVlYCBhbW91bnQuIiwKICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICIgSWYgdGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYWdhaW4gaXQgb3ZlcndyaXRlcyB0aGUgY3VycmVudCBhbGxvd2FuY2Ugd2l0aCBgdmFsdWVgLiIsCiAgICAgICAgICAgICIiLAogICAgICAgICAgICAiIEFuIGBBcHByb3ZhbGAgZXZlbnQgaXMgZW1pdHRlZC4iCiAgICAgICAgICBdLAogICAgICAgICAgImxhYmVsIjogImFwcHJvdmUiLAogICAgICAgICAgIm11dGF0ZXMiOiB0cnVlLAogICAgICAgICAgInBheWFibGUiOiBmYWxzZSwKICAgICAgICAgICJyZXR1cm5UeXBlIjogewogICAgICAgICAgICAiZGlzcGxheU5hbWUiOiBbIlJlc3VsdCJdLAogICAgICAgICAgICAidHlwZSI6IDgKICAgICAgICAgIH0sCiAgICAgICAgICAic2VsZWN0b3IiOiAiMHg2ODEyNjZhMCIKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJhcmdzIjogWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgImxhYmVsIjogImZyb20iLAogICAgICAgICAgICAgICJ0eXBlIjogewogICAgICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJBY2NvdW50SWQiXSwKICAgICAgICAgICAgICAgICJ0eXBlIjogMgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICJsYWJlbCI6ICJ0byIsCiAgICAgICAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAgICAgICAiZGlzcGxheU5hbWUiOiBbIkFjY291bnRJZCJdLAogICAgICAgICAgICAgICAgInR5cGUiOiAyCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgImxhYmVsIjogInZhbHVlIiwKICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICJkaXNwbGF5TmFtZSI6IFsiQmFsYW5jZSJdLAogICAgICAgICAgICAgICAgInR5cGUiOiAwCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICBdLAogICAgICAgICAgImRvY3MiOiBbCiAgICAgICAgICAgICIgVHJhbnNmZXJzIGB2YWx1ZWAgdG9rZW5zIG9uIHRoZSBiZWhhbGYgb2YgYGZyb21gIHRvIHRoZSBhY2NvdW50IGB0b2AuIiwKICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICIgVGhpcyBjYW4gYmUgdXNlZCB0byBhbGxvdyBhIGNvbnRyYWN0IHRvIHRyYW5zZmVyIHRva2VucyBvbiBvbmVzIGJlaGFsZiBhbmQvb3IiLAogICAgICAgICAgICAiIHRvIGNoYXJnZSBmZWVzIGluIHN1Yi1jdXJyZW5jaWVzLCBmb3IgZXhhbXBsZS4iLAogICAgICAgICAgICAiIiwKICAgICAgICAgICAgIiBPbiBzdWNjZXNzIGEgYFRyYW5zZmVyYCBldmVudCBpcyBlbWl0dGVkLiIsCiAgICAgICAgICAgICIiLAogICAgICAgICAgICAiICMgRXJyb3JzIiwKICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICIgUmV0dXJucyBgSW5zdWZmaWNpZW50QWxsb3dhbmNlYCBlcnJvciBpZiB0aGVyZSBhcmUgbm90IGVub3VnaCB0b2tlbnMgYWxsb3dlZCIsCiAgICAgICAgICAgICIgZm9yIHRoZSBjYWxsZXIgdG8gd2l0aGRyYXcgZnJvbSBgZnJvbWAuIiwKICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICIgUmV0dXJucyBgSW5zdWZmaWNpZW50QmFsYW5jZWAgZXJyb3IgaWYgdGhlcmUgYXJlIG5vdCBlbm91Z2ggdG9rZW5zIG9uIiwKICAgICAgICAgICAgIiB0aGUgYWNjb3VudCBiYWxhbmNlIG9mIGBmcm9tYC4iCiAgICAgICAgICBdLAogICAgICAgICAgImxhYmVsIjogInRyYW5zZmVyX2Zyb20iLAogICAgICAgICAgIm11dGF0ZXMiOiB0cnVlLAogICAgICAgICAgInBheWFibGUiOiBmYWxzZSwKICAgICAgICAgICJyZXR1cm5UeXBlIjogewogICAgICAgICAgICAiZGlzcGxheU5hbWUiOiBbIlJlc3VsdCJdLAogICAgICAgICAgICAidHlwZSI6IDgKICAgICAgICAgIH0sCiAgICAgICAgICAic2VsZWN0b3IiOiAiMHgwYjM5NmYxOCIKICAgICAgICB9CiAgICAgIF0KICAgIH0sCiAgICAic3RvcmFnZSI6IHsKICAgICAgInN0cnVjdCI6IHsKICAgICAgICAiZmllbGRzIjogWwogICAgICAgICAgewogICAgICAgICAgICAibGF5b3V0IjogewogICAgICAgICAgICAgICJjZWxsIjogewogICAgICAgICAgICAgICAgImtleSI6ICIweDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiLAogICAgICAgICAgICAgICAgInR5IjogMAogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAidG90YWxfc3VwcGx5IgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImxheW91dCI6IHsKICAgICAgICAgICAgICAiY2VsbCI6IHsKICAgICAgICAgICAgICAgICJrZXkiOiAiMHgwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIiwKICAgICAgICAgICAgICAgICJ0eSI6IDEKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImJhbGFuY2VzIgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImxheW91dCI6IHsKICAgICAgICAgICAgICAiY2VsbCI6IHsKICAgICAgICAgICAgICAgICJrZXkiOiAiMHgwMjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIiwKICAgICAgICAgICAgICAgICJ0eSI6IDYKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImFsbG93YW5jZXMiCiAgICAgICAgICB9CiAgICAgICAgXQogICAgICB9CiAgICB9LAogICAgInR5cGVzIjogWwogICAgICB7CiAgICAgICAgImlkIjogMCwKICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICJkZWYiOiB7CiAgICAgICAgICAgICJwcmltaXRpdmUiOiAidTEyOCIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiaWQiOiAxLAogICAgICAgICJ0eXBlIjogewogICAgICAgICAgImRlZiI6IHsKICAgICAgICAgICAgImNvbXBvc2l0ZSI6IHsKICAgICAgICAgICAgICAiZmllbGRzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAibmFtZSI6ICJvZmZzZXRfa2V5IiwKICAgICAgICAgICAgICAgICAgInR5cGUiOiA1LAogICAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiS2V5IgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICJwYXJhbXMiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAibmFtZSI6ICJLIiwKICAgICAgICAgICAgICAidHlwZSI6IDIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICJuYW1lIjogIlYiLAogICAgICAgICAgICAgICJ0eXBlIjogMAogICAgICAgICAgICB9CiAgICAgICAgICBdLAogICAgICAgICAgInBhdGgiOiBbImlua19zdG9yYWdlIiwgImxhenkiLCAibWFwcGluZyIsICJNYXBwaW5nIl0KICAgICAgICB9CiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiaWQiOiAyLAogICAgICAgICJ0eXBlIjogewogICAgICAgICAgImRlZiI6IHsKICAgICAgICAgICAgImNvbXBvc2l0ZSI6IHsKICAgICAgICAgICAgICAiZmllbGRzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAidHlwZSI6IDMsCiAgICAgICAgICAgICAgICAgICJ0eXBlTmFtZSI6ICJbdTg7IDMyXSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAicGF0aCI6IFsiaW5rX2VudiIsICJ0eXBlcyIsICJBY2NvdW50SWQiXQogICAgICAgIH0KICAgICAgfSwKICAgICAgewogICAgICAgICJpZCI6IDMsCiAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAiZGVmIjogewogICAgICAgICAgICAiYXJyYXkiOiB7CiAgICAgICAgICAgICAgImxlbiI6IDMyLAogICAgICAgICAgICAgICJ0eXBlIjogNAogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9LAogICAgICB7CiAgICAgICAgImlkIjogNCwKICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICJkZWYiOiB7CiAgICAgICAgICAgICJwcmltaXRpdmUiOiAidTgiCiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9LAogICAgICB7CiAgICAgICAgImlkIjogNSwKICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICJkZWYiOiB7CiAgICAgICAgICAgICJjb21wb3NpdGUiOiB7CiAgICAgICAgICAgICAgImZpZWxkcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgInR5cGUiOiAzLAogICAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiW3U4OyAzMl0iCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXQogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgInBhdGgiOiBbImlua19wcmltaXRpdmVzIiwgIktleSJdCiAgICAgICAgfQogICAgICB9LAogICAgICB7CiAgICAgICAgImlkIjogNiwKICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICJkZWYiOiB7CiAgICAgICAgICAgICJjb21wb3NpdGUiOiB7CiAgICAgICAgICAgICAgImZpZWxkcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgIm5hbWUiOiAib2Zmc2V0X2tleSIsCiAgICAgICAgICAgICAgICAgICJ0eXBlIjogNSwKICAgICAgICAgICAgICAgICAgInR5cGVOYW1lIjogIktleSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAicGFyYW1zIjogWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgIm5hbWUiOiAiSyIsCiAgICAgICAgICAgICAgInR5cGUiOiA3CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAibmFtZSI6ICJWIiwKICAgICAgICAgICAgICAidHlwZSI6IDAKICAgICAgICAgICAgfQogICAgICAgICAgXSwKICAgICAgICAgICJwYXRoIjogWyJpbmtfc3RvcmFnZSIsICJsYXp5IiwgIm1hcHBpbmciLCAiTWFwcGluZyJdCiAgICAgICAgfQogICAgICB9LAogICAgICB7CiAgICAgICAgImlkIjogNywKICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICJkZWYiOiB7CiAgICAgICAgICAgICJ0dXBsZSI6IFsyLCAyXQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSwKICAgICAgewogICAgICAgICJpZCI6IDgsCiAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAiZGVmIjogewogICAgICAgICAgICAidmFyaWFudCI6IHsKICAgICAgICAgICAgICAidmFyaWFudHMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJmaWVsZHMiOiBbCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiA5CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAiaW5kZXgiOiAwLAogICAgICAgICAgICAgICAgICAibmFtZSI6ICJPayIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJmaWVsZHMiOiBbCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAxMAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAgICAgImluZGV4IjogMSwKICAgICAgICAgICAgICAgICAgIm5hbWUiOiAiRXJyIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICJwYXJhbXMiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAibmFtZSI6ICJUIiwKICAgICAgICAgICAgICAidHlwZSI6IDkKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICJuYW1lIjogIkUiLAogICAgICAgICAgICAgICJ0eXBlIjogMTAKICAgICAgICAgICAgfQogICAgICAgICAgXSwKICAgICAgICAgICJwYXRoIjogWyJSZXN1bHQiXQogICAgICAgIH0KICAgICAgfSwKICAgICAgewogICAgICAgICJpZCI6IDksCiAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAiZGVmIjogewogICAgICAgICAgICAidHVwbGUiOiBbXQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSwKICAgICAgewogICAgICAgICJpZCI6IDEwLAogICAgICAgICJ0eXBlIjogewogICAgICAgICAgImRlZiI6IHsKICAgICAgICAgICAgInZhcmlhbnQiOiB7CiAgICAgICAgICAgICAgInZhcmlhbnRzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAiaW5kZXgiOiAwLAogICAgICAgICAgICAgICAgICAibmFtZSI6ICJJbnN1ZmZpY2llbnRCYWxhbmNlIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImluZGV4IjogMSwKICAgICAgICAgICAgICAgICAgIm5hbWUiOiAiSW5zdWZmaWNpZW50QWxsb3dhbmNlIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICJwYXRoIjogWyJlcmMyMCIsICJlcmMyMCIsICJFcnJvciJdCiAgICAgICAgfQogICAgICB9LAogICAgICB7CiAgICAgICAgImlkIjogMTEsCiAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAiZGVmIjogewogICAgICAgICAgICAidmFyaWFudCI6IHsKICAgICAgICAgICAgICAidmFyaWFudHMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJpbmRleCI6IDAsCiAgICAgICAgICAgICAgICAgICJuYW1lIjogIk5vbmUiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAiZmllbGRzIjogWwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogMgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAgICAgImluZGV4IjogMSwKICAgICAgICAgICAgICAgICAgIm5hbWUiOiAiU29tZSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAicGFyYW1zIjogWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgIm5hbWUiOiAiVCIsCiAgICAgICAgICAgICAgInR5cGUiOiAyCiAgICAgICAgICAgIH0KICAgICAgICAgIF0sCiAgICAgICAgICAicGF0aCI6IFsiT3B0aW9uIl0KICAgICAgICB9CiAgICAgIH0KICAgIF0KICB9Cn0K' diff --git a/mocks/blocks-mocks.ts b/mocks/blocks-mocks.ts index 18d0a86..9ce2a12 100644 --- a/mocks/blocks-mocks.ts +++ b/mocks/blocks-mocks.ts @@ -2,6 +2,8 @@ export const mockBlock = { hash: '0x03b26a67c6c7fda467f7b96d09b99d04ef9a8163043e72b5e5474358631afad2', parentHash: '0x9b0f818b9cac7d9451819de6172e308d67c4b8ff8c2f1f6773cdb20c40573858', number: 27, + timestamp: 1590000000, + encodedLength: 100, createdDate: '2022-08-25 22:49:21.843575', } diff --git a/mocks/contracts-mocks.ts b/mocks/contracts-mocks.ts index d8a237f..04333a1 100644 --- a/mocks/contracts-mocks.ts +++ b/mocks/contracts-mocks.ts @@ -10,3 +10,12 @@ export const mockContract = { address: '5GRYcveXcsy8Y6jpHc19xE9wm6xSfzKbzZPFKZvGwzBms4hz', metadata: JSON.stringify(abi), } + +export const mockContracts = [mockContract] + +export const mockContractQueries = { + ...mockContract, + queries: [{ args: [{ fake: 'arg' }] }], +} + +export const mockQueryString = [{ args: ['{"fake":"arg"}'] }] diff --git a/mocks/events-mocks.ts b/mocks/events-mocks.ts index 2c33382..ed20c76 100644 --- a/mocks/events-mocks.ts +++ b/mocks/events-mocks.ts @@ -1,5 +1,61 @@ import { numberToU8a } from '@polkadot/util' +export const mockFormattedEvent = { + from: '', + to: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY', + value: '30000000', +} + +export const mockDecodedEvent = { + args: [ + { + toString: () => '', + }, + { + toString: () => '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY', + }, + { + toString: () => '30000000', + }, + ], + event: { + args: [ + { + name: 'from', + type: { + info: 9, + lookupIndex: 11, + lookupName: undefined, + type: 'Option', + docs: [], + namespace: 'Option', + }, + toString: () => '', + }, + { + name: 'to', + type: { + info: 9, + lookupIndex: 11, + lookupName: undefined, + type: 'Option', + docs: [], + namespace: 'Option', + }, + toString: () => '', + }, + { + name: 'value', + type: { + info: 10, + type: 'Balance', + }, + toString: () => '', + }, + ], + }, +} + export const mockEvents = [ { id: '34709348-7d86-5bb3-81ce-4320b3fd1f4e', @@ -13,6 +69,7 @@ export const mockEvents = [ '5C9QorN8S8X2Cwpa98cRevWR7YHmKqDGUPMDM3rZnLzWnRj9', '0x000001d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0000c52ebca2b1000000000000000000', ], + decodedData: undefined, createdDate: '2022-08-31 20:03:28.568881', contractAddress: '5C9QorN8S8X2Cwpa98cRevWR7YHmKqDGUPMDM3rZnLzWnRj9', }, @@ -28,6 +85,7 @@ export const mockEvents = [ '5C9QorN8S8X2Cwpa98cRevWR7YHmKqDGUPMDM3rZnLzWnRj9', '0x0001d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e0040e59c301200000000000000000000', ], + decodedData: mockDecodedEvent, createdDate: '2022-08-31 20:03:38.814484', contractAddress: '5C9QorN8S8X2Cwpa98cRevWR7YHmKqDGUPMDM3rZnLzWnRj9', }, @@ -90,53 +148,3 @@ export const mockRecords = [ '[0x0045726332303a3a5472616e7366657200000000000000000000000000000000, 0x63c87cd1c4007df77d6b16ae28c5393bee3a62fb8577e38243a6f6f5a82c457f, 0xda2d695d3b5a304e0039e7fc4419c34fa0c1f239189c99bb72a6484f1634782b]', }, ] - -export const mockDecodedEvent = { - args: [ - { - toString: () => '', - }, - { - toString: () => '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY', - }, - { - toString: () => '30000000', - }, - ], - event: { - args: [ - { - name: 'from', - type: { - info: 9, - lookupIndex: 11, - lookupName: undefined, - type: 'Option', - docs: [], - namespace: 'Option', - }, - toString: () => '', - }, - { - name: 'to', - type: { - info: 9, - lookupIndex: 11, - lookupName: undefined, - type: 'Option', - docs: [], - namespace: 'Option', - }, - toString: () => '', - }, - { - name: 'value', - type: { - info: 10, - type: 'Balance', - }, - toString: () => '', - }, - ], - }, -} diff --git a/mocks/pino-mocks.ts b/mocks/pino-mocks.ts index 215aead..8d0be2f 100644 --- a/mocks/pino-mocks.ts +++ b/mocks/pino-mocks.ts @@ -6,5 +6,6 @@ export const mockPinoService = (serviceName: string) => ({ info: jest.fn(), debug: jest.fn(), error: jest.fn(), + warn: jest.fn(), }, }) diff --git a/mocks/transactions-mock.ts b/mocks/transactions-mock.ts index 7e25327..bdb9d9b 100644 --- a/mocks/transactions-mock.ts +++ b/mocks/transactions-mock.ts @@ -11,6 +11,7 @@ export const mockTransaction = { signer: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY', nonce: 37, tip: 0, + timestamp: 1600000000000, createdDate: '2022-08-25 23:42:49.006343', } @@ -41,6 +42,8 @@ export const mockTransactions = [ }, ] +export const mockTimestamp = 1600000000000 + export const mockExtrinsics = [ { hash: stringToHex('0x01c780fccc47dc4e9652180876a8267dc9f9dd501ed249f077e32c1653a89f2a'), @@ -57,6 +60,22 @@ export const mockExtrinsics = [ method: { method: 'set', section: 'timestamp', + args: [mockTimestamp], + }, + encodedLength: 0, + registry: { + chainDecimals: { + toString: () => '12', + }, + chainSS58: { + toString: () => '42', + }, + }, + era: {}, + version: 0, + type: 0, + callIndex: { + toString: () => '0x0000', }, }, { @@ -74,6 +93,7 @@ export const mockExtrinsics = [ method: { method: 'call', section: 'timestamp', + args: [mockTimestamp], }, }, ] diff --git a/package.json b/package.json index ad8cedd..d7a9ca9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ink-substrate-explorer-api", - "version": "1.0.0", + "version": "1.0.1", "description": "Ink Explorer is an application that provides Ink contracts related information on Substrate based blockchains.", "author": "Blockcoders ", "license": "MIT", @@ -93,12 +93,12 @@ "@nestjs/mapped-types": "1.1.0", "@nestjs/platform-fastify": "8.4.7", "@nestjs/typeorm": "9.0.0", - "@polkadot/api": "^8.14.1", - "@polkadot/api-augment": "^8.14.1", - "@polkadot/api-contract": "^8.14.1", - "@polkadot/types": "^8.14.1", - "@polkadot/types-codec": "^8.14.1", - "@polkadot/types-create": "^8.14.1", + "@polkadot/api": "^9.4.3", + "@polkadot/api-augment": "^9.4.3", + "@polkadot/api-contract": "^9.4.3", + "@polkadot/types": "^9.4.3", + "@polkadot/types-codec": "^9.4.3", + "@polkadot/types-create": "^9.4.3", "@polkadot/util": "10.1.2", "@substrate/txwrapper": "^7.0.1", "@substrate/txwrapper-core": "^3.1.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2e48f59..7b71472 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,12 +15,12 @@ specifiers: '@nestjs/schematics': ^8.0.11 '@nestjs/testing': ^8.4.7 '@nestjs/typeorm': 9.0.0 - '@polkadot/api': ^8.14.1 - '@polkadot/api-augment': ^8.14.1 - '@polkadot/api-contract': ^8.14.1 - '@polkadot/types': ^8.14.1 - '@polkadot/types-codec': ^8.14.1 - '@polkadot/types-create': ^8.14.1 + '@polkadot/api': ^9.4.3 + '@polkadot/api-augment': ^9.4.3 + '@polkadot/api-contract': ^9.4.3 + '@polkadot/types': ^9.4.3 + '@polkadot/types-codec': ^9.4.3 + '@polkadot/types-create': ^9.4.3 '@polkadot/util': 10.1.2 '@substrate/txwrapper': ^7.0.1 '@substrate/txwrapper-core': ^3.1.7 @@ -78,12 +78,12 @@ dependencies: '@nestjs/mapped-types': 1.1.0_7zw7e46jhcfuw5vwuwho2brjki '@nestjs/platform-fastify': 8.4.7_7tsmhnugyerf5okgqzer2mfqme '@nestjs/typeorm': 9.0.0_zhrs42futwpjx7z3p6twpp4g7i - '@polkadot/api': 8.14.1 - '@polkadot/api-augment': 8.14.1 - '@polkadot/api-contract': 8.14.1 - '@polkadot/types': 8.14.1 - '@polkadot/types-codec': 8.14.1 - '@polkadot/types-create': 8.14.1 + '@polkadot/api': 9.4.3 + '@polkadot/api-augment': 9.4.3 + '@polkadot/api-contract': 9.4.3 + '@polkadot/types': 9.4.3 + '@polkadot/types-codec': 9.4.3 + '@polkadot/types-create': 9.4.3 '@polkadot/util': 10.1.2 '@substrate/txwrapper': 7.0.1 '@substrate/txwrapper-core': 3.1.7 @@ -654,6 +654,20 @@ packages: regenerator-runtime: 0.13.9 dev: false + /@babel/runtime/7.19.0: + resolution: {integrity: sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.13.9 + dev: false + + /@babel/runtime/7.19.4: + resolution: {integrity: sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.13.9 + dev: false + /@babel/template/7.18.10: resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} engines: {node: '>=6.9.0'} @@ -1521,6 +1535,10 @@ packages: resolution: {integrity: sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==} dev: false + /@noble/hashes/1.1.3: + resolution: {integrity: sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A==} + dev: false + /@noble/secp256k1/1.5.5: resolution: {integrity: sha512-sZ1W6gQzYnu45wPrWx8D3kwI2/U29VYTx9OjbDAd7jwRItJ0cSTMPRL/C8AWZFn9kWFLQGqEXVEE86w4Z8LpIQ==} dev: false @@ -1533,6 +1551,10 @@ packages: resolution: {integrity: sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==} dev: false + /@noble/secp256k1/1.7.0: + resolution: {integrity: sha512-kbacwGSsH/CTout0ZnZWxnW1B+jH/7r/WAAKLBtrRJ/+CUH7lgmQzl3GTrQua3SGKWNSDsS6lmjnDpIJ5Dxyaw==} + dev: false + /@nodelib/fs.scandir/2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1592,7 +1614,7 @@ packages: resolution: {integrity: sha512-7csQLS6zuYuGq7W1EkTBz1ZmxyRvx/Qpz7E7zPSwxmY8Whb7Yn2effU9XF0eCcRpyfSW8LodF8wMmLxGYs1OaQ==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/api-base': 7.15.1 '@polkadot/rpc-augment': 7.15.1 '@polkadot/types': 7.15.1 @@ -1608,28 +1630,45 @@ packages: resolution: {integrity: sha512-65GMlgVnZd08Ifh8uAj+p/+MlXxvsAfBcCHjQhOmbCE0dki+rzTPUR31LsWyDKtuw+nUBj0iZN4PelO+wU4r0g==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/api-base': 8.14.1 '@polkadot/rpc-augment': 8.14.1 '@polkadot/types': 8.14.1 '@polkadot/types-augment': 8.14.1 '@polkadot/types-codec': 8.14.1 - '@polkadot/util': 10.1.6 + '@polkadot/util': 10.1.10 transitivePeerDependencies: - supports-color dev: false - /@polkadot/api-augment/9.3.3: - resolution: {integrity: sha512-usO5G2lDjzmwrPCgpe9IS5J2gddrDfeuWECc9/ruw35/ag4x8uZkiViC9762pF9fu9ZzNfSrk2QRnVGRcbG1ZQ==} + /@polkadot/api-augment/9.4.3: + resolution: {integrity: sha512-w1iAdfpHprQiPkk9s98vRFqf9AJ70GoheGAEqO6p7JKYoutPlA8Pg8NiacwiCWW464zdbRn/T2/fWGtn8Iv27A==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/api-base': 9.3.3 - '@polkadot/rpc-augment': 9.3.3 - '@polkadot/types': 9.3.3 - '@polkadot/types-augment': 9.3.3 - '@polkadot/types-codec': 9.3.3 - '@polkadot/util': 10.1.7 + '@babel/runtime': 7.19.0 + '@polkadot/api-base': 9.4.3 + '@polkadot/rpc-augment': 9.4.3 + '@polkadot/types': 9.4.3 + '@polkadot/types-augment': 9.4.3 + '@polkadot/types-codec': 9.4.3 + '@polkadot/util': 10.1.10 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: false + + /@polkadot/api-augment/9.5.2: + resolution: {integrity: sha512-dH6QMY8Z3zI6CrgSU3eSe6f0KWDb5PYGztg/FXGPrjh7Vjic7syWZ1LD6zaHJAFWDp80BEdEXfqr4lConrCKGg==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.4 + '@polkadot/api-base': 9.5.2 + '@polkadot/rpc-augment': 9.5.2 + '@polkadot/types': 9.5.2 + '@polkadot/types-augment': 9.5.2 + '@polkadot/types-codec': 9.5.2 + '@polkadot/util': 10.1.11 transitivePeerDependencies: - bufferutil - supports-color @@ -1640,11 +1679,11 @@ packages: resolution: {integrity: sha512-UlhLdljJPDwGpm5FxOjvJNFTxXMRFaMuVNx6EklbuetbBEJ/Amihhtj0EJRodxQwtZ4ZtPKYKt+g+Dn7OJJh4g==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/rpc-core': 7.15.1 '@polkadot/types': 7.15.1 '@polkadot/util': 8.7.1 - rxjs: 7.5.6 + rxjs: 7.5.7 transitivePeerDependencies: - encoding - supports-color @@ -1654,51 +1693,68 @@ packages: resolution: {integrity: sha512-EXFhNXIfpirf18IsqcG2pGQW1/Xn+bfjqVYQMMJ4ZONtYH4baZZlXk7SoXCCHonN2x1ixs4DOcRx5oVxjabdIQ==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/rpc-core': 8.14.1 '@polkadot/types': 8.14.1 - '@polkadot/util': 10.1.6 - rxjs: 7.5.6 + '@polkadot/util': 10.1.10 + rxjs: 7.5.7 transitivePeerDependencies: - supports-color dev: false - /@polkadot/api-base/9.3.3: - resolution: {integrity: sha512-MFjcdwNyqKxoWkqSJRkMtaQogFxsCW6HBVowT0lUrQ2WzTLBWQqi7DcC/0RsRQXXN/SsUwczi3g9b12wqLZLhg==} + /@polkadot/api-base/9.4.3: + resolution: {integrity: sha512-gYzf7LIcKo/rEGlXgoMOS619srcTmyD7wwZ9b0xh/Xg0vHPyUi8OVs3i4SRQrXS8KSVuZzBCrqALPytXmV0xdg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/rpc-core': 9.3.3 - '@polkadot/types': 9.3.3 - '@polkadot/util': 10.1.7 - rxjs: 7.5.6 + '@babel/runtime': 7.19.0 + '@polkadot/rpc-core': 9.4.3 + '@polkadot/types': 9.4.3 + '@polkadot/util': 10.1.10 + rxjs: 7.5.7 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate dev: false - /@polkadot/api-contract/8.14.1: - resolution: {integrity: sha512-ZIdlSoN5WktQD/Q97cg7MuRcQsFe+4RZDXLew2uUg2R1IyEon+TzEGPXUPVAEQuhlOyRxT6f4/UEM/yTdoGPSQ==} + /@polkadot/api-base/9.5.2: + resolution: {integrity: sha512-BBsH9SLB1FHgjdiU32cZX1puL3Eh8IjOJHjRsO/5SdttciQhF5g/u/m/mM/55qnlXmffI9s2Jre18G0XtVU9Aw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/api': 8.14.1 - '@polkadot/types': 8.14.1 - '@polkadot/types-codec': 8.14.1 - '@polkadot/types-create': 8.14.1 - '@polkadot/util': 10.1.6 - '@polkadot/util-crypto': 10.1.2 - rxjs: 7.5.6 + '@babel/runtime': 7.19.4 + '@polkadot/rpc-core': 9.5.2 + '@polkadot/types': 9.5.2 + '@polkadot/util': 10.1.11 + rxjs: 7.5.7 transitivePeerDependencies: + - bufferutil - supports-color + - utf-8-validate + dev: false + + /@polkadot/api-contract/9.4.3: + resolution: {integrity: sha512-PnBZyUgaLf7DGHkfrRrYISGRXLpZXykJj3L6KKcMrZL7MgiPvyhYzNVXCTmhGOjPQxhaYUDk8VPWmArLf8qT2Q==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.0 + '@polkadot/api': 9.4.3 + '@polkadot/types': 9.4.3 + '@polkadot/types-codec': 9.4.3 + '@polkadot/types-create': 9.4.3 + '@polkadot/util': 10.1.10 + '@polkadot/util-crypto': 10.1.10 + rxjs: 7.5.7 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate dev: false /@polkadot/api-derive/4.17.1: resolution: {integrity: sha512-mgq57F1yAiZjuiA0vrR2zWidyyd+mGe7Kbs4SxVeDWLsNbLc9+eASIfX7Hch2SDHIn3CQpv6DQqJH00uDfw9Lw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/api': 4.17.1 '@polkadot/rpc-core': 4.17.1 '@polkadot/types': 4.17.1 @@ -1714,7 +1770,7 @@ packages: resolution: {integrity: sha512-CsOQppksQBaa34L1fWRzmfQQpoEBwfH0yTTQxgj3h7rFYGVPxEKGeFjo1+IgI2vXXvOO73Z8E4H/MnbxvKrs1Q==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/api': 7.15.1 '@polkadot/api-augment': 7.15.1 '@polkadot/api-base': 7.15.1 @@ -1723,7 +1779,7 @@ packages: '@polkadot/types-codec': 7.15.1 '@polkadot/util': 8.7.1 '@polkadot/util-crypto': 8.7.1 - rxjs: 7.5.6 + rxjs: 7.5.7 transitivePeerDependencies: - encoding - supports-color @@ -1733,34 +1789,54 @@ packages: resolution: {integrity: sha512-eWG1MrQhHMUjt9gDHN9/9/ZMATu1MolqcalPFhNoGtdON3+I0J3ntjQ4y5X7+p2OGwQplpYRKqbK4k7tKzu8tA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/api': 8.14.1 '@polkadot/api-augment': 8.14.1 '@polkadot/api-base': 8.14.1 '@polkadot/rpc-core': 8.14.1 '@polkadot/types': 8.14.1 '@polkadot/types-codec': 8.14.1 - '@polkadot/util': 10.1.6 - '@polkadot/util-crypto': 10.1.2 - rxjs: 7.5.6 + '@polkadot/util': 10.1.10 + '@polkadot/util-crypto': 10.1.10 + rxjs: 7.5.7 transitivePeerDependencies: - supports-color dev: false - /@polkadot/api-derive/9.3.3: - resolution: {integrity: sha512-UiIEKJ0YttgrAqikK/sH0CxedZMijoM33Fuyr4mNWe7srb5MewoABdnwzUMmRVDLjrKA18gtOfSNhqEDliRYGw==} + /@polkadot/api-derive/9.4.3: + resolution: {integrity: sha512-6lKjJs93ucSF/mmljG32TcWq4gg35MimbuXxDYwNYXwuGm6ocN0auWp6Opg+DGLuwapfHhkOyZxSBVWi37gjEQ==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/api': 9.3.3 - '@polkadot/api-augment': 9.3.3 - '@polkadot/api-base': 9.3.3 - '@polkadot/rpc-core': 9.3.3 - '@polkadot/types': 9.3.3 - '@polkadot/types-codec': 9.3.3 - '@polkadot/util': 10.1.7 - '@polkadot/util-crypto': 10.1.7 - rxjs: 7.5.6 + '@babel/runtime': 7.19.0 + '@polkadot/api': 9.4.3 + '@polkadot/api-augment': 9.4.3 + '@polkadot/api-base': 9.4.3 + '@polkadot/rpc-core': 9.4.3 + '@polkadot/types': 9.4.3 + '@polkadot/types-codec': 9.4.3 + '@polkadot/util': 10.1.10 + '@polkadot/util-crypto': 10.1.10 + rxjs: 7.5.7 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: false + + /@polkadot/api-derive/9.5.2: + resolution: {integrity: sha512-kWn12dlqfIES1trNLd3O1i2qa4T97v/co1VMCgVstICwCt3+mGZgpxkMqQqPiWHagKEVeBNoAn+h8eOiQlbujA==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.4 + '@polkadot/api': 9.5.2 + '@polkadot/api-augment': 9.5.2 + '@polkadot/api-base': 9.5.2 + '@polkadot/rpc-core': 9.5.2 + '@polkadot/types': 9.5.2 + '@polkadot/types-codec': 9.5.2 + '@polkadot/util': 10.1.11 + '@polkadot/util-crypto': 10.1.11 + rxjs: 7.5.7 transitivePeerDependencies: - bufferutil - supports-color @@ -1771,7 +1847,7 @@ packages: resolution: {integrity: sha512-uuNIKWC+PjM+1AARRu4NLWOEudZE6DW8UOlaubx3uGhPywqPIP+HGWP2I6PqRGYKARBWxxOvca1Q7WoKzpYC8w==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/api-derive': 4.17.1 '@polkadot/keyring': 6.11.1 '@polkadot/metadata': 4.17.1 @@ -1792,7 +1868,7 @@ packages: resolution: {integrity: sha512-z0z6+k8+R9ixRMWzfsYrNDnqSV5zHKmyhTCL0I7+1I081V18MJTCFUKubrh0t1gD0/FCt3U9Ibvr4IbtukYLrQ==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/api-augment': 7.15.1 '@polkadot/api-base': 7.15.1 '@polkadot/api-derive': 7.15.1 @@ -1808,7 +1884,7 @@ packages: '@polkadot/util': 8.7.1 '@polkadot/util-crypto': 8.7.1 eventemitter3: 4.0.7 - rxjs: 7.5.6 + rxjs: 7.5.7 transitivePeerDependencies: - encoding - supports-color @@ -1818,7 +1894,7 @@ packages: resolution: {integrity: sha512-jg26eIKFYqVfDBTAopHL3aDaNw9j6TdUkXuvYJOnynpecU4xwbTVKcOtSOjJ2eRX4MgMQ4zlyMHJx3iKw0uUTA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/api-augment': 8.14.1 '@polkadot/api-base': 8.14.1 '@polkadot/api-derive': 8.14.1 @@ -1831,7 +1907,7 @@ packages: '@polkadot/types-codec': 8.14.1 '@polkadot/types-create': 8.14.1 '@polkadot/types-known': 8.14.1 - '@polkadot/util': 10.1.6 + '@polkadot/util': 10.1.10 '@polkadot/util-crypto': 10.1.2 eventemitter3: 4.0.7 rxjs: 7.5.6 @@ -1839,27 +1915,54 @@ packages: - supports-color dev: false - /@polkadot/api/9.3.3: - resolution: {integrity: sha512-esOfwnKS/6JRL0C8TDqYn4GC9GkWp8vTdKIWLuncW2jEtiJLYccb5IVngfOQImVrqAQoV1hJdLnj9X6k+tGqQQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/api-augment': 9.3.3 - '@polkadot/api-base': 9.3.3 - '@polkadot/api-derive': 9.3.3 - '@polkadot/keyring': 10.1.7 - '@polkadot/rpc-augment': 9.3.3 - '@polkadot/rpc-core': 9.3.3 - '@polkadot/rpc-provider': 9.3.3 - '@polkadot/types': 9.3.3 - '@polkadot/types-augment': 9.3.3 - '@polkadot/types-codec': 9.3.3 - '@polkadot/types-create': 9.3.3 - '@polkadot/types-known': 9.3.3 - '@polkadot/util': 10.1.7 - '@polkadot/util-crypto': 10.1.7 + /@polkadot/api/9.4.3: + resolution: {integrity: sha512-vbeWW2tyntAmWllUqnOwlaprFT+5o8a0uP0Qkz5QfLslUFZtxhHhLWtQWVtJnoqC5FN10ZybDkUGFlsxNsvwgg==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.0 + '@polkadot/api-augment': 9.4.3 + '@polkadot/api-base': 9.4.3 + '@polkadot/api-derive': 9.4.3 + '@polkadot/keyring': 10.1.10 + '@polkadot/rpc-augment': 9.4.3 + '@polkadot/rpc-core': 9.4.3 + '@polkadot/rpc-provider': 9.4.3 + '@polkadot/types': 9.4.3 + '@polkadot/types-augment': 9.4.3 + '@polkadot/types-codec': 9.4.3 + '@polkadot/types-create': 9.4.3 + '@polkadot/types-known': 9.4.3 + '@polkadot/util': 10.1.10 + '@polkadot/util-crypto': 10.1.10 eventemitter3: 4.0.7 - rxjs: 7.5.6 + rxjs: 7.5.7 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: false + + /@polkadot/api/9.5.2: + resolution: {integrity: sha512-iEF/E8vQan3fHmIEl3bX7Yn/1jQLlvSDwPOxiQdj4tIcF36HX6vCbkdhQKRif0CNYES58TA9EKFiCNg81k+kXw==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.4 + '@polkadot/api-augment': 9.5.2 + '@polkadot/api-base': 9.5.2 + '@polkadot/api-derive': 9.5.2 + '@polkadot/keyring': 10.1.11 + '@polkadot/rpc-augment': 9.5.2 + '@polkadot/rpc-core': 9.5.2 + '@polkadot/rpc-provider': 9.5.2 + '@polkadot/types': 9.5.2 + '@polkadot/types-augment': 9.5.2 + '@polkadot/types-codec': 9.5.2 + '@polkadot/types-create': 9.5.2 + '@polkadot/types-known': 9.5.2 + '@polkadot/util': 10.1.11 + '@polkadot/util-crypto': 10.1.11 + eventemitter3: 4.0.7 + rxjs: 7.5.7 transitivePeerDependencies: - bufferutil - supports-color @@ -1913,29 +2016,38 @@ packages: - utf-8-validate dev: false - /@polkadot/keyring/10.1.2: - resolution: {integrity: sha512-b6hP3JFGYjsNNT3NO7I8fWRPqovgL4IvjvLttkfzpM6eM1zRRupqQ+Q50Jdl/3YUcr26PcxQcdRqJku4WyDABg==} + /@polkadot/keyring/10.1.10: + resolution: {integrity: sha512-crKYBbwmPcFoTP6mby2+o1QWsjAyi5QlKzU8tXuXOApP6SBuqmDujIuLOKNG2vZoftNdVldsVL0WmKVYtBeuQg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/util': 10.1.2 - '@polkadot/util-crypto': 10.1.2 + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.10 + '@polkadot/util-crypto': 10.1.10 dev: false - /@polkadot/keyring/10.1.7: - resolution: {integrity: sha512-lArwaAS3hDs+HHupDIC4r2mFaAfmNQV2YzwL2wM5zhOqB2RugN03BFrgwNll0y9/Bg8rYDqM3Y5BvVMzgMZ6XA==} + /@polkadot/keyring/10.1.11: + resolution: {integrity: sha512-Nv8cZaOA/KbdslDMTklJ58+y+UPpic3+oMQoozuq48Ccjv7WeW2BX47XM/RNE8nYFg6EHa6Whfm4IFaFb8s7ag==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/util': 10.1.7 - '@polkadot/util-crypto': 10.1.7 + '@babel/runtime': 7.19.4 + '@polkadot/util': 10.1.11 + '@polkadot/util-crypto': 10.1.11 + dev: false + + /@polkadot/keyring/10.1.2: + resolution: {integrity: sha512-b6hP3JFGYjsNNT3NO7I8fWRPqovgL4IvjvLttkfzpM6eM1zRRupqQ+Q50Jdl/3YUcr26PcxQcdRqJku4WyDABg==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.2 + '@polkadot/util-crypto': 10.1.2 dev: false /@polkadot/keyring/6.11.1: resolution: {integrity: sha512-rW8INl7pO6Dmaffd6Df1yAYCRWa2RmWQ0LGfJeA/M6seVIkI6J3opZqAd4q2Op+h9a7z4TESQGk8yggOEL+Csg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 6.11.1 '@polkadot/util-crypto': 6.11.1 dev: false @@ -1944,7 +2056,7 @@ packages: resolution: {integrity: sha512-6UGoIxhiTyISkYEZhUbCPpgVxaneIfb/DBVlHtbvaABc8Mqh1KuqcTIq19Mh9wXlBuijl25rw4lUASrE/9sBqg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 7.9.2 '@polkadot/util-crypto': 7.9.2 dev: false @@ -1953,7 +2065,7 @@ packages: resolution: {integrity: sha512-t6ZgQVC+nQT7XwbWtEhkDpiAzxKVJw8Xd/gWdww6xIrawHu7jo3SGB4QNdPgkf8TvDHYAAJiupzVQYAlOIq3GA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 8.7.1 '@polkadot/util-crypto': 8.7.1 dev: false @@ -1962,7 +2074,7 @@ packages: resolution: {integrity: sha512-219isiCWVfbu5JxZnOPj+cV4T+S0XHS4+Jal3t3xz9y4nbgr+25Pa4KInEsJPx0u8EZAxMeiUCX3vd5U7oe72g==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/types': 4.17.1 '@polkadot/types-known': 4.17.1 '@polkadot/util': 6.11.1 @@ -1978,43 +2090,52 @@ packages: '@substrate/ss58-registry': 1.25.0 dev: false - /@polkadot/networks/10.1.2: - resolution: {integrity: sha512-67ZPqdhLYDGNX1jMEa3+hujh9j30Dr9AdqgdjE8Z3GdWoEVRp9Zda3DXMnDIQlRBQ32pRZty7dFhIq61Bv/whQ==} + /@polkadot/networks/10.1.10: + resolution: {integrity: sha512-Db78t2XnFIZbdSdu1aFuj3/1cNwcSzG/+wNrpCQ9dPhnGPy5S1GVbmU8pyxTftPKdTFc+8RdBr+5bc0d5ijGiA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/util': 10.1.2 - '@substrate/ss58-registry': 1.25.0 + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.10 + '@substrate/ss58-registry': 1.31.0 dev: false - /@polkadot/networks/10.1.7: - resolution: {integrity: sha512-ol864SZ/GwAF72GQOPRy+Y9r6NtgJJjMBlDLESvV5VK64eEB0MRSSyiOdd7y/4SumR9crrrNimx3ynACFgxZ8A==} + /@polkadot/networks/10.1.11: + resolution: {integrity: sha512-4FfOVETXwh6PL6wd6fYJMkRSQKm+xUw3vR5rHqcAnB696FpMFPPErc6asgZ9lYMyzNJRY3yG86HQpFhtCv1nGA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/util': 10.1.7 - '@substrate/ss58-registry': 1.28.0 + '@babel/runtime': 7.19.4 + '@polkadot/util': 10.1.11 + '@substrate/ss58-registry': 1.33.0 + dev: false + + /@polkadot/networks/10.1.2: + resolution: {integrity: sha512-67ZPqdhLYDGNX1jMEa3+hujh9j30Dr9AdqgdjE8Z3GdWoEVRp9Zda3DXMnDIQlRBQ32pRZty7dFhIq61Bv/whQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.2 + '@substrate/ss58-registry': 1.25.0 dev: false /@polkadot/networks/6.11.1: resolution: {integrity: sha512-0C6Ha2kvr42se3Gevx6UhHzv3KnPHML0N73Amjwvdr4y0HLZ1Nfw+vcm5yqpz5gpiehqz97XqFrsPRauYdcksQ==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 dev: false /@polkadot/networks/7.9.2: resolution: {integrity: sha512-4obI1RdW5/7TFwbwKA9oqw8aggVZ65JAUvIFMd2YmMC2T4+NiZLnok0WhRkhZkUnqjLIHXYNwq7Ho1i39dte0g==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 dev: false /@polkadot/networks/8.7.1: resolution: {integrity: sha512-8xAmhDW0ry5EKcEjp6VTuwoTm0DdDo/zHsmx88P6sVL87gupuFsL+B6TrsYLl8GcaqxujwrOlKB+CKTUg7qFKg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 8.7.1 '@substrate/ss58-registry': 1.25.0 dev: false @@ -2023,7 +2144,7 @@ packages: resolution: {integrity: sha512-oMAdF8Y9CLBI0EUZBcycHcvbQQdbkJHevPJ/lwnZXJTaueXuav/Xm2yiFj5J3V8meIjLocURlMawgsAVItXOBQ==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 9.7.2 '@substrate/ss58-registry': 1.25.0 dev: false @@ -2032,7 +2153,7 @@ packages: resolution: {integrity: sha512-sK0+mphN7nGz/eNPsshVi0qd0+N0Pqxuebwc1YkUGP0f9EkDxzSGp6UjGcSwWVaAtk9WZZ1MpK1Jwb/2GrKV7Q==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/rpc-core': 7.15.1 '@polkadot/types': 7.15.1 '@polkadot/types-codec': 7.15.1 @@ -2046,24 +2167,39 @@ packages: resolution: {integrity: sha512-0dIsNVIMeCp0kV7+Obz0Odt6K32Ka2ygwhiV5jhhJthy8GJBPo94mKDed5gzln3Dgl2LEdJJt1h/pgCx4a2i4A==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/rpc-core': 8.14.1 '@polkadot/types': 8.14.1 '@polkadot/types-codec': 8.14.1 - '@polkadot/util': 10.1.6 + '@polkadot/util': 10.1.10 transitivePeerDependencies: - supports-color dev: false - /@polkadot/rpc-augment/9.3.3: - resolution: {integrity: sha512-xU+Fc1gm3C0CvFl2+38LN5qAdyw4ECSj2qxTymro6jqnHxpiyCvRtMg5Grl3MzREVFwhthg80W19jT1hjdPhyg==} + /@polkadot/rpc-augment/9.4.3: + resolution: {integrity: sha512-j4oFAPfP+AyQVb1rl8Jbj5k0UqfZyHUy0+CLHtu/Q0S9Wk0R1SDPACpI+93H0DjwYAFfsxbRMhloAH1IJWD5uA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/rpc-core': 9.3.3 - '@polkadot/types': 9.3.3 - '@polkadot/types-codec': 9.3.3 - '@polkadot/util': 10.1.7 + '@babel/runtime': 7.19.0 + '@polkadot/rpc-core': 9.4.3 + '@polkadot/types': 9.4.3 + '@polkadot/types-codec': 9.4.3 + '@polkadot/util': 10.1.10 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: false + + /@polkadot/rpc-augment/9.5.2: + resolution: {integrity: sha512-QAcunC7p/T4xy6e4m0Q1c9tiVYxnm+S9o10tmtx0K4qXzrc/4I2/tsw3nEGi3BzJhvMpFondSQGcJ3gyLwpmVA==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.4 + '@polkadot/rpc-core': 9.5.2 + '@polkadot/types': 9.5.2 + '@polkadot/types-codec': 9.5.2 + '@polkadot/util': 10.1.11 transitivePeerDependencies: - bufferutil - supports-color @@ -2074,7 +2210,7 @@ packages: resolution: {integrity: sha512-1gqYaYuSSQsRmt3ol55jmjBP/euKyAh4PwSj94I2wu0fngK/FZwVZNDJZn/Ib68X/s38TBIgqJ6+YdUdr3z1xw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/metadata': 4.17.1 '@polkadot/rpc-provider': 4.17.1 '@polkadot/types': 4.17.1 @@ -2089,12 +2225,12 @@ packages: resolution: {integrity: sha512-4Sb0e0PWmarCOizzxQAE1NQSr5z0n+hdkrq3+aPohGu9Rh4PodG+OWeIBy7Ov/3GgdhNQyBLG+RiVtliXecM3g==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/rpc-augment': 7.15.1 '@polkadot/rpc-provider': 7.15.1 '@polkadot/types': 7.15.1 '@polkadot/util': 8.7.1 - rxjs: 7.5.6 + rxjs: 7.5.7 transitivePeerDependencies: - encoding - supports-color @@ -2104,26 +2240,42 @@ packages: resolution: {integrity: sha512-deQ8Ob59ao/1fZQdaVtFjYR/HCBdxSYvQGt7/alBu1Uig9Sahx9oKcMkU5rWY36XqGZYos4zLay98W2hDlf+6Q==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/rpc-augment': 8.14.1 '@polkadot/rpc-provider': 8.14.1 '@polkadot/types': 8.14.1 - '@polkadot/util': 10.1.6 - rxjs: 7.5.6 + '@polkadot/util': 10.1.10 + rxjs: 7.5.7 transitivePeerDependencies: - supports-color dev: false - /@polkadot/rpc-core/9.3.3: - resolution: {integrity: sha512-KMT98HeYt6IpFvTRKWhFkHxQvGhuVIT0gyOjvT+hmuDQqt3k3bcgoQSR7218uD51NNYhnZJpjAKl3LTJz2Fdgg==} + /@polkadot/rpc-core/9.4.3: + resolution: {integrity: sha512-xTU33bNnqdLaaCFdGnoxY03rmmgUKH/2JoEa+fBRvt9RPc7KuanWSKSeHieekZXSgCXBJ3zbfStyo43klg74OQ==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/rpc-augment': 9.3.3 - '@polkadot/rpc-provider': 9.3.3 - '@polkadot/types': 9.3.3 - '@polkadot/util': 10.1.7 - rxjs: 7.5.6 + '@babel/runtime': 7.19.0 + '@polkadot/rpc-augment': 9.4.3 + '@polkadot/rpc-provider': 9.4.3 + '@polkadot/types': 9.4.3 + '@polkadot/util': 10.1.10 + rxjs: 7.5.7 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: false + + /@polkadot/rpc-core/9.5.2: + resolution: {integrity: sha512-4PbNz0GEp3FXYOnsS7mDHZy9DNVBOl56fq8vs09rLkEkrrvGkHmCvabEEWL7OPbwBzwzsCxdgI+IdkVTUKXPkQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.4 + '@polkadot/rpc-augment': 9.5.2 + '@polkadot/rpc-provider': 9.5.2 + '@polkadot/types': 9.5.2 + '@polkadot/util': 10.1.11 + rxjs: 7.5.7 transitivePeerDependencies: - bufferutil - supports-color @@ -2134,7 +2286,7 @@ packages: resolution: {integrity: sha512-vlU1H5mnfP0Ej8PbjcxwF9ZlT7LtcpekOKI4iYfMnfdelSUKUVyaD5PC8yRGIg9fxkorA6OM5AZs116jAl3TLA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/types': 4.17.1 '@polkadot/util': 6.11.1 '@polkadot/util-crypto': 6.11.1 @@ -2151,7 +2303,7 @@ packages: resolution: {integrity: sha512-n0RWfSaD/r90JXeJkKry1aGZwJeBUUiMpXUQ9Uvp6DYBbYEDs0fKtWLpdT3PdFrMbe5y3kwQmNLxwe6iF4+mzg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/keyring': 8.7.1 '@polkadot/types': 7.15.1 '@polkadot/types-support': 7.15.1 @@ -2173,12 +2325,12 @@ packages: resolution: {integrity: sha512-pAUSHZiSWLhBSYf4LmLc8iCaeqTu7Ajn8AzyqxvZDHGnIrzV5M7eTjpNDP84qno6jWRHKQ/IILr62hausEmS5w==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/keyring': 10.1.2 '@polkadot/types': 8.14.1 '@polkadot/types-support': 8.14.1 - '@polkadot/util': 10.1.6 - '@polkadot/util-crypto': 10.1.2 + '@polkadot/util': 10.1.10 + '@polkadot/util-crypto': 10.1.10 '@polkadot/x-fetch': 10.1.2 '@polkadot/x-global': 10.1.6 '@polkadot/x-ws': 10.1.2 @@ -2190,20 +2342,43 @@ packages: - supports-color dev: false - /@polkadot/rpc-provider/9.3.3: - resolution: {integrity: sha512-A5eX5WfG5JeYXUNRBOEGtSqvmQN6jqbrAmXkufSWYvGb/1Ip2l/9oHuUjswGLdpaWfOkpVkClyCXIFtWx06XNw==} + /@polkadot/rpc-provider/9.4.3: + resolution: {integrity: sha512-8HCkwlDnH6Y6WNT0Yg8e6YM5Wk+GacnO906nhtHByR2MRL8ugvLRb0x97PSPrR+NYs+ecYUURFkRy0fujuFcHQ==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/keyring': 10.1.7 - '@polkadot/types': 9.3.3 - '@polkadot/types-support': 9.3.3 - '@polkadot/util': 10.1.7 - '@polkadot/util-crypto': 10.1.7 - '@polkadot/x-fetch': 10.1.7 - '@polkadot/x-global': 10.1.7 - '@polkadot/x-ws': 10.1.7 - '@substrate/connect': 0.7.11 + '@babel/runtime': 7.19.0 + '@polkadot/keyring': 10.1.10 + '@polkadot/types': 9.4.3 + '@polkadot/types-support': 9.4.3 + '@polkadot/util': 10.1.10 + '@polkadot/util-crypto': 10.1.10 + '@polkadot/x-fetch': 10.1.10 + '@polkadot/x-global': 10.1.10 + '@polkadot/x-ws': 10.1.10 + '@substrate/connect': 0.7.14 + eventemitter3: 4.0.7 + mock-socket: 9.1.5 + nock: 13.2.9 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: false + + /@polkadot/rpc-provider/9.5.2: + resolution: {integrity: sha512-Sn2jfvAsvQcl35o0up8JR/XbDMS/3YVDEN2sFuzXtiD77W2njukItbZT+BolfAW+biAUs3bNomump5k/YLiLKg==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.4 + '@polkadot/keyring': 10.1.11 + '@polkadot/types': 9.5.2 + '@polkadot/types-support': 9.5.2 + '@polkadot/util': 10.1.11 + '@polkadot/util-crypto': 10.1.11 + '@polkadot/x-fetch': 10.1.11 + '@polkadot/x-global': 10.1.11 + '@polkadot/x-ws': 10.1.11 + '@substrate/connect': 0.7.14 eventemitter3: 4.0.7 mock-socket: 9.1.5 nock: 13.2.9 @@ -2217,7 +2392,7 @@ packages: resolution: {integrity: sha512-aqm7xT/66TCna0I2utpIekoquKo0K5pnkA/7WDzZ6gyD8he2h0IXfe8xWjVmuyhjxrT/C/7X1aUF2Z0xlOCwzQ==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/types': 7.15.1 '@polkadot/types-codec': 7.15.1 '@polkadot/util': 8.7.1 @@ -2227,27 +2402,37 @@ packages: resolution: {integrity: sha512-Xa4TUFqyZT+IJ6pBSwDjWcF42u/E34OyC+gbs5Z2vWQ4EzSDkq4xNoUKjJlEEgTemsD9lhPOIc4jvqTCefwxEw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/types': 8.14.1 '@polkadot/types-codec': 8.14.1 - '@polkadot/util': 10.1.6 + '@polkadot/util': 10.1.10 dev: false - /@polkadot/types-augment/9.3.3: - resolution: {integrity: sha512-XAhyX5DEYnsMunpoU1podjm5ODosTmMwwpNcUK95ALcyzkpstyWIjUW3JhaEOzIshsYmJUNxM7/cSI4jv/VLAg==} + /@polkadot/types-augment/9.4.3: + resolution: {integrity: sha512-TvN3vhUVylFyWGHHXOO4/iHIFW6EXHLBlIBC7YhUQc0dZOD+mKjnNblEtDY/GazlwBQjq9bhXcoH0S6KIpiSIg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/types': 9.3.3 - '@polkadot/types-codec': 9.3.3 - '@polkadot/util': 10.1.7 + '@babel/runtime': 7.19.0 + '@polkadot/types': 9.4.3 + '@polkadot/types-codec': 9.4.3 + '@polkadot/util': 10.1.10 + dev: false + + /@polkadot/types-augment/9.5.2: + resolution: {integrity: sha512-LDJdv/84sECwA0R5lK85/orxjoozJe3+2jeLjRiKr8S6qm9XRfz0wLCSF866kpSGBZ4B1dYBUhzjoSu95y2Jug==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.4 + '@polkadot/types': 9.5.2 + '@polkadot/types-codec': 9.5.2 + '@polkadot/util': 10.1.11 dev: false /@polkadot/types-codec/7.15.1: resolution: {integrity: sha512-nI11dT7FGaeDd/fKPD8iJRFGhosOJoyjhZ0gLFFDlKCaD3AcGBRTTY8HFJpP/5QXXhZzfZsD93fVKrosnegU0Q==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 8.7.1 dev: false @@ -2255,25 +2440,34 @@ packages: resolution: {integrity: sha512-y6YDN4HwvEgSWlgrEV04QBBxDxES1cTuUQFzZJzOTuZCWpA371Mdj3M9wYxGXMnj0wa+rCQGECHPZZaNxBMiKg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/util': 10.1.6 - '@polkadot/x-bigint': 10.1.2 + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.10 + '@polkadot/x-bigint': 10.1.10 dev: false - /@polkadot/types-codec/9.3.3: - resolution: {integrity: sha512-DiSGZ/pwZO0huS4CnyI0Z4nsvKSFUAjjcVQ7lt1BqCRcUFoIZtYQgzXftia1kSXnJs4J13PMcFTfQZeTDnp4Sg==} + /@polkadot/types-codec/9.4.3: + resolution: {integrity: sha512-x0BJZxcPyollDx9urF7rAfDdKHZXe150p9op2if8fw02LNTDGGsrWLw7DD8ISNwXbtL8L+N1ipc0mVqfsHg+Aw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/util': 10.1.7 - '@polkadot/x-bigint': 10.1.7 + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.10 + '@polkadot/x-bigint': 10.1.10 + dev: false + + /@polkadot/types-codec/9.5.2: + resolution: {integrity: sha512-FJPjE3ceTGTcadeC8d5C+aSR8SLKuQrXKIBmMNBky+WwzEo0vufRqxFWcPLxAOEeeUPgBXS967tP15+UU4psGA==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.4 + '@polkadot/util': 10.1.11 + '@polkadot/x-bigint': 10.1.11 dev: false /@polkadot/types-create/7.15.1: resolution: {integrity: sha512-+HiaHn7XOwP0kv/rVdORlVkNuMoxuvt+jd67A/CeEreJiXqRLu+S61Mdk7wi6719PTaOal1hTDFfyGrtUd8FSQ==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/types-codec': 7.15.1 '@polkadot/util': 8.7.1 dev: false @@ -2282,25 +2476,34 @@ packages: resolution: {integrity: sha512-fb9yyblj5AYAPzeCIq0kYSfzDxRDi/0ud9gN2UzB3H7M/O4n2mPC1vD4UOLF+B7l9QzCrt4e+k+/riGp7GfvyA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/types-codec': 8.14.1 - '@polkadot/util': 10.1.6 + '@polkadot/util': 10.1.10 dev: false - /@polkadot/types-create/9.3.3: - resolution: {integrity: sha512-LRS5sWYtPyXZ8AC7j9foFQQzYhay2q4YnXD9Hfz2ULrjtpjdUgR0hP3GpBKfxDnlWESpzGjegSAIDs+z/sKnfA==} + /@polkadot/types-create/9.4.3: + resolution: {integrity: sha512-kx5Yccp/I4RrtbOo3+iFJSVDwbl0Y9Xm0B4p7khYkKUHAbNuuFZMMnnMru2hOTWDgpQPN6Fbixt9pdy4TD6Xnw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/types-codec': 9.3.3 - '@polkadot/util': 10.1.7 + '@babel/runtime': 7.19.0 + '@polkadot/types-codec': 9.4.3 + '@polkadot/util': 10.1.10 + dev: false + + /@polkadot/types-create/9.5.2: + resolution: {integrity: sha512-YbplL8K0LqUEHoV3FgZ5B83oVV67KGbLXsWHVVaUZBPsmtXJXrbBfSyJgl/80I2n4lXEBmg3sFAYMbaSTvL05A==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.4 + '@polkadot/types-codec': 9.5.2 + '@polkadot/util': 10.1.11 dev: false /@polkadot/types-known/4.17.1: resolution: {integrity: sha512-YkOwGrO+k9aVrBR8FgYHnfJKhOfpdgC5ZRYNL/xJ9oa7lBYqPts9ENAxeBmJS/5IGeDF9f32MNyrCP2umeCXWg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/networks': 6.11.1 '@polkadot/types': 4.17.1 '@polkadot/util': 6.11.1 @@ -2310,7 +2513,7 @@ packages: resolution: {integrity: sha512-Z8bHpPQy+mqUm0uR1tai6ra0bQIoPmgRcGFYUM+rJtW1kx/6kZLh10HAICjLpPeA1cwLRzaxHRDqH5MCU6OgXw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/networks': 8.7.1 '@polkadot/types': 6.12.1 '@polkadot/util': 8.7.1 @@ -2320,7 +2523,7 @@ packages: resolution: {integrity: sha512-LMcNP0CxT84DqAKV62/qDeeIVIJCR5yzE9b+9AsYhyfhE4apwxjrThqZA7K0CF56bOdQJSexAerYB/jwk2IijA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/networks': 8.7.1 '@polkadot/types': 7.15.1 '@polkadot/types-codec': 7.15.1 @@ -2332,31 +2535,43 @@ packages: resolution: {integrity: sha512-GP7gRo9nmitykkrRnoLF61Qm19UFdTwMsOnJkdm7AOeWDmZGxutacgO6k1tBsHr38hsiCCGsB/JiseUgywvGIw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/networks': 10.1.2 '@polkadot/types': 8.14.1 '@polkadot/types-codec': 8.14.1 '@polkadot/types-create': 8.14.1 - '@polkadot/util': 10.1.6 + '@polkadot/util': 10.1.10 dev: false - /@polkadot/types-known/9.3.3: - resolution: {integrity: sha512-TcDGzHpPZdMxrywLHTbjaHaFRdJdFaL5QGpvcSeDwAGHz7zU6Aq29AT9HwJ8GrBNihLALUj79S1/D2WfmJuXFA==} + /@polkadot/types-known/9.4.3: + resolution: {integrity: sha512-JoIC31If1tLhz4ykNCcJCJGEuufJo7c880vCDLzdYn/OCxxHvdrUeNAFZu0ua/QNHNpT7Pl24NGUrE2QfmZbRg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/networks': 10.1.7 - '@polkadot/types': 9.3.3 - '@polkadot/types-codec': 9.3.3 - '@polkadot/types-create': 9.3.3 - '@polkadot/util': 10.1.7 + '@babel/runtime': 7.19.0 + '@polkadot/networks': 10.1.10 + '@polkadot/types': 9.4.3 + '@polkadot/types-codec': 9.4.3 + '@polkadot/types-create': 9.4.3 + '@polkadot/util': 10.1.10 + dev: false + + /@polkadot/types-known/9.5.2: + resolution: {integrity: sha512-iNaGOF6dGiTvy3Ns8Z7WNjYD1SGnZiapDAKPH4brPuJqMpN6/FxYpfPSSOKx+IJEamsdINcaggb87eWyPxH8CA==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.4 + '@polkadot/networks': 10.1.11 + '@polkadot/types': 9.5.2 + '@polkadot/types-codec': 9.5.2 + '@polkadot/types-create': 9.5.2 + '@polkadot/util': 10.1.11 dev: false /@polkadot/types-support/7.15.1: resolution: {integrity: sha512-FIK251ffVo+NaUXLlaJeB5OvT7idDd3uxaoBM6IwsS87rzt2CcWMyCbu0uX89AHZUhSviVx7xaBxfkGEqMePWA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 8.7.1 dev: false @@ -2364,23 +2579,31 @@ packages: resolution: {integrity: sha512-XqR4qq6pCZyNBuFVod8nFSNUmLssrjoU9bOIn4Ua2cqNlI9xsuKaI1X5ySEn/oWOtKQ2L5hbCm9vkXrEtXBl1w==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/util': 10.1.6 + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.10 dev: false - /@polkadot/types-support/9.3.3: - resolution: {integrity: sha512-KJeL3bBc8XEIDuUFjYLBunAvMkVi8LXdln4V1FPHEt6OgXkbqJlc9KAwgrPUaV1+Ki0LIBDDYKtUiMG3c9Ip+g==} + /@polkadot/types-support/9.4.3: + resolution: {integrity: sha512-PCIHVj40A5qgUQJHOM4BpeVwXPVNo0PNeVVWMPPLdnUMr3hX8dqCjZnWAUizgTICJ5EutCLL5wKP6/JBZmmWsA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/util': 10.1.7 + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.10 + dev: false + + /@polkadot/types-support/9.5.2: + resolution: {integrity: sha512-Zdbl5fvGQjUkyE1r67vhyPEqLUwlZ35GCnkoobY9MgN6gylhSjNue/shpG4uGsEjWVQL7GkFkrPiwtzDArVilg==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.4 + '@polkadot/util': 10.1.11 dev: false /@polkadot/types/4.17.1: resolution: {integrity: sha512-rjW4OFdwvFekzN3ATLibC2JPSd8AWt5YepJhmuCPdwH26r3zB8bEC6dM7YQExLVUmygVPvgXk5ffHI6RAdXBMg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/metadata': 4.17.1 '@polkadot/util': 6.11.1 '@polkadot/util-crypto': 6.11.1 @@ -2391,84 +2614,115 @@ packages: resolution: {integrity: sha512-O37cAGUL0xiXTuO3ySweVh0OuFUD6asrd0TfuzGsEp3jAISWdElEHV5QDiftWq8J9Vf8BMgTcP2QLFbmSusxqA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/types-known': 6.12.1 '@polkadot/util': 8.7.1 '@polkadot/util-crypto': 8.7.1 - rxjs: 7.5.6 + rxjs: 7.5.7 dev: false /@polkadot/types/7.15.1: resolution: {integrity: sha512-KawZVS+eLR1D6O7c/P5cSUwr6biM9Qd2KwKtJIO8l1Mrxp7r+y2tQnXSSXVAd6XPdb3wVMhnIID+NW3W99TAnQ==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/keyring': 8.7.1 '@polkadot/types-augment': 7.15.1 '@polkadot/types-codec': 7.15.1 '@polkadot/types-create': 7.15.1 '@polkadot/util': 8.7.1 '@polkadot/util-crypto': 8.7.1 - rxjs: 7.5.6 + rxjs: 7.5.7 dev: false /@polkadot/types/8.14.1: resolution: {integrity: sha512-Xza16ejKrSd4XhTOlbfISyxZ2sRmbMAZk5pX7VEMHVZHqV98o+bJ2f9Kk7F8YJijkHHGosCLDestP9R5nLoOoA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/keyring': 10.1.2 '@polkadot/types-augment': 8.14.1 '@polkadot/types-codec': 8.14.1 '@polkadot/types-create': 8.14.1 - '@polkadot/util': 10.1.6 - '@polkadot/util-crypto': 10.1.2 - rxjs: 7.5.6 + '@polkadot/util': 10.1.10 + '@polkadot/util-crypto': 10.1.10 + rxjs: 7.5.7 dev: false - /@polkadot/types/9.3.3: - resolution: {integrity: sha512-By7VC9erdsJCDR9DNtgSuWSrKeLpJ7tnStS8Ii31LW1ueYDWCx1CO28fogq4UYf53pMbhNCWDGPFk1ZZn8ZchA==} + /@polkadot/types/9.4.3: + resolution: {integrity: sha512-SXHih0+TajRAZAl+uuFPpy/TxySX8oYvYg67FwRclqNsHc1Qwj5JFs0HJtuf60UkvPGqbQpNek5ND6O1VBHHQA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/keyring': 10.1.7 - '@polkadot/types-augment': 9.3.3 - '@polkadot/types-codec': 9.3.3 - '@polkadot/types-create': 9.3.3 - '@polkadot/util': 10.1.7 - '@polkadot/util-crypto': 10.1.7 - rxjs: 7.5.6 + '@babel/runtime': 7.19.0 + '@polkadot/keyring': 10.1.10 + '@polkadot/types-augment': 9.4.3 + '@polkadot/types-codec': 9.4.3 + '@polkadot/types-create': 9.4.3 + '@polkadot/util': 10.1.10 + '@polkadot/util-crypto': 10.1.10 + rxjs: 7.5.7 dev: false - /@polkadot/util-crypto/10.1.2: - resolution: {integrity: sha512-lSgxSLF/XkksL8St3kyw8SCLic0JvyIf8uOezQZYyjSJKT3Gl8gGu9wCAKNAmboU0FgO8cnLO9AcAEkhCHvnyw==} + /@polkadot/types/9.5.2: + resolution: {integrity: sha512-6C5xzOrMK+fu0JMOlSO+8dPDhpwKPOaKMv3v5BMvBEWtDNKM81/QQoAoYT7DSVXq/V16icSFxPs9IWC+6Qq5ag==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@noble/hashes': 1.1.2 - '@noble/secp256k1': 1.6.3 - '@polkadot/networks': 10.1.2 - '@polkadot/util': 10.1.2 - '@polkadot/wasm-crypto': 6.3.1_h5wsx5l4wlp2h2idvasjrnjqhm - '@polkadot/x-bigint': 10.1.2 - '@polkadot/x-randomvalues': 10.1.2 + '@babel/runtime': 7.19.4 + '@polkadot/keyring': 10.1.11 + '@polkadot/types-augment': 9.5.2 + '@polkadot/types-codec': 9.5.2 + '@polkadot/types-create': 9.5.2 + '@polkadot/util': 10.1.11 + '@polkadot/util-crypto': 10.1.11 + rxjs: 7.5.7 + dev: false + + /@polkadot/util-crypto/10.1.10: + resolution: {integrity: sha512-w9h/wf4wZXeUkRnihhnfqlaKuoQtrjkjK3C5liCQkr9vx5zOsmg/nMSDP8UUFJX0msPPYpFeNvzn7oDIs6qSZA==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.0 + '@noble/hashes': 1.1.3 + '@noble/secp256k1': 1.7.0 + '@polkadot/networks': 10.1.10 + '@polkadot/util': 10.1.10 + '@polkadot/wasm-crypto': 6.3.1_xnbzfk7hwbn2cwqh2nrvbgvkzq + '@polkadot/x-bigint': 10.1.10 + '@polkadot/x-randomvalues': 10.1.10 '@scure/base': 1.1.1 ed2curve: 0.3.0 tweetnacl: 1.0.3 dev: false - /@polkadot/util-crypto/10.1.7: - resolution: {integrity: sha512-zGmSU7a0wdWfpDtfc+Q7fUuW+extu9o1Uh4JpkuwwZ/dxmyW5xlfqVsIScM1pdPyjJsyamX8KwsKiVsW4slasg==} + /@polkadot/util-crypto/10.1.11: + resolution: {integrity: sha512-wG63frIMAR5T/HXGM0SFNzZZdk7qDBsfLXfn6PIZiXCCCsdEYPzS5WltB7fkhicYpbePJ7VgdCAddj1l4IcGyg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.4 + '@noble/hashes': 1.1.3 + '@noble/secp256k1': 1.7.0 + '@polkadot/networks': 10.1.11 + '@polkadot/util': 10.1.11 + '@polkadot/wasm-crypto': 6.3.1_kq5krb3p4bzvrcxi3xa2lgyh6u + '@polkadot/x-bigint': 10.1.11 + '@polkadot/x-randomvalues': 10.1.11 + '@scure/base': 1.1.1 + ed2curve: 0.3.0 + tweetnacl: 1.0.3 + dev: false + + /@polkadot/util-crypto/10.1.2: + resolution: {integrity: sha512-lSgxSLF/XkksL8St3kyw8SCLic0JvyIf8uOezQZYyjSJKT3Gl8gGu9wCAKNAmboU0FgO8cnLO9AcAEkhCHvnyw==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.0 '@noble/hashes': 1.1.2 '@noble/secp256k1': 1.6.3 - '@polkadot/networks': 10.1.7 - '@polkadot/util': 10.1.7 - '@polkadot/wasm-crypto': 6.3.1_iavvhndpjoeut6ernjqjjplteq - '@polkadot/x-bigint': 10.1.7 - '@polkadot/x-randomvalues': 10.1.7 + '@polkadot/networks': 10.1.2 + '@polkadot/util': 10.1.2 + '@polkadot/wasm-crypto': 6.3.1_h5wsx5l4wlp2h2idvasjrnjqhm + '@polkadot/x-bigint': 10.1.2 + '@polkadot/x-randomvalues': 10.1.2 '@scure/base': 1.1.1 ed2curve: 0.3.0 tweetnacl: 1.0.3 @@ -2478,7 +2732,7 @@ packages: resolution: {integrity: sha512-fWA1Nz17FxWJslweZS4l0Uo30WXb5mYV1KEACVzM+BSZAvG5eoiOAYX6VYZjyw6/7u53XKrWQlD83iPsg3KvZw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/networks': 6.11.1 '@polkadot/util': 6.11.1 '@polkadot/wasm-crypto': 4.6.1_7agzzbeuhezrwkh2zmxh2lt2xi @@ -2500,7 +2754,7 @@ packages: resolution: {integrity: sha512-nNwqUwP44eCH9jKKcPie+IHLKkg9LMe6H7hXo91hy3AtoslnNrT51tP3uAm5yllhLvswJfnAgnlHq7ybCgqeFw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/networks': 7.9.2 '@polkadot/util': 7.9.2 '@polkadot/wasm-crypto': 4.6.1_dqtjokeiluc5zkdxxwbtwmatza @@ -2522,7 +2776,7 @@ packages: resolution: {integrity: sha512-TaSuJ2aNrB5sYK7YXszkEv24nYJKRFqjF2OrggoMg6uYxUAECvTkldFnhtgeizMweRMxJIBu6bMHlSIutbWgjw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@noble/hashes': 1.0.0 '@noble/secp256k1': 1.5.5 '@polkadot/networks': 8.7.1 @@ -2539,7 +2793,7 @@ packages: resolution: {integrity: sha512-tfz6mJtPwoNteivKCmR+QklC4mr1/hGZRsDJLWKaFhanDinYZ3V2pJM1EbCI6WONLuuzlTxsDXjAffWzzRqlPA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@noble/hashes': 1.1.2 '@noble/secp256k1': 1.6.0 '@polkadot/networks': 9.7.2 @@ -2565,6 +2819,32 @@ packages: bn.js: 5.2.1 dev: false + /@polkadot/util/10.1.10: + resolution: {integrity: sha512-BQoTfSxZ3BWAgWDjgKBVdyw1AJGaoOeAidCA+LZcHV6wlMu5643AZPUnoMrW413MbbpxsIhJXtNttqOwjo8MjA==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.0 + '@polkadot/x-bigint': 10.1.10 + '@polkadot/x-global': 10.1.10 + '@polkadot/x-textdecoder': 10.1.10 + '@polkadot/x-textencoder': 10.1.10 + '@types/bn.js': 5.1.1 + bn.js: 5.2.1 + dev: false + + /@polkadot/util/10.1.11: + resolution: {integrity: sha512-6m51lw6g6ilqO/k4BQY7rD0lYM9NCnC4FiM7CEEUc7j8q86qxdcZ88zdNldkhNsTIQnfmCtkK3GRzZW6VYrbUw==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.4 + '@polkadot/x-bigint': 10.1.11 + '@polkadot/x-global': 10.1.11 + '@polkadot/x-textdecoder': 10.1.11 + '@polkadot/x-textencoder': 10.1.11 + '@types/bn.js': 5.1.1 + bn.js: 5.2.1 + dev: false + /@polkadot/util/10.1.2: resolution: {integrity: sha512-gYSpJyrrw5gZWgTVu6PJ1PBUzi3GqwmaK6XRgi4deHmQRn9TEXTToGtHmleJWnaTCRW8Vvh5B5RNNV2C/+va4w==} engines: {node: '>=14.0.0'} @@ -2582,7 +2862,7 @@ packages: resolution: {integrity: sha512-k+gCKmgwxp0smmLIR7SfiEYEToayWXjrC7pQ0PqAGxpBNOdVMSCzLMnOHf9AI5cjs/lx6ULr1fHn721wLVonkw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-bigint': 10.1.6 '@polkadot/x-global': 10.1.6 '@polkadot/x-textdecoder': 10.1.6 @@ -2591,24 +2871,11 @@ packages: bn.js: 5.2.1 dev: false - /@polkadot/util/10.1.7: - resolution: {integrity: sha512-s7gDLdNb4HUpoe3faXwoO6HwiUp8pi66voYKiUYRh1kEtW1o9vGBgyZPHPGC/FBgILzTJKii/9XxnSex60zBTA==} - engines: {node: '>=14.0.0'} - dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/x-bigint': 10.1.7 - '@polkadot/x-global': 10.1.7 - '@polkadot/x-textdecoder': 10.1.7 - '@polkadot/x-textencoder': 10.1.7 - '@types/bn.js': 5.1.1 - bn.js: 5.2.1 - dev: false - /@polkadot/util/6.11.1: resolution: {integrity: sha512-TEdCetr9rsdUfJZqQgX/vxLuV4XU8KMoKBMJdx+JuQ5EWemIdQkEtMBdL8k8udNGbgSNiYFA6rPppATeIxAScg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-textdecoder': 6.11.1 '@polkadot/x-textencoder': 6.11.1 '@types/bn.js': 4.11.6 @@ -2621,7 +2888,7 @@ packages: resolution: {integrity: sha512-6ABY6ErgkCsM4C6+X+AJSY4pBGwbKlHZmUtHftaiTvbaj4XuA4nTo3GU28jw8wY0Jh2cJZJvt6/BJ5GVkm5tBA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-textdecoder': 7.9.2 '@polkadot/x-textencoder': 7.9.2 '@types/bn.js': 4.11.6 @@ -2634,12 +2901,12 @@ packages: resolution: {integrity: sha512-XjY1bTo7V6OvOCe4yn8H2vifeuBciCy0gq0k5P1tlGUQLI/Yt0hvDmxcA0FEPtqg8CL+rYRG7WXGPVNjkrNvyQ==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-bigint': 8.7.1 '@polkadot/x-global': 8.7.1 '@polkadot/x-textdecoder': 8.7.1 '@polkadot/x-textencoder': 8.7.1 - '@types/bn.js': 5.1.0 + '@types/bn.js': 5.1.1 bn.js: 5.2.1 ip-regex: 4.3.0 dev: false @@ -2648,12 +2915,12 @@ packages: resolution: {integrity: sha512-ivTmA+KkPCq5i3O0Gk+dTds/hwdwlYCh89aKfeaG9ni3XHUbbuBgTqHneo648HqxwAwSAyiDiwE9EdXrzAdO4Q==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-bigint': 9.7.2 '@polkadot/x-global': 9.7.2 '@polkadot/x-textdecoder': 9.7.2 '@polkadot/x-textencoder': 9.7.2 - '@types/bn.js': 5.1.0 + '@types/bn.js': 5.1.1 bn.js: 5.2.1 ip-regex: 4.3.0 dev: false @@ -2665,7 +2932,7 @@ packages: '@polkadot/util': '*' '@polkadot/x-randomvalues': '*' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 9.7.2 '@polkadot/x-randomvalues': 9.7.2 dev: false @@ -2677,21 +2944,33 @@ packages: '@polkadot/util': '*' '@polkadot/x-randomvalues': '*' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 10.1.2 '@polkadot/x-randomvalues': 10.1.2 dev: false - /@polkadot/wasm-bridge/6.3.1_iavvhndpjoeut6ernjqjjplteq: + /@polkadot/wasm-bridge/6.3.1_kq5krb3p4bzvrcxi3xa2lgyh6u: resolution: {integrity: sha512-1TYkHsb9AEFhU9uZj3biEnN2yKQNzdrwSjiTvfCYnt97pnEkKsZI6cku+YPZQv5w/x9CQa5Yua9e2DVVZSivGA==} engines: {node: '>=14.0.0'} peerDependencies: '@polkadot/util': '*' '@polkadot/x-randomvalues': '*' dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/util': 10.1.7 - '@polkadot/x-randomvalues': 10.1.7 + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.11 + '@polkadot/x-randomvalues': 10.1.11 + dev: false + + /@polkadot/wasm-bridge/6.3.1_xnbzfk7hwbn2cwqh2nrvbgvkzq: + resolution: {integrity: sha512-1TYkHsb9AEFhU9uZj3biEnN2yKQNzdrwSjiTvfCYnt97pnEkKsZI6cku+YPZQv5w/x9CQa5Yua9e2DVVZSivGA==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@polkadot/util': '*' + '@polkadot/x-randomvalues': '*' + dependencies: + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.10 + '@polkadot/x-randomvalues': 10.1.10 dev: false /@polkadot/wasm-crypto-asmjs/4.6.1_@polkadot+util@6.11.1: @@ -2700,7 +2979,7 @@ packages: peerDependencies: '@polkadot/util': '*' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 6.11.1 dev: false @@ -2710,7 +2989,7 @@ packages: peerDependencies: '@polkadot/util': '*' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 7.9.2 dev: false @@ -2720,28 +2999,38 @@ packages: peerDependencies: '@polkadot/util': '*' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 8.7.1 dev: false - /@polkadot/wasm-crypto-asmjs/6.3.1_@polkadot+util@10.1.2: + /@polkadot/wasm-crypto-asmjs/6.3.1_@polkadot+util@10.1.10: resolution: {integrity: sha512-zbombRfA5v/mUWQQhgg2YwaxhRmxRIrvskw65x+lruax3b6xPBFDs7yplopiJU3r8h2pTgQvX/DUksvqz2TCRQ==} engines: {node: '>=14.0.0'} peerDependencies: '@polkadot/util': '*' dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/util': 10.1.2 + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.10 dev: false - /@polkadot/wasm-crypto-asmjs/6.3.1_@polkadot+util@10.1.7: + /@polkadot/wasm-crypto-asmjs/6.3.1_@polkadot+util@10.1.11: resolution: {integrity: sha512-zbombRfA5v/mUWQQhgg2YwaxhRmxRIrvskw65x+lruax3b6xPBFDs7yplopiJU3r8h2pTgQvX/DUksvqz2TCRQ==} engines: {node: '>=14.0.0'} peerDependencies: '@polkadot/util': '*' dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/util': 10.1.7 + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.11 + dev: false + + /@polkadot/wasm-crypto-asmjs/6.3.1_@polkadot+util@10.1.2: + resolution: {integrity: sha512-zbombRfA5v/mUWQQhgg2YwaxhRmxRIrvskw65x+lruax3b6xPBFDs7yplopiJU3r8h2pTgQvX/DUksvqz2TCRQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@polkadot/util': '*' + dependencies: + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.2 dev: false /@polkadot/wasm-crypto-asmjs/6.3.1_@polkadot+util@9.7.2: @@ -2750,7 +3039,7 @@ packages: peerDependencies: '@polkadot/util': '*' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 9.7.2 dev: false @@ -2761,7 +3050,7 @@ packages: '@polkadot/util': '*' '@polkadot/x-randomvalues': '*' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 9.7.2 '@polkadot/wasm-bridge': 6.3.1_bqbpofxh4fwo2uvuz4bljqm3ua '@polkadot/wasm-crypto-asmjs': 6.3.1_@polkadot+util@9.7.2 @@ -2776,7 +3065,7 @@ packages: '@polkadot/util': '*' '@polkadot/x-randomvalues': '*' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 10.1.2 '@polkadot/wasm-bridge': 6.3.1_h5wsx5l4wlp2h2idvasjrnjqhm '@polkadot/wasm-crypto-asmjs': 6.3.1_@polkadot+util@10.1.2 @@ -2784,19 +3073,34 @@ packages: '@polkadot/x-randomvalues': 10.1.2 dev: false - /@polkadot/wasm-crypto-init/6.3.1_iavvhndpjoeut6ernjqjjplteq: + /@polkadot/wasm-crypto-init/6.3.1_kq5krb3p4bzvrcxi3xa2lgyh6u: resolution: {integrity: sha512-9yaUBcu+snwjJLmPPGl3cyGRQ1afyFGm16qzTM0sgG/ZCfUlK4uk8KWZe+sBUKgoxb2oXY7Y4WklKgQI1YBdfw==} engines: {node: '>=14.0.0'} peerDependencies: '@polkadot/util': '*' '@polkadot/x-randomvalues': '*' dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/util': 10.1.7 - '@polkadot/wasm-bridge': 6.3.1_iavvhndpjoeut6ernjqjjplteq - '@polkadot/wasm-crypto-asmjs': 6.3.1_@polkadot+util@10.1.7 - '@polkadot/wasm-crypto-wasm': 6.3.1_@polkadot+util@10.1.7 - '@polkadot/x-randomvalues': 10.1.7 + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.11 + '@polkadot/wasm-bridge': 6.3.1_kq5krb3p4bzvrcxi3xa2lgyh6u + '@polkadot/wasm-crypto-asmjs': 6.3.1_@polkadot+util@10.1.11 + '@polkadot/wasm-crypto-wasm': 6.3.1_@polkadot+util@10.1.11 + '@polkadot/x-randomvalues': 10.1.11 + dev: false + + /@polkadot/wasm-crypto-init/6.3.1_xnbzfk7hwbn2cwqh2nrvbgvkzq: + resolution: {integrity: sha512-9yaUBcu+snwjJLmPPGl3cyGRQ1afyFGm16qzTM0sgG/ZCfUlK4uk8KWZe+sBUKgoxb2oXY7Y4WklKgQI1YBdfw==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@polkadot/util': '*' + '@polkadot/x-randomvalues': '*' + dependencies: + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.10 + '@polkadot/wasm-bridge': 6.3.1_xnbzfk7hwbn2cwqh2nrvbgvkzq + '@polkadot/wasm-crypto-asmjs': 6.3.1_@polkadot+util@10.1.10 + '@polkadot/wasm-crypto-wasm': 6.3.1_@polkadot+util@10.1.10 + '@polkadot/x-randomvalues': 10.1.10 dev: false /@polkadot/wasm-crypto-wasm/4.6.1_@polkadot+util@6.11.1: @@ -2805,7 +3109,7 @@ packages: peerDependencies: '@polkadot/util': '*' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 6.11.1 dev: false @@ -2815,7 +3119,7 @@ packages: peerDependencies: '@polkadot/util': '*' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 7.9.2 dev: false @@ -2825,30 +3129,41 @@ packages: peerDependencies: '@polkadot/util': '*' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 8.7.1 dev: false - /@polkadot/wasm-crypto-wasm/6.3.1_@polkadot+util@10.1.2: + /@polkadot/wasm-crypto-wasm/6.3.1_@polkadot+util@10.1.10: resolution: {integrity: sha512-idSlzKGVzCfeCMRHsacRvqwojSaTadFxL/Dbls4z1thvfa3U9Ku0d2qVtlwg7Hj+tYWDiuP8Kygs+6bQwfs0XA==} engines: {node: '>=14.0.0'} peerDependencies: '@polkadot/util': '*' dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/util': 10.1.2 - '@polkadot/wasm-util': 6.3.1_@polkadot+util@10.1.2 + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.10 + '@polkadot/wasm-util': 6.3.1_@polkadot+util@10.1.10 dev: false - /@polkadot/wasm-crypto-wasm/6.3.1_@polkadot+util@10.1.7: + /@polkadot/wasm-crypto-wasm/6.3.1_@polkadot+util@10.1.11: resolution: {integrity: sha512-idSlzKGVzCfeCMRHsacRvqwojSaTadFxL/Dbls4z1thvfa3U9Ku0d2qVtlwg7Hj+tYWDiuP8Kygs+6bQwfs0XA==} engines: {node: '>=14.0.0'} peerDependencies: '@polkadot/util': '*' dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/util': 10.1.7 - '@polkadot/wasm-util': 6.3.1_@polkadot+util@10.1.7 + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.11 + '@polkadot/wasm-util': 6.3.1_@polkadot+util@10.1.11 + dev: false + + /@polkadot/wasm-crypto-wasm/6.3.1_@polkadot+util@10.1.2: + resolution: {integrity: sha512-idSlzKGVzCfeCMRHsacRvqwojSaTadFxL/Dbls4z1thvfa3U9Ku0d2qVtlwg7Hj+tYWDiuP8Kygs+6bQwfs0XA==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@polkadot/util': '*' + dependencies: + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.2 + '@polkadot/wasm-util': 6.3.1_@polkadot+util@10.1.2 dev: false /@polkadot/wasm-crypto-wasm/6.3.1_@polkadot+util@9.7.2: @@ -2857,7 +3172,7 @@ packages: peerDependencies: '@polkadot/util': '*' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 9.7.2 '@polkadot/wasm-util': 6.3.1_@polkadot+util@9.7.2 dev: false @@ -2869,7 +3184,7 @@ packages: '@polkadot/util': '*' '@polkadot/x-randomvalues': '*' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 6.11.1 '@polkadot/wasm-crypto-asmjs': 4.6.1_@polkadot+util@6.11.1 '@polkadot/wasm-crypto-wasm': 4.6.1_@polkadot+util@6.11.1 @@ -2883,7 +3198,7 @@ packages: '@polkadot/util': '*' '@polkadot/x-randomvalues': '*' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 7.9.2 '@polkadot/wasm-crypto-asmjs': 4.6.1_@polkadot+util@7.9.2 '@polkadot/wasm-crypto-wasm': 4.6.1_@polkadot+util@7.9.2 @@ -2897,7 +3212,7 @@ packages: '@polkadot/util': '*' '@polkadot/x-randomvalues': '*' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 8.7.1 '@polkadot/wasm-crypto-asmjs': 5.1.1_@polkadot+util@8.7.1 '@polkadot/wasm-crypto-wasm': 5.1.1_@polkadot+util@8.7.1 @@ -2911,7 +3226,7 @@ packages: '@polkadot/util': '*' '@polkadot/x-randomvalues': '*' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 9.7.2 '@polkadot/wasm-bridge': 6.3.1_bqbpofxh4fwo2uvuz4bljqm3ua '@polkadot/wasm-crypto-asmjs': 6.3.1_@polkadot+util@9.7.2 @@ -2928,7 +3243,7 @@ packages: '@polkadot/util': '*' '@polkadot/x-randomvalues': '*' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 10.1.2 '@polkadot/wasm-bridge': 6.3.1_h5wsx5l4wlp2h2idvasjrnjqhm '@polkadot/wasm-crypto-asmjs': 6.3.1_@polkadot+util@10.1.2 @@ -2938,41 +3253,68 @@ packages: '@polkadot/x-randomvalues': 10.1.2 dev: false - /@polkadot/wasm-crypto/6.3.1_iavvhndpjoeut6ernjqjjplteq: + /@polkadot/wasm-crypto/6.3.1_kq5krb3p4bzvrcxi3xa2lgyh6u: resolution: {integrity: sha512-OO8h0qeVkqp4xYZaRVl4iuWOEtq282pNBHDKb6SOJuI2g59eWGcKh4EQU9Me2VP6qzojIqptrkrVt7KQXC68gA==} engines: {node: '>=14.0.0'} peerDependencies: '@polkadot/util': '*' '@polkadot/x-randomvalues': '*' dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/util': 10.1.7 - '@polkadot/wasm-bridge': 6.3.1_iavvhndpjoeut6ernjqjjplteq - '@polkadot/wasm-crypto-asmjs': 6.3.1_@polkadot+util@10.1.7 - '@polkadot/wasm-crypto-init': 6.3.1_iavvhndpjoeut6ernjqjjplteq - '@polkadot/wasm-crypto-wasm': 6.3.1_@polkadot+util@10.1.7 - '@polkadot/wasm-util': 6.3.1_@polkadot+util@10.1.7 - '@polkadot/x-randomvalues': 10.1.7 + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.11 + '@polkadot/wasm-bridge': 6.3.1_kq5krb3p4bzvrcxi3xa2lgyh6u + '@polkadot/wasm-crypto-asmjs': 6.3.1_@polkadot+util@10.1.11 + '@polkadot/wasm-crypto-init': 6.3.1_kq5krb3p4bzvrcxi3xa2lgyh6u + '@polkadot/wasm-crypto-wasm': 6.3.1_@polkadot+util@10.1.11 + '@polkadot/wasm-util': 6.3.1_@polkadot+util@10.1.11 + '@polkadot/x-randomvalues': 10.1.11 dev: false - /@polkadot/wasm-util/6.3.1_@polkadot+util@10.1.2: + /@polkadot/wasm-crypto/6.3.1_xnbzfk7hwbn2cwqh2nrvbgvkzq: + resolution: {integrity: sha512-OO8h0qeVkqp4xYZaRVl4iuWOEtq282pNBHDKb6SOJuI2g59eWGcKh4EQU9Me2VP6qzojIqptrkrVt7KQXC68gA==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@polkadot/util': '*' + '@polkadot/x-randomvalues': '*' + dependencies: + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.10 + '@polkadot/wasm-bridge': 6.3.1_xnbzfk7hwbn2cwqh2nrvbgvkzq + '@polkadot/wasm-crypto-asmjs': 6.3.1_@polkadot+util@10.1.10 + '@polkadot/wasm-crypto-init': 6.3.1_xnbzfk7hwbn2cwqh2nrvbgvkzq + '@polkadot/wasm-crypto-wasm': 6.3.1_@polkadot+util@10.1.10 + '@polkadot/wasm-util': 6.3.1_@polkadot+util@10.1.10 + '@polkadot/x-randomvalues': 10.1.10 + dev: false + + /@polkadot/wasm-util/6.3.1_@polkadot+util@10.1.10: resolution: {integrity: sha512-12oAv5J7Yoc9m6jixrSaQCxpOkWOyzHx3DMC8qmLjRiwdBWxqLmImOVRVnFsbaxqSbhBIHRuJphVxWE+GZETDg==} engines: {node: '>=14.0.0'} peerDependencies: '@polkadot/util': '*' dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/util': 10.1.2 + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.10 dev: false - /@polkadot/wasm-util/6.3.1_@polkadot+util@10.1.7: + /@polkadot/wasm-util/6.3.1_@polkadot+util@10.1.11: resolution: {integrity: sha512-12oAv5J7Yoc9m6jixrSaQCxpOkWOyzHx3DMC8qmLjRiwdBWxqLmImOVRVnFsbaxqSbhBIHRuJphVxWE+GZETDg==} engines: {node: '>=14.0.0'} peerDependencies: '@polkadot/util': '*' dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/util': 10.1.7 + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.11 + dev: false + + /@polkadot/wasm-util/6.3.1_@polkadot+util@10.1.2: + resolution: {integrity: sha512-12oAv5J7Yoc9m6jixrSaQCxpOkWOyzHx3DMC8qmLjRiwdBWxqLmImOVRVnFsbaxqSbhBIHRuJphVxWE+GZETDg==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@polkadot/util': '*' + dependencies: + '@babel/runtime': 7.19.0 + '@polkadot/util': 10.1.2 dev: false /@polkadot/wasm-util/6.3.1_@polkadot+util@9.7.2: @@ -2981,7 +3323,7 @@ packages: peerDependencies: '@polkadot/util': '*' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/util': 9.7.2 dev: false @@ -2993,6 +3335,22 @@ packages: '@polkadot/x-global': 10.1.1 dev: false + /@polkadot/x-bigint/10.1.10: + resolution: {integrity: sha512-4Jt0BO0WTby6r9A2DgkDxf/LFaICQHvSl1VSFtBf0Z0GV2n4OxkBX5x/1bdEdGEvYT5rM7RbR3xI7EL+W1ixHA==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.0 + '@polkadot/x-global': 10.1.10 + dev: false + + /@polkadot/x-bigint/10.1.11: + resolution: {integrity: sha512-TC4KZ+ni/SJhcf/LIwD49C/kwvACu0nCchETNO+sAfJ7COXZwHDUJXVXmwN5PgkQxwsWsKKuJmzR/Fi1bgMWnQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.4 + '@polkadot/x-global': 10.1.11 + dev: false + /@polkadot/x-bigint/10.1.2: resolution: {integrity: sha512-TCwv3NjQdfLb7CBYR8EA5t0CrMfYx3IF4hKjctuplL+mDNI0VzNn4qVKW62AjouI8kMbn7VyBPfoBeuYX8Ixrw==} engines: {node: '>=14.0.0'} @@ -3005,23 +3363,15 @@ packages: resolution: {integrity: sha512-yeBZQ9+u49KqDBaeSw+ytshqzyaScKrDjAxpWCfOGxJaB+5Nv1W7fqi3OJ4S/HN5DYItr0a6UC14e1hiZUtZCg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 10.1.6 dev: false - /@polkadot/x-bigint/10.1.7: - resolution: {integrity: sha512-uaClHpI6cnDumIfejUKvNTkB43JleEb0V6OIufDKJ/e1aCLE3f/Ws9ggwL8ea05lQP5k5xqOzbPdizi/UvrgKQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/x-global': 10.1.7 - dev: false - /@polkadot/x-bigint/8.7.1: resolution: {integrity: sha512-ClkhgdB/KqcAKk3zA6Qw8wBL6Wz67pYTPkrAtImpvoPJmR+l4RARauv+MH34JXMUNlNb3aUwqN6lq2Z1zN+mJg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 8.7.1 dev: false @@ -3029,26 +3379,36 @@ packages: resolution: {integrity: sha512-qi8/DTGypFSt5vvNOsYcEaqH72lymfyidGlsHlZ6e7nNASnEhk/NaOcINiTr1ds+fpu4dtKXWAIPZufujf2JeQ==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 9.7.2 dev: false - /@polkadot/x-fetch/10.1.2: - resolution: {integrity: sha512-Zd7npq9H/kDaehiM2iyPX1+cSfuhCvqDxuS8GLTjARIVGGURBfA+NjRM6o6jsXa3HCtv+lB67Qdw1m/PSxfIpQ==} + /@polkadot/x-fetch/10.1.10: + resolution: {integrity: sha512-LvTxAN6GaJzfgZ74WFYPZrIkMEThpX5u7O4ILiExcJt87E19cSWlYSHDa5n+OLjUpq0lBV2ueF90iUblt6aHpg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/x-global': 10.1.2 + '@babel/runtime': 7.19.0 + '@polkadot/x-global': 10.1.10 '@types/node-fetch': 2.6.2 node-fetch: 3.2.10 dev: false - /@polkadot/x-fetch/10.1.7: - resolution: {integrity: sha512-NL+xrlqUoCLwCIAvQLwOA189gSUgeSGOFjCmZ9uMkBqf35KXeZoHWse6YaoseTSlnAal3dQOGbXnYWZ4Ck2OSA==} + /@polkadot/x-fetch/10.1.11: + resolution: {integrity: sha512-WtyUr9itVD9BLnxCUloJ1iwrXOY/lnlEShEYKHcSm6MIHtbJolePd3v1+o5mOX+bdDbHXhPZnH8anCCqDNDRqg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/x-global': 10.1.7 + '@babel/runtime': 7.19.4 + '@polkadot/x-global': 10.1.11 + '@types/node-fetch': 2.6.2 + node-fetch: 3.2.10 + dev: false + + /@polkadot/x-fetch/10.1.2: + resolution: {integrity: sha512-Zd7npq9H/kDaehiM2iyPX1+cSfuhCvqDxuS8GLTjARIVGGURBfA+NjRM6o6jsXa3HCtv+lB67Qdw1m/PSxfIpQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.0 + '@polkadot/x-global': 10.1.2 '@types/node-fetch': 2.6.2 node-fetch: 3.2.10 dev: false @@ -3057,7 +3417,7 @@ packages: resolution: {integrity: sha512-qJyLLnm+4SQEZ002UDz2wWnXbnnH84rIS0mLKZ5k82H4lMYY+PQflvzv6sbu463e/lgiEao+6zvWS6DSKv1Yog==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 6.11.1 '@types/node-fetch': 2.6.2 node-fetch: 2.6.7 @@ -3069,7 +3429,7 @@ packages: resolution: {integrity: sha512-ygNparcalYFGbspXtdtZOHvNXZBkNgmNO+um9C0JYq74K5OY9/be93uyfJKJ8JcRJtOqBfVDsJpbiRkuJ1PRfg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 8.7.1 '@types/node-fetch': 2.6.2 node-fetch: 2.6.7 @@ -3084,76 +3444,91 @@ packages: '@babel/runtime': 7.18.9 dev: false - /@polkadot/x-global/10.1.2: - resolution: {integrity: sha512-//r3NVLYdYQs0So0IK8Pa0pnL5pPi0geQWE6qjTtPD0oszuN9SUDqDlFQj3I3vqQOwgybbzBGNYRRinP8B2xUg==} + /@polkadot/x-global/10.1.10: + resolution: {integrity: sha512-WFfgaZSrzPlKLdnOus2mIFGzUbSDIQK6RMCfFfM9SmF3DkoxN40z5Nkni4PztfKr22stlkhmhnX/Lp/NxpuT6Q==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 dev: false - /@polkadot/x-global/10.1.6: - resolution: {integrity: sha512-/nraYZg0hdSjbczhDBAsHlEqeZLs0u0xa8HJrfH2lq8+HOIYkQpJPHOqiQIvEe/VFRq7Xnbij+4uffV+otzB/w==} + /@polkadot/x-global/10.1.11: + resolution: {integrity: sha512-bWz5gdcELy6+xfr27R1GE5MPX4nfVlchzHQH+DR6OBbSi9g/PeycQAvFB6IkTmP+YEbNNtIpxnSP37zoUaG3xw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.4 dev: false - /@polkadot/x-global/10.1.7: - resolution: {integrity: sha512-k2ZUZyBVgDnP/Ysxapa0mthn63j6gsN2V0kZejEQPyOfCHtQQkse3jFvAWdslpWoR8j2k8SN5O6reHc0F4f7mA==} + /@polkadot/x-global/10.1.2: + resolution: {integrity: sha512-//r3NVLYdYQs0So0IK8Pa0pnL5pPi0geQWE6qjTtPD0oszuN9SUDqDlFQj3I3vqQOwgybbzBGNYRRinP8B2xUg==} engines: {node: '>=14.0.0'} dependencies: '@babel/runtime': 7.18.9 dev: false + /@polkadot/x-global/10.1.6: + resolution: {integrity: sha512-/nraYZg0hdSjbczhDBAsHlEqeZLs0u0xa8HJrfH2lq8+HOIYkQpJPHOqiQIvEe/VFRq7Xnbij+4uffV+otzB/w==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.0 + dev: false + /@polkadot/x-global/6.11.1: resolution: {integrity: sha512-lsBK/e4KbjfieyRmnPs7bTiGbP/6EoCZz7rqD/voNS5qsJAaXgB9LR+ilubun9gK/TDpebyxgO+J19OBiQPIRw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 dev: false /@polkadot/x-global/7.9.2: resolution: {integrity: sha512-JX5CrGWckHf1P9xKXq4vQCAuMUbL81l2hOWX7xeP8nv4caHEpmf5T1wD1iMdQBL5PFifo6Pg0V6/oZBB+bts7A==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 dev: false /@polkadot/x-global/8.7.1: resolution: {integrity: sha512-WOgUor16IihgNVdiTVGAWksYLUAlqjmODmIK1cuWrLOZtV1VBomWcb3obkO9sh5P6iWziAvCB/i+L0vnTN9ZCA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 dev: false /@polkadot/x-global/9.7.2: resolution: {integrity: sha512-3NN5JhjosaelaFWBJSlv9mb/gDAlt7RuZ8NKlOjB+LQHd9g6ZbnYi5wwjW+i/x/3E4IVbBx66uvWgNaw7IBrkg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 dev: false - /@polkadot/x-randomvalues/10.1.2: - resolution: {integrity: sha512-KOu6iZWye9KD6qoahiqZ0alrT/5FSGL4XXLhVSg69xAqD6yG2oi2aKA6cZpDU19uZGqVneqsgpebDsrZ0nLUEg==} + /@polkadot/x-randomvalues/10.1.10: + resolution: {integrity: sha512-KM4sCI/DNLIXlmnkeJIuYvh3pPuWvnkbR1a6TUB12J1izUJ+uGV+cAFRR4/EZk3oEsG/Tgivbs56meEOo3ws5A==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/x-global': 10.1.2 + '@babel/runtime': 7.19.0 + '@polkadot/x-global': 10.1.10 dev: false - /@polkadot/x-randomvalues/10.1.7: - resolution: {integrity: sha512-3er4UYOlozLGgFYWwcbmcFslmO8m82u4cAGR4AaEag0VdV7jLO/M5lTmivT/3rtLSww6sjkEfr522GM2Q5lmFg==} + /@polkadot/x-randomvalues/10.1.11: + resolution: {integrity: sha512-V2V37f5hoM5B32eCpGw87Lwstin2+ArXhOZ8ENKncbQLXzbF9yTODueDoA5Vt0MJCs2CDP9cyiCYykcanqVkxg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/x-global': 10.1.7 + '@babel/runtime': 7.19.4 + '@polkadot/x-global': 10.1.11 + dev: false + + /@polkadot/x-randomvalues/10.1.2: + resolution: {integrity: sha512-KOu6iZWye9KD6qoahiqZ0alrT/5FSGL4XXLhVSg69xAqD6yG2oi2aKA6cZpDU19uZGqVneqsgpebDsrZ0nLUEg==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.0 + '@polkadot/x-global': 10.1.2 dev: false /@polkadot/x-randomvalues/6.11.1: resolution: {integrity: sha512-2MfUfGZSOkuPt7GF5OJkPDbl4yORI64SUuKM25EGrJ22o1UyoBnPOClm9eYujLMD6BfDZRM/7bQqqoLW+NuHVw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 6.11.1 dev: false @@ -3161,7 +3536,7 @@ packages: resolution: {integrity: sha512-svQfG31yCXf6yVyIgP0NgCzEy7oc3Lw054ZspkaqjOivxYdrXaf5w3JSSUyM/MRjI2+nk+B/EyJoMYcfSwTfsQ==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 7.9.2 dev: false @@ -3169,7 +3544,7 @@ packages: resolution: {integrity: sha512-njt17MlfN6yNyNEti7fL12lr5qM6A1aSGkWKVuqzc7XwSBesifJuW4km5u6r2gwhXjH2eHDv9SoQ7WXu8vrrkg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 8.7.1 dev: false @@ -3177,7 +3552,7 @@ packages: resolution: {integrity: sha512-819slnXNpoVtqdhjI19ao7w5m+Zwx11VfwCZkFQypVv3b/1UEoKG/baJA9dVI6yMvhnBN//i8mLgNy3IXWbVVw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 9.7.2 dev: false @@ -3185,7 +3560,7 @@ packages: resolution: {integrity: sha512-zIciEmij7SUuXXg9g/683Irx6GogxivrQS2pgBir2DI/YZq+um52+Dqg1mqsEZt74N4KMTMnzAZAP6LJOBOMww==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 rxjs: 6.6.7 dev: false @@ -3197,6 +3572,22 @@ packages: '@polkadot/x-global': 10.1.1 dev: false + /@polkadot/x-textdecoder/10.1.10: + resolution: {integrity: sha512-cAk37faYXx8IICeaq/tdl+aiIXwo3SLrx9XNoQqhX02g+SEs3ARM7zJcohj/p8ynWAI+ezNcsKn1wh174nquHw==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.0 + '@polkadot/x-global': 10.1.10 + dev: false + + /@polkadot/x-textdecoder/10.1.11: + resolution: {integrity: sha512-QZqie04SR6pAj260PaLBfZUGXWKI357t4ROVJhpaj06qc1zrk1V8Mwkr49+WzjAPFEOqo70HWnzXmPNCH4dQiw==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.4 + '@polkadot/x-global': 10.1.11 + dev: false + /@polkadot/x-textdecoder/10.1.2: resolution: {integrity: sha512-liMlSSKfLGTvcUPz1fMicH2HoKLgSjzxFYsbNfXJOe9GobQfSrAOcprM0j4gNJqN5EoZhze9Sf1rMTORQwomtg==} engines: {node: '>=14.0.0'} @@ -3209,23 +3600,15 @@ packages: resolution: {integrity: sha512-T+jvyv6OvUgGfOlMDLkPKEmQnZGP1CNohdEDeRr93AmeYikIfbC20qYuAc0bEBXR7/rPXgnqiEfrpkL2W3r/Ig==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 10.1.6 dev: false - /@polkadot/x-textdecoder/10.1.7: - resolution: {integrity: sha512-iAFOHludmZFOyVL8sQFv4TDqbcqQU5gwwYv74duTA+WQBgbSITJrBahSCV/rXOjUqds9pzQO3qBFzziznNnkiQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/x-global': 10.1.7 - dev: false - /@polkadot/x-textdecoder/6.11.1: resolution: {integrity: sha512-DI1Ym2lyDSS/UhnTT2e9WutukevFZ0WGpzj4eotuG2BTHN3e21uYtYTt24SlyRNMrWJf5+TkZItmZeqs1nwAfQ==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 6.11.1 dev: false @@ -3233,7 +3616,7 @@ packages: resolution: {integrity: sha512-wfwbSHXPhrOAl12QvlIOGNkMH/N/h8PId2ytIjvM/8zPPFB5Il6DWSFLtVapOGEpIFjEWbd5t8Td4pHBVXIEbg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 7.9.2 dev: false @@ -3241,7 +3624,7 @@ packages: resolution: {integrity: sha512-ia0Ie2zi4VdQdNVD2GE2FZzBMfX//hEL4w546RMJfZM2LqDS674LofHmcyrsv5zscLnnRyCxZC1+J2dt+6MDIA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 8.7.1 dev: false @@ -3249,7 +3632,7 @@ packages: resolution: {integrity: sha512-hhrMNZwJBmusdpqjDRpOHZoMB4hpyJt9Gu9Bi9is7/D/vq/hpxq8z7s6NxrbRyXJf1SIk6NMK0jf5XjRLdKdbw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 9.7.2 dev: false @@ -3261,6 +3644,22 @@ packages: '@polkadot/x-global': 10.1.1 dev: false + /@polkadot/x-textencoder/10.1.10: + resolution: {integrity: sha512-Auaql6BL5UHtWakZUQyj4y/BrM0tm4bYG5vXCMQCA1Gg0ky+46DhgpRrAQ9F7NNgWg1A6dA2I9KuAA4BTbNx0w==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.0 + '@polkadot/x-global': 10.1.10 + dev: false + + /@polkadot/x-textencoder/10.1.11: + resolution: {integrity: sha512-UX+uV9AbDID81waaG/NvTkkf7ZNVW7HSHaddgbWjQEVW2Ex4ByccBarY5jEi6cErEPKfzCamKhgXflu0aV9LWw==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.4 + '@polkadot/x-global': 10.1.11 + dev: false + /@polkadot/x-textencoder/10.1.2: resolution: {integrity: sha512-bSMvesZ43Er6+jogt9IfwWN/E8bhkl4a9nNnpyS/vTh+j6n/DfDQrvYpKDpRIn7oJA6lfs/mL9Jo5jjJTngaxg==} engines: {node: '>=14.0.0'} @@ -3273,23 +3672,15 @@ packages: resolution: {integrity: sha512-e+iHdR1P/8xAc54l3gHfqozH6ZfxPkKlVVaz3vOMnzfc8cA3Zw93mLYkGtLDqv+825LkSrWSmb/bDZb6YyEEXg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 10.1.6 dev: false - /@polkadot/x-textencoder/10.1.7: - resolution: {integrity: sha512-GzjaWZDbgzZ0IQT60xuZ7cZ0wnlNVYMqpfI9KvBc58X9dPI3TIMwzbXDVzZzpjY1SAqJGs4hJse9HMWZazfhew==} - engines: {node: '>=14.0.0'} - dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/x-global': 10.1.7 - dev: false - /@polkadot/x-textencoder/6.11.1: resolution: {integrity: sha512-8ipjWdEuqFo+R4Nxsc3/WW9CSEiprX4XU91a37ZyRVC4e9R1bmvClrpXmRQLVcAQyhRvG8DKOOtWbz8xM+oXKg==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 6.11.1 dev: false @@ -3297,7 +3688,7 @@ packages: resolution: {integrity: sha512-A19wwYINuZwU2dUyQ/mMzB0ISjyfc4cISfL4zCMUAVgj7xVoXMYV2GfjNdMpA8Wsjch3su6pxLbtJ2wU03sRTQ==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 7.9.2 dev: false @@ -3305,7 +3696,7 @@ packages: resolution: {integrity: sha512-XDO0A27Xy+eJCKSxENroB8Dcnl+UclGG4ZBei+P/BqZ9rsjskUyd2Vsl6peMXAcsxwOE7g0uTvujoGM8jpKOXw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 8.7.1 dev: false @@ -3313,28 +3704,40 @@ packages: resolution: {integrity: sha512-GHbSdbMPixDAOnJ9cvL/x9sPNeHegPoDSqCAzY5H6/zHc/fNn0vUu0To9VpPgPhp/Jb9dbc0h8YqEyvOcOlphw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 9.7.2 dev: false - /@polkadot/x-ws/10.1.2: - resolution: {integrity: sha512-RQkc6TPM7xOKHMrE3R/8+FdE9fMGJEN7yfK/GixpMGzw98NcVedxJ1xTL19r76hJvOSeZAEks5oqgMxF8K9Pbg==} + /@polkadot/x-ws/10.1.10: + resolution: {integrity: sha512-JxDgfm0ox2XPAtdTeJXYl6qq7LY/KOPi69wRpFMczWaYUsZubO6EiRzgzjuFlHY4/oxfjS/D+YbzcjefTxHz6g==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/x-global': 10.1.2 + '@babel/runtime': 7.19.0 + '@polkadot/x-global': 10.1.10 '@types/websocket': 1.0.5 websocket: 1.0.34 transitivePeerDependencies: - supports-color dev: false - /@polkadot/x-ws/10.1.7: - resolution: {integrity: sha512-aNkotxHx3qPVjiItD9lbNONs4GNzqeeZ98wHtCjd9JWl/g+xNkOVF3xQ8++1qSHPBEYSwKh9URjQH2+CD2XlvQ==} + /@polkadot/x-ws/10.1.11: + resolution: {integrity: sha512-EUbL/R1A/NxYf6Rnb1M7U9yeTuo5r4y2vcQllE5aBLaQ0cFnRykHzlmZlVX1E7O5uy3lYVdxWC7sNgxItIWkWA==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 - '@polkadot/x-global': 10.1.7 + '@babel/runtime': 7.19.4 + '@polkadot/x-global': 10.1.11 + '@types/websocket': 1.0.5 + websocket: 1.0.34 + transitivePeerDependencies: + - supports-color + dev: false + + /@polkadot/x-ws/10.1.2: + resolution: {integrity: sha512-RQkc6TPM7xOKHMrE3R/8+FdE9fMGJEN7yfK/GixpMGzw98NcVedxJ1xTL19r76hJvOSeZAEks5oqgMxF8K9Pbg==} + engines: {node: '>=14.0.0'} + dependencies: + '@babel/runtime': 7.19.0 + '@polkadot/x-global': 10.1.2 '@types/websocket': 1.0.5 websocket: 1.0.34 transitivePeerDependencies: @@ -3345,7 +3748,7 @@ packages: resolution: {integrity: sha512-GNu4ywrMlVi0QF6QSpKwYWMK6JRK+kadgN/zEhMoH1z5h8LwpqDLv128j5WspWbQti2teCQtridjf7t2Lzoe8Q==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 6.11.1 '@types/websocket': 1.0.5 websocket: 1.0.34 @@ -3357,7 +3760,7 @@ packages: resolution: {integrity: sha512-Mt0tcNzGXyKnN3DQ06alkv+JLtTfXWu6zSypFrrKHSQe3u79xMQ1nSicmpT3gWLhIa8YF+8CYJXMrqaXgCnDhw==} engines: {node: '>=14.0.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 '@polkadot/x-global': 8.7.1 '@types/websocket': 1.0.5 websocket: 1.0.34 @@ -3460,7 +3863,7 @@ packages: /@subsocial/definitions/0.6.11: resolution: {integrity: sha512-FQDzZmSaHXQ9x5HoudPcDYf3BmH2CN7zPbPZS+01LZXhelDN7qbNk36+pBeXki0zmtUnevWjy6LKld8zZ3XLBw==} dependencies: - '@polkadot/api': 9.3.3 + '@polkadot/api': 9.5.2 lodash.camelcase: 4.3.0 transitivePeerDependencies: - bufferutil @@ -3482,11 +3885,11 @@ packages: - supports-color dev: false - /@substrate/connect/0.7.11: - resolution: {integrity: sha512-/xiOlkmJfl2XPYQTmyWKEh2AXryEAPSMAxZXs6D/aqYDy0TKZDAp1dfQiHyPt1vMwOlnM4WJv9lPks3ZMwCP+w==} + /@substrate/connect/0.7.14: + resolution: {integrity: sha512-uW5uBmihpivshmmmw+rsg7qOV0KqVSep4rWOXFMP8aFQinvmqw4JqxP21og4H/7JZxttYUBFQVsdtXHGKJ0aVQ==} dependencies: '@substrate/connect-extension-protocol': 1.0.1 - '@substrate/smoldot-light': 0.6.30 + '@substrate/smoldot-light': 0.6.34 eventemitter3: 4.0.7 transitivePeerDependencies: - bufferutil @@ -3511,8 +3914,8 @@ packages: - supports-color dev: false - /@substrate/smoldot-light/0.6.30: - resolution: {integrity: sha512-U/F75XzxuNG+KGSujxsMAm8zUBpBON+l0oX19EnSWjvqD+smYjvcj1SeqQhFYxJjtoCQyZLedKBsZGyNbG3FbQ==} + /@substrate/smoldot-light/0.6.34: + resolution: {integrity: sha512-+HK9MaJ0HelJmpf4YYR+salJ7dhVBltmhGlyz5l8OXS9DW18fe0Z2wxEo8P5kX9CUxlCXEb8J9JBRQAYBPHbwQ==} dependencies: pako: 2.0.4 ws: 8.8.1 @@ -3535,8 +3938,12 @@ packages: resolution: {integrity: sha512-LmCH4QJRdHaeLsLTPSgJaXguMoIW+Ig9fA9LRPpeya9HefVAJ7gZuUYinldv+QmX7evNm5CL0rspNUS8l1DvXg==} dev: false - /@substrate/ss58-registry/1.28.0: - resolution: {integrity: sha512-XPSwSq4CThLyg+OnZ5/LHh3SPDQjRdGS3Ux5ClgWhRCQamlU86FCT1LBwQ/i+ximbdBfqKRRzVhm1ql3AJ9FKQ==} + /@substrate/ss58-registry/1.31.0: + resolution: {integrity: sha512-OSOmdjaq9foXfHBy9aLVMwGheygvsiZlv4dggnLOYOuhSmNCsSB/PaW4DBz+/tSdK1Fo9+ZiFW6cF24RA+m0sw==} + dev: false + + /@substrate/ss58-registry/1.33.0: + resolution: {integrity: sha512-DztMuMcEfu+tJrtIQIIp5gO8/XJZ8N8UwPObDCSNgrp7trtSkPJAUFB9qXaReXtN9UvTcVBMTWk6VPfFi04Wkg==} dev: false /@substrate/txwrapper-core/3.1.7: @@ -8039,6 +8446,12 @@ packages: dependencies: tslib: 2.4.0 + /rxjs/7.5.7: + resolution: {integrity: sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==} + dependencies: + tslib: 2.4.0 + dev: false + /safe-buffer/5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} diff --git a/src/app.resolver.spec.ts b/src/app.resolver.spec.ts index efeae0f..344a19e 100644 --- a/src/app.resolver.spec.ts +++ b/src/app.resolver.spec.ts @@ -21,4 +21,10 @@ describe('AppResolver', () => { expect(resolver.status()).toEqual('running') }) }) + + describe('version', () => { + it('should return the current version', () => { + expect(resolver.version()).toEqual('v1.0.1') + }) + }) }) diff --git a/src/app.resolver.ts b/src/app.resolver.ts index 57a7f9e..12041d1 100644 --- a/src/app.resolver.ts +++ b/src/app.resolver.ts @@ -6,4 +6,9 @@ export class AppResolver { status(): string { return 'running' } + + @Query(/* istanbul ignore next */ () => String) + version(): string { + return 'v1.0.1' + } } diff --git a/src/blocks/blocks.service.spec.ts b/src/blocks/blocks.service.spec.ts index 4133200..cac66e0 100644 --- a/src/blocks/blocks.service.spec.ts +++ b/src/blocks/blocks.service.spec.ts @@ -83,6 +83,8 @@ describe('BlocksService', () => { parentHash: mockBlock.parentHash, number, } as any) || {}, + mockBlock.timestamp, + mockBlock.encodedLength, ), ).resolves.toBe(mockBlock) expect(repo.create).toBeCalledTimes(1) @@ -90,9 +92,9 @@ describe('BlocksService', () => { hash: mockBlock.hash, parentHash: mockBlock.parentHash, number: mockBlock.number, + timestamp: mockBlock.timestamp, + encodedLength: mockBlock.encodedLength, }) - // TODO: fix repo.save called - // expect(repo.save).toBeCalledTimes(1) }) it('should return an existing block', () => { @@ -109,6 +111,8 @@ describe('BlocksService', () => { parentHash: mockBlock.parentHash, number, } as any) || {}, + mockBlock.timestamp, + mockBlock.encodedLength, ), ).resolves.toBe(mockBlock) expect(repo.create).toBeCalledTimes(1) @@ -116,8 +120,33 @@ describe('BlocksService', () => { hash: mockBlock.hash, parentHash: mockBlock.parentHash, number: mockBlock.number, + encodedLength: mockBlock.encodedLength, + timestamp: mockBlock.timestamp, }) expect(repo.save).toBeCalledTimes(0) }) + + it('should fail', async () => { + jest.spyOn(repo, 'findOneBy').mockRejectedValue(new Error('Failed')) + + const number = { + toHex: () => '27', + } + + try { + await service.createFromHeader( + ({ + hash: mockBlock.hash, + parentHash: mockBlock.parentHash, + number, + } as any) || {}, + mockBlock.timestamp, + mockBlock.encodedLength, + ) + } catch (error) { + expect(error).toBeInstanceOf(Error) + expect((error as Error).message).toBe('Failed') + } + }) }) }) diff --git a/src/blocks/blocks.service.ts b/src/blocks/blocks.service.ts index 2101832..1377c3f 100644 --- a/src/blocks/blocks.service.ts +++ b/src/blocks/blocks.service.ts @@ -26,16 +26,22 @@ export class BlocksService { } async fetchBlocks(args: FetchBlocksInput): Promise { - return this.blockRepository.find(args) + const { skip, take, orderByNumber, orderAsc } = args + const order: any = {} + const by = orderByNumber ? 'number' : 'timestamp' + order[by] = orderAsc ? 'ASC' : 'DESC' + return this.blockRepository.find({ skip, take, order }) } - async createFromHeader(header: Header): Promise { + async createFromHeader(header: Header, timestamp: number, encodedLength: number): Promise { try { const { hash, parentHash, number } = header const block = this.blockRepository.create({ hash: hash.toString().toLowerCase(), parentHash: parentHash.toString().toLowerCase(), number: parseInt(number.toHex()), + timestamp, + encodedLength, }) const persistedBlock = await retry( async () => { diff --git a/src/blocks/dtos/fetch-blocks.input.ts b/src/blocks/dtos/fetch-blocks.input.ts index 19639e1..b9e73b1 100644 --- a/src/blocks/dtos/fetch-blocks.input.ts +++ b/src/blocks/dtos/fetch-blocks.input.ts @@ -7,4 +7,10 @@ export class FetchBlocksInput { @Field(/* istanbul ignore next */ () => Int) take = 10 + + @Field(/* istanbul ignore next */ () => Boolean) + orderByNumber?: boolean = false + + @Field(/* istanbul ignore next */ () => Boolean) + orderAsc?: boolean = false } diff --git a/src/blocks/entity/block.entity.ts b/src/blocks/entity/block.entity.ts index 10c0356..d741691 100644 --- a/src/blocks/entity/block.entity.ts +++ b/src/blocks/entity/block.entity.ts @@ -1,4 +1,4 @@ -import { Field, Int, ObjectType } from '@nestjs/graphql' +import { Field, Float, Int, ObjectType } from '@nestjs/graphql' import { BaseEntity, Column, CreateDateColumn, Entity, Index, OneToMany, PrimaryColumn } from 'typeorm' import { Transaction } from '../../transactions/entity/transaction.entity' @@ -20,6 +20,14 @@ export class Block extends BaseEntity { @Field(/* istanbul ignore next */ () => Int) number!: number + @Column('bigint') + @Field(/* istanbul ignore next */ () => Float) + timestamp!: number + + @Column('bigint') + @Field(/* istanbul ignore next */ () => Float) + encodedLength!: number + @OneToMany( /* istanbul ignore next */ () => Transaction, /* istanbul ignore next */ (transaction: Transaction) => transaction.block, diff --git a/src/contracts/contracts.resolver.spec.ts b/src/contracts/contracts.resolver.spec.ts index 5a19101..f038116 100644 --- a/src/contracts/contracts.resolver.spec.ts +++ b/src/contracts/contracts.resolver.spec.ts @@ -1,6 +1,12 @@ import { NotFoundException } from '@nestjs/common' import { Test, TestingModule } from '@nestjs/testing' -import { mockContract, generateAbiInBase64 } from '../../mocks/contracts-mocks' +import { + mockContract, + mockContracts, + mockContractQueries, + generateAbiInBase64, + mockQueryString, +} from '../../mocks/contracts-mocks' import { mockEvents } from '../../mocks/events-mocks' import { EventsService } from '../events/events.service' import { ContractsResolver } from './contracts.resolver' @@ -20,6 +26,8 @@ describe('ContractsResolver', () => { { provide: ContractsService, useFactory: () => ({ + getContractQueries: jest.fn(() => mockContractQueries), + fetchContracts: jest.fn(() => mockContracts), findOne: jest.fn(() => mockContract), uploadMetadata: jest.fn(() => true), }), @@ -48,6 +56,24 @@ describe('ContractsResolver', () => { }) }) + describe('getContracts', () => { + it('should get a list of contracts', async () => { + const args = { + skip: 0, + take: 10, + } + const contracts = await resolver.getContracts(args) + expect(contracts).toEqual(mockContracts) + }) + }) + + describe('getContractQueries', () => { + it('should get contractQueries by address', async () => { + const contractQueries = await resolver.getContractQueries(mockContract.address) + expect(contractQueries).toEqual(mockContractQueries) + }) + }) + describe('uploadMetada', () => { it('should update the metada for a contract', async () => { const contract = await resolver.uploadMetadata(base64metadata, mockContract.address) @@ -75,4 +101,25 @@ describe('ContractsResolver', () => { expect(events).toBe(mockEvents) }) }) + + describe('hasMetadata', () => { + it('should return true if the contract has metadata', () => { + expect(resolver.hasMetadata(mockContract as any)).resolves.toBe(true) + }) + + it('should return false if the contract has no metadata', () => { + const mockNoMetadata = { ...mockContract, metadata: null } + expect(resolver.hasMetadata(mockNoMetadata as any)).resolves.toBe(false) + }) + }) + + describe('queries', () => { + it('should return the queries (empty) of the contract', () => { + expect(resolver.queries(mockContract as any)).resolves.toEqual([]) + }) + + it('should return the queries of the contract', () => { + expect(resolver.queries(mockContractQueries as any)).resolves.toEqual(mockQueryString) + }) + }) }) diff --git a/src/contracts/contracts.resolver.ts b/src/contracts/contracts.resolver.ts index 0536fcc..616de33 100644 --- a/src/contracts/contracts.resolver.ts +++ b/src/contracts/contracts.resolver.ts @@ -3,7 +3,8 @@ import { FetchEventsInput } from '../events/dtos/fetch-events.input' import { Event } from '../events/entity/event.entity' import { EventsService } from '../events/events.service' import { ContractsService } from './contracts.service' -import { Contract } from './entity/contract.entity' +import { FetchContractsInput } from './dtos/fetch-contracts.input' +import { Contract, ContractQuery } from './entity/contract.entity' @Resolver(() => Contract) export class ContractsResolver { @@ -14,6 +15,16 @@ export class ContractsResolver { return this.contractsService.findOne(address) } + @Query(/* istanbul ignore next */ () => [Contract]) + async getContracts(@Args() args: FetchContractsInput) { + return this.contractsService.fetchContracts(args) + } + + @Query(/* istanbul ignore next */ () => Contract) + async getContractQueries(@Args('address', { type: () => String }) address: string) { + return this.contractsService.getContractQueries(address) + } + @Mutation(/* istanbul ignore next */ () => Boolean) async uploadMetadata( @Args('metadata', { type: /* istanbul ignore next */ () => String }) metadata: string, @@ -35,4 +46,22 @@ export class ContractsResolver { } return this.eventsService.fetchEvents(args) } + + @ResolveField('queries', /* istanbul ignore next */ () => [ContractQuery]) + async queries(@Parent() contract: Contract) { + const { queries } = contract + if (!queries) { + return [] + } + queries.forEach((query) => { + query.args = query.args.map((arg) => JSON.stringify(arg)) + }) + return queries + } + + @ResolveField('hasMetadata', /* istanbul ignore next */ () => Boolean) + async hasMetadata(@Parent() contract: Contract) { + const { metadata } = contract + return !!metadata + } } diff --git a/src/contracts/contracts.service.spec.ts b/src/contracts/contracts.service.spec.ts index cfe36ff..07bc592 100644 --- a/src/contracts/contracts.service.spec.ts +++ b/src/contracts/contracts.service.spec.ts @@ -1,11 +1,18 @@ import { NotFoundException } from '@nestjs/common' import { Test, TestingModule } from '@nestjs/testing' import { getRepositoryToken } from '@nestjs/typeorm' +import { ApiPromise } from '@polkadot/api' import { Repository } from 'typeorm' +import { apiMock } from '../../mocks/api-mock' +import { BASE64_METADATA } from '../../mocks/base64-metadata.mock' +import { mockContractQueries } from '../../mocks/contracts-mocks' import { mockPinoService } from '../../mocks/pino-mocks' +import { connect } from '../utils' import { ContractsService } from './contracts.service' import { Contract } from './entity/contract.entity' +jest.mock('../utils') + const mockContracts = [ { address: '5F73xwbK9jtcG1YY38DG5wVLm42y15pCa8zE79snVT5z9X1t', @@ -14,12 +21,10 @@ const mockContracts = [ }, ] -const base64metadata = - 'ewogICJzb3VyY2UiOiB7CiAgICAiaGFzaCI6ICIweDNhYTFjOGJhNWY1OTAzNGE0MmE5M2MwMGVlMDM5YTk0NjRkNmZhNjNkNzBiNjg4OWEyNTk2ZjQ1MjhiMjhhMTkiLAogICAgImxhbmd1YWdlIjogImluayEgMy4zLjAiLAogICAgImNvbXBpbGVyIjogInJ1c3RjIDEuNjQuMC1uaWdodGx5IgogIH0sCiAgImNvbnRyYWN0IjogewogICAgIm5hbWUiOiAiZXJjMjAiLAogICAgInZlcnNpb24iOiAiMC4xLjAiLAogICAgImF1dGhvcnMiOiBbIlt5b3VyX25hbWVdIDxbeW91cl9lbWFpbF0+Il0KICB9LAogICJWMyI6IHsKICAgICJzcGVjIjogewogICAgICAiY29uc3RydWN0b3JzIjogWwogICAgICAgIHsKICAgICAgICAgICJhcmdzIjogWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgImxhYmVsIjogImluaXRpYWxfc3VwcGx5IiwKICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICJkaXNwbGF5TmFtZSI6IFsiQmFsYW5jZSJdLAogICAgICAgICAgICAgICAgInR5cGUiOiAwCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICBdLAogICAgICAgICAgImRvY3MiOiBbIkNyZWF0ZXMgYSBuZXcgRVJDLTIwIGNvbnRyYWN0IHdpdGggdGhlIHNwZWNpZmllZCBpbml0aWFsIHN1cHBseS4iXSwKICAgICAgICAgICJsYWJlbCI6ICJuZXciLAogICAgICAgICAgInBheWFibGUiOiBmYWxzZSwKICAgICAgICAgICJzZWxlY3RvciI6ICIweDliYWU5ZDVlIgogICAgICAgIH0KICAgICAgXSwKICAgICAgImRvY3MiOiBbXSwKICAgICAgImV2ZW50cyI6IFsKICAgICAgICB7CiAgICAgICAgICAiYXJncyI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICJkb2NzIjogW10sCiAgICAgICAgICAgICAgImluZGV4ZWQiOiB0cnVlLAogICAgICAgICAgICAgICJsYWJlbCI6ICJmcm9tIiwKICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICJkaXNwbGF5TmFtZSI6IFsiT3B0aW9uIl0sCiAgICAgICAgICAgICAgICAidHlwZSI6IDExCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgImRvY3MiOiBbXSwKICAgICAgICAgICAgICAiaW5kZXhlZCI6IHRydWUsCiAgICAgICAgICAgICAgImxhYmVsIjogInRvIiwKICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICJkaXNwbGF5TmFtZSI6IFsiT3B0aW9uIl0sCiAgICAgICAgICAgICAgICAidHlwZSI6IDExCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgImRvY3MiOiBbXSwKICAgICAgICAgICAgICAiaW5kZXhlZCI6IGZhbHNlLAogICAgICAgICAgICAgICJsYWJlbCI6ICJ2YWx1ZSIsCiAgICAgICAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAgICAgICAiZGlzcGxheU5hbWUiOiBbIkJhbGFuY2UiXSwKICAgICAgICAgICAgICAgICJ0eXBlIjogMAogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgXSwKICAgICAgICAgICJkb2NzIjogWyIgRXZlbnQgZW1pdHRlZCB3aGVuIGEgdG9rZW4gdHJhbnNmZXIgb2NjdXJzLiJdLAogICAgICAgICAgImxhYmVsIjogIlRyYW5zZmVyIgogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgImFyZ3MiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAiZG9jcyI6IFtdLAogICAgICAgICAgICAgICJpbmRleGVkIjogdHJ1ZSwKICAgICAgICAgICAgICAibGFiZWwiOiAib3duZXIiLAogICAgICAgICAgICAgICJ0eXBlIjogewogICAgICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJBY2NvdW50SWQiXSwKICAgICAgICAgICAgICAgICJ0eXBlIjogMgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICJkb2NzIjogW10sCiAgICAgICAgICAgICAgImluZGV4ZWQiOiB0cnVlLAogICAgICAgICAgICAgICJsYWJlbCI6ICJzcGVuZGVyIiwKICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICJkaXNwbGF5TmFtZSI6IFsiQWNjb3VudElkIl0sCiAgICAgICAgICAgICAgICAidHlwZSI6IDIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAiZG9jcyI6IFtdLAogICAgICAgICAgICAgICJpbmRleGVkIjogZmFsc2UsCiAgICAgICAgICAgICAgImxhYmVsIjogInZhbHVlIiwKICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICJkaXNwbGF5TmFtZSI6IFsiQmFsYW5jZSJdLAogICAgICAgICAgICAgICAgInR5cGUiOiAwCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICBdLAogICAgICAgICAgImRvY3MiOiBbCiAgICAgICAgICAgICIgRXZlbnQgZW1pdHRlZCB3aGVuIGFuIGFwcHJvdmFsIG9jY3VycyB0aGF0IGBzcGVuZGVyYCBpcyBhbGxvd2VkIHRvIHdpdGhkcmF3IiwKICAgICAgICAgICAgIiB1cCB0byB0aGUgYW1vdW50IG9mIGB2YWx1ZWAgdG9rZW5zIGZyb20gYG93bmVyYC4iCiAgICAgICAgICBdLAogICAgICAgICAgImxhYmVsIjogIkFwcHJvdmFsIgogICAgICAgIH0KICAgICAgXSwKICAgICAgIm1lc3NhZ2VzIjogWwogICAgICAgIHsKICAgICAgICAgICJhcmdzIjogW10sCiAgICAgICAgICAiZG9jcyI6IFsiIFJldHVybnMgdGhlIHRvdGFsIHRva2VuIHN1cHBseS4iXSwKICAgICAgICAgICJsYWJlbCI6ICJ0b3RhbF9zdXBwbHkiLAogICAgICAgICAgIm11dGF0ZXMiOiBmYWxzZSwKICAgICAgICAgICJwYXlhYmxlIjogZmFsc2UsCiAgICAgICAgICAicmV0dXJuVHlwZSI6IHsKICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJCYWxhbmNlIl0sCiAgICAgICAgICAgICJ0eXBlIjogMAogICAgICAgICAgfSwKICAgICAgICAgICJzZWxlY3RvciI6ICIweGRiNjM3NWE4IgogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgImFyZ3MiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAibGFiZWwiOiAib3duZXIiLAogICAgICAgICAgICAgICJ0eXBlIjogewogICAgICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJBY2NvdW50SWQiXSwKICAgICAgICAgICAgICAgICJ0eXBlIjogMgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgXSwKICAgICAgICAgICJkb2NzIjogWwogICAgICAgICAgICAiIFJldHVybnMgdGhlIGFjY291bnQgYmFsYW5jZSBmb3IgdGhlIHNwZWNpZmllZCBgb3duZXJgLiIsCiAgICAgICAgICAgICIiLAogICAgICAgICAgICAiIFJldHVybnMgYDBgIGlmIHRoZSBhY2NvdW50IGlzIG5vbi1leGlzdGVudC4iCiAgICAgICAgICBdLAogICAgICAgICAgImxhYmVsIjogImJhbGFuY2Vfb2YiLAogICAgICAgICAgIm11dGF0ZXMiOiBmYWxzZSwKICAgICAgICAgICJwYXlhYmxlIjogZmFsc2UsCiAgICAgICAgICAicmV0dXJuVHlwZSI6IHsKICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJCYWxhbmNlIl0sCiAgICAgICAgICAgICJ0eXBlIjogMAogICAgICAgICAgfSwKICAgICAgICAgICJzZWxlY3RvciI6ICIweDBmNzU1YTU2IgogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgImFyZ3MiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAibGFiZWwiOiAib3duZXIiLAogICAgICAgICAgICAgICJ0eXBlIjogewogICAgICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJBY2NvdW50SWQiXSwKICAgICAgICAgICAgICAgICJ0eXBlIjogMgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICJsYWJlbCI6ICJzcGVuZGVyIiwKICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICJkaXNwbGF5TmFtZSI6IFsiQWNjb3VudElkIl0sCiAgICAgICAgICAgICAgICAidHlwZSI6IDIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIF0sCiAgICAgICAgICAiZG9jcyI6IFsKICAgICAgICAgICAgIiBSZXR1cm5zIHRoZSBhbW91bnQgd2hpY2ggYHNwZW5kZXJgIGlzIHN0aWxsIGFsbG93ZWQgdG8gd2l0aGRyYXcgZnJvbSBgb3duZXJgLiIsCiAgICAgICAgICAgICIiLAogICAgICAgICAgICAiIFJldHVybnMgYDBgIGlmIG5vIGFsbG93YW5jZSBoYXMgYmVlbiBzZXQuIgogICAgICAgICAgXSwKICAgICAgICAgICJsYWJlbCI6ICJhbGxvd2FuY2UiLAogICAgICAgICAgIm11dGF0ZXMiOiBmYWxzZSwKICAgICAgICAgICJwYXlhYmxlIjogZmFsc2UsCiAgICAgICAgICAicmV0dXJuVHlwZSI6IHsKICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJCYWxhbmNlIl0sCiAgICAgICAgICAgICJ0eXBlIjogMAogICAgICAgICAgfSwKICAgICAgICAgICJzZWxlY3RvciI6ICIweDZhMDAxNjVlIgogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgImFyZ3MiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAibGFiZWwiOiAidG8iLAogICAgICAgICAgICAgICJ0eXBlIjogewogICAgICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJBY2NvdW50SWQiXSwKICAgICAgICAgICAgICAgICJ0eXBlIjogMgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICJsYWJlbCI6ICJ2YWx1ZSIsCiAgICAgICAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAgICAgICAiZGlzcGxheU5hbWUiOiBbIkJhbGFuY2UiXSwKICAgICAgICAgICAgICAgICJ0eXBlIjogMAogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgXSwKICAgICAgICAgICJkb2NzIjogWwogICAgICAgICAgICAiIFRyYW5zZmVycyBgdmFsdWVgIGFtb3VudCBvZiB0b2tlbnMgZnJvbSB0aGUgY2FsbGVyJ3MgYWNjb3VudCB0byBhY2NvdW50IGB0b2AuIiwKICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICIgT24gc3VjY2VzcyBhIGBUcmFuc2ZlcmAgZXZlbnQgaXMgZW1pdHRlZC4iLAogICAgICAgICAgICAiIiwKICAgICAgICAgICAgIiAjIEVycm9ycyIsCiAgICAgICAgICAgICIiLAogICAgICAgICAgICAiIFJldHVybnMgYEluc3VmZmljaWVudEJhbGFuY2VgIGVycm9yIGlmIHRoZXJlIGFyZSBub3QgZW5vdWdoIHRva2VucyBvbiIsCiAgICAgICAgICAgICIgdGhlIGNhbGxlcidzIGFjY291bnQgYmFsYW5jZS4iCiAgICAgICAgICBdLAogICAgICAgICAgImxhYmVsIjogInRyYW5zZmVyIiwKICAgICAgICAgICJtdXRhdGVzIjogdHJ1ZSwKICAgICAgICAgICJwYXlhYmxlIjogZmFsc2UsCiAgICAgICAgICAicmV0dXJuVHlwZSI6IHsKICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJSZXN1bHQiXSwKICAgICAgICAgICAgInR5cGUiOiA4CiAgICAgICAgICB9LAogICAgICAgICAgInNlbGVjdG9yIjogIjB4ODRhMTVkYTEiCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAiYXJncyI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICJsYWJlbCI6ICJzcGVuZGVyIiwKICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICJkaXNwbGF5TmFtZSI6IFsiQWNjb3VudElkIl0sCiAgICAgICAgICAgICAgICAidHlwZSI6IDIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAibGFiZWwiOiAidmFsdWUiLAogICAgICAgICAgICAgICJ0eXBlIjogewogICAgICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJCYWxhbmNlIl0sCiAgICAgICAgICAgICAgICAidHlwZSI6IDAKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIF0sCiAgICAgICAgICAiZG9jcyI6IFsKICAgICAgICAgICAgIiBBbGxvd3MgYHNwZW5kZXJgIHRvIHdpdGhkcmF3IGZyb20gdGhlIGNhbGxlcidzIGFjY291bnQgbXVsdGlwbGUgdGltZXMsIHVwIHRvIiwKICAgICAgICAgICAgIiB0aGUgYHZhbHVlYCBhbW91bnQuIiwKICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICIgSWYgdGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYWdhaW4gaXQgb3ZlcndyaXRlcyB0aGUgY3VycmVudCBhbGxvd2FuY2Ugd2l0aCBgdmFsdWVgLiIsCiAgICAgICAgICAgICIiLAogICAgICAgICAgICAiIEFuIGBBcHByb3ZhbGAgZXZlbnQgaXMgZW1pdHRlZC4iCiAgICAgICAgICBdLAogICAgICAgICAgImxhYmVsIjogImFwcHJvdmUiLAogICAgICAgICAgIm11dGF0ZXMiOiB0cnVlLAogICAgICAgICAgInBheWFibGUiOiBmYWxzZSwKICAgICAgICAgICJyZXR1cm5UeXBlIjogewogICAgICAgICAgICAiZGlzcGxheU5hbWUiOiBbIlJlc3VsdCJdLAogICAgICAgICAgICAidHlwZSI6IDgKICAgICAgICAgIH0sCiAgICAgICAgICAic2VsZWN0b3IiOiAiMHg2ODEyNjZhMCIKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJhcmdzIjogWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgImxhYmVsIjogImZyb20iLAogICAgICAgICAgICAgICJ0eXBlIjogewogICAgICAgICAgICAgICAgImRpc3BsYXlOYW1lIjogWyJBY2NvdW50SWQiXSwKICAgICAgICAgICAgICAgICJ0eXBlIjogMgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICJsYWJlbCI6ICJ0byIsCiAgICAgICAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAgICAgICAiZGlzcGxheU5hbWUiOiBbIkFjY291bnRJZCJdLAogICAgICAgICAgICAgICAgInR5cGUiOiAyCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgImxhYmVsIjogInZhbHVlIiwKICAgICAgICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICAgICAgICJkaXNwbGF5TmFtZSI6IFsiQmFsYW5jZSJdLAogICAgICAgICAgICAgICAgInR5cGUiOiAwCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICBdLAogICAgICAgICAgImRvY3MiOiBbCiAgICAgICAgICAgICIgVHJhbnNmZXJzIGB2YWx1ZWAgdG9rZW5zIG9uIHRoZSBiZWhhbGYgb2YgYGZyb21gIHRvIHRoZSBhY2NvdW50IGB0b2AuIiwKICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICIgVGhpcyBjYW4gYmUgdXNlZCB0byBhbGxvdyBhIGNvbnRyYWN0IHRvIHRyYW5zZmVyIHRva2VucyBvbiBvbmVzIGJlaGFsZiBhbmQvb3IiLAogICAgICAgICAgICAiIHRvIGNoYXJnZSBmZWVzIGluIHN1Yi1jdXJyZW5jaWVzLCBmb3IgZXhhbXBsZS4iLAogICAgICAgICAgICAiIiwKICAgICAgICAgICAgIiBPbiBzdWNjZXNzIGEgYFRyYW5zZmVyYCBldmVudCBpcyBlbWl0dGVkLiIsCiAgICAgICAgICAgICIiLAogICAgICAgICAgICAiICMgRXJyb3JzIiwKICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICIgUmV0dXJucyBgSW5zdWZmaWNpZW50QWxsb3dhbmNlYCBlcnJvciBpZiB0aGVyZSBhcmUgbm90IGVub3VnaCB0b2tlbnMgYWxsb3dlZCIsCiAgICAgICAgICAgICIgZm9yIHRoZSBjYWxsZXIgdG8gd2l0aGRyYXcgZnJvbSBgZnJvbWAuIiwKICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICIgUmV0dXJucyBgSW5zdWZmaWNpZW50QmFsYW5jZWAgZXJyb3IgaWYgdGhlcmUgYXJlIG5vdCBlbm91Z2ggdG9rZW5zIG9uIiwKICAgICAgICAgICAgIiB0aGUgYWNjb3VudCBiYWxhbmNlIG9mIGBmcm9tYC4iCiAgICAgICAgICBdLAogICAgICAgICAgImxhYmVsIjogInRyYW5zZmVyX2Zyb20iLAogICAgICAgICAgIm11dGF0ZXMiOiB0cnVlLAogICAgICAgICAgInBheWFibGUiOiBmYWxzZSwKICAgICAgICAgICJyZXR1cm5UeXBlIjogewogICAgICAgICAgICAiZGlzcGxheU5hbWUiOiBbIlJlc3VsdCJdLAogICAgICAgICAgICAidHlwZSI6IDgKICAgICAgICAgIH0sCiAgICAgICAgICAic2VsZWN0b3IiOiAiMHgwYjM5NmYxOCIKICAgICAgICB9CiAgICAgIF0KICAgIH0sCiAgICAic3RvcmFnZSI6IHsKICAgICAgInN0cnVjdCI6IHsKICAgICAgICAiZmllbGRzIjogWwogICAgICAgICAgewogICAgICAgICAgICAibGF5b3V0IjogewogICAgICAgICAgICAgICJjZWxsIjogewogICAgICAgICAgICAgICAgImtleSI6ICIweDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiLAogICAgICAgICAgICAgICAgInR5IjogMAogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAidG90YWxfc3VwcGx5IgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImxheW91dCI6IHsKICAgICAgICAgICAgICAiY2VsbCI6IHsKICAgICAgICAgICAgICAgICJrZXkiOiAiMHgwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIiwKICAgICAgICAgICAgICAgICJ0eSI6IDEKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImJhbGFuY2VzIgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImxheW91dCI6IHsKICAgICAgICAgICAgICAiY2VsbCI6IHsKICAgICAgICAgICAgICAgICJrZXkiOiAiMHgwMjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIiwKICAgICAgICAgICAgICAgICJ0eSI6IDYKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImFsbG93YW5jZXMiCiAgICAgICAgICB9CiAgICAgICAgXQogICAgICB9CiAgICB9LAogICAgInR5cGVzIjogWwogICAgICB7CiAgICAgICAgImlkIjogMCwKICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICJkZWYiOiB7CiAgICAgICAgICAgICJwcmltaXRpdmUiOiAidTEyOCIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiaWQiOiAxLAogICAgICAgICJ0eXBlIjogewogICAgICAgICAgImRlZiI6IHsKICAgICAgICAgICAgImNvbXBvc2l0ZSI6IHsKICAgICAgICAgICAgICAiZmllbGRzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAibmFtZSI6ICJvZmZzZXRfa2V5IiwKICAgICAgICAgICAgICAgICAgInR5cGUiOiA1LAogICAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiS2V5IgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICJwYXJhbXMiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAibmFtZSI6ICJLIiwKICAgICAgICAgICAgICAidHlwZSI6IDIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICJuYW1lIjogIlYiLAogICAgICAgICAgICAgICJ0eXBlIjogMAogICAgICAgICAgICB9CiAgICAgICAgICBdLAogICAgICAgICAgInBhdGgiOiBbImlua19zdG9yYWdlIiwgImxhenkiLCAibWFwcGluZyIsICJNYXBwaW5nIl0KICAgICAgICB9CiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiaWQiOiAyLAogICAgICAgICJ0eXBlIjogewogICAgICAgICAgImRlZiI6IHsKICAgICAgICAgICAgImNvbXBvc2l0ZSI6IHsKICAgICAgICAgICAgICAiZmllbGRzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAidHlwZSI6IDMsCiAgICAgICAgICAgICAgICAgICJ0eXBlTmFtZSI6ICJbdTg7IDMyXSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAicGF0aCI6IFsiaW5rX2VudiIsICJ0eXBlcyIsICJBY2NvdW50SWQiXQogICAgICAgIH0KICAgICAgfSwKICAgICAgewogICAgICAgICJpZCI6IDMsCiAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAiZGVmIjogewogICAgICAgICAgICAiYXJyYXkiOiB7CiAgICAgICAgICAgICAgImxlbiI6IDMyLAogICAgICAgICAgICAgICJ0eXBlIjogNAogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9LAogICAgICB7CiAgICAgICAgImlkIjogNCwKICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICJkZWYiOiB7CiAgICAgICAgICAgICJwcmltaXRpdmUiOiAidTgiCiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9LAogICAgICB7CiAgICAgICAgImlkIjogNSwKICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICJkZWYiOiB7CiAgICAgICAgICAgICJjb21wb3NpdGUiOiB7CiAgICAgICAgICAgICAgImZpZWxkcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgInR5cGUiOiAzLAogICAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiW3U4OyAzMl0iCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXQogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgInBhdGgiOiBbImlua19wcmltaXRpdmVzIiwgIktleSJdCiAgICAgICAgfQogICAgICB9LAogICAgICB7CiAgICAgICAgImlkIjogNiwKICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICJkZWYiOiB7CiAgICAgICAgICAgICJjb21wb3NpdGUiOiB7CiAgICAgICAgICAgICAgImZpZWxkcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgIm5hbWUiOiAib2Zmc2V0X2tleSIsCiAgICAgICAgICAgICAgICAgICJ0eXBlIjogNSwKICAgICAgICAgICAgICAgICAgInR5cGVOYW1lIjogIktleSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAicGFyYW1zIjogWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgIm5hbWUiOiAiSyIsCiAgICAgICAgICAgICAgInR5cGUiOiA3CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAibmFtZSI6ICJWIiwKICAgICAgICAgICAgICAidHlwZSI6IDAKICAgICAgICAgICAgfQogICAgICAgICAgXSwKICAgICAgICAgICJwYXRoIjogWyJpbmtfc3RvcmFnZSIsICJsYXp5IiwgIm1hcHBpbmciLCAiTWFwcGluZyJdCiAgICAgICAgfQogICAgICB9LAogICAgICB7CiAgICAgICAgImlkIjogNywKICAgICAgICAidHlwZSI6IHsKICAgICAgICAgICJkZWYiOiB7CiAgICAgICAgICAgICJ0dXBsZSI6IFsyLCAyXQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSwKICAgICAgewogICAgICAgICJpZCI6IDgsCiAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAiZGVmIjogewogICAgICAgICAgICAidmFyaWFudCI6IHsKICAgICAgICAgICAgICAidmFyaWFudHMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJmaWVsZHMiOiBbCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiA5CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAiaW5kZXgiOiAwLAogICAgICAgICAgICAgICAgICAibmFtZSI6ICJPayIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJmaWVsZHMiOiBbCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAxMAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAgICAgImluZGV4IjogMSwKICAgICAgICAgICAgICAgICAgIm5hbWUiOiAiRXJyIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICJwYXJhbXMiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAibmFtZSI6ICJUIiwKICAgICAgICAgICAgICAidHlwZSI6IDkKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICJuYW1lIjogIkUiLAogICAgICAgICAgICAgICJ0eXBlIjogMTAKICAgICAgICAgICAgfQogICAgICAgICAgXSwKICAgICAgICAgICJwYXRoIjogWyJSZXN1bHQiXQogICAgICAgIH0KICAgICAgfSwKICAgICAgewogICAgICAgICJpZCI6IDksCiAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAiZGVmIjogewogICAgICAgICAgICAidHVwbGUiOiBbXQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSwKICAgICAgewogICAgICAgICJpZCI6IDEwLAogICAgICAgICJ0eXBlIjogewogICAgICAgICAgImRlZiI6IHsKICAgICAgICAgICAgInZhcmlhbnQiOiB7CiAgICAgICAgICAgICAgInZhcmlhbnRzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAiaW5kZXgiOiAwLAogICAgICAgICAgICAgICAgICAibmFtZSI6ICJJbnN1ZmZpY2llbnRCYWxhbmNlIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImluZGV4IjogMSwKICAgICAgICAgICAgICAgICAgIm5hbWUiOiAiSW5zdWZmaWNpZW50QWxsb3dhbmNlIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICJwYXRoIjogWyJlcmMyMCIsICJlcmMyMCIsICJFcnJvciJdCiAgICAgICAgfQogICAgICB9LAogICAgICB7CiAgICAgICAgImlkIjogMTEsCiAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAiZGVmIjogewogICAgICAgICAgICAidmFyaWFudCI6IHsKICAgICAgICAgICAgICAidmFyaWFudHMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJpbmRleCI6IDAsCiAgICAgICAgICAgICAgICAgICJuYW1lIjogIk5vbmUiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAiZmllbGRzIjogWwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogMgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAgICAgImluZGV4IjogMSwKICAgICAgICAgICAgICAgICAgIm5hbWUiOiAiU29tZSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAicGFyYW1zIjogWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgIm5hbWUiOiAiVCIsCiAgICAgICAgICAgICAgInR5cGUiOiAyCiAgICAgICAgICAgIH0KICAgICAgICAgIF0sCiAgICAgICAgICAicGF0aCI6IFsiT3B0aW9uIl0KICAgICAgICB9CiAgICAgIH0KICAgIF0KICB9Cn0K' - describe('ContractService', () => { let service: ContractsService let repo: Repository + let api: ApiPromise beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ @@ -28,6 +33,8 @@ describe('ContractService', () => { { provide: getRepositoryToken(Contract), useValue: { + find: jest.fn().mockResolvedValue(mockContracts), + findOne: jest.fn().mockResolvedValue(mockContracts[0]), findOneBy: jest.fn().mockResolvedValue(mockContracts[0]), save: jest.fn().mockResolvedValue(true), }, @@ -38,6 +45,13 @@ describe('ContractService', () => { service = module.get(ContractsService) repo = module.get>(getRepositoryToken(Contract)) + + const MockedApi = ApiPromise as jest.MockedClass + MockedApi.create = jest.fn().mockResolvedValue(apiMock) + api = await MockedApi.create() + + const mockedConnect = connect as jest.MockedFunction + mockedConnect.mockResolvedValue(api) }) it('should be defined', () => { @@ -58,9 +72,23 @@ describe('ContractService', () => { }) }) + describe('fetchContracts', () => { + it('should get a list of contracts', () => { + const repoSpy = jest.spyOn(repo, 'find') + expect(service.fetchContracts({ skip: 0, take: 5 })).resolves.toEqual(mockContracts) + expect(repoSpy).toBeCalledWith({ skip: 0, take: 5 }) + }) + + it('it should return empty list for skip to high', () => { + const repoSpy = jest.spyOn(repo, 'find').mockResolvedValueOnce([]) + expect(service.fetchContracts({ skip: 10000, take: 5 })).resolves.toEqual([]) + expect(repoSpy).toBeCalledWith({ skip: 10000, take: 5 }) + }) + }) + describe('uploadMetadata', () => { it('should update the metada for a contract', () => { - expect(service.uploadMetadata(mockContracts[0] as any, base64metadata)).resolves.toEqual(true) + expect(service.uploadMetadata(mockContracts[0] as any, BASE64_METADATA)).resolves.toEqual(true) expect(repo.save).toBeCalledTimes(1) }) @@ -71,4 +99,15 @@ describe('ContractService', () => { expect(service.uploadMetadata(mockContracts[0] as any, '1234')).resolves.toEqual(false) }) }) + + describe('getContractQueries', () => { + it.skip('should get a contract with queries', async () => { + const repoSpy = jest.spyOn(repo, 'findOne').mockResolvedValueOnce(mockContractQueries as unknown as Contract) + const contract = await service.getContractQueries(mockContractQueries.address) + expect(contract.address).toEqual(mockContractQueries.address) + expect(contract.metadata).toEqual(mockContractQueries.metadata) + expect(contract.queries).toEqual(mockContractQueries.queries) + expect(repoSpy).toBeCalledWith(mockContractQueries.address) + }) + }) }) diff --git a/src/contracts/contracts.service.ts b/src/contracts/contracts.service.ts index de0b511..2d8d3dc 100644 --- a/src/contracts/contracts.service.ts +++ b/src/contracts/contracts.service.ts @@ -1,8 +1,12 @@ import { Injectable, NotFoundException } from '@nestjs/common' import { InjectRepository } from '@nestjs/typeorm' +import { Abi, ContractPromise } from '@polkadot/api-contract' import { InjectPinoLogger, PinoLogger } from 'nestjs-pino' import { Repository } from 'typeorm' -import { Contract } from './entity/contract.entity' +import { connect } from '../utils' +import { FetchContractsInput } from './dtos/fetch-contracts.input' +import { Contract, ContractQuery } from './entity/contract.entity' +const WS_PROVIDER = process.env.WS_PROVIDER || 'ws://127.0.0.1:9944' @Injectable() export class ContractsService { @@ -21,6 +25,14 @@ export class ContractsService { return contract } + async fetchContracts(args: FetchContractsInput): Promise { + const { skip, take } = args + return this.contractRepository.find({ + skip, + take, + }) + } + async uploadMetadata(contract: Contract, metadata: string): Promise { try { const buff = Buffer.from(metadata, 'base64') @@ -33,4 +45,29 @@ export class ContractsService { } return true } + + async getContractQueries(contractAddress: string): Promise { + const api = await connect(WS_PROVIDER) + const contract = await this.findOne(contractAddress) + const { address, metadata } = contract + if (!address || !metadata) { + this.logger.warn('Contract address or metadata not found') + contract.queries = [] + return contract + } + const abi = new Abi(metadata) + const contractPromise = new ContractPromise(api, abi, address) + const contractQueries: ContractQuery[] = [] + Object.keys(contractPromise.query).map((k) => { + const { method, docs, args, identifier } = contractPromise.query[k].meta + contractQueries.push({ + method, + docs, + args, + name: (identifier[0].toUpperCase() + identifier.substring(1)).replace('_', ' '), + }) + }) + contract.queries = contractQueries + return contract + } } diff --git a/src/contracts/dtos/fetch-contracts.input.ts b/src/contracts/dtos/fetch-contracts.input.ts new file mode 100644 index 0000000..8d37142 --- /dev/null +++ b/src/contracts/dtos/fetch-contracts.input.ts @@ -0,0 +1,10 @@ +import { Field, Int, ArgsType } from '@nestjs/graphql' + +@ArgsType() +export class FetchContractsInput { + @Field(/* istanbul ignore next */ () => Int) + skip? = 0 + + @Field(/* istanbul ignore next */ () => Int) + take? = 20 +} diff --git a/src/contracts/entity/contract.entity.ts b/src/contracts/entity/contract.entity.ts index bedbedc..25ade83 100644 --- a/src/contracts/entity/contract.entity.ts +++ b/src/contracts/entity/contract.entity.ts @@ -1,4 +1,5 @@ import { Field, ObjectType } from '@nestjs/graphql' +import { AbiParam } from '@polkadot/api-contract/types' import { BaseEntity, Column, CreateDateColumn, Entity, Index, OneToMany, PrimaryColumn } from 'typeorm' import { Event } from '../../events/entity/event.entity' @@ -19,8 +20,26 @@ export class Contract extends BaseEntity { }) events!: Event[] + @Field(/* istanbul ignore next */ () => [ContractQuery]) + queries?: ContractQuery[] + @CreateDateColumn({ default: /* istanbul ignore next */ () => 'NOW()', }) createdDate!: Date } + +@ObjectType() +export class ContractQuery { + @Field(/* istanbul ignore next */ () => String) + name!: string + + @Field(/* istanbul ignore next */ () => String) + method!: string + + @Field(/* istanbul ignore next */ () => [String]) + args!: AbiParam[] | string[] + + @Field(/* istanbul ignore next */ () => [String]) + docs!: string[] +} diff --git a/src/events/dtos/fetch-events.input.ts b/src/events/dtos/fetch-events.input.ts index 009115a..839a4d0 100644 --- a/src/events/dtos/fetch-events.input.ts +++ b/src/events/dtos/fetch-events.input.ts @@ -8,6 +8,9 @@ export class FetchEventsInput { @Field(/* istanbul ignore next */ () => Int, { nullable: true }) take? = 20 + @Field(/* istanbul ignore next */ () => Boolean) + orderAsc?: boolean = false + @Field(/* istanbul ignore next */ () => String, { nullable: true }) contract?: string diff --git a/src/events/entity/event.entity.ts b/src/events/entity/event.entity.ts index 584736b..46bf318 100644 --- a/src/events/entity/event.entity.ts +++ b/src/events/entity/event.entity.ts @@ -1,4 +1,5 @@ -import { Field, ObjectType } from '@nestjs/graphql' +import { Field, Float, ObjectType } from '@nestjs/graphql' +import { DecodedEvent } from '@polkadot/api-contract/types' import { Codec } from '@polkadot/types-codec/types' import { IEventData } from '@polkadot/types/types' import { BaseEntity, Column, Entity, JoinColumn, ManyToOne, PrimaryColumn, CreateDateColumn } from 'typeorm' @@ -39,6 +40,10 @@ export class Event extends BaseEntity { @Field(/* istanbul ignore next */ () => String) topics!: string + @Column('bigint') + @Field(/* istanbul ignore next */ () => Float) + timestamp!: number + @ManyToOne( /* istanbul ignore next */ () => Transaction, /* istanbul ignore next */ (transaction: Transaction) => transaction.events, @@ -54,6 +59,10 @@ export class Event extends BaseEntity { @Field(/* istanbul ignore next */ () => String, { nullable: true }) data?: Codec[] & IEventData + @Column({ type: 'jsonb', nullable: true, default: {} }) + @Field(/* istanbul ignore next */ () => String, { nullable: true }) + decodedData?: DecodedEvent + @CreateDateColumn({ default: /* istanbul ignore next */ () => 'NOW()', }) diff --git a/src/events/events.resolver.spec.ts b/src/events/events.resolver.spec.ts index fa6cf76..aa83047 100644 --- a/src/events/events.resolver.spec.ts +++ b/src/events/events.resolver.spec.ts @@ -1,6 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing' -import { mockDecodedEvent, mockEvents } from '../../mocks/events-mocks' +import { mockDecodedEvent, mockEvents, mockFormattedEvent } from '../../mocks/events-mocks' import { EventsService } from '../events/events.service' +import { FetchEventsInput } from './dtos/fetch-events.input' import { EventsResolver } from './events.resolver' describe('EventsResolver', () => { @@ -14,8 +15,10 @@ describe('EventsResolver', () => { { provide: EventsService, useFactory: jest.fn(() => ({ + findById: () => mockEvents[0], fetchEvents: () => mockEvents, decodeEvents: () => mockDecodedEvent, + formatDecoded: () => mockFormattedEvent, })), }, ], @@ -30,7 +33,7 @@ describe('EventsResolver', () => { }) describe('getEvents', () => { - it('should get a transaction by hash', async () => { + it('should get events by contract address', async () => { const events = await resolver.getEvents({ skip: 0, take: 10, @@ -40,15 +43,74 @@ describe('EventsResolver', () => { }) }) + describe('getEvent', () => { + it('should get the event by id', async () => { + const event = await resolver.getEvent(mockEvents[0].id) + expect(event).toEqual(mockEvents[0]) + }) + }) + describe('decodeEvents', () => { it('should return decoded events for a contract address', () => { - expect(resolver.decodeEvents(mockEvents[0].contractAddress)).resolves.toEqual(JSON.stringify(mockDecodedEvent)) + const args: FetchEventsInput = { + skip: 0, + take: 10, + contract: mockEvents[0].contractAddress, + } + expect(resolver.decodeEvents(args)).resolves.toEqual(JSON.stringify(mockDecodedEvent)) }) it('should return an error message', () => { + const args: FetchEventsInput = { + skip: 0, + take: 10, + contract: mockEvents[0].contractAddress, + } jest.spyOn(eventService, 'decodeEvents').mockRejectedValue(Promise.reject('Contract not found')) + expect(resolver.decodeEvents(args)).rejects.toBe('Contract not found') + }) + }) + + describe('decodeEvent', () => { + it('should return a decoded event', () => { + const { contractAddress, id } = mockEvents[0] + expect(resolver.decodeEvent(contractAddress, id)).resolves.toEqual(JSON.stringify(mockDecodedEvent)) + }) + + it('should return an error message', () => { + const { contractAddress, id } = mockEvents[0] + jest.spyOn(eventService, 'findById').mockRejectedValue(Promise.reject('Failed to find event')) + expect(resolver.decodeEvent(contractAddress, id)).rejects.toBe('Failed to find event') + }) + + it('should return an error message', async () => { + const { contractAddress, id } = mockEvents[0] + jest.spyOn(eventService, 'findById').mockResolvedValueOnce(Promise.resolve(null)) + try { + await resolver.decodeEvent(contractAddress, id) + } catch (error) { + expect((error as Error).message).toEqual('Event not found') + } + }) + }) + + describe('get decoded data', () => { + it('should return the decoded (empty) data from an event', () => { + expect(resolver.decodedData(mockEvents[0] as any)).resolves.toEqual('') + }) + + it('should return the decoded data from an event', () => { + expect(resolver.decodedData(mockEvents[1] as any)).resolves.toEqual(JSON.stringify(mockDecodedEvent)) + }) + }) + + describe('get formatted data', () => { + it('should return the formatted data (empty) from an event', () => { + expect(resolver.formattedData(mockEvents[0] as any)).resolves.toEqual('') + }) - expect(resolver.decodeEvents(mockEvents[0].contractAddress)).rejects.toBe('Contract not found') + it('should return the formatted data from an event', () => { + expect(resolver.formattedData(mockEvents[1] as any)).resolves.toEqual(JSON.stringify(mockFormattedEvent)) }) }) diff --git a/src/events/events.resolver.ts b/src/events/events.resolver.ts index 252d599..3ab6753 100644 --- a/src/events/events.resolver.ts +++ b/src/events/events.resolver.ts @@ -1,4 +1,4 @@ -import { Args, Parent, Query, ResolveField, Resolver } from '@nestjs/graphql' +import { Args, Mutation, Parent, Query, ResolveField, Resolver } from '@nestjs/graphql' import { FetchEventsInput } from './dtos/fetch-events.input' import { Event } from './entity/event.entity' import { EventsService } from './events.service' @@ -11,12 +11,33 @@ export class EventsResolver { return this.eventsService.fetchEvents(args) } - @Query(/* istanbul ignore next */ () => String) - async decodeEvents(@Args('contractAddress', { type: () => String }) contractAddress: string) { + @Query(/* istanbul ignore next */ () => Event) + async getEvent(@Args('id', { type: () => String }) id: string) { + return this.eventsService.findById(id) + } + + @Mutation(/* istanbul ignore next */ () => String) + async decodeEvents(@Args() args: FetchEventsInput) { try { - const events = await this.eventsService.fetchEvents({ contract: contractAddress as string }) - const response = await this.eventsService.decodeEvents(events, contractAddress as string) + const events = await this.eventsService.fetchEvents(args) + const decodedEvents = await this.eventsService.decodeEvents(events, args.contract as string) + return JSON.stringify(decodedEvents) + } catch (error) { + return error + } + } + @Mutation(/* istanbul ignore next */ () => String) + async decodeEvent( + @Args('contractAddress', { type: () => String }) contractAddress: string, + @Args('id', { type: () => String }) id: string, + ) { + try { + const event = await this.eventsService.findById(id) + if (!event) { + throw new Error('Event not found') + } + const response = await this.eventsService.decodeEvents([event], contractAddress as string) return JSON.stringify(response) } catch (error) { return error @@ -28,4 +49,22 @@ export class EventsResolver { const { data } = event return JSON.stringify(data) } + + @ResolveField('decodedData', /* istanbul ignore next */ () => String) + async decodedData(@Parent() event: Event) { + const { decodedData } = event + if (!decodedData) { + return '' + } + return JSON.stringify(decodedData) + } + + @ResolveField('formattedData', /* istanbul ignore next */ () => String) + async formattedData(@Parent() event: Event) { + const { decodedData } = event + if (!decodedData) { + return '' + } + return JSON.stringify(this.eventsService.formatDecoded(decodedData)) + } } diff --git a/src/events/events.service.spec.ts b/src/events/events.service.spec.ts index 17bf4e4..4037943 100644 --- a/src/events/events.service.spec.ts +++ b/src/events/events.service.spec.ts @@ -24,6 +24,7 @@ describe('EventsService', () => { { provide: getRepositoryToken(Event), useValue: { + findOne: jest.fn().mockResolvedValue(null), findOneBy: jest.fn().mockResolvedValue(mockEvents[0]), find: jest.fn().mockResolvedValue(mockEvents), create: jest.fn().mockResolvedValue(mockEvents[0]), @@ -113,8 +114,13 @@ describe('EventsService', () => { .spyOn(repo, 'save') .mockResolvedValueOnce(mockEvents[0] as never) .mockResolvedValueOnce(mockEvents[1] as never) - - const events = await service.createEventsFromRecords(mockRecords as any, 1, mockTransaction.hash) + jest.spyOn(repo, 'findOne').mockResolvedValueOnce(null).mockResolvedValueOnce(null) + const events = await service.createEventsFromRecords( + mockRecords as any, + 1, + mockTransaction.hash, + mockTransaction.timestamp, + ) expect(events).toStrictEqual(mockEvents) }) @@ -131,7 +137,12 @@ describe('EventsService', () => { .mockResolvedValueOnce(mockEvents[0] as never) .mockResolvedValueOnce(mockEvents[1] as never) - const events = await service.createEventsFromRecords(mockRecords as any, 1, mockTransaction.hash) + const events = await service.createEventsFromRecords( + mockRecords as any, + 1, + mockTransaction.hash, + mockTransaction.timestamp, + ) expect(events).toStrictEqual(mockEvents) }) diff --git a/src/events/events.service.ts b/src/events/events.service.ts index bfc6ae5..76f36e1 100644 --- a/src/events/events.service.ts +++ b/src/events/events.service.ts @@ -5,6 +5,7 @@ import { DecodedEvent } from '@polkadot/api-contract/types' import { Vec } from '@polkadot/types-codec' import { FrameSystemEventRecord } from '@polkadot/types/lookup' import { numberToU8a } from '@polkadot/util' +import { InjectPinoLogger, PinoLogger } from 'nestjs-pino' import { Repository } from 'typeorm' import { fromString } from 'uuidv4' import { Contract } from '../contracts/entity/contract.entity' @@ -14,6 +15,8 @@ import { Event } from './entity/event.entity' @Injectable() export class EventsService { constructor( + @InjectPinoLogger(EventsService.name) + private readonly logger: PinoLogger, @InjectRepository(Event) private readonly eventRepository: Repository, @InjectRepository(Contract) @@ -21,8 +24,13 @@ export class EventsService { ) {} async fetchEvents(args: FetchEventsInput): Promise { - const { skip, take, contract, transactionHash } = args - return this.eventRepository.find({ skip, take, where: { contract: { address: contract }, transactionHash } }) + const { skip, take, contract, transactionHash, orderAsc } = args + return this.eventRepository.find({ + skip, + take, + where: { contract: { address: contract }, transactionHash }, + order: { timestamp: orderAsc ? 'ASC' : 'DESC' }, + }) } async findById(id: string): Promise { @@ -33,6 +41,7 @@ export class EventsService { records: Vec, extrinsicIndex: number, transactionHash: string, + timestamp: number, ): Promise { const events = records.filter(({ phase }) => phase.isApplyExtrinsic && phase.asApplyExtrinsic.eq(extrinsicIndex)) const contractEmittedEvents = events.filter((record) => record?.event?.method === 'ContractEmitted') @@ -66,16 +75,37 @@ export class EventsService { topics: topics.toString(), data, transactionHash: transactionHash.toString().toLowerCase(), + timestamp, }) }) - return Promise.all(eventsToSave.map((event) => this.eventRepository.save(event))) + return Promise.all( + eventsToSave.map(async (e) => { + let event = (await this.eventRepository.findOne({ where: { id: e.id } })) as Event + if (!event) { + event = (await this.eventRepository.save(e)) as Event + } + return event + }), + ) } async decodeEvents(events: Event[], contractAddress: string) { const contract = await this.contractRespository.findOneBy({ address: contractAddress }) if (!contract) throw new Error('Contract not found') if (!contract.metadata) throw new Error('Upload the metadata first') - return events.map((event) => this.decodeContractEmittedEvent(contract.metadata as string, event.data)) + return Promise.all( + events.map(async (event) => { + try { + const decodedEvent = this.decodeContractEmittedEvent(contract.metadata as string, event.data) + event.decodedData = decodedEvent + await this.eventRepository.update(event.id, event) + return { decodedData: decodedEvent, formattedData: this.formatDecoded(decodedEvent) } + } catch (error) { + this.logger.error(error) + return { message: "Can't decode event", error } + } + }), + ) } decodeContractEmittedEvent(abi: string | Record, data: any): DecodedEvent { diff --git a/src/schema.graphql b/src/schema.graphql index fab45c3..c2ae06b 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -3,61 +3,81 @@ # ------------------------------------------------------ type Block { + encodedLength: Float! hash: String! number: Int! parentHash: String! + timestamp: Float! transactions: [Transaction!]! } type Contract { address: String! events: [Event!]! + hasMetadata: Boolean! metadata: String + queries: [ContractQuery!]! +} + +type ContractQuery { + args: [String!]! + docs: [String!]! + method: String! + name: String! } type Event { data: String + decodedData: String + formattedData: String! id: String! index: String! method: String! section: String! + timestamp: Float! topics: String! transactionHash: String } type Mutation { + decodeEvent(contractAddress: String!, id: String!): String! + decodeEvents(contract: String, orderAsc: Boolean = false, skip: Int = 0, take: Int = 20, transactionHash: String): String! uploadMetadata(contractAddress: String!, metadata: String!): Boolean! } type Query { - decodeEvents(contractAddress: String!): String! getBlock(hash: String!): Block! - getBlocks(skip: Int = 0, take: Int = 10): [Block!]! + getBlocks(orderAsc: Boolean = false, orderByNumber: Boolean = false, skip: Int = 0, take: Int = 10): [Block!]! getContract(address: String!): Contract! - getEvents(contract: String, skip: Int = 0, take: Int = 20, transactionHash: String): [Event!]! + getContractQueries(address: String!): Contract! + getContracts(skip: Int = 0, take: Int = 20): [Contract!]! + getEvent(id: String!): Event! + getEvents(contract: String, orderAsc: Boolean = false, skip: Int = 0, take: Int = 20, transactionHash: String): [Event!]! getTransaction(hash: String!): Transaction! - getTransactions(blockHash: String, skip: Int = 0, take: Int = 20): [Transaction!]! + getTransactions(blockHash: String, orderAsc: Boolean = false, skip: Int = 0, take: Int = 20): [Transaction!]! + getTransactionsByContract(address: String!, orderAsc: Boolean = false, skip: Int = 0, take: Int = 10): [Transaction!]! status: String! + version: String! } type Transaction { + args: String blockHash: String + callIndex: String + decimals: String + encodedLength: Int + era: String events: [Event!]! - - """Transaction hash""" hash: String! method: String! - - """Transaction's nonce""" nonce: Int section: String! - - """Signature generated by the signer""" signature: String! - - """Address of the signer""" signer: String - - """Extra gas paid for the Tx as tip""" + ss58: String + timestamp: Float! tip: Int + tokens: String + type: Int + version: Int } \ No newline at end of file diff --git a/src/subscriptions/subscriptions.service.spec.ts b/src/subscriptions/subscriptions.service.spec.ts index 4df6153..34e0fca 100644 --- a/src/subscriptions/subscriptions.service.spec.ts +++ b/src/subscriptions/subscriptions.service.spec.ts @@ -4,12 +4,14 @@ import { apiMock } from '../../mocks/api-mock' import { mockBlock, mockBlocks } from '../../mocks/blocks-mocks' import { mockEvents } from '../../mocks/events-mocks' import { mockPinoService } from '../../mocks/pino-mocks' -import { mockExtrinsics, mockTransactions } from '../../mocks/transactions-mock' +import { mockExtrinsics, mockTimestamp, mockTransactions } from '../../mocks/transactions-mock' import { BlocksService } from '../blocks/blocks.service' import { EventsService } from '../events/events.service' import { TransactionsService } from '../transactions/transactions.service' +import { connect } from '../utils' import { SubscriptionsService } from './subscriptions.service' jest.mock('@polkadot/api') +jest.mock('../utils') describe('subscriptionsService', () => { let service: SubscriptionsService @@ -20,6 +22,9 @@ describe('subscriptionsService', () => { const MockedApi = ApiPromise as jest.MockedClass MockedApi.create = jest.fn().mockResolvedValue(apiMock) api = await MockedApi.create() + + const mockedConnect = connect as jest.MockedFunction + mockedConnect.mockResolvedValue(api) }) beforeEach(async () => { @@ -58,21 +63,22 @@ describe('subscriptionsService', () => { }) describe('onModuleInit', () => { - it('should show an error message', async () => { + it('should show an error message', () => { try { - jest.spyOn(service, 'syncBlocks').mockResolvedValue(Promise.reject('grcp error')) + jest.spyOn(service, 'syncBlocks').mockImplementation(() => { + throw new Error('grcp error') + }) - await service.onModuleInit() + service.onModuleInit() fail("Shouldn't reach this point") } catch (error) { - expect(error).toBe('grcp error') + expect((error as Error).message).toBe('grcp error') } }) }) describe('syncBlocks', () => { it('should load all blocks', async () => { - jest.spyOn(SubscriptionsService, 'connect').mockImplementation(() => Promise.resolve(api)) jest.spyOn(blockService, 'getLastBlock').mockResolvedValue({ ...mockBlock, number: 20 } as any) jest.spyOn(service, 'subscribeNewHeads').mockImplementation(() => Promise.resolve([]) as any) jest @@ -88,7 +94,6 @@ describe('subscriptionsService', () => { }) it('should show already sync message', async () => { - jest.spyOn(SubscriptionsService, 'connect').mockImplementation(() => Promise.resolve(api)) jest.spyOn(blockService, 'getLastBlock').mockResolvedValue({ ...mockBlock, number: 100 } as any) jest.spyOn(service, 'subscribeNewHeads').mockImplementation(() => Promise.resolve([]) as any) @@ -97,6 +102,18 @@ describe('subscriptionsService', () => { expect(result).toBe(undefined) expect(blockService.getLastBlock).toBeCalledTimes(1) }) + + it('should show fail', async () => { + jest.spyOn(blockService, 'getLastBlock').mockResolvedValue({ ...mockBlock, number: 20 } as any) + jest.spyOn(service, 'subscribeNewHeads').mockImplementation(() => Promise.resolve([]) as any) + jest.spyOn(service, 'processBlock').mockRejectedValueOnce(new Error('Failed to process block')) + try { + await service.syncBlocks() + } catch (error) { + expect(blockService.getLastBlock).toBeCalledTimes(1) + expect((error as Error).message).toBe('Failed to process block') + } + }) }) describe('registerBlockData', () => { @@ -130,6 +147,7 @@ describe('subscriptionsService', () => { }, extrinsics: mockExtrinsics, records: [], + timestamp: mockTimestamp, }), ) }) diff --git a/src/subscriptions/subscriptions.service.ts b/src/subscriptions/subscriptions.service.ts index af30cb6..4b0139c 100644 --- a/src/subscriptions/subscriptions.service.ts +++ b/src/subscriptions/subscriptions.service.ts @@ -2,13 +2,14 @@ import { Injectable, OnModuleInit } from '@nestjs/common' import '@polkadot/api-augment' -import { ApiPromise, WsProvider } from '@polkadot/api' +import { ApiPromise } from '@polkadot/api' import { BlockHash, Header } from '@polkadot/types/interfaces' import { InjectPinoLogger, PinoLogger } from 'nestjs-pino' import PQueue from 'p-queue' import { BlocksService } from '../blocks/blocks.service' import { EventsService } from '../events/events.service' import { TransactionsService } from '../transactions/transactions.service' +import { connect } from '../utils' const retry = require('async-await-retry') const FIRST_BLOCK_TO_LOAD = Number(process.env.FIRST_BLOCK_TO_LOAD) || 0 @@ -26,24 +27,18 @@ export class SubscriptionsService implements OnModuleInit { private readonly eventsService: EventsService, ) {} - async onModuleInit(): Promise { + onModuleInit(): void { try { this.logger.info('Subscribing to new heads...') - await this.syncBlocks() + this.syncBlocks() } catch (error) { this.logger.error({ error }, 'Error while processing blocks.') throw error } } - static async connect(): Promise { - const provider = new WsProvider(WS_PROVIDER) - return ApiPromise.create({ provider }) - } - async syncBlocks() { - const api = await SubscriptionsService.connect() - + const api = await connect(WS_PROVIDER) const lastDBBlockNumber = (await this.blocksService.getLastBlock())?.number || 0 const lastBlockNumber = (await api.rpc.chain.getHeader()).number.toNumber() const loadFromBlockNumber = LOAD_ALL_BLOCKS ? FIRST_BLOCK_TO_LOAD : lastDBBlockNumber @@ -83,8 +78,11 @@ export class SubscriptionsService implements OnModuleInit { async getBlockData(api: ApiPromise, hash: BlockHash) { const [block, records] = await Promise.all([api.rpc.chain.getBlock(hash), api.query.system.events.at(hash)]) + const encodedLength = block.encodedLength const { header, extrinsics } = block.block || {} - return { header, extrinsics, records } + const timestampArgs = extrinsics.map((e) => e.method).find((m) => m.section === 'timestamp' && m.method === 'set') + const timestamp = Number(timestampArgs?.args[0].toString()) || Date.now() + return { header, extrinsics, records, timestamp, encodedLength } } getBlocksToLoad(from: number, to: number): number[] { @@ -116,11 +114,15 @@ export class SubscriptionsService implements OnModuleInit { } async registerBlockData(blockData: any) { - const { header, extrinsics, records } = blockData - const block = await this.blocksService.createFromHeader(header) - const transactions = await this.transactionsService.createTransactionsFromExtrinsics(extrinsics, block.hash) + const { header, extrinsics, records, timestamp, encodedLength } = blockData + const block = await this.blocksService.createFromHeader(header, timestamp, encodedLength) + const transactions = await this.transactionsService.createTransactionsFromExtrinsics( + extrinsics, + block.hash, + timestamp, + ) for (const [index, tx] of transactions.entries()) { - await this.eventsService.createEventsFromRecords(records, index, tx.hash) + await this.eventsService.createEventsFromRecords(records, index, tx.hash, timestamp) } return block } diff --git a/src/transactions/dtos/fetch-transactions-by-contract.input.ts b/src/transactions/dtos/fetch-transactions-by-contract.input.ts new file mode 100644 index 0000000..ef83c7b --- /dev/null +++ b/src/transactions/dtos/fetch-transactions-by-contract.input.ts @@ -0,0 +1,16 @@ +import { Field, Int, ArgsType } from '@nestjs/graphql' + +@ArgsType() +export class FetchTransactionsByContractInput { + @Field(/* istanbul ignore next */ () => String) + address: string | undefined + + @Field(/* istanbul ignore next */ () => Int) + skip? = 0 + + @Field(/* istanbul ignore next */ () => Int) + take? = 10 + + @Field(/* istanbul ignore next */ () => Boolean) + orderAsc?: boolean = false +} diff --git a/src/transactions/dtos/fetch-transactions.input.ts b/src/transactions/dtos/fetch-transactions.input.ts index 8312501..f4b9e0b 100644 --- a/src/transactions/dtos/fetch-transactions.input.ts +++ b/src/transactions/dtos/fetch-transactions.input.ts @@ -10,4 +10,7 @@ export class FetchTransactionsInput { @Field(/* istanbul ignore next */ () => String, { nullable: true }) blockHash?: string + + @Field(/* istanbul ignore next */ () => Boolean) + orderAsc?: boolean = false } diff --git a/src/transactions/entity/transaction.entity.ts b/src/transactions/entity/transaction.entity.ts index f75e0be..75cadbf 100644 --- a/src/transactions/entity/transaction.entity.ts +++ b/src/transactions/entity/transaction.entity.ts @@ -1,4 +1,4 @@ -import { Field, Int, ObjectType } from '@nestjs/graphql' +import { Field, Float, Int, ObjectType } from '@nestjs/graphql' import { BaseEntity, Column, @@ -20,7 +20,7 @@ export class Transaction extends BaseEntity { @PrimaryColumn({ unique: true, }) - @Field(/* istanbul ignore next */ () => String, { description: 'Transaction hash' }) + @Field(/* istanbul ignore next */ () => String) hash!: string @Column() @@ -29,11 +29,15 @@ export class Transaction extends BaseEntity { @Column() @Field(/* istanbul ignore next */ () => String) - method!: string + section!: string @Column() @Field(/* istanbul ignore next */ () => String) - section!: string + method!: string + + @Column('bigint') + @Field(/* istanbul ignore next */ () => Float) + timestamp!: number @ManyToOne(/* istanbul ignore next */ () => Block, /* istanbul ignore next */ (block: Block) => block.transactions, { onDelete: 'SET NULL', @@ -48,27 +52,59 @@ export class Transaction extends BaseEntity { events!: Event[] @Column() - @Field(/* istanbul ignore next */ () => String, { description: 'Signature generated by the signer' }) + @Field(/* istanbul ignore next */ () => String) signature?: string @Column() - @Field(/* istanbul ignore next */ () => String, { description: 'Address of the signer', nullable: true }) + @Field(/* istanbul ignore next */ () => String, { nullable: true }) signer?: string @Column('int') - @Field(/* istanbul ignore next */ () => Int, { description: "Transaction's nonce", nullable: true }) + @Field(/* istanbul ignore next */ () => Int, { nullable: true }) nonce?: number @Column('int') - @Field(/* istanbul ignore next */ () => Int, { description: 'Extra gas paid for the Tx as tip', nullable: true }) + @Field(/* istanbul ignore next */ () => Int, { nullable: true }) tip?: number + @Column('int') + @Field(/* istanbul ignore next */ () => Int, { nullable: true }) + version?: number + + @Column('int') + @Field(/* istanbul ignore next */ () => Int, { nullable: true }) + type?: number + + @Column('int') + @Field(/* istanbul ignore next */ () => Int, { nullable: true }) + encodedLength?: number + + @Column() + @Field(/* istanbul ignore next */ () => String, { nullable: true }) + callIndex?: string + + @Column() + @Field(/* istanbul ignore next */ () => String, { nullable: true }) + decimals?: string + + @Column() + @Field(/* istanbul ignore next */ () => String, { nullable: true }) + ss58?: string + + @Column() + @Field(/* istanbul ignore next */ () => String, { nullable: true }) + tokens?: string + + @Column() + @Field(/* istanbul ignore next */ () => String, { nullable: true }) + era?: string + + @Column() + @Field(/* istanbul ignore next */ () => String, { nullable: true }) + args?: string + @CreateDateColumn({ default: /* istanbul ignore next */ () => 'NOW()', }) createdDate!: Date - // TODO: add this - //era?: GenericExtrinsicEra - // We are not storing this for now - //args: any } diff --git a/src/transactions/transactions.resolver.ts b/src/transactions/transactions.resolver.ts index bcf08b4..3f5d9ff 100644 --- a/src/transactions/transactions.resolver.ts +++ b/src/transactions/transactions.resolver.ts @@ -2,6 +2,7 @@ import { Args, Parent, Query, ResolveField, Resolver } from '@nestjs/graphql' import { FetchEventsInput } from '../events/dtos/fetch-events.input' import { Event } from '../events/entity/event.entity' import { EventsService } from '../events/events.service' +import { FetchTransactionsByContractInput } from './dtos/fetch-transactions-by-contract.input' import { FetchTransactionsInput } from './dtos/fetch-transactions.input' import { Transaction } from './entity/transaction.entity' import { TransactionsService } from './transactions.service' @@ -19,6 +20,11 @@ export class TransactionsResolver { return this.transactionsService.fetchTransactions(args) } + @Query(/* istanbul ignore next */ () => [Transaction]) + async getTransactionsByContract(@Args() args: FetchTransactionsByContractInput) { + return this.transactionsService.getTransactionsByContractAddress(args) + } + @ResolveField('events', /* istanbul ignore next */ () => [Event]) async getEvents(@Parent() transaction: Transaction) { const { hash } = transaction diff --git a/src/transactions/transactions.service.spec.ts b/src/transactions/transactions.service.spec.ts index a7394d2..b208ebe 100644 --- a/src/transactions/transactions.service.spec.ts +++ b/src/transactions/transactions.service.spec.ts @@ -3,7 +3,13 @@ import { Test, TestingModule } from '@nestjs/testing' import { getRepositoryToken } from '@nestjs/typeorm' import { Repository } from 'typeorm' import { mockPinoService } from '../../mocks/pino-mocks' -import { mockExtrinsics, mockSavedTransactions, mockTransaction, mockTransactions } from '../../mocks/transactions-mock' +import { + mockExtrinsics, + mockSavedTransactions, + mockTimestamp, + mockTransaction, + mockTransactions, +} from '../../mocks/transactions-mock' import { Transaction } from './entity/transaction.entity' import { TransactionsService } from './transactions.service' @@ -66,7 +72,7 @@ describe('TransactionsService', () => { .mockResolvedValueOnce(mockSavedTransactions[0]) .mockResolvedValueOnce(mockSavedTransactions[1]) const blockHash = '0xffcfae3ecc9ab7b79fc0cd451dad35477a32219b219b29584b968826ac04c1a1' - const savedTxs = await service.createTransactionsFromExtrinsics(mockExtrinsics as any, blockHash) + const savedTxs = await service.createTransactionsFromExtrinsics(mockExtrinsics as any, blockHash, mockTimestamp) mockSavedTransactions.forEach((tx, i) => { expect(savedTxs[i].hash).toEqual(tx.hash) expect(savedTxs[i].blockHash).toEqual(tx.blockHash) @@ -87,7 +93,7 @@ describe('TransactionsService', () => { .mockResolvedValueOnce(mockSavedTransactions[0]) .mockResolvedValueOnce(mockSavedTransactions[1]) const blockHash = '0xffcfae3ecc9ab7b79fc0cd451dad35477a32219b219b29584b968826ac04c1a1' - const savedTxs = await service.createTransactionsFromExtrinsics(mockExtrinsics as any, blockHash) + const savedTxs = await service.createTransactionsFromExtrinsics(mockExtrinsics as any, blockHash, mockTimestamp) mockSavedTransactions.forEach((tx, i) => { expect(savedTxs[i].hash).toEqual(tx.hash) expect(savedTxs[i].blockHash).toEqual(tx.blockHash) @@ -107,7 +113,7 @@ describe('TransactionsService', () => { try { jest.spyOn(repo, 'findOneBy').mockResolvedValue(Promise.reject("Can't connect to database")) const blockHash = '0xffcfae3ecc9ab7b79fc0cd451dad35477a32219b219b29584b968826ac04c1a1' - await service.createTransactionsFromExtrinsics(mockExtrinsics as any, blockHash) + await service.createTransactionsFromExtrinsics(mockExtrinsics as any, blockHash, mockTimestamp) fail("Shouldn't reach this point") } catch (error) { expect(error).toEqual("Can't connect to database") diff --git a/src/transactions/transactions.service.ts b/src/transactions/transactions.service.ts index 4672115..cea238c 100644 --- a/src/transactions/transactions.service.ts +++ b/src/transactions/transactions.service.ts @@ -3,9 +3,10 @@ import { Injectable, NotFoundException } from '@nestjs/common' import { InjectRepository } from '@nestjs/typeorm' import { GenericExtrinsic } from '@polkadot/types' import { Vec } from '@polkadot/types-codec' -import { AnyTuple } from '@polkadot/types-codec/types' +import { AnyTuple, ArgsDef } from '@polkadot/types-codec/types' import { InjectPinoLogger, PinoLogger } from 'nestjs-pino' import { Repository } from 'typeorm' +import { FetchTransactionsByContractInput } from './dtos/fetch-transactions-by-contract.input' import { FetchTransactionsInput } from './dtos/fetch-transactions.input' import { Transaction } from './entity/transaction.entity' const retry = require('async-await-retry') @@ -28,28 +29,57 @@ export class TransactionsService { } async fetchTransactions(args: FetchTransactionsInput): Promise { - const { skip, take, blockHash } = args - return this.transactionRepository.find({ skip, take, where: { blockHash } }) + const { skip, take, blockHash, orderAsc } = args + return this.transactionRepository.find({ + skip, + take, + where: { blockHash }, + order: { timestamp: orderAsc ? 'ASC' : 'DESC' }, + }) } async createTransactionsFromExtrinsics( extrinsics: Vec>, blockHash: string, + timestamp: number, ): Promise { return Promise.all( extrinsics.map(async (extrinsic) => { try { - const { hash: transactionHash, nonce, signature, signer, tip } = extrinsic - const { method, section } = extrinsic.method + const { + hash: transactionHash, + nonce, + signature, + signer, + encodedLength, + registry, + tip, + era, + version, + type, + callIndex, + } = extrinsic + const { method, section, args, argsDef } = extrinsic.method + const formattedArgs = this.formatArgs(args, argsDef) const tx = this.transactionRepository.create({ hash: transactionHash.toString().toLowerCase(), - method: method, - section: section, - nonce: nonce.toNumber(), + blockHash: blockHash.toLowerCase(), + section, + method, signature: signature.toString(), signer: signer.toString(), + nonce: nonce.toNumber(), tip: tip.toNumber(), - blockHash: blockHash.toLowerCase(), + timestamp, + version, + type: type, + encodedLength, + callIndex: callIndex?.toString(), + decimals: registry?.chainDecimals?.toString(), + ss58: registry?.chainSS58?.toString(), + tokens: registry?.chainTokens?.toString(), + era: JSON.stringify(era), + args: JSON.stringify(formattedArgs), }) const transaction = await retry( async () => { @@ -71,4 +101,26 @@ export class TransactionsService { }), ) } + + // This function creates a new object with the same keys as the argsDef object and the values from the args object + formatArgs(args: AnyTuple, argsDef: ArgsDef) { + if (!argsDef) return args + const formattedArgs: any = {} + Object.keys(argsDef).forEach((key: any, index) => { + formattedArgs[key] = args[index] + }) + return formattedArgs + } + + async getTransactionsByContractAddress(args: FetchTransactionsByContractInput): Promise { + const { skip = 0, take = 10, address, orderAsc = false } = args + return this.transactionRepository + .createQueryBuilder('transaction') + .leftJoin('transaction.events', 'event') + .where('event.contractAddress = :address', { address }) + .skip(skip) + .take(take) + .orderBy('transaction.timestamp', orderAsc ? 'ASC' : 'DESC') + .getMany() + } } diff --git a/src/utils.spec.ts b/src/utils.spec.ts new file mode 100644 index 0000000..0467182 --- /dev/null +++ b/src/utils.spec.ts @@ -0,0 +1,18 @@ +import { ApiPromise } from '@polkadot/api' +import { apiMock } from '../mocks/api-mock' +import { connect } from './utils' +jest.mock('@polkadot/api') +describe('Utils', () => { + let api: ApiPromise + + beforeEach(async () => { + const MockedApi = ApiPromise as jest.MockedClass + MockedApi.create = jest.fn().mockResolvedValue(apiMock) + api = await MockedApi.create() + }) + + it('should return an ApiPromise instance', async () => { + const result = await connect('ws://localhost:9944') + expect(result).toEqual(api) + }) +}) diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..965012d --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,5 @@ +import { ApiPromise, WsProvider } from '@polkadot/api' + +export const connect = async (provider: string | string[] | undefined) => { + return ApiPromise.create({ provider: new WsProvider(provider) }) +}