From 19d2069b36d21416210b23afc90a977d4a951469 Mon Sep 17 00:00:00 2001 From: linsyhen99 Date: Fri, 27 Oct 2023 17:47:43 +0800 Subject: [PATCH 1/8] Adding example usages of the parser to parse instructions and parse events Signed-off-by: linsyhen99 --- examples/ek-event-parser/.env.example | 2 + examples/ek-event-parser/.gitignore | 6 + examples/ek-event-parser/README.md | 1 + examples/ek-event-parser/package.json | 25 + examples/ek-event-parser/pnpm-lock.yaml | 1060 +++++++++++++++++ .../src/constants/programLogsConstant.ts | 4 + .../src/helpers/eventParser.ts | 112 ++ .../src/helpers/loadEnvironmentVariables.ts | 17 + examples/ek-event-parser/src/index.ts | 125 ++ .../src/models/logContextStack.ts | 15 + .../src/models/logExtractor.ts | 12 + examples/ek-event-parser/tsconfig.json | 109 ++ examples/ek-instruction-parser/.env.example | 4 + examples/ek-instruction-parser/.gitignore | 5 + examples/ek-instruction-parser/README.md | 1 + examples/ek-instruction-parser/package.json | 26 + examples/ek-instruction-parser/pnpm-lock.yaml | 1060 +++++++++++++++++ .../src/helpers/loadEnvironmentVariables.ts | 27 + examples/ek-instruction-parser/src/index.ts | 111 ++ examples/ek-instruction-parser/tsconfig.json | 109 ++ 20 files changed, 2831 insertions(+) create mode 100644 examples/ek-event-parser/.env.example create mode 100644 examples/ek-event-parser/.gitignore create mode 100644 examples/ek-event-parser/README.md create mode 100644 examples/ek-event-parser/package.json create mode 100644 examples/ek-event-parser/pnpm-lock.yaml create mode 100644 examples/ek-event-parser/src/constants/programLogsConstant.ts create mode 100644 examples/ek-event-parser/src/helpers/eventParser.ts create mode 100644 examples/ek-event-parser/src/helpers/loadEnvironmentVariables.ts create mode 100644 examples/ek-event-parser/src/index.ts create mode 100644 examples/ek-event-parser/src/models/logContextStack.ts create mode 100644 examples/ek-event-parser/src/models/logExtractor.ts create mode 100644 examples/ek-event-parser/tsconfig.json create mode 100644 examples/ek-instruction-parser/.env.example create mode 100644 examples/ek-instruction-parser/.gitignore create mode 100644 examples/ek-instruction-parser/README.md create mode 100644 examples/ek-instruction-parser/package.json create mode 100644 examples/ek-instruction-parser/pnpm-lock.yaml create mode 100644 examples/ek-instruction-parser/src/helpers/loadEnvironmentVariables.ts create mode 100644 examples/ek-instruction-parser/src/index.ts create mode 100644 examples/ek-instruction-parser/tsconfig.json diff --git a/examples/ek-event-parser/.env.example b/examples/ek-event-parser/.env.example new file mode 100644 index 0000000..ebecb4c --- /dev/null +++ b/examples/ek-event-parser/.env.example @@ -0,0 +1,2 @@ +PROGRAM_HASH= +IDL_TYPE= \ No newline at end of file diff --git a/examples/ek-event-parser/.gitignore b/examples/ek-event-parser/.gitignore new file mode 100644 index 0000000..df27cb0 --- /dev/null +++ b/examples/ek-event-parser/.gitignore @@ -0,0 +1,6 @@ +.idea/ +node_modules/ +.env +idl.json +.DS_Store + diff --git a/examples/ek-event-parser/README.md b/examples/ek-event-parser/README.md new file mode 100644 index 0000000..9bb27c7 --- /dev/null +++ b/examples/ek-event-parser/README.md @@ -0,0 +1 @@ +# event-parsing-with-ek diff --git a/examples/ek-event-parser/package.json b/examples/ek-event-parser/package.json new file mode 100644 index 0000000..fe9bb52 --- /dev/null +++ b/examples/ek-event-parser/package.json @@ -0,0 +1,25 @@ +{ + "name": "ek-event-parser", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "dev": "nodemon --exec ts-node src/index.ts", + "build": "tsc --outDir dist", + "clean": "rm -r dist && rm -r node_modules" + }, + "author": "", + "license": "ISC", + "dependencies": { + "@solanafm/explorer-kit": "^1.0.0", + "@solanafm/explorer-kit-idls": "^1.0.0", + "@types/node": "^20.8.7", + "axios": "^1.5.1", + "dotenv": "^16.3.1", + "ts-node": "^10.9.1", + "typescript": "^5.2.2" + }, + "devDependencies": { + "nodemon": "^3.0.1" + } +} \ No newline at end of file diff --git a/examples/ek-event-parser/pnpm-lock.yaml b/examples/ek-event-parser/pnpm-lock.yaml new file mode 100644 index 0000000..77121ac --- /dev/null +++ b/examples/ek-event-parser/pnpm-lock.yaml @@ -0,0 +1,1060 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + '@solanafm/explorer-kit': + specifier: ^1.0.0 + version: 1.0.0 + '@solanafm/explorer-kit-idls': + specifier: ^1.0.0 + version: 1.0.0 + '@types/node': + specifier: ^20.8.7 + version: 20.8.7 + axios: + specifier: ^1.5.1 + version: 1.5.1 + dotenv: + specifier: ^16.3.1 + version: 16.3.1 + ts-node: + specifier: ^10.9.1 + version: 10.9.1(@types/node@20.8.7)(typescript@5.2.2) + typescript: + specifier: ^5.2.2 + version: 5.2.2 + +devDependencies: + nodemon: + specifier: ^3.0.1 + version: 3.0.1 + +packages: + + /@babel/runtime@7.23.2: + resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.0 + dev: false + + /@coral-xyz/anchor@0.27.0: + resolution: {integrity: sha512-+P/vPdORawvg3A9Wj02iquxb4T0C5m4P6aZBVYysKl4Amk+r6aMPZkUhilBkD6E4Nuxnoajv3CFykUfkGE0n5g==} + engines: {node: '>=11'} + dependencies: + '@coral-xyz/borsh': 0.27.0(@solana/web3.js@1.87.2) + '@solana/web3.js': 1.87.2 + base64-js: 1.5.1 + bn.js: 5.2.1 + bs58: 4.0.1 + buffer-layout: 1.2.2 + camelcase: 6.3.0 + cross-fetch: 3.1.8 + crypto-hash: 1.3.0 + eventemitter3: 4.0.7 + js-sha256: 0.9.0 + pako: 2.1.0 + snake-case: 3.0.4 + superstruct: 0.15.5 + toml: 3.0.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@coral-xyz/anchor@0.28.1-beta.2: + resolution: {integrity: sha512-xreUcOFF8+IQKWOBUrDKJbIw2ftpRVybFlEPVrbSlOBCbreCWrQ5754Gt9cHIcuBDAzearCDiBqzsGQdNgPJiw==} + engines: {node: '>=11'} + dependencies: + '@coral-xyz/borsh': 0.28.0(@solana/web3.js@1.87.2) + '@noble/hashes': 1.3.2 + '@solana/web3.js': 1.87.2 + base64-js: 1.5.1 + bn.js: 5.2.1 + bs58: 4.0.1 + buffer-layout: 1.2.2 + camelcase: 6.3.0 + cross-fetch: 3.1.8 + crypto-hash: 1.3.0 + eventemitter3: 4.0.7 + pako: 2.1.0 + snake-case: 3.0.4 + superstruct: 0.15.5 + toml: 3.0.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@coral-xyz/borsh@0.27.0(@solana/web3.js@1.87.2): + resolution: {integrity: sha512-tJKzhLukghTWPLy+n8K8iJKgBq1yLT/AxaNd10yJrX8mI56ao5+OFAKAqW/h0i79KCvb4BK0VGO5ECmmolFz9A==} + engines: {node: '>=10'} + peerDependencies: + '@solana/web3.js': ^1.68.0 + dependencies: + '@solana/web3.js': 1.87.2 + bn.js: 5.2.1 + buffer-layout: 1.2.2 + dev: false + + /@coral-xyz/borsh@0.28.0(@solana/web3.js@1.87.2): + resolution: {integrity: sha512-/u1VTzw7XooK7rqeD7JLUSwOyRSesPUk0U37BV9zK0axJc1q0nRbKFGFLYCQ16OtdOJTTwGfGp11Lx9B45bRCQ==} + engines: {node: '>=10'} + peerDependencies: + '@solana/web3.js': ^1.68.0 + dependencies: + '@solana/web3.js': 1.87.2 + bn.js: 5.2.1 + buffer-layout: 1.2.2 + dev: false + + /@cspotcode/source-map-support@0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: false + + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + dev: false + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: false + + /@jridgewell/trace-mapping@0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: false + + /@metaplex-foundation/umi-options@0.8.9: + resolution: {integrity: sha512-jSQ61sZMPSAk/TXn8v8fPqtz3x8d0/blVZXLLbpVbo2/T5XobiI6/MfmlUosAjAUaQl6bHRF8aIIqZEFkJiy4A==} + dev: false + + /@metaplex-foundation/umi-public-keys@0.8.9: + resolution: {integrity: sha512-CxMzN7dgVGOq9OcNCJe2casKUpJ3RmTVoOvDFyeoTQuK+vkZ1YSSahbqC1iGuHEtKTLSjtWjKvUU6O7zWFTw3Q==} + dependencies: + '@metaplex-foundation/umi-serializers-encodings': 0.8.9 + dev: false + + /@metaplex-foundation/umi-serializers-core@0.8.9: + resolution: {integrity: sha512-WT82tkiYJ0Qmscp7uTj1Hz6aWQPETwaKLAENAUN5DeWghkuBKtuxyBKVvEOuoXerJSdhiAk0e8DWA4cxcTTQ/w==} + dev: false + + /@metaplex-foundation/umi-serializers-encodings@0.8.9: + resolution: {integrity: sha512-N3VWLDTJ0bzzMKcJDL08U3FaqRmwlN79FyE4BHj6bbAaJ9LEHjDQ9RJijZyWqTm0jE7I750fU7Ow5EZL38Xi6Q==} + dependencies: + '@metaplex-foundation/umi-serializers-core': 0.8.9 + dev: false + + /@metaplex-foundation/umi-serializers-numbers@0.8.9: + resolution: {integrity: sha512-NtBf1fnVNQJHFQjLFzRu2i9GGnigb9hOm/Gfrk628d0q0tRJB7BOM3bs5C61VAs7kJs4yd+pDNVAERJkknQ7Lg==} + dependencies: + '@metaplex-foundation/umi-serializers-core': 0.8.9 + dev: false + + /@metaplex-foundation/umi-serializers@0.8.9: + resolution: {integrity: sha512-Sve8Etm3zqvLSUfza+MYRkjTnCpiaAFT7VWdqeHzA3n58P0AfT3p74RrZwVt/UFkxI+ln8BslwBDJmwzcPkuHw==} + dependencies: + '@metaplex-foundation/umi-options': 0.8.9 + '@metaplex-foundation/umi-public-keys': 0.8.9 + '@metaplex-foundation/umi-serializers-core': 0.8.9 + '@metaplex-foundation/umi-serializers-encodings': 0.8.9 + '@metaplex-foundation/umi-serializers-numbers': 0.8.9 + dev: false + + /@metaplex-foundation/umi@0.8.9: + resolution: {integrity: sha512-Gip7HPDCjsX7OakPFBiifX89AofUGcsj/ujbvOfd/6GDIL4XjX79royuT3yyxzovRxyiaPF/kCK6a2dKtm69Kw==} + dependencies: + '@metaplex-foundation/umi-options': 0.8.9 + '@metaplex-foundation/umi-public-keys': 0.8.9 + '@metaplex-foundation/umi-serializers': 0.8.9 + dev: false + + /@noble/curves@1.2.0: + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + dependencies: + '@noble/hashes': 1.3.2 + dev: false + + /@noble/hashes@1.3.2: + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + dev: false + + /@solana/buffer-layout@4.0.1: + resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} + engines: {node: '>=5.10'} + dependencies: + buffer: 6.0.3 + dev: false + + /@solana/web3.js@1.87.2: + resolution: {integrity: sha512-TZNhS+tvJbYjm0LAvIkUy/3Aqgt2l6/3X6XsVUpvj5MGOl2Q6Ch8hYSxcUUtMbAFNN3sUXmV8NhhMLNJEvI6TA==} + dependencies: + '@babel/runtime': 7.23.2 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.0 + node-fetch: 2.7.0 + rpc-websockets: 7.6.1 + superstruct: 0.14.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@solanafm/explorer-kit-idls@1.0.0: + resolution: {integrity: sha512-5ykQlPW4rA9sS5RvsiG/66lceI6rmPkyIubam795vrkP+cVW6A9W3kXV1A1o5zZUzIHQO/X8HA5JSItelnZsKQ==} + dependencies: + '@coral-xyz/anchor': 0.27.0 + '@solanafm/kinobi-lite': 0.12.0 + axios: 1.5.1 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - utf-8-validate + dev: false + + /@solanafm/explorer-kit@1.0.0: + resolution: {integrity: sha512-xKeG+SZ8gZBlM1re+Udlm6AhDYtL7v6f4IW/GL+YIqOvD5Wz4GI23Em7qWfVo9bwsR4nN2bS+IOpBsYX5GGRMw==} + dependencies: + '@coral-xyz/anchor': 0.28.1-beta.2 + '@metaplex-foundation/umi': 0.8.9 + '@metaplex-foundation/umi-serializers': 0.8.9 + '@solanafm/kinobi-lite': 0.12.0 + '@solanafm/utils': 0.3.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@solanafm/kinobi-lite@0.12.0: + resolution: {integrity: sha512-K3daAv8HoJzM6UiDUG1Tj0tZIcCSJENmqx5nw4J2+sOwyZm1leFvVkIHM+WOExh/IqI7PglipRJbrF0OXN007Q==} + dependencies: + '@noble/hashes': 1.3.2 + chalk: 4.1.2 + dev: false + + /@solanafm/utils@0.3.0: + resolution: {integrity: sha512-SI0Q+PIH+t9gT4cPrLVKlPpjhByHFunyL01j/VfI2sBlBueuyCpO9PgpK/VQA2sZ8wdDqhq2g6gatzuNnlLJiQ==} + dependencies: + '@metaplex-foundation/umi-options': 0.8.9 + bn.js: 5.2.1 + bs58: 5.0.0 + dayjs: 1.11.10 + dev: false + + /@tsconfig/node10@1.0.9: + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + dev: false + + /@tsconfig/node12@1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: false + + /@tsconfig/node14@1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: false + + /@tsconfig/node16@1.0.4: + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + dev: false + + /@types/connect@3.4.37: + resolution: {integrity: sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q==} + dependencies: + '@types/node': 20.8.7 + dev: false + + /@types/node@12.20.55: + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + dev: false + + /@types/node@20.8.7: + resolution: {integrity: sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==} + dependencies: + undici-types: 5.25.3 + dev: false + + /@types/ws@7.4.7: + resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + dependencies: + '@types/node': 20.8.7 + dev: false + + /JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + dev: false + + /abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + dev: true + + /acorn-walk@8.2.0: + resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + engines: {node: '>=0.4.0'} + dev: false + + /acorn@8.10.0: + resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: false + + /agentkeepalive@4.5.0: + resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} + engines: {node: '>= 8.0.0'} + dependencies: + humanize-ms: 1.2.1 + dev: false + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: false + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: false + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + + /axios@1.5.1: + resolution: {integrity: sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==} + dependencies: + follow-redirects: 1.15.3 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /base-x@3.0.9: + resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /base-x@4.0.0: + resolution: {integrity: sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==} + dev: false + + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: false + + /bigint-buffer@1.1.5: + resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} + engines: {node: '>= 10.0.0'} + requiresBuild: true + dependencies: + bindings: 1.5.0 + dev: false + + /binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + dependencies: + file-uri-to-path: 1.0.0 + dev: false + + /bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + dev: false + + /borsh@0.7.0: + resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + dependencies: + bn.js: 5.2.1 + bs58: 4.0.1 + text-encoding-utf-8: 1.0.2 + dev: false + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + dependencies: + base-x: 3.0.9 + dev: false + + /bs58@5.0.0: + resolution: {integrity: sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==} + dependencies: + base-x: 4.0.0 + dev: false + + /buffer-layout@1.2.2: + resolution: {integrity: sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==} + engines: {node: '>=4.5'} + dev: false + + /buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + + /bufferutil@4.0.8: + resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} + engines: {node: '>=6.14.2'} + requiresBuild: true + dependencies: + node-gyp-build: 4.6.1 + dev: false + + /camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: false + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: false + + /chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: false + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: false + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false + + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: false + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: false + + /cross-fetch@3.1.8: + resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + dev: false + + /crypto-hash@1.3.0: + resolution: {integrity: sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==} + engines: {node: '>=8'} + dev: false + + /dayjs@1.11.10: + resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} + dev: false + + /debug@3.2.7(supports-color@5.5.0): + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + supports-color: 5.5.0 + dev: true + + /delay@5.0.0: + resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} + engines: {node: '>=10'} + dev: false + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false + + /diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: false + + /dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dependencies: + no-case: 3.0.4 + tslib: 2.6.2 + dev: false + + /dotenv@16.3.1: + resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + engines: {node: '>=12'} + dev: false + + /es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + dev: false + + /es6-promisify@5.0.0: + resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + dependencies: + es6-promise: 4.2.8 + dev: false + + /eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + dev: false + + /eyes@0.1.8: + resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} + engines: {node: '> 0.1.90'} + dev: false + + /fast-stable-stringify@1.0.0: + resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + dev: false + + /file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + dev: false + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /follow-redirects@1.15.3: + resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: false + + /humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + dependencies: + ms: 2.1.3 + dev: false + + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: false + + /ignore-by-default@1.0.1: + resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + dev: true + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /isomorphic-ws@4.0.1(ws@7.5.9): + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + dependencies: + ws: 7.5.9 + dev: false + + /jayson@4.1.0: + resolution: {integrity: sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A==} + engines: {node: '>=8'} + hasBin: true + dependencies: + '@types/connect': 3.4.37 + '@types/node': 12.20.55 + '@types/ws': 7.4.7 + JSONStream: 1.3.5 + commander: 2.20.3 + delay: 5.0.0 + es6-promisify: 5.0.0 + eyes: 0.1.8 + isomorphic-ws: 4.0.1(ws@7.5.9) + json-stringify-safe: 5.0.1 + uuid: 8.3.2 + ws: 7.5.9 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + + /js-sha256@0.9.0: + resolution: {integrity: sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==} + dev: false + + /json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + dev: false + + /jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + dev: false + + /lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + dependencies: + tslib: 2.6.2 + dev: false + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: false + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + /no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + dependencies: + lower-case: 2.0.2 + tslib: 2.6.2 + dev: false + + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /node-gyp-build@4.6.1: + resolution: {integrity: sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==} + hasBin: true + requiresBuild: true + dev: false + + /nodemon@3.0.1: + resolution: {integrity: sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + chokidar: 3.5.3 + debug: 3.2.7(supports-color@5.5.0) + ignore-by-default: 1.0.1 + minimatch: 3.1.2 + pstree.remy: 1.1.8 + semver: 7.5.4 + simple-update-notifier: 2.0.0 + supports-color: 5.5.0 + touch: 3.1.0 + undefsafe: 2.0.5 + dev: true + + /nopt@1.0.10: + resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==} + hasBin: true + dependencies: + abbrev: 1.1.1 + dev: true + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /pako@2.1.0: + resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} + dev: false + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false + + /pstree.remy@1.1.8: + resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + dev: true + + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /regenerator-runtime@0.14.0: + resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + dev: false + + /rpc-websockets@7.6.1: + resolution: {integrity: sha512-MmRGaJJvxTHSRxYPjJJqcj2zWnCetw7YbYbKlD0Yc7qVw6PsZhRJg1MI3mpWlpBs+4zO+urlNfLl9zLsdOD/gA==} + dependencies: + '@babel/runtime': 7.23.2 + eventemitter3: 4.0.7 + uuid: 8.3.2 + ws: 8.14.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + dev: false + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: false + + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /simple-update-notifier@2.0.0: + resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} + engines: {node: '>=10'} + dependencies: + semver: 7.5.4 + dev: true + + /snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + dependencies: + dot-case: 3.0.4 + tslib: 2.6.2 + dev: false + + /superstruct@0.14.2: + resolution: {integrity: sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==} + dev: false + + /superstruct@0.15.5: + resolution: {integrity: sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ==} + dev: false + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: false + + /text-encoding-utf-8@1.0.2: + resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} + dev: false + + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: false + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /toml@3.0.0: + resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + dev: false + + /touch@3.1.0: + resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==} + hasBin: true + dependencies: + nopt: 1.0.10 + dev: true + + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + + /ts-node@10.9.1(@types/node@20.8.7)(typescript@5.2.2): + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.8.7 + acorn: 8.10.0 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.2.2 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: false + + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + dev: false + + /typescript@5.2.2: + resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} + engines: {node: '>=14.17'} + hasBin: true + dev: false + + /undefsafe@2.0.5: + resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + dev: true + + /undici-types@5.25.3: + resolution: {integrity: sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==} + dev: false + + /utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + requiresBuild: true + dependencies: + node-gyp-build: 4.6.1 + dev: false + + /uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + dev: false + + /v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: false + + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + + /ws@7.5.9: + resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + + /ws@8.14.2(bufferutil@4.0.8)(utf-8-validate@5.0.10): + resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + dev: false + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + + /yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: false diff --git a/examples/ek-event-parser/src/constants/programLogsConstant.ts b/examples/ek-event-parser/src/constants/programLogsConstant.ts new file mode 100644 index 0000000..74eeb9b --- /dev/null +++ b/examples/ek-event-parser/src/constants/programLogsConstant.ts @@ -0,0 +1,4 @@ +export const PROGRAM_LOG = "Program log: "; +export const PROGRAM_DATA = "Program data: "; +export const PROGRAM_LOG_START_INDEX = PROGRAM_LOG.length; +export const PROGRAM_DATA_START_INDEX = PROGRAM_DATA.length; diff --git a/examples/ek-event-parser/src/helpers/eventParser.ts b/examples/ek-event-parser/src/helpers/eventParser.ts new file mode 100644 index 0000000..a6f9307 --- /dev/null +++ b/examples/ek-event-parser/src/helpers/eventParser.ts @@ -0,0 +1,112 @@ +import { + PROGRAM_DATA, + PROGRAM_DATA_START_INDEX, + PROGRAM_LOG, + PROGRAM_LOG_START_INDEX, +} from "../constants/programLogsConstant"; +import { LogContextStack } from "../models/logContextStack"; +import { LogExtractor } from "../models/logExtractor"; + +export function* parseLogs( + logs: string[], + errorOnDecodeFailed: boolean = false +) { + const logsExtractor = new LogExtractor(logs); + const logsContextStack = new LogContextStack(); + + let log = logsExtractor.next(); + while (log !== null) { + let [event, programHash, popped] = identifyLog( + logsContextStack, + log, + errorOnDecodeFailed + ); + + if (event) { + yield { + event: event, + programHash: logsContextStack.getProgram(), + }; + } + if (programHash) { + logsContextStack.push(programHash); + } + if (popped) { + logsContextStack.pop(); + } + + log = logsExtractor.next(); + } +} + +const identifyLog = ( + context: LogContextStack, + log: string, + errorOnDecodeFailed: boolean +): [string | null, string | null, boolean] => { + if (context.stack.length > 0) { + return extractProgramLog(log, errorOnDecodeFailed); + } else { + return [null, ...extractSystemLog(log)]; + } +}; + +const extractProgramLog = ( + log: string, + errorOnDecodeFailed: boolean +): [string | null, string | null, boolean] => { + if (log.startsWith(PROGRAM_LOG) || log.startsWith(PROGRAM_DATA)) { + const logStr = log.startsWith(PROGRAM_LOG) + ? log.slice(PROGRAM_LOG_START_INDEX) + : log.slice(PROGRAM_DATA_START_INDEX); + const event = logStr; + + if (errorOnDecodeFailed && event === null) { + throw new Error(`Unable to decode log ${logStr}`); + } + return [event, null, false]; + } else { + return [null, ...extractSystemLog(log)]; + } +}; + +const extractSystemLog = (log: string): [string | null, boolean] => { + const logStart = log.split(":")[0]; + if (logStart) { + const cpiInvokationPattern = new RegExp("Program (.+?) invoke"); + const cpiMatch = logStart.match(cpiInvokationPattern); + + if (logStart.match(/^Program (.*) success/g) !== null) { + return [null, true]; + } else if (cpiMatch) { + if (cpiMatch[1]) { + return [cpiMatch[1], false]; + } + return [null, false]; + } else { + return [null, false]; + } + } + + return [null, false]; +}; + +export const convertLogsToEventsMap = (logs: string[]) => { + const eventMap = new Map(); + for (const event of parseLogs(logs)) { + // Regex String checker to only get base64 strings + const base64RegexCheck = new RegExp( + "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$" + ); + + if (base64RegexCheck.test(event.event)) { + if (eventMap.has(event.programHash)) { + eventMap.get(event.programHash)?.push(event.event); + } else { + eventMap.set(event.programHash, [event.event]); + } + } + } + + return eventMap; +}; diff --git a/examples/ek-event-parser/src/helpers/loadEnvironmentVariables.ts b/examples/ek-event-parser/src/helpers/loadEnvironmentVariables.ts new file mode 100644 index 0000000..221964e --- /dev/null +++ b/examples/ek-event-parser/src/helpers/loadEnvironmentVariables.ts @@ -0,0 +1,17 @@ +import { config } from "dotenv"; + +config(); + +export type Environment = { + programHash: string; +}; + +export const getEnvironmentVariables = (): Environment => { + if (!process.env.PROGRAM_HASH) { + throw new Error("PROGRAM_HASH environment variable is not set"); + } + + return { + programHash: process.env.PROGRAM_HASH, + }; +}; diff --git a/examples/ek-event-parser/src/index.ts b/examples/ek-event-parser/src/index.ts new file mode 100644 index 0000000..3473334 --- /dev/null +++ b/examples/ek-event-parser/src/index.ts @@ -0,0 +1,125 @@ +import { IdlItem, getProgramIdl } from "@solanafm/explorer-kit-idls"; +import { convertLogsToEventsMap } from "./helpers/eventParser"; +import { getEnvironmentVariables } from "./helpers/loadEnvironmentVariables"; +import fs from "fs"; +import { + EventParserInterface, + Parser, + ParserType, + SolanaFMParser, + checkIfEventParser, +} from "@solanafm/explorer-kit"; + +const environment = getEnvironmentVariables(); + +const app = async () => { + const logs: string[] = [ + "Program ComputeBudget111111111111111111111111111111 invoke [1]", + "Program ComputeBudget111111111111111111111111111111 success", + "Program JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB invoke [1]", + "Program log: Instruction: Route", + "Program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc invoke [2]", + "Program log: Instruction: Swap", + "Program log: fee_growth: 1093994082951", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]", + "Program log: Instruction: Transfer", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 1339463 compute units", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]", + "Program log: Instruction: Transfer", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4736 of 1331898 compute units", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", + "Program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc consumed 55954 of 1379575 compute units", + "Program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc success", + "Program data: UWzjvs3QCsQOA2hfjpCQU+RYEhxm9adq7cdwaqEcgviqlSqPK3h5qcb6evO+2606PWXzaqvJdDGxu+TC0vbg5HymAgNFL11hQEIPAAAAAAAGm4hX/quBhPtof2NGGMA12sQ53BrrO1WYoPAAAAAAARgu5AEAAAAA", + "Program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc invoke [2]", + "Program log: Instruction: Swap", + "Program log: fee_growth: 94074010856", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]", + "Program log: Instruction: Transfer", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4736 of 1267773 compute units", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]", + "Program log: Instruction: Transfer", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 1260120 compute units", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", + "Program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc consumed 54865 of 1306828 compute units", + "Program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc success", + "Program data: UWzjvs3QCsQOA2hfjpCQU+RYEhxm9adq7cdwaqEcgviqlSqPK3h5qQabiFf+q4GE+2h/Y0YYwDXaxDncGus7VZig8AAAAAABGC7kAQAAAADG+nrzvtutOj1l82qryXQxsbvkwtL24OR8pgIDRS9dYfRFDwAAAAAA", + "Program JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB consumed 150851 of 1400000 compute units", + "Program JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB success", + ]; + const eventMap = convertLogsToEventsMap(logs); + const parser = await setupParser(); + const parsedEvents: { [key: string]: any[] } = {}; + + for (const [prorgamId, eventMapLogs] of eventMap.entries()) { + if (prorgamId !== environment.programHash) { + continue; + } + + try { + const events = []; + for (const log of eventMapLogs) { + const decodedEvent = parser.parseEvents(log); + events.push(decodedEvent); + } + + parsedEvents[prorgamId] = events; + } catch (err) { + console.log("Parser extraction error, due to: ", err); + } + } + + console.log("Parsed events: ", parsedEvents); +}; + +const setupParser = async () => { + const idlItemFromLibrary = await getProgramIdl(environment.programHash); + let eventParser: EventParserInterface | undefined; + if (idlItemFromLibrary === null) { + eventParser = setupParserFromLocalIdl(); + console.log("Successfully loaded parser from local idl file"); + } else { + const parser = new SolanaFMParser( + idlItemFromLibrary, + environment.programHash + ); + const registryParser = parser.createParser(ParserType.EVENT); + if (registryParser && checkIfEventParser(registryParser)) { + eventParser = registryParser; + console.log("Successfully loaded parser from registry"); + } + } + if (!eventParser) { + throw new Error("Failed to load parser"); + } + return eventParser; +}; + +const setupParserFromLocalIdl = () => { + const jsonString = fs.readFileSync("./idl.json", "utf8"); + const idlFile = JSON.parse(jsonString); + let idlType: "anchor" | "shank" | "kinobi" | string = ""; + if (!process.env.IDL_TYPE) { + throw new Error("IDL_TYPE environment variable is not set"); + } + idlType = process.env.IDL_TYPE; + if (idlType !== "anchor" && idlType !== "shank" && idlType !== "kinobi") { + throw new Error(`IDL_TYPE ${idlType} is not valid`); + } + + const idlItem: IdlItem = { + programId: environment.programHash, + idl: idlFile, + idlType: idlType, + }; + + const parser = new SolanaFMParser(idlItem, environment.programHash); + const eventsParser = parser.createParser(ParserType.EVENT); + if (eventsParser && checkIfEventParser(eventsParser)) { + return eventsParser; + } +}; + +app(); diff --git a/examples/ek-event-parser/src/models/logContextStack.ts b/examples/ek-event-parser/src/models/logContextStack.ts new file mode 100644 index 0000000..6fc31b4 --- /dev/null +++ b/examples/ek-event-parser/src/models/logContextStack.ts @@ -0,0 +1,15 @@ +export class LogContextStack { + stack: string[] = []; + + getProgram(): string { + return this.stack[this.stack.length - 1] ?? "Unknown Program"; + } + + push(programHash: string) { + this.stack.push(programHash); + } + + pop() { + this.stack.pop(); + } +} diff --git a/examples/ek-event-parser/src/models/logExtractor.ts b/examples/ek-event-parser/src/models/logExtractor.ts new file mode 100644 index 0000000..9ef3390 --- /dev/null +++ b/examples/ek-event-parser/src/models/logExtractor.ts @@ -0,0 +1,12 @@ +export class LogExtractor { + constructor(public logs: string[]) {} + + next(): string | null { + if (this.logs.length === 0) { + return null; + } + const log = this.logs[0]; + this.logs = this.logs.slice(1); + return log; + } +} diff --git a/examples/ek-event-parser/tsconfig.json b/examples/ek-event-parser/tsconfig.json new file mode 100644 index 0000000..e075f97 --- /dev/null +++ b/examples/ek-event-parser/tsconfig.json @@ -0,0 +1,109 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/examples/ek-instruction-parser/.env.example b/examples/ek-instruction-parser/.env.example new file mode 100644 index 0000000..477129c --- /dev/null +++ b/examples/ek-instruction-parser/.env.example @@ -0,0 +1,4 @@ +PROGRAM_HASH= +IDL_TYPE= +TRANSACTION_HASH= +RPC_URL= \ No newline at end of file diff --git a/examples/ek-instruction-parser/.gitignore b/examples/ek-instruction-parser/.gitignore new file mode 100644 index 0000000..58819bd --- /dev/null +++ b/examples/ek-instruction-parser/.gitignore @@ -0,0 +1,5 @@ +.idea/ +node_modules/ +.env +idl.json +.DS_Store diff --git a/examples/ek-instruction-parser/README.md b/examples/ek-instruction-parser/README.md new file mode 100644 index 0000000..334ca59 --- /dev/null +++ b/examples/ek-instruction-parser/README.md @@ -0,0 +1 @@ +# instruction-parser-with-ek diff --git a/examples/ek-instruction-parser/package.json b/examples/ek-instruction-parser/package.json new file mode 100644 index 0000000..f0a7ded --- /dev/null +++ b/examples/ek-instruction-parser/package.json @@ -0,0 +1,26 @@ +{ + "name": "ek-instruction-parser", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "dev": "nodemon --exec ts-node src/index.ts", + "build": "tsc --outDir dist", + "clean": "rm -r dist && rm -r node_modules" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@solanafm/explorer-kit": "^1.0.0", + "@solanafm/explorer-kit-idls": "^1.0.0", + "@types/node": "^20.8.7", + "axios": "^1.5.1", + "dotenv": "^16.3.1", + "ts-node": "^10.9.1", + "typescript": "^5.2.2" + }, + "devDependencies": { + "nodemon": "^3.0.1" + } +} \ No newline at end of file diff --git a/examples/ek-instruction-parser/pnpm-lock.yaml b/examples/ek-instruction-parser/pnpm-lock.yaml new file mode 100644 index 0000000..d0a6edb --- /dev/null +++ b/examples/ek-instruction-parser/pnpm-lock.yaml @@ -0,0 +1,1060 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + '@solanafm/explorer-kit': + specifier: ^1.0.0 + version: 1.0.2 + '@solanafm/explorer-kit-idls': + specifier: ^1.0.0 + version: 1.0.0 + '@types/node': + specifier: ^20.8.7 + version: 20.8.9 + axios: + specifier: ^1.5.1 + version: 1.5.1 + dotenv: + specifier: ^16.3.1 + version: 16.3.1 + ts-node: + specifier: ^10.9.1 + version: 10.9.1(@types/node@20.8.9)(typescript@5.2.2) + typescript: + specifier: ^5.2.2 + version: 5.2.2 + +devDependencies: + nodemon: + specifier: ^3.0.1 + version: 3.0.1 + +packages: + + /@babel/runtime@7.23.2: + resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.0 + dev: false + + /@coral-xyz/anchor@0.27.0: + resolution: {integrity: sha512-+P/vPdORawvg3A9Wj02iquxb4T0C5m4P6aZBVYysKl4Amk+r6aMPZkUhilBkD6E4Nuxnoajv3CFykUfkGE0n5g==} + engines: {node: '>=11'} + dependencies: + '@coral-xyz/borsh': 0.27.0(@solana/web3.js@1.87.2) + '@solana/web3.js': 1.87.2 + base64-js: 1.5.1 + bn.js: 5.2.1 + bs58: 4.0.1 + buffer-layout: 1.2.2 + camelcase: 6.3.0 + cross-fetch: 3.1.8 + crypto-hash: 1.3.0 + eventemitter3: 4.0.7 + js-sha256: 0.9.0 + pako: 2.1.0 + snake-case: 3.0.4 + superstruct: 0.15.5 + toml: 3.0.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@coral-xyz/anchor@0.28.1-beta.2: + resolution: {integrity: sha512-xreUcOFF8+IQKWOBUrDKJbIw2ftpRVybFlEPVrbSlOBCbreCWrQ5754Gt9cHIcuBDAzearCDiBqzsGQdNgPJiw==} + engines: {node: '>=11'} + dependencies: + '@coral-xyz/borsh': 0.28.0(@solana/web3.js@1.87.2) + '@noble/hashes': 1.3.2 + '@solana/web3.js': 1.87.2 + base64-js: 1.5.1 + bn.js: 5.2.1 + bs58: 4.0.1 + buffer-layout: 1.2.2 + camelcase: 6.3.0 + cross-fetch: 3.1.8 + crypto-hash: 1.3.0 + eventemitter3: 4.0.7 + pako: 2.1.0 + snake-case: 3.0.4 + superstruct: 0.15.5 + toml: 3.0.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@coral-xyz/borsh@0.27.0(@solana/web3.js@1.87.2): + resolution: {integrity: sha512-tJKzhLukghTWPLy+n8K8iJKgBq1yLT/AxaNd10yJrX8mI56ao5+OFAKAqW/h0i79KCvb4BK0VGO5ECmmolFz9A==} + engines: {node: '>=10'} + peerDependencies: + '@solana/web3.js': ^1.68.0 + dependencies: + '@solana/web3.js': 1.87.2 + bn.js: 5.2.1 + buffer-layout: 1.2.2 + dev: false + + /@coral-xyz/borsh@0.28.0(@solana/web3.js@1.87.2): + resolution: {integrity: sha512-/u1VTzw7XooK7rqeD7JLUSwOyRSesPUk0U37BV9zK0axJc1q0nRbKFGFLYCQ16OtdOJTTwGfGp11Lx9B45bRCQ==} + engines: {node: '>=10'} + peerDependencies: + '@solana/web3.js': ^1.68.0 + dependencies: + '@solana/web3.js': 1.87.2 + bn.js: 5.2.1 + buffer-layout: 1.2.2 + dev: false + + /@cspotcode/source-map-support@0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: false + + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + dev: false + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: false + + /@jridgewell/trace-mapping@0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: false + + /@metaplex-foundation/umi-options@0.8.9: + resolution: {integrity: sha512-jSQ61sZMPSAk/TXn8v8fPqtz3x8d0/blVZXLLbpVbo2/T5XobiI6/MfmlUosAjAUaQl6bHRF8aIIqZEFkJiy4A==} + dev: false + + /@metaplex-foundation/umi-public-keys@0.8.9: + resolution: {integrity: sha512-CxMzN7dgVGOq9OcNCJe2casKUpJ3RmTVoOvDFyeoTQuK+vkZ1YSSahbqC1iGuHEtKTLSjtWjKvUU6O7zWFTw3Q==} + dependencies: + '@metaplex-foundation/umi-serializers-encodings': 0.8.9 + dev: false + + /@metaplex-foundation/umi-serializers-core@0.8.9: + resolution: {integrity: sha512-WT82tkiYJ0Qmscp7uTj1Hz6aWQPETwaKLAENAUN5DeWghkuBKtuxyBKVvEOuoXerJSdhiAk0e8DWA4cxcTTQ/w==} + dev: false + + /@metaplex-foundation/umi-serializers-encodings@0.8.9: + resolution: {integrity: sha512-N3VWLDTJ0bzzMKcJDL08U3FaqRmwlN79FyE4BHj6bbAaJ9LEHjDQ9RJijZyWqTm0jE7I750fU7Ow5EZL38Xi6Q==} + dependencies: + '@metaplex-foundation/umi-serializers-core': 0.8.9 + dev: false + + /@metaplex-foundation/umi-serializers-numbers@0.8.9: + resolution: {integrity: sha512-NtBf1fnVNQJHFQjLFzRu2i9GGnigb9hOm/Gfrk628d0q0tRJB7BOM3bs5C61VAs7kJs4yd+pDNVAERJkknQ7Lg==} + dependencies: + '@metaplex-foundation/umi-serializers-core': 0.8.9 + dev: false + + /@metaplex-foundation/umi-serializers@0.8.9: + resolution: {integrity: sha512-Sve8Etm3zqvLSUfza+MYRkjTnCpiaAFT7VWdqeHzA3n58P0AfT3p74RrZwVt/UFkxI+ln8BslwBDJmwzcPkuHw==} + dependencies: + '@metaplex-foundation/umi-options': 0.8.9 + '@metaplex-foundation/umi-public-keys': 0.8.9 + '@metaplex-foundation/umi-serializers-core': 0.8.9 + '@metaplex-foundation/umi-serializers-encodings': 0.8.9 + '@metaplex-foundation/umi-serializers-numbers': 0.8.9 + dev: false + + /@metaplex-foundation/umi@0.8.9: + resolution: {integrity: sha512-Gip7HPDCjsX7OakPFBiifX89AofUGcsj/ujbvOfd/6GDIL4XjX79royuT3yyxzovRxyiaPF/kCK6a2dKtm69Kw==} + dependencies: + '@metaplex-foundation/umi-options': 0.8.9 + '@metaplex-foundation/umi-public-keys': 0.8.9 + '@metaplex-foundation/umi-serializers': 0.8.9 + dev: false + + /@noble/curves@1.2.0: + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + dependencies: + '@noble/hashes': 1.3.2 + dev: false + + /@noble/hashes@1.3.2: + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + dev: false + + /@solana/buffer-layout@4.0.1: + resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} + engines: {node: '>=5.10'} + dependencies: + buffer: 6.0.3 + dev: false + + /@solana/web3.js@1.87.2: + resolution: {integrity: sha512-TZNhS+tvJbYjm0LAvIkUy/3Aqgt2l6/3X6XsVUpvj5MGOl2Q6Ch8hYSxcUUtMbAFNN3sUXmV8NhhMLNJEvI6TA==} + dependencies: + '@babel/runtime': 7.23.2 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.0 + node-fetch: 2.7.0 + rpc-websockets: 7.6.1 + superstruct: 0.14.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@solanafm/explorer-kit-idls@1.0.0: + resolution: {integrity: sha512-5ykQlPW4rA9sS5RvsiG/66lceI6rmPkyIubam795vrkP+cVW6A9W3kXV1A1o5zZUzIHQO/X8HA5JSItelnZsKQ==} + dependencies: + '@coral-xyz/anchor': 0.27.0 + '@solanafm/kinobi-lite': 0.12.0 + axios: 1.5.1 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - utf-8-validate + dev: false + + /@solanafm/explorer-kit@1.0.2: + resolution: {integrity: sha512-Ne1NxN3xUWvn/Oc8WPLsFmxTkFSBpMKLsRsjGMUYfW5nsIL86KYveh23ANgcevBLSz+TpCb4mU82XVY+JrJeIQ==} + dependencies: + '@coral-xyz/anchor': 0.28.1-beta.2 + '@metaplex-foundation/umi': 0.8.9 + '@metaplex-foundation/umi-serializers': 0.8.9 + '@solanafm/kinobi-lite': 0.12.0 + '@solanafm/utils': 0.3.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@solanafm/kinobi-lite@0.12.0: + resolution: {integrity: sha512-K3daAv8HoJzM6UiDUG1Tj0tZIcCSJENmqx5nw4J2+sOwyZm1leFvVkIHM+WOExh/IqI7PglipRJbrF0OXN007Q==} + dependencies: + '@noble/hashes': 1.3.2 + chalk: 4.1.2 + dev: false + + /@solanafm/utils@0.3.0: + resolution: {integrity: sha512-SI0Q+PIH+t9gT4cPrLVKlPpjhByHFunyL01j/VfI2sBlBueuyCpO9PgpK/VQA2sZ8wdDqhq2g6gatzuNnlLJiQ==} + dependencies: + '@metaplex-foundation/umi-options': 0.8.9 + bn.js: 5.2.1 + bs58: 5.0.0 + dayjs: 1.11.10 + dev: false + + /@tsconfig/node10@1.0.9: + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + dev: false + + /@tsconfig/node12@1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: false + + /@tsconfig/node14@1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: false + + /@tsconfig/node16@1.0.4: + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + dev: false + + /@types/connect@3.4.37: + resolution: {integrity: sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q==} + dependencies: + '@types/node': 20.8.9 + dev: false + + /@types/node@12.20.55: + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + dev: false + + /@types/node@20.8.9: + resolution: {integrity: sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==} + dependencies: + undici-types: 5.26.5 + dev: false + + /@types/ws@7.4.7: + resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + dependencies: + '@types/node': 20.8.9 + dev: false + + /JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + dev: false + + /abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + dev: true + + /acorn-walk@8.2.0: + resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + engines: {node: '>=0.4.0'} + dev: false + + /acorn@8.10.0: + resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: false + + /agentkeepalive@4.5.0: + resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} + engines: {node: '>= 8.0.0'} + dependencies: + humanize-ms: 1.2.1 + dev: false + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: false + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: false + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + + /axios@1.5.1: + resolution: {integrity: sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==} + dependencies: + follow-redirects: 1.15.3 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /base-x@3.0.9: + resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /base-x@4.0.0: + resolution: {integrity: sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==} + dev: false + + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: false + + /bigint-buffer@1.1.5: + resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} + engines: {node: '>= 10.0.0'} + requiresBuild: true + dependencies: + bindings: 1.5.0 + dev: false + + /binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + dependencies: + file-uri-to-path: 1.0.0 + dev: false + + /bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + dev: false + + /borsh@0.7.0: + resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + dependencies: + bn.js: 5.2.1 + bs58: 4.0.1 + text-encoding-utf-8: 1.0.2 + dev: false + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + dependencies: + base-x: 3.0.9 + dev: false + + /bs58@5.0.0: + resolution: {integrity: sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==} + dependencies: + base-x: 4.0.0 + dev: false + + /buffer-layout@1.2.2: + resolution: {integrity: sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==} + engines: {node: '>=4.5'} + dev: false + + /buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + + /bufferutil@4.0.8: + resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} + engines: {node: '>=6.14.2'} + requiresBuild: true + dependencies: + node-gyp-build: 4.6.1 + dev: false + + /camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: false + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: false + + /chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: false + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: false + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false + + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: false + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: false + + /cross-fetch@3.1.8: + resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + dev: false + + /crypto-hash@1.3.0: + resolution: {integrity: sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==} + engines: {node: '>=8'} + dev: false + + /dayjs@1.11.10: + resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} + dev: false + + /debug@3.2.7(supports-color@5.5.0): + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + supports-color: 5.5.0 + dev: true + + /delay@5.0.0: + resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} + engines: {node: '>=10'} + dev: false + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false + + /diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: false + + /dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dependencies: + no-case: 3.0.4 + tslib: 2.6.2 + dev: false + + /dotenv@16.3.1: + resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + engines: {node: '>=12'} + dev: false + + /es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + dev: false + + /es6-promisify@5.0.0: + resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + dependencies: + es6-promise: 4.2.8 + dev: false + + /eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + dev: false + + /eyes@0.1.8: + resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} + engines: {node: '> 0.1.90'} + dev: false + + /fast-stable-stringify@1.0.0: + resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + dev: false + + /file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + dev: false + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /follow-redirects@1.15.3: + resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: false + + /humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + dependencies: + ms: 2.1.3 + dev: false + + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: false + + /ignore-by-default@1.0.1: + resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + dev: true + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /isomorphic-ws@4.0.1(ws@7.5.9): + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + dependencies: + ws: 7.5.9 + dev: false + + /jayson@4.1.0: + resolution: {integrity: sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A==} + engines: {node: '>=8'} + hasBin: true + dependencies: + '@types/connect': 3.4.37 + '@types/node': 12.20.55 + '@types/ws': 7.4.7 + JSONStream: 1.3.5 + commander: 2.20.3 + delay: 5.0.0 + es6-promisify: 5.0.0 + eyes: 0.1.8 + isomorphic-ws: 4.0.1(ws@7.5.9) + json-stringify-safe: 5.0.1 + uuid: 8.3.2 + ws: 7.5.9 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + + /js-sha256@0.9.0: + resolution: {integrity: sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==} + dev: false + + /json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + dev: false + + /jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + dev: false + + /lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + dependencies: + tslib: 2.6.2 + dev: false + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: false + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + /no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + dependencies: + lower-case: 2.0.2 + tslib: 2.6.2 + dev: false + + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /node-gyp-build@4.6.1: + resolution: {integrity: sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==} + hasBin: true + requiresBuild: true + dev: false + + /nodemon@3.0.1: + resolution: {integrity: sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + chokidar: 3.5.3 + debug: 3.2.7(supports-color@5.5.0) + ignore-by-default: 1.0.1 + minimatch: 3.1.2 + pstree.remy: 1.1.8 + semver: 7.5.4 + simple-update-notifier: 2.0.0 + supports-color: 5.5.0 + touch: 3.1.0 + undefsafe: 2.0.5 + dev: true + + /nopt@1.0.10: + resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==} + hasBin: true + dependencies: + abbrev: 1.1.1 + dev: true + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /pako@2.1.0: + resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} + dev: false + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false + + /pstree.remy@1.1.8: + resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + dev: true + + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /regenerator-runtime@0.14.0: + resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + dev: false + + /rpc-websockets@7.6.1: + resolution: {integrity: sha512-MmRGaJJvxTHSRxYPjJJqcj2zWnCetw7YbYbKlD0Yc7qVw6PsZhRJg1MI3mpWlpBs+4zO+urlNfLl9zLsdOD/gA==} + dependencies: + '@babel/runtime': 7.23.2 + eventemitter3: 4.0.7 + uuid: 8.3.2 + ws: 8.14.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + dev: false + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: false + + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /simple-update-notifier@2.0.0: + resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} + engines: {node: '>=10'} + dependencies: + semver: 7.5.4 + dev: true + + /snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + dependencies: + dot-case: 3.0.4 + tslib: 2.6.2 + dev: false + + /superstruct@0.14.2: + resolution: {integrity: sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==} + dev: false + + /superstruct@0.15.5: + resolution: {integrity: sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ==} + dev: false + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: false + + /text-encoding-utf-8@1.0.2: + resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} + dev: false + + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: false + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /toml@3.0.0: + resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + dev: false + + /touch@3.1.0: + resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==} + hasBin: true + dependencies: + nopt: 1.0.10 + dev: true + + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + + /ts-node@10.9.1(@types/node@20.8.9)(typescript@5.2.2): + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.8.9 + acorn: 8.10.0 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.2.2 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: false + + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + dev: false + + /typescript@5.2.2: + resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} + engines: {node: '>=14.17'} + hasBin: true + dev: false + + /undefsafe@2.0.5: + resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + dev: true + + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: false + + /utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + requiresBuild: true + dependencies: + node-gyp-build: 4.6.1 + dev: false + + /uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + dev: false + + /v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: false + + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + + /ws@7.5.9: + resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + + /ws@8.14.2(bufferutil@4.0.8)(utf-8-validate@5.0.10): + resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + dev: false + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + + /yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: false diff --git a/examples/ek-instruction-parser/src/helpers/loadEnvironmentVariables.ts b/examples/ek-instruction-parser/src/helpers/loadEnvironmentVariables.ts new file mode 100644 index 0000000..93cb0cb --- /dev/null +++ b/examples/ek-instruction-parser/src/helpers/loadEnvironmentVariables.ts @@ -0,0 +1,27 @@ +import { config } from "dotenv"; + +config(); + +export type Environment = { + programHash: string; + transactionHash: string; + rpc_url: string; +}; + +export const getEnvironmentVariables = (): Environment => { + if (!process.env.PROGRAM_HASH) { + throw new Error("PROGRAM_HASH environment variable is not defined"); + } + if (!process.env.TRANSACTION_HASH) { + throw new Error("TRANSACTION_HASH environment variable is not defined"); + } + if (!process.env.RPC_URL) { + throw new Error("RPC_URL environment variable is not defined"); + } + + return { + programHash: process.env.PROGRAM_HASH, + transactionHash: process.env.TRANSACTION_HASH, + rpc_url: process.env.RPC_URL, + }; +}; diff --git a/examples/ek-instruction-parser/src/index.ts b/examples/ek-instruction-parser/src/index.ts new file mode 100644 index 0000000..e7d6b1c --- /dev/null +++ b/examples/ek-instruction-parser/src/index.ts @@ -0,0 +1,111 @@ +import { IdlItem, getProgramIdl } from "@solanafm/explorer-kit-idls"; +import { getEnvironmentVariables } from "./helpers/loadEnvironmentVariables"; +import { + InstructionParserInterface, + ParserType, + SolanaFMParser, + checkIfInstructionParser, +} from "@solanafm/explorer-kit"; +import fs from "fs"; +import axios from "axios"; + +const environment = getEnvironmentVariables(); + +const app = async () => { + const instructionParser = await setupParser(); + const transactionResponse = await axios.post(environment.rpc_url, { + jsonrpc: "2.0", + id: 1, + method: "getTransaction", + params: [ + environment.transactionHash, + { + encoding: "jsonParsed", + maxSupportedTransactionVersion: 0, + }, + ], + }); + + if (!transactionResponse.data.result) { + throw new Error("Transaction not found"); + } + + const transaction = transactionResponse.data.result; + + // Try to parse the program's instructions with ek parser + const instructions = transaction.transaction.message.instructions; + for (const instruction of instructions) { + if (instruction.programId === environment.programHash) { + const parsedInstruction = instructionParser.parseInstructions( + instruction.data, + instruction.accounts + ); + console.log("Parsed instruction, ", parsedInstruction); + } + } + + // Try to parse the program's inner instructions with ek parser + const innerInstructions = transaction.meta.innerInstructions; + for (const innerInstruction of innerInstructions) { + for (const innerObj of innerInstruction.instructions) { + if (!innerObj.parsed && innerObj.programId === environment.programHash) { + const parsedInnerInstruction = instructionParser.parseInstructions( + innerInstruction.data, + innerInstruction.accounts + ); + console.log("Parsed inner instruction, ", parsedInnerInstruction); + } + } + } +}; + +const setupParser = async () => { + const idlItemFromLibrary = await getProgramIdl(environment.programHash); + let instructionParser: InstructionParserInterface | undefined; + if (idlItemFromLibrary === null) { + instructionParser = setupParserFromLocalIdl(); + console.log("Successfully laoded parser from local idl file"); + } else { + const parser = new SolanaFMParser( + idlItemFromLibrary, + environment.programHash + ); + const registryParser = parser.createParser(ParserType.INSTRUCTION); + if (registryParser && checkIfInstructionParser(registryParser)) { + instructionParser = registryParser; + console.log("Successfully loaded parser from registry"); + } + } + + if (!instructionParser) { + throw new Error("Failed to load parser"); + } + return instructionParser; +}; + +const setupParserFromLocalIdl = () => { + const jsonString = fs.readFileSync("./idl.json", "utf8"); + const idlFile = JSON.parse(jsonString); + let idlType: "anchor" | "shank" | "kinobi" | string = ""; + if (!process.env.IDL_TYPE) { + throw new Error("IDL_TYPE environment variable is not defined"); + } + idlType = process.env.IDL_TYPE; + if (idlType !== "anchor" && idlType !== "shank" && idlType !== "kinobi") { + throw new Error(`IDL_TYPE ${idlType} is not valid`); + } + + const idlItem: IdlItem = { + programId: environment.programHash, + idl: idlFile, + idlType: idlType, + }; + + const parser = new SolanaFMParser(idlItem, environment.programHash); + const instructionsParser = parser.createParser(ParserType.INSTRUCTION); + if (instructionsParser && checkIfInstructionParser(instructionsParser)) { + return instructionsParser; + } +}; + +app(); diff --git a/examples/ek-instruction-parser/tsconfig.json b/examples/ek-instruction-parser/tsconfig.json new file mode 100644 index 0000000..e075f97 --- /dev/null +++ b/examples/ek-instruction-parser/tsconfig.json @@ -0,0 +1,109 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} From 65d4336f4a73407f9af8199e68b863d77b06cad5 Mon Sep 17 00:00:00 2001 From: Zamiel Chia Date: Fri, 27 Oct 2023 19:16:00 +0800 Subject: [PATCH 2/8] docs: add issues template --- .github/ISSUE_TEMPLATE/bug_report.md | 38 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..dd84ea7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..bbcbbe7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From 258a9f7b883c2847c84f24ddb40d188185cabb00 Mon Sep 17 00:00:00 2001 From: zamielchia Date: Fri, 27 Oct 2023 19:56:44 +0800 Subject: [PATCH 3/8] docs: Update README.md to add contributing and badges --- README.md | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 213 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 359224f..71e6bc1 100644 --- a/README.md +++ b/README.md @@ -1 +1,213 @@ -# SolanaFM ExplorerKit +

+ + SolanaFM logo + +

+ +

Solana Data Parser for Developers

+

Framework agnostic and can be used by anyone, everywhere

+
+ +

+ + + + + + +

+
+ +## Features + +- 📦 **Framework agnostic** - Use it with any framework you want +- ♻️ **Space efficient** - Reduce package size overhead as you don't have to generate SDKs for your project to use +- 🧑‍💻 **User friendly** - Easy to use and understand + +## Getting Started + +### ⚡️ Installation + +Install ExplorerKit with these simple commands: + +- Use any package manager that you desire to install ExplorerKit + +Using **npm**: + +```bash +npm add @solanafm/explorer-kit +npm add @solanafm/explorer-kit-idls +``` + +Using **yarn**: + +```bash +yarn add @solanafm/explorer-kit +yarn add @solanafm/explorer-kit-idls +``` + +Using **pnpm**: + +```bash +pnpm add @solanafm/explorer-kit +pnpm add @solanafm/explorer-kit-idls +``` + +Once the packages have been installed, you can start using ExplorerKit in your project 🎉 + +### 🚀 Usage + +How to get a SolanaFM IdlItem to start parsing a transaction or account state for a particular program: + +```ts +import { getProgramIdl } from "@solanafm/explorer-kit-idls"; + +const programId = "PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY"; +// Get the IDL for a specific program hash +const SFMIdlItem = await getProgramIdl(programId); +// You can also get an IDL at a specific slot context if you're trying to histroically parse a transaction / account +// but the IDL might not be backwards compatible. +const historicalSFMIdlItem = await getProgramIdl(programId, { + slotContext: 132322893, +}); +```**** + +Parsing a transaction: + +```ts +import { SolanaFMParser. checkIfInstructionParser, ParserType } from "@solanafm/explorer-kit" +import { getProgramIdl } from "@solanafm/explorer-kit-idls"; + +const programId = "PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY"; +// Get the IDL for a specific program hash +const SFMIdlItem = await getProgramIdl(programId); +// You can also get an IDL at a specific slot context if you're trying to histroically parse a transaction / account +// but the IDL might not be backwards compatible. +const historicalSFMIdlItem = await getProgramIdl(programId, { + slotContext: 132322893, +}); +// For now, we only support parsing transactions with an encoded base 58 message +const ixData = "1AMTAauCh9UPEJKKd6LnGGtWqFvRs2aUZkv9r6wNe3PTzB1KS9TbwYzM8Cp7vUSDYZXTxXJp5M" +// Checks if SFMIdlItem is defined, if not you will not be able to initialize the parser layout +if (SFMIdlItem) { + const parser = new SolanaFMParser(SFMIdlItem); + const instructionParser = parser.createParser(ParserType.INSTRUCTION); + + if (instructionParser && checkIfInstructionParser(instructionParser)) { + // Parse the transaction + const decodedData = parser.parseTransaction(ixData); + } +} +``` + +Parsing an event data: + +```ts +import { SolanaFMParser. checkIfEventParser, ParserType } from "@solanafm/explorer-kit" + +// For event data they have to base-64 encoded and they can be extracted from logs or a inner instruction with CPI logs. +// Phoenix Program Event Data +const eventData = "DwEABF2SDQAAAABDfDtlAAAAAKiVfA0AAAAAL9p3EN7QVm+wCbiCUn2jVyJyazsZQYgqVRhf6h2a/pX5SjR+9eBu2sQU7NYr1TEeH7vRFNOiXSyDLJ9g+fDJrwMAAgAABPzrK7CsLqR5NiVFXYwyp7QgatDNQXbn3JA8wOVXQfANFxMTAAAAAIB/AAAAAAAAg7MAAAAAAAAAAAAAAAAAAAIBAAT86yuwrC6keTYlRV2MMqe0IGrQzUF259yQPMDlV0HwDhcTEwAAAACCfwAAAAAAAByBAAAAAAAA6EwCAAAAAAAGAgAAAAAAAAAAAAAAAAAAAAAAnzQBAAAAAABzEb6ZAAAAALveBwAAAAAA" +const parser = new SolanaFMParser(SFMIdlItem); +const eventParser = parser.createParser(ParserType.EVENT); + +if (eventParser && checkIfEventParser(eventParser)) { + // Parse the transaction + const decodedData = parser.parseEvents(eventData); +} +``` + +Parsing an account data: + +```ts +import { SolanaFMParser. checkIfAccountParser, ParserType } from "@solanafm/explorer-kit" + +// Account data have to be base-64 encoded +// Stake Pool Account Data +const accountData = "AWq1iyr99ATwNekhxZcljopQjeBixmWt+p/5CTXBmRbd3Noj1MlCDU6CVh08awajdvCUB/G3tPyo/emrHFdD8Wfh4Pippvxf8kLk81F78B7Wst0ZUaC6ttlDVyWShgT3cP/LqkIDCUdVLBkThURwDuYX1RR+JyWBHNvgnIkDCm914o2jckW1NrCzDbv9Jn/RWcT0cAMYKm8U4SfG/F878wV0XwxEYxirEMlfQJSVhXDNBXRlpU2rFNnd40gahv7V/Mvj/aPav/vdTOwRdFALTRZQlijB9G5myz+0QWe7U7EGIQbd9uHXZaGT2cvhRs7reawctIXtX1s3kTqM9YV+/wCpE2P1ZIWKAQDUAp5GdmQBAMkBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQJwAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAECcAAAAAAAAAAAAAAAAAAABWHWK1dGQBAAgnQqFYigEAv0rw1gHIAQAPfXpGLPQBABAnAAAAAAAAAAAAAAAAAAAAicd7jscBANVMdCNW7gEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; + +const parser = new SolanaFMParser(SFMIdlItem); +const eventParser = parser.createParser(ParserType.ACCOUNT); + +if (eventParser && checkIfAccountParser(eventParser)) { + // Parse the transaction + const decodedData = parser.parseAccount(accountData); +} +``` + +Once the data is parsed, the returned data type will look something like this + +```ts +export type ParserOutput = { + // The name of the struct that's being used to parse the data + name: string; + // The parsed data according to the IDL schema + data: any; + // ParserType depends on the type of parser you have initialized + type: ParserType; +} | null; + +``` + +More to be added soon... + +You can also checkout the [examples](https://github.com/solana-fm/explorer-kit/examples) as well! + +## Caveats and Limitations + +- IDLs found in `@solanafm/explorer-kit-idls` are usually IDLs for programs that are immutable and are not expected to change. These IDLs can be imported directly from the package and used in your project without interacting with our API. If you wish to get the latest IDLs that might be on chain, `getProgramIdl()` will do a API call to our API to query for the relevant IDLs +- **Account** and **Event** parsers only takes in a `base64` encoded string at the moment +- **Instruction** parsers only takes in a `base58` encoded string at the moment + +## Supported Programs + + | Program IDs | Program | Working Parsers | +|-----------------------------------------------------------------------------------------|--------------------------------|----------------------------------------------| +| 11111111111111111111111111111111 | System Program | Account, Instructions | +| Config1111111111111111111111111111111111111 | Config Program | Account, Instructions | +| Stake11111111111111111111111111111111111111 | Stake Program | Account, Instructions | +| Vote111111111111111111111111111111111111111 | Vote Program | Account, Instructions | +| ComputeBudget111111111111111111111111111111 | Compute Budget Program | Instructions | +| BPFLoaderUpgradeab1e11111111111111111111111 | BPF Upgradeable Loader Program | Account, Instructions | +| TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA | Token Program | Account, Instructions | +| TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb | Token 2022 Program | Account, Instructions, Extensions (built-in) | +| namesLPneVptA9Z5rqUDD9tMTWEJwofgaYwp8cawRkX | Name Service Program | Account, Instructions | +| SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy | Stake Pool Program | Account, Instructions | +| ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL | Associated Token Program | Instructions | +| PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY | Phoenix Program | Account, Instructions, Events | +| metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s | Token Metadata Program | Account, Instructions | +| auth9SigNpDKz4sJJ1DfCTuZrZNSAgh9sFD3rboVmgg | Token Auth Rules Program | Instructions | +| AddressLookupTab1e1111111111111111111111111 | Address Lookup Table | Account, Instructions | +| SysvarC1ock11111111111111111111111111111111 | Clock Sysvar | Account | +| SysvarEpochSchedu1e111111111111111111111111 | Epoch Schedule Sysvar | Account | +| SysvarFees111111111111111111111111111111111 | Fees Sysvar | Account | +| SysvarRecentB1ockHashes11111111111111111111 | Recent Blockhashes Sysvar | Account | +| SysvarRent111111111111111111111111111111111 | Rent Sysvar | Account | +| SysvarRewards111111111111111111111111111111 | Rewards Sysvar | Account | +| SysvarS1otHashes111111111111111111111111111 | Slot Hashes Sysvar | Account | +| SysvarStakeHistory1111111111111111111111111 | Stake History Sysvar | Account | +| MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo | Memo Program | Instructions | +| cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK | SPL Account Compression | Instructions, Events | +| BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY | Bubblegum | Instructions, Events | +| TCMPhJdwDryooaGtiocG1u3xcYbRpiJzb283XfCZsDp | Tensor Compression | Instructions, Events | + +And many more programs that have their IDLs uploaded on chain. Feel free to contact anyone in the team or open a pull request to have your IDLs added to the list! + +## Credits + +Explorer Kit is hugely inspired and built upon [Kinobi](https://github.com/metaplex-foundation/kinobi). Without Kinobi, Explorer Kit would not have been possible at it's current iteration. + +Also, huge thanks to the following projects and engineers for making this possible: + +- [Loris](https://github.com/lorisleiva) - For all the work and help he has poured into Kinobi and Umi +- [Umi](https://github.com/metaplex-foundation/umi) - Usage of their deserializers to decode the various data types +- [Kinobi](https://github.com/metaplex-foundation/kinobi) - Kinobi parsing of IDLs to a Kinobi Tree has been a great inspiration in creating a layout to be stored in memory for deserialization +- [Anchor](https://github.com/coral-xyz/anchor/tree/master) + +## Contributing + +We welcome all contributions to Explorer Kit! Feel free to open a pull request or issues to discuss your ideas and suggestions. You may checkout our [contributing guide](/CONTRIBUTING.md) for more information on how to contribute to Explorer Kit. + +## License + +Explorer Kit is licensed under the [GNU v3](/LICENSE) From 512265a9e5b347a07be8e9bc8845dacc9ef8efe8 Mon Sep 17 00:00:00 2001 From: zamielchia Date: Fri, 27 Oct 2023 19:56:57 +0800 Subject: [PATCH 4/8] docs: Add CONTRIBUTING.md --- CONTRIBUTING.MD | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 CONTRIBUTING.MD diff --git a/CONTRIBUTING.MD b/CONTRIBUTING.MD new file mode 100644 index 0000000..3a6dd7e --- /dev/null +++ b/CONTRIBUTING.MD @@ -0,0 +1,75 @@ +# Contributing + +## Table of contents + +- [Contributing](#contributing) + - [Table of contents](#table-of-contents) + - [Setting Up the Environment](#setting-up-the-environment) + - [Running Tests](#running-tests) + - [Submitting a Pull Request (PR)](#submitting-a-pull-request-pr) + - [After your pull request is merged](#after-your-pull-request-is-merged) + +## Setting Up the Environment + +1. Run `pnpm install` in the root of the repository to install all dependencies. +2. Run `pnpm build` to create an initial build of the `explorerkit-idls` and `explorerkit-translator` +3. You should now be able to edit the source code to your liking and run `pnpm dev` to ensure that your changes are being watched +4. After you are dong with your changes, you can write test cases in the `tests` folder of the root of the package to ensure that your changes work as expected. You can run `pnpm test` in the root of the repository to run all the tests in the repository. + +## Running Tests + +You can run the tests of the project that you modified by going to the project's directory and running: + +```bash +pnpm test +``` + +Alternatively, you can run it from anywhere by specifying the name of the project using the `--filter` option: + +```bash +pnpm --filter @solanafm/explorerkit-idls +``` + +## Submitting a Pull Request (PR) + +Before you submit your Pull Request (PR), do remember to generate a changeset by running `npx changeset` in the root of the repository. This will generate a changeset that will be used during release. + +```bash +npx changeset +``` + +- Summarise the changes you have done for this PR and also include the changeset files in your commit when you are submitting your PR. +- Ensure that your PR is up to date with the latest changes from the main branch. You can do this by running `git pull --rebase upstream main` in the root of the repository. +- Ensure that your PR passes all the tests. You can do this by running `pnpm test` in the root of the repository. +- Once everything has been done, you can submit your PR to the `main` branch of the repository. + +That's it! Thank you for your contribution! + +### After your pull request is merged + +After your pull request is merged, you can safely delete your branch and pull the changes +from the main (upstream) repository: + +- Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows: + + ```bash + git push origin --delete my-fix-branch + ``` + +- Check out the main branch: + + ```bash + git checkout main -f + ``` + +- Delete the local branch: + + ```bash + git branch -D my-fix-branch + ``` + +- Update your main with the latest upstream version: + + ```bash + git pull --ff upstream main + ``` From 695e2c78f6c5ef4f6dfeef82d4bc08b53a8073d0 Mon Sep 17 00:00:00 2001 From: zamielchia Date: Fri, 27 Oct 2023 20:05:10 +0800 Subject: [PATCH 5/8] docs: Add logo image for README.md --- images/logo.png | Bin 0 -> 83567 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/logo.png diff --git a/images/logo.png b/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3fe56da27c0293f5e7c1965ed5282a88e6247ea1 GIT binary patch literal 83567 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%0DX?)HHoln#n@{{CBV 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ͅ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 Date: Fri, 27 Oct 2023 20:06:51 +0800 Subject: [PATCH 6/8] docs: Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 71e6bc1..812ed39 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ const SFMIdlItem = await getProgramIdl(programId); const historicalSFMIdlItem = await getProgramIdl(programId, { slotContext: 132322893, }); -```**** +``` Parsing a transaction: From f7a9815c619956eaa426ef6df13d9924af06ca71 Mon Sep 17 00:00:00 2001 From: linsyhen99 Date: Fri, 27 Oct 2023 17:47:43 +0800 Subject: [PATCH 7/8] Adding example usages of the parser to parse instructions and parse events Signed-off-by: linsyhen99 --- examples/ek-event-parser/.env.example | 2 + examples/ek-event-parser/.gitignore | 6 + examples/ek-event-parser/README.md | 1 + examples/ek-event-parser/package.json | 25 + examples/ek-event-parser/pnpm-lock.yaml | 1060 +++++++++++++++++ .../src/constants/programLogsConstant.ts | 4 + .../src/helpers/eventParser.ts | 112 ++ .../src/helpers/loadEnvironmentVariables.ts | 17 + examples/ek-event-parser/src/index.ts | 125 ++ .../src/models/logContextStack.ts | 15 + .../src/models/logExtractor.ts | 12 + examples/ek-event-parser/tsconfig.json | 109 ++ examples/ek-instruction-parser/.env.example | 4 + examples/ek-instruction-parser/.gitignore | 5 + examples/ek-instruction-parser/README.md | 1 + examples/ek-instruction-parser/package.json | 26 + examples/ek-instruction-parser/pnpm-lock.yaml | 1060 +++++++++++++++++ .../src/helpers/loadEnvironmentVariables.ts | 27 + examples/ek-instruction-parser/src/index.ts | 111 ++ examples/ek-instruction-parser/tsconfig.json | 109 ++ 20 files changed, 2831 insertions(+) create mode 100644 examples/ek-event-parser/.env.example create mode 100644 examples/ek-event-parser/.gitignore create mode 100644 examples/ek-event-parser/README.md create mode 100644 examples/ek-event-parser/package.json create mode 100644 examples/ek-event-parser/pnpm-lock.yaml create mode 100644 examples/ek-event-parser/src/constants/programLogsConstant.ts create mode 100644 examples/ek-event-parser/src/helpers/eventParser.ts create mode 100644 examples/ek-event-parser/src/helpers/loadEnvironmentVariables.ts create mode 100644 examples/ek-event-parser/src/index.ts create mode 100644 examples/ek-event-parser/src/models/logContextStack.ts create mode 100644 examples/ek-event-parser/src/models/logExtractor.ts create mode 100644 examples/ek-event-parser/tsconfig.json create mode 100644 examples/ek-instruction-parser/.env.example create mode 100644 examples/ek-instruction-parser/.gitignore create mode 100644 examples/ek-instruction-parser/README.md create mode 100644 examples/ek-instruction-parser/package.json create mode 100644 examples/ek-instruction-parser/pnpm-lock.yaml create mode 100644 examples/ek-instruction-parser/src/helpers/loadEnvironmentVariables.ts create mode 100644 examples/ek-instruction-parser/src/index.ts create mode 100644 examples/ek-instruction-parser/tsconfig.json diff --git a/examples/ek-event-parser/.env.example b/examples/ek-event-parser/.env.example new file mode 100644 index 0000000..ebecb4c --- /dev/null +++ b/examples/ek-event-parser/.env.example @@ -0,0 +1,2 @@ +PROGRAM_HASH= +IDL_TYPE= \ No newline at end of file diff --git a/examples/ek-event-parser/.gitignore b/examples/ek-event-parser/.gitignore new file mode 100644 index 0000000..df27cb0 --- /dev/null +++ b/examples/ek-event-parser/.gitignore @@ -0,0 +1,6 @@ +.idea/ +node_modules/ +.env +idl.json +.DS_Store + diff --git a/examples/ek-event-parser/README.md b/examples/ek-event-parser/README.md new file mode 100644 index 0000000..9bb27c7 --- /dev/null +++ b/examples/ek-event-parser/README.md @@ -0,0 +1 @@ +# event-parsing-with-ek diff --git a/examples/ek-event-parser/package.json b/examples/ek-event-parser/package.json new file mode 100644 index 0000000..fe9bb52 --- /dev/null +++ b/examples/ek-event-parser/package.json @@ -0,0 +1,25 @@ +{ + "name": "ek-event-parser", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "dev": "nodemon --exec ts-node src/index.ts", + "build": "tsc --outDir dist", + "clean": "rm -r dist && rm -r node_modules" + }, + "author": "", + "license": "ISC", + "dependencies": { + "@solanafm/explorer-kit": "^1.0.0", + "@solanafm/explorer-kit-idls": "^1.0.0", + "@types/node": "^20.8.7", + "axios": "^1.5.1", + "dotenv": "^16.3.1", + "ts-node": "^10.9.1", + "typescript": "^5.2.2" + }, + "devDependencies": { + "nodemon": "^3.0.1" + } +} \ No newline at end of file diff --git a/examples/ek-event-parser/pnpm-lock.yaml b/examples/ek-event-parser/pnpm-lock.yaml new file mode 100644 index 0000000..77121ac --- /dev/null +++ b/examples/ek-event-parser/pnpm-lock.yaml @@ -0,0 +1,1060 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + '@solanafm/explorer-kit': + specifier: ^1.0.0 + version: 1.0.0 + '@solanafm/explorer-kit-idls': + specifier: ^1.0.0 + version: 1.0.0 + '@types/node': + specifier: ^20.8.7 + version: 20.8.7 + axios: + specifier: ^1.5.1 + version: 1.5.1 + dotenv: + specifier: ^16.3.1 + version: 16.3.1 + ts-node: + specifier: ^10.9.1 + version: 10.9.1(@types/node@20.8.7)(typescript@5.2.2) + typescript: + specifier: ^5.2.2 + version: 5.2.2 + +devDependencies: + nodemon: + specifier: ^3.0.1 + version: 3.0.1 + +packages: + + /@babel/runtime@7.23.2: + resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.0 + dev: false + + /@coral-xyz/anchor@0.27.0: + resolution: {integrity: sha512-+P/vPdORawvg3A9Wj02iquxb4T0C5m4P6aZBVYysKl4Amk+r6aMPZkUhilBkD6E4Nuxnoajv3CFykUfkGE0n5g==} + engines: {node: '>=11'} + dependencies: + '@coral-xyz/borsh': 0.27.0(@solana/web3.js@1.87.2) + '@solana/web3.js': 1.87.2 + base64-js: 1.5.1 + bn.js: 5.2.1 + bs58: 4.0.1 + buffer-layout: 1.2.2 + camelcase: 6.3.0 + cross-fetch: 3.1.8 + crypto-hash: 1.3.0 + eventemitter3: 4.0.7 + js-sha256: 0.9.0 + pako: 2.1.0 + snake-case: 3.0.4 + superstruct: 0.15.5 + toml: 3.0.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@coral-xyz/anchor@0.28.1-beta.2: + resolution: {integrity: sha512-xreUcOFF8+IQKWOBUrDKJbIw2ftpRVybFlEPVrbSlOBCbreCWrQ5754Gt9cHIcuBDAzearCDiBqzsGQdNgPJiw==} + engines: {node: '>=11'} + dependencies: + '@coral-xyz/borsh': 0.28.0(@solana/web3.js@1.87.2) + '@noble/hashes': 1.3.2 + '@solana/web3.js': 1.87.2 + base64-js: 1.5.1 + bn.js: 5.2.1 + bs58: 4.0.1 + buffer-layout: 1.2.2 + camelcase: 6.3.0 + cross-fetch: 3.1.8 + crypto-hash: 1.3.0 + eventemitter3: 4.0.7 + pako: 2.1.0 + snake-case: 3.0.4 + superstruct: 0.15.5 + toml: 3.0.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@coral-xyz/borsh@0.27.0(@solana/web3.js@1.87.2): + resolution: {integrity: sha512-tJKzhLukghTWPLy+n8K8iJKgBq1yLT/AxaNd10yJrX8mI56ao5+OFAKAqW/h0i79KCvb4BK0VGO5ECmmolFz9A==} + engines: {node: '>=10'} + peerDependencies: + '@solana/web3.js': ^1.68.0 + dependencies: + '@solana/web3.js': 1.87.2 + bn.js: 5.2.1 + buffer-layout: 1.2.2 + dev: false + + /@coral-xyz/borsh@0.28.0(@solana/web3.js@1.87.2): + resolution: {integrity: sha512-/u1VTzw7XooK7rqeD7JLUSwOyRSesPUk0U37BV9zK0axJc1q0nRbKFGFLYCQ16OtdOJTTwGfGp11Lx9B45bRCQ==} + engines: {node: '>=10'} + peerDependencies: + '@solana/web3.js': ^1.68.0 + dependencies: + '@solana/web3.js': 1.87.2 + bn.js: 5.2.1 + buffer-layout: 1.2.2 + dev: false + + /@cspotcode/source-map-support@0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: false + + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + dev: false + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: false + + /@jridgewell/trace-mapping@0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: false + + /@metaplex-foundation/umi-options@0.8.9: + resolution: {integrity: sha512-jSQ61sZMPSAk/TXn8v8fPqtz3x8d0/blVZXLLbpVbo2/T5XobiI6/MfmlUosAjAUaQl6bHRF8aIIqZEFkJiy4A==} + dev: false + + /@metaplex-foundation/umi-public-keys@0.8.9: + resolution: {integrity: sha512-CxMzN7dgVGOq9OcNCJe2casKUpJ3RmTVoOvDFyeoTQuK+vkZ1YSSahbqC1iGuHEtKTLSjtWjKvUU6O7zWFTw3Q==} + dependencies: + '@metaplex-foundation/umi-serializers-encodings': 0.8.9 + dev: false + + /@metaplex-foundation/umi-serializers-core@0.8.9: + resolution: {integrity: sha512-WT82tkiYJ0Qmscp7uTj1Hz6aWQPETwaKLAENAUN5DeWghkuBKtuxyBKVvEOuoXerJSdhiAk0e8DWA4cxcTTQ/w==} + dev: false + + /@metaplex-foundation/umi-serializers-encodings@0.8.9: + resolution: {integrity: sha512-N3VWLDTJ0bzzMKcJDL08U3FaqRmwlN79FyE4BHj6bbAaJ9LEHjDQ9RJijZyWqTm0jE7I750fU7Ow5EZL38Xi6Q==} + dependencies: + '@metaplex-foundation/umi-serializers-core': 0.8.9 + dev: false + + /@metaplex-foundation/umi-serializers-numbers@0.8.9: + resolution: {integrity: sha512-NtBf1fnVNQJHFQjLFzRu2i9GGnigb9hOm/Gfrk628d0q0tRJB7BOM3bs5C61VAs7kJs4yd+pDNVAERJkknQ7Lg==} + dependencies: + '@metaplex-foundation/umi-serializers-core': 0.8.9 + dev: false + + /@metaplex-foundation/umi-serializers@0.8.9: + resolution: {integrity: sha512-Sve8Etm3zqvLSUfza+MYRkjTnCpiaAFT7VWdqeHzA3n58P0AfT3p74RrZwVt/UFkxI+ln8BslwBDJmwzcPkuHw==} + dependencies: + '@metaplex-foundation/umi-options': 0.8.9 + '@metaplex-foundation/umi-public-keys': 0.8.9 + '@metaplex-foundation/umi-serializers-core': 0.8.9 + '@metaplex-foundation/umi-serializers-encodings': 0.8.9 + '@metaplex-foundation/umi-serializers-numbers': 0.8.9 + dev: false + + /@metaplex-foundation/umi@0.8.9: + resolution: {integrity: sha512-Gip7HPDCjsX7OakPFBiifX89AofUGcsj/ujbvOfd/6GDIL4XjX79royuT3yyxzovRxyiaPF/kCK6a2dKtm69Kw==} + dependencies: + '@metaplex-foundation/umi-options': 0.8.9 + '@metaplex-foundation/umi-public-keys': 0.8.9 + '@metaplex-foundation/umi-serializers': 0.8.9 + dev: false + + /@noble/curves@1.2.0: + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + dependencies: + '@noble/hashes': 1.3.2 + dev: false + + /@noble/hashes@1.3.2: + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + dev: false + + /@solana/buffer-layout@4.0.1: + resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} + engines: {node: '>=5.10'} + dependencies: + buffer: 6.0.3 + dev: false + + /@solana/web3.js@1.87.2: + resolution: {integrity: sha512-TZNhS+tvJbYjm0LAvIkUy/3Aqgt2l6/3X6XsVUpvj5MGOl2Q6Ch8hYSxcUUtMbAFNN3sUXmV8NhhMLNJEvI6TA==} + dependencies: + '@babel/runtime': 7.23.2 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.0 + node-fetch: 2.7.0 + rpc-websockets: 7.6.1 + superstruct: 0.14.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@solanafm/explorer-kit-idls@1.0.0: + resolution: {integrity: sha512-5ykQlPW4rA9sS5RvsiG/66lceI6rmPkyIubam795vrkP+cVW6A9W3kXV1A1o5zZUzIHQO/X8HA5JSItelnZsKQ==} + dependencies: + '@coral-xyz/anchor': 0.27.0 + '@solanafm/kinobi-lite': 0.12.0 + axios: 1.5.1 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - utf-8-validate + dev: false + + /@solanafm/explorer-kit@1.0.0: + resolution: {integrity: sha512-xKeG+SZ8gZBlM1re+Udlm6AhDYtL7v6f4IW/GL+YIqOvD5Wz4GI23Em7qWfVo9bwsR4nN2bS+IOpBsYX5GGRMw==} + dependencies: + '@coral-xyz/anchor': 0.28.1-beta.2 + '@metaplex-foundation/umi': 0.8.9 + '@metaplex-foundation/umi-serializers': 0.8.9 + '@solanafm/kinobi-lite': 0.12.0 + '@solanafm/utils': 0.3.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@solanafm/kinobi-lite@0.12.0: + resolution: {integrity: sha512-K3daAv8HoJzM6UiDUG1Tj0tZIcCSJENmqx5nw4J2+sOwyZm1leFvVkIHM+WOExh/IqI7PglipRJbrF0OXN007Q==} + dependencies: + '@noble/hashes': 1.3.2 + chalk: 4.1.2 + dev: false + + /@solanafm/utils@0.3.0: + resolution: {integrity: sha512-SI0Q+PIH+t9gT4cPrLVKlPpjhByHFunyL01j/VfI2sBlBueuyCpO9PgpK/VQA2sZ8wdDqhq2g6gatzuNnlLJiQ==} + dependencies: + '@metaplex-foundation/umi-options': 0.8.9 + bn.js: 5.2.1 + bs58: 5.0.0 + dayjs: 1.11.10 + dev: false + + /@tsconfig/node10@1.0.9: + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + dev: false + + /@tsconfig/node12@1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: false + + /@tsconfig/node14@1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: false + + /@tsconfig/node16@1.0.4: + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + dev: false + + /@types/connect@3.4.37: + resolution: {integrity: sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q==} + dependencies: + '@types/node': 20.8.7 + dev: false + + /@types/node@12.20.55: + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + dev: false + + /@types/node@20.8.7: + resolution: {integrity: sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==} + dependencies: + undici-types: 5.25.3 + dev: false + + /@types/ws@7.4.7: + resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + dependencies: + '@types/node': 20.8.7 + dev: false + + /JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + dev: false + + /abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + dev: true + + /acorn-walk@8.2.0: + resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + engines: {node: '>=0.4.0'} + dev: false + + /acorn@8.10.0: + resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: false + + /agentkeepalive@4.5.0: + resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} + engines: {node: '>= 8.0.0'} + dependencies: + humanize-ms: 1.2.1 + dev: false + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: false + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: false + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + + /axios@1.5.1: + resolution: {integrity: sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==} + dependencies: + follow-redirects: 1.15.3 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /base-x@3.0.9: + resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /base-x@4.0.0: + resolution: {integrity: sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==} + dev: false + + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: false + + /bigint-buffer@1.1.5: + resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} + engines: {node: '>= 10.0.0'} + requiresBuild: true + dependencies: + bindings: 1.5.0 + dev: false + + /binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + dependencies: + file-uri-to-path: 1.0.0 + dev: false + + /bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + dev: false + + /borsh@0.7.0: + resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + dependencies: + bn.js: 5.2.1 + bs58: 4.0.1 + text-encoding-utf-8: 1.0.2 + dev: false + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + dependencies: + base-x: 3.0.9 + dev: false + + /bs58@5.0.0: + resolution: {integrity: sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==} + dependencies: + base-x: 4.0.0 + dev: false + + /buffer-layout@1.2.2: + resolution: {integrity: sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==} + engines: {node: '>=4.5'} + dev: false + + /buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + + /bufferutil@4.0.8: + resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} + engines: {node: '>=6.14.2'} + requiresBuild: true + dependencies: + node-gyp-build: 4.6.1 + dev: false + + /camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: false + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: false + + /chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: false + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: false + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false + + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: false + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: false + + /cross-fetch@3.1.8: + resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + dev: false + + /crypto-hash@1.3.0: + resolution: {integrity: sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==} + engines: {node: '>=8'} + dev: false + + /dayjs@1.11.10: + resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} + dev: false + + /debug@3.2.7(supports-color@5.5.0): + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + supports-color: 5.5.0 + dev: true + + /delay@5.0.0: + resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} + engines: {node: '>=10'} + dev: false + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false + + /diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: false + + /dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dependencies: + no-case: 3.0.4 + tslib: 2.6.2 + dev: false + + /dotenv@16.3.1: + resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + engines: {node: '>=12'} + dev: false + + /es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + dev: false + + /es6-promisify@5.0.0: + resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + dependencies: + es6-promise: 4.2.8 + dev: false + + /eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + dev: false + + /eyes@0.1.8: + resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} + engines: {node: '> 0.1.90'} + dev: false + + /fast-stable-stringify@1.0.0: + resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + dev: false + + /file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + dev: false + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /follow-redirects@1.15.3: + resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: false + + /humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + dependencies: + ms: 2.1.3 + dev: false + + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: false + + /ignore-by-default@1.0.1: + resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + dev: true + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /isomorphic-ws@4.0.1(ws@7.5.9): + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + dependencies: + ws: 7.5.9 + dev: false + + /jayson@4.1.0: + resolution: {integrity: sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A==} + engines: {node: '>=8'} + hasBin: true + dependencies: + '@types/connect': 3.4.37 + '@types/node': 12.20.55 + '@types/ws': 7.4.7 + JSONStream: 1.3.5 + commander: 2.20.3 + delay: 5.0.0 + es6-promisify: 5.0.0 + eyes: 0.1.8 + isomorphic-ws: 4.0.1(ws@7.5.9) + json-stringify-safe: 5.0.1 + uuid: 8.3.2 + ws: 7.5.9 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + + /js-sha256@0.9.0: + resolution: {integrity: sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==} + dev: false + + /json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + dev: false + + /jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + dev: false + + /lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + dependencies: + tslib: 2.6.2 + dev: false + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: false + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + /no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + dependencies: + lower-case: 2.0.2 + tslib: 2.6.2 + dev: false + + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /node-gyp-build@4.6.1: + resolution: {integrity: sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==} + hasBin: true + requiresBuild: true + dev: false + + /nodemon@3.0.1: + resolution: {integrity: sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + chokidar: 3.5.3 + debug: 3.2.7(supports-color@5.5.0) + ignore-by-default: 1.0.1 + minimatch: 3.1.2 + pstree.remy: 1.1.8 + semver: 7.5.4 + simple-update-notifier: 2.0.0 + supports-color: 5.5.0 + touch: 3.1.0 + undefsafe: 2.0.5 + dev: true + + /nopt@1.0.10: + resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==} + hasBin: true + dependencies: + abbrev: 1.1.1 + dev: true + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /pako@2.1.0: + resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} + dev: false + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false + + /pstree.remy@1.1.8: + resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + dev: true + + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /regenerator-runtime@0.14.0: + resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + dev: false + + /rpc-websockets@7.6.1: + resolution: {integrity: sha512-MmRGaJJvxTHSRxYPjJJqcj2zWnCetw7YbYbKlD0Yc7qVw6PsZhRJg1MI3mpWlpBs+4zO+urlNfLl9zLsdOD/gA==} + dependencies: + '@babel/runtime': 7.23.2 + eventemitter3: 4.0.7 + uuid: 8.3.2 + ws: 8.14.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + dev: false + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: false + + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /simple-update-notifier@2.0.0: + resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} + engines: {node: '>=10'} + dependencies: + semver: 7.5.4 + dev: true + + /snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + dependencies: + dot-case: 3.0.4 + tslib: 2.6.2 + dev: false + + /superstruct@0.14.2: + resolution: {integrity: sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==} + dev: false + + /superstruct@0.15.5: + resolution: {integrity: sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ==} + dev: false + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: false + + /text-encoding-utf-8@1.0.2: + resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} + dev: false + + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: false + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /toml@3.0.0: + resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + dev: false + + /touch@3.1.0: + resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==} + hasBin: true + dependencies: + nopt: 1.0.10 + dev: true + + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + + /ts-node@10.9.1(@types/node@20.8.7)(typescript@5.2.2): + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.8.7 + acorn: 8.10.0 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.2.2 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: false + + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + dev: false + + /typescript@5.2.2: + resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} + engines: {node: '>=14.17'} + hasBin: true + dev: false + + /undefsafe@2.0.5: + resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + dev: true + + /undici-types@5.25.3: + resolution: {integrity: sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==} + dev: false + + /utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + requiresBuild: true + dependencies: + node-gyp-build: 4.6.1 + dev: false + + /uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + dev: false + + /v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: false + + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + + /ws@7.5.9: + resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + + /ws@8.14.2(bufferutil@4.0.8)(utf-8-validate@5.0.10): + resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + dev: false + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + + /yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: false diff --git a/examples/ek-event-parser/src/constants/programLogsConstant.ts b/examples/ek-event-parser/src/constants/programLogsConstant.ts new file mode 100644 index 0000000..74eeb9b --- /dev/null +++ b/examples/ek-event-parser/src/constants/programLogsConstant.ts @@ -0,0 +1,4 @@ +export const PROGRAM_LOG = "Program log: "; +export const PROGRAM_DATA = "Program data: "; +export const PROGRAM_LOG_START_INDEX = PROGRAM_LOG.length; +export const PROGRAM_DATA_START_INDEX = PROGRAM_DATA.length; diff --git a/examples/ek-event-parser/src/helpers/eventParser.ts b/examples/ek-event-parser/src/helpers/eventParser.ts new file mode 100644 index 0000000..a6f9307 --- /dev/null +++ b/examples/ek-event-parser/src/helpers/eventParser.ts @@ -0,0 +1,112 @@ +import { + PROGRAM_DATA, + PROGRAM_DATA_START_INDEX, + PROGRAM_LOG, + PROGRAM_LOG_START_INDEX, +} from "../constants/programLogsConstant"; +import { LogContextStack } from "../models/logContextStack"; +import { LogExtractor } from "../models/logExtractor"; + +export function* parseLogs( + logs: string[], + errorOnDecodeFailed: boolean = false +) { + const logsExtractor = new LogExtractor(logs); + const logsContextStack = new LogContextStack(); + + let log = logsExtractor.next(); + while (log !== null) { + let [event, programHash, popped] = identifyLog( + logsContextStack, + log, + errorOnDecodeFailed + ); + + if (event) { + yield { + event: event, + programHash: logsContextStack.getProgram(), + }; + } + if (programHash) { + logsContextStack.push(programHash); + } + if (popped) { + logsContextStack.pop(); + } + + log = logsExtractor.next(); + } +} + +const identifyLog = ( + context: LogContextStack, + log: string, + errorOnDecodeFailed: boolean +): [string | null, string | null, boolean] => { + if (context.stack.length > 0) { + return extractProgramLog(log, errorOnDecodeFailed); + } else { + return [null, ...extractSystemLog(log)]; + } +}; + +const extractProgramLog = ( + log: string, + errorOnDecodeFailed: boolean +): [string | null, string | null, boolean] => { + if (log.startsWith(PROGRAM_LOG) || log.startsWith(PROGRAM_DATA)) { + const logStr = log.startsWith(PROGRAM_LOG) + ? log.slice(PROGRAM_LOG_START_INDEX) + : log.slice(PROGRAM_DATA_START_INDEX); + const event = logStr; + + if (errorOnDecodeFailed && event === null) { + throw new Error(`Unable to decode log ${logStr}`); + } + return [event, null, false]; + } else { + return [null, ...extractSystemLog(log)]; + } +}; + +const extractSystemLog = (log: string): [string | null, boolean] => { + const logStart = log.split(":")[0]; + if (logStart) { + const cpiInvokationPattern = new RegExp("Program (.+?) invoke"); + const cpiMatch = logStart.match(cpiInvokationPattern); + + if (logStart.match(/^Program (.*) success/g) !== null) { + return [null, true]; + } else if (cpiMatch) { + if (cpiMatch[1]) { + return [cpiMatch[1], false]; + } + return [null, false]; + } else { + return [null, false]; + } + } + + return [null, false]; +}; + +export const convertLogsToEventsMap = (logs: string[]) => { + const eventMap = new Map(); + for (const event of parseLogs(logs)) { + // Regex String checker to only get base64 strings + const base64RegexCheck = new RegExp( + "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$" + ); + + if (base64RegexCheck.test(event.event)) { + if (eventMap.has(event.programHash)) { + eventMap.get(event.programHash)?.push(event.event); + } else { + eventMap.set(event.programHash, [event.event]); + } + } + } + + return eventMap; +}; diff --git a/examples/ek-event-parser/src/helpers/loadEnvironmentVariables.ts b/examples/ek-event-parser/src/helpers/loadEnvironmentVariables.ts new file mode 100644 index 0000000..221964e --- /dev/null +++ b/examples/ek-event-parser/src/helpers/loadEnvironmentVariables.ts @@ -0,0 +1,17 @@ +import { config } from "dotenv"; + +config(); + +export type Environment = { + programHash: string; +}; + +export const getEnvironmentVariables = (): Environment => { + if (!process.env.PROGRAM_HASH) { + throw new Error("PROGRAM_HASH environment variable is not set"); + } + + return { + programHash: process.env.PROGRAM_HASH, + }; +}; diff --git a/examples/ek-event-parser/src/index.ts b/examples/ek-event-parser/src/index.ts new file mode 100644 index 0000000..3473334 --- /dev/null +++ b/examples/ek-event-parser/src/index.ts @@ -0,0 +1,125 @@ +import { IdlItem, getProgramIdl } from "@solanafm/explorer-kit-idls"; +import { convertLogsToEventsMap } from "./helpers/eventParser"; +import { getEnvironmentVariables } from "./helpers/loadEnvironmentVariables"; +import fs from "fs"; +import { + EventParserInterface, + Parser, + ParserType, + SolanaFMParser, + checkIfEventParser, +} from "@solanafm/explorer-kit"; + +const environment = getEnvironmentVariables(); + +const app = async () => { + const logs: string[] = [ + "Program ComputeBudget111111111111111111111111111111 invoke [1]", + "Program ComputeBudget111111111111111111111111111111 success", + "Program JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB invoke [1]", + "Program log: Instruction: Route", + "Program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc invoke [2]", + "Program log: Instruction: Swap", + "Program log: fee_growth: 1093994082951", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]", + "Program log: Instruction: Transfer", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 1339463 compute units", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]", + "Program log: Instruction: Transfer", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4736 of 1331898 compute units", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", + "Program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc consumed 55954 of 1379575 compute units", + "Program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc success", + "Program data: UWzjvs3QCsQOA2hfjpCQU+RYEhxm9adq7cdwaqEcgviqlSqPK3h5qcb6evO+2606PWXzaqvJdDGxu+TC0vbg5HymAgNFL11hQEIPAAAAAAAGm4hX/quBhPtof2NGGMA12sQ53BrrO1WYoPAAAAAAARgu5AEAAAAA", + "Program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc invoke [2]", + "Program log: Instruction: Swap", + "Program log: fee_growth: 94074010856", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]", + "Program log: Instruction: Transfer", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4736 of 1267773 compute units", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]", + "Program log: Instruction: Transfer", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 1260120 compute units", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", + "Program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc consumed 54865 of 1306828 compute units", + "Program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc success", + "Program data: UWzjvs3QCsQOA2hfjpCQU+RYEhxm9adq7cdwaqEcgviqlSqPK3h5qQabiFf+q4GE+2h/Y0YYwDXaxDncGus7VZig8AAAAAABGC7kAQAAAADG+nrzvtutOj1l82qryXQxsbvkwtL24OR8pgIDRS9dYfRFDwAAAAAA", + "Program JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB consumed 150851 of 1400000 compute units", + "Program JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB success", + ]; + const eventMap = convertLogsToEventsMap(logs); + const parser = await setupParser(); + const parsedEvents: { [key: string]: any[] } = {}; + + for (const [prorgamId, eventMapLogs] of eventMap.entries()) { + if (prorgamId !== environment.programHash) { + continue; + } + + try { + const events = []; + for (const log of eventMapLogs) { + const decodedEvent = parser.parseEvents(log); + events.push(decodedEvent); + } + + parsedEvents[prorgamId] = events; + } catch (err) { + console.log("Parser extraction error, due to: ", err); + } + } + + console.log("Parsed events: ", parsedEvents); +}; + +const setupParser = async () => { + const idlItemFromLibrary = await getProgramIdl(environment.programHash); + let eventParser: EventParserInterface | undefined; + if (idlItemFromLibrary === null) { + eventParser = setupParserFromLocalIdl(); + console.log("Successfully loaded parser from local idl file"); + } else { + const parser = new SolanaFMParser( + idlItemFromLibrary, + environment.programHash + ); + const registryParser = parser.createParser(ParserType.EVENT); + if (registryParser && checkIfEventParser(registryParser)) { + eventParser = registryParser; + console.log("Successfully loaded parser from registry"); + } + } + if (!eventParser) { + throw new Error("Failed to load parser"); + } + return eventParser; +}; + +const setupParserFromLocalIdl = () => { + const jsonString = fs.readFileSync("./idl.json", "utf8"); + const idlFile = JSON.parse(jsonString); + let idlType: "anchor" | "shank" | "kinobi" | string = ""; + if (!process.env.IDL_TYPE) { + throw new Error("IDL_TYPE environment variable is not set"); + } + idlType = process.env.IDL_TYPE; + if (idlType !== "anchor" && idlType !== "shank" && idlType !== "kinobi") { + throw new Error(`IDL_TYPE ${idlType} is not valid`); + } + + const idlItem: IdlItem = { + programId: environment.programHash, + idl: idlFile, + idlType: idlType, + }; + + const parser = new SolanaFMParser(idlItem, environment.programHash); + const eventsParser = parser.createParser(ParserType.EVENT); + if (eventsParser && checkIfEventParser(eventsParser)) { + return eventsParser; + } +}; + +app(); diff --git a/examples/ek-event-parser/src/models/logContextStack.ts b/examples/ek-event-parser/src/models/logContextStack.ts new file mode 100644 index 0000000..6fc31b4 --- /dev/null +++ b/examples/ek-event-parser/src/models/logContextStack.ts @@ -0,0 +1,15 @@ +export class LogContextStack { + stack: string[] = []; + + getProgram(): string { + return this.stack[this.stack.length - 1] ?? "Unknown Program"; + } + + push(programHash: string) { + this.stack.push(programHash); + } + + pop() { + this.stack.pop(); + } +} diff --git a/examples/ek-event-parser/src/models/logExtractor.ts b/examples/ek-event-parser/src/models/logExtractor.ts new file mode 100644 index 0000000..9ef3390 --- /dev/null +++ b/examples/ek-event-parser/src/models/logExtractor.ts @@ -0,0 +1,12 @@ +export class LogExtractor { + constructor(public logs: string[]) {} + + next(): string | null { + if (this.logs.length === 0) { + return null; + } + const log = this.logs[0]; + this.logs = this.logs.slice(1); + return log; + } +} diff --git a/examples/ek-event-parser/tsconfig.json b/examples/ek-event-parser/tsconfig.json new file mode 100644 index 0000000..e075f97 --- /dev/null +++ b/examples/ek-event-parser/tsconfig.json @@ -0,0 +1,109 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/examples/ek-instruction-parser/.env.example b/examples/ek-instruction-parser/.env.example new file mode 100644 index 0000000..477129c --- /dev/null +++ b/examples/ek-instruction-parser/.env.example @@ -0,0 +1,4 @@ +PROGRAM_HASH= +IDL_TYPE= +TRANSACTION_HASH= +RPC_URL= \ No newline at end of file diff --git a/examples/ek-instruction-parser/.gitignore b/examples/ek-instruction-parser/.gitignore new file mode 100644 index 0000000..58819bd --- /dev/null +++ b/examples/ek-instruction-parser/.gitignore @@ -0,0 +1,5 @@ +.idea/ +node_modules/ +.env +idl.json +.DS_Store diff --git a/examples/ek-instruction-parser/README.md b/examples/ek-instruction-parser/README.md new file mode 100644 index 0000000..334ca59 --- /dev/null +++ b/examples/ek-instruction-parser/README.md @@ -0,0 +1 @@ +# instruction-parser-with-ek diff --git a/examples/ek-instruction-parser/package.json b/examples/ek-instruction-parser/package.json new file mode 100644 index 0000000..f0a7ded --- /dev/null +++ b/examples/ek-instruction-parser/package.json @@ -0,0 +1,26 @@ +{ + "name": "ek-instruction-parser", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "dev": "nodemon --exec ts-node src/index.ts", + "build": "tsc --outDir dist", + "clean": "rm -r dist && rm -r node_modules" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@solanafm/explorer-kit": "^1.0.0", + "@solanafm/explorer-kit-idls": "^1.0.0", + "@types/node": "^20.8.7", + "axios": "^1.5.1", + "dotenv": "^16.3.1", + "ts-node": "^10.9.1", + "typescript": "^5.2.2" + }, + "devDependencies": { + "nodemon": "^3.0.1" + } +} \ No newline at end of file diff --git a/examples/ek-instruction-parser/pnpm-lock.yaml b/examples/ek-instruction-parser/pnpm-lock.yaml new file mode 100644 index 0000000..d0a6edb --- /dev/null +++ b/examples/ek-instruction-parser/pnpm-lock.yaml @@ -0,0 +1,1060 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + '@solanafm/explorer-kit': + specifier: ^1.0.0 + version: 1.0.2 + '@solanafm/explorer-kit-idls': + specifier: ^1.0.0 + version: 1.0.0 + '@types/node': + specifier: ^20.8.7 + version: 20.8.9 + axios: + specifier: ^1.5.1 + version: 1.5.1 + dotenv: + specifier: ^16.3.1 + version: 16.3.1 + ts-node: + specifier: ^10.9.1 + version: 10.9.1(@types/node@20.8.9)(typescript@5.2.2) + typescript: + specifier: ^5.2.2 + version: 5.2.2 + +devDependencies: + nodemon: + specifier: ^3.0.1 + version: 3.0.1 + +packages: + + /@babel/runtime@7.23.2: + resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.0 + dev: false + + /@coral-xyz/anchor@0.27.0: + resolution: {integrity: sha512-+P/vPdORawvg3A9Wj02iquxb4T0C5m4P6aZBVYysKl4Amk+r6aMPZkUhilBkD6E4Nuxnoajv3CFykUfkGE0n5g==} + engines: {node: '>=11'} + dependencies: + '@coral-xyz/borsh': 0.27.0(@solana/web3.js@1.87.2) + '@solana/web3.js': 1.87.2 + base64-js: 1.5.1 + bn.js: 5.2.1 + bs58: 4.0.1 + buffer-layout: 1.2.2 + camelcase: 6.3.0 + cross-fetch: 3.1.8 + crypto-hash: 1.3.0 + eventemitter3: 4.0.7 + js-sha256: 0.9.0 + pako: 2.1.0 + snake-case: 3.0.4 + superstruct: 0.15.5 + toml: 3.0.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@coral-xyz/anchor@0.28.1-beta.2: + resolution: {integrity: sha512-xreUcOFF8+IQKWOBUrDKJbIw2ftpRVybFlEPVrbSlOBCbreCWrQ5754Gt9cHIcuBDAzearCDiBqzsGQdNgPJiw==} + engines: {node: '>=11'} + dependencies: + '@coral-xyz/borsh': 0.28.0(@solana/web3.js@1.87.2) + '@noble/hashes': 1.3.2 + '@solana/web3.js': 1.87.2 + base64-js: 1.5.1 + bn.js: 5.2.1 + bs58: 4.0.1 + buffer-layout: 1.2.2 + camelcase: 6.3.0 + cross-fetch: 3.1.8 + crypto-hash: 1.3.0 + eventemitter3: 4.0.7 + pako: 2.1.0 + snake-case: 3.0.4 + superstruct: 0.15.5 + toml: 3.0.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@coral-xyz/borsh@0.27.0(@solana/web3.js@1.87.2): + resolution: {integrity: sha512-tJKzhLukghTWPLy+n8K8iJKgBq1yLT/AxaNd10yJrX8mI56ao5+OFAKAqW/h0i79KCvb4BK0VGO5ECmmolFz9A==} + engines: {node: '>=10'} + peerDependencies: + '@solana/web3.js': ^1.68.0 + dependencies: + '@solana/web3.js': 1.87.2 + bn.js: 5.2.1 + buffer-layout: 1.2.2 + dev: false + + /@coral-xyz/borsh@0.28.0(@solana/web3.js@1.87.2): + resolution: {integrity: sha512-/u1VTzw7XooK7rqeD7JLUSwOyRSesPUk0U37BV9zK0axJc1q0nRbKFGFLYCQ16OtdOJTTwGfGp11Lx9B45bRCQ==} + engines: {node: '>=10'} + peerDependencies: + '@solana/web3.js': ^1.68.0 + dependencies: + '@solana/web3.js': 1.87.2 + bn.js: 5.2.1 + buffer-layout: 1.2.2 + dev: false + + /@cspotcode/source-map-support@0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: false + + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + dev: false + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: false + + /@jridgewell/trace-mapping@0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: false + + /@metaplex-foundation/umi-options@0.8.9: + resolution: {integrity: sha512-jSQ61sZMPSAk/TXn8v8fPqtz3x8d0/blVZXLLbpVbo2/T5XobiI6/MfmlUosAjAUaQl6bHRF8aIIqZEFkJiy4A==} + dev: false + + /@metaplex-foundation/umi-public-keys@0.8.9: + resolution: {integrity: sha512-CxMzN7dgVGOq9OcNCJe2casKUpJ3RmTVoOvDFyeoTQuK+vkZ1YSSahbqC1iGuHEtKTLSjtWjKvUU6O7zWFTw3Q==} + dependencies: + '@metaplex-foundation/umi-serializers-encodings': 0.8.9 + dev: false + + /@metaplex-foundation/umi-serializers-core@0.8.9: + resolution: {integrity: sha512-WT82tkiYJ0Qmscp7uTj1Hz6aWQPETwaKLAENAUN5DeWghkuBKtuxyBKVvEOuoXerJSdhiAk0e8DWA4cxcTTQ/w==} + dev: false + + /@metaplex-foundation/umi-serializers-encodings@0.8.9: + resolution: {integrity: sha512-N3VWLDTJ0bzzMKcJDL08U3FaqRmwlN79FyE4BHj6bbAaJ9LEHjDQ9RJijZyWqTm0jE7I750fU7Ow5EZL38Xi6Q==} + dependencies: + '@metaplex-foundation/umi-serializers-core': 0.8.9 + dev: false + + /@metaplex-foundation/umi-serializers-numbers@0.8.9: + resolution: {integrity: sha512-NtBf1fnVNQJHFQjLFzRu2i9GGnigb9hOm/Gfrk628d0q0tRJB7BOM3bs5C61VAs7kJs4yd+pDNVAERJkknQ7Lg==} + dependencies: + '@metaplex-foundation/umi-serializers-core': 0.8.9 + dev: false + + /@metaplex-foundation/umi-serializers@0.8.9: + resolution: {integrity: sha512-Sve8Etm3zqvLSUfza+MYRkjTnCpiaAFT7VWdqeHzA3n58P0AfT3p74RrZwVt/UFkxI+ln8BslwBDJmwzcPkuHw==} + dependencies: + '@metaplex-foundation/umi-options': 0.8.9 + '@metaplex-foundation/umi-public-keys': 0.8.9 + '@metaplex-foundation/umi-serializers-core': 0.8.9 + '@metaplex-foundation/umi-serializers-encodings': 0.8.9 + '@metaplex-foundation/umi-serializers-numbers': 0.8.9 + dev: false + + /@metaplex-foundation/umi@0.8.9: + resolution: {integrity: sha512-Gip7HPDCjsX7OakPFBiifX89AofUGcsj/ujbvOfd/6GDIL4XjX79royuT3yyxzovRxyiaPF/kCK6a2dKtm69Kw==} + dependencies: + '@metaplex-foundation/umi-options': 0.8.9 + '@metaplex-foundation/umi-public-keys': 0.8.9 + '@metaplex-foundation/umi-serializers': 0.8.9 + dev: false + + /@noble/curves@1.2.0: + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + dependencies: + '@noble/hashes': 1.3.2 + dev: false + + /@noble/hashes@1.3.2: + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + dev: false + + /@solana/buffer-layout@4.0.1: + resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} + engines: {node: '>=5.10'} + dependencies: + buffer: 6.0.3 + dev: false + + /@solana/web3.js@1.87.2: + resolution: {integrity: sha512-TZNhS+tvJbYjm0LAvIkUy/3Aqgt2l6/3X6XsVUpvj5MGOl2Q6Ch8hYSxcUUtMbAFNN3sUXmV8NhhMLNJEvI6TA==} + dependencies: + '@babel/runtime': 7.23.2 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.0 + node-fetch: 2.7.0 + rpc-websockets: 7.6.1 + superstruct: 0.14.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@solanafm/explorer-kit-idls@1.0.0: + resolution: {integrity: sha512-5ykQlPW4rA9sS5RvsiG/66lceI6rmPkyIubam795vrkP+cVW6A9W3kXV1A1o5zZUzIHQO/X8HA5JSItelnZsKQ==} + dependencies: + '@coral-xyz/anchor': 0.27.0 + '@solanafm/kinobi-lite': 0.12.0 + axios: 1.5.1 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - utf-8-validate + dev: false + + /@solanafm/explorer-kit@1.0.2: + resolution: {integrity: sha512-Ne1NxN3xUWvn/Oc8WPLsFmxTkFSBpMKLsRsjGMUYfW5nsIL86KYveh23ANgcevBLSz+TpCb4mU82XVY+JrJeIQ==} + dependencies: + '@coral-xyz/anchor': 0.28.1-beta.2 + '@metaplex-foundation/umi': 0.8.9 + '@metaplex-foundation/umi-serializers': 0.8.9 + '@solanafm/kinobi-lite': 0.12.0 + '@solanafm/utils': 0.3.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@solanafm/kinobi-lite@0.12.0: + resolution: {integrity: sha512-K3daAv8HoJzM6UiDUG1Tj0tZIcCSJENmqx5nw4J2+sOwyZm1leFvVkIHM+WOExh/IqI7PglipRJbrF0OXN007Q==} + dependencies: + '@noble/hashes': 1.3.2 + chalk: 4.1.2 + dev: false + + /@solanafm/utils@0.3.0: + resolution: {integrity: sha512-SI0Q+PIH+t9gT4cPrLVKlPpjhByHFunyL01j/VfI2sBlBueuyCpO9PgpK/VQA2sZ8wdDqhq2g6gatzuNnlLJiQ==} + dependencies: + '@metaplex-foundation/umi-options': 0.8.9 + bn.js: 5.2.1 + bs58: 5.0.0 + dayjs: 1.11.10 + dev: false + + /@tsconfig/node10@1.0.9: + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + dev: false + + /@tsconfig/node12@1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: false + + /@tsconfig/node14@1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: false + + /@tsconfig/node16@1.0.4: + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + dev: false + + /@types/connect@3.4.37: + resolution: {integrity: sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q==} + dependencies: + '@types/node': 20.8.9 + dev: false + + /@types/node@12.20.55: + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + dev: false + + /@types/node@20.8.9: + resolution: {integrity: sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==} + dependencies: + undici-types: 5.26.5 + dev: false + + /@types/ws@7.4.7: + resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + dependencies: + '@types/node': 20.8.9 + dev: false + + /JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + dev: false + + /abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + dev: true + + /acorn-walk@8.2.0: + resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + engines: {node: '>=0.4.0'} + dev: false + + /acorn@8.10.0: + resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: false + + /agentkeepalive@4.5.0: + resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} + engines: {node: '>= 8.0.0'} + dependencies: + humanize-ms: 1.2.1 + dev: false + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: false + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: false + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + + /axios@1.5.1: + resolution: {integrity: sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==} + dependencies: + follow-redirects: 1.15.3 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /base-x@3.0.9: + resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /base-x@4.0.0: + resolution: {integrity: sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==} + dev: false + + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: false + + /bigint-buffer@1.1.5: + resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} + engines: {node: '>= 10.0.0'} + requiresBuild: true + dependencies: + bindings: 1.5.0 + dev: false + + /binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + dependencies: + file-uri-to-path: 1.0.0 + dev: false + + /bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + dev: false + + /borsh@0.7.0: + resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + dependencies: + bn.js: 5.2.1 + bs58: 4.0.1 + text-encoding-utf-8: 1.0.2 + dev: false + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + dependencies: + base-x: 3.0.9 + dev: false + + /bs58@5.0.0: + resolution: {integrity: sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==} + dependencies: + base-x: 4.0.0 + dev: false + + /buffer-layout@1.2.2: + resolution: {integrity: sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==} + engines: {node: '>=4.5'} + dev: false + + /buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + + /bufferutil@4.0.8: + resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} + engines: {node: '>=6.14.2'} + requiresBuild: true + dependencies: + node-gyp-build: 4.6.1 + dev: false + + /camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: false + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: false + + /chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: false + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: false + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false + + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: false + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: false + + /cross-fetch@3.1.8: + resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + dev: false + + /crypto-hash@1.3.0: + resolution: {integrity: sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==} + engines: {node: '>=8'} + dev: false + + /dayjs@1.11.10: + resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} + dev: false + + /debug@3.2.7(supports-color@5.5.0): + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + supports-color: 5.5.0 + dev: true + + /delay@5.0.0: + resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} + engines: {node: '>=10'} + dev: false + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false + + /diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: false + + /dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dependencies: + no-case: 3.0.4 + tslib: 2.6.2 + dev: false + + /dotenv@16.3.1: + resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + engines: {node: '>=12'} + dev: false + + /es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + dev: false + + /es6-promisify@5.0.0: + resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + dependencies: + es6-promise: 4.2.8 + dev: false + + /eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + dev: false + + /eyes@0.1.8: + resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} + engines: {node: '> 0.1.90'} + dev: false + + /fast-stable-stringify@1.0.0: + resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + dev: false + + /file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + dev: false + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /follow-redirects@1.15.3: + resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: false + + /humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + dependencies: + ms: 2.1.3 + dev: false + + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: false + + /ignore-by-default@1.0.1: + resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + dev: true + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /isomorphic-ws@4.0.1(ws@7.5.9): + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + dependencies: + ws: 7.5.9 + dev: false + + /jayson@4.1.0: + resolution: {integrity: sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A==} + engines: {node: '>=8'} + hasBin: true + dependencies: + '@types/connect': 3.4.37 + '@types/node': 12.20.55 + '@types/ws': 7.4.7 + JSONStream: 1.3.5 + commander: 2.20.3 + delay: 5.0.0 + es6-promisify: 5.0.0 + eyes: 0.1.8 + isomorphic-ws: 4.0.1(ws@7.5.9) + json-stringify-safe: 5.0.1 + uuid: 8.3.2 + ws: 7.5.9 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + + /js-sha256@0.9.0: + resolution: {integrity: sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==} + dev: false + + /json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + dev: false + + /jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + dev: false + + /lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + dependencies: + tslib: 2.6.2 + dev: false + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: false + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + /no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + dependencies: + lower-case: 2.0.2 + tslib: 2.6.2 + dev: false + + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /node-gyp-build@4.6.1: + resolution: {integrity: sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==} + hasBin: true + requiresBuild: true + dev: false + + /nodemon@3.0.1: + resolution: {integrity: sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + chokidar: 3.5.3 + debug: 3.2.7(supports-color@5.5.0) + ignore-by-default: 1.0.1 + minimatch: 3.1.2 + pstree.remy: 1.1.8 + semver: 7.5.4 + simple-update-notifier: 2.0.0 + supports-color: 5.5.0 + touch: 3.1.0 + undefsafe: 2.0.5 + dev: true + + /nopt@1.0.10: + resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==} + hasBin: true + dependencies: + abbrev: 1.1.1 + dev: true + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /pako@2.1.0: + resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} + dev: false + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false + + /pstree.remy@1.1.8: + resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + dev: true + + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /regenerator-runtime@0.14.0: + resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + dev: false + + /rpc-websockets@7.6.1: + resolution: {integrity: sha512-MmRGaJJvxTHSRxYPjJJqcj2zWnCetw7YbYbKlD0Yc7qVw6PsZhRJg1MI3mpWlpBs+4zO+urlNfLl9zLsdOD/gA==} + dependencies: + '@babel/runtime': 7.23.2 + eventemitter3: 4.0.7 + uuid: 8.3.2 + ws: 8.14.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + dev: false + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: false + + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /simple-update-notifier@2.0.0: + resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} + engines: {node: '>=10'} + dependencies: + semver: 7.5.4 + dev: true + + /snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + dependencies: + dot-case: 3.0.4 + tslib: 2.6.2 + dev: false + + /superstruct@0.14.2: + resolution: {integrity: sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==} + dev: false + + /superstruct@0.15.5: + resolution: {integrity: sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ==} + dev: false + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: false + + /text-encoding-utf-8@1.0.2: + resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} + dev: false + + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: false + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /toml@3.0.0: + resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + dev: false + + /touch@3.1.0: + resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==} + hasBin: true + dependencies: + nopt: 1.0.10 + dev: true + + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + + /ts-node@10.9.1(@types/node@20.8.9)(typescript@5.2.2): + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.8.9 + acorn: 8.10.0 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.2.2 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: false + + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + dev: false + + /typescript@5.2.2: + resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} + engines: {node: '>=14.17'} + hasBin: true + dev: false + + /undefsafe@2.0.5: + resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + dev: true + + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: false + + /utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + requiresBuild: true + dependencies: + node-gyp-build: 4.6.1 + dev: false + + /uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + dev: false + + /v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: false + + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + + /ws@7.5.9: + resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + + /ws@8.14.2(bufferutil@4.0.8)(utf-8-validate@5.0.10): + resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + dev: false + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + + /yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: false diff --git a/examples/ek-instruction-parser/src/helpers/loadEnvironmentVariables.ts b/examples/ek-instruction-parser/src/helpers/loadEnvironmentVariables.ts new file mode 100644 index 0000000..93cb0cb --- /dev/null +++ b/examples/ek-instruction-parser/src/helpers/loadEnvironmentVariables.ts @@ -0,0 +1,27 @@ +import { config } from "dotenv"; + +config(); + +export type Environment = { + programHash: string; + transactionHash: string; + rpc_url: string; +}; + +export const getEnvironmentVariables = (): Environment => { + if (!process.env.PROGRAM_HASH) { + throw new Error("PROGRAM_HASH environment variable is not defined"); + } + if (!process.env.TRANSACTION_HASH) { + throw new Error("TRANSACTION_HASH environment variable is not defined"); + } + if (!process.env.RPC_URL) { + throw new Error("RPC_URL environment variable is not defined"); + } + + return { + programHash: process.env.PROGRAM_HASH, + transactionHash: process.env.TRANSACTION_HASH, + rpc_url: process.env.RPC_URL, + }; +}; diff --git a/examples/ek-instruction-parser/src/index.ts b/examples/ek-instruction-parser/src/index.ts new file mode 100644 index 0000000..e7d6b1c --- /dev/null +++ b/examples/ek-instruction-parser/src/index.ts @@ -0,0 +1,111 @@ +import { IdlItem, getProgramIdl } from "@solanafm/explorer-kit-idls"; +import { getEnvironmentVariables } from "./helpers/loadEnvironmentVariables"; +import { + InstructionParserInterface, + ParserType, + SolanaFMParser, + checkIfInstructionParser, +} from "@solanafm/explorer-kit"; +import fs from "fs"; +import axios from "axios"; + +const environment = getEnvironmentVariables(); + +const app = async () => { + const instructionParser = await setupParser(); + const transactionResponse = await axios.post(environment.rpc_url, { + jsonrpc: "2.0", + id: 1, + method: "getTransaction", + params: [ + environment.transactionHash, + { + encoding: "jsonParsed", + maxSupportedTransactionVersion: 0, + }, + ], + }); + + if (!transactionResponse.data.result) { + throw new Error("Transaction not found"); + } + + const transaction = transactionResponse.data.result; + + // Try to parse the program's instructions with ek parser + const instructions = transaction.transaction.message.instructions; + for (const instruction of instructions) { + if (instruction.programId === environment.programHash) { + const parsedInstruction = instructionParser.parseInstructions( + instruction.data, + instruction.accounts + ); + console.log("Parsed instruction, ", parsedInstruction); + } + } + + // Try to parse the program's inner instructions with ek parser + const innerInstructions = transaction.meta.innerInstructions; + for (const innerInstruction of innerInstructions) { + for (const innerObj of innerInstruction.instructions) { + if (!innerObj.parsed && innerObj.programId === environment.programHash) { + const parsedInnerInstruction = instructionParser.parseInstructions( + innerInstruction.data, + innerInstruction.accounts + ); + console.log("Parsed inner instruction, ", parsedInnerInstruction); + } + } + } +}; + +const setupParser = async () => { + const idlItemFromLibrary = await getProgramIdl(environment.programHash); + let instructionParser: InstructionParserInterface | undefined; + if (idlItemFromLibrary === null) { + instructionParser = setupParserFromLocalIdl(); + console.log("Successfully laoded parser from local idl file"); + } else { + const parser = new SolanaFMParser( + idlItemFromLibrary, + environment.programHash + ); + const registryParser = parser.createParser(ParserType.INSTRUCTION); + if (registryParser && checkIfInstructionParser(registryParser)) { + instructionParser = registryParser; + console.log("Successfully loaded parser from registry"); + } + } + + if (!instructionParser) { + throw new Error("Failed to load parser"); + } + return instructionParser; +}; + +const setupParserFromLocalIdl = () => { + const jsonString = fs.readFileSync("./idl.json", "utf8"); + const idlFile = JSON.parse(jsonString); + let idlType: "anchor" | "shank" | "kinobi" | string = ""; + if (!process.env.IDL_TYPE) { + throw new Error("IDL_TYPE environment variable is not defined"); + } + idlType = process.env.IDL_TYPE; + if (idlType !== "anchor" && idlType !== "shank" && idlType !== "kinobi") { + throw new Error(`IDL_TYPE ${idlType} is not valid`); + } + + const idlItem: IdlItem = { + programId: environment.programHash, + idl: idlFile, + idlType: idlType, + }; + + const parser = new SolanaFMParser(idlItem, environment.programHash); + const instructionsParser = parser.createParser(ParserType.INSTRUCTION); + if (instructionsParser && checkIfInstructionParser(instructionsParser)) { + return instructionsParser; + } +}; + +app(); diff --git a/examples/ek-instruction-parser/tsconfig.json b/examples/ek-instruction-parser/tsconfig.json new file mode 100644 index 0000000..e075f97 --- /dev/null +++ b/examples/ek-instruction-parser/tsconfig.json @@ -0,0 +1,109 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} From 377401438f343ba2edafa0ba29d52d56c4841304 Mon Sep 17 00:00:00 2001 From: linsyhen99 Date: Sun, 29 Oct 2023 07:43:33 +0200 Subject: [PATCH 8/8] Udpated env example and support retrieving transaction through rpc instead of a hard coded string[] Signed-off-by: linsyhen99 --- examples/ek-event-parser/.env.example | 4 +- examples/ek-event-parser/README.md | 36 +++++++++ .../src/helpers/loadEnvironmentVariables.ts | 10 +++ examples/ek-event-parser/src/index.ts | 73 +++++++------------ 4 files changed, 74 insertions(+), 49 deletions(-) diff --git a/examples/ek-event-parser/.env.example b/examples/ek-event-parser/.env.example index ebecb4c..477129c 100644 --- a/examples/ek-event-parser/.env.example +++ b/examples/ek-event-parser/.env.example @@ -1,2 +1,4 @@ PROGRAM_HASH= -IDL_TYPE= \ No newline at end of file +IDL_TYPE= +TRANSACTION_HASH= +RPC_URL= \ No newline at end of file diff --git a/examples/ek-event-parser/README.md b/examples/ek-event-parser/README.md index 9bb27c7..8624b94 100644 --- a/examples/ek-event-parser/README.md +++ b/examples/ek-event-parser/README.md @@ -1 +1,37 @@ # event-parsing-with-ek + +A sample project that showcases the basic usages and integrations with EK-Parser that decodes the program's event data based on the IDL file + +## About + +- The list of program IDLs identified/indexed/curated by the SolanaFM's team is listed here in this library + + - https://www.npmjs.com/package/@solanafm/ek-idls-repo + +- If your IDL is not part of the identified IDLs list, you can still use the Parser by manually injecting your IDL file into the Parser object + - To manually initialise the Parser with your own IDL file please follow the guide below + +## Populate the project with a .env file to get started + +- Sample env configuration file + +``` +PROGRAM_HASH= +INSTRUCTIONS= +PARSER_TYPE=registry # "manual" | "registry" +STARTING_BLOCK=245000000 +RPC_URL= + +# Loading IDL from local file +IDL_TYPE=shank # "anchor" | "shank" | "kinobi" +``` + +--- + +# Initialising the Parser with a custom IDL file configuration + +1. Ensure that your IDL file is either generated by anchor/shank +2. Create a `idl.json` file in the local directory and populate the json file with your generated IDL file +3. Indicate your `PROGRAM_HASH` in the `.env` file +4. Change your `PARSER_TYPE` to `manual` +5. Indicate your `IDL_TYPE` field in the `.env` file \ No newline at end of file diff --git a/examples/ek-event-parser/src/helpers/loadEnvironmentVariables.ts b/examples/ek-event-parser/src/helpers/loadEnvironmentVariables.ts index 221964e..f0da747 100644 --- a/examples/ek-event-parser/src/helpers/loadEnvironmentVariables.ts +++ b/examples/ek-event-parser/src/helpers/loadEnvironmentVariables.ts @@ -4,14 +4,24 @@ config(); export type Environment = { programHash: string; + transactionHash: string; + rpc_url: string; }; export const getEnvironmentVariables = (): Environment => { if (!process.env.PROGRAM_HASH) { throw new Error("PROGRAM_HASH environment variable is not set"); } + if (!process.env.TRANSACTION_HASH) { + throw new Error("TRANSACTION_HASH environment variable is not set"); + } + if (!process.env.RPC_URL) { + throw new Error("RPC_URL environment variable is not set"); + } return { programHash: process.env.PROGRAM_HASH, + transactionHash: process.env.TRANSACTION_HASH, + rpc_url: process.env.RPC_URL, }; }; diff --git a/examples/ek-event-parser/src/index.ts b/examples/ek-event-parser/src/index.ts index 3473334..2b8ba73 100644 --- a/examples/ek-event-parser/src/index.ts +++ b/examples/ek-event-parser/src/index.ts @@ -2,55 +2,35 @@ import { IdlItem, getProgramIdl } from "@solanafm/explorer-kit-idls"; import { convertLogsToEventsMap } from "./helpers/eventParser"; import { getEnvironmentVariables } from "./helpers/loadEnvironmentVariables"; import fs from "fs"; -import { - EventParserInterface, - Parser, - ParserType, - SolanaFMParser, - checkIfEventParser, -} from "@solanafm/explorer-kit"; +import { EventParserInterface, Parser, ParserType, SolanaFMParser, checkIfEventParser } from "@solanafm/explorer-kit"; +import axios from "axios"; const environment = getEnvironmentVariables(); const app = async () => { - const logs: string[] = [ - "Program ComputeBudget111111111111111111111111111111 invoke [1]", - "Program ComputeBudget111111111111111111111111111111 success", - "Program JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB invoke [1]", - "Program log: Instruction: Route", - "Program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc invoke [2]", - "Program log: Instruction: Swap", - "Program log: fee_growth: 1093994082951", - "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]", - "Program log: Instruction: Transfer", - "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 1339463 compute units", - "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", - "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]", - "Program log: Instruction: Transfer", - "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4736 of 1331898 compute units", - "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", - "Program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc consumed 55954 of 1379575 compute units", - "Program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc success", - "Program data: UWzjvs3QCsQOA2hfjpCQU+RYEhxm9adq7cdwaqEcgviqlSqPK3h5qcb6evO+2606PWXzaqvJdDGxu+TC0vbg5HymAgNFL11hQEIPAAAAAAAGm4hX/quBhPtof2NGGMA12sQ53BrrO1WYoPAAAAAAARgu5AEAAAAA", - "Program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc invoke [2]", - "Program log: Instruction: Swap", - "Program log: fee_growth: 94074010856", - "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]", - "Program log: Instruction: Transfer", - "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4736 of 1267773 compute units", - "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", - "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]", - "Program log: Instruction: Transfer", - "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 1260120 compute units", - "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", - "Program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc consumed 54865 of 1306828 compute units", - "Program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc success", - "Program data: UWzjvs3QCsQOA2hfjpCQU+RYEhxm9adq7cdwaqEcgviqlSqPK3h5qQabiFf+q4GE+2h/Y0YYwDXaxDncGus7VZig8AAAAAABGC7kAQAAAADG+nrzvtutOj1l82qryXQxsbvkwtL24OR8pgIDRS9dYfRFDwAAAAAA", - "Program JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB consumed 150851 of 1400000 compute units", - "Program JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB success", - ]; - const eventMap = convertLogsToEventsMap(logs); const parser = await setupParser(); + + const transactionResponse = await axios.post(environment.rpc_url, { + jsonrpc: "2.0", + id: 1, + method: "getTransaction", + params: [ + environment.transactionHash, + { + encoding: "jsonParsed", + maxSupportedTransactionVersion: 0, + }, + ], + }); + + if (!transactionResponse.data.result) { + throw new Error("Transaction not found"); + } + + const transaction = transactionResponse.data.result; + + const logs: string[] = transaction.meta.logMessages; + const eventMap = convertLogsToEventsMap(logs); const parsedEvents: { [key: string]: any[] } = {}; for (const [prorgamId, eventMapLogs] of eventMap.entries()) { @@ -81,10 +61,7 @@ const setupParser = async () => { eventParser = setupParserFromLocalIdl(); console.log("Successfully loaded parser from local idl file"); } else { - const parser = new SolanaFMParser( - idlItemFromLibrary, - environment.programHash - ); + const parser = new SolanaFMParser(idlItemFromLibrary, environment.programHash); const registryParser = parser.createParser(ParserType.EVENT); if (registryParser && checkIfEventParser(registryParser)) { eventParser = registryParser;