diff --git a/package.json b/package.json index a3cfa48..993a87a 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "db:generate": "prisma generate", "db:push": "prisma db push", "db:studio": "prisma studio", - "db:seed": "prisma db push --force-reset && npx prisma db seed", + "db:seed": "prisma db seed", "db:reset": "prisma db push --force-reset" }, "prisma": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fef3c7b..b3d8978 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -92,28 +92,31 @@ importers: dependencies: '@astrojs/check': specifier: ^0.3.1 - version: 0.3.1(prettier@3.1.0)(typescript@5.2.2) + version: 0.3.1(prettier@3.1.0)(typescript@5.3.2) '@astrojs/starlight': - specifier: ^0.12.1 - version: 0.12.1(astro@3.5.5) + specifier: ^0.13.0 + version: 0.13.0(astro@3.5.6) '@astrojs/starlight-tailwind': specifier: ^2.0.1 - version: 2.0.1(@astrojs/starlight@0.12.1)(@astrojs/tailwind@5.0.2)(tailwindcss@3.3.5) + version: 2.0.1(@astrojs/starlight@0.13.0)(@astrojs/tailwind@5.0.2)(tailwindcss@3.3.5) '@astrojs/tailwind': - specifier: ^5.0.0 - version: 5.0.2(astro@3.5.5)(tailwindcss@3.3.5)(ts-node@10.9.1) + specifier: ^5.0.2 + version: 5.0.2(astro@3.5.6)(tailwindcss@3.3.5)(ts-node@10.9.1) astro: - specifier: ^3.2.3 - version: 3.5.5(@types/node@20.9.2)(typescript@5.2.2) + specifier: ^3.5.6 + version: 3.5.6(@types/node@20.9.2)(typescript@5.3.2) + astro-expressive-code: + specifier: ^0.29.1 + version: 0.29.1(astro@3.5.6) sharp: - specifier: ^0.32.5 + specifier: ^0.32.6 version: 0.32.6 tailwindcss: - specifier: ^3.3.3 + specifier: ^3.3.5 version: 3.3.5(ts-node@10.9.1) typescript: - specifier: 5.2.2 - version: 5.2.2 + specifier: 5.3.2 + version: 5.3.2 packages: @@ -131,20 +134,20 @@ packages: engines: {node: '>=6.0.0'} dependencies: '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.9 + '@jridgewell/trace-mapping': 0.3.20 dev: false - /@astrojs/check@0.3.1(prettier@3.1.0)(typescript@5.2.2): + /@astrojs/check@0.3.1(prettier@3.1.0)(typescript@5.3.2): resolution: {integrity: sha512-3LjEUvh7Z4v9NPokaqKMXQ0DwnSXfmtcyAuWVTjNt9yzjv54SxykobV5CTOB3TIko+Rqg59ejamJBxaJN6fvkw==} hasBin: true peerDependencies: typescript: ^5.0.0 dependencies: - '@astrojs/language-server': 2.5.2(prettier@3.1.0)(typescript@5.2.2) + '@astrojs/language-server': 2.5.2(prettier@3.1.0)(typescript@5.3.2) chokidar: 3.5.3 fast-glob: 3.3.2 kleur: 4.1.5 - typescript: 5.2.2 + typescript: 5.3.2 yargs: 17.7.2 transitivePeerDependencies: - prettier @@ -159,7 +162,7 @@ packages: resolution: {integrity: sha512-06DD2ZnItMwUnH81LBLco3tWjcZ1lGU9rLCCBaeUCGYe9cI0wKyY2W3kDyoW1I6GmcWgt1fu+D1CTvz+FIKf8A==} dev: false - /@astrojs/language-server@2.5.2(prettier@3.1.0)(typescript@5.2.2): + /@astrojs/language-server@2.5.2(prettier@3.1.0)(typescript@5.3.2): resolution: {integrity: sha512-O5SMzoQ65wSxA1KygreI9UJYmHpgt15bSYBxceHwqX7OCDM4Ek8mr6mZn45LGDtwM3dp1uup7kp8exfRPwIFbA==} hasBin: true peerDependencies: @@ -173,7 +176,7 @@ packages: dependencies: '@astrojs/compiler': 2.3.2 '@jridgewell/sourcemap-codec': 1.4.15 - '@volar/kit': 1.10.10(typescript@5.2.2) + '@volar/kit': 1.10.10(typescript@5.3.2) '@volar/language-core': 1.10.10 '@volar/language-server': 1.10.10 '@volar/language-service': 1.10.10 @@ -194,13 +197,13 @@ packages: - typescript dev: false - /@astrojs/markdown-remark@3.5.0(astro@3.5.5): + /@astrojs/markdown-remark@3.5.0(astro@3.5.6): resolution: {integrity: sha512-q7vdIqzYhxpsfghg2YmkmSXCfp4w7lBTYP+SSHw89wVhC5Riltr3u8w2otBRxNLSByNi+ht/gGkFC23Shetytw==} peerDependencies: astro: ^3.0.0 dependencies: '@astrojs/prism': 3.0.0 - astro: 3.5.5(@types/node@20.9.2)(typescript@5.2.2) + astro: 3.5.6(@types/node@20.9.2)(typescript@5.3.2) github-slugger: 2.0.0 import-meta-resolve: 3.1.1 mdast-util-definitions: 6.0.0 @@ -218,16 +221,16 @@ packages: - supports-color dev: false - /@astrojs/mdx@1.1.5(astro@3.5.5): + /@astrojs/mdx@1.1.5(astro@3.5.6): resolution: {integrity: sha512-4bveyB1Lb1vWo2kdHJjQYoCytWlrIjAxHATHUTuYnBPmdPjsfy9wuCnb9rozwyyarDABx87CzG5gotBNYd+dVA==} engines: {node: '>=18.14.1'} peerDependencies: astro: ^3.0.0 dependencies: - '@astrojs/markdown-remark': 3.5.0(astro@3.5.5) + '@astrojs/markdown-remark': 3.5.0(astro@3.5.6) '@mdx-js/mdx': 2.3.0 acorn: 8.11.2 - astro: 3.5.5(@types/node@20.9.2)(typescript@5.2.2) + astro: 3.5.6(@types/node@20.9.2)(typescript@5.3.2) es-module-lexer: 1.4.1 estree-util-visit: 1.2.1 github-slugger: 2.0.0 @@ -258,28 +261,29 @@ packages: zod: 3.22.4 dev: false - /@astrojs/starlight-tailwind@2.0.1(@astrojs/starlight@0.12.1)(@astrojs/tailwind@5.0.2)(tailwindcss@3.3.5): + /@astrojs/starlight-tailwind@2.0.1(@astrojs/starlight@0.13.0)(@astrojs/tailwind@5.0.2)(tailwindcss@3.3.5): resolution: {integrity: sha512-niMgFcR7NHcsBVy8UAN3F2gqhmoN5v83st5Hu4YzvUL+6SNwjQmIipXppXdN9+iVneRjPr6PLGzDfI+wnjSBWQ==} peerDependencies: '@astrojs/starlight': '>=0.9.0' '@astrojs/tailwind': ^5.0.0 tailwindcss: ^3.3.3 dependencies: - '@astrojs/starlight': 0.12.1(astro@3.5.5) - '@astrojs/tailwind': 5.0.2(astro@3.5.5)(tailwindcss@3.3.5)(ts-node@10.9.1) + '@astrojs/starlight': 0.13.0(astro@3.5.6) + '@astrojs/tailwind': 5.0.2(astro@3.5.6)(tailwindcss@3.3.5)(ts-node@10.9.1) tailwindcss: 3.3.5(ts-node@10.9.1) dev: false - /@astrojs/starlight@0.12.1(astro@3.5.5): - resolution: {integrity: sha512-XdsmaSWOyx4Ufsvov8Mu6R8dg5fUzzP7f3fVXALrBaHUqpHs4+6IkVUjdOhGnDkSigEPTE3gYyFixpvo0J37GA==} + /@astrojs/starlight@0.13.0(astro@3.5.6): + resolution: {integrity: sha512-3SVWGP9Qze3UkM5Wozpx+5v9dh75ZFPSHRqzeuXNtctn5nHjlzvOgIIQnuyyNhIEQMfml1lo83jL3Vsf7Qk7Iw==} peerDependencies: astro: ^3.2.0 dependencies: - '@astrojs/mdx': 1.1.5(astro@3.5.5) + '@astrojs/mdx': 1.1.5(astro@3.5.6) '@astrojs/sitemap': 3.0.3 '@pagefind/default-ui': 1.0.4 '@types/mdast': 3.0.15 - astro: 3.5.5(@types/node@20.9.2)(typescript@5.2.2) + astro: 3.5.6(@types/node@20.9.2)(typescript@5.3.2) + astro-expressive-code: 0.29.1(astro@3.5.6) bcp-47: 2.1.0 execa: 8.0.1 hast-util-select: 5.0.5 @@ -295,13 +299,13 @@ packages: - supports-color dev: false - /@astrojs/tailwind@5.0.2(astro@3.5.5)(tailwindcss@3.3.5)(ts-node@10.9.1): + /@astrojs/tailwind@5.0.2(astro@3.5.6)(tailwindcss@3.3.5)(ts-node@10.9.1): resolution: {integrity: sha512-oXqeqmBlkQmsltrsU9nEWeXOtrZIAHW8dcmX7BCdrjzPnU6dPwWzAwhddNQ9ihKiWwsLnlbwQZIo2CDigcZlIA==} peerDependencies: astro: ^3.2.4 tailwindcss: ^3.0.24 dependencies: - astro: 3.5.5(@types/node@20.9.2)(typescript@5.2.2) + astro: 3.5.6(@types/node@20.9.2)(typescript@5.3.2) autoprefixer: 10.4.16(postcss@8.4.31) postcss: 8.4.31 postcss-load-config: 4.0.1(postcss@8.4.31)(ts-node@10.9.1) @@ -558,6 +562,11 @@ packages: dependencies: '@jridgewell/trace-mapping': 0.3.9 + /@ctrl/tinycolor@3.6.1: + resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==} + engines: {node: '>=10'} + dev: false + /@emmetio/abbreviation@2.3.3: resolution: {integrity: sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==} dependencies: @@ -963,6 +972,38 @@ packages: requiresBuild: true optional: true + /@expressive-code/core@0.29.1: + resolution: {integrity: sha512-gz7K1r/S12vYPVUvhAdFcr+zdMbMhi7fPO2iTEEUCIhFUgOoUpOVjupFL+5q46URBGvoZTfmUJge1FBQmGstfA==} + dependencies: + '@ctrl/tinycolor': 3.6.1 + hast-util-to-html: 8.0.4 + hastscript: 7.2.0 + postcss: 8.4.31 + postcss-nested: 6.0.1(postcss@8.4.31) + dev: false + + /@expressive-code/plugin-frames@0.29.1: + resolution: {integrity: sha512-nnukQNBBpCSIZITBlFkxJ+4Eh+Hkmix6Db7k5lCBb6Qd/nXeodXFKWROvhtOzH6Jp1UWcpkNtBh3HVmATQRUzA==} + dependencies: + '@expressive-code/core': 0.29.1 + hastscript: 7.2.0 + dev: false + + /@expressive-code/plugin-shiki@0.29.1: + resolution: {integrity: sha512-4TOJzC8Y4fvLeM7PslH990j3x7luRCkXAWTm4L45ZrBLrU2+7SKn436/mM9k8G+Z1189+e9rSAUFwn1h/VY6QA==} + dependencies: + '@expressive-code/core': 0.29.1 + shiki: 0.14.5 + dev: false + + /@expressive-code/plugin-text-markers@0.29.1: + resolution: {integrity: sha512-fEsI1n1IEisJl+M2ayHy0AbsHIynnpq1yzc4qJk/0sXpouLOMSgw5dKftSmPio+9fXQoNfmYKmJz+OkuPmdy0A==} + dependencies: + '@expressive-code/core': 0.29.1 + hastscript: 7.2.0 + unist-util-visit-parents: 5.1.3 + dev: false + /@graphql-tools/executor@1.1.0(graphql@16.8.1): resolution: {integrity: sha512-+1wmnaUHETSYxiK/ELsT60x584Rw3QKBB7F/7fJ83HKPnLifmE2Dm/K9Eyt6L0Ppekf1jNUbWBpmBGb8P5hAeg==} engines: {node: '>=16.0.0'} @@ -1558,14 +1599,14 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: false - /@volar/kit@1.10.10(typescript@5.2.2): + /@volar/kit@1.10.10(typescript@5.3.2): resolution: {integrity: sha512-V2SyUPCPUhueqH8j5t48LJ0QsjExGSXzTv/XOdkUHV7hJ/ekyRGFqKxcfBtMq/nK6Tgu2G1ba+6u0d7e6wKcQw==} peerDependencies: typescript: '*' dependencies: '@volar/language-service': 1.10.10 typesafe-path: 0.2.2 - typescript: 5.2.2 + typescript: 5.3.2 vscode-languageserver-textdocument: 1.0.11 vscode-uri: 3.0.8 dev: false @@ -1714,6 +1755,10 @@ packages: engines: {node: '>=12'} dev: false + /ansi-sequence-parser@1.1.1: + resolution: {integrity: sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==} + dev: false + /ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -1774,14 +1819,23 @@ packages: hasBin: true dev: false - /astro@3.5.5(@types/node@20.9.2)(typescript@5.2.2): - resolution: {integrity: sha512-zJDZhO8XheXzpqkZgBXlP8e3j8psf0A21fh5Bq4HNR6gOmgOnM62Pok3O2ClbGygabfl2Preeun0pBRFn5+y0A==} + /astro-expressive-code@0.29.1(astro@3.5.6): + resolution: {integrity: sha512-hvu8kDMr3KD3vqAyJj6KdTDLuebsgnFQdw6V8myJRj464BUMiqPgmufvkuxLrqDCTJvfARJdwf/Q/H3Rqu3mhQ==} + peerDependencies: + astro: ^3.0.0-beta + dependencies: + astro: 3.5.6(@types/node@20.9.2)(typescript@5.3.2) + remark-expressive-code: 0.29.1 + dev: false + + /astro@3.5.6(@types/node@20.9.2)(typescript@5.3.2): + resolution: {integrity: sha512-50gKrQl7rlPKeChtZVLRMNQDVKJP2PoGk8ZiDVHt4U4AjJjnLs/XvOBuseoSXvQW5Zbp0IQuDN/uzq8hRhTl6w==} engines: {node: '>=18.14.1', npm: '>=6.14.0'} hasBin: true dependencies: '@astrojs/compiler': 2.3.2 '@astrojs/internal-helpers': 0.2.1 - '@astrojs/markdown-remark': 3.5.0(astro@3.5.5) + '@astrojs/markdown-remark': 3.5.0(astro@3.5.6) '@astrojs/telemetry': 3.0.4 '@babel/core': 7.23.3 '@babel/generator': 7.23.3 @@ -1829,7 +1883,7 @@ packages: shikiji: 0.6.13 string-width: 6.1.0 strip-ansi: 7.1.0 - tsconfck: 3.0.0(typescript@5.2.2) + tsconfck: 3.0.0(typescript@5.3.2) unist-util-visit: 4.1.2 vfile: 5.3.7 vite: 4.5.0(@types/node@20.9.2) @@ -2515,6 +2569,15 @@ packages: engines: {node: '>=6'} dev: false + /expressive-code@0.29.1: + resolution: {integrity: sha512-KyEkbSRz2+2gbgtYviOb8xr+QhoAfRQe1VxLAmeZ99c57KAleBpfZHU7JeHj84vputFK6Ge6P87ou9ijD1DXbw==} + dependencies: + '@expressive-code/core': 0.29.1 + '@expressive-code/plugin-frames': 0.29.1 + '@expressive-code/plugin-shiki': 0.29.1 + '@expressive-code/plugin-text-markers': 0.29.1 + dev: false + /extend-shallow@2.0.1: resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} engines: {node: '>=0.10.0'} @@ -3212,6 +3275,10 @@ packages: resolution: {integrity: sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==} dev: false + /jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + dev: false + /jsonwebtoken@9.0.2: resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} engines: {node: '>=12', npm: '>=6'} @@ -4567,6 +4634,14 @@ packages: - supports-color dev: false + /remark-expressive-code@0.29.1: + resolution: {integrity: sha512-iRdN3XLEFLlUNqUCeBPlLgaZROI5lAM3OK7bnwrmQ0ubXJTfV3oET6WL0c5QGijoCZzzDapNiRlRZPrNDoL+5Q==} + dependencies: + expressive-code: 0.29.1 + hast-util-to-html: 8.0.4 + unist-util-visit: 4.1.2 + dev: false + /remark-gfm@3.0.1: resolution: {integrity: sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==} dependencies: @@ -4803,6 +4878,15 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + /shiki@0.14.5: + resolution: {integrity: sha512-1gCAYOcmCFONmErGTrS1fjzJLA7MGZmKzrBNX7apqSwhyITJg2O102uFzXUeBxNnEkDA9vHIKLyeKq0V083vIw==} + dependencies: + ansi-sequence-parser: 1.1.1 + jsonc-parser: 3.2.0 + vscode-oniguruma: 1.7.0 + vscode-textmate: 8.0.0 + dev: false + /shikiji@0.6.13: resolution: {integrity: sha512-4T7X39csvhT0p7GDnq9vysWddf2b6BeioiN3Ymhnt3xcy9tXmDcnsEFVxX18Z4YcQgEE/w48dLJ4pPPUcG9KkA==} dependencies: @@ -5194,7 +5278,7 @@ packages: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - /tsconfck@3.0.0(typescript@5.2.2): + /tsconfck@3.0.0(typescript@5.3.2): resolution: {integrity: sha512-w3wnsIrJNi7avf4Zb0VjOoodoO0woEqGgZGQm+LHH9przdUI+XDKsWAXwxHA1DaRTjeuZNcregSzr7RaA8zG9A==} engines: {node: ^18 || >=20} hasBin: true @@ -5204,7 +5288,7 @@ packages: typescript: optional: true dependencies: - typescript: 5.2.2 + typescript: 5.3.2 dev: false /tsconfig-paths@4.2.0: @@ -5298,6 +5382,12 @@ packages: engines: {node: '>=14.17'} hasBin: true + /typescript@5.3.2: + resolution: {integrity: sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==} + engines: {node: '>=14.17'} + hasBin: true + dev: false + /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} @@ -5707,6 +5797,14 @@ packages: resolution: {integrity: sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==} dev: false + /vscode-oniguruma@1.7.0: + resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} + dev: false + + /vscode-textmate@8.0.0: + resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} + dev: false + /vscode-uri@2.1.2: resolution: {integrity: sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==} dev: false diff --git a/prisma/schema.prisma b/prisma/schema.prisma index aa71eb0..1a3b15b 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -73,7 +73,7 @@ model E7LToken { mrcryptoTokenId Int? MrCrypto MrCrypto? @relation(fields: [mrcryptoTokenId], references: [tokenId]) linkedAt BigInt - E7L E7L @relation(fields: [e7lId], references: [id]) + E7L E7L @relation(fields: [e7lId], references: [id], onDelete: Cascade) e7lId String metadataURL String imageURL String diff --git a/prisma/seed.ts b/prisma/seed.ts index 26cb773..81bc132 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -45,9 +45,9 @@ const e7lList: Prisma.E7LCreateInput[] = [ }, { name: "Mr. Crypto Gentleman's Day", - deployedBlock: 45678048, - lastBlockIndexed: 45678048, - contractAddress: "0x33c4b744557fb4f0676188a19d9f7e263fe8094e", + deployedBlock: 44709909, + lastBlockIndexed: 44709909, + contractAddress: "0x6955861dd2177324d47485a9ecca71794adb318f", imageURL: "https://media.discordapp.net/attachments/994890616163020870/1126094353111199744/NFT_Barbie_Ticket_Final.png", }, @@ -55,7 +55,7 @@ const e7lList: Prisma.E7LCreateInput[] = [ name: "Mr. Crypto Poker Club", deployedBlock: 45678048, lastBlockIndexed: 45678048, - contractAddress: "0x6955861dd2177324d47485a9ecca71794adb318f", + contractAddress: "0x33c4b744557fb4f0676188a19d9f7e263fe8094e", imageURL: "https://media.discordapp.net/attachments/1083074062756106270/1099735293134897153/ticket.jpg", }, diff --git a/src/indexer/E7L.ts b/src/indexer/E7L.ts index 8edb5d6..c9609b7 100644 --- a/src/indexer/E7L.ts +++ b/src/indexer/E7L.ts @@ -1,7 +1,13 @@ import { prisma } from "@/db"; -import { BLOCKS_PER_QUERY, bigIntMin, client } from "./common"; +import { + BLOCKS_PER_QUERY, + MRCRYPTO_ADDRESS, + bigIntMin, + client, +} from "./common"; import { abiE7L } from "./abis/abi-E7L"; import { E7L } from "@prisma/client"; +import { abiE7lNew } from "./abis/abi-E7L-new"; export async function indexE7L( lastBlockIndexed: bigint, @@ -39,8 +45,18 @@ async function indexLinks(e7l: E7L, block: bigint, currentBlock: bigint) { toBlock: bigIntMin(block + BLOCKS_PER_QUERY - 1n, currentBlock), }); + const filter2 = await client.createContractEventFilter({ + abi: abiE7lNew, + address: e7l.contractAddress as `0x${string}`, + eventName: "Link", + fromBlock: block, + toBlock: bigIntMin(block + BLOCKS_PER_QUERY - 1n, currentBlock), + }); + const logs = await client.getFilterLogs({ filter }); + const logs2 = await client.getFilterLogs({ filter: filter2 }); + // Index old E7L for (let log of logs) { const e7lTokenId = Number(log.args.tokenId); const mrcryptoTokenId = Number(log.args.parentTokenId); @@ -49,7 +65,41 @@ async function indexLinks(e7l: E7L, block: bigint, currentBlock: bigint) { console.log( `[${e7l.name.padStart(10)}] E7L ${e7lTokenId .toString() - .padStart(4)} linked to MrCrypto ${e7lTokenId.toString().padStart(4)}`, + .padStart(4)} linked to MrCrypto ${mrcryptoTokenId + .toString() + .padStart(4)}`, + ); + + await prisma.e7LToken.update({ + where: { + e7lId_e7lTokenId: { + e7lId: e7l.id, + e7lTokenId, + }, + }, + data: { + mrcryptoTokenId, + linkedAt: block, + }, + }); + } + + // Index new E7L (with parentContract in the abi) + for (let log of logs2) { + const e7lTokenId = Number(log.args.tokenId); + const mrcryptoTokenId = Number(log.args.parentTokenId); + const block = log.blockNumber ?? 0n; + + if (log.args.parentContract != MRCRYPTO_ADDRESS) { + continue; + } + + console.log( + `[${e7l.name.padStart(10)}] E7L ${e7lTokenId + .toString() + .padStart(4)} linked to MrCrypto ${mrcryptoTokenId + .toString() + .padStart(4)}`, ); await prisma.e7LToken.update({ diff --git a/src/indexer/abis/abi-E7L-new.ts b/src/indexer/abis/abi-E7L-new.ts new file mode 100644 index 0000000..0cb47a5 --- /dev/null +++ b/src/indexer/abis/abi-E7L-new.ts @@ -0,0 +1,388 @@ +export const abiE7lNew = [ + { + inputs: [ + { internalType: "uint256", name: "price_", type: "uint256" }, + { internalType: "address", name: "MRC_", type: "address" }, + { internalType: "address", name: "USDC_", type: "address" }, + { internalType: "string", name: "name_", type: "string" }, + { internalType: "string", name: "symbol_", type: "string" }, + { internalType: "string", name: "baseURI_", type: "string" }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "owner", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "approved", + type: "address", + }, + { + indexed: true, + internalType: "uint256", + name: "tokenId", + type: "uint256", + }, + ], + name: "Approval", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "owner", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "operator", + type: "address", + }, + { indexed: false, internalType: "bool", name: "approved", type: "bool" }, + ], + name: "ApprovalForAll", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "tokenId", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "parentTokenId", + type: "uint256", + }, + { + indexed: false, + internalType: "contract IERC721", + name: "parentContract", + type: "address", + }, + ], + name: "Link", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "participant", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "tokenId", + type: "uint256", + }, + ], + name: "NewParticipant", + type: "event", + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: "address", name: "from", type: "address" }, + { indexed: true, internalType: "address", name: "to", type: "address" }, + { + indexed: true, + internalType: "uint256", + name: "tokenId", + type: "uint256", + }, + ], + name: "Transfer", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "tokenId", + type: "uint256", + }, + ], + name: "Unlink", + type: "event", + }, + { + inputs: [ + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "tokenId", type: "uint256" }, + ], + name: "approve", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "address", name: "owner", type: "address" }], + name: "balanceOf", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "baseExtension", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "baseURI", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "price_", type: "uint256" }], + name: "changePrice", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "tokenId", type: "uint256" }], + name: "getApproved", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getParticiapants", + outputs: [{ internalType: "uint256[]", name: "", type: "uint256[]" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "owner", type: "address" }, + { internalType: "address", name: "operator", type: "address" }, + ], + name: "isApprovedForAll", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "tokenId", type: "uint256" }], + name: "isRegistered", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "uint256", name: "tokenId", type: "uint256" }, + { internalType: "uint256", name: "parentTokenId", type: "uint256" }, + { + internalType: "contract IERC721", + name: "parentContract", + type: "address", + }, + ], + name: "linkToken", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "tokenId", type: "uint256" }], + name: "mint", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "name", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "owner", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "tokenId", type: "uint256" }], + name: "ownerOf", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "paused", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "price", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "from", type: "address" }, + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "tokenId", type: "uint256" }, + ], + name: "safeTransferFrom", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "from", type: "address" }, + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "tokenId", type: "uint256" }, + { internalType: "bytes", name: "data", type: "bytes" }, + ], + name: "safeTransferFrom", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "operator", type: "address" }, + { internalType: "bool", name: "approved", type: "bool" }, + ], + name: "setApprovalForAll", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "string", name: "_newBaseExtension", type: "string" }, + ], + name: "setBaseExtension", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "string", name: "_newBaseURI", type: "string" }], + name: "setBaseURI", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "bool", name: "paused_", type: "bool" }], + name: "setPaused", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "bytes4", name: "interfaceId", type: "bytes4" }], + name: "supportsInterface", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "symbol", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "tokenId", type: "uint256" }], + name: "syncToken", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "tokenId", type: "uint256" }], + name: "tokenInfo", + outputs: [ + { + components: [ + { internalType: "uint256", name: "parentTokenId", type: "uint256" }, + { + internalType: "contract IERC721", + name: "parentContract", + type: "address", + }, + ], + internalType: "struct LinkableToken", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "tokenId", type: "uint256" }], + name: "tokenURI", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "from", type: "address" }, + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "tokenId", type: "uint256" }, + ], + name: "transferFrom", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "address", name: "owner_", type: "address" }], + name: "transferOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "withdraw", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { stateMutability: "payable", type: "receive" }, +] as const; diff --git a/src/indexer/common.ts b/src/indexer/common.ts index 2faaabe..fa650eb 100644 --- a/src/indexer/common.ts +++ b/src/indexer/common.ts @@ -4,6 +4,9 @@ import { polygon } from "viem/chains"; export const BLOCKS_PER_QUERY = 100_000n as const; +export const MRCRYPTO_ADDRESS = + "0xeF453154766505FEB9dBF0a58E6990fd6eB66969" as const; + const ALCHEMY_URL = env.RPC_URL; const transport = http(ALCHEMY_URL); diff --git a/src/indexer/mrcrypto.ts b/src/indexer/mrcrypto.ts index 7454b41..8486427 100644 --- a/src/indexer/mrcrypto.ts +++ b/src/indexer/mrcrypto.ts @@ -1,5 +1,11 @@ import { prisma } from "@/db"; -import { BLOCKS_PER_QUERY, bigIntMax, bigIntMin, client } from "./common"; +import { + BLOCKS_PER_QUERY, + MRCRYPTO_ADDRESS, + bigIntMax, + bigIntMin, + client, +} from "./common"; import { abiMrcrypto } from "./abis/abi-mrcrypto"; import { formatEther, formatUnits } from "viem"; import { abiWETH } from "./abis/abi-weth"; @@ -7,7 +13,6 @@ import { metadata } from "./metadata"; import { Payment } from "@prisma/client"; const MRCRYPTO_DEPLOY_BLOCK: bigint = 25839541n as const; -const MRCRYPTO_ADDRESS = "0xeF453154766505FEB9dBF0a58E6990fd6eB66969" as const; const USDC_ADDRESS = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174" as const; const WETH_ADDRESS = "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619" as const; diff --git a/web/astro.config.mjs b/web/astro.config.mjs index 58298f8..314ee2f 100644 --- a/web/astro.config.mjs +++ b/web/astro.config.mjs @@ -55,7 +55,7 @@ export default defineConfig({ ], }, { - label: "Utilizando docker", + label: "Instalación con docker", items: [ { label: "Pre-requisitos", @@ -67,6 +67,15 @@ export default defineConfig({ }, ], }, + { + label: "Uso del indexador", + items: [ + { + label: "Playground", + link: "/guia-de-uso/playground", + }, + ], + }, ], }, { @@ -120,14 +129,6 @@ export default defineConfig({ rel: "noopener", }, }, - { - label: "Discord", - link: "https://discord.gg/cRBBd27FSj", - attrs: { - target: "_blank", - rel: "noopener", - }, - }, ], }, ], diff --git a/web/package.json b/web/package.json index 4b372c8..b173317 100644 --- a/web/package.json +++ b/web/package.json @@ -11,12 +11,13 @@ }, "dependencies": { "@astrojs/check": "^0.3.1", - "@astrojs/starlight": "^0.12.1", + "@astrojs/starlight": "^0.13.0", "@astrojs/starlight-tailwind": "^2.0.1", - "@astrojs/tailwind": "^5.0.0", - "astro": "^3.2.3", - "sharp": "^0.32.5", - "tailwindcss": "^3.3.3", - "typescript": "5.2.2" + "@astrojs/tailwind": "^5.0.2", + "astro": "^3.5.6", + "astro-expressive-code": "^0.29.1", + "sharp": "^0.32.6", + "tailwindcss": "^3.3.5", + "typescript": "5.3.2" } } diff --git a/web/src/assets/playground-example.png b/web/src/assets/playground-example.png new file mode 100644 index 0000000..161e701 Binary files /dev/null and b/web/src/assets/playground-example.png differ diff --git a/web/src/content/docs/guia-de-uso/docker/instalacion.md b/web/src/content/docs/guia-de-uso/docker/instalacion.md index aa496e8..069b1d0 100644 --- a/web/src/content/docs/guia-de-uso/docker/instalacion.md +++ b/web/src/content/docs/guia-de-uso/docker/instalacion.md @@ -7,14 +7,14 @@ description: Requisitos necesarios para la puesta en marcha del indexador. Para clonar el repositorio, ejecuta el siguiente comando en tu terminal: -```bash +```bash frame="none" git clone https://github.com/Racks-Community/MrCryptoIndexer.git cd MrCryptoIndexer ``` ## Copiar variables de entorno -```bash +```bash frame="none" cp .env.example .env ``` @@ -23,11 +23,13 @@ cp .env.example .env La única variable de entorno **obligatoria** para configurar es `RPC_URL`, esta es la API de acceso a la blockchain de Polygon. Las demás pueden dejarse con los valores por defecto (_no recomendable para producción_). -Puedes conseguirla una propia en (Alchemy)[https://www.alchemy.com/] +Puedes conseguirla una propia en [Alchemy](https://www.alchemy.com/) Debería tener un formato similar a este: -``` +```bash ins="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +# .env + RPC_URL=https://polygon-mainnet.g.alchemy.com/v2/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ``` @@ -35,6 +37,55 @@ RPC_URL=https://polygon-mainnet.g.alchemy.com/v2/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Para levantar el entorno, utilizado `docker compose` -```bash +```bash frame="none" docker compose up --build -d ``` + +En la terminal deberíamos ver algo similar a esto: + +```bash title="Terminal" +CLI Building entry: src/server.ts +CLI Using tsconfig: tsconfig.json +CLI tsup v8.0.0 +CLI Using tsup config: /app/tsup.config.ts +CLI Target: node18 +CLI Cleaning output folder +CJS Build start +CJS dist/server.js 2.69 MB +CJS ⚡️ Build success in 198ms +DTS Build start +DTS ⚡️ Build success in 5032ms +DTS dist/server.d.ts 13.00 B + +> mrcryptoindexer@1.0.0 build:schema +> ts-node -r tsconfig-paths/register src/schema/index.ts + +Indexer stared ⚒️ at Tue, 21 Nov 2023 16:55:28 GMT +🚀 Server ready at: http://127.0.0.1:4000 +⭐️ See sample queries: http://pris.ly/e/ts/graphql#using-the-graphql-api + +Current block number: 50219518 +indexing from block 25839541 to 25939540 +indexing from block 25939541 to 26039540 +indexing from block 26039541 to 26139540 +... +``` + +Ahora toca esperar a que se sincronice la base de datos con la blockchain, esto tardar un rato, sobre todo al principio. + +:::note + +Los rangos de bloques del `26939541-27039540` y el `27439541-27539540`, son los que más tardan en sincronizarse, ya que son los que más transacciones tienen, debido a que son los bloques correspondientes a la primera y segunda fase del _mint_ del los **Mr. Crypto**. + +::: + +## Indexación terminada + +Cuando la indexación haya terminado, deberíamos ver algo similar a esto en la terminal: + +```bash title="Terminal" +Indexer finished ✅ 🎉 😄 at Tue, 21 Nov 2023 18:02:36 GMT +Waiting 5 minutes for next indexation ⏰ +``` + +Y a los 5 minutos, volverá a comenzar la indexación desde donde termino la última vez y así sucesivamente. diff --git a/web/src/content/docs/guia-de-uso/local/instalacion.md b/web/src/content/docs/guia-de-uso/local/instalacion.md index 597118b..cf2dc8e 100644 --- a/web/src/content/docs/guia-de-uso/local/instalacion.md +++ b/web/src/content/docs/guia-de-uso/local/instalacion.md @@ -34,7 +34,8 @@ Para la variable `RPC_URL`, puedes conseguir una propia en (Alchemy)[https://www Debería tener un formato similar a este: -``` +```bash +# .env DATABASE_URL=postgresql://{usario}:{constraseña}@localhost:5432/{nombre de la base de datos} RPC_URL=https://polygon-mainnet.g.alchemy.com/v2/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ``` @@ -56,3 +57,52 @@ pnpm db:seed ```bash pnpm start ``` + +En la terminal deberíamos ver algo similar a esto: + +```bash title="Terminal" +CLI Building entry: src/server.ts +CLI Using tsconfig: tsconfig.json +CLI tsup v8.0.0 +CLI Using tsup config: /app/tsup.config.ts +CLI Target: node18 +CLI Cleaning output folder +CJS Build start +CJS dist/server.js 2.69 MB +CJS ⚡️ Build success in 198ms +DTS Build start +DTS ⚡️ Build success in 5032ms +DTS dist/server.d.ts 13.00 B + +> mrcryptoindexer@1.0.0 build:schema +> ts-node -r tsconfig-paths/register src/schema/index.ts + +Indexer stared ⚒️ at Tue, 21 Nov 2023 16:55:28 GMT +🚀 Server ready at: http://127.0.0.1:4000 +⭐️ See sample queries: http://pris.ly/e/ts/graphql#using-the-graphql-api + +Current block number: 50219518 +indexing from block 25839541 to 25939540 +indexing from block 25939541 to 26039540 +indexing from block 26039541 to 26139540 +... +``` + +Ahora toca esperar a que se sincronice la base de datos con la blockchain, esto tardar un rato, sobre todo al principio. + +:::note + +Los rangos de bloques del `26939541-27039540` y el `27439541-27539540`, son los que más tardan en sincronizarse, ya que son los que más transacciones tienen, debido a que son los bloques correspondientes a la primera y segunda fase del _mint_ del los **Mr. Crypto**. + +::: + +## Indexación terminada + +Cuando la indexación haya terminado, deberíamos ver algo similar a esto en la terminal: + +```bash title="Terminal" +Indexer finished ✅ 🎉 😄 at Tue, 21 Nov 2023 18:02:36 GMT +Waiting 5 minutes for next indexation ⏰ +``` + +Y a los 5 minutos, volverá a comenzar la indexación desde donde termino la última vez y así sucesivamente. diff --git a/web/src/content/docs/guia-de-uso/playground.md b/web/src/content/docs/guia-de-uso/playground.md new file mode 100644 index 0000000..d0bb87d --- /dev/null +++ b/web/src/content/docs/guia-de-uso/playground.md @@ -0,0 +1,62 @@ +--- +title: Playground +description: Playground para probar el funcionamiento del indexador. +--- + +## ¿Qué es el Playground? + +El Playground es una herramienta que te permite probar el funcionamiento del indexador de MrCrypto, haciendo petición de tipo GraphQL. + +## ¿Cómo funciona? + +Una vez tenemos el indexador en funcionamiento, podemos acceder al Playground a través de `localhost:4000`. + +Al izquierda de la pantalla, podemos ver el panel de peticiones, donde podemos escribir las peticiones que queremos hacer al indexador. + +Al lado derecho, podemos ver el panel de resultados, donde podemos ver el resultado de la petición que hemos hecho. + +![Playground](../../../assets/playground-example.png) + +## Probar el funcionamiento + +Para probar el funcionamiento, podemos hacer una petición de prueba, como por ejemplo la información general de colección: + +```graphql +{ + collectionInfo { + name + description + address + volumen { + amount + currency + } + } +} +``` + +Resultado esperado + +```json +{ + "data": { + "collectionInfo": { + "name": "Mr. Crypto by Racksmafia", + "description": "The official RACKS® NFT collection", + "address": "0xeF453154766505FEB9dBF0a58E6990fd6eB66969", + "volumen": [ + { + "amount": 18359.35350999999, + "currency": "USDC" + }, + { + "amount": 820.9822752498037, + "currency": "WETH" + } + ] + } + } +} +``` + +[Probar en vivo](https://indexer.mrcryptonft.com/?query=query+%7B%0A++collectionInfo%7B%0A++++name%0A++++description%0A++++address%0A++++volumen%7B%0A++++++amount%0A++++++currency%0A++++%7D%0A++%7D%0A%7D)