From 31a0ef18517c8a2399001b3cffaabd11e0f8a330 Mon Sep 17 00:00:00 2001 From: luzzifoss Date: Mon, 29 Jan 2024 20:13:22 +0000 Subject: [PATCH 1/4] chore: add upload existing cids on s3 script --- README.md | 29 ++ package.json | 5 + pnpm-lock.yaml | 529 ++++++++++++++++++++++++-- scripts/upload-existing-cids-on-s3.ts | 229 +++++++++++ 4 files changed, 768 insertions(+), 24 deletions(-) create mode 100644 scripts/upload-existing-cids-on-s3.ts diff --git a/README.md b/README.md index 0bed75d..5fa2351 100644 --- a/README.md +++ b/README.md @@ -238,6 +238,35 @@ script execute: pnpm upload-folder ``` +### Uploading existing CIDs to S3 + +The script under `/scripts/upload-existing-cids-on-s3.ts` takes care of +detecting all the CIDs used across the Carrot protocol and uploading them to the +S3 limbo/persistent storage. It works with underlying data encoded in both raw +JSON and DAG PB `multicodec` formats with the option of adding more supported +codecs if needed, and it also works across chains. It requires a few env +variables in order to be ran: + +- `S3_BUCKET`: the name of the S3 bucket to which to upload the data. +- `S3_ENDPOINT (optional)`: the endpoint of the S3 bucket to which to upload the + data. +- `S3_ACCESS_KEY_ID`: an AWS access key id with the correct permission policies + attached to it to upload data to the target bucket. +- `S3_SECRET_ACCESS_KEY`: the secret key associated with the specified access + key id. + +You can put these env in the same `.env` file you use to run the server in dev +mode and you can also test the script against a local S3 deployment in the same +way (by bootstrapping MinIO through the provided Docker Compose file and putting +the right values in the `.env` file). + +To launch the script just execute the following command in your terminal from +the root of the repo: + +``` +pnpm upload-existing-cids-on-s3 +``` + ## OpenAPI The OpenAPI specification is exposed under `/swagger.json`, while the Swagger UI diff --git a/package.json b/package.json index 3090db8..f6378ce 100644 --- a/package.json +++ b/package.json @@ -13,22 +13,27 @@ "format": "eslint --fix --ext .js ./ && prettier --write './**/*.{json,md}'", "generate-jwt": "tsx scripts/generate-jwt.ts", "upload-folder": "tsx scripts/upload-folder.ts", + "upload-existing-cids-on-s3": "tsx scripts/upload-existing-cids-on-s3.ts", "build": "esbuild ./src/index.ts --platform=node --format=esm --define:process.env.NODE_ENV=\\\"production\\\" --bundle --packages=external --minify --outdir=./out --out-extension:.js=.mjs", "dev": "nodemon --exec tsx src/index.ts" }, "devDependencies": { + "@carrot-kpi/sdk": "^1.49.0", "@commitlint/cli": "^18.4.4", "@commitlint/config-conventional": "^18.4.4", "@smithy/types": "^2.9.1", "@types/jsonwebtoken": "^9.0.5", "@types/pg": "^8.10.9", + "blockstore-core": "^4.3.10", "dotenv": "^16.3.1", "esbuild": "^0.19.11", "eslint": "^8.56.0", "eslint-config-custom": "*", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", + "graphql-request": "^6.1.0", "husky": "^8.0.3", + "ipfs-unixfs-exporter": "^13.4.0", "nodemon": "^3.0.3", "pino": "^8.17.2", "prettier": "^3.2.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 08439a0..0c6b19b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -61,6 +61,9 @@ dependencies: version: 2.2.0(typescript@5.3.3) devDependencies: + '@carrot-kpi/sdk': + specifier: ^1.49.0 + version: 1.49.0(@carrot-kpi/shared-state@0.16.0)(typescript@5.3.3) '@commitlint/cli': specifier: ^18.4.4 version: 18.4.4(@types/node@20.11.5)(typescript@5.3.3) @@ -76,6 +79,9 @@ devDependencies: '@types/pg': specifier: ^8.10.9 version: 8.10.9 + blockstore-core: + specifier: ^4.3.10 + version: 4.3.10 dotenv: specifier: ^16.3.1 version: 16.3.1 @@ -94,9 +100,15 @@ devDependencies: eslint-plugin-prettier: specifier: ^5.1.3 version: 5.1.3(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.2.4) + graphql-request: + specifier: ^6.1.0 + version: 6.1.0(graphql@16.8.1) husky: specifier: ^8.0.3 version: 8.0.3 + ipfs-unixfs-exporter: + specifier: ^13.4.0 + version: 13.4.0 nodemon: specifier: ^3.0.3 version: 3.0.3 @@ -122,7 +134,6 @@ packages: /@adraffy/ens-normalize@1.10.0: resolution: {integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==} - dev: false /@apidevtools/json-schema-ref-parser@11.1.0: resolution: {integrity: sha512-g/VW9ZQEFJAOwAyUb8JFf7MLiLy2uEB4rU270rGzDwICxnxMlPy0O11KVePSgS36K1NI29gSlK84n5INGhd4Ag==} @@ -797,6 +808,54 @@ packages: regenerator-runtime: 0.14.1 dev: true + /@carrot-kpi/contracts@0.9.0: + resolution: {integrity: sha512-pVxQiTXkTqJwm1xHnkLN/Trwbw9F509ZLfp1ovwujgJN1Kz+Nv7rVg0Y6QpMgXXC6hlvyMJIn/kIFsq+gl4m+w==} + dev: true + + /@carrot-kpi/sdk@1.49.0(@carrot-kpi/shared-state@0.16.0)(typescript@5.3.3): + resolution: {integrity: sha512-QBiDmtxEnnS5t8KYDloG2ACriYGM/7lJ/1ViG7J/YPKzx0xk4G0yvkRLQ8zBtVeHoJsdJNRF2+a8sPUniwIdOA==} + peerDependencies: + '@carrot-kpi/shared-state': '*' + dependencies: + '@carrot-kpi/contracts': 0.9.0 + '@carrot-kpi/shared-state': 0.16.0(react@18.2.0)(redux@4.2.1) + decimal.js-light: 2.5.1 + multiformats: 9.9.0 + viem: 1.21.4(typescript@5.3.3) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + dev: true + + /@carrot-kpi/shared-state@0.16.0(react@18.2.0)(redux@4.2.1): + resolution: {integrity: sha512-ZaOimlOkCVOz8DTnf/j0eAoILYNv6lRfo6WJWORKCJhMogYlTqJE16H5N7CujeE1OXfiXrzX76dRd1p3erVmTw==} + peerDependencies: + react: ^18.2.0 + dependencies: + '@reduxjs/toolkit': 1.9.7(react-redux@8.1.3)(react@18.2.0) + lodash.debounce: 4.0.8 + react: 18.2.0 + react-redux: 8.1.3(react@18.2.0)(redux@4.2.1) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + - react-dom + - react-native + - redux + dev: true + + /@chainsafe/is-ip@2.0.2: + resolution: {integrity: sha512-ndGqEMG1W5WkGagaqOZHpPU172AGdxr+LD15sv3WIUvT5oCFUrG1Y0CW/v2Egwj4JXEvSibaIIIqImsm98y1nA==} + dev: true + + /@chainsafe/netmask@2.0.0: + resolution: {integrity: sha512-I3Z+6SWUoaljh3TBzCnCxjlUyN8tA+NAk5L6m9IxvCf1BENQTePzPMis97CoN/iMW1St3WN+AWCCRp+TTBRiDg==} + dependencies: + '@chainsafe/is-ip': 2.0.2 + dev: true + /@commitlint/cli@18.4.4(@types/node@20.11.5)(typescript@5.3.3): resolution: {integrity: sha512-Ro3wIo//fV3XiV1EkdpHog6huaEyNcUAVrSmtgKqYM5g982wOWmP4FXvEDFwRMVgz878CNBvvCc33dMZ5AQJ/g==} engines: {node: '>=v18'} @@ -1205,6 +1264,14 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@graphql-typed-document-node/core@3.2.0(graphql@16.8.1): + resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + graphql: 16.8.1 + dev: true + /@hapi/accept@6.0.3: resolution: {integrity: sha512-p72f9k56EuF0n3MwlBNThyVE5PXX40g+aQh+C/xbKrfzahM2Oispv3AXmOIU51t3j77zay1qrX7IIziZXspMlw==} dependencies: @@ -1496,7 +1563,6 @@ packages: dependencies: cborg: 4.0.8 multiformats: 13.0.1 - dev: false /@ipld/dag-json@10.1.7: resolution: {integrity: sha512-ipraTPMA40sZAtUYwFvjHeQjReDJXWI8V3lrOeyedKxMb9rOOCS0B7eodRoWM3RIS2qMqtnu1oZr8kP+QJEN0Q==} @@ -1504,14 +1570,12 @@ packages: dependencies: cborg: 4.0.8 multiformats: 13.0.1 - dev: false /@ipld/dag-pb@4.0.8: resolution: {integrity: sha512-693AqMY2jvhe+w4jSwjnDrbhxIu39gm1H4f6/KD5gG+6VFMM6EXV7vq85BvEf8CRsnA0+auWfA29/S8gbWI0Ew==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} dependencies: multiformats: 13.0.1 - dev: false /@ipld/dag-ucan@3.4.0: resolution: {integrity: sha512-sW4R43w3DbEdoGWWJZCwsblwXa600HCanG9p2w1MJPVBNTNjhvqc3XI0uEqKhT2oqKWrND7uInVtcPmZme7hhA==} @@ -1537,13 +1601,51 @@ packages: resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} dev: false + /@libp2p/interface@1.1.2: + resolution: {integrity: sha512-uC4hxtEJuWiDiZfokkSNEEbCzdyZrqb5kp67Wc5PjZsySZ2IoImdIfie003yQXlB1xBp/XUJzdC6kVu4M7LUmg==} + dependencies: + '@multiformats/multiaddr': 12.1.14 + it-pushable: 3.2.3 + it-stream-types: 2.0.1 + multiformats: 13.0.1 + progress-events: 1.0.0 + uint8arraylist: 2.4.8 + transitivePeerDependencies: + - supports-color + dev: true + + /@libp2p/logger@4.0.5: + resolution: {integrity: sha512-cXETMNZINnxeQBlfQ2S4di92FDDU89R7RHagrpebGrM7oLl5nf/Mw6myc23kGaM3/2YG3ko2rl9sYjemu0azTA==} + dependencies: + '@libp2p/interface': 1.1.2 + '@multiformats/multiaddr': 12.1.14 + debug: 4.3.4(supports-color@5.5.0) + interface-datastore: 8.2.10 + multiformats: 13.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@multiformats/multiaddr@12.1.14: + resolution: {integrity: sha512-1C0Mo73chzu7pTzTquuKs5vUtw70jhqg1i6pUNznGb0WV6RFa6vyB+D697Os5+cLx+DiItrAY6VzMtlGQsMzYg==} + dependencies: + '@chainsafe/is-ip': 2.0.2 + '@chainsafe/netmask': 2.0.0 + '@libp2p/interface': 1.1.2 + dns-over-http-resolver: 3.0.2 + multiformats: 13.0.1 + uint8-varint: 2.0.3 + uint8arrays: 5.0.1 + transitivePeerDependencies: + - supports-color + dev: true + /@multiformats/murmur3@2.1.8: resolution: {integrity: sha512-6vId1C46ra3R1sbJUOFCZnsUIveR9oF20yhPmAFxPm0JfrX3/ZRCgP3YDrBzlGoEppOXnA9czHeYc0T9mB6hbA==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} dependencies: multiformats: 13.0.1 murmurhash3js-revisited: 3.0.0 - dev: false /@next/eslint-plugin-next@12.3.4: resolution: {integrity: sha512-BFwj8ykJY+zc1/jWANsDprDIu2MgwPOIKxNVnrKvPs+f5TPegrVnem8uScND+1veT4B7F6VeqgaNLFW1Hzl9Og==} @@ -1555,7 +1657,6 @@ packages: resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} dependencies: '@noble/hashes': 1.3.2 - dev: false /@noble/curves@1.3.0: resolution: {integrity: sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==} @@ -1570,12 +1671,10 @@ packages: /@noble/hashes@1.3.2: resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} engines: {node: '>= 16'} - dev: false /@noble/hashes@1.3.3: resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} engines: {node: '>= 16'} - dev: false /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -1653,13 +1752,31 @@ packages: resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} dev: false + /@reduxjs/toolkit@1.9.7(react-redux@8.1.3)(react@18.2.0): + resolution: {integrity: sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==} + peerDependencies: + react: ^16.9.0 || ^17.0.0 || ^18 + react-redux: ^7.2.1 || ^8.0.2 + peerDependenciesMeta: + react: + optional: true + react-redux: + optional: true + dependencies: + immer: 9.0.21 + react: 18.2.0 + react-redux: 8.1.3(react@18.2.0)(redux@4.2.1) + redux: 4.2.1 + redux-thunk: 2.4.2(redux@4.2.1) + reselect: 4.1.8 + dev: true + /@rushstack/eslint-patch@1.7.0: resolution: {integrity: sha512-Jh4t/593gxs0lJZ/z3NnasKlplXT2f+4y/LZYuaKZW5KAaiVFL/fThhs+17EbUd53jUVJ0QudYCBGbN/psvaqg==} dev: true /@scure/base@1.1.5: resolution: {integrity: sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==} - dev: false /@scure/bip32@1.3.2: resolution: {integrity: sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==} @@ -1667,14 +1784,12 @@ packages: '@noble/curves': 1.2.0 '@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.3 '@scure/base': 1.1.5 - dev: false /@scure/bip39@1.2.2: resolution: {integrity: sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA==} @@ -2151,6 +2266,13 @@ packages: tslib: 2.6.2 dev: false + /@types/hoist-non-react-statics@3.3.5: + resolution: {integrity: sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==} + dependencies: + '@types/react': 18.2.48 + hoist-non-react-statics: 3.3.2 + dev: true + /@types/json-schema@7.0.15: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: false @@ -2200,10 +2322,30 @@ packages: pg-types: 4.0.1 dev: true + /@types/prop-types@15.7.11: + resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} + dev: true + + /@types/react@18.2.48: + resolution: {integrity: sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==} + dependencies: + '@types/prop-types': 15.7.11 + '@types/scheduler': 0.16.8 + csstype: 3.1.3 + dev: true + /@types/retry@0.12.1: resolution: {integrity: sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==} dev: false + /@types/scheduler@0.16.8: + resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==} + dev: true + + /@types/use-sync-external-store@0.0.3: + resolution: {integrity: sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==} + dev: true + /@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.3.3): resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2443,6 +2585,20 @@ packages: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} dev: true + /abitype@0.9.8(typescript@5.3.3): + resolution: {integrity: sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.19.1 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + dependencies: + typescript: 5.3.3 + dev: true + /abitype@1.0.0(typescript@5.3.3): resolution: {integrity: sha512-NMeMah//6bJ56H5XRj8QCV4AwuW6hB6zqz2LnhhLdcWVQOsXki6/Pn3APeqxCma62nXIcmZWdu1DlHWS74umVQ==} peerDependencies: @@ -2692,6 +2848,23 @@ packages: engines: {node: '>=8'} dev: true + /blockstore-core@4.3.10: + resolution: {integrity: sha512-YLpkZ9GRiakh40hFx3eC6YpPbIO+6pKwc+BDrnCTSnsjfUtmV6v/3D3zvWn3wK00iQsfX0/B3ThFhr6p97uThA==} + dependencies: + '@libp2p/logger': 4.0.5 + err-code: 3.0.1 + interface-blockstore: 5.2.9 + interface-store: 5.1.7 + it-drain: 3.0.5 + it-filter: 3.0.4 + it-merge: 3.0.3 + it-pushable: 3.2.3 + multiformats: 13.0.1 + uint8arrays: 5.0.1 + transitivePeerDependencies: + - supports-color + dev: true + /bowser@2.11.0: resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} dev: false @@ -2769,7 +2942,6 @@ packages: /cborg@4.0.8: resolution: {integrity: sha512-/6QDK0Hw//cV4YNWZZjdIUMFNw0DZmb56jdVGJPwXP7874gSN0AMYqM07mVKpAm+6Nn7U8lvYFzPgBGatC+5xw==} hasBin: true - dev: false /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} @@ -2919,6 +3091,14 @@ packages: typescript: 5.3.3 dev: true + /cross-fetch@3.1.8: + resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + dev: true + /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -2928,6 +3108,10 @@ packages: which: 2.0.2 dev: true + /csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + dev: true + /damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} dev: true @@ -2981,6 +3165,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /decimal.js-light@2.5.1: + resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} + dev: true + /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true @@ -3015,6 +3203,15 @@ packages: path-type: 4.0.0 dev: true + /dns-over-http-resolver@3.0.2: + resolution: {integrity: sha512-5batkHOjCkuAfrFa+IPmt3jyeZqLtSMfAo1HQp3hfwtzgUwHooecTFplnYC093u5oRNL4CQHCXh3OfER7+vWrA==} + dependencies: + debug: 4.3.4(supports-color@5.5.0) + receptacle: 1.3.2 + transitivePeerDependencies: + - supports-color + dev: true + /doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -3082,7 +3279,6 @@ packages: /err-code@3.0.1: resolution: {integrity: sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==} - dev: false /error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} @@ -3573,6 +3769,10 @@ packages: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} + /eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + dev: true + /events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} @@ -3849,6 +4049,31 @@ packages: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} dev: true + /graphql-request@6.1.0(graphql@16.8.1): + resolution: {integrity: sha512-p+XPfS4q7aIpKVcgmnZKhMNqhltk20hfXtkaIkTfjjmiKMJ5xrt5c743cL03y/K7y1rg3WrIC49xGiEQ4mxdNw==} + peerDependencies: + graphql: 14 - 16 + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.8.1) + cross-fetch: 3.1.8 + graphql: 16.8.1 + transitivePeerDependencies: + - encoding + dev: true + + /graphql@16.8.1: + resolution: {integrity: sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + dev: true + + /hamt-sharding@3.0.2: + resolution: {integrity: sha512-f0DzBD2tSmLFdFsLAvOflIBqFPjerbA7BfmwO8mVho/5hXwgyyYhv+ijIzidQf/DpDX3bRjAQvhGoBFj+DBvPw==} + engines: {node: '>=16.0.0', npm: '>=7.0.0'} + dependencies: + sparse-array: 1.3.2 + uint8arrays: 4.0.10 + dev: true + /handlebars@4.7.8: resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} engines: {node: '>=0.4.7'} @@ -3940,6 +4165,12 @@ packages: function-bind: 1.1.2 dev: true + /hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + dependencies: + react-is: 16.13.1 + dev: true + /hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} dev: true @@ -3986,6 +4217,10 @@ packages: engines: {node: '>= 4'} dev: true + /immer@9.0.21: + resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==} + dev: true + /import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} @@ -4018,6 +4253,24 @@ packages: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} dev: true + /interface-blockstore@5.2.9: + resolution: {integrity: sha512-2nyiiOcmGSE5Z0K/Dck5Ayp2a51g1CEG1JyasqNYU/y+n0ykrT9sxuq+Dtc2w3qGpPuBBUirC4HwfGgBT4Z5lA==} + dependencies: + interface-store: 5.1.7 + multiformats: 13.0.1 + dev: true + + /interface-datastore@8.2.10: + resolution: {integrity: sha512-D8RuxMdjOPB+j6WMDJ+I2aXTDzUT6DIVjgzo1E+ODL7w8WrSFl9FXD2SYmgj6vVzdb7Kb5qmAI9pEnDZJz7ifg==} + dependencies: + interface-store: 5.1.7 + uint8arrays: 5.0.1 + dev: true + + /interface-store@5.1.7: + resolution: {integrity: sha512-DVMTgZ43NAdDtXL3QsEq8N0vuUYVBxiGbxN0uI0lrNasuX/CGSrU7bjOO2DaGTMNut4Pt3ae+VQYFvNtH4Oyeg==} + dev: true + /internal-slot@1.0.6: resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==} engines: {node: '>= 0.4'} @@ -4027,6 +4280,36 @@ packages: side-channel: 1.0.4 dev: true + /ipfs-unixfs-exporter@13.4.0: + resolution: {integrity: sha512-6KkGnh9KxWPQQ26k/mAG3jLzvvT85cz4tmKJK/DlDxXHmSmMAu9IkAvu2RfVy/BHPtT1+zF7Fw1Y5CNiZzHuLg==} + dependencies: + '@ipld/dag-cbor': 9.0.8 + '@ipld/dag-json': 10.1.7 + '@ipld/dag-pb': 4.0.8 + '@multiformats/murmur3': 2.1.8 + err-code: 3.0.1 + hamt-sharding: 3.0.2 + interface-blockstore: 5.2.9 + ipfs-unixfs: 11.1.3 + it-filter: 3.0.4 + it-last: 3.0.4 + it-map: 3.0.5 + it-parallel: 3.0.6 + it-pipe: 3.0.1 + it-pushable: 3.2.3 + multiformats: 13.0.1 + p-queue: 8.0.1 + progress-events: 1.0.0 + dev: true + + /ipfs-unixfs@11.1.3: + resolution: {integrity: sha512-sy6Koojwm/EcM8yvDlycRYA89C8wIcLcGTMMpqnCPUtqTCdl+JxsuPNCBgAu7tmO8Nipm7Tv7f0g/erxTGKKRA==} + dependencies: + err-code: 3.0.1 + protons-runtime: 5.2.2 + uint8arraylist: 2.4.8 + dev: true + /ipfs-utils@9.0.14: resolution: {integrity: sha512-zIaiEGX18QATxgaS0/EOQNoo33W0islREABAcxXE8n7y2MGAlB+hdsxXn4J0hGZge8IqVQhW8sWIb+oJz2yEvg==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} @@ -4271,12 +4554,21 @@ packages: ws: '*' dependencies: ws: 8.13.0 - dev: false /it-all@1.0.6: resolution: {integrity: sha512-3cmCc6Heqe3uWi3CVM/k51fa/XbMFpQVzFoDsV0IZNHSQDyAXl3c4MjHkFX5kF3922OGj7Myv1nSEUgRtcuM1A==} dev: false + /it-drain@3.0.5: + resolution: {integrity: sha512-qYFe4SWdvs9oJGUY5bSjvmiLUMLzFEODNOQUdYdCIkuIgQF+AUB2INhM4yQ09buJ2rhHKDFxvTD/+yUq6qg0XA==} + dev: true + + /it-filter@3.0.4: + resolution: {integrity: sha512-e0sz+st4sudK/zH6GZ/gRTRP8A/ADuJFCYDmRgMbZvR79y5+v4ZXav850bBZk5wL9zXaYZFxS1v/6Qi+Vjwh5g==} + dependencies: + it-peekable: 3.0.3 + dev: true + /it-glob@1.0.2: resolution: {integrity: sha512-Ch2Dzhw4URfB9L/0ZHyY+uqOnKvBNeS/SMcRiPmJfpHiM0TsUZn+GkpcZxAoF3dJVdPm/PuIk3A4wlV7SUo23Q==} dependencies: @@ -4284,6 +4576,52 @@ packages: minimatch: 3.1.2 dev: false + /it-last@3.0.4: + resolution: {integrity: sha512-Ns+KTsQWhs0KCvfv5X3Ck3lpoYxHcp4zUp4d+AOdmC8cXXqDuoZqAjfWhgCbxJubXyIYWdfE2nRcfWqgvZHP8Q==} + dev: true + + /it-map@3.0.5: + resolution: {integrity: sha512-hB0TDXo/h4KSJJDSRLgAPmDroiXP6Fx1ck4Bzl3US9hHfZweTKsuiP0y4gXuTMcJlS6vj0bb+f70rhkD47ZA3w==} + dependencies: + it-peekable: 3.0.3 + dev: true + + /it-merge@3.0.3: + resolution: {integrity: sha512-FYVU15KC5pb/GQX1Ims+lee8d4pdqGVCpWr0lkNj8o4xuNo7jY71k6GuEiWdP+T7W1bJqewSxX5yoTy5yZpRVA==} + dependencies: + it-pushable: 3.2.3 + dev: true + + /it-parallel@3.0.6: + resolution: {integrity: sha512-i7UM7I9LTkDJw3YIqXHFAPZX6CWYzGc+X3irdNrVExI4vPazrJdI7t5OqrSVN8CONXLAunCiqaSV/zZRbQR56A==} + dependencies: + p-defer: 4.0.0 + dev: true + + /it-peekable@3.0.3: + resolution: {integrity: sha512-Wx21JX/rMzTEl9flx3DGHuPV1KQFGOl8uoKfQtmZHgPQtGb89eQ6RyVd82h3HuP9Ghpt0WgBDlmmdWeHXqyx7w==} + dev: true + + /it-pipe@3.0.1: + resolution: {integrity: sha512-sIoNrQl1qSRg2seYSBH/3QxWhJFn9PKYvOf/bHdtCBF0bnghey44VyASsWzn5dAx0DCDDABq1hZIuzKmtBZmKA==} + engines: {node: '>=16.0.0', npm: '>=7.0.0'} + dependencies: + it-merge: 3.0.3 + it-pushable: 3.2.3 + it-stream-types: 2.0.1 + dev: true + + /it-pushable@3.2.3: + resolution: {integrity: sha512-gzYnXYK8Y5t5b/BnJUr7glfQLO4U5vyb05gPx/TyTw+4Bv1zM9gFk4YsOrnulWefMewlphCjKkakFvj1y99Tcg==} + dependencies: + p-defer: 4.0.0 + dev: true + + /it-stream-types@2.0.1: + resolution: {integrity: sha512-6DmOs5r7ERDbvS4q8yLKENcj6Yecr7QQTqWApbZdfAUTEC947d+PEha7PCqhm//9oxaLYL7TWRekwhoXl2s6fg==} + engines: {node: '>=16.0.0', npm: '>=7.0.0'} + dev: true + /it-to-stream@1.0.0: resolution: {integrity: sha512-pLULMZMAB/+vbdvbZtebC0nWBTbG581lk6w8P7DfIIIKUfa8FbY7Oi0FxZcFPbxvISs7A9E+cMpLDBc1XhpAOA==} dependencies: @@ -4462,6 +4800,10 @@ packages: resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} dev: false + /lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + dev: true + /lodash.get@4.4.2: resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} dev: false @@ -4663,16 +5005,17 @@ packages: /multiformats@12.1.3: resolution: {integrity: sha512-eajQ/ZH7qXZQR2AgtfpmSMizQzmyYVmCql7pdhldPuYQi4atACekbJaQplk6dWyIi10jCaFnd6pqvcEFXjbaJw==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} - dev: false /multiformats@13.0.1: resolution: {integrity: sha512-bt3R5iXe2O8xpp3wkmQhC73b/lC4S2ihU8Dndwcsysqbydqb8N+bpP116qMcClZ17g58iSIwtXUTcg2zT4sniA==} - dev: false + + /multiformats@9.9.0: + resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + dev: true /murmurhash3js-revisited@3.0.0: resolution: {integrity: sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g==} engines: {node: '>=8.0.0'} - dev: false /nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} @@ -4706,7 +5049,6 @@ packages: optional: true dependencies: whatwg-url: 5.0.0 - dev: false /nodemon@3.0.3: resolution: {integrity: sha512-7jH/NXbFPxVaMwmBCC2B9F/V6X1VkEdNgx3iu9jji8WxWcvhMWkmhNWhI5077zknOnZnBzba9hZP6bCPJLSReQ==} @@ -4879,7 +5221,6 @@ packages: /p-defer@4.0.0: resolution: {integrity: sha512-Vb3QRvQ0Y5XnF40ZUWW7JfLogicVh/EnA5gBIvKDJoYpeI82+1E3AlB9yOcKFS0AhHrWVnAQO39fbR0G99IVEQ==} engines: {node: '>=12'} - dev: false /p-fifo@1.0.0: resolution: {integrity: sha512-IjoCxXW48tqdtDFz6fqo5q1UfFVjjVZe8TC1QRflvNUJtNfCUhxOUw6MOVZhDPjqhSzc26xKdugsO17gmzd5+A==} @@ -4916,6 +5257,14 @@ packages: p-limit: 3.1.0 dev: true + /p-queue@8.0.1: + resolution: {integrity: sha512-NXzu9aQJTAzbBqOt2hwsR63ea7yvxJc0PwN/zobNAudYfb1B7R08SzB4TsLeSbUCuG467NhnoT0oO6w1qRO+BA==} + engines: {node: '>=18'} + dependencies: + eventemitter3: 5.0.1 + p-timeout: 6.1.2 + dev: true + /p-retry@5.1.2: resolution: {integrity: sha512-couX95waDu98NfNZV+i/iLt+fdVxmI7CbrrdC2uDWfPdUAApyxT4wmDlyOtR5KtTDmkDO0zDScDjDou9YHhd9g==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -4924,6 +5273,11 @@ packages: retry: 0.13.1 dev: false + /p-timeout@6.1.2: + resolution: {integrity: sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==} + engines: {node: '>=14.16'} + dev: true + /p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} @@ -5161,6 +5515,11 @@ packages: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} + /progress-events@1.0.0: + resolution: {integrity: sha512-zIB6QDrSbPfRg+33FZalluFIowkbV5Xh1xSuetjG+rlC5he6u2dc6VQJ0TbMdlN3R1RHdpOqxEFMKTnQ+itUwA==} + engines: {node: '>=16.0.0', npm: '>=7.0.0'} + dev: true + /prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} dependencies: @@ -5188,6 +5547,13 @@ packages: long: 5.2.3 dev: false + /protons-runtime@5.2.2: + resolution: {integrity: sha512-o97rNPN9pE3cxOxjs/waZNRKlbY/DR11oc20rUvarWZgFzQLLLzJU0RFh5JPi6GJCN67VGVn9/FDIEtFblfB3A==} + dependencies: + uint8arraylist: 2.4.8 + uint8arrays: 5.0.1 + dev: true + /pstree.remy@1.1.8: resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} dev: true @@ -5216,12 +5582,54 @@ packages: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} dev: true + /react-is@18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + dev: true + /react-native-fetch-api@3.0.0: resolution: {integrity: sha512-g2rtqPjdroaboDKTsJCTlcmtw54E25OjyaunUP0anOZn4Fuo2IKs8BVfe02zVggA/UysbmfSnRJIqtNkAgggNA==} dependencies: p-defer: 3.0.0 dev: false + /react-redux@8.1.3(react@18.2.0)(redux@4.2.1): + resolution: {integrity: sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==} + peerDependencies: + '@types/react': ^16.8 || ^17.0 || ^18.0 + '@types/react-dom': ^16.8 || ^17.0 || ^18.0 + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + react-native: '>=0.59' + redux: ^4 || ^5.0.0-beta.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + react-dom: + optional: true + react-native: + optional: true + redux: + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@types/hoist-non-react-statics': 3.3.5 + '@types/use-sync-external-store': 0.0.3 + hoist-non-react-statics: 3.3.2 + react: 18.2.0 + react-is: 18.2.0 + redux: 4.2.1 + use-sync-external-store: 1.2.0(react@18.2.0) + dev: true + + /react@18.2.0: + resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + engines: {node: '>=0.10.0'} + dependencies: + loose-envify: 1.4.0 + dev: true + /read-pkg-up@7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} engines: {node: '>=8'} @@ -5270,6 +5678,12 @@ packages: resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} engines: {node: '>= 12.13.0'} + /receptacle@1.3.2: + resolution: {integrity: sha512-HrsFvqZZheusncQRiEE7GatOAETrARKV/lnfYicIm8lbvp/JQOdADOfhjBd2DajvoszEyxSM6RlAAIZgEoeu/A==} + dependencies: + ms: 2.1.3 + dev: true + /redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} @@ -5278,6 +5692,20 @@ packages: strip-indent: 3.0.0 dev: true + /redux-thunk@2.4.2(redux@4.2.1): + resolution: {integrity: sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==} + peerDependencies: + redux: ^4 + dependencies: + redux: 4.2.1 + dev: true + + /redux@4.2.1: + resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==} + dependencies: + '@babel/runtime': 7.23.8 + dev: true + /reflect.getprototypeof@1.0.4: resolution: {integrity: sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==} engines: {node: '>= 0.4'} @@ -5312,6 +5740,10 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + /reselect@4.1.8: + resolution: {integrity: sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==} + dev: true + /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -5487,6 +5919,10 @@ packages: engines: {node: '>=0.10.0'} dev: false + /sparse-array@1.3.2: + resolution: {integrity: sha512-ZT711fePGn3+kQyLuv1fpd3rNSkNF8vd5Kv2D+qnOANeyKs3fx6bUMGWRPvgTTcYV64QMqZKZwcuaQSP3AZ0tg==} + dev: true + /spdx-correct@3.2.0: resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} dependencies: @@ -5708,7 +6144,6 @@ packages: /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - dev: false /trim-newlines@3.0.1: resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} @@ -5839,11 +6274,29 @@ packages: dev: false optional: true + /uint8-varint@2.0.3: + resolution: {integrity: sha512-seXTM8ba4uuAMDgi3UHXPdDxCBKjWWZigW+F+1ESPhOZv9ekT1qmbdzYHLSNA+u+wHj10P55dQ41y2Qh7NOqiA==} + dependencies: + uint8arraylist: 2.4.8 + uint8arrays: 5.0.1 + dev: true + + /uint8arraylist@2.4.8: + resolution: {integrity: sha512-vc1PlGOzglLF0eae1M8mLRTBivsvrGsdmJ5RbK3e+QRvRLOZfZhQROTwH/OfyF3+ZVUg9/8hE8bmKP2CvP9quQ==} + dependencies: + uint8arrays: 5.0.1 + dev: true + /uint8arrays@4.0.10: resolution: {integrity: sha512-AnJNUGGDJAgFw/eWu/Xb9zrVKEGlwJJCaeInlf3BkecE/zcTobk5YXYIPNQJO1q5Hh1QZrQQHf0JvcHqz2hqoA==} dependencies: multiformats: 12.1.3 - dev: false + + /uint8arrays@5.0.1: + resolution: {integrity: sha512-ND5RpJAnPgHmZT7hWD/2T4BwRp04j8NLKvMKC/7bhiEwEjUMkQ4kvBKiH6hOqbljd6qJ2xS8reL3vl1e33grOQ==} + dependencies: + multiformats: 13.0.1 + dev: true /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} @@ -5866,6 +6319,14 @@ packages: dependencies: punycode: 2.3.1 + /use-sync-external-store@1.2.0(react@18.2.0): + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + dev: true + /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -5890,6 +6351,29 @@ packages: resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==} dev: false + /viem@1.21.4(typescript@5.3.3): + resolution: {integrity: sha512-BNVYdSaUjeS2zKQgPs+49e5JKocfo60Ib2yiXOWBT6LuVxY1I/6fFX3waEtpXvL1Xn4qu+BVitVtMh9lyThyhQ==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@adraffy/ens-normalize': 1.10.0 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/bip32': 1.3.2 + '@scure/bip39': 1.2.1 + abitype: 0.9.8(typescript@5.3.3) + isows: 1.0.3(ws@8.13.0) + typescript: 5.3.3 + ws: 8.13.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + dev: true + /viem@2.2.0(typescript@5.3.3): resolution: {integrity: sha512-3wfpJTDwtO1f+OWdRQ+2Gr51AQ0rR1FPmBT19LZW8+QLFzXnYASR52tfapF1MfmitSIxZSwVoBEihekC8aAJqA==} peerDependencies: @@ -5915,14 +6399,12 @@ packages: /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - dev: false /whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} dependencies: tr46: 0.0.3 webidl-conversions: 3.0.1 - dev: false /when-exit@2.1.2: resolution: {integrity: sha512-u9J+toaf3CCxCAzM/484qNAxQE75rFdVgiFEEV8Xps2gzYhf0tx73s1WXDQhkwV17E3MxRMz40m7Ekd2/121Lg==} @@ -6012,7 +6494,6 @@ packages: optional: true utf-8-validate: optional: true - dev: false /xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} diff --git a/scripts/upload-existing-cids-on-s3.ts b/scripts/upload-existing-cids-on-s3.ts new file mode 100644 index 0000000..2e0f372 --- /dev/null +++ b/scripts/upload-existing-cids-on-s3.ts @@ -0,0 +1,229 @@ +import { ChainId, SUBGRAPH_URL } from "@carrot-kpi/sdk"; +import { CarReader } from "@ipld/car"; +import { gql, request as gqlRequest } from "graphql-request"; +import { S3 } from "@aws-sdk/client-s3"; +import { recursive } from "ipfs-unixfs-exporter"; +import { MemoryBlockstore } from "blockstore-core"; +import { config as dotenvConfig } from "dotenv"; +import { CID } from "multiformats/cid"; +import { requireEnv } from "../src/utils.js"; +import { Upload } from "@aws-sdk/lib-storage"; +import { Readable } from "node:stream"; +import { Address, Chain, createPublicClient, http } from "viem"; +import { gnosis, polygonMumbai, scrollSepolia, sepolia } from "viem/chains"; + +dotenvConfig(); + +const IPFS_GATEWAY_URL = "https://w3s.link"; +const DEFILLAMA_ORACLE_ABI = [ + { + type: "function", + name: "specification", + inputs: [], + outputs: [{ name: "", type: "string", internalType: "string" }], + stateMutability: "view", + }, +] as const; +const CHAIN: Record = { + [ChainId.GNOSIS]: gnosis, + [ChainId.POLYGON_MUMBAI]: polygonMumbai, + [ChainId.SCROLL_SEPOLIA]: scrollSepolia, + [ChainId.SEPOLIA]: sepolia, +}; + +const bucketName = requireEnv({ name: "S3_BUCKET" }); +console.log(`Using bucket name ${bucketName}`); + +const s3 = new S3({ + region: "us-east-1", + endpoint: process.env.S3_ENDPOINT, + credentials: { + accessKeyId: requireEnv({ name: "S3_ACCESS_KEY_ID" }), + secretAccessKey: requireEnv({ name: "S3_SECRET_ACCESS_KEY" }), + }, +}); + +const fetchCids = async (): Promise<{ cid: string; template: boolean }[]> => { + try { + const cids: { cid: string; template: boolean }[] = []; + for (const [chain, subgraphUrl] of Object.entries(SUBGRAPH_URL)) { + if (!subgraphUrl) { + console.warn( + `Skipping network ${chain} (no subgraph available)`, + ); + continue; + } + const response = await gqlRequest<{ + tokenTemplates: { cid: string }[]; + oracleTemplates: { cid: string }[]; + defilLamaOracles: { oracles: { address: Address }[] }[]; + tokens: { cid: string }[]; + }>( + subgraphUrl as string, + gql` + query getCids { + tokenTemplates: kpitokenTemplates { + cid: specificationCid + } + oracleTemplates: oracleTemplates { + cid: specificationCid + } + defilLamaOracles: oracleTemplates( + where: { managerId: 1 } + ) { + oracles { + address: id + } + } + tokens: kpitokens { + cid: descriptionCid + } + } + `, + ); + response.tokens.forEach(({ cid }) => + cids.push({ cid, template: false }), + ); + response.tokenTemplates + .concat(response.oracleTemplates) + .forEach(({ cid }) => cids.push({ cid, template: true })); + + const defiLlamaOracleAddresses = response.defilLamaOracles.flatMap( + (defiLlamaOracle) => + defiLlamaOracle.oracles.map((oracle) => oracle.address), + ); + const publicClient = createPublicClient({ + chain: CHAIN[chain], + transport: http(), + }); + const defiLlamaOracleSpecificationCids = + await publicClient.multicall({ + allowFailure: false, + contracts: defiLlamaOracleAddresses.map((address) => { + return { + address, + abi: DEFILLAMA_ORACLE_ABI, + functionName: "specification", + args: [], + }; + }), + }); + defiLlamaOracleSpecificationCids.forEach( + (defiLlamaOracleSpecificationCid) => { + cids.push({ + cid: defiLlamaOracleSpecificationCid, + template: false, + }); + }, + ); + } + + return Array.from( + new Set(cids.map((wrappedCid) => wrappedCid.cid)), + ).reduce((accumulator: { cid: string; template: boolean }[], cid) => { + const wrappedCid = cids.find( + (wrappedCid) => wrappedCid.cid === cid, + ); + if (wrappedCid) accumulator.push(wrappedCid); + return accumulator; + }, []); + } catch (error) { + console.error("Could not fetch CIDs", error); + process.exit(1); + } +}; + +const handleJsonCid = async ( + cid: string, +): Promise<{ objectKey: string; data: Readable }[]> => { + const response = await fetch( + `${IPFS_GATEWAY_URL}/ipfs/${cid}?download=true&format=raw`, + ); + if (!response || !response.body) + throw new Error( + `Could not get raw JSON data for CID ${cid}: ${await response.text()}`, + ); + return [ + { + objectKey: cid, + data: Readable.fromWeb(response.body as unknown as any), + }, + ]; +}; + +const handleDagPbCid = async ( + cid: string, +): Promise<{ objectKey: string; data: Readable }[]> => { + const response = await fetch( + `https://w3s.link/ipfs/${cid}?download=true&format=car`, + ); + if (!response || !response.body) + throw new Error( + `Could not fetch CAR data for CID ${cid}: ${await response.text()}`, + ); + + const body = new Uint8Array(await response.arrayBuffer()); + + const car = await CarReader.fromBytes(body); + const roots = await car.getRoots(); + if (roots.length === 0 || roots.length > 1) + throw new Error(`Zero or more than one root for cid ${cid}`); + + const blockstore = new MemoryBlockstore(); + for await (const block of car.blocks()) { + blockstore.put(block.cid, block.bytes); + } + + const entries: { objectKey: string; data: Readable }[] = []; + for await (const entry of recursive(cid, blockstore)) { + if (entry.type === "directory") { + continue; + } + entries.push({ + objectKey: entry.path, + data: Readable.from(entry.content()), + }); + } + + return entries; +}; + +const handleCid = async ( + cid: string, +): Promise<{ objectKey: string; data: Readable }[]> => { + const parsedCid = CID.parse(cid); + switch (parsedCid.code) { + case 512: { + return handleJsonCid(cid); + } + case 112: { + return handleDagPbCid(cid); + } + default: { + throw new Error(`Unsupported codec ${parsedCid.code} used`); + } + } +}; + +const main = async () => { + const cids = await fetchCids(); + + let done = 0; + for (const { cid, template } of cids) { + const uploads = await handleCid(cid); + for (const upload of uploads) { + await new Upload({ + client: s3, + params: { + Bucket: bucketName, + Key: upload.objectKey, + Body: upload.data, + Tagging: `CarrotTemplate=${template}&CarrotLimbo=false`, + }, + }).done(); + } + console.log(`[${++done}/${cids.length}] - ${cid}`); + } +}; + +await main(); From 402de5b0ad9dcf1abc395fddd2d2a4ed591d899f Mon Sep 17 00:00:00 2001 From: luzzifoss Date: Tue, 30 Jan 2024 09:59:00 +0000 Subject: [PATCH 2/4] feat: correctly set mime type while uploading --- package.json | 1 + pnpm-lock.yaml | 9 +++++++++ scripts/upload-existing-cids-on-s3.ts | 16 ++++++++++++---- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index f6378ce..c2dc233 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "graphql-request": "^6.1.0", "husky": "^8.0.3", "ipfs-unixfs-exporter": "^13.4.0", + "mime": "^4.0.1", "nodemon": "^3.0.3", "pino": "^8.17.2", "prettier": "^3.2.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0c6b19b..8bea872 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -109,6 +109,9 @@ devDependencies: ipfs-unixfs-exporter: specifier: ^13.4.0 version: 13.4.0 + mime: + specifier: ^4.0.1 + version: 4.0.1 nodemon: specifier: ^3.0.3 version: 3.0.3 @@ -4958,6 +4961,12 @@ packages: engines: {node: '>= 0.6'} dev: false + /mime@4.0.1: + resolution: {integrity: sha512-5lZ5tyrIfliMXzFtkYyekWbtRXObT9OWa8IwQ5uxTBDHucNNwniRqo0yInflj+iYi5CBa6qxadGzGarDfuEOxA==} + engines: {node: '>=16'} + hasBin: true + dev: true + /mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} diff --git a/scripts/upload-existing-cids-on-s3.ts b/scripts/upload-existing-cids-on-s3.ts index 2e0f372..bd4d236 100644 --- a/scripts/upload-existing-cids-on-s3.ts +++ b/scripts/upload-existing-cids-on-s3.ts @@ -11,6 +11,7 @@ import { Upload } from "@aws-sdk/lib-storage"; import { Readable } from "node:stream"; import { Address, Chain, createPublicClient, http } from "viem"; import { gnosis, polygonMumbai, scrollSepolia, sepolia } from "viem/chains"; +import mime from "mime"; dotenvConfig(); @@ -135,7 +136,7 @@ const fetchCids = async (): Promise<{ cid: string; template: boolean }[]> => { const handleJsonCid = async ( cid: string, -): Promise<{ objectKey: string; data: Readable }[]> => { +): Promise<{ objectKey: string; data: Readable; contentType: string }[]> => { const response = await fetch( `${IPFS_GATEWAY_URL}/ipfs/${cid}?download=true&format=raw`, ); @@ -147,13 +148,14 @@ const handleJsonCid = async ( { objectKey: cid, data: Readable.fromWeb(response.body as unknown as any), + contentType: "application/json", }, ]; }; const handleDagPbCid = async ( cid: string, -): Promise<{ objectKey: string; data: Readable }[]> => { +): Promise<{ objectKey: string; data: Readable; contentType: string }[]> => { const response = await fetch( `https://w3s.link/ipfs/${cid}?download=true&format=car`, ); @@ -174,7 +176,11 @@ const handleDagPbCid = async ( blockstore.put(block.cid, block.bytes); } - const entries: { objectKey: string; data: Readable }[] = []; + const entries: { + objectKey: string; + data: Readable; + contentType: string; + }[] = []; for await (const entry of recursive(cid, blockstore)) { if (entry.type === "directory") { continue; @@ -182,6 +188,7 @@ const handleDagPbCid = async ( entries.push({ objectKey: entry.path, data: Readable.from(entry.content()), + contentType: mime.getType(entry.name) || "application/octet-stream", }); } @@ -190,7 +197,7 @@ const handleDagPbCid = async ( const handleCid = async ( cid: string, -): Promise<{ objectKey: string; data: Readable }[]> => { +): Promise<{ objectKey: string; data: Readable; contentType: string }[]> => { const parsedCid = CID.parse(cid); switch (parsedCid.code) { case 512: { @@ -218,6 +225,7 @@ const main = async () => { Bucket: bucketName, Key: upload.objectKey, Body: upload.data, + ContentType: upload.contentType, Tagging: `CarrotTemplate=${template}&CarrotLimbo=false`, }, }).done(); From 0a2ceeeb34f704d3226806ca44cf6411605574e1 Mon Sep 17 00:00:00 2001 From: luzzifoss Date: Tue, 30 Jan 2024 11:19:40 +0000 Subject: [PATCH 3/4] fix: use subdomain style gateway to fetch content --- scripts/upload-existing-cids-on-s3.ts | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/scripts/upload-existing-cids-on-s3.ts b/scripts/upload-existing-cids-on-s3.ts index bd4d236..89e862f 100644 --- a/scripts/upload-existing-cids-on-s3.ts +++ b/scripts/upload-existing-cids-on-s3.ts @@ -15,7 +15,6 @@ import mime from "mime"; dotenvConfig(); -const IPFS_GATEWAY_URL = "https://w3s.link"; const DEFILLAMA_ORACLE_ABI = [ { type: "function", @@ -136,9 +135,10 @@ const fetchCids = async (): Promise<{ cid: string; template: boolean }[]> => { const handleJsonCid = async ( cid: string, + parsedCid: CID, ): Promise<{ objectKey: string; data: Readable; contentType: string }[]> => { const response = await fetch( - `${IPFS_GATEWAY_URL}/ipfs/${cid}?download=true&format=raw`, + `https://${parsedCid.toV1()}.ipfs.dweb.link/?download=true&format=raw`, ); if (!response || !response.body) throw new Error( @@ -147,7 +147,7 @@ const handleJsonCid = async ( return [ { objectKey: cid, - data: Readable.fromWeb(response.body as unknown as any), + data: Readable.fromWeb(response.body as any), contentType: "application/json", }, ]; @@ -155,24 +155,25 @@ const handleJsonCid = async ( const handleDagPbCid = async ( cid: string, + parsedCid: CID, ): Promise<{ objectKey: string; data: Readable; contentType: string }[]> => { const response = await fetch( - `https://w3s.link/ipfs/${cid}?download=true&format=car`, + `https://${parsedCid.toV1()}.ipfs.dweb.link/?download=true&format=car`, ); if (!response || !response.body) throw new Error( `Could not fetch CAR data for CID ${cid}: ${await response.text()}`, ); - const body = new Uint8Array(await response.arrayBuffer()); - - const car = await CarReader.fromBytes(body); - const roots = await car.getRoots(); + const carReader = await CarReader.fromIterable( + Readable.fromWeb(response.body as any), + ); + const roots = await carReader.getRoots(); if (roots.length === 0 || roots.length > 1) throw new Error(`Zero or more than one root for cid ${cid}`); const blockstore = new MemoryBlockstore(); - for await (const block of car.blocks()) { + for await (const block of carReader.blocks()) { blockstore.put(block.cid, block.bytes); } @@ -201,10 +202,10 @@ const handleCid = async ( const parsedCid = CID.parse(cid); switch (parsedCid.code) { case 512: { - return handleJsonCid(cid); + return handleJsonCid(cid, parsedCid); } case 112: { - return handleDagPbCid(cid); + return handleDagPbCid(cid, parsedCid); } default: { throw new Error(`Unsupported codec ${parsedCid.code} used`); From fc4e07627fa26b26ef725b9f9d195be952512f6c Mon Sep 17 00:00:00 2001 From: luzzifoss Date: Tue, 30 Jan 2024 15:41:48 +0000 Subject: [PATCH 4/4] chore: separate .env file, readme update and new region env --- .gitignore | 3 ++- README.md | 16 +++++++++------- scripts/upload-existing-cids-on-s3.ts | 7 ++++--- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index cbd9962..7726e21 100644 --- a/.gitignore +++ b/.gitignore @@ -136,7 +136,8 @@ terraform/*.json *.out tfplan -.env +.env* +!.env.example build .compose .turbo diff --git a/README.md b/README.md index 5fa2351..06759b8 100644 --- a/README.md +++ b/README.md @@ -243,11 +243,12 @@ pnpm upload-folder The script under `/scripts/upload-existing-cids-on-s3.ts` takes care of detecting all the CIDs used across the Carrot protocol and uploading them to the S3 limbo/persistent storage. It works with underlying data encoded in both raw -JSON and DAG PB `multicodec` formats with the option of adding more supported -codecs if needed, and it also works across chains. It requires a few env -variables in order to be ran: +JSON and MerkleDAG PB `multicodec` formats with the option of adding more +supported codecs if needed, and it also works across chains. It requires a few +env variables in order to be ran: - `S3_BUCKET`: the name of the S3 bucket to which to upload the data. +- `S3_REGION`: the region in which the S3 bucket is available. - `S3_ENDPOINT (optional)`: the endpoint of the S3 bucket to which to upload the data. - `S3_ACCESS_KEY_ID`: an AWS access key id with the correct permission policies @@ -255,10 +256,11 @@ variables in order to be ran: - `S3_SECRET_ACCESS_KEY`: the secret key associated with the specified access key id. -You can put these env in the same `.env` file you use to run the server in dev -mode and you can also test the script against a local S3 deployment in the same -way (by bootstrapping MinIO through the provided Docker Compose file and putting -the right values in the `.env` file). +You need to put these envs in a separate `.env.upload-existing-cids-on-s3` file +and you can also test the script against a local S3 deployment in the same way +it's possible to do it with the development server (by bootstrapping MinIO +through the provided Docker Compose file and putting the right values in the +`.env.upload-existing-cids-on-s3` file). To launch the script just execute the following command in your terminal from the root of the repo: diff --git a/scripts/upload-existing-cids-on-s3.ts b/scripts/upload-existing-cids-on-s3.ts index 89e862f..8c83e18 100644 --- a/scripts/upload-existing-cids-on-s3.ts +++ b/scripts/upload-existing-cids-on-s3.ts @@ -13,7 +13,7 @@ import { Address, Chain, createPublicClient, http } from "viem"; import { gnosis, polygonMumbai, scrollSepolia, sepolia } from "viem/chains"; import mime from "mime"; -dotenvConfig(); +dotenvConfig({ path: ".env.upload-existing-cids-on-s3" }); const DEFILLAMA_ORACLE_ABI = [ { @@ -32,10 +32,11 @@ const CHAIN: Record = { }; const bucketName = requireEnv({ name: "S3_BUCKET" }); -console.log(`Using bucket name ${bucketName}`); +const bucketRegion = requireEnv({ name: "S3_REGION" }); +console.log(`Using bucket name ${bucketName} in region ${bucketRegion}`); const s3 = new S3({ - region: "us-east-1", + region: bucketRegion, endpoint: process.env.S3_ENDPOINT, credentials: { accessKeyId: requireEnv({ name: "S3_ACCESS_KEY_ID" }),