From 8c51ef58ec794e2da0cee07ab4b5bd148ba9cde5 Mon Sep 17 00:00:00 2001 From: Pat Sissons Date: Wed, 21 Feb 2024 18:05:11 -0800 Subject: [PATCH] improved opengraph support --- .eslintrc.cjs | 10 +- package.json | 10 +- pnpm-lock.yaml | 365 +++++++++++++++++- src/app.html | 2 - src/lib/client/constants.ts | 1 + src/lib/client/ens.ts | 2 +- src/lib/client/graphql.ts | 22 +- src/lib/client/poap.ts | 111 ++++-- src/lib/client/urql.ts | 22 +- src/lib/components/AppFrame/app-frame.svelte | 6 +- .../EventTokens/event-tokens.svelte | 9 +- src/lib/components/Loadable/index.ts | 2 + .../components/Loadable/loadable-query.svelte | 13 + src/lib/components/Loadable/loadable.svelte | 22 ++ src/lib/components/Seo/index.ts | 1 + src/lib/components/Seo/seo.svelte | 24 +- src/lib/components/Seo/types.ts | 5 + src/lib/components/Token/account.svelte | 4 +- src/lib/components/Token/token.svelte | 5 +- src/lib/components/Tokens/index.ts | 1 + src/lib/components/Tokens/tokens.svelte | 25 ++ src/lib/server/ens.ts | 8 +- src/lib/server/poap.ts | 84 +++- src/lib/types/ambient.d.ts | 12 +- src/lib/types/poap.ts | 5 + src/routes/+layout.svelte | 5 +- src/routes/+page.server.ts | 11 + src/routes/+page.svelte | 36 +- src/routes/account/[address]/+page.server.ts | 16 + src/routes/account/[address]/+page.svelte | 26 ++ src/routes/api/ens/[address]/+server.ts | 3 +- src/routes/api/poap/[id]/+server.ts | 3 +- src/routes/event/[id]/+page.server.ts | 15 +- src/routes/event/[id]/+page.svelte | 23 +- src/routes/og/account/[address]/+server.ts | 32 ++ src/routes/og/event/[id]/+server.ts | 23 ++ src/routes/og/token/[id]/+server.ts | 6 + .../og/token/[id]/debug/+page.server.ts | 37 ++ src/routes/og/token/[id]/debug/+page.svelte | 12 + src/routes/og/token/[id]/og-background.png | Bin 0 -> 137885 bytes src/routes/og/token/[id]/og-token.svelte | 181 +++++++++ .../og/token/[id]/svelte-to-png/index.ts | 34 ++ .../og/token/[id]/svelte-to-png/inlineCSS.ts | 80 ++++ .../token/[id]/svelte-to-png/svelteToJsx.ts | 31 ++ .../[id]/svelte-to-png/toReactElement.ts | 139 +++++++ src/routes/og/token/[id]/tokenResponse.ts | 60 +++ src/routes/token/[id]/+page.server.ts | 35 +- src/routes/token/[id]/+page.svelte | 12 +- src/routes/token/[id]/data.ts | 35 ++ vite.config.ts | 8 +- 50 files changed, 1481 insertions(+), 153 deletions(-) create mode 100644 src/lib/client/constants.ts create mode 100644 src/lib/components/Loadable/index.ts create mode 100644 src/lib/components/Loadable/loadable-query.svelte create mode 100644 src/lib/components/Loadable/loadable.svelte create mode 100644 src/lib/components/Seo/types.ts create mode 100644 src/lib/components/Tokens/index.ts create mode 100644 src/lib/components/Tokens/tokens.svelte create mode 100644 src/routes/+page.server.ts create mode 100644 src/routes/account/[address]/+page.server.ts create mode 100644 src/routes/account/[address]/+page.svelte create mode 100644 src/routes/og/account/[address]/+server.ts create mode 100644 src/routes/og/event/[id]/+server.ts create mode 100644 src/routes/og/token/[id]/+server.ts create mode 100644 src/routes/og/token/[id]/debug/+page.server.ts create mode 100644 src/routes/og/token/[id]/debug/+page.svelte create mode 100644 src/routes/og/token/[id]/og-background.png create mode 100644 src/routes/og/token/[id]/og-token.svelte create mode 100644 src/routes/og/token/[id]/svelte-to-png/index.ts create mode 100644 src/routes/og/token/[id]/svelte-to-png/inlineCSS.ts create mode 100644 src/routes/og/token/[id]/svelte-to-png/svelteToJsx.ts create mode 100644 src/routes/og/token/[id]/svelte-to-png/toReactElement.ts create mode 100644 src/routes/og/token/[id]/tokenResponse.ts create mode 100644 src/routes/token/[id]/data.ts diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 614692d..8745c4b 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -21,6 +21,10 @@ module.exports = { es2017: true, node: true, }, + globals: { + $$Generic: 'readable', + $$Slots: 'readable', + }, overrides: [ { files: ['*.svelte'], @@ -38,8 +42,11 @@ module.exports = { }, ], rules: { + // this rule is interfering with $$Generic, so we'll disable it for now + // see: https://github.com/sveltejs/eslint-plugin-svelte/issues/541 + '@typescript-eslint/no-redundant-type-constituents': 'off', '@typescript-eslint/no-unused-vars': [ - 'warn', + 'error', { // allow unused function parameters that start with an underscore argsIgnorePattern: '^_', @@ -47,6 +54,7 @@ module.exports = { destructuredArrayIgnorePattern: '^_', // allow destructuring of unused fields in order to shrink an object shape ignoreRestSiblings: true, + varsIgnorePattern: '^\\$\\$(Props|Events|Slots)$', }, ], }, diff --git a/package.json b/package.json index 079ae82..9105d62 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "scripts": { "clean": "rimraf ./.svelte-kit", "dev": "vite dev", - "build": "vite build", + "build": "pnpm sync && vite build", "preview": "vite preview", "sync": "svelte-kit sync", "validate:svelte": "pnpm sync && svelte-check --tsconfig ./tsconfig.json", @@ -21,10 +21,15 @@ "dependencies": { "@download/blockies": "^1.0.3", "@ensdomains/ensjs": "^3.2.0", + "@fontsource/inter": "^5.0.16", + "@fontsource/roboto-mono": "^5.0.16", + "@napi-rs/canvas": "^0.1.45", + "@resvg/resvg-js": "^2.6.0", "@urql/core": "^4.2.3", "@urql/svelte": "^4.0.4", "date-fns": "^3.3.1", "dotenv": "^16.3.2", + "satori": "^0.10.11", "svelte": "^4.2.7", "tailwindcss": "^3.4.1", "viem": "^2.5.0" @@ -55,7 +60,8 @@ "svelte-check": "^3.6.0", "tslib": "^2.4.1", "typescript": "^5.0.0", - "vite": "^5.0.3" + "vite": "^5.0.3", + "vite-plugin-arraybuffer": "^0.0.2" }, "type": "module" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ed31a19..b04f637 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,18 @@ importers: '@ensdomains/ensjs': specifier: ^3.2.0 version: 3.2.0(typescript@5.3.3)(viem@2.5.0) + '@fontsource/inter': + specifier: ^5.0.16 + version: 5.0.16 + '@fontsource/roboto-mono': + specifier: ^5.0.16 + version: 5.0.16 + '@napi-rs/canvas': + specifier: ^0.1.45 + version: 0.1.45 + '@resvg/resvg-js': + specifier: ^2.6.0 + version: 2.6.0 '@urql/core': specifier: ^4.2.3 version: 4.2.3(graphql@16.8.1) @@ -26,6 +38,9 @@ importers: dotenv: specifier: ^16.3.2 version: 16.3.2 + satori: + specifier: ^0.10.11 + version: 0.10.13 svelte: specifier: ^4.2.7 version: 4.2.9 @@ -114,6 +129,9 @@ importers: vite: specifier: ^5.0.3 version: 5.0.12 + vite-plugin-arraybuffer: + specifier: ^0.0.2 + version: 0.0.2 packages/subgraph: dependencies: @@ -685,6 +703,14 @@ packages: js-yaml: 4.1.0 dev: false + /@fontsource/inter@5.0.16: + resolution: {integrity: sha512-qF0aH5UiZvCmneX5orJbVRoc2VTyLTV3X/7laMp03Qt28L+B9tFlZODOGUL64wDWc69YVdi1LeJB0cIgd51lvw==} + dev: false + + /@fontsource/roboto-mono@5.0.16: + resolution: {integrity: sha512-unZYfjXts55DQyODz0I9DzbSrS5DRKPNq9crJpNJe/Vy818bLnijprcJv3fvqwdDqTT0dRm2Fhk09QEIdtAc+Q==} + dev: false + /@graphprotocol/graph-cli@0.67.1(@types/node@20.11.5)(node-fetch@3.3.2)(typescript@5.3.3): resolution: {integrity: sha512-8Q8QNDmag/jj8y6dc3X77RsPniUlAWambg5Lp9k73KbXgCm8Zy2MqnlbP3/QhLWq84ZhwqBJ8Yyyrf8Z1+g+MA==} engines: {node: '>=18'} @@ -849,6 +875,102 @@ packages: - supports-color dev: true + /@napi-rs/canvas-android-arm64@0.1.45: + resolution: {integrity: sha512-ogC8zhiuxzFK0qBg0RHOI+UJ9Ne7/fM2k1+E+VShuuf3DqFgLvu+d1L0MgM3SnqgzIaPNUyc78yleG/xMhBJjA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@napi-rs/canvas-darwin-arm64@0.1.45: + resolution: {integrity: sha512-7bbTZR6Y84SXau/WNUU+iskrnzXUva1RgF7Eto73mgkZa8KAXNLjCY/emN4Vjq2YxxI3BysVrRuZx53ZDVrFOQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@napi-rs/canvas-darwin-x64@0.1.45: + resolution: {integrity: sha512-/JHRIpkedmOXSDTUKleQjTKKo0lZt9aajPLPhVGZDl50vrY5s6r2RPa4lwp3OXbb7YyIoeYTGioID0zP5bDF2w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@napi-rs/canvas-linux-arm-gnueabihf@0.1.45: + resolution: {integrity: sha512-rcsMEzb+TgXFXwhqtde31wFh0d9eXiSsGh40EuntS3RKK67+6G2amDjtGedlUFwetdF2DZHx3eJgCkVpTzg1rg==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@napi-rs/canvas-linux-arm64-gnu@0.1.45: + resolution: {integrity: sha512-IYXqmT4vx12XSPoNjQT0iKQdS79lNpafYqnEl27L3eTOV8Kh9W+f57lONNc/k05RUS0UD/H/aXv5vbRiGqn9Ng==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@napi-rs/canvas-linux-arm64-musl@0.1.45: + resolution: {integrity: sha512-gphILu2+CV9rj1cbklYRfWGGCOtlezwvszhlea6aus75AL4etQ4xlWn2DKHz8vphh13cRHS8QbChCUmwLuxdgg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@napi-rs/canvas-linux-x64-gnu@0.1.45: + resolution: {integrity: sha512-gROXfmw5lmVZe6lRjxi1oX1VsmPAHA6kv2Kvl3j/g/maNm3KgLRE1sfolCbGvSglKyUvXQiemyUUEcnhppCDrA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@napi-rs/canvas-linux-x64-musl@0.1.45: + resolution: {integrity: sha512-hAgc/t03w+WwyR9ntc0kJpSqd2KNrx7l03+qrbdoYL95MP2sC4ycdhAC8UWM0zqowATBd2sOdGSrXdeHZihyzQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@napi-rs/canvas-win32-x64-msvc@0.1.45: + resolution: {integrity: sha512-gnYuSuNrKJojIaqWdZjAC5h92RPW9vdKKhPJzQgZPtUkQJ7Do3JfIDQObg7TS3E18Zf6A5+fRo25VIcKhCJvMg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@napi-rs/canvas@0.1.45: + resolution: {integrity: sha512-6BBOL62RvY8JFFpnScVT4BLJha/yya/NNtP2K1rIlhnLgfnzAQxKCISoLZZHjBVox6ngBOR4hHqJRoqoLFXhZQ==} + engines: {node: '>= 10'} + optionalDependencies: + '@napi-rs/canvas-android-arm64': 0.1.45 + '@napi-rs/canvas-darwin-arm64': 0.1.45 + '@napi-rs/canvas-darwin-x64': 0.1.45 + '@napi-rs/canvas-linux-arm-gnueabihf': 0.1.45 + '@napi-rs/canvas-linux-arm64-gnu': 0.1.45 + '@napi-rs/canvas-linux-arm64-musl': 0.1.45 + '@napi-rs/canvas-linux-x64-gnu': 0.1.45 + '@napi-rs/canvas-linux-x64-musl': 0.1.45 + '@napi-rs/canvas-win32-x64-msvc': 0.1.45 + dev: false + /@noble/curves@1.2.0: resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} dependencies: @@ -1085,6 +1207,132 @@ packages: resolution: {integrity: sha512-zGzFsgtZ44mgL4Xef2gOy1hrRVdrs9mcxCOOKZrIPsmbZW14yTkaF591GXxpQvjXiHtgZ/iA9qLyWH6oSReIxQ==} dev: false + /@resvg/resvg-js-android-arm-eabi@2.6.0: + resolution: {integrity: sha512-lJnZ/2P5aMocrFMW7HWhVne5gH82I8xH6zsfH75MYr4+/JOaVcGCTEQ06XFohGMdYRP3v05SSPLPvTM/RHjxfA==} + engines: {node: '>= 10'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@resvg/resvg-js-android-arm64@2.6.0: + resolution: {integrity: sha512-N527f529bjMwYWShZYfBD60dXA4Fux+D695QsHQ93BDYZSHUoOh1CUGUyICevnTxs7VgEl98XpArmUWBZQVMfQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@resvg/resvg-js-darwin-arm64@2.6.0: + resolution: {integrity: sha512-MabUKLVayEwlPo0mIqAmMt+qESN8LltCvv5+GLgVga1avpUrkxj/fkU1TKm8kQegutUjbP/B0QuMuUr0uhF8ew==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@resvg/resvg-js-darwin-x64@2.6.0: + resolution: {integrity: sha512-zrFetdnSw/suXjmyxSjfDV7i61hahv6DDG6kM7BYN2yJ3Es5+BZtqYZTcIWogPJedYKmzN1YTMWGd/3f0ubFiA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@resvg/resvg-js-linux-arm-gnueabihf@2.6.0: + resolution: {integrity: sha512-sH4gxXt7v7dGwjGyzLwn7SFGvwZG6DQqLaZ11MmzbCwd9Zosy1TnmrMJfn6TJ7RHezmQMgBPi18bl55FZ1AT4A==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@resvg/resvg-js-linux-arm64-gnu@2.6.0: + resolution: {integrity: sha512-fCyMncqCJtrlANADIduYF4IfnWQ295UKib7DAxFXQhBsM9PLDTpizr0qemZcCNadcwSVHnAIzL4tliZhCM8P6A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@resvg/resvg-js-linux-arm64-musl@2.6.0: + resolution: {integrity: sha512-ouLjTgBQHQyxLht4FdMPTvuY8xzJigM9EM2Tlu0llWkN1mKyTQrvYWi6TA6XnKdzDJHy7ZLpWpjZi7F5+Pg+Vg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@resvg/resvg-js-linux-x64-gnu@2.6.0: + resolution: {integrity: sha512-n3zC8DWsvxC1AwxpKFclIPapDFibs5XdIRoV/mcIlxlh0vseW1F49b97F33BtJQRmlntsqqN6GMMqx8byB7B+Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@resvg/resvg-js-linux-x64-musl@2.6.0: + resolution: {integrity: sha512-n4tasK1HOlAxdTEROgYA1aCfsEKk0UOFDNd/AQTTZlTmCbHKXPq+O8npaaKlwXquxlVK8vrkcWbksbiGqbCAcw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@resvg/resvg-js-win32-arm64-msvc@2.6.0: + resolution: {integrity: sha512-X2+EoBJFwDI5LDVb51Sk7ldnVLitMGr9WwU/i21i3fAeAXZb3hM16k67DeTy16OYkT2dk/RfU1tP1wG+rWbz2Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@resvg/resvg-js-win32-ia32-msvc@2.6.0: + resolution: {integrity: sha512-L7oevWjQoUgK5W1fCKn0euSVemhDXVhrjtwqpc7MwBKKimYeiOshO1Li1pa8bBt5PESahenhWgdB6lav9O0fEg==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@resvg/resvg-js-win32-x64-msvc@2.6.0: + resolution: {integrity: sha512-8lJlghb+Unki5AyKgsnFbRJwkEj9r1NpwyuBG8yEJiG1W9eEGl03R3I7bsVa3haof/3J1NlWf0rzSa1G++A2iw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@resvg/resvg-js@2.6.0: + resolution: {integrity: sha512-Tf3YpbBKcQn991KKcw/vg7vZf98v01seSv6CVxZBbRkL/xyjnoYB6KgrFL6zskT1A4dWC/vg77KyNOW+ePaNlA==} + engines: {node: '>= 10'} + optionalDependencies: + '@resvg/resvg-js-android-arm-eabi': 2.6.0 + '@resvg/resvg-js-android-arm64': 2.6.0 + '@resvg/resvg-js-darwin-arm64': 2.6.0 + '@resvg/resvg-js-darwin-x64': 2.6.0 + '@resvg/resvg-js-linux-arm-gnueabihf': 2.6.0 + '@resvg/resvg-js-linux-arm64-gnu': 2.6.0 + '@resvg/resvg-js-linux-arm64-musl': 2.6.0 + '@resvg/resvg-js-linux-x64-gnu': 2.6.0 + '@resvg/resvg-js-linux-x64-musl': 2.6.0 + '@resvg/resvg-js-win32-arm64-msvc': 2.6.0 + '@resvg/resvg-js-win32-ia32-msvc': 2.6.0 + '@resvg/resvg-js-win32-x64-msvc': 2.6.0 + dev: false + /@rollup/pluginutils@4.2.1: resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} @@ -1205,17 +1453,26 @@ packages: resolution: {integrity: sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==} dependencies: '@noble/curves': 1.2.0 - '@noble/hashes': 1.3.2 + '@noble/hashes': 1.3.3 '@scure/base': 1.1.5 dev: false /@scure/bip39@1.2.1: resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==} dependencies: - '@noble/hashes': 1.3.2 + '@noble/hashes': 1.3.3 '@scure/base': 1.1.5 dev: false + /@shuding/opentype.js@1.4.0-beta.0: + resolution: {integrity: sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==} + engines: {node: '>= 8.0.0'} + hasBin: true + dependencies: + fflate: 0.7.4 + string.prototype.codepointat: 0.2.1 + dev: false + /@sveltejs/adapter-auto@3.1.1(@sveltejs/kit@2.4.1): resolution: {integrity: sha512-6LeZft2Fo/4HfmLBi5CucMYmgRxgcETweQl/yQoZo/895K3S9YWYN4Sfm/IhwlIpbJp3QNvhKmwCHbsqQNYQpw==} peerDependencies: @@ -1960,6 +2217,11 @@ packages: safe-buffer: 5.2.1 dev: false + /base64-js@0.0.8: + resolution: {integrity: sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==} + engines: {node: '>= 0.4'} + dev: false + /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} dev: false @@ -2148,6 +2410,10 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} + /camelize@1.0.1: + resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} + dev: false + /caniuse-lite@1.0.30001579: resolution: {integrity: sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==} dev: true @@ -2415,11 +2681,32 @@ packages: shebang-command: 2.0.0 which: 2.0.2 + /css-background-parser@0.1.0: + resolution: {integrity: sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==} + dev: false + + /css-box-shadow@1.0.0-3: + resolution: {integrity: sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==} + dev: false + + /css-color-keywords@1.0.0: + resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==} + engines: {node: '>=4'} + dev: false + /css-functions-list@3.2.1: resolution: {integrity: sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==} engines: {node: '>=12 || >=16'} dev: true + /css-to-react-native@3.2.0: + resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==} + dependencies: + camelize: 1.0.1 + css-color-keywords: 1.0.0 + postcss-value-parser: 4.2.0 + dev: false + /css-tree@2.3.1: resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} @@ -2680,6 +2967,10 @@ packages: minimalistic-crypto-utils: 1.0.1 dev: false + /emoji-regex@10.3.0: + resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + dev: false + /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -2780,6 +3071,10 @@ packages: engines: {node: '>=6'} dev: true + /escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + dev: false + /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} @@ -3122,6 +3417,10 @@ packages: web-streams-polyfill: 3.3.2 dev: false + /fflate@0.7.4: + resolution: {integrity: sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==} + dev: false + /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -3557,6 +3856,11 @@ packages: dependencies: function-bind: 1.1.2 + /hex-rgb@4.3.0: + resolution: {integrity: sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==} + engines: {node: '>=6'} + dev: false + /hmac-drbg@1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} dependencies: @@ -4136,6 +4440,13 @@ packages: resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==} engines: {node: '>=14'} + /linebreak@1.1.0: + resolution: {integrity: sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==} + dependencies: + base64-js: 0.0.8 + unicode-trie: 2.0.0 + dev: false + /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -4644,6 +4955,10 @@ packages: p-limit: 3.1.0 dev: true + /pako@0.2.9: + resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} + dev: false + /pako@2.1.0: resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} dev: false @@ -4658,6 +4973,13 @@ packages: resolution: {integrity: sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==} dev: false + /parse-css-color@0.2.1: + resolution: {integrity: sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg==} + dependencies: + color-name: 1.1.4 + hex-rgb: 4.3.0 + dev: false + /parse-duration@1.1.0: resolution: {integrity: sha512-z6t9dvSJYaPoQq7quMzdEagSFtpGu+utzHqqxmpVWNNZRIXnvqyCvn9XsTdh7c/w0Bqmdz3RB3YnRaKtpRtEXQ==} dev: false @@ -5203,6 +5525,22 @@ packages: rimraf: 2.7.1 dev: true + /satori@0.10.13: + resolution: {integrity: sha512-klCwkVYMQ/ZN5inJLHzrUmGwoRfsdP7idB5hfpJ1jfiJk1ErDitK8Hkc6Kll1+Ox2WtqEuGecSZLnmup3CGzvQ==} + engines: {node: '>=16'} + dependencies: + '@shuding/opentype.js': 1.4.0-beta.0 + css-background-parser: 0.1.0 + css-box-shadow: 1.0.0-3 + css-to-react-native: 3.2.0 + emoji-regex: 10.3.0 + escape-html: 1.0.3 + linebreak: 1.1.0 + parse-css-color: 0.2.1 + postcss-value-parser: 4.2.0 + yoga-wasm-web: 0.3.3 + dev: false + /scrypt-js@3.0.1: resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} dev: false @@ -5433,6 +5771,10 @@ packages: emoji-regex: 9.2.2 strip-ansi: 7.1.0 + /string.prototype.codepointat@0.2.1: + resolution: {integrity: sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==} + dev: false + /string_decoder@0.10.31: resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} dev: false @@ -5901,6 +6243,10 @@ packages: globrex: 0.1.2 dev: true + /tiny-inflate@1.0.3: + resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} + dev: false + /tmp-promise@3.0.3: resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==} dependencies: @@ -6043,6 +6389,13 @@ packages: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} dev: false + /unicode-trie@2.0.0: + resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} + dependencies: + pako: 0.2.9 + tiny-inflate: 1.0.3 + dev: false + /universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} @@ -6126,6 +6479,10 @@ packages: - zod dev: false + /vite-plugin-arraybuffer@0.0.2: + resolution: {integrity: sha512-ibjyFobimOplfrKZFG7ecdLSp0L0eo6YOat9Nm5AQ95edq5bMt/hN0dx4oJifczdyQECSqg7R+j5IM2hsC9lvQ==} + dev: true + /vite@5.0.12: resolution: {integrity: sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==} engines: {node: ^18.0.0 || >=20.0.0} @@ -6341,3 +6698,7 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true + + /yoga-wasm-web@0.3.3: + resolution: {integrity: sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==} + dev: false diff --git a/src/app.html b/src/app.html index 012f242..c81e4c8 100644 --- a/src/app.html +++ b/src/app.html @@ -8,10 +8,8 @@ - - %sveltekit.head% diff --git a/src/lib/client/constants.ts b/src/lib/client/constants.ts new file mode 100644 index 0000000..32036ec --- /dev/null +++ b/src/lib/client/constants.ts @@ -0,0 +1 @@ +export const MaxItems = 5 diff --git a/src/lib/client/ens.ts b/src/lib/client/ens.ts index 40dfdcf..9ae7aa9 100644 --- a/src/lib/client/ens.ts +++ b/src/lib/client/ens.ts @@ -1,4 +1,4 @@ -import type { ENSRecords } from '$lib/types/poap' +import type { ENSRecords } from '$lib/types/ens' import { Cache } from './cache' import { fetchJson } from './json' diff --git a/src/lib/client/graphql.ts b/src/lib/client/graphql.ts index 7d9ab64..9961486 100644 --- a/src/lib/client/graphql.ts +++ b/src/lib/client/graphql.ts @@ -1,4 +1,4 @@ -import { Client, cacheExchange, fetchExchange, gql, setContextClient } from '@urql/svelte' +import { Client, cacheExchange, fetchExchange, gql } from '@urql/core' import type { Fetch } from './types' export function createClient(fetch?: Fetch) { @@ -9,10 +9,6 @@ export function createClient(fetch?: Fetch) { }) } -export function initializeGraphQL() { - setContextClient(createClient()) -} - const fragments = { event: gql` fragment EventFragment on Event { @@ -77,6 +73,22 @@ export const query = { } } + ${fragments.event} + ${fragments.token} + `, + account: gql` + query AccountQuery($address: String!, $first: Int = 5) { + account(id: $address) { + id + tokens(first: $first, orderBy: created, orderDirection: desc) { + ...TokenFragment + event { + ...EventFragment + } + } + } + } + ${fragments.event} ${fragments.token} `, diff --git a/src/lib/client/poap.ts b/src/lib/client/poap.ts index a6939ec..c0c8706 100644 --- a/src/lib/client/poap.ts +++ b/src/lib/client/poap.ts @@ -1,9 +1,14 @@ -import { getContextClient, queryStore } from '@urql/svelte' -import type { POAPEventMetadata, POAPEventWithTokens, POAPTokenWithEvent } from '$lib/types/poap' +import { getContextClient } from '@urql/svelte' +import type { + POAPAccountWithTokens, + POAPEventMetadata, + POAPEventWithTokens, + POAPTokenWithEvent, +} from '$lib/types/poap' import { Cache } from './cache' import { query } from './graphql' import { fetchJson } from './json' -import { withPolling } from './urql' +import { withInitialData, withPolling } from './urql' const apiBasePath = '/api/poap' const metadataCache = new Cache() @@ -16,40 +21,55 @@ export async function fetchPOAPMetadata(eventId: string) { ) } -interface FetchPOAPEventsVariables { +export interface FetchPOAPEventsVariables { ids: number[] + first?: number } -interface FetchPOAPEventsData { +export interface FetchPOAPEventsData { events: POAPEventWithTokens[] } -export function queryPOAPEvents(ids: FetchPOAPEventsVariables['ids']) { - return withPolling({ - client: getContextClient(), - query: query.events, - variables: { - ids, +export function queryPOAPEvents( + ids: FetchPOAPEventsVariables['ids'], + first: FetchPOAPEventsVariables['first'], + initialData?: FetchPOAPEventsData, +) { + return withPolling( + { + client: getContextClient(), + query: query.events, + variables: { + ids, + first, + }, }, - }) + initialData, + ) } -interface FetchPOAPTokensVariables { +export interface FetchPOAPTokensVariables { first?: number } -interface FetchPOAPTokensData { +export interface FetchPOAPTokensData { tokens: POAPTokenWithEvent[] } -export function queryPOAPTokens(first: FetchPOAPTokensVariables['first']) { - return withPolling({ - client: getContextClient(), - query: query.tokens, - variables: { - first, +export function queryPOAPTokens( + first: FetchPOAPTokensVariables['first'], + initialData?: FetchPOAPTokensData, +) { + return withPolling( + { + client: getContextClient(), + query: query.tokens, + variables: { + first, + }, }, - }) + initialData, + ) } export interface FetchPOAPTokenVariables { @@ -57,15 +77,48 @@ export interface FetchPOAPTokenVariables { } export interface FetchPOAPTokenData { - token: POAPTokenWithEvent + token?: POAPTokenWithEvent | null } -export function queryPOAPToken(id: FetchPOAPTokenVariables['id']) { - return queryStore({ - client: getContextClient(), - query: query.token, - variables: { - id, +export function queryPOAPToken( + id: FetchPOAPTokenVariables['id'], + initialData?: FetchPOAPTokensData, +) { + return withInitialData( + { + client: getContextClient(), + query: query.token, + variables: { + id, + }, }, - }) + initialData, + ) +} + +export interface FetchPOAPAccountVariables { + address: string + first?: number +} + +export interface FetchPOAPAccountData { + account?: POAPAccountWithTokens | null +} + +export function queryPOAPAccount( + address: FetchPOAPAccountVariables['address'], + first: FetchPOAPAccountVariables['first'], + initialData?: FetchPOAPAccountData, +) { + return withPolling( + { + client: getContextClient(), + query: query.account, + variables: { + address: address.toLowerCase(), + first, + }, + }, + initialData, + ) } diff --git a/src/lib/client/urql.ts b/src/lib/client/urql.ts index 75d0fb3..38ead4d 100644 --- a/src/lib/client/urql.ts +++ b/src/lib/client/urql.ts @@ -6,10 +6,30 @@ import { } from '@urql/svelte' import { derived, readable, writable } from 'svelte/store' +export function withInitialData( + queryArgs: QueryArgs, + initialData?: Data, +) { + if (!initialData) return queryStore(queryArgs) + + const fetched = writable(false) + return derived([fetched, queryStore(queryArgs)], ([hasFetched, query]) => { + if (query.data) { + fetched.set(true) + } + + return { + ...query, + data: hasFetched ? query.data : query.data || initialData, + } + }) +} + export function withPolling( queryArgs: QueryArgs, + initialData?: Data, ) { - const initial = queryStore(queryArgs) + const initial = withInitialData(queryArgs, initialData) const result = writable>() const query = derived([initial, result], ([initial, next]) => { return next || initial diff --git a/src/lib/components/AppFrame/app-frame.svelte b/src/lib/components/AppFrame/app-frame.svelte index eb20d7c..ce8b6e1 100644 --- a/src/lib/components/AppFrame/app-frame.svelte +++ b/src/lib/components/AppFrame/app-frame.svelte @@ -1,8 +1,10 @@ - +
diff --git a/src/lib/components/EventTokens/event-tokens.svelte b/src/lib/components/EventTokens/event-tokens.svelte index 2b30515..38d95ff 100644 --- a/src/lib/components/EventTokens/event-tokens.svelte +++ b/src/lib/components/EventTokens/event-tokens.svelte @@ -1,11 +1,12 @@
- {#each tokens as token} - {#key token.id} - - {/key} + {#each tokens as token (token.id)} + {/each}
diff --git a/src/lib/components/Loadable/index.ts b/src/lib/components/Loadable/index.ts new file mode 100644 index 0000000..fca7290 --- /dev/null +++ b/src/lib/components/Loadable/index.ts @@ -0,0 +1,2 @@ +export { default as Loadable } from './loadable.svelte' +export { default as LoadableQuery } from './loadable-query.svelte' diff --git a/src/lib/components/Loadable/loadable-query.svelte b/src/lib/components/Loadable/loadable-query.svelte new file mode 100644 index 0000000..8ff54cb --- /dev/null +++ b/src/lib/components/Loadable/loadable-query.svelte @@ -0,0 +1,13 @@ + + + + + diff --git a/src/lib/components/Loadable/loadable.svelte b/src/lib/components/Loadable/loadable.svelte new file mode 100644 index 0000000..c3e046a --- /dev/null +++ b/src/lib/components/Loadable/loadable.svelte @@ -0,0 +1,22 @@ + + +
+ {#if error} + + {:else if data} + + {:else} +
+ +
+ {/if} +
diff --git a/src/lib/components/Seo/index.ts b/src/lib/components/Seo/index.ts index 8f482df..72f7232 100644 --- a/src/lib/components/Seo/index.ts +++ b/src/lib/components/Seo/index.ts @@ -1 +1,2 @@ export { default as Seo } from './seo.svelte' +export * from './types' diff --git a/src/lib/components/Seo/seo.svelte b/src/lib/components/Seo/seo.svelte index 0425005..0233314 100644 --- a/src/lib/components/Seo/seo.svelte +++ b/src/lib/components/Seo/seo.svelte @@ -1,18 +1,24 @@ + +
+ {#each tokens as token (token.id)} + + {/each} +
diff --git a/src/lib/server/ens.ts b/src/lib/server/ens.ts index a64eb25..bbf0797 100644 --- a/src/lib/server/ens.ts +++ b/src/lib/server/ens.ts @@ -1,6 +1,6 @@ import { createPublicClient, http, isAddress } from 'viem' import { mainnet } from 'viem/chains' -import { getEnsAvatar, getEnsName, normalize, getEnsText } from 'viem/ens' +import { getEnsAvatar, getEnsName, normalize, getEnsText, getEnsAddress } from 'viem/ens' import type { ENSRecords } from '$lib/types/ens' const client = createPublicClient({ @@ -37,3 +37,9 @@ export async function fetchENS(address: string): Promise { return `https://metadata.ens.domains/mainnet/avatar/${name}` } } + +export function fetchReverseENS(address: string) { + if (isAddress(address)) return Promise.resolve(address) + + return getEnsAddress(client, { name: normalize(address) }) +} diff --git a/src/lib/server/poap.ts b/src/lib/server/poap.ts index e90d72d..b6d3a32 100644 --- a/src/lib/server/poap.ts +++ b/src/lib/server/poap.ts @@ -1,8 +1,18 @@ import { createClient, query } from '$lib/client/graphql' import { fetchJson } from '$lib/client/json' -import type { FetchPOAPTokenData } from '$lib/client/poap' +import type { + FetchPOAPAccountData, + FetchPOAPAccountVariables, + FetchPOAPEventsData, + FetchPOAPEventsVariables, + FetchPOAPTokenData, + FetchPOAPTokenVariables, + FetchPOAPTokensData, + FetchPOAPTokensVariables, +} from '$lib/client/poap' import type { Fetch } from '$lib/client/types' import type { POAPEventMetadata } from '$lib/types/poap' +import { gql } from '@urql/svelte' import { POAP_API_KEY } from './env' // see https://documentation.poap.tech/ for api key @@ -18,6 +28,74 @@ export function fetchPOAPMetadata(eventId: number, fetch: Fetch) { }) } -export function fetchPOAPToken(id: number, fetch: Fetch) { - return createClient(fetch).query(query.token, { id }).toPromise() +export function fetchPOAPEvents( + ids: FetchPOAPEventsVariables['ids'], + first: FetchPOAPEventsVariables['first'], + fetch: Fetch, +) { + return createClient(fetch) + .query(query.events, { ids, first }) + .toPromise() +} + +export function fetchPOAPTokens(first: FetchPOAPTokensVariables['first'], fetch: Fetch) { + return createClient(fetch) + .query(query.tokens, { first }) + .toPromise() +} + +export function fetchPOAPToken(id: FetchPOAPTokenVariables['id'], fetch: Fetch) { + return createClient(fetch) + .query(query.token, { id }) + .toPromise() +} + +export function fetchPOAPAccount( + address: FetchPOAPAccountVariables['address'], + first: FetchPOAPAccountVariables['first'], + fetch: Fetch, +) { + return createClient(fetch) + .query< + FetchPOAPAccountData, + FetchPOAPAccountVariables + >(query.account, { address: address.toLowerCase(), first }) + .toPromise() +} + +export function fetchLatestEventPOAPTokens(eventIds: number[], fetch: Fetch) { + return createClient(fetch) + .query<{ events: { id: string; tokens: { id: string; created: string }[] }[] }>( + gql` + query LatestEventToken($eventIds: [ID!]!) { + events(where: { id_in: $eventIds }, orderBy: created, orderDirection: desc) { + id + tokens(first: 1, orderBy: created, orderDirection: desc) { + id + created + } + } + } + `, + { eventIds }, + ) + .toPromise() +} + +export function fetchLatestAccountPOAPToken(address: string, fetch: Fetch) { + return createClient(fetch) + .query<{ account: { id: string; tokens: { id: string }[] } | null | undefined }>( + gql` + query LatestEventToken($address: String!) { + account(id: $address) { + id + tokens(first: 1, orderBy: created, orderDirection: desc) { + id + } + } + } + `, + { address: address.toLowerCase() }, + ) + .toPromise() } diff --git a/src/lib/types/ambient.d.ts b/src/lib/types/ambient.d.ts index 0c72a0d..96b0b14 100644 --- a/src/lib/types/ambient.d.ts +++ b/src/lib/types/ambient.d.ts @@ -1,5 +1,5 @@ declare module '@download/blockies' { - import type { Canvas } from 'canvas' + import type { Canvas } from '@napi-rs/canvas' interface Options { seed?: string color?: string @@ -11,3 +11,13 @@ declare module '@download/blockies' { export function createIcon(opts: Options): HTMLCanvasElement export function renderIcon(opts: Options, canvas: HTMLCanvasElement | Canvas): HTMLCanvasElement } + +declare module '*.woff?arraybuffer' { + const content: ArrayBuffer + export default content +} + +declare module '*.png?arraybuffer' { + const content: ArrayBuffer + export default content +} diff --git a/src/lib/types/poap.ts b/src/lib/types/poap.ts index be8c0ba..43dea74 100644 --- a/src/lib/types/poap.ts +++ b/src/lib/types/poap.ts @@ -30,6 +30,11 @@ export interface POAPEventWithTokens extends POAPEvent { tokens: POAPToken[] } +export interface POAPAccountWithTokens { + id: string + tokens: POAPTokenWithEvent[] +} + export interface POAPEventMetadata { id: number fancy_id: string diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 48f9de3..88132e6 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,8 +1,9 @@
diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts new file mode 100644 index 0000000..0eac2e7 --- /dev/null +++ b/src/routes/+page.server.ts @@ -0,0 +1,11 @@ +import { MaxItems } from '$lib/client/constants' +import { fetchPOAPTokens } from '$lib/server/poap' +import type { PageServerLoad } from './$types' + +export const load: PageServerLoad = async ({ fetch, url }) => { + const max = Number(url.searchParams.get('max')) || MaxItems + + const query = await fetchPOAPTokens(max, fetch) + + return { max, initialData: query.data } +} diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index ceab769..a0ed9d9 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,35 +1,17 @@ - -
- {#if $query.error} - - {:else if tokens} -
- {#each tokens as token (token.id)} - - {/each} -
- {:else} -
- -
- {/if} -
+ + + + diff --git a/src/routes/account/[address]/+page.server.ts b/src/routes/account/[address]/+page.server.ts new file mode 100644 index 0000000..0ebb099 --- /dev/null +++ b/src/routes/account/[address]/+page.server.ts @@ -0,0 +1,16 @@ +import { error } from '@sveltejs/kit' +import { MaxItems } from '$lib/client/constants' +import { fetchReverseENS } from '$lib/server/ens' +import { fetchPOAPAccount } from '$lib/server/poap' +import type { PageServerLoad } from './$types' + +export const load: PageServerLoad = async ({ fetch, params, url }) => { + const address = await fetchReverseENS(params.address) + if (!address) throw error(422, `Invalid address: ${params.address}`) + + const max = Number(url.searchParams.get('max')) || MaxItems + + const query = await fetchPOAPAccount(address, max, fetch) + + return { account: params.address, address, max, initialData: query.data } +} diff --git a/src/routes/account/[address]/+page.svelte b/src/routes/account/[address]/+page.svelte new file mode 100644 index 0000000..471c929 --- /dev/null +++ b/src/routes/account/[address]/+page.svelte @@ -0,0 +1,26 @@ + + + + + {#if account} + + {:else} + + {/if} + + diff --git a/src/routes/api/ens/[address]/+server.ts b/src/routes/api/ens/[address]/+server.ts index 1e56ffd..3f98831 100644 --- a/src/routes/api/ens/[address]/+server.ts +++ b/src/routes/api/ens/[address]/+server.ts @@ -1,5 +1,6 @@ -import { error, json, type RequestHandler } from '@sveltejs/kit' +import { error, json } from '@sveltejs/kit' import { fetchENS } from '$lib/server/ens' +import type { RequestHandler } from './$types' export const POST: RequestHandler = async ({ params }) => { try { diff --git a/src/routes/api/poap/[id]/+server.ts b/src/routes/api/poap/[id]/+server.ts index df16e3d..5a92d09 100644 --- a/src/routes/api/poap/[id]/+server.ts +++ b/src/routes/api/poap/[id]/+server.ts @@ -1,5 +1,6 @@ -import { error, json, type RequestHandler } from '@sveltejs/kit' +import { error, json } from '@sveltejs/kit' import { fetchPOAPMetadata } from '$lib/server/poap' +import type { RequestHandler } from './$types' export const POST: RequestHandler = async ({ params, fetch }) => { try { diff --git a/src/routes/event/[id]/+page.server.ts b/src/routes/event/[id]/+page.server.ts index bf5d801..d5e3be0 100644 --- a/src/routes/event/[id]/+page.server.ts +++ b/src/routes/event/[id]/+page.server.ts @@ -1,5 +1,6 @@ import { error } from '@sveltejs/kit' -import { fetchPOAPMetadata } from '$lib/server/poap' +import { MaxItems } from '$lib/client/constants' +import { fetchPOAPEvents, fetchPOAPMetadata } from '$lib/server/poap' import type { PageServerLoad } from './$types' export const load: PageServerLoad = async ({ fetch, params, url }) => { @@ -12,12 +13,14 @@ export const load: PageServerLoad = async ({ fetch, params, url }) => { throw error(422, 'Invalid POAP event IDs') } - const max = Number(url.searchParams.get('max')) || 25 + const max = Number(url.searchParams.get('max')) || MaxItems - const metadata = await Promise.all(ids.map((id) => fetchPOAPMetadata(id, fetch))).then( - (metadata) => + const [metadata, query] = await Promise.all([ + Promise.all(ids.map((id) => fetchPOAPMetadata(id, fetch))).then((metadata) => Object.fromEntries(metadata.filter(Boolean).map((metadata) => [metadata.id, metadata])), - ) + ), + fetchPOAPEvents(ids, max, fetch), + ]) - return { ids, max, metadata } + return { ids, max, metadata, initialData: query.data } } diff --git a/src/routes/event/[id]/+page.svelte b/src/routes/event/[id]/+page.svelte index a1683bb..c1e756b 100644 --- a/src/routes/event/[id]/+page.svelte +++ b/src/routes/event/[id]/+page.svelte @@ -1,28 +1,17 @@ - -
- {#if $query.error} - - {:else if events} - - {:else} -
- -
- {/if} -
+ + + + diff --git a/src/routes/og/account/[address]/+server.ts b/src/routes/og/account/[address]/+server.ts new file mode 100644 index 0000000..224e65b --- /dev/null +++ b/src/routes/og/account/[address]/+server.ts @@ -0,0 +1,32 @@ +import { error } from '@sveltejs/kit' +import { fetchReverseENS } from '$lib/server/ens' +import { fetchLatestAccountPOAPToken } from '$lib/server/poap' +import { tokenResponse } from '../../token/[id]/tokenResponse' +import type { RequestHandler } from './$types' + +export const GET: RequestHandler = async ({ params, fetch }) => { + const address = await fetchReverseENS(params.address) + if (!address) throw error(422, `Invalid address: ${params.address}`) + + const { data, error: accountError } = await fetchLatestAccountPOAPToken(address, fetch) + + if (accountError) { + console.error('Failed to fetch POAP account', address, accountError) + throw error(422, 'Failed to fetch POAP account') + } + + if (!data) { + console.error('Failed to fetch POAP account data', address) + throw error(422, 'Failed to fetch POAP account data') + } + + if (!data.account) { + console.error('POAP account not found', address, params.address) + throw error(404, 'POAP account not found') + } + + const tokenId = data.account.tokens[0]?.id + if (!tokenId) throw error(404, 'POAP token not found for account') + + return tokenResponse(tokenId, fetch) +} diff --git a/src/routes/og/event/[id]/+server.ts b/src/routes/og/event/[id]/+server.ts new file mode 100644 index 0000000..aa4b6c7 --- /dev/null +++ b/src/routes/og/event/[id]/+server.ts @@ -0,0 +1,23 @@ +import { error } from '@sveltejs/kit' +import { fetchLatestEventPOAPTokens } from '$lib/server/poap' +import { tokenResponse } from '../../token/[id]/tokenResponse' +import type { RequestHandler } from './$types' + +export const GET: RequestHandler = async ({ params, fetch }) => { + const ids = params.id + .split(',') + .map((id) => Number(id.trim())) + .filter((id) => Number.isInteger(id)) + if (ids.length === 0) { + console.error('Invalid POAP event IDs', params.id) + throw error(422, 'Invalid POAP event IDs') + } + + const query = await fetchLatestEventPOAPTokens(ids, fetch) + const tokenId = query.data?.events + .flatMap(({ tokens }) => tokens) + .sort((a, b) => Number(b.created) - Number(a.created))[0]?.id + if (!tokenId) throw error(404, 'POAP token not found for events') + + return tokenResponse(tokenId, fetch) +} diff --git a/src/routes/og/token/[id]/+server.ts b/src/routes/og/token/[id]/+server.ts new file mode 100644 index 0000000..166b3a4 --- /dev/null +++ b/src/routes/og/token/[id]/+server.ts @@ -0,0 +1,6 @@ +import { tokenResponse } from './tokenResponse' +import type { RequestHandler } from './$types' + +export const GET: RequestHandler = ({ params: { id }, fetch }) => { + return tokenResponse(id, fetch) +} diff --git a/src/routes/og/token/[id]/debug/+page.server.ts b/src/routes/og/token/[id]/debug/+page.server.ts new file mode 100644 index 0000000..583bcdd --- /dev/null +++ b/src/routes/og/token/[id]/debug/+page.server.ts @@ -0,0 +1,37 @@ +import { renderIcon } from '@download/blockies' +import { createCanvas } from '@napi-rs/canvas' +import { error } from '@sveltejs/kit' +import { loadTokenData } from '../../../../token/[id]/data' +import backgroundImage from '../og-background.png?arraybuffer' +import type { PageServerLoad } from './$types' + +export const load: PageServerLoad = async ({ fetch, params }) => { + const data = await loadTokenData(params.id, fetch) + + if (!data.token) { + throw error(404, 'Token not found') + } + + const { token, metadata, ens } = data + + const avatar = + ens.avatar || + renderIcon( + { + seed: token.owner.id, + size: 20, + scale: 10, + }, + createCanvas(200, 200), + ).toDataURL() + + const background = `data:image/png;base64,${Buffer.from(backgroundImage).toString('base64')}` + + return { + token, + metadata, + ens, + avatar, + background, + } +} diff --git a/src/routes/og/token/[id]/debug/+page.svelte b/src/routes/og/token/[id]/debug/+page.svelte new file mode 100644 index 0000000..e2ad77f --- /dev/null +++ b/src/routes/og/token/[id]/debug/+page.svelte @@ -0,0 +1,12 @@ + + +
+
+ +
+
diff --git a/src/routes/og/token/[id]/og-background.png b/src/routes/og/token/[id]/og-background.png new file mode 100644 index 0000000000000000000000000000000000000000..3c09f21d83a2545d2fdb3481fcdb57053555b412 GIT binary patch literal 137885 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 z){ⅅ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 + /* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call */ + import { formatDistanceToNow } from 'date-fns' + + /** + * @type {import('$lib/types/poap').POAPToken} + */ + export let token + /** + * @type {import('$lib/types/poap').POAPEventMetadata} + */ + export let metadata + /** + * @type {import('$lib/types/ens').ENSRecords} + */ + export let ens + /** + * @type {string} + */ + export let avatar + /** + * @type {string} + */ + export let background + + +
+
+ background +
+
+
+
+ {ens.name || `${token.owner.id.slice(0, 6)}…${token.owner.id.slice(-4)}`} avatar +
+
+
+
+

+ {metadata.name} +

+
+
+

{metadata.description}

+
+
+

+ Token + + #{token.id} + +

+

+ Mint + + #{token.mintOrder} + +

+

+ Event + + #{token.event.id} + +

+
+
+
+

+ {token.owner.id} +

+ + {token.owner.tokensOwned} + +
+

+ {formatDistanceToNow(Number(token.created) * 1000, { + includeSeconds: true, + addSuffix: true, + })} +

+
+
+
+
+ {metadata.name} POAP image +
+
+
+
diff --git a/src/routes/og/token/[id]/svelte-to-png/index.ts b/src/routes/og/token/[id]/svelte-to-png/index.ts new file mode 100644 index 0000000..b797176 --- /dev/null +++ b/src/routes/og/token/[id]/svelte-to-png/index.ts @@ -0,0 +1,34 @@ +import { Resvg } from '@resvg/resvg-js' +import satori, { type SatoriOptions } from 'satori' +import type { ComponentType, SvelteComponent } from 'svelte' +import { svelteComponentToJsx } from './svelteToJsx' + +// this is all a cleaned up version of https://github.com/etherCorps/svelte-og and https://github.com/etherCorps/svelte-h2j + +export async function svelteToPngResponse( + component: ComponentType, + props: Record, + options: SatoriOptions, +) { + const reactElement = svelteComponentToJsx(component, props) + const svg = await satori(reactElement, options) + const resvg = new Resvg(svg, { + fitTo: { + mode: 'width', + value: 'width' in options ? options.width : 1200, + }, + font: { + // It will be faster to disable loading system fonts. + loadSystemFonts: false, + }, + }) + const pngData = resvg.render() + const pngBuffer = pngData.asPng() + return new Response(pngBuffer, { + headers: { + 'Content-Type': 'image/png', + 'Cache-Control': 'public, immutable, no-transform, max-age=31536000', + }, + status: 200, + }) +} diff --git a/src/routes/og/token/[id]/svelte-to-png/inlineCSS.ts b/src/routes/og/token/[id]/svelte-to-png/inlineCSS.ts new file mode 100644 index 0000000..3ffcb0e --- /dev/null +++ b/src/routes/og/token/[id]/svelte-to-png/inlineCSS.ts @@ -0,0 +1,80 @@ +import type { Style } from 'svelte/types/compiler/interfaces' + +// 3. Make it better if possible +export function extractStyles(cssAst: Style) { + const styles: Record = {} + if (Object.hasOwn(cssAst, 'children') && cssAst.children.length) { + for (const { prelude, block } of cssAst.children) { + if (hasChildren(prelude)) { + for (const selector of prelude.children) { + if (!hasClassnames(selector)) continue + + const classNames = selector.children + .filter((node) => node.type === 'ClassSelector') + .map((node) => node.name) + for (const className of classNames) { + if (!hasDeclarations(block)) continue + + styles[className] = block.children + .map((declaration) => { + return `${declaration.property}: ${declaration.value.children + .map((identifier) => { + return identifier.name + }) + .join(' ')}` + }) + .join('; ') + } + } + } + } + } + return styles + + function hasChildren(node: unknown): node is { children: unknown[] } { + return Boolean( + node && + typeof node === 'object' && + 'children' in node && + Array.isArray(node.children) && + node.children.length > 0, + ) + } + + function hasClassnames(node: unknown): node is { children: { type: string; name: string }[] } { + if (!hasChildren(node)) return false + + const [first] = node.children + + return Boolean( + first && + typeof first === 'object' && + 'type' in first && + typeof first.type === 'string' && + 'name' in first && + typeof first.name === 'string', + ) + } + + function hasDeclarations( + node: unknown, + ): node is { children: { property: string; value: { children: { name: string }[] } }[] } { + if (!hasChildren(node)) return false + + const [first] = node.children + + return Boolean( + first && + typeof first === 'object' && + 'property' in first && + typeof first.property === 'string' && + 'value' in first && + typeof first.value === 'object' && + hasChildren(first.value) && + first.value.children[0] && + typeof first.value.children[0] === 'object' && + 'name' in first.value.children[0] && + typeof first.value.children[0].name === 'string', + ) + } +} diff --git a/src/routes/og/token/[id]/svelte-to-png/svelteToJsx.ts b/src/routes/og/token/[id]/svelte-to-png/svelteToJsx.ts new file mode 100644 index 0000000..333c307 --- /dev/null +++ b/src/routes/og/token/[id]/svelte-to-png/svelteToJsx.ts @@ -0,0 +1,31 @@ +import type { ComponentType, SvelteComponent } from 'svelte' +import { toReactElement } from './toReactElement.js' + +type SvelteSSRComponent = ComponentType & { + render: (props: Record) => { + html: string + css: { code: string } + } +} + +export function svelteComponentToJsx( + component: ComponentType, + props: Record, +) { + if (!isSvelteSSRComponent(component)) throw new Error('Component is not a Svelte SSR component') + + const SvelteRenderedMarkup = component.render(props) + let htmlTemplate = SvelteRenderedMarkup.html || '' + + if (SvelteRenderedMarkup.css.code) { + htmlTemplate = `${htmlTemplate}` + } + + return toReactElement(htmlTemplate) + + function isSvelteSSRComponent( + component: ComponentType, + ): component is SvelteSSRComponent { + return Boolean('render' in component && typeof component.render === 'function') + } +} diff --git a/src/routes/og/token/[id]/svelte-to-png/toReactElement.ts b/src/routes/og/token/[id]/svelte-to-png/toReactElement.ts new file mode 100644 index 0000000..5aafb4a --- /dev/null +++ b/src/routes/og/token/[id]/svelte-to-png/toReactElement.ts @@ -0,0 +1,139 @@ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +/* eslint-disable @typescript-eslint/no-unsafe-call */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +import { walk, parse } from 'svelte/compiler' +import type { Ast } from 'svelte/types/compiler/interfaces' +import { extractStyles } from './inlineCSS.js' +/* Start of code from satori-html for cssToObject converter*/ +const camelize = (ident: string) => + ident.replace(/-([a-z])/g, (_, char) => String(char).toUpperCase()) +const cssToObject = (str: string) => { + const obj: Record = {} + let t = 0 + let pair = ['', ''] + const flags: Record = { '(': 0, ')': 0 } + for (const c of str) { + if (!flags['('] && c === ':') { + t = 1 + } else if (c === ';') { + const [decl = '', value = ''] = pair + obj[camelize(decl.trim())] = value.trim() + t = 0 + pair = ['', ''] + } else { + pair[t] += c + switch (c) { + case '(': { + flags[c]++ + break + } + case ')': { + flags['(']-- + break + } + } + } + } + const [decl = '', value = ''] = pair + if (decl.trim() && value.trim()) { + obj[camelize(decl.trim())] = value.trim() + } + + return obj +} + +interface VNode { + type: string + props: { + style?: Record + children?: string | VNode | VNode[] + [prop: string]: unknown + } +} +/* End of satori-html */ + +export function toReactElement(htmlString: string): VNode { + const nodeMap = new WeakMap() + const root: VNode = { + type: 'div', + props: { + style: { + display: 'flex', + flexDirection: 'column', + width: '100%', + height: '100%', + }, + children: [], + }, + } + const svelteAST: Ast = parse(htmlString) + let styles: Record = {} + if (svelteAST && svelteAST.css) { + styles = extractStyles(svelteAST.css) + } + + walk(svelteAST as any, { + enter(node: any, parent: any, prop, index) { + let newNode: any = {} + if (node.type === 'Fragment') { + nodeMap.set(node, root) + } else if (node.type === 'Element') { + newNode.type = node.name + let { ...props } = node.attributes + if (node.attributes.length > 0) { + let classStyles: string | null = null + let styleExists = false + node.attributes.forEach((attribute: any) => { + if (Object.keys(styles).length && attribute.name === 'class') { + classStyles = styles[attribute.value[0].data] + } + if (attribute.name === 'style') { + styleExists = true + const newRawStyle = classStyles + ? attribute.value[0].data + '; ' + classStyles + : attribute.value[0].data + props['style'] = cssToObject(newRawStyle) as any + } else { + props[attribute.name] = attribute.value[0].data + } + }) + if (Object.keys(styles).length && !styleExists && classStyles) { + props['style'] = cssToObject(classStyles) + } + delete props[0] + } + // numbered props failing on svgs + props = Object.entries(props).reduce((newProps: any, [key, value]) => { + if (Number.isNaN(Number(key))) { + newProps[key] = value as any + } + return newProps + }, {}) + props.children = [] as unknown as string + Object.assign(newNode, { props }) + nodeMap.set(node, newNode) + if (parent && index != null) { + const newParent = nodeMap.get(parent) + newParent.props.children[index] = newNode + } + } else if (node.type === 'Text') { + newNode = node.data.trim() + if (newNode) { + if (parent && parent.type !== 'Attribute') { + const newParent = nodeMap.get(parent) + if (parent.children.length === 1) { + newParent.props.children = newNode + } else if (index != null) { + newParent.props.children[index] = newNode + } + } + } + } + }, + }) + + return root +} diff --git a/src/routes/og/token/[id]/tokenResponse.ts b/src/routes/og/token/[id]/tokenResponse.ts new file mode 100644 index 0000000..88b0772 --- /dev/null +++ b/src/routes/og/token/[id]/tokenResponse.ts @@ -0,0 +1,60 @@ +import { renderIcon } from '@download/blockies' +import inter400 from '@fontsource/inter/files/inter-latin-400-normal.woff?arraybuffer' +import inter600 from '@fontsource/inter/files/inter-latin-600-normal.woff?arraybuffer' +import robotoMono400 from '@fontsource/roboto-mono/files/roboto-mono-latin-400-normal.woff?arraybuffer' +import { error } from '@sveltejs/kit' +import { createCanvas } from '@napi-rs/canvas' +import type { Fetch } from '$lib/client/types' +import { loadTokenData } from '../../../token/[id]/data' +import backgroundImage from './og-background.png?arraybuffer' +import OgToken from './og-token.svelte' +import { svelteToPngResponse } from './svelte-to-png' + +export async function tokenResponse(id: string, fetch: Fetch) { + try { + const props = await loadTokenData(id, fetch) + if (!props.token) throw error(404, 'Token not found') + + const avatar = + props.ens.avatar || + renderIcon( + { + seed: props.token.owner.id, + size: 20, + scale: 10, + }, + createCanvas(200, 200), + ).toDataURL() + + const background = `data:image/png;base64,${Buffer.from(backgroundImage).toString('base64')}` + + return await svelteToPngResponse( + OgToken, + { ...props, avatar, background }, + { + width: 1200, + height: 630, + fonts: [ + { + name: 'sans-serif', + data: inter400, + weight: 400, + }, + { + name: 'sans-serif', + data: inter600, + weight: 600, + }, + { + name: 'monospace', + data: robotoMono400, + weight: 400, + }, + ], + }, + ) + } catch (err) { + console.error('error building opengraph image', err) + throw error(500, err instanceof Error ? err.message : 'Opengraph image error') + } +} diff --git a/src/routes/token/[id]/+page.server.ts b/src/routes/token/[id]/+page.server.ts index d3c3707..d2d642f 100644 --- a/src/routes/token/[id]/+page.server.ts +++ b/src/routes/token/[id]/+page.server.ts @@ -1,35 +1,6 @@ -import { error } from '@sveltejs/kit' -import { fetchPOAPMetadata, fetchPOAPToken } from '$lib/server/poap' import type { PageServerLoad } from './$types' -import { fetchENS } from '$lib/server/ens' +import { loadTokenData } from './data' -export const load: PageServerLoad = async ({ fetch, params }) => { - const id = Number(params.id.trim()) - if (!Number.isInteger(id)) { - console.error('Invalid POAP event ID', id) - throw error(422, 'Invalid POAP event ID') - } - - const { data, error: tokenError } = await fetchPOAPToken(id, fetch) - if (tokenError) { - console.error('Failed to fetch POAP token', id, tokenError) - throw error(422, 'Failed to fetch POAP token') - } - - if (!data) { - console.error('Failed to fetch POAP token data', id) - throw error(422, 'Failed to fetch POAP token data') - } - - if (!data.token) { - console.error('POAP token not found', id) - return { id } - } - - const { token } = data - const metadata = await fetchPOAPMetadata(Number(token.event.id), fetch) - - const ens = await fetchENS(token.owner.id) - - return { id, token, metadata, ens } +export const load: PageServerLoad = ({ fetch, params }) => { + return loadTokenData(params.id, fetch) } diff --git a/src/routes/token/[id]/+page.svelte b/src/routes/token/[id]/+page.svelte index a24b205..e6c592d 100644 --- a/src/routes/token/[id]/+page.svelte +++ b/src/routes/token/[id]/+page.svelte @@ -7,11 +7,13 @@ export let data: PageData - +
- {#if !data.token} - - {:else} + {#if data.token}
+ {:else} + {/if}
diff --git a/src/routes/token/[id]/data.ts b/src/routes/token/[id]/data.ts new file mode 100644 index 0000000..86783d9 --- /dev/null +++ b/src/routes/token/[id]/data.ts @@ -0,0 +1,35 @@ +import { error } from '@sveltejs/kit' +import type { Fetch } from '$lib/client/types' +import { fetchENS } from '$lib/server/ens' +import { fetchPOAPMetadata, fetchPOAPToken } from '$lib/server/poap' + +export async function loadTokenData(token_id: string, fetch: Fetch) { + const id = Number(token_id.trim()) + if (!Number.isInteger(id)) { + console.error('Invalid POAP event ID', id) + throw error(422, 'Invalid POAP event ID') + } + + const { data, error: tokenError } = await fetchPOAPToken(id, fetch) + if (tokenError) { + console.error('Failed to fetch POAP token', id, tokenError) + throw error(422, 'Failed to fetch POAP token') + } + + if (!data) { + console.error('Failed to fetch POAP token data', id) + throw error(422, 'Failed to fetch POAP token data') + } + + if (!data.token) { + console.error('POAP token not found', id) + return { id } + } + + const { token } = data + const metadata = await fetchPOAPMetadata(Number(token.event.id), fetch) + + const ens = await fetchENS(token.owner.id) + + return { id, token, metadata, ens } +} diff --git a/vite.config.ts b/vite.config.ts index 5d5aad4..1beaf7e 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,9 +1,15 @@ import { sveltekit } from '@sveltejs/kit/vite' import { defineConfig } from 'vite' +import arraybuffer from 'vite-plugin-arraybuffer' export default defineConfig({ - plugins: [sveltekit()], + plugins: [sveltekit(), arraybuffer()], optimizeDeps: { exclude: ['@urql/svelte'], }, + build: { + rollupOptions: { + external: ['@napi-rs/canvas', '@resvg/resvg-js', 'satori', 'svelte/compiler'], + }, + }, })