diff --git a/offchain/src/contracts-url.ts b/offchain/src/contracts-url.ts index c11201b..a742a2f 100644 --- a/offchain/src/contracts-url.ts +++ b/offchain/src/contracts-url.ts @@ -1 +1 @@ -export default 'https://bafkreigq7bnsin33zynqbwt45oytfg6nqalur3matsx6u3xuxhdh7qzw4q.ipfs.w3s.link' \ No newline at end of file +export default 'https://lime-urban-salamander-570.mypinata.cloud/ipfs/bafkreigeigtn7vqpp5fkwt5gqgvjlvnpn3nvnshcppjme4mfbvbl2vggo4' \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 98ff5cb..696515e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -66,12 +66,6 @@ importers: '@ikigai-github/mintun-offchain': specifier: workspace:../offchain version: link:../offchain - '@ipld/car': - specifier: ^5.3.0 - version: 5.3.0 - '@ipld/dag-ucan': - specifier: ^3.4.0 - version: 3.4.0 '@mdx-js/loader': specifier: ^3.0.1 version: 3.0.1(webpack@5.90.3(@swc/core@1.4.17)) @@ -135,9 +129,6 @@ importers: '@types/mdx': specifier: ^2.0.13 version: 2.0.13 - '@web3-storage/w3up-client': - specifier: ^15.0.0 - version: 15.0.0(encoding@0.1.13) bech32: specifier: ^2.0.0 version: 2.0.0 @@ -168,6 +159,9 @@ importers: node-fetch: specifier: ^3.3.2 version: 3.3.2 + pinata: + specifier: ^2.5.6 + version: 2.5.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: ^18.3.1 version: 18.3.1 @@ -872,28 +866,6 @@ packages: cpu: [x64] os: [win32] - '@ipld/car@5.3.0': - resolution: {integrity: sha512-OB8LVvJeVAFFGluNIkZeDZ/aGeoekFKsuIvNT9I5sJIb5WekQuW5+lekjQ7Z7mZ7DBKuke/kI4jBT1j0/akU1w==} - engines: {node: '>=16.0.0', npm: '>=7.0.0'} - - '@ipld/dag-cbor@9.2.0': - resolution: {integrity: sha512-N14oMy0q4gM6OuZkIpisKe0JBSjf1Jb39VI+7jMLiWX9124u1Z3Fdj/Tag1NA0cVxxqWDh0CqsjcVfOKtelPDA==} - engines: {node: '>=16.0.0', npm: '>=7.0.0'} - - '@ipld/dag-json@10.2.0': - resolution: {integrity: sha512-O9YLUrl3d3WbVz7v1WkajFkyfOLEe2Fep+wor4fgVe0ywxzrivrj437NiPcVyB+2EDdFn/Q7tCHFf8YVhDf8ZA==} - engines: {node: '>=16.0.0', npm: '>=7.0.0'} - - '@ipld/dag-pb@4.1.0': - resolution: {integrity: sha512-LJU451Drqs5zjFm7jI4Hs3kHlilOqkjcSfPiQgVsZnWaYb2C7YdfhnclrVn/X+ucKejlU9BL3+gXFCZUXkMuCg==} - engines: {node: '>=16.0.0', npm: '>=7.0.0'} - - '@ipld/dag-ucan@3.4.0': - resolution: {integrity: sha512-sW4R43w3DbEdoGWWJZCwsblwXa600HCanG9p2w1MJPVBNTNjhvqc3XI0uEqKhT2oqKWrND7uInVtcPmZme7hhA==} - - '@ipld/unixfs@2.2.0': - resolution: {integrity: sha512-lDQ2eRhJlbFaBoO3bhOmDVCLmpOnhwtwbilqUgAAhbhoPSmLrnv7gsBuToZjXOdPaEGSL7apkmm6nFrcU6zh4Q==} - '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -1063,10 +1035,6 @@ packages: '@multiformats/multiaddr@13.0.3': resolution: {integrity: sha512-mEqqJ4r3a/uuFMTpRkU316wGNIDQNhuVWpm+ebKTQeYsfv9jXbPONWM6VVnj3KGUrwfsX7GZOyp4TFqEA2SPCw==} - '@multiformats/murmur3@2.1.8': - resolution: {integrity: sha512-6vId1C46ra3R1sbJUOFCZnsUIveR9oF20yhPmAFxPm0JfrX3/ZRCgP3YDrBzlGoEppOXnA9czHeYc0T9mB6hbA==} - engines: {node: '>=16.0.0', npm: '>=7.0.0'} - '@next/env@14.1.0': resolution: {integrity: sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw==} @@ -1138,12 +1106,6 @@ packages: cpu: [x64] os: [win32] - '@noble/curves@1.3.0': - resolution: {integrity: sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==} - - '@noble/ed25519@1.7.3': - resolution: {integrity: sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==} - '@noble/hashes@1.3.3': resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} engines: {node: '>= 16'} @@ -1485,43 +1447,10 @@ packages: resolution: {integrity: sha512-YBcMfqNSwn3SujUJvAaySy5tlYbYm6tVt9SKoXu8BaTdKGROiJDgPR3TXpZdAKUfklzm3lRapJEAltiMQtBgZg==} engines: {node: '>=10.12.0'} - '@perma/map@1.0.3': - resolution: {integrity: sha512-Bf5njk0fnJGTFE2ETntq0N1oJ6YdCPIpTDn3R3KYZJQdeYSOCNL7mBrFlGnbqav8YQhJA/p81pvHINX9vAtHkQ==} - '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@protobufjs/aspromise@1.1.2': - resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} - - '@protobufjs/base64@1.1.2': - resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} - - '@protobufjs/codegen@2.0.4': - resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} - - '@protobufjs/eventemitter@1.1.0': - resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} - - '@protobufjs/fetch@1.1.0': - resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} - - '@protobufjs/float@1.0.2': - resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} - - '@protobufjs/inquire@1.1.0': - resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} - - '@protobufjs/path@1.1.2': - resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} - - '@protobufjs/pool@1.1.0': - resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} - - '@protobufjs/utf8@1.1.0': - resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} - '@radix-ui/number@1.0.1': resolution: {integrity: sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==} @@ -2027,9 +1956,6 @@ packages: '@scure/base@1.1.5': resolution: {integrity: sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==} - '@scure/bip39@1.2.2': - resolution: {integrity: sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA==} - '@simplewebauthn/browser@13.3.0': resolution: {integrity: sha512-BE/UWv6FOToAdVk0EokzkqQQDOWtNydYlY6+OrmiZ5SCNmb41VehttboTetUM3T/fr6EAFYVXjz4My2wg230rQ==} @@ -2042,10 +1968,6 @@ packages: '@sinclair/typebox@0.32.27': resolution: {integrity: sha512-JHRrubCKiXi6VKlbBTpTQnExkUFasPMIaXCJYJhqVBGLliQVt1yBZZgiZo3/uSmvAdXlIIdGoTAT6RB09L0QqA==} - '@storacha/one-webcrypto@https://codeload.github.com/web3-storage/one-webcrypto/tar.gz/9e029e2fd477bd95bb80abd3553bbac704ccc7a6': - resolution: {tarball: https://codeload.github.com/web3-storage/one-webcrypto/tar.gz/9e029e2fd477bd95bb80abd3553bbac704ccc7a6} - version: 1.0.1 - '@swc/core-darwin-arm64@1.4.17': resolution: {integrity: sha512-HVl+W4LezoqHBAYg2JCqR+s9ife9yPfgWSj37iIawLWzOmuuJ7jVdIB7Ee2B75bEisSEKyxRlTl6Y1Oq3owBgw==} engines: {node: '>=10'} @@ -2213,9 +2135,6 @@ packages: '@types/mdx@2.0.13': resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} - '@types/minimatch@3.0.5': - resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} - '@types/ms@0.7.34': resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} @@ -2237,9 +2156,6 @@ packages: '@types/react@18.3.1': resolution: {integrity: sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==} - '@types/retry@0.12.1': - resolution: {integrity: sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==} - '@types/unist@2.0.10': resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==} @@ -2277,24 +2193,6 @@ packages: resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} engines: {node: ^16.0.0 || >=18.0.0} - '@ucanto/client@9.0.1': - resolution: {integrity: sha512-cV8w3AnaZaYCdUmyFFICj8YhFckDoy2DvWgAzGDMkPz0WbUW4lw9Tjm4hEE8x5kiP47wYej/pHKWCcoELiU0qw==} - - '@ucanto/core@10.0.1': - resolution: {integrity: sha512-1BfUaJu0/c9Rl/WdZSDbScJJLsPsPe1g4ynl5kubUj3xDD/lyp/Q12PQVQ2X7hDiWwkpwmxCkRMkOxwc70iNKQ==} - - '@ucanto/interface@10.0.1': - resolution: {integrity: sha512-+Vr/N4mLsdynV9/bqtdFiq7WsUf3265/Qx2aHJmPtXo9/QvWKthJtpe0g8U4NWkWpVfqIFvyAO2db6D9zWQfQw==} - - '@ucanto/principal@9.0.1': - resolution: {integrity: sha512-8eAvaZHW1vyET4X90rkJv6pmW1IOdEYlZYwO3wDgTkC5m9VytBEywCvpzP57cavdYIbbPse5QS9nMEGvk87zhw==} - - '@ucanto/transport@9.1.1': - resolution: {integrity: sha512-3CR17nEemOVaTuMZa6waWgVL4sLxSPcxYvpaNeJ6NZo1rfsqdyRXOtbVV/RcI2BtUL0Cao6JM6P9+gdghfc5ng==} - - '@ucanto/validator@9.0.2': - resolution: {integrity: sha512-LxhRbDMIoLt9LYHq/Rz1WCEH8AtmdsBTS/it28Ij/A3W0zyoSwUpAUxBtXaKRh/gpbxdWmjxX+nVfFJYL//b4g==} - '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} @@ -2374,39 +2272,6 @@ packages: '@vitest/utils@0.34.6': resolution: {integrity: sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==} - '@web3-storage/access@20.0.0': - resolution: {integrity: sha512-kl2b3ZuN3NvAxDM6K8GlPgu1o67JtA3EGId8Bg+tFRqZiQlERQmMMOfLl8zKVOUvlq4bDFtWHl6EViLO4BwSJw==} - - '@web3-storage/blob-index@1.0.3': - resolution: {integrity: sha512-VjGLhf6Gf4ZmzjJXS6wU4aRvnM+HLcuRCJHegjQ36ka52sR2WWOcqDNNVvabtlpnYjGtVFQCPUzaCcs18wpqHQ==} - engines: {node: '>=16.15'} - - '@web3-storage/capabilities@16.0.0': - resolution: {integrity: sha512-wCjLpYc6t8tFRZrF2k2vBteJDWzHkmQjoJG0Yy/fjA04IjNN48iVZaCMQIANHXZxDGlYRGxhwzDwl4dovAdSTQ==} - - '@web3-storage/capabilities@17.2.0': - resolution: {integrity: sha512-hnJGIQcCAMBbR8sfgkEwnjBVcpNpNRBnzSEB2E/wKkKIjHKimw3ClsVznu6jjFExCXFaKHd6r1eAU4NcTYsueg==} - - '@web3-storage/data-segment@3.2.0': - resolution: {integrity: sha512-SM6eNumXzrXiQE2/J59+eEgCRZNYPxKhRoHX2QvV3/scD4qgcf4g+paWBc3UriLEY1rCboygGoPsnqYJNyZyfA==} - - '@web3-storage/data-segment@5.1.0': - resolution: {integrity: sha512-FYdmtKvNiVz+maZ++k4PdD43rfJW5DeagLpstq2y84CyOKNRBWbHLCZ/Ec5zT9iGI+0WgsCGbpC/WlG0jlrnhA==} - - '@web3-storage/did-mailto@2.1.0': - resolution: {integrity: sha512-TRmfSXj1IhtX3ESurSNOylZSBKi0z/VJNoMLpof+AVRdovgZjjocpiePQTs2pfHKqHTHfJXc9AboWyK4IKTWMw==} - engines: {node: '>=16.15'} - - '@web3-storage/filecoin-client@3.3.3': - resolution: {integrity: sha512-xFL8odr5PpTjQvpfw/4jphcm7ZvcBRMSKHn3ReEaVcFjxQL45Rojjleuq/QEdMwrNfsLCqqAxC54jk55o5/ERQ==} - - '@web3-storage/upload-client@16.1.1': - resolution: {integrity: sha512-aVGpcqnLxRk4u3uZAum1jwC5BbEbjuqAZZBrGNZ3UZVFnnJJXPm3DE+r1WC8FV2mbgC/yKKqDMu1FP1uB9wJkA==} - - '@web3-storage/w3up-client@15.0.0': - resolution: {integrity: sha512-XEzfHgn4NVS212xXH+BRlFzMFoB+TaAeQHLrrW9zoWlPnKJJphdKE2hVJZBPovIU5HWSPNsNM4mdkowYEQ73OQ==} - engines: {node: '>=18'} - '@webassemblyjs/ast@1.11.6': resolution: {integrity: sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==} @@ -2495,21 +2360,10 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - actor@2.3.1: - resolution: {integrity: sha512-ST/3wnvcP2tKDXnum7nLCLXm+/rsf8vPocXH2Fre6D8FQwNkGDd4JEitBlXj007VQJfiGYRQvXqwOBZVi+JtRg==} - agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} - ajv-formats@2.1.1: - resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} - peerDependencies: - ajv: ^8.0.0 - peerDependenciesMeta: - ajv: - optional: true - ajv-keywords@3.5.2: resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} peerDependencies: @@ -2518,9 +2372,6 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - ajv@8.12.0: - resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} - ajv@8.6.3: resolution: {integrity: sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==} @@ -2551,9 +2402,6 @@ packages: any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - any-signal@3.0.1: - resolution: {integrity: sha512-xgZgJtKEa9YmDqXodIgl7Fl1C8yNXr8w6gXjqK3LW4GcEiYT+6AQfJSE/8SPsEpLLmcvbv8YU+qet94UewHxqg==} - anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} @@ -2661,9 +2509,6 @@ packages: asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - atomically@2.0.2: - resolution: {integrity: sha512-Xfmb4q5QV7uqTlVdMSTtO5eF4DCHfNOdaPyKlbFShkzeNP+3lj3yjjcbdjSmEY4+pDBKJ9g26aP+ImTe88UHoQ==} - attr-accept@2.2.2: resolution: {integrity: sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==} engines: {node: '>=4'} @@ -2715,10 +2560,6 @@ packages: bech32@2.0.0: resolution: {integrity: sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==} - bigint-mod-arith@3.3.1: - resolution: {integrity: sha512-pX/cYW3dCa87Jrzv6DAr8ivbbJRzEX5yGhdt8IutnX/PCIXfpx+mabWNK/M8qqh+zQ0J3thftUBHW0ByuUlG0w==} - engines: {node: '>=10.4.0'} - bignumber.js@9.3.1: resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} @@ -2757,9 +2598,6 @@ packages: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} - browser-readablestream-to-it@1.0.3: - resolution: {integrity: sha512-+12sHB+Br8HIh6VAMVEG5r3UXCyESIgDW7kzk3BjIXa43DVqVwL7GC5TW3jeh+72dtcH99pPVpw0X8i0jt+/kw==} - browserslist@4.23.0: resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -2816,9 +2654,6 @@ packages: caniuse-lite@1.0.30001612: resolution: {integrity: sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==} - carstream@2.2.0: - resolution: {integrity: sha512-/gHkK0lQjmGM45fhdx8JD+x7a1XS1qUk3T9xWWSt3oZiWPLq4u/lnDstp+N55K7hqTKKlb0CCr43EHTrlbmJSQ==} - cbor@10.0.12: resolution: {integrity: sha512-exQDevYd7ZQLP4moMQcZkKCVZsXLAtUSflObr3xTh4xzFIv/xBCdvCd6L259kQOUP2kcTC0jvC6PpZIf/WmRXA==} engines: {node: '>=20'} @@ -2958,10 +2793,6 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - conf@11.0.2: - resolution: {integrity: sha512-jjyhlQ0ew/iwmtwsS2RaB6s8DBifcE2GYBEaw2SJDUY/slJJbNfY4GlDVzOs/ff8cM/Wua5CikqXgbFl5eu85A==} - engines: {node: '>=14.16'} - console-control-strings@1.1.0: resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} @@ -3049,10 +2880,6 @@ packages: date-fns@3.6.0: resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} - debounce-fn@5.1.2: - resolution: {integrity: sha512-Sr4SdOZ4vw6eQDvPYNxHogvrxmCIld/VenC5JbNrFwMiwd7lY/Z18ZFfo+EWNG4DD9nFlAujWAo/wGuOPHmy5A==} - engines: {node: '>=12'} - debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -3169,10 +2996,6 @@ packages: domutils@2.8.0: resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} - dot-prop@7.2.0: - resolution: {integrity: sha512-Ol/IPXUARn9CSbkrdV4VJo7uCy1I3VuSiWCaFSg+8BdUOzF9n3jefIpcgAydvUZbTdEBZs2vEiTiS9m61ssiDA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dotenv-expand@5.1.0: resolution: {integrity: sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==} @@ -3192,10 +3015,6 @@ packages: engines: {node: '>=16'} hasBin: true - electron-fetch@1.9.1: - resolution: {integrity: sha512-M9qw6oUILGVrcENMSRRefE1MbHPIz0h79EKIeJWK9v563aT9Qkh8aEHPO1H5vi970wPirNY+jO9OpFoLiMsMGA==} - engines: {node: '>=6'} - electron-to-chromium@1.4.673: resolution: {integrity: sha512-zjqzx4N7xGdl5468G+vcgzDhaHkaYgVcf9MqgexcTqsl2UHSCmOj/Bi3HAprg4BZCpC7HyD8a6nZl6QAZf72gw==} @@ -3229,13 +3048,6 @@ packages: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} - env-paths@3.0.0: - resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - err-code@3.0.1: - resolution: {integrity: sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==} - error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} @@ -3600,9 +3412,6 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-fifo@1.3.2: - resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} - fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} @@ -3746,9 +3555,6 @@ packages: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} - get-iterator@1.0.2: - resolution: {integrity: sha512-v+dm9bNVfOYsY1OrhaCrmyOcYoSeVvbt+hHZ0Au+T+p1y+0Uyj9aMaGIeUTT6xdpRbWzDeYKvfOslPhggQMcsg==} - get-nonce@1.0.1: resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} engines: {node: '>=6'} @@ -3998,10 +3804,6 @@ packages: resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} engines: {node: '>= 12'} - ipfs-utils@9.0.14: - resolution: {integrity: sha512-zIaiEGX18QATxgaS0/EOQNoo33W0islREABAcxXE8n7y2MGAlB+hdsxXn4J0hGZge8IqVQhW8sWIb+oJz2yEvg==} - engines: {node: '>=16.0.0', npm: '>=7.0.0'} - is-alphabetical@2.0.1: resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} @@ -4055,9 +3857,6 @@ packages: is-decimal@2.0.1: resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} - is-electron@2.2.2: - resolution: {integrity: sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==} - is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -4102,10 +3901,6 @@ packages: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} - is-plain-obj@2.1.0: - resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} - engines: {node: '>=8'} - is-plain-obj@4.1.0: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} @@ -4174,15 +3969,6 @@ packages: peerDependencies: ws: '*' - it-all@1.0.6: - resolution: {integrity: sha512-3cmCc6Heqe3uWi3CVM/k51fa/XbMFpQVzFoDsV0IZNHSQDyAXl3c4MjHkFX5kF3922OGj7Myv1nSEUgRtcuM1A==} - - it-glob@1.0.2: - resolution: {integrity: sha512-Ch2Dzhw4URfB9L/0ZHyY+uqOnKvBNeS/SMcRiPmJfpHiM0TsUZn+GkpcZxAoF3dJVdPm/PuIk3A4wlV7SUo23Q==} - - it-to-stream@1.0.0: - resolution: {integrity: sha512-pLULMZMAB/+vbdvbZtebC0nWBTbG581lk6w8P7DfIIIKUfa8FbY7Oi0FxZcFPbxvISs7A9E+cMpLDBc1XhpAOA==} - iterator.prototype@1.1.2: resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} @@ -4231,9 +4017,6 @@ packages: json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - json-schema-typed@8.0.1: - resolution: {integrity: sha512-XQmWYj2Sm4kn4WeTYvmpKEbyPsL7nBsb647c7pMe6l02/yx2+Jfc4dT6UZkEXnIUb5LhD55r2HPsJ1milQ4rDg==} - json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -4386,9 +4169,6 @@ packages: lodash@4.18.1: resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} - long@5.2.3: - resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} - longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -4468,10 +4248,6 @@ packages: mdn-data@2.0.14: resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} - merge-options@3.0.4: - resolution: {integrity: sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==} - engines: {node: '>=10'} - merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -4584,10 +4360,6 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - min-document@2.19.2: resolution: {integrity: sha512-8S5I8db/uZN8r9HSLFVWPdJCvYOejMcEC82VIzNUc6Zkklf/d1gg2psfE79/vyhWOj4+J8MtwmoOz3TmvaGu5A==} @@ -4655,24 +4427,12 @@ packages: msgpackr@1.10.1: resolution: {integrity: sha512-r5VRLv9qouXuLiIBrLpl2d5ZvPt8svdQTl5/vMvE4nzDMyEX4sgW5yWhuBBj5UmgwOTWj8CIdSXn5sAfsHAWIQ==} - multiformats@11.0.2: - resolution: {integrity: sha512-b5mYMkOkARIuVZCpvijFj9a6m5wMVLC7cf/jIPd5D/ARDOfLC5+IFkbgDXQgcU2goIsTD/O9NY4DI/Mt4OGvlg==} - engines: {node: '>=16.0.0', npm: '>=7.0.0'} - - multiformats@12.1.3: - resolution: {integrity: sha512-eajQ/ZH7qXZQR2AgtfpmSMizQzmyYVmCql7pdhldPuYQi4atACekbJaQplk6dWyIi10jCaFnd6pqvcEFXjbaJw==} - engines: {node: '>=16.0.0', npm: '>=7.0.0'} - multiformats@13.1.0: resolution: {integrity: sha512-HzdtdBwxsIkzpeXzhQ5mAhhuxcHbjEHH+JQoxt7hG/2HGFjjwyolLo7hbaexcnhoEuV4e0TNJ8kkpMjiEYY4VQ==} multiformats@14.0.5: resolution: {integrity: sha512-vbIm83F2yZ1pWJGS0yl0ysracIvv56LtbrIyiIQHoLdYDJOMoLfVFsXhh9DUH4SFdkdkFhucyWniihsNzVEjkQ==} - murmurhash3js-revisited@3.0.0: - resolution: {integrity: sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g==} - engines: {node: '>=8.0.0'} - mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} @@ -4687,11 +4447,6 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - native-fetch@3.0.0: - resolution: {integrity: sha512-G3Z7vx0IFb/FQ4JxvtqGABsOTIqRWvgQz6e+erkB+JJD6LrszQtMozEHI4EkmgZQvnGHrpLVzUWk7t4sJCIkVw==} - peerDependencies: - node-fetch: '*' - natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -4851,9 +4606,6 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - one-webcrypto@1.0.3: - resolution: {integrity: sha512-fu9ywBVBPx0gS9K0etIROTiCkvI5S1TDjFsYFb3rC1ewFxeOqsbzq7aIMBHsYfrTHBcGXJaONXXjTl8B01cW1Q==} - onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} @@ -4869,17 +4621,6 @@ packages: resolution: {integrity: sha512-wrAwOeXp1RRMFfQY8Sy7VaGVmPocaLwSFOYCGKSyo8qmJ+/yaafCl5BCA1IQZWqFSRBrKDYFeR9d/VyQzfH/jg==} engines: {node: '>= 6.0'} - p-defer@3.0.0: - resolution: {integrity: sha512-ugZxsxmtTln604yeYd29EGrNhazN2lywetzpKhfmQjW/VJmhpDmWbiX+h0zL8V91R0UXkhb3KtPmyq9PZw3aYw==} - engines: {node: '>=8'} - - p-defer@4.0.0: - resolution: {integrity: sha512-Vb3QRvQ0Y5XnF40ZUWW7JfLogicVh/EnA5gBIvKDJoYpeI82+1E3AlB9yOcKFS0AhHrWVnAQO39fbR0G99IVEQ==} - engines: {node: '>=12'} - - p-fifo@1.0.0: - resolution: {integrity: sha512-IjoCxXW48tqdtDFz6fqo5q1UfFVjjVZe8TC1QRflvNUJtNfCUhxOUw6MOVZhDPjqhSzc26xKdugsO17gmzd5+A==} - p-finally@2.0.1: resolution: {integrity: sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==} engines: {node: '>=8'} @@ -4900,10 +4641,6 @@ packages: resolution: {integrity: sha512-NXAOdnEe5FsZJfT4oK84lE1Y5cFFdWlRuOo5tww8DyNMxyRXwn39fIkUtNLKppcPC+UYU/bXujNCUGDv01y7CA==} engines: {node: '>=20'} - p-retry@5.1.2: - resolution: {integrity: sha512-couX95waDu98NfNZV+i/iLt+fdVxmI7CbrrdC2uDWfPdUAApyxT4wmDlyOtR5KtTDmkDO0zDScDjDou9YHhd9g==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - p-timeout@7.0.1: resolution: {integrity: sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==} engines: {node: '>=20'} @@ -4993,6 +4730,18 @@ packages: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} + pinata@2.5.6: + resolution: {integrity: sha512-bsM+0nvbE9Wk5SUpR6RKg2IBeJpe6yMrKrytbEF7CMQ3bjowWDC5DxzIL0fHQSOZCgb3rDnDt0gVJqz3COI5vQ==} + engines: {node: '>=20'} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} @@ -5154,10 +4903,6 @@ packages: property-information@6.4.1: resolution: {integrity: sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w==} - protobufjs@7.2.6: - resolution: {integrity: sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==} - engines: {node: '>=12.0.0'} - proxy-from-env@2.1.0: resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} engines: {node: '>=10'} @@ -5179,9 +4924,6 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - rabin-rs@2.1.0: - resolution: {integrity: sha512-5y72gAXPzIBsAMHcpxZP8eMDuDT98qMP1BqSDHRbHkJJXEgWIN1lA47LxUqzsK6jknOJtgfkQr9v+7qMlFDm6g==} - randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} @@ -5228,9 +4970,6 @@ packages: react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - react-native-fetch-api@3.0.0: - resolution: {integrity: sha512-g2rtqPjdroaboDKTsJCTlcmtw54E25OjyaunUP0anOZn4Fuo2IKs8BVfe02zVggA/UysbmfSnRJIqtNkAgggNA==} - react-refresh@0.9.0: resolution: {integrity: sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ==} engines: {node: '>=0.10.0'} @@ -5337,10 +5076,6 @@ packages: resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} hasBin: true - retry@0.13.1: - resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} - engines: {node: '>= 4'} - reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -5535,9 +5270,6 @@ packages: stream-to-array@2.3.0: resolution: {integrity: sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA==} - stream-to-it@0.2.4: - resolution: {integrity: sha512-4vEbkSs83OahpmBybNJXlJd7d6/RxzkkSdT3I0mnGt79Xd2Kk+e1JqbvAvsQfCeKj3aKb0QIWkyK3/n0j506vQ==} - stream-to-promise@2.2.0: resolution: {integrity: sha512-HAGUASw8NT0k8JvIVutB2Y/9iBk7gpgEyAudXwNJmZERdMITGdajOa4VJfD/kNiA3TppQpTP4J+CtcHwdzKBAw==} @@ -5612,9 +5344,6 @@ packages: strip-literal@1.3.0: resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} - stubborn-fs@1.2.5: - resolution: {integrity: sha512-H2N9c26eXjzL/S/K+i/RHHcFanE74dptvvjM8iwzwbVcWY/zjBbgRqF3K0DY4+OD+uTTASTBvDoxPDaPN02D7g==} - style-to-object@0.4.4: resolution: {integrity: sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==} @@ -5660,9 +5389,6 @@ packages: engines: {node: '>=10.13.0'} hasBin: true - sync-multihash-sha2@1.0.0: - resolution: {integrity: sha512-A5gVpmtKF0ov+/XID0M0QRJqF2QxAsj3x/LlDC8yivzgoYCoWkV+XaZPfVu7Vj1T/hYzYS1tfjwboSbXjqocug==} - tailwind-merge@2.3.0: resolution: {integrity: sha512-vkYrLpIP+lgR0tQCG6AP7zZXCTLc1Lnv/CCRT3BqJ9CZ3ui2++GPaGb1x/ILsINIMSYqqvrpqjUFsMNLlW99EA==} @@ -5824,14 +5550,6 @@ packages: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} - type-fest@2.19.0: - resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} - engines: {node: '>=12.20'} - - type-fest@4.11.1: - resolution: {integrity: sha512-MFMf6VkEVZAETidGGSYW2B1MjXbGX+sWIywn2QPEaJ3j08V+MwVRHMXtf2noB8ENJaD0LIun9wh5Z6OPNf1QzQ==} - engines: {node: '>=16'} - typed-array-buffer@1.0.2: resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} @@ -5893,9 +5611,6 @@ packages: uint8arraylist@3.0.2: resolution: {integrity: sha512-LDVoq9BQaGJzGDUovEnoX6rpKCvnY/Jbtws4ikwnBzjRbq5qBAFpBZevUEbSmMM87aO0Sp+wOZy2ZXf5yODmXQ==} - uint8arrays@4.0.10: - resolution: {integrity: sha512-AnJNUGGDJAgFw/eWu/Xb9zrVKEGlwJJCaeInlf3BkecE/zcTobk5YXYIPNQJO1q5Hh1QZrQQHf0JvcHqz2hqoA==} - uint8arrays@5.0.3: resolution: {integrity: sha512-6LBuKji28kHjgPJMkQ6GDaBb1lRwIhyOYq6pDGwYMoDPfImE9SkuYENVmR0yu9yGgs2clHUSY9fKDukR+AXfqQ==} @@ -6011,9 +5726,6 @@ packages: valibot@0.31.1: resolution: {integrity: sha512-2YYIhPrnVSz/gfT2/iXVTrSj92HwchCt9Cga/6hX4B26iCz9zkIsGTS0HjDYTZfTi1Un0X6aRvhBi1cfqs/i0Q==} - varint@6.0.0: - resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==} - vaul@0.9.0: resolution: {integrity: sha512-bZSySGbAHiTXmZychprnX/dE0EsSige88xtyyL3/MCRbrFotRPQZo7UdydGXZWw+CKbNOw5Ow8gwAo93/nB/Cg==} peerDependencies: @@ -6138,9 +5850,6 @@ packages: whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - when-exit@2.1.2: - resolution: {integrity: sha512-u9J+toaf3CCxCAzM/484qNAxQE75rFdVgiFEEV8Xps2gzYhf0tx73s1WXDQhkwV17E3MxRMz40m7Ekd2/121Lg==} - which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} @@ -6890,43 +6599,6 @@ snapshots: '@img/sharp-win32-x64@0.33.3': optional: true - '@ipld/car@5.3.0': - dependencies: - '@ipld/dag-cbor': 9.2.0 - cborg: 4.2.0 - multiformats: 13.1.0 - varint: 6.0.0 - - '@ipld/dag-cbor@9.2.0': - dependencies: - cborg: 4.2.0 - multiformats: 13.1.0 - - '@ipld/dag-json@10.2.0': - dependencies: - cborg: 4.2.0 - multiformats: 13.1.0 - - '@ipld/dag-pb@4.1.0': - dependencies: - multiformats: 13.1.0 - - '@ipld/dag-ucan@3.4.0': - dependencies: - '@ipld/dag-cbor': 9.2.0 - '@ipld/dag-json': 10.2.0 - multiformats: 11.0.2 - - '@ipld/unixfs@2.2.0': - dependencies: - '@ipld/dag-pb': 4.1.0 - '@multiformats/murmur3': 2.1.8 - '@perma/map': 1.0.3 - actor: 2.3.1 - multiformats: 11.0.2 - protobufjs: 7.2.6 - rabin-rs: 2.1.0 - '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -7293,11 +6965,6 @@ snapshots: uint8-varint: 3.0.0 uint8arrays: 6.1.1 - '@multiformats/murmur3@2.1.8': - dependencies: - multiformats: 13.1.0 - murmurhash3js-revisited: 3.0.0 - '@next/env@14.1.0': {} '@next/eslint-plugin-next@14.2.3': @@ -7338,12 +7005,6 @@ snapshots: '@next/swc-win32-x64-msvc@14.1.0': optional: true - '@noble/curves@1.3.0': - dependencies: - '@noble/hashes': 1.3.3 - - '@noble/ed25519@1.7.3': {} - '@noble/hashes@1.3.3': {} '@nodelib/fs.scandir@2.1.5': @@ -7979,37 +7640,9 @@ snapshots: tslib: 2.6.2 webcrypto-core: 1.7.9 - '@perma/map@1.0.3': - dependencies: - '@multiformats/murmur3': 2.1.8 - murmurhash3js-revisited: 3.0.0 - '@pkgjs/parseargs@0.11.0': optional: true - '@protobufjs/aspromise@1.1.2': {} - - '@protobufjs/base64@1.1.2': {} - - '@protobufjs/codegen@2.0.4': {} - - '@protobufjs/eventemitter@1.1.0': {} - - '@protobufjs/fetch@1.1.0': - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/inquire': 1.1.0 - - '@protobufjs/float@1.0.2': {} - - '@protobufjs/inquire@1.1.0': {} - - '@protobufjs/path@1.1.2': {} - - '@protobufjs/pool@1.1.0': {} - - '@protobufjs/utf8@1.1.0': {} - '@radix-ui/number@1.0.1': dependencies: '@babel/runtime': 7.23.9 @@ -8539,11 +8172,6 @@ snapshots: '@scure/base@1.1.5': {} - '@scure/bip39@1.2.2': - dependencies: - '@noble/hashes': 1.3.3 - '@scure/base': 1.1.5 - '@simplewebauthn/browser@13.3.0': {} '@sinclair/typebox@0.25.24': {} @@ -8552,8 +8180,6 @@ snapshots: '@sinclair/typebox@0.32.27': {} - '@storacha/one-webcrypto@https://codeload.github.com/web3-storage/one-webcrypto/tar.gz/9e029e2fd477bd95bb80abd3553bbac704ccc7a6': {} - '@swc/core-darwin-arm64@1.4.17': optional: true @@ -8700,8 +8326,6 @@ snapshots: '@types/mdx@2.0.13': {} - '@types/minimatch@3.0.5': {} - '@types/ms@0.7.34': {} '@types/node@14.18.33': {} @@ -8725,8 +8349,6 @@ snapshots: '@types/prop-types': 15.7.11 csstype: 3.1.3 - '@types/retry@0.12.1': {} - '@types/unist@2.0.10': {} '@types/unist@3.0.2': {} @@ -8771,47 +8393,6 @@ snapshots: '@typescript-eslint/types': 6.21.0 eslint-visitor-keys: 3.4.3 - '@ucanto/client@9.0.1': - dependencies: - '@ucanto/core': 10.0.1 - '@ucanto/interface': 10.0.1 - - '@ucanto/core@10.0.1': - dependencies: - '@ipld/car': 5.3.0 - '@ipld/dag-cbor': 9.2.0 - '@ipld/dag-ucan': 3.4.0 - '@ucanto/interface': 10.0.1 - multiformats: 11.0.2 - - '@ucanto/interface@10.0.1': - dependencies: - '@ipld/dag-ucan': 3.4.0 - multiformats: 11.0.2 - - '@ucanto/principal@9.0.1': - dependencies: - '@ipld/dag-ucan': 3.4.0 - '@noble/curves': 1.3.0 - '@noble/ed25519': 1.7.3 - '@noble/hashes': 1.3.3 - '@ucanto/interface': 10.0.1 - multiformats: 11.0.2 - one-webcrypto: 1.0.3 - - '@ucanto/transport@9.1.1': - dependencies: - '@ucanto/core': 10.0.1 - '@ucanto/interface': 10.0.1 - - '@ucanto/validator@9.0.2': - dependencies: - '@ipld/car': 5.3.0 - '@ipld/dag-cbor': 9.2.0 - '@ucanto/core': 10.0.1 - '@ucanto/interface': 10.0.1 - multiformats: 11.0.2 - '@ungap/structured-clone@1.2.0': {} '@utxorpc/sdk@0.6.8(@bufbuild/protobuf@1.10.1)': @@ -9001,118 +8582,6 @@ snapshots: loupe: 2.3.7 pretty-format: 29.7.0 - '@web3-storage/access@20.0.0': - dependencies: - '@ipld/car': 5.3.0 - '@ipld/dag-ucan': 3.4.0 - '@scure/bip39': 1.2.2 - '@ucanto/client': 9.0.1 - '@ucanto/core': 10.0.1 - '@ucanto/interface': 10.0.1 - '@ucanto/principal': 9.0.1 - '@ucanto/transport': 9.1.1 - '@ucanto/validator': 9.0.2 - '@web3-storage/capabilities': 17.2.0 - '@web3-storage/did-mailto': 2.1.0 - bigint-mod-arith: 3.3.1 - conf: 11.0.2 - multiformats: 12.1.3 - one-webcrypto: '@storacha/one-webcrypto@https://codeload.github.com/web3-storage/one-webcrypto/tar.gz/9e029e2fd477bd95bb80abd3553bbac704ccc7a6' - p-defer: 4.0.0 - type-fest: 4.11.1 - uint8arrays: 4.0.10 - - '@web3-storage/blob-index@1.0.3': - dependencies: - '@ipld/dag-cbor': 9.2.0 - '@ucanto/core': 10.0.1 - '@ucanto/interface': 10.0.1 - '@web3-storage/capabilities': 17.2.0 - carstream: 2.2.0 - multiformats: 13.1.0 - uint8arrays: 5.0.3 - - '@web3-storage/capabilities@16.0.0': - dependencies: - '@ucanto/core': 10.0.1 - '@ucanto/interface': 10.0.1 - '@ucanto/principal': 9.0.1 - '@ucanto/transport': 9.1.1 - '@ucanto/validator': 9.0.2 - '@web3-storage/data-segment': 3.2.0 - uint8arrays: 5.0.3 - - '@web3-storage/capabilities@17.2.0': - dependencies: - '@ucanto/core': 10.0.1 - '@ucanto/interface': 10.0.1 - '@ucanto/principal': 9.0.1 - '@ucanto/transport': 9.1.1 - '@ucanto/validator': 9.0.2 - '@web3-storage/data-segment': 3.2.0 - uint8arrays: 5.0.3 - - '@web3-storage/data-segment@3.2.0': - dependencies: - '@ipld/dag-cbor': 9.2.0 - multiformats: 11.0.2 - sync-multihash-sha2: 1.0.0 - - '@web3-storage/data-segment@5.1.0': - dependencies: - '@ipld/dag-cbor': 9.2.0 - multiformats: 11.0.2 - sync-multihash-sha2: 1.0.0 - - '@web3-storage/did-mailto@2.1.0': {} - - '@web3-storage/filecoin-client@3.3.3': - dependencies: - '@ipld/dag-ucan': 3.4.0 - '@ucanto/client': 9.0.1 - '@ucanto/core': 10.0.1 - '@ucanto/interface': 10.0.1 - '@ucanto/transport': 9.1.1 - '@web3-storage/capabilities': 16.0.0 - - '@web3-storage/upload-client@16.1.1(encoding@0.1.13)': - dependencies: - '@ipld/car': 5.3.0 - '@ipld/dag-cbor': 9.2.0 - '@ipld/dag-ucan': 3.4.0 - '@ipld/unixfs': 2.2.0 - '@ucanto/client': 9.0.1 - '@ucanto/core': 10.0.1 - '@ucanto/interface': 10.0.1 - '@ucanto/transport': 9.1.1 - '@web3-storage/blob-index': 1.0.3 - '@web3-storage/capabilities': 17.2.0 - '@web3-storage/data-segment': 5.1.0 - '@web3-storage/filecoin-client': 3.3.3 - ipfs-utils: 9.0.14(encoding@0.1.13) - multiformats: 12.1.3 - p-retry: 5.1.2 - varint: 6.0.0 - transitivePeerDependencies: - - encoding - - '@web3-storage/w3up-client@15.0.0(encoding@0.1.13)': - dependencies: - '@ipld/dag-ucan': 3.4.0 - '@ucanto/client': 9.0.1 - '@ucanto/core': 10.0.1 - '@ucanto/interface': 10.0.1 - '@ucanto/principal': 9.0.1 - '@ucanto/transport': 9.1.1 - '@web3-storage/access': 20.0.0 - '@web3-storage/blob-index': 1.0.3 - '@web3-storage/capabilities': 17.2.0 - '@web3-storage/did-mailto': 2.1.0 - '@web3-storage/filecoin-client': 3.3.3 - '@web3-storage/upload-client': 16.1.1(encoding@0.1.13) - transitivePeerDependencies: - - encoding - '@webassemblyjs/ast@1.11.6': dependencies: '@webassemblyjs/helper-numbers': 1.11.6 @@ -9218,18 +8687,12 @@ snapshots: acorn@8.11.3: {} - actor@2.3.1: {} - agent-base@6.0.2: dependencies: debug: 4.3.4 transitivePeerDependencies: - supports-color - ajv-formats@2.1.1(ajv@8.12.0): - optionalDependencies: - ajv: 8.12.0 - ajv-keywords@3.5.2(ajv@6.12.6): dependencies: ajv: 6.12.6 @@ -9241,13 +8704,6 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 - ajv@8.12.0: - dependencies: - fast-deep-equal: 3.1.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - uri-js: 4.4.1 - ajv@8.6.3: dependencies: fast-deep-equal: 3.1.3 @@ -9273,8 +8729,6 @@ snapshots: any-promise@1.3.0: {} - any-signal@3.0.1: {} - anymatch@3.1.3: dependencies: normalize-path: 3.0.0 @@ -9409,11 +8863,6 @@ snapshots: asynckit@0.4.0: {} - atomically@2.0.2: - dependencies: - stubborn-fs: 1.2.5 - when-exit: 2.1.2 - attr-accept@2.2.2: {} autoprefixer@10.4.19(postcss@8.4.38): @@ -9462,8 +8911,6 @@ snapshots: bech32@2.0.0: {} - bigint-mod-arith@3.3.1: {} - bignumber.js@9.3.1: {} binary-extensions@2.2.0: {} @@ -9509,8 +8956,6 @@ snapshots: dependencies: fill-range: 7.0.1 - browser-readablestream-to-it@1.0.3: {} - browserslist@4.23.0: dependencies: caniuse-lite: 1.0.30001587 @@ -9568,12 +9013,6 @@ snapshots: caniuse-lite@1.0.30001612: {} - carstream@2.2.0: - dependencies: - '@ipld/dag-cbor': 9.2.0 - multiformats: 13.1.0 - uint8arraylist: 2.4.8 - cbor@10.0.12: dependencies: nofilter: 3.1.0 @@ -9721,17 +9160,6 @@ snapshots: concat-map@0.0.1: {} - conf@11.0.2: - dependencies: - ajv: 8.12.0 - ajv-formats: 2.1.1(ajv@8.12.0) - atomically: 2.0.2 - debounce-fn: 5.1.2 - dot-prop: 7.2.0 - env-paths: 3.0.0 - json-schema-typed: 8.0.1 - semver: 7.6.0 - console-control-strings@1.1.0: {} content-type@1.0.4: {} @@ -9829,10 +9257,6 @@ snapshots: date-fns@3.6.0: {} - debounce-fn@5.1.2: - dependencies: - mimic-fn: 4.0.0 - debug@3.2.7: dependencies: ms: 2.1.2 @@ -9925,10 +9349,6 @@ snapshots: domelementtype: 2.3.0 domhandler: 4.3.1 - dot-prop@7.2.0: - dependencies: - type-fest: 2.19.0 - dotenv-expand@5.1.0: {} dotenv@7.0.0: {} @@ -9953,10 +9373,6 @@ snapshots: signal-exit: 4.0.2 time-span: 4.0.0 - electron-fetch@1.9.1: - dependencies: - encoding: 0.1.13 - electron-to-chromium@1.4.673: {} emoji-regex@8.0.0: {} @@ -9966,6 +9382,7 @@ snapshots: encoding@0.1.13: dependencies: iconv-lite: 0.6.3 + optional: true end-of-stream@1.1.0: dependencies: @@ -9986,10 +9403,6 @@ snapshots: env-paths@2.2.1: {} - env-paths@3.0.0: {} - - err-code@3.0.1: {} - error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 @@ -10530,8 +9943,6 @@ snapshots: fast-deep-equal@3.1.3: {} - fast-fifo@1.3.2: {} - fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -10693,8 +10104,6 @@ snapshots: hasown: 2.0.4 math-intrinsics: 1.1.0 - get-iterator@1.0.2: {} - get-nonce@1.0.1: {} get-port@4.2.0: {} @@ -10926,6 +10335,7 @@ snapshots: iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 + optional: true ieee754@1.2.1: {} @@ -10968,27 +10378,6 @@ snapshots: jsbn: 1.1.0 sprintf-js: 1.1.3 - ipfs-utils@9.0.14(encoding@0.1.13): - dependencies: - any-signal: 3.0.1 - browser-readablestream-to-it: 1.0.3 - buffer: 6.0.3 - electron-fetch: 1.9.1 - err-code: 3.0.1 - is-electron: 2.2.2 - iso-url: 1.2.1 - it-all: 1.0.6 - it-glob: 1.0.2 - it-to-stream: 1.0.0 - merge-options: 3.0.4 - nanoid: 3.3.7 - native-fetch: 3.0.0(node-fetch@2.7.0(encoding@0.1.13)) - node-fetch: 2.7.0(encoding@0.1.13) - react-native-fetch-api: 3.0.0 - stream-to-it: 0.2.4 - transitivePeerDependencies: - - encoding - is-alphabetical@2.0.1: {} is-alphanumerical@2.0.1: @@ -11043,8 +10432,6 @@ snapshots: is-decimal@2.0.1: {} - is-electron@2.2.2: {} - is-extglob@2.1.1: {} is-finalizationregistry@1.0.2: @@ -11077,8 +10464,6 @@ snapshots: is-path-inside@3.0.3: {} - is-plain-obj@2.1.0: {} - is-plain-obj@4.1.0: {} is-reference@3.0.2: @@ -11139,22 +10524,6 @@ snapshots: dependencies: ws: 7.5.13 - it-all@1.0.6: {} - - it-glob@1.0.2: - dependencies: - '@types/minimatch': 3.0.5 - minimatch: 3.1.2 - - it-to-stream@1.0.0: - dependencies: - buffer: 6.0.3 - fast-fifo: 1.3.2 - get-iterator: 1.0.2 - p-defer: 3.0.0 - p-fifo: 1.0.0 - readable-stream: 3.6.2 - iterator.prototype@1.1.2: dependencies: define-properties: 1.2.1 @@ -11204,8 +10573,6 @@ snapshots: json-schema-traverse@1.0.0: {} - json-schema-typed@8.0.1: {} - json-stable-stringify-without-jsonify@1.0.1: {} json5@1.0.2: @@ -11340,8 +10707,6 @@ snapshots: lodash@4.18.1: {} - long@5.2.3: {} - longest-streak@3.1.0: {} loose-envify@1.4.0: @@ -11487,10 +10852,6 @@ snapshots: mdn-data@2.0.14: {} - merge-options@3.0.4: - dependencies: - is-plain-obj: 2.1.0 - merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -11720,8 +11081,6 @@ snapshots: mimic-fn@2.1.0: {} - mimic-fn@4.0.0: {} - min-document@2.19.2: dependencies: dom-walk: 0.1.2 @@ -11795,16 +11154,10 @@ snapshots: optionalDependencies: msgpackr-extract: 3.0.2 - multiformats@11.0.2: {} - - multiformats@12.1.3: {} - multiformats@13.1.0: {} multiformats@14.0.5: {} - murmurhash3js-revisited@3.0.0: {} - mz@2.7.0: dependencies: any-promise: 1.3.0 @@ -11818,10 +11171,6 @@ snapshots: nanoid@3.3.7: {} - native-fetch@3.0.0(node-fetch@2.7.0(encoding@0.1.13)): - dependencies: - node-fetch: 2.7.0(encoding@0.1.13) - natural-compare@1.4.0: {} neo-async@2.6.2: {} @@ -11979,8 +11328,6 @@ snapshots: dependencies: wrappy: 1.0.2 - one-webcrypto@1.0.3: {} - onetime@5.1.2: dependencies: mimic-fn: 2.1.0 @@ -11998,15 +11345,6 @@ snapshots: os-paths@4.4.0: {} - p-defer@3.0.0: {} - - p-defer@4.0.0: {} - - p-fifo@1.0.0: - dependencies: - fast-fifo: 1.3.2 - p-defer: 3.0.0 - p-finally@2.0.1: {} p-limit@3.1.0: @@ -12026,11 +11364,6 @@ snapshots: eventemitter3: 5.0.4 p-timeout: 7.0.1 - p-retry@5.1.2: - dependencies: - '@types/retry': 0.12.1 - retry: 0.13.1 - p-timeout@7.0.1: {} parcel@2.12.0(@swc/helpers@0.5.2)(postcss@8.4.38)(terser@5.29.1)(typescript@5.3.3): @@ -12141,6 +11474,11 @@ snapshots: pify@2.3.0: {} + pinata@2.5.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + optionalDependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + pirates@4.0.6: {} pkg-types@1.0.3: @@ -12253,21 +11591,6 @@ snapshots: property-information@6.4.1: {} - protobufjs@7.2.6: - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/base64': 1.1.2 - '@protobufjs/codegen': 2.0.4 - '@protobufjs/eventemitter': 1.1.0 - '@protobufjs/fetch': 1.1.0 - '@protobufjs/float': 1.0.2 - '@protobufjs/inquire': 1.1.0 - '@protobufjs/path': 1.1.2 - '@protobufjs/pool': 1.1.0 - '@protobufjs/utf8': 1.1.0 - '@types/node': 20.12.7 - long: 5.2.3 - proxy-from-env@2.1.0: {} pump@3.0.0: @@ -12285,8 +11608,6 @@ snapshots: queue-microtask@1.2.3: {} - rabin-rs@2.1.0: {} - randombytes@2.1.0: dependencies: safe-buffer: 5.2.1 @@ -12332,10 +11653,6 @@ snapshots: react-is@18.2.0: {} - react-native-fetch-api@3.0.0: - dependencies: - p-defer: 3.0.0 - react-refresh@0.9.0: {} react-remove-scroll-bar@2.3.5(@types/react@18.3.1)(react@18.3.1): @@ -12470,8 +11787,6 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - retry@0.13.1: {} - reusify@1.0.4: {} rimraf@3.0.2: @@ -12694,10 +12009,6 @@ snapshots: dependencies: any-promise: 1.3.0 - stream-to-it@0.2.4: - dependencies: - get-iterator: 1.0.2 - stream-to-promise@2.2.0: dependencies: any-promise: 1.3.0 @@ -12800,8 +12111,6 @@ snapshots: dependencies: acorn: 8.11.3 - stubborn-fs@1.2.5: {} - style-to-object@0.4.4: dependencies: inline-style-parser: 0.1.1 @@ -12851,10 +12160,6 @@ snapshots: picocolors: 1.0.0 stable: 0.1.8 - sync-multihash-sha2@1.0.0: - dependencies: - '@noble/hashes': 1.3.3 - tailwind-merge@2.3.0: dependencies: '@babel/runtime': 7.24.4 @@ -13050,10 +12355,6 @@ snapshots: type-fest@0.20.2: {} - type-fest@2.19.0: {} - - type-fest@4.11.1: {} - typed-array-buffer@1.0.2: dependencies: call-bind: 1.0.7 @@ -13133,10 +12434,6 @@ snapshots: dependencies: uint8arrays: 6.1.1 - uint8arrays@4.0.10: - dependencies: - multiformats: 12.1.3 - uint8arrays@5.0.3: dependencies: multiformats: 13.1.0 @@ -13260,8 +12557,6 @@ snapshots: valibot@0.31.1: {} - varint@6.0.0: {} - vaul@0.9.0(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@radix-ui/react-dialog': 1.0.5(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -13435,8 +12730,6 @@ snapshots: tr46: 0.0.3 webidl-conversions: 3.0.1 - when-exit@2.1.2: {} - which-boxed-primitive@1.0.2: dependencies: is-bigint: 1.0.4 diff --git a/scripts/README.md b/scripts/README.md index 8ccf431..cd837d2 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -5,21 +5,10 @@ Development utility scripts which right now just consists of a script to bump th ## Required Tools - Bun - [bun|(https://bun.sh/docs/installation)] -- Web3 storage cli - `bun install -g @eb3-storage/w3cli` -## Setup web3 storage credentials +## Setup Pinata credentials -You should only need to run these steps once on your machine. The script uses the key and proof for upload permissions. - -- Login - - `w3 login ` -- Create a new space - - `w3 space create "blah"` -- Create a access key - - `w3 key create ` -- Write the private key (starting "Mg...") in the .env file variable `W3_KEY` -- Create a delegate proof and store in proof.txt - - `w3 delegation create --can space/blob/add --can space/index/add --can filecoin/offer --can upload/add --base64 > proof.txt` +You should only need to do this once on your machine. Create an **Admin**-scoped API key from the [Pinata dashboard](https://app.pinata.cloud/) and put its JWT in the `PINATA_KEY` environment variable. Also set `PINATA_GATEWAY_DOMAIN` to your account's dedicated gateway domain (Gateways tab in the dashboard, looks like `.mypinata.cloud`) — the shared `gateway.pinata.cloud` gateway 404s on freshly pinned content. ## Bump version diff --git a/scripts/bun.lockb b/scripts/bun.lockb index dfa8504..892c33f 100755 Binary files a/scripts/bun.lockb and b/scripts/bun.lockb differ diff --git a/scripts/package.json b/scripts/package.json index 54684f5..62cc7a5 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@types/semver": "^7.5.8", - "@web3-storage/w3up-client": "^15.0.0", + "pinata": "^2.5.6", "semver": "^7.6.2", "smol-toml": "^1.2.2" } diff --git a/scripts/upload-contract.ts b/scripts/upload-contract.ts index d85816f..9ee6275 100644 --- a/scripts/upload-contract.ts +++ b/scripts/upload-contract.ts @@ -1,10 +1,9 @@ -import * as Client from '@web3-storage/w3up-client'; -import { Signer } from '@web3-storage/w3up-client/principal/ed25519'; -import * as Proof from '@web3-storage/w3up-client/proof'; -import { StoreMemory } from '@web3-storage/w3up-client/stores/memory'; +import { PinataSDK } from 'pinata'; import { checkVersionsMatch } from './check-version'; +const PINATA_GATEWAY = process.env.PINATA_GATEWAY_DOMAIN || 'gateway.pinata.cloud'; + export async function uploadContracts() { const versionsMatch = checkVersionsMatch(); @@ -13,30 +12,21 @@ export async function uploadContracts() { 'The aiken.toml and the plutus.json version files do not match. Did you run build the contracts after bumping the version?' ); } - + console.log('Uploading latest contracts to IPFS...'); - const key = process.env.W3_KEY; + const jwt = process.env.PINATA_KEY; - if (!key) { - throw new Error('key must be set to create a server client to web3.storage'); + if (!jwt) { + throw new Error('PINATA_KEY must be set to create a Pinata client'); } - // Loading from file because this proof a very large base64 string that gets truncated - // somewhere (bun or OS) to 4096 characters. - const proof = await Bun.file('proof.txt').text(); - const principal = Signer.parse(key); - const store = new StoreMemory(); - const client = await Client.create({ principal, store }); - const parsed = await Proof.parse(proof); - const space = await client.addSpace(parsed); - - await client.setCurrentSpace(space.did()); + const pinata = new PinataSDK({ pinataJwt: jwt }); const file = Bun.file('../contracts/plutus.json'); - const link = await client.uploadFile(file); - const cid = link.toString(); + const upload = await pinata.upload.public.file(new File([await file.arrayBuffer()], 'plutus.json')); + const cid = upload.cid; console.log(`Latest contracts uploaded with cid: ${cid}`); const contractFile = Bun.file('../offchain/src/contracts-url.ts'); - Bun.write(contractFile, `export default 'https://${cid}.ipfs.w3s.link'`); + Bun.write(contractFile, `export default 'https://${PINATA_GATEWAY}/ipfs/${cid}'`); } diff --git a/web/.env.template b/web/.env.template index aad8370..23aa90f 100644 --- a/web/.env.template +++ b/web/.env.template @@ -9,5 +9,8 @@ SERVICE_WALLET_KEY_PREPROD= SERVICE_WALLET_ADDRESS_MAINNET= SERVICE_WALLET_KEY_MAINNET= -# README.md includes instructions on setting up web3 storage space credentials -W3_STORAGE_KEY= \ No newline at end of file +# README.md includes instructions on setting up a Pinata API key +PINATA_JWT= +# Required in practice: the shared gateway.pinata.cloud gateway 404s on freshly pinned +# content, so set this to your account's dedicated gateway domain (Pinata dashboard -> Gateways) +NEXT_PUBLIC_PINATA_GATEWAY_DOMAIN= \ No newline at end of file diff --git a/web/README.md b/web/README.md index 6bd6efd..cbfcf55 100644 --- a/web/README.md +++ b/web/README.md @@ -21,43 +21,23 @@ For Blockfrost you need to set the Preprod or Mainnet API key depending on netwo You may also need to add a project in the Blockfrost dashboard for the chosen network. Place the API key displayed in the dashboard into `.env.local` under the variable `NEXT_PUBLIC_BLOCKFROST_KEY_PREPROD` or `NEXT_PUBLIC_BLOCKFROST_KEY_MAINNET` depending on which network you chose. You can setup both if you would like to as well. -### Web3 Storage +### Pinata -Web3 storage is used for uploading images to IPFS. To use the API with Mintun you will need to first install the cli tool. +[Pinata](https://pinata.cloud/) is used for uploading images to IPFS. Sign up for a free account (no credit card required), then from the dashboard create an **Admin**-scoped API key. This key is only ever used server-side to mint short-lived, narrowly-scoped upload keys on demand — it never uploads anything directly and is never sent to the browser. -``` -pnpm install -g @web3-storage/w3cli -``` - -Next you need to login. If you don't already have an account this command will create one for you. One drawback is even with free tier you need to enter credit card information. We will see if there is a better solution in the future. The good news is the free tier is plenty of space for testing. - -``` -w3 login alice@example.com - -``` - -Next create a space and set the CLI to use that space +Copy the key's JWT into `.env.local`: ``` -w3 space create -w3 space use +PINATA_JWT= ``` -Now you can generate the credentials needed to perform client side upload from mintun. +Then grab your account's dedicated gateway domain from the dashboard (Gateways tab, looks like `.mypinata.cloud`) and set it too — the shared `gateway.pinata.cloud` gateway is unreliable for freshly pinned content (returns 404s), so a dedicated gateway is required, not optional: ``` -# The following command returns what will be your Agent private key and DID -w3 key create - -# ❗️ Store the private key (starting "Mg...") in environment variable W3_STORAGE_KEY - -w3 delegation create --can space/blob/add --can space/index/add --can filecoin/offer --can upload/add --can store/add --base64 > web/.proof - -# ❗️ Create a delegate proof and store it in 'web/.proof' - +NEXT_PUBLIC_PINATA_GATEWAY_DOMAIN=.mypinata.cloud ``` -Now you should be ready to upload. If you get some parse errors when uploading then something probably went wrong with generating the key. The [detailed guide](https://web3.storage/docs/how-to/upload/#using-the-cli) on web3.storage site may be of help. +No CLI tool or manual space/delegation setup is needed beyond that. The app mints a fresh, single-purpose upload key from the admin JWT every time a user uploads images. ## Current Task List diff --git a/web/app/api/storage/delegate/route.ts b/web/app/api/storage/delegate/route.ts deleted file mode 100644 index c040452..0000000 --- a/web/app/api/storage/delegate/route.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { NextRequest } from 'next/server'; - -import { createDelegation, createServerClient } from '@/lib/storage/server'; - -export const dynamic = 'force-dynamic'; - -// Delegate upload permissions to the requestor so that they can directly upload to IPFS -export async function POST(request: NextRequest) { - const { did } = await request.json(); - const client = await createServerClient(); - const delegation = await createDelegation(client, did); - - return new Response(delegation); -} diff --git a/web/app/api/storage/key/route.ts b/web/app/api/storage/key/route.ts new file mode 100644 index 0000000..95168ae --- /dev/null +++ b/web/app/api/storage/key/route.ts @@ -0,0 +1,11 @@ +import { createPinataClient, createScopedKey } from '@/lib/storage/server'; + +export const dynamic = 'force-dynamic'; + +// Mints a short-lived, narrowly-scoped Pinata key so the caller can upload directly to IPFS +export async function POST() { + const client = createPinataClient(); + const jwt = await createScopedKey(client); + + return Response.json({ jwt }); +} diff --git a/web/app/collection/create/use-genesis-mint.ts b/web/app/collection/create/use-genesis-mint.ts index fa554da..70831e9 100644 --- a/web/app/collection/create/use-genesis-mint.ts +++ b/web/app/collection/create/use-genesis-mint.ts @@ -5,7 +5,7 @@ import type { CollectionImage, ImagePurpose, MeshContext } from '@ikigai-github/ import { getTime } from 'date-fns'; import { countImages } from '@/lib/image'; -import { createWebClient } from '@/lib/storage/client'; +import { uploadDirectory } from '@/lib/storage/client'; import { useWallet } from '@/lib/wallet'; import { useCreateCollectionContext } from './context'; @@ -36,7 +36,6 @@ export default function useGenesisMint() { if (numImages) { setUploadProgress(0); - const client = await createWebClient(); const uploaded: CollectionImage[] = []; const files: File[] = []; for (const [mode, values] of Object.entries(images)) { @@ -60,13 +59,12 @@ export default function useGenesisMint() { } } - const result = await client.uploadDirectory(files, { + const cid = await uploadDirectory(files, { onUploadProgress: (status) => { setUploadProgress((status.loaded * 100) / status.total); }, }); - const cid = result.toString(); uploaded.forEach((item) => (item.src = item.src.replace('', cid))); setUploadProgress(1); diff --git a/web/app/collection/manage/[network]/[policy]/collection-info.tsx b/web/app/collection/manage/[network]/[policy]/collection-info.tsx index 0b47518..46e530c 100644 --- a/web/app/collection/manage/[network]/[policy]/collection-info.tsx +++ b/web/app/collection/manage/[network]/[policy]/collection-info.tsx @@ -8,7 +8,8 @@ import { DiscordLogoIcon, GlobeIcon, InfoCircledIcon, InstagramLogoIcon, Twitter import { formatDistanceStrict, formatDistanceToNow } from 'date-fns'; import { useIsMounted } from 'usehooks-ts'; -import { getBrandImageUrl } from '@/lib/image'; +import { getBrandImageUrls } from '@/lib/image'; +import IpfsImage from '@/components/ipfs-image'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'; import { useManageCollectionContext } from './context'; @@ -17,7 +18,7 @@ import StoreMintingPolicy from './store-minting-policy'; export default function CollectionInfo() { const { info, state, royalties, policy, drafts, mintReferenceUtxo } = useManageCollectionContext(); - const brandUrl = getBrandImageUrl(info); + const brandUrls = getBrandImageUrls(info); const isMounted = useIsMounted(); const remaining = useMemo(() => { @@ -35,8 +36,8 @@ export default function CollectionInfo() {
{info ? ( - brandUrl ? ( - Brand Image + brandUrls ? ( + ) : undefined ) : ( Brand Image diff --git a/web/app/collection/manage/[network]/[policy]/draft-nft.tsx b/web/app/collection/manage/[network]/[policy]/draft-nft.tsx index 582f4ad..b02732a 100644 --- a/web/app/collection/manage/[network]/[policy]/draft-nft.tsx +++ b/web/app/collection/manage/[network]/[policy]/draft-nft.tsx @@ -7,7 +7,7 @@ import { HobbyKnifeIcon, PlusIcon } from '@radix-ui/react-icons'; import { useForm } from 'react-hook-form'; import { uid as createUid } from 'uid'; -import { DefaultImageDetail, getWebImageUrl, ImageDetail } from '@/lib/image'; +import { DefaultImageDetail, getWebImageUrls, ImageDetail } from '@/lib/image'; import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion'; import { Button } from '@/components/ui/button'; import { Card } from '@/components/ui/card'; @@ -15,6 +15,7 @@ import { Form, FormControl, FormDescription, FormField, FormItem } from '@/compo import { Input } from '@/components/ui/input'; import DrawerDialog from '@/components/drawer-dialog'; import ImageDropzone from '@/components/image-dropzone'; +import IpfsImage from '@/components/ipfs-image'; import { useManageCollectionContext } from './context'; import DraftTagContent from './draft-tag-content'; @@ -42,9 +43,9 @@ function DraftNftCard({ uid }: { uid: string }) { const url = useMemo(() => { if (typeof image.data !== 'string') { - return URL.createObjectURL(image.data); + return [URL.createObjectURL(image.data)]; } else { - return getWebImageUrl(image.data); + return getWebImageUrls(image.data); } }, [image.data]); @@ -63,7 +64,7 @@ function DraftNftCard({ uid }: { uid: string }) { return (
- {name} +
{displayName}
diff --git a/web/app/collection/manage/[network]/[policy]/manage-collection.tsx b/web/app/collection/manage/[network]/[policy]/manage-collection.tsx index 259f2e6..bfcc84e 100644 --- a/web/app/collection/manage/[network]/[policy]/manage-collection.tsx +++ b/web/app/collection/manage/[network]/[policy]/manage-collection.tsx @@ -1,10 +1,9 @@ 'use client'; import { useMemo } from 'react'; -import Image from 'next/image'; -import bannerPlaceholder from '@/public/banner-placeholder.webp'; -import { getBannerImageUrl } from '@/lib/image'; +import { getBannerImageUrls } from '@/lib/image'; +import IpfsImage from '@/components/ipfs-image'; import Collection from './collection'; import CollectionInfo from './collection-info'; @@ -13,14 +12,14 @@ import { useManageCollectionContext } from './context'; export default function ManageCollection() { const { info } = useManageCollectionContext(); - const bannerUrl = useMemo(() => { - return getBannerImageUrl(info); + const bannerUrls = useMemo(() => { + return getBannerImageUrls(info); }, [info]); return ( <> - {bannerUrl ? ( - Collection Banner + {bannerUrls ? ( + ) : (
)} diff --git a/web/app/collection/manage/[network]/[policy]/mint-drafts.tsx b/web/app/collection/manage/[network]/[policy]/mint-drafts.tsx index e4d60d5..41b78a4 100644 --- a/web/app/collection/manage/[network]/[policy]/mint-drafts.tsx +++ b/web/app/collection/manage/[network]/[policy]/mint-drafts.tsx @@ -2,9 +2,10 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; import { MintunNft } from '@ikigai-github/mintun-offchain'; import { CheckIcon } from '@radix-ui/react-icons'; -import { getWebImageUrl } from '@/lib/image'; +import { getWebImageUrls } from '@/lib/image'; import { timeout } from '@/lib/utils'; import { notifyError, useWallet } from '@/lib/wallet'; +import IpfsImage from '@/components/ipfs-image'; import { Button } from '@/components/ui/button'; import TransactionDialog from '@/components/transaction-dialog'; @@ -13,7 +14,7 @@ import { useManageCollectionContext } from './context'; type DraftOption = { uid: string; name: string; - url: string; + url: string[]; selected: boolean; }; @@ -27,7 +28,7 @@ export default function MintDrafts() { useEffect(() => { const sequence = state?.nextSequence || 0; const options = drafts.map((draft, index) => { - const url = getWebImageUrl(draft.image.data as string); + const url = getWebImageUrls(draft.image.data as string); const name = draft.name || `${info?.name} #${sequence + index}`; const uid = draft.uid; const selected = index < 10; @@ -181,7 +182,7 @@ export default function MintDrafts() { onClick={() => onSelectToggle(index)} > {option.selected ? :
} - {option.name} + {option.name || 'Generated'} ); @@ -192,7 +193,7 @@ export default function MintDrafts() { return (
  • - {option.name} + {option.name || 'Generated'}
  • ); diff --git a/web/app/collection/manage/[network]/[policy]/nft.tsx b/web/app/collection/manage/[network]/[policy]/nft.tsx index a74b0d3..b783a94 100644 --- a/web/app/collection/manage/[network]/[policy]/nft.tsx +++ b/web/app/collection/manage/[network]/[policy]/nft.tsx @@ -1,7 +1,7 @@ -import Image from 'next/image'; import { HobbyKnifeIcon } from '@radix-ui/react-icons'; -import { getWebImageUrl } from '@/lib/image'; +import { getWebImageUrls } from '@/lib/image'; +import IpfsImage from '@/components/ipfs-image'; import { Card } from '@/components/ui/card'; import { Dialog, @@ -17,12 +17,12 @@ import Traits from './traits'; import { CollectionNft } from './types'; function NftCard({ nft, status }: CollectionNft) { - const url = getWebImageUrl(nft.image); + const urls = getWebImageUrls(nft.image); return (
    - {nft.name} +
    {nft.name}
    @@ -33,14 +33,14 @@ function NftCard({ nft, status }: CollectionNft) { } function NftCardDetail({ nft, status }: CollectionNft) { - const url = getWebImageUrl(nft.image); + const urls = getWebImageUrls(nft.image); return (
    {/* TODO: Make this a carousel if there is more than one image */} - {nft.name} +
    {nft.name} diff --git a/web/app/collection/manage/[network]/[policy]/use-save-draft.ts b/web/app/collection/manage/[network]/[policy]/use-save-draft.ts index a8f1546..23ecaab 100644 --- a/web/app/collection/manage/[network]/[policy]/use-save-draft.ts +++ b/web/app/collection/manage/[network]/[policy]/use-save-draft.ts @@ -1,7 +1,7 @@ import { useCallback, useState } from 'react'; import { getWebImageUrl, ImageDetail } from '@/lib/image'; -import { createWebClient } from '@/lib/storage/client'; +import { uploadDirectory } from '@/lib/storage/client'; import { useManageCollectionContext } from './context'; import { DraftTokenData } from './types'; @@ -12,7 +12,6 @@ export default function useSaveDraft(uid: string) { const uploadImages = useCallback( async (images: Record) => { - const client = await createWebClient(); const files: File[] = []; const uploaded: Record = {}; for (const key in images) { @@ -30,13 +29,12 @@ export default function useSaveDraft(uid: string) { } if (files.length) { - const result = await client.uploadDirectory(files, { + const cid = await uploadDirectory(files, { onUploadProgress: (status) => { setUploadProgress((status.loaded * 100) / status.total); }, }); - const cid = result.toString(); for (const key in uploaded) { const image = uploaded[key]; if (typeof image.data === 'string') { diff --git a/web/components/collections-list.tsx b/web/components/collections-list.tsx index db7088f..7dfb009 100644 --- a/web/components/collections-list.tsx +++ b/web/components/collections-list.tsx @@ -6,7 +6,7 @@ import { Network } from '@meshsdk/core'; import { Img } from 'react-image'; import { CollectionInfoExtended, getAllWalletCollections } from '@/lib/collection'; -import { getBrandImageUrl } from '@/lib/image'; +import { getBrandImageUrls } from '@/lib/image'; import { useWallet } from '@/lib/wallet'; type CollectionCardProps = { @@ -15,10 +15,7 @@ type CollectionCardProps = { }; const CollectionCard = ({ info, network }: CollectionCardProps) => { - const src = [ - getBrandImageUrl(info) || '/collection-thumbnail-placeholder.webp', - '/collection-thumbnail-placeholder.webp', - ]; + const src = [...(getBrandImageUrls(info) || []), '/collection-thumbnail-placeholder.webp']; const name = info.name; return ( diff --git a/web/components/ipfs-image.tsx b/web/components/ipfs-image.tsx new file mode 100644 index 0000000..8877198 --- /dev/null +++ b/web/components/ipfs-image.tsx @@ -0,0 +1,14 @@ +import { Img } from 'react-image'; + +type IpfsImageProps = { + src: string[]; + alt: string; + className?: string; +}; + +// Renders an image resolved from one or more IPFS gateway URLs, automatically falling back +// to the next url in the list if an earlier one fails to load (e.g. an old CID that's only +// pinned on the legacy web3.storage/Storacha gateway rather than the current Pinata gateway). +export default function IpfsImage({ src, alt, className }: IpfsImageProps) { + return {alt}; +} diff --git a/web/lib/image.ts b/web/lib/image.ts index f874b71..40b1ce1 100644 --- a/web/lib/image.ts +++ b/web/lib/image.ts @@ -73,40 +73,57 @@ export function getPreviews(lookup: ImageLookup) { .map((value) => value?.preview); } -export function getWebImageUrl(url: string | undefined) { +const PINATA_GATEWAY = process.env.NEXT_PUBLIC_PINATA_GATEWAY_DOMAIN || 'gateway.pinata.cloud'; + +// Returns candidate URLs for an ipfs:// url in priority order: the current Pinata gateway +// first, then the legacy web3.storage/Storacha gateway as a fallback for content pinned +// there before the migration to Pinata. Non-ipfs urls have no fallback so a single url is returned. +export function getWebImageUrls(url: string | undefined): string[] { if (url === undefined || url === '') { - return ''; + return ['']; } else if (url.startsWith('http://') || url.startsWith('https://') || url.startsWith('data:image')) { - return url; + return [url]; } else if (url.startsWith('ar://')) { const id = url.substring(5); - return `https://arweave.net/${id}`; + return [`https://arweave.net/${id}`]; } else { const paths = url.replaceAll('ipfs://ipfs/', '').replaceAll('ipfs://', '').split('/', 2); const cid = paths[0]; const name = paths[1]; if (name) { - return `https://${cid}.ipfs.w3s.link/${name}`; + return [`https://${PINATA_GATEWAY}/ipfs/${cid}/${name}`, `https://${cid}.ipfs.w3s.link/${name}`]; } - return `https://${cid}.ipfs.w3s.link`; + return [`https://${PINATA_GATEWAY}/ipfs/${cid}`, `https://${cid}.ipfs.w3s.link`]; } } -export function getBannerImageUrl(info?: CollectionInfo) { +export function getWebImageUrl(url: string | undefined) { + return getWebImageUrls(url)[0]; +} + +export function getBannerImageUrls(info?: CollectionInfo) { const image = info?.images?.find((image) => image.purpose === 'Banner' || image.purpose === 'General') || info?.images?.[0]; if (image) { - return getWebImageUrl(image.src); + return getWebImageUrls(image.src); } } -export function getBrandImageUrl(info?: CollectionInfo) { +export function getBannerImageUrl(info?: CollectionInfo) { + return getBannerImageUrls(info)?.[0]; +} + +export function getBrandImageUrls(info?: CollectionInfo) { const image = info?.images?.find((image) => image.purpose === 'Brand' || image.purpose === 'Thumbnail') || info?.images?.[0]; if (image) { - return getWebImageUrl(image.src); + return getWebImageUrls(image.src); } } + +export function getBrandImageUrl(info?: CollectionInfo) { + return getBrandImageUrls(info)?.[0]; +} diff --git a/web/lib/storage/client.ts b/web/lib/storage/client.ts index 85425e4..9735725 100644 --- a/web/lib/storage/client.ts +++ b/web/lib/storage/client.ts @@ -1,49 +1,57 @@ -import { useEffect, useState } from 'react'; -import { Client, create } from '@web3-storage/w3up-client'; -import * as Delegation from '@web3-storage/w3up-client/delegation'; - -export async function createWebClient() { - const client = await create(); - const did = client.agent.did(); - const apiUrl = '/api/storage/delegate'; - const response = await fetch(apiUrl, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ did }), - }); - const data = await response.arrayBuffer(); +const PINATA_PIN_URL = 'https://api.pinata.cloud/pinning/pinFileToIPFS'; - // Deserialize the delegation - const delegation = await Delegation.extract(new Uint8Array(data)); - if (!delegation.ok) { - throw new Error('Failed to extract delegation', { cause: delegation.error }); - } +async function getUploadKey() { + const response = await fetch('/api/storage/key', { method: 'POST' }); - // Add proof that this agent has been delegated capabilities on the space - const space = await client.addSpace(delegation.ok); - client.setCurrentSpace(space.did()); + if (!response.ok) { + throw new Error('Failed to get an upload key'); + } - return client; + const { jwt } = await response.json(); + return jwt as string; } -export function useStorageClient() { - const [client, setClient] = useState(null); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - - useEffect(() => { - createWebClient() - .then((client) => { - setClient(client); - setLoading(false); - }) - .catch((error) => { - setError(error); - setLoading(false); - }); - }, [setClient, setLoading, setError]); - - return { client, loading, error }; +export type UploadProgress = { + loaded: number; + total: number; +}; + +export type UploadOptions = { + onUploadProgress?: (progress: UploadProgress) => void; +}; + +// Uploads a set of files as a single IPFS directory so they resolve under one shared CID, +// e.g. ipfs:///. Uses XHR (not fetch) so upload progress can be reported. +export async function uploadDirectory(files: File[], options?: UploadOptions): Promise { + const jwt = await getUploadKey(); + + const data = new FormData(); + for (const file of files) { + data.append('file', file, file.name); + } + + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open('POST', PINATA_PIN_URL); + xhr.setRequestHeader('Authorization', `Bearer ${jwt}`); + + xhr.upload.onprogress = (event) => { + if (options?.onUploadProgress) { + options.onUploadProgress({ loaded: event.loaded, total: event.total }); + } + }; + + xhr.onload = () => { + if (xhr.status >= 200 && xhr.status < 300) { + const result = JSON.parse(xhr.responseText); + resolve(result.IpfsHash as string); + } else { + reject(new Error(`Failed to upload files to IPFS: ${xhr.status} ${xhr.responseText}`)); + } + }; + + xhr.onerror = () => reject(new Error('Failed to upload files to IPFS')); + + xhr.send(data); + }); } diff --git a/web/lib/storage/server.ts b/web/lib/storage/server.ts index 83a851f..a215fbd 100644 --- a/web/lib/storage/server.ts +++ b/web/lib/storage/server.ts @@ -1,54 +1,25 @@ import 'server-only'; -import { fstat } from 'fs'; -import { readFile } from 'fs/promises'; -import { CarReader } from '@ipld/car'; -import * as DID from '@ipld/dag-ucan/did'; -import { Client, create } from '@web3-storage/w3up-client'; -import { Signer } from '@web3-storage/w3up-client/principal/ed25519'; -import * as Proof from '@web3-storage/w3up-client/proof'; -import { StoreMemory } from '@web3-storage/w3up-client/stores/memory'; +import { PinataSDK } from 'pinata'; -export async function createServerClient() { - const key = process.env.W3_STORAGE_KEY; - let proof = process.env.W3_STORAGE_PROOF; +export function createPinataClient() { + const jwt = process.env.PINATA_JWT; - if (!key) { - throw new Error('key and proof must be set to create a server client to web3.storage'); + if (!jwt) { + throw new Error('PINATA_JWT must be set to create a Pinata client'); } - if (!proof) { - try { - const result = await readFile('.proof'); - proof = result.toString(); - } catch (e) { - throw new Error('Failed to load proof cannot create w3 storage client'); - } - } - - const principal = Signer.parse(key); - const store = new StoreMemory(); - const client = await create({ principal, store }); - const parsed = await Proof.parse(proof); - const space = await client.addSpace(parsed); - await client.setCurrentSpace(space.did()); - - return client; + return new PinataSDK({ pinataJwt: jwt }); } -export async function createDelegation(client: Client, did: string) { - // Create a delegation for a specific DID - const audience = DID.parse(did); - const expiration = Math.floor(Date.now() / 1000) + 60 * 60 * 1; // 1 hour from now - const delegation = await client.createDelegation( - audience, - ['space/blob/add', 'space/index/add', 'filecoin/offer', 'upload/add'], - { - expiration, - } - ); +// Mints a short-lived, narrowly-scoped key that only allows pinning files so it can be +// safely handed to the browser for a direct upload without exposing the admin JWT. +export async function createScopedKey(client: PinataSDK) { + const key = await client.keys.create({ + keyName: `mintun-upload-${Date.now()}`, + permissions: { endpoints: { pinning: { pinFileToIPFS: true } } }, + maxUses: 2, + }); - // Serialize the delegation and send it to the client - const archive = await delegation.archive(); - return archive.ok; + return key.JWT; } diff --git a/web/next.config.mjs b/web/next.config.mjs index f6d2ca3..3f68c24 100644 --- a/web/next.config.mjs +++ b/web/next.config.mjs @@ -4,7 +4,11 @@ import * as NextMdx from '@next/mdx'; const nextConfig = { swcMinify: true, images: { - remotePatterns: [{ protocol: 'https', hostname: '**.w3s.link' }], + remotePatterns: [ + { protocol: 'https', hostname: 'gateway.pinata.cloud' }, + { protocol: 'https', hostname: '**.mypinata.cloud' }, + { protocol: 'https', hostname: '**.w3s.link' }, + ], }, productionBrowserSourceMaps: true, pageExtensions: ['jsx', 'js', 'ts', 'tsx', 'mdx'], diff --git a/web/package.json b/web/package.json index ed5b421..8ed4346 100644 --- a/web/package.json +++ b/web/package.json @@ -12,8 +12,6 @@ "@hookform/error-message": "^2.0.1", "@hookform/resolvers": "^3.6.0", "@ikigai-github/mintun-offchain": "workspace:../offchain", - "@ipld/car": "^5.3.0", - "@ipld/dag-ucan": "^3.4.0", "@mdx-js/loader": "^3.0.1", "@mdx-js/react": "^3.0.1", "@meshsdk/core": "^1.9.1", @@ -35,7 +33,6 @@ "@radix-ui/react-tooltip": "^1.0.7", "@tanstack/react-table": "^8.16.0", "@types/mdx": "^2.0.13", - "@web3-storage/w3up-client": "^15.0.0", "bech32": "^2.0.0", "buffer": "^6.0.3", "cborg": "^4.2.0", @@ -46,6 +43,7 @@ "next": "14.1.0", "next-themes": "^0.2.1", "node-fetch": "^3.3.2", + "pinata": "^2.5.6", "react": "^18.3.1", "react-day-picker": "^8.10.1", "react-dom": "^18.3.1",